The emitters should automatically determine operand size by checking the vm_type of the variable.
Signed-off-by: Eduard - Gabriel Munteanu <eduard.munte...@linux360.ro> --- arch/x86/emit-code.c | 135 ++++++++++++++++------------------- arch/x86/include/arch/instruction.h | 31 -------- arch/x86/use-def.c | 35 ++------- 3 files changed, 68 insertions(+), 133 deletions(-) diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c index 00b79c6..69db8c9 100644 --- a/arch/x86/emit-code.c +++ b/arch/x86/emit-code.c @@ -1589,6 +1589,16 @@ static inline unsigned long rip_relative(struct buffer *buf, return addr - (unsigned long) buffer_current(buf) - insn_size; } +static inline int is_64bit_reg(struct operand *reg) +{ + return (reg->reg.interval->var_info->vm_type == J_LONG); +} + +static int is_64bit_bin_reg_op(struct operand *a, struct operand *b) +{ + return (is_64bit_reg(a) || is_64bit_reg(b)); +} + static void __emit_reg(struct buffer *buf, int rex_w, unsigned char opc, @@ -1607,24 +1617,24 @@ static void __emit_reg(struct buffer *buf, emit(buf, opc + reg_low(__reg)); } -static void __emit64_push_reg(struct buffer *buf, enum machine_reg reg) +static void __emit_push_reg(struct buffer *buf, enum machine_reg reg) { __emit_reg(buf, 0, 0x50, reg); } -static void emit64_push_reg(struct buffer *buf, struct operand *operand) +static void emit_push_reg(struct buffer *buf, struct operand *operand) { - __emit64_push_reg(buf, mach_reg(&operand->reg)); + __emit_push_reg(buf, mach_reg(&operand->reg)); } -static void __emit64_pop_reg(struct buffer *buf, enum machine_reg reg) +static void __emit_pop_reg(struct buffer *buf, enum machine_reg reg) { __emit_reg(buf, 0, 0x58, reg); } -static void emit64_pop_reg(struct buffer *buf, struct operand *operand) +static void emit_pop_reg(struct buffer *buf, struct operand *operand) { - __emit64_pop_reg(buf, mach_reg(&operand->reg)); + __emit_pop_reg(buf, mach_reg(&operand->reg)); } static void __emit_reg_reg(struct buffer *buf, @@ -1675,13 +1685,6 @@ static void __emit64_mov_reg_reg(struct buffer *buf, __emit_reg_reg(buf, 1, 0x89, src, dst); } -static void emit64_mov_reg_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) -{ - __emit64_mov_reg_reg(buf, mach_reg(&src->reg), mach_reg(&dest->reg)); -} - static void __emit32_mov_reg_reg(struct buffer *buf, enum machine_reg src, enum machine_reg dst) @@ -1689,11 +1692,16 @@ static void __emit32_mov_reg_reg(struct buffer *buf, __emit_reg_reg(buf, 0, 0x89, src, dst); } -static void emit32_mov_reg_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) +static void emit_mov_reg_reg(struct buffer *buf, + struct operand *src, + struct operand *dest) { - __emit32_mov_reg_reg(buf, mach_reg(&src->reg), mach_reg(&dest->reg)); + if (is_64bit_bin_reg_op(src, dest)) + __emit64_mov_reg_reg(buf, + mach_reg(&src->reg), mach_reg(&dest->reg)); + else + __emit32_mov_reg_reg(buf, + mach_reg(&src->reg), mach_reg(&dest->reg)); } static void emit_alu_imm_reg(struct buffer *buf, @@ -1730,13 +1738,6 @@ static void __emit64_sub_imm_reg(struct buffer *buf, emit_alu_imm_reg(buf, 1, 0x05, imm, reg); } -static void emit64_sub_imm_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) -{ - __emit64_sub_imm_reg(buf, src->imm, mach_reg(&dest->reg)); -} - static void __emit32_sub_imm_reg(struct buffer *buf, unsigned long imm, enum machine_reg reg) @@ -1744,11 +1745,14 @@ static void __emit32_sub_imm_reg(struct buffer *buf, emit_alu_imm_reg(buf, 0, 0x05, imm, reg); } -static void emit32_sub_imm_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) +static void emit_sub_imm_reg(struct buffer *buf, + struct operand *src, + struct operand *dest) { - __emit32_sub_imm_reg(buf, src->imm, mach_reg(&dest->reg)); + if (is_64bit_reg(dest)) + __emit64_sub_imm_reg(buf, src->imm, mach_reg(&dest->reg)); + else + __emit32_sub_imm_reg(buf, src->imm, mach_reg(&dest->reg)); } static void __emit64_add_imm_reg(struct buffer *buf, @@ -1758,13 +1762,6 @@ static void __emit64_add_imm_reg(struct buffer *buf, emit_alu_imm_reg(buf, 1, 0x00, imm, reg); } -static void emit64_add_imm_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) -{ - __emit64_add_imm_reg(buf, src->imm, mach_reg(&dest->reg)); -} - static void __emit32_add_imm_reg(struct buffer *buf, long imm, enum machine_reg reg) @@ -1772,11 +1769,14 @@ static void __emit32_add_imm_reg(struct buffer *buf, emit_alu_imm_reg(buf, 0, 0x00, imm, reg); } -static void emit32_add_imm_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) +static void emit_add_imm_reg(struct buffer *buf, + struct operand *src, + struct operand *dest) { - __emit64_add_imm_reg(buf, src->imm, mach_reg(&dest->reg)); + if (is_64bit_reg(dest)) + __emit64_add_imm_reg(buf, src->imm, mach_reg(&dest->reg)); + else + __emit64_add_imm_reg(buf, src->imm, mach_reg(&dest->reg)); } static void emit_imm64(struct buffer *buf, unsigned long imm) @@ -1805,7 +1805,7 @@ static void emit64_imm(struct buffer *buf, long imm) emit_imm64(buf, imm); } -static void __emit64_push_imm(struct buffer *buf, long imm) +static void __emit_push_imm(struct buffer *buf, long imm) { unsigned char opc; @@ -1818,9 +1818,9 @@ static void __emit64_push_imm(struct buffer *buf, long imm) emit_imm(buf, imm); } -static void emit64_push_imm(struct buffer *buf, struct operand *operand) +static void emit_push_imm(struct buffer *buf, struct operand *operand) { - __emit64_push_imm(buf, operand->imm); + __emit_push_imm(buf, operand->imm); } static void __emit_membase(struct buffer *buf, @@ -1958,18 +1958,11 @@ static void __emit32_test_membase_reg(struct buffer *buf, __emit_membase_reg(buf, 0, 0x85, src, disp, dest); } -static void emit64_test_membase_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) -{ - emit_membase_reg(buf, 1, 0x85, src, dest); -} - -static void emit32_test_membase_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) +static void emit_test_membase_reg(struct buffer *buf, + struct operand *src, + struct operand *dest) { - emit_membase_reg(buf, 0, 0x85, src, dest); + emit_membase_reg(buf, is_64bit_bin_reg_op(src, dest), 0x85, src, dest); } static void emit_indirect_jump_reg(struct buffer *buf, enum machine_reg reg) @@ -1990,9 +1983,9 @@ static void __emit64_mov_imm_reg(struct buffer *buf, emit_imm64(buf, imm); } -static void emit64_mov_imm_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) +static void emit_mov_imm_reg(struct buffer *buf, + struct operand *src, + struct operand *dest) { __emit64_mov_imm_reg(buf, src->imm, mach_reg(&dest->reg)); } @@ -2005,30 +1998,24 @@ static void __emit64_mov_membase_reg(struct buffer *buf, __emit_membase_reg(buf, 1, 0x8b, base_reg, disp, dest_reg); } -static void emit64_mov_membase_reg(struct buffer *buf, - struct operand *src, - struct operand *dest) +static void emit_mov_membase_reg(struct buffer *buf, + struct operand *src, + struct operand *dest) { emit_membase_reg(buf, 1, 0x8b, src, dest); } struct emitter emitters[] = { GENERIC_X86_EMITTERS, - - DECL_EMITTER(INSN64_ADD_IMM_REG, emit64_add_imm_reg, TWO_OPERANDS), - DECL_EMITTER(INSN64_MOV_IMM_REG, emit64_mov_imm_reg, TWO_OPERANDS), - DECL_EMITTER(INSN64_MOV_MEMBASE_REG, emit64_mov_membase_reg, TWO_OPERANDS), - DECL_EMITTER(INSN64_MOV_REG_REG, emit64_mov_reg_reg, TWO_OPERANDS), - DECL_EMITTER(INSN64_PUSH_IMM, emit64_push_imm, SINGLE_OPERAND), - DECL_EMITTER(INSN64_PUSH_REG, emit64_push_reg, SINGLE_OPERAND), - DECL_EMITTER(INSN64_POP_REG, emit64_pop_reg, SINGLE_OPERAND), - DECL_EMITTER(INSN64_SUB_IMM_REG, emit64_sub_imm_reg, TWO_OPERANDS), - DECL_EMITTER(INSN64_TEST_MEMBASE_REG, emit64_test_membase_reg, TWO_OPERANDS), - - DECL_EMITTER(INSN32_ADD_IMM_REG, emit32_add_imm_reg, TWO_OPERANDS), - DECL_EMITTER(INSN32_MOV_REG_REG, emit32_mov_reg_reg, TWO_OPERANDS), - DECL_EMITTER(INSN32_SUB_IMM_REG, emit32_sub_imm_reg, TWO_OPERANDS), - DECL_EMITTER(INSN32_TEST_MEMBASE_REG, emit64_test_membase_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_ADD_IMM_REG, emit_add_imm_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_MOV_IMM_REG, emit_mov_imm_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_MOV_MEMBASE_REG, emit_mov_membase_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_MOV_REG_REG, emit_mov_reg_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_PUSH_IMM, emit_push_imm, SINGLE_OPERAND), + DECL_EMITTER(INSN_PUSH_REG, emit_push_reg, SINGLE_OPERAND), + DECL_EMITTER(INSN_POP_REG, emit_pop_reg, SINGLE_OPERAND), + DECL_EMITTER(INSN_SUB_IMM_REG, emit_sub_imm_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_TEST_MEMBASE_REG, emit_test_membase_reg, TWO_OPERANDS), }; void emit_prolog(struct buffer *buf, unsigned long nr_locals) diff --git a/arch/x86/include/arch/instruction.h b/arch/x86/include/arch/instruction.h index b3c6f42..88be8a8 100644 --- a/arch/x86/include/arch/instruction.h +++ b/arch/x86/include/arch/instruction.h @@ -129,37 +129,6 @@ enum insn_type { INSN_XOR_IMM_REG, INSN_XOR_REG_REG, INSN_XOR_XMM_REG_REG, - -#ifdef CONFIG_X86_64 - INSN64_ADD_IMM_REG, - INSN64_MOV_IMM_REG, - INSN64_MOV_MEMBASE_REG, - INSN64_MOV_REG_REG, - INSN64_PUSH_IMM, - INSN64_PUSH_REG, - INSN64_POP_REG, - INSN64_SUB_IMM_REG, - INSN64_TEST_MEMBASE_REG, - - INSN32_ADD_IMM_REG, - INSN32_MOV_REG_REG, - INSN32_PUSH_IMM, - INSN32_PUSH_REG, - INSN32_POP_REG, - INSN32_SUB_IMM_REG, - INSN32_TEST_MEMBASE_REG, - - /* Aliases for instructions in common code. */ - INSN64_CALL_REL = INSN_CALL_REL, - INSN64_JE_BRANCH = INSN_JE_BRANCH, - INSN64_JGE_BRANCH = INSN_JGE_BRANCH, - INSN64_JG_BRANCH = INSN_JG_BRANCH, - INSN64_JLE_BRANCH = INSN_JLE_BRANCH, - INSN64_JL_BRANCH = INSN_JL_BRANCH, - INSN64_JMP_BRANCH = INSN_JMP_BRANCH, - INSN64_JNE_BRANCH = INSN_JNE_BRANCH, - INSN64_RET = INSN_RET, -#endif }; struct insn { diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c index eeebf9a..1c7790c 100644 --- a/arch/x86/use-def.c +++ b/arch/x86/use-def.c @@ -40,17 +40,6 @@ struct insn_info { #define DECLARE_INFO(_type, _flags) [_type] = { .flags = _flags } static struct insn_info insn_infos[] = { - DECLARE_INFO(INSN_CALL_REL, USE_NONE | DEF_xAX | DEF_xCX | DEF_xDX), - DECLARE_INFO(INSN_JE_BRANCH, USE_NONE | DEF_NONE), - DECLARE_INFO(INSN_JGE_BRANCH, USE_NONE | DEF_NONE), - DECLARE_INFO(INSN_JG_BRANCH, USE_NONE | DEF_NONE), - DECLARE_INFO(INSN_JLE_BRANCH, USE_NONE | DEF_NONE), - DECLARE_INFO(INSN_JL_BRANCH, USE_NONE | DEF_NONE), - DECLARE_INFO(INSN_JMP_BRANCH, USE_NONE | DEF_NONE), - DECLARE_INFO(INSN_JNE_BRANCH, USE_NONE | DEF_NONE), - DECLARE_INFO(INSN_RET, USE_NONE | DEF_NONE), - -#ifdef CONFIG_X86_32 DECLARE_INFO(INSN_ADC_IMM_REG, DEF_DST), DECLARE_INFO(INSN_ADC_MEMBASE_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_ADC_REG_REG, USE_SRC | DEF_DST), @@ -59,12 +48,13 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_ADD_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_AND_MEMBASE_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_AND_REG_REG, USE_SRC | DEF_DST), - DECLARE_INFO(INSN_CALL_REG, USE_SRC | DEF_EAX | DEF_ECX | DEF_EDX), + DECLARE_INFO(INSN_CALL_REG, USE_SRC | DEF_xAX | DEF_xCX | DEF_xDX), + DECLARE_INFO(INSN_CALL_REL, USE_NONE | DEF_xAX | DEF_xCX | DEF_xDX), DECLARE_INFO(INSN_CLTD_REG_REG, USE_SRC | DEF_SRC | DEF_DST), DECLARE_INFO(INSN_CMP_IMM_REG, USE_DST), DECLARE_INFO(INSN_CMP_MEMBASE_REG, USE_SRC | DEF_DST), - DECLARE_INFO(INSN_DIV_MEMBASE_REG, USE_SRC | DEF_DST | DEF_EAX | DEF_EDX), - DECLARE_INFO(INSN_DIV_REG_REG, USE_SRC | DEF_DST | DEF_EAX | DEF_EDX), + DECLARE_INFO(INSN_DIV_MEMBASE_REG, USE_SRC | DEF_DST | DEF_xAX | DEF_xDX), + DECLARE_INFO(INSN_DIV_REG_REG, USE_SRC | DEF_DST | DEF_xAX | DEF_xDX), DECLARE_INFO(INSN_FADD_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_FSUB_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_FMUL_REG_REG, USE_SRC | DEF_DST), @@ -97,8 +87,8 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_MOV_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_MOVSX_8_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_MOVSX_16_REG_REG, USE_SRC | DEF_DST), - DECLARE_INFO(INSN_MUL_MEMBASE_EAX, USE_SRC | DEF_DST | DEF_EDX | DEF_EAX), - DECLARE_INFO(INSN_MUL_REG_EAX, USE_SRC | DEF_DST | DEF_EDX | DEF_EAX), + DECLARE_INFO(INSN_MUL_MEMBASE_EAX, USE_SRC | DEF_DST | DEF_xDX | DEF_xAX), + DECLARE_INFO(INSN_MUL_REG_EAX, USE_SRC | DEF_DST | DEF_xDX | DEF_xAX), DECLARE_INFO(INSN_MUL_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_NEG_REG, USE_SRC | DEF_SRC), DECLARE_INFO(INSN_OR_MEMBASE_REG, USE_SRC | DEF_DST), @@ -106,6 +96,7 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_PUSH_IMM, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_PUSH_REG, USE_SRC | DEF_NONE), DECLARE_INFO(INSN_POP_REG, USE_NONE | DEF_SRC), + DECLARE_INFO(INSN_RET, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_SAR_IMM_REG, DEF_DST), DECLARE_INFO(INSN_SAR_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_SBB_IMM_REG, USE_NONE | DEF_DST), @@ -121,18 +112,6 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_XOR_IMM_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_XOR_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_XOR_XMM_REG_REG, USE_SRC | DEF_DST), -#else /* CONFIG_X86_32 */ - DECLARE_INFO(INSN32_ADD_IMM_REG, DEF_DST), - DECLARE_INFO(INSN32_MOV_REG_REG, USE_SRC | DEF_DST), - DECLARE_INFO(INSN32_SUB_IMM_REG, USE_NONE | DEF_DST), - - DECLARE_INFO(INSN64_ADD_IMM_REG, DEF_DST), - DECLARE_INFO(INSN64_MOV_REG_REG, USE_SRC | DEF_DST), - DECLARE_INFO(INSN64_PUSH_IMM, USE_NONE | DEF_NONE), - DECLARE_INFO(INSN64_PUSH_REG, USE_SRC | DEF_NONE), - DECLARE_INFO(INSN64_POP_REG, USE_NONE | DEF_SRC), - DECLARE_INFO(INSN64_SUB_IMM_REG, USE_NONE | DEF_DST), -#endif }; static inline struct insn_info *get_info(struct insn *insn) -- 1.6.0.6 ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel