diff options
Diffstat (limited to 'py/asmx64.c')
-rw-r--r-- | py/asmx64.c | 75 |
1 files changed, 36 insertions, 39 deletions
diff --git a/py/asmx64.c b/py/asmx64.c index 8d074dc40..3f111781f 100644 --- a/py/asmx64.c +++ b/py/asmx64.c @@ -54,19 +54,21 @@ #define OPCODE_MOV_RM64_TO_R64 (0x8b) #define OPCODE_LEA_MEM_TO_R64 (0x8d) /* /r */ #define OPCODE_XOR_R64_TO_RM64 (0x31) /* /r */ -#define OPCODE_ADD_R64_TO_RM64 (0x01) +#define OPCODE_ADD_R64_TO_RM64 (0x01) /* /r */ #define OPCODE_ADD_I32_TO_RM32 (0x81) /* /0 */ #define OPCODE_ADD_I8_TO_RM32 (0x83) /* /0 */ #define OPCODE_SUB_R64_FROM_RM64 (0x29) #define OPCODE_SUB_I32_FROM_RM64 (0x81) /* /5 */ #define OPCODE_SUB_I8_FROM_RM64 (0x83) /* /5 */ -#define OPCODE_SHL_RM32_BY_I8 (0xc1) /* /4 */ -#define OPCODE_SHR_RM32_BY_I8 (0xc1) /* /5 */ -#define OPCODE_SAR_RM32_BY_I8 (0xc1) /* /7 */ -#define OPCODE_CMP_I32_WITH_RM32 (0x81) /* /7 */ -#define OPCODE_CMP_I8_WITH_RM32 (0x83) /* /7 */ -#define OPCODE_CMP_R64_WITH_RM64 (0x39) -#define OPCODE_CMP_RM32_WITH_R32 (0x3b) +//#define OPCODE_SHL_RM32_BY_I8 (0xc1) /* /4 */ +//#define OPCODE_SHR_RM32_BY_I8 (0xc1) /* /5 */ +//#define OPCODE_SAR_RM32_BY_I8 (0xc1) /* /7 */ +#define OPCODE_SHL_RM64_CL (0xd3) /* /4 */ +#define OPCODE_SAR_RM64_CL (0xd3) /* /7 */ +//#define OPCODE_CMP_I32_WITH_RM32 (0x81) /* /7 */ +//#define OPCODE_CMP_I8_WITH_RM32 (0x83) /* /7 */ +#define OPCODE_CMP_R64_WITH_RM64 (0x39) /* /r */ +//#define OPCODE_CMP_RM32_WITH_R32 (0x3b) #define OPCODE_TEST_R8_WITH_RM8 (0x84) /* /r */ #define OPCODE_JMP_REL8 (0xeb) #define OPCODE_JMP_REL32 (0xe9) @@ -253,6 +255,10 @@ STATIC void asm_x64_write_r64_disp(asm_x64_t *as, int r64, int disp_r64, int dis } } +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 | (src_r64 < 8 ? 0 : REX_R) | (dest_r64 < 8 ? 0 : REX_B), op, MODRM_R64(src_r64) | MODRM_RM_REG | MODRM_RM_R64(dest_r64)); +} + void asm_x64_nop(asm_x64_t *as) { asm_x64_write_byte_1(as, OPCODE_NOP); } @@ -290,9 +296,8 @@ STATIC void asm_x64_ret(asm_x64_t *as) { asm_x64_write_byte_1(as, OPCODE_RET); } -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 | (src_r64 < 8 ? 0 : REX_R) | (dest_r64 < 8 ? 0 : REX_B), OPCODE_MOV_R64_TO_RM64, MODRM_R64(src_r64) | MODRM_RM_REG | MODRM_RM_R64(dest_r64)); +void asm_x64_mov_r64_r64(asm_x64_t *as, int dest_r64, int src_r64) { + asm_x64_generic_r64_r64(as, dest_r64, src_r64, OPCODE_MOV_R64_TO_RM64); } void asm_x64_mov_r8_to_disp(asm_x64_t *as, int src_r64, int dest_r64, int dest_disp) { @@ -377,30 +382,24 @@ void asm_x64_mov_i64_to_r64_aligned(asm_x64_t *as, int64_t src_i64, int dest_r64 asm_x64_mov_i64_to_r64(as, src_i64, dest_r64); } -void asm_x64_xor_r64_to_r64(asm_x64_t *as, int src_r64, int dest_r64) { - assert(src_r64 < 8); - assert(dest_r64 < 8); - asm_x64_write_byte_3(as, REX_PREFIX | REX_W, OPCODE_XOR_R64_TO_RM64, MODRM_R64(src_r64) | MODRM_RM_REG | MODRM_RM_R64(dest_r64)); +void asm_x64_xor_r64_r64(asm_x64_t *as, int dest_r64, int src_r64) { + asm_x64_generic_r64_r64(as, dest_r64, src_r64, OPCODE_XOR_R64_TO_RM64); } -void asm_x64_add_r64_to_r64(asm_x64_t *as, int src_r64, int dest_r64) { - assert(src_r64 < 8); - assert(dest_r64 < 8); - 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_shl_r64_cl(asm_x64_t* as, int dest_r64) { + asm_x64_generic_r64_r64(as, dest_r64, 4, OPCODE_SHL_RM64_CL); } -/* -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_sar_r64_cl(asm_x64_t* as, int dest_r64) { + asm_x64_generic_r64_r64(as, dest_r64, 7, OPCODE_SAR_RM64_CL); } -*/ -void asm_x64_sub_r64_from_r64(asm_x64_t *as, int src_r64, int dest_r64) { - // use REX prefix for 64 bit operation - assert(src_r64 < 8); - assert(dest_r64 < 8); - 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_add_r64_r64(asm_x64_t *as, int dest_r64, int src_r64) { + asm_x64_generic_r64_r64(as, dest_r64, src_r64, OPCODE_ADD_R64_TO_RM64); +} + +void asm_x64_sub_r64_r64(asm_x64_t *as, int dest_r64, int src_r64) { + asm_x64_generic_r64_r64(as, dest_r64, src_r64, OPCODE_SUB_R64_FROM_RM64); } /* @@ -417,7 +416,7 @@ void asm_x64_sub_i32_from_r32(asm_x64_t *as, int src_i32, int dest_r32) { } */ -void asm_x64_sub_i32_from_r64(asm_x64_t *as, int src_i32, int dest_r64) { +STATIC void asm_x64_sub_r64_i32(asm_x64_t *as, int dest_r64, int src_i32) { assert(dest_r64 < 8); if (SIGNED_FIT8(src_i32)) { // use REX prefix for 64 bit operation @@ -448,9 +447,7 @@ void asm_x64_sar_r32_by_imm(asm_x64_t *as, int r32, int imm) { */ void asm_x64_cmp_r64_with_r64(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_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)); + asm_x64_generic_r64_r64(as, src_r64_b, src_r64_a, OPCODE_CMP_R64_WITH_RM64); } /* @@ -541,12 +538,12 @@ void asm_x64_jcc_label(asm_x64_t *as, int jcc_type, int label) { void asm_x64_entry(asm_x64_t *as, int num_locals) { asm_x64_push_r64(as, ASM_X64_REG_RBP); - asm_x64_mov_r64_to_r64(as, ASM_X64_REG_RSP, ASM_X64_REG_RBP); + asm_x64_mov_r64_r64(as, ASM_X64_REG_RBP, ASM_X64_REG_RSP); if (num_locals < 0) { num_locals = 0; } num_locals |= 1; // make it odd so stack is aligned on 16 byte boundary - asm_x64_sub_i32_from_r64(as, num_locals * WORD_SIZE, ASM_X64_REG_RSP); + asm_x64_sub_r64_i32(as, ASM_X64_REG_RSP, num_locals * WORD_SIZE); asm_x64_push_r64(as, ASM_X64_REG_RBX); asm_x64_push_r64(as, ASM_X64_REG_R12); asm_x64_push_r64(as, ASM_X64_REG_R13); @@ -587,7 +584,7 @@ void asm_x64_mov_r64_to_local(asm_x64_t *as, int src_r64, int dest_local_num) { void asm_x64_mov_local_addr_to_r64(asm_x64_t *as, int local_num, int dest_r64) { int offset = asm_x64_local_offset_from_ebp(as, local_num); if (offset == 0) { - asm_x64_mov_r64_to_r64(as, ASM_X64_REG_RBP, dest_r64); + asm_x64_mov_r64_r64(as, dest_r64, ASM_X64_REG_RBP); } else { asm_x64_lea_disp_to_r64(as, ASM_X64_REG_RBP, offset, dest_r64); } @@ -600,7 +597,7 @@ void asm_x64_push_local(asm_x64_t *as, int local_num) { void asm_x64_push_local_addr(asm_x64_t *as, int local_num, int temp_r64) { - asm_x64_mov_r64_to_r64(as, ASM_X64_REG_RBP, temp_r64); + asm_x64_mov_r64_r64(as, temp_r64, ASM_X64_REG_RBP); asm_x64_add_i32_to_r32(as, asm_x64_local_offset_from_ebp(as, local_num), temp_r64); asm_x64_push_r64(as, temp_r64); } @@ -614,7 +611,7 @@ void asm_x64_call(asm_x64_t *as, void* func) asm_x64_sub_i32_from_r32(as, 8, ASM_X64_REG_RSP); asm_x64_write_byte_1(as, OPCODE_CALL_REL32); asm_x64_write_word32(as, func - (void*)(as->code_cur + 4)); - asm_x64_mov_r64_to_r64(as, ASM_X64_REG_RBP, ASM_X64_REG_RSP); + asm_x64_mov_r64_r64(as, ASM_X64_REG_RSP, ASM_X64_REG_RBP); } void asm_x64_call_i1(asm_x64_t *as, void* func, int i1) @@ -625,7 +622,7 @@ void asm_x64_call_i1(asm_x64_t *as, void* func, int i1) asm_x64_write_byte_1(as, OPCODE_CALL_REL32); asm_x64_write_word32(as, func - (void*)(as->code_cur + 4)); asm_x64_add_i32_to_r32(as, 16, ASM_X64_REG_RSP); - asm_x64_mov_r64_to_r64(as, ASM_X64_REG_RBP, ASM_X64_REG_RSP); + asm_x64_mov_r64_r64(as, ASM_X64_REG_RSP, ASM_X64_REG_RBP); } */ |