Signed-off-by: Arthur Huillet <arthur.huil...@free.fr> --- arch/x86/emit-code.c | 38 +++++++++++++++++++++++++++++++++++ arch/x86/include/arch/instruction.h | 16 ++++++++++++- arch/x86/lir-printer.c | 14 ++++++++++++ arch/x86/use-def.c | 2 + 4 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c index e72ae27..bf2b1b7 100644 --- a/arch/x86/emit-code.c +++ b/arch/x86/emit-code.c @@ -613,6 +613,20 @@ emit_mov_memlocal_reg(struct buffer *buf, struct operand *src, struct operand *d __emit_membase_reg(buf, 0x8b, REG_EBP, disp, dest_reg); } +static void +emit_mov_memlocal_freg(struct buffer *buf, struct operand *src, struct operand *dest) +{ + enum machine_reg dest_reg; + unsigned long disp; + + dest_reg = mach_reg(&dest->reg); + disp = slot_offset(src->slot); + + emit(buf, 0xf3); + emit(buf, 0x0f); + __emit_membase_reg(buf, 0x10, REG_EBP, disp, dest_reg); +} + static void emit_mov_membase_reg(struct buffer *buf, struct operand *src, struct operand *dest) { @@ -710,6 +724,28 @@ static void emit_mov_reg_memlocal(struct buffer *buf, struct operand *src, emit_imm(buf, disp); } +static void emit_mov_freg_memlocal(struct buffer *buf, struct operand *src, + struct operand *dest) +{ + unsigned long disp; + int mod; + + disp = slot_offset(dest->slot); + + if (is_imm_8(disp)) + mod = 0x01; + else + mod = 0x02; + + emit(buf, 0xf3); + emit(buf, 0x0f); + emit(buf, 0x11); + emit(buf, encode_modrm(mod, encode_reg(&src->reg), + __encode_reg(REG_EBP))); + + emit_imm(buf, disp); +} + static void emit_mov_reg_memindex(struct buffer *buf, struct operand *src, struct operand *dest) { @@ -1120,6 +1156,7 @@ struct emitter emitters[] = { DECL_EMITTER(INSN_MOV_IMM_MEMBASE, emit_mov_imm_membase, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_IMM_REG, emit_mov_imm_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_MEMLOCAL_REG, emit_mov_memlocal_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_MOV_MEMLOCAL_FREG, emit_mov_memlocal_freg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_MEMBASE_REG, emit_mov_membase_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_MEMDISP_REG, emit_mov_memdisp_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_REG_MEMDISP, emit_mov_reg_memdisp, TWO_OPERANDS), @@ -1128,6 +1165,7 @@ struct emitter emitters[] = { DECL_EMITTER(INSN_MOV_REG_MEMBASE, emit_mov_reg_membase, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_REG_MEMINDEX, emit_mov_reg_memindex, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_REG_MEMLOCAL, emit_mov_reg_memlocal, TWO_OPERANDS), + DECL_EMITTER(INSN_MOV_FREG_MEMLOCAL, emit_mov_freg_memlocal, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_REG_REG, emit_mov_reg_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MOVSX_REG_REG, emit_movsx_reg_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MUL_MEMBASE_EAX, emit_mul_membase_eax, TWO_OPERANDS), diff --git a/arch/x86/include/arch/instruction.h b/arch/x86/include/arch/instruction.h index 40f1ad5..0c4d0dd 100644 --- a/arch/x86/include/arch/instruction.h +++ b/arch/x86/include/arch/instruction.h @@ -81,6 +81,7 @@ enum insn_type { INSN_MOV_IMM_MEMBASE, INSN_MOV_IMM_REG, INSN_MOV_MEMLOCAL_REG, + INSN_MOV_MEMLOCAL_FREG, INSN_MOV_MEMBASE_REG, INSN_MOV_MEMDISP_REG, INSN_MOV_REG_MEMDISP, @@ -89,6 +90,7 @@ enum insn_type { INSN_MOV_REG_MEMBASE, INSN_MOV_REG_MEMINDEX, INSN_MOV_REG_MEMLOCAL, + INSN_MOV_FREG_MEMLOCAL, INSN_MOV_REG_REG, INSN_MOVSX_REG_REG, INSN_MUL_MEMBASE_EAX, @@ -196,13 +198,23 @@ struct insn *memlocal_insn(enum insn_type, struct stack_slot *); static inline struct insn * spill_insn(struct var_info *var, struct stack_slot *slot) { - return reg_memlocal_insn(INSN_MOV_REG_MEMLOCAL, var, slot); + if (var->type == REG_TYPE_GPR) + return reg_memlocal_insn(INSN_MOV_REG_MEMLOCAL, var, slot); + else if (var->type == REG_TYPE_FPU) + return reg_memlocal_insn(INSN_MOV_FREG_MEMLOCAL, var, slot); + else + return NULL; } static inline struct insn * reload_insn(struct stack_slot *slot, struct var_info *var) { - return memlocal_reg_insn(INSN_MOV_MEMLOCAL_REG, slot, var); + if (var->type == REG_TYPE_GPR) + return memlocal_reg_insn(INSN_MOV_MEMLOCAL_REG, slot, var); + else if (var->type == REG_TYPE_FPU) + return memlocal_reg_insn(INSN_MOV_MEMLOCAL_FREG, slot, var); + else + return NULL; } struct insn *alloc_insn(enum insn_type); diff --git a/arch/x86/lir-printer.c b/arch/x86/lir-printer.c index 7ad6bc4..ea39e28 100644 --- a/arch/x86/lir-printer.c +++ b/arch/x86/lir-printer.c @@ -340,6 +340,12 @@ static int print_mov_memlocal_reg(struct string *str, struct insn *insn) return print_memlocal_reg(str, insn); } +static int print_mov_memlocal_freg(struct string *str, struct insn *insn) +{ + print_func_name(str); + return print_memlocal_reg(str, insn); +} + static int print_mov_membase_reg(struct string *str, struct insn *insn) { print_func_name(str); @@ -388,6 +394,12 @@ static int print_mov_reg_memlocal(struct string *str, struct insn *insn) return print_reg_memlocal(str, insn); } +static int print_mov_freg_memlocal(struct string *str, struct insn *insn) +{ + print_func_name(str); + return print_reg_memlocal(str, insn); +} + static int print_mov_reg_reg(struct string *str, struct insn *insn) { print_func_name(str); @@ -580,6 +592,7 @@ static print_insn_fn insn_printers[] = { [INSN_MOV_IMM_MEMBASE] = print_mov_imm_membase, [INSN_MOV_IMM_REG] = print_mov_imm_reg, [INSN_MOV_MEMLOCAL_REG] = print_mov_memlocal_reg, + [INSN_MOV_MEMLOCAL_FREG] = print_mov_memlocal_freg, [INSN_MOV_MEMBASE_REG] = print_mov_membase_reg, [INSN_MOV_MEMDISP_REG] = print_mov_memdisp_reg, [INSN_MOV_REG_MEMDISP] = print_mov_reg_memdisp, @@ -588,6 +601,7 @@ static print_insn_fn insn_printers[] = { [INSN_MOV_REG_MEMBASE] = print_mov_reg_membase, [INSN_MOV_REG_MEMINDEX] = print_mov_reg_memindex, [INSN_MOV_REG_MEMLOCAL] = print_mov_reg_memlocal, + [INSN_MOV_FREG_MEMLOCAL] = print_mov_freg_memlocal, [INSN_MOV_REG_REG] = print_mov_reg_reg, [INSN_MOVSX_REG_REG] = print_movsx_reg_reg, [INSN_MUL_MEMBASE_EAX] = print_mul_membase_eax, diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c index a367237..926c3ce 100644 --- a/arch/x86/use-def.c +++ b/arch/x86/use-def.c @@ -56,6 +56,7 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_MOV_IMM_MEMBASE, USE_DST), DECLARE_INFO(INSN_MOV_IMM_REG, DEF_DST), DECLARE_INFO(INSN_MOV_MEMLOCAL_REG, USE_FP | DEF_DST), + DECLARE_INFO(INSN_MOV_MEMLOCAL_FREG, USE_FP | DEF_DST), DECLARE_INFO(INSN_MOV_MEMBASE_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_MOV_MEMDISP_REG, USE_NONE | DEF_DST), DECLARE_INFO(INSN_MOV_REG_MEMDISP, USE_NONE | DEF_SRC), @@ -63,6 +64,7 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_MOV_MEMINDEX_REG, USE_SRC | USE_IDX_SRC | DEF_DST), DECLARE_INFO(INSN_MOV_REG_MEMINDEX, USE_SRC | USE_DST | USE_IDX_DST | DEF_NONE), DECLARE_INFO(INSN_MOV_REG_MEMLOCAL, USE_SRC), + DECLARE_INFO(INSN_MOV_FREG_MEMLOCAL, USE_SRC), DECLARE_INFO(INSN_MOV_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_MOVSX_REG_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_MUL_MEMBASE_EAX, USE_SRC | DEF_DST | DEF_EDX | DEF_EAX), -- 1.6.3.3 ------------------------------------------------------------------------------ _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel