void asm_x64_sub_r32_from_r32(asm_x64_t* as, int src_r32, int dest_r32) { // defaults to 32 bit operation asm_x64_write_byte_2(as, OPCODE_SUB_R64_FROM_RM64, MODRM_R64(src_r32) | MODRM_RM_REG | MODRM_RM_R64(dest_r32)); }
void asm_x64_sub_r64_from_r64(asm_x64_t* as, int src_r64, int dest_r64) { // use REX prefix for 64 bit operation asm_x64_write_byte_3(as, REX_PREFIX | REX_W, OPCODE_SUB_R64_FROM_RM64, MODRM_R64(src_r64) | MODRM_RM_REG | MODRM_RM_R64(dest_r64)); }
void asm_x64_mov_r64_to_r64(asm_x64_t* as, int src_r64, int dest_r64) { // use REX prefix for 64 bit operation asm_x64_write_byte_3(as, REX_PREFIX | REX_W, OPCODE_MOV_R64_TO_RM64, MODRM_R64(src_r64) | MODRM_RM_REG | MODRM_RM_R64(dest_r64)); }
void asm_x64_add_r64_to_r64(asm_x64_t* as, int src_r64, int dest_r64) { asm_x64_write_byte_3(as, REX_PREFIX | REX_W, OPCODE_ADD_R64_TO_RM64, MODRM_R64(src_r64) | MODRM_RM_REG | MODRM_RM_R64(dest_r64)); }
void asm_x64_setcc_r8(asm_x64_t* as, int jcc_type, int dest_r8) { asm_x64_write_byte_3(as, OPCODE_SETCC_RM8_A, OPCODE_SETCC_RM8_B | jcc_type, MODRM_R64(0) | MODRM_RM_REG | MODRM_RM_R64(dest_r8)); }
void asm_x64_mov_r32_to_r32(asm_x64_t* as, int src_r32, int dest_r32) { // defaults to 32 bit operation asm_x64_write_byte_2(as, OPCODE_MOV_R64_TO_RM64, MODRM_R64(src_r32) | MODRM_RM_REG | MODRM_RM_R64(dest_r32)); }
void asm_x64_cmp_r64_with_r64(asm_x64_t* as, int src_r64_a, int src_r64_b) { asm_x64_write_byte_3(as, REX_PREFIX | REX_W, OPCODE_CMP_R64_WITH_RM64, MODRM_R64(src_r64_a) | MODRM_RM_REG | MODRM_RM_R64(src_r64_b)); }
void asm_x64_test_r8_with_r8(asm_x64_t* as, int src_r64_a, int src_r64_b) { // TODO implement for other registers assert(src_r64_a == REG_RAX); assert(src_r64_b == REG_RAX); asm_x64_write_byte_2(as, OPCODE_TEST_R8_WITH_RM8, MODRM_R64(src_r64_a) | MODRM_RM_REG | MODRM_RM_R64(src_r64_b)); }
void asm_x64_sar_r32_by_imm(asm_x64_t* as, int r32, int imm) { asm_x64_write_byte_2(as, OPCODE_SAR_RM32_BY_I8, MODRM_R64(7) | MODRM_RM_REG | MODRM_RM_R64(r32)); asm_x64_write_byte_1(as, imm); }
void asm_x64_jmp_reg(asm_x64_t *as, int src_r64) { assert(src_r64 < 8); asm_x64_write_byte_2(as, OPCODE_JMP_RM64, MODRM_R64(4) | MODRM_RM_REG | MODRM_RM_R64(src_r64)); }
void asm_x64_test_r8_with_r8(asm_x64_t *as, int src_r64_a, int src_r64_b) { assert(src_r64_a < 8); assert(src_r64_b < 8); asm_x64_write_byte_2(as, OPCODE_TEST_R8_WITH_RM8, MODRM_R64(src_r64_a) | MODRM_RM_REG | MODRM_RM_R64(src_r64_b)); }
void asm_x64_mul_r64_r64(asm_x64_t *as, int dest_r64, int src_r64) { // imul reg64, reg/mem64 -- 0x0f 0xaf /r asm_x64_write_byte_1(as, REX_PREFIX | REX_W | REX_R_FROM_R64(dest_r64) | REX_B_FROM_R64(src_r64)); asm_x64_write_byte_3(as, 0x0f, 0xaf, MODRM_R64(dest_r64) | MODRM_RM_REG | MODRM_RM_R64(src_r64)); }
STATIC void asm_x64_generic_r64_r64(asm_x64_t *as, int dest_r64, int src_r64, int op) { asm_x64_write_byte_3(as, REX_PREFIX | REX_W | REX_R_FROM_R64(src_r64) | REX_B_FROM_R64(dest_r64), op, MODRM_R64(src_r64) | MODRM_RM_REG | MODRM_RM_R64(dest_r64)); }