This moves some code emitters into a "generic emitters" section of
emit-code.c, so x86-64 can use them.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munte...@linux360.ro>
---
 arch/x86/emit-code.c |  494 ++++++++++++++++++++++++++------------------------
 1 files changed, 259 insertions(+), 235 deletions(-)

diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index 4056509..8d0d333 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -33,14 +33,29 @@
 
 #include <../jamvm/lock.h>
 
-/************************
- * Common code emitters *
- ************************/
-
-#ifdef CONFIG_X86_32
+/* Aliases and prototypes to make common emitters work as expected. */
+#ifdef CONFIG_X86_64
+# define __emit_add_imm_reg    __emit64_add_imm_reg
+# define __emit_pop_reg                __emit64_pop_reg
+# define __emit_push_imm       __emit64_push_imm
+# define __emit_push_membase   __emit64_push_membase
+# define __emit_push_reg       __emit64_push_reg
+#endif
+
+static unsigned char __encode_reg(enum machine_reg reg);
+static void __emit_add_imm_reg(struct buffer *buf,
+                              long imm,
+                              enum machine_reg reg);
+static void __emit_pop_reg(struct buffer *buf, enum machine_reg reg);
+static void __emit_push_imm(struct buffer *buf, long imm);
+static void __emit_push_membase(struct buffer *buf,
+                               enum machine_reg src_reg,
+                               unsigned long disp);
+static void __emit_push_reg(struct buffer *buf, enum machine_reg reg);
+static void emit_exception_test(struct buffer *buf, enum machine_reg reg);
 
 /************************
- * x86-32 code emitters *
+ * Common code emitters *
  ************************/
 
 #define PREFIX_SIZE 1
@@ -49,47 +64,16 @@
 
 #define CALL_INSN_SIZE 5
 
-/*
- *     __encode_reg:   Encode register to be used in IA-32 instruction.
- *     @reg: Register to encode.
- *
- *     Returns register in r/m or reg/opcode field format of the ModR/M byte.
- */
-static unsigned char __encode_reg(enum machine_reg reg)
-{
-       unsigned char ret = 0;
-
-       switch (reg) {
-       case REG_EAX:
-               ret = 0x00;
-               break;
-       case REG_EBX:
-               ret = 0x03;
-               break;
-       case REG_ECX:
-               ret = 0x01;
-               break;
-       case REG_EDX:
-               ret = 0x02;
-               break;
-       case REG_ESI:
-               ret = 0x06;
-               break;
-       case REG_EDI:
-               ret = 0x07;
-               break;
-       case REG_ESP:
-               ret = 0x04;
-               break;
-       case REG_EBP:
-               ret = 0x05;
-               break;
-       case REG_UNASSIGNED:
-               assert(!"unassigned register in code emission");
-               break;
-       }
-       return ret;
-}
+#define GENERIC_X86_EMITTERS \
+       DECL_EMITTER(INSN_CALL_REL, emit_call, SINGLE_OPERAND),         \
+       DECL_EMITTER(INSN_JE_BRANCH, emit_je_branch, BRANCH),           \
+       DECL_EMITTER(INSN_JGE_BRANCH, emit_jge_branch, BRANCH),         \
+       DECL_EMITTER(INSN_JG_BRANCH, emit_jg_branch, BRANCH),           \
+       DECL_EMITTER(INSN_JLE_BRANCH, emit_jle_branch, BRANCH),         \
+       DECL_EMITTER(INSN_JL_BRANCH, emit_jl_branch, BRANCH),           \
+       DECL_EMITTER(INSN_JMP_BRANCH, emit_jmp_branch, BRANCH),         \
+       DECL_EMITTER(INSN_JNE_BRANCH, emit_jne_branch, BRANCH),         \
+       DECL_EMITTER(INSN_RET, emit_ret, NO_OPERANDS)
 
 static unsigned char encode_reg(struct use_position *reg)
 {
@@ -167,6 +151,233 @@ static void emit_imm(struct buffer *buf, long imm)
                emit_imm32(buf, imm);
 }
 
+static void __emit_call(struct buffer *buf, void *call_target)
+{
+       int disp = call_target - buffer_current(buf) - CALL_INSN_SIZE;
+
+       emit(buf, 0xe8);
+       emit_imm32(buf, disp);
+}
+
+static void emit_call(struct buffer *buf, struct operand *operand)
+{
+       __emit_call(buf, (void *)operand->rel);
+}
+
+static void emit_ret(struct buffer *buf)
+{
+       emit(buf, 0xc3);
+}
+
+static void emit_leave(struct buffer *buf)
+{
+       emit(buf, 0xc9);
+}
+
+void emit_branch_rel(struct buffer *buf, unsigned char prefix,
+                    unsigned char opc, long rel32)
+{
+       if (prefix)
+               emit(buf, prefix);
+       emit(buf, opc);
+       emit_imm32(buf, rel32);
+}
+
+static long branch_rel_addr(struct insn *insn, unsigned long target_offset)
+{
+       long ret;
+
+       ret = target_offset - insn->mach_offset - BRANCH_INSN_SIZE;
+       if (insn->escaped)
+               ret -= PREFIX_SIZE;
+
+       return ret;
+}
+
+static void __emit_branch(struct buffer *buf, unsigned char prefix,
+                         unsigned char opc, struct insn *insn)
+{
+       struct basic_block *target_bb;
+       long addr = 0;
+
+       if (prefix)
+               insn->escaped = true;
+
+       target_bb = insn->operand.branch_target;
+
+       if (target_bb->is_emitted) {
+               struct insn *target_insn =
+                   list_first_entry(&target_bb->insn_list, struct insn,
+                              insn_list_node);
+
+               addr = branch_rel_addr(insn, target_insn->mach_offset);
+       } else
+               list_add(&insn->branch_list_node, &target_bb->backpatch_insns);
+
+       emit_branch_rel(buf, prefix, opc, addr);
+}
+
+static void emit_je_branch(struct buffer *buf, struct insn *insn)
+{
+       __emit_branch(buf, 0x0f, 0x84, insn);
+}
+
+static void emit_jne_branch(struct buffer *buf, struct insn *insn)
+{
+       __emit_branch(buf, 0x0f, 0x85, insn);
+}
+
+static void emit_jge_branch(struct buffer *buf, struct insn *insn)
+{
+       __emit_branch(buf, 0x0f, 0x8d, insn);
+}
+
+static void emit_jg_branch(struct buffer *buf, struct insn *insn)
+{
+       __emit_branch(buf, 0x0f, 0x8f, insn);
+}
+
+static void emit_jle_branch(struct buffer *buf, struct insn *insn)
+{
+       __emit_branch(buf, 0x0f, 0x8e, insn);
+}
+
+static void emit_jl_branch(struct buffer *buf, struct insn *insn)
+{
+       __emit_branch(buf, 0x0f, 0x8c, insn);
+}
+
+static void emit_jmp_branch(struct buffer *buf, struct insn *insn)
+{
+       __emit_branch(buf, 0x00, 0xe9, insn);
+}
+
+void emit_lock(struct buffer *buf, struct object *obj)
+{
+       __emit_push_imm(buf, (unsigned long)obj);
+       __emit_call(buf, objectLock);
+       __emit_add_imm_reg(buf, 0x04, REG_ESP);
+
+       __emit_push_reg(buf, REG_EAX);
+       emit_exception_test(buf, REG_EAX);
+       __emit_pop_reg(buf, REG_EAX);
+}
+
+void emit_unlock(struct buffer *buf, struct object *obj)
+{
+       /* Save caller-saved registers which contain method's return value */
+       __emit_push_reg(buf, REG_EAX);
+       __emit_push_reg(buf, REG_EDX);
+
+       __emit_push_imm(buf, (unsigned long)obj);
+       __emit_call(buf, objectUnlock);
+       __emit_add_imm_reg(buf, 0x04, REG_ESP);
+
+       emit_exception_test(buf, REG_EAX);
+
+       __emit_pop_reg(buf, REG_EDX);
+       __emit_pop_reg(buf, REG_EAX);
+}
+
+void emit_lock_this(struct buffer *buf)
+{
+       unsigned long this_arg_offset;
+
+       this_arg_offset = offsetof(struct jit_stack_frame, args);
+
+       __emit_push_membase(buf, REG_EBP, this_arg_offset);
+       __emit_call(buf, objectLock);
+       __emit_add_imm_reg(buf, 0x04, REG_ESP);
+
+       __emit_push_reg(buf, REG_EAX);
+       emit_exception_test(buf, REG_EAX);
+       __emit_pop_reg(buf, REG_EAX);
+}
+
+void emit_unlock_this(struct buffer *buf)
+{
+       unsigned long this_arg_offset;
+
+       this_arg_offset = offsetof(struct jit_stack_frame, args);
+
+       /* Save caller-saved registers which contain method's return value */
+       __emit_push_reg(buf, REG_EAX);
+       __emit_push_reg(buf, REG_EDX);
+
+       __emit_push_membase(buf, REG_EBP, this_arg_offset);
+       __emit_call(buf, objectUnlock);
+       __emit_add_imm_reg(buf, 0x04, REG_ESP);
+
+       emit_exception_test(buf, REG_EAX);
+
+       __emit_pop_reg(buf, REG_EDX);
+       __emit_pop_reg(buf, REG_EAX);
+}
+
+void backpatch_branch_target(struct buffer *buf,
+                            struct insn *insn,
+                            unsigned long target_offset)
+{
+       unsigned long backpatch_offset;
+       long relative_addr;
+
+       backpatch_offset = insn->mach_offset + BRANCH_TARGET_OFFSET;
+       if (insn->escaped)
+               backpatch_offset += PREFIX_SIZE;
+
+       relative_addr = branch_rel_addr(insn, target_offset);
+
+       write_imm32(buf, backpatch_offset, relative_addr);
+}
+
+#ifdef CONFIG_X86_32
+
+/************************
+ * x86-32 code emitters *
+ ************************/
+
+/*
+ *     __encode_reg:   Encode register to be used in IA-32 instruction.
+ *     @reg: Register to encode.
+ *
+ *     Returns register in r/m or reg/opcode field format of the ModR/M byte.
+ */
+static unsigned char __encode_reg(enum machine_reg reg)
+{
+       unsigned char ret = 0;
+
+       switch (reg) {
+       case REG_EAX:
+               ret = 0x00;
+               break;
+       case REG_EBX:
+               ret = 0x03;
+               break;
+       case REG_ECX:
+               ret = 0x01;
+               break;
+       case REG_EDX:
+               ret = 0x02;
+               break;
+       case REG_ESI:
+               ret = 0x06;
+               break;
+       case REG_EDI:
+               ret = 0x07;
+               break;
+       case REG_ESP:
+               ret = 0x04;
+               break;
+       case REG_EBP:
+               ret = 0x05;
+               break;
+       case REG_UNASSIGNED:
+               assert(!"unassigned register in code emission");
+               break;
+       }
+       return ret;
+}
+
 static void
 __emit_reg_reg(struct buffer *buf, unsigned char opc,
               enum machine_reg direct_reg, enum machine_reg rm_reg)
@@ -495,29 +706,6 @@ static void emit_push_imm(struct buffer *buf, struct 
operand *operand)
        __emit_push_imm(buf, operand->imm);
 }
 
-static void __emit_call(struct buffer *buf, void *call_target)
-{
-       int disp = call_target - buffer_current(buf) - CALL_INSN_SIZE;
-
-       emit(buf, 0xe8);
-       emit_imm32(buf, disp);
-}
-
-static void emit_call(struct buffer *buf, struct operand *operand)
-{
-       __emit_call(buf, (void *)operand->rel);
-}
-
-static void emit_ret(struct buffer *buf)
-{
-       emit(buf, 0xc3);
-}
-
-static void emit_leave(struct buffer *buf)
-{
-       emit(buf, 0xc9);
-}
-
 static void __emit_epilog(struct buffer *buf)
 {
        emit_leave(buf);
@@ -753,84 +941,6 @@ static void emit_indirect_jump_reg(struct buffer *buf, 
enum machine_reg reg)
        emit(buf, encode_modrm(0x3, 0x04, __encode_reg(reg)));
 }
 
-void emit_branch_rel(struct buffer *buf, unsigned char prefix,
-                    unsigned char opc, long rel32)
-{
-       if (prefix)
-               emit(buf, prefix);
-       emit(buf, opc);
-       emit_imm32(buf, rel32);
-}
-
-static long branch_rel_addr(struct insn *insn, unsigned long target_offset)
-{
-       long ret;
-
-       ret = target_offset - insn->mach_offset - BRANCH_INSN_SIZE;
-       if (insn->escaped)
-               ret -= PREFIX_SIZE;
-
-       return ret;
-}
-
-static void __emit_branch(struct buffer *buf, unsigned char prefix,
-                         unsigned char opc, struct insn *insn)
-{
-       struct basic_block *target_bb;
-       long addr = 0;
-
-       if (prefix)
-               insn->escaped = true;
-
-       target_bb = insn->operand.branch_target;
-
-       if (target_bb->is_emitted) {
-               struct insn *target_insn =
-                   list_first_entry(&target_bb->insn_list, struct insn,
-                              insn_list_node);
-
-               addr = branch_rel_addr(insn, target_insn->mach_offset);
-       } else
-               list_add(&insn->branch_list_node, &target_bb->backpatch_insns);
-
-       emit_branch_rel(buf, prefix, opc, addr);
-}
-
-static void emit_je_branch(struct buffer *buf, struct insn *insn)
-{
-       __emit_branch(buf, 0x0f, 0x84, insn);
-}
-
-static void emit_jne_branch(struct buffer *buf, struct insn *insn)
-{
-       __emit_branch(buf, 0x0f, 0x85, insn);
-}
-
-static void emit_jge_branch(struct buffer *buf, struct insn *insn)
-{
-       __emit_branch(buf, 0x0f, 0x8d, insn);
-}
-
-static void emit_jg_branch(struct buffer *buf, struct insn *insn)
-{
-       __emit_branch(buf, 0x0f, 0x8f, insn);
-}
-
-static void emit_jle_branch(struct buffer *buf, struct insn *insn)
-{
-       __emit_branch(buf, 0x0f, 0x8e, insn);
-}
-
-static void emit_jl_branch(struct buffer *buf, struct insn *insn)
-{
-       __emit_branch(buf, 0x0f, 0x8c, insn);
-}
-
-static void emit_jmp_branch(struct buffer *buf, struct insn *insn)
-{
-       __emit_branch(buf, 0x00, 0xe9, insn);
-}
-
 static void emit_indirect_call(struct buffer *buf, struct operand *operand)
 {
        emit(buf, 0xff);
@@ -878,69 +988,8 @@ static void emit_exception_test(struct buffer *buf, enum 
machine_reg reg)
        __emit_test_membase_reg(buf, reg, 0, reg);
 }
 
-void emit_lock(struct buffer *buf, struct object *obj)
-{
-       __emit_push_imm(buf, (unsigned long)obj);
-       __emit_call(buf, objectLock);
-       __emit_add_imm_reg(buf, 0x04, REG_ESP);
-
-       __emit_push_reg(buf, REG_EAX);
-       emit_exception_test(buf, REG_EAX);
-       __emit_pop_reg(buf, REG_EAX);
-}
-
-void emit_unlock(struct buffer *buf, struct object *obj)
-{
-       /* Save caller-saved registers which contain method's return value */
-       __emit_push_reg(buf, REG_EAX);
-       __emit_push_reg(buf, REG_EDX);
-
-       __emit_push_imm(buf, (unsigned long)obj);
-       __emit_call(buf, objectUnlock);
-       __emit_add_imm_reg(buf, 0x04, REG_ESP);
-
-       emit_exception_test(buf, REG_EAX);
-
-       __emit_pop_reg(buf, REG_EDX);
-       __emit_pop_reg(buf, REG_EAX);
-}
-
-void emit_lock_this(struct buffer *buf)
-{
-       unsigned long this_arg_offset;
-
-       this_arg_offset = offsetof(struct jit_stack_frame, args);
-
-       __emit_push_membase(buf, REG_EBP, this_arg_offset);
-       __emit_call(buf, objectLock);
-       __emit_add_imm_reg(buf, 0x04, REG_ESP);
-
-       __emit_push_reg(buf, REG_EAX);
-       emit_exception_test(buf, REG_EAX);
-       __emit_pop_reg(buf, REG_EAX);
-}
-
-void emit_unlock_this(struct buffer *buf)
-{
-       unsigned long this_arg_offset;
-
-       this_arg_offset = offsetof(struct jit_stack_frame, args);
-
-       /* Save caller-saved registers which contain method's return value */
-       __emit_push_reg(buf, REG_EAX);
-       __emit_push_reg(buf, REG_EDX);
-
-       __emit_push_membase(buf, REG_EBP, this_arg_offset);
-       __emit_call(buf, objectUnlock);
-       __emit_add_imm_reg(buf, 0x04, REG_ESP);
-
-       emit_exception_test(buf, REG_EAX);
-
-       __emit_pop_reg(buf, REG_EDX);
-       __emit_pop_reg(buf, REG_EAX);
-}
-
 struct emitter emitters[] = {
+       GENERIC_X86_EMITTERS,
        DECL_EMITTER(INSN_ADC_IMM_REG, emit_adc_imm_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_ADC_REG_REG, emit_adc_reg_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_ADC_MEMBASE_REG, emit_adc_membase_reg, TWO_OPERANDS),
@@ -949,19 +998,11 @@ struct emitter emitters[] = {
        DECL_EMITTER(INSN_ADD_REG_REG, emit_add_reg_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_AND_MEMBASE_REG, emit_and_membase_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_CALL_REG, emit_indirect_call, SINGLE_OPERAND),
-       DECL_EMITTER(INSN_CALL_REL, emit_call, SINGLE_OPERAND),
        DECL_EMITTER(INSN_CLTD_REG_REG, emit_cltd_reg_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_CMP_IMM_REG, emit_cmp_imm_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_CMP_MEMBASE_REG, emit_cmp_membase_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_CMP_REG_REG, emit_cmp_reg_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_DIV_MEMBASE_REG, emit_div_membase_reg, TWO_OPERANDS),
-       DECL_EMITTER(INSN_JE_BRANCH, emit_je_branch, BRANCH),
-       DECL_EMITTER(INSN_JGE_BRANCH, emit_jge_branch, BRANCH),
-       DECL_EMITTER(INSN_JG_BRANCH, emit_jg_branch, BRANCH),
-       DECL_EMITTER(INSN_JLE_BRANCH, emit_jle_branch, BRANCH),
-       DECL_EMITTER(INSN_JL_BRANCH, emit_jl_branch, BRANCH),
-       DECL_EMITTER(INSN_JMP_BRANCH, emit_jmp_branch, BRANCH),
-       DECL_EMITTER(INSN_JNE_BRANCH, emit_jne_branch, BRANCH),
        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),
@@ -982,7 +1023,6 @@ struct emitter emitters[] = {
        DECL_EMITTER(INSN_PUSH_REG, emit_push_reg, SINGLE_OPERAND),
        DECL_EMITTER(INSN_POP_MEMLOCAL, emit_pop_memlocal, SINGLE_OPERAND),
        DECL_EMITTER(INSN_POP_REG, emit_pop_reg, SINGLE_OPERAND),
-       DECL_EMITTER(INSN_RET, emit_ret, NO_OPERANDS),
        DECL_EMITTER(INSN_SAR_IMM_REG, emit_sar_imm_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_SAR_REG_REG, emit_sar_reg_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_SBB_IMM_REG, emit_sbb_imm_reg, TWO_OPERANDS),
@@ -998,22 +1038,6 @@ struct emitter emitters[] = {
        DECL_EMITTER(INSN_XOR_IMM_REG, emit_xor_imm_reg, TWO_OPERANDS),
 };
 
-void backpatch_branch_target(struct buffer *buf,
-                            struct insn *insn,
-                            unsigned long target_offset)
-{
-       unsigned long backpatch_offset;
-       long relative_addr;
-
-       backpatch_offset = insn->mach_offset + BRANCH_TARGET_OFFSET;
-       if (insn->escaped)
-               backpatch_offset += PREFIX_SIZE;
-
-       relative_addr = branch_rel_addr(insn, target_offset);
-
-       write_imm32(buf, backpatch_offset, relative_addr);
-}
-
 /*
  * This fixes relative calls generated by EXPR_INVOKE.
  *
-- 
1.6.0.6


------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing 
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to