* jit/s390/emit.c: Likiwise.
* jit/s390/codegen.c: Likewise.
* jit/s390/codegen.h: Likewise.
* jit/s390/md-asm.h: Likewise.
* jit/s390/patcher.c: Likewise.
* jit/s390/asmpart.S: Likewise.
* jit/codegen-common.c: Likewise.
memory. All functions writing values into the data area return the offset
relative the begin of the code area (start of procedure).
- $Id: codegen-common.c 7246 2007-01-29 18:49:05Z twisti $
+ $Id: codegen-common.c 7300 2007-02-07 22:06:53Z pm $
*/
pr->next = cd->patchrefs;
cd->patchrefs = pr;
-#if defined(ENABLE_JIT) && (defined(__ALPHA__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__))
+#if defined(ENABLE_JIT) && (defined(__ALPHA__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__) || defined(__S390__))
/* Generate NOPs for opt_shownops. */
if (opt_shownops)
Changes: Edwin Steiner
- $Id: asmpart.S 7283 2007-02-04 19:41:14Z pm $
+ $Id: asmpart.S 7300 2007-02-07 22:06:53Z pm $
*/
asm_handle_exception:
asm_handle_nat_exception:
asm_abstractmethoderror:
-asm_patcher_wrapper:
asm_replacement_out:
asm_replacement_in:
asm_builtin_f2i:
/* call jit_asm_compile in a PIC way */
- bras itmp3, L_bras_jac
+ bras itmp2, L_bras_jac
.long jit_asm_compile
L_bras_jac:
- l itmp3, 0(itmp3)
- basr %r14, itmp3
+ l itmp2, 0(itmp2)
+ basr %r14, itmp2
lr pv, v0 /* save return value */
sub $3,xpc /* exception address is ra - 3 */
jmp L_asm_handle_exception
+#endif
/* asm_patcher_wrapper *********************************************************
XXX
Stack layout:
- 40 return address
- 32 pointer to virtual java_objectheader
- 24 machine code (which is patched back later)
- 16 unresolved class/method/field reference
- 8 data segment displacement from load instructions
- 0 pointer to patcher function
- -8 bp
+ 20 return address into JIT code (patch position)
+ 16 pointer to virtual java_objectheader
+ 12 machine code (which is patched back later)
+ 8 unresolved class/method/field reference
+ 4 data segment displacement from load instructions
+ 0 patcher function pointer to call (pv afterwards)
*******************************************************************************/
asm_patcher_wrapper:
- push bp /* save base pointer */
- mov sp,bp /* move actual sp to bp */
- sub $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),sp
- and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
- /* leaf functions) */
+# define apw_sfs (96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE + VOLATILE_FLOAT_REGISTERS_SIZE)
+
+ ahi sp, -apw_sfs /* create stack frame */
+
+ /* store all volatile registers and a2, because we will touch it */
+
+ st a2, 96(sp)
+ STORE_VOLATILE_INTEGER_REGISTERS(96 + 4)
+ STORE_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
+
+ /* pass arguments */
- SAVE_ARGUMENT_REGISTERS(3)
- SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
+ la a0, apw_sfs(sp) /* pass SP of patcher stub */
+ lr a1, pv /* pass PV (if NULL, use findmethod) */
+ lhi a2, 0 /* pass RA (it's on the stack) */
- mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
- mov itmp2,1*8(sp) /* can be used by some instructions */
+ /* call patcher_wrapper */
- mov bp,a0 /* pass SP of patcher stub */
- add $(1*8),a0
- mov $0,a1 /* pass PV (if NULL, use findmethod) */
- mov $0,a2 /* pass RA (it's on the stack) */
- call patcher_wrapper@PLT
- mov v0,2*8(sp) /* save return value */
+ bras itmp1, L_apw_bras /* call patcher_wrapper */
+ .long patcher_wrapper
+L_apw_bras:
+ l itmp1, 0(itmp1)
+ basr %r14, itmp1
- RESTORE_ARGUMENT_REGISTERS(3)
- RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
+ /* store return value */
- mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
- mov 1*8(sp),itmp2 /* can be used by some instructions */
- mov 2*8(sp),itmp3 /* restore return value */
+ st v0,0(sp) /* save return value */
- mov bp,sp /* restore original sp */
- pop bp /* restore bp */
- add $(5*8),sp /* remove patcher stackframe, keep RA */
+ /* restore volatile registers */
- test itmp3,itmp3 /* exception thrown? */
- jne L_asm_patcher_wrapper_exception
- ret /* call new patched code */
+ l a2, 96(sp)
+ LOAD_VOLATILE_INTEGER_REGISTERS(96 + 4)
+ LOAD_VOLATILE_FLOAT_REGISTERS(96 + 4 + VOLATILE_INTEGER_REGISTERS_SIZE)
+
+ l itmp3, 0(sp) /* restore return value */
+ ltr itmp3, itmp3 /* exception thrown ? */
+ jne L_asm_patcher_wrapper_exception /* handle exception */
+ ahi sp, apw_sfs /* remove stack frame */
+ l itmp3, 20(sp) /* load return address to JIT from stack */
+ br itmp3 /* return */
L_asm_patcher_wrapper_exception:
+ .long 0
+#if 0
mov itmp3,xptr /* get exception */
pop xpc /* get and remove return address */
jmp L_asm_handle_exception
+#endif
+#if 0
/* asm_replacement_out *********************************************************
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 7283 2007-02-04 19:41:14Z pm $
+ $Id: codegen.c 7300 2007-02-07 22:06:53Z pm $
*/
p = cd->stackframesize;
p--; M_AST(REG_RA, REG_SP, p * 4);
for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
- p--; M_LST(rd->savintregs[i], REG_SP, p * 4);
+ p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
}
for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
/* constant operations ************************************************/
case ICMD_ICONST: /* ... ==> ..., constant */
- OOPS();
-#if 0
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
ICONST(d, iptr->sx.val.i);
emit_store_dst(jd, iptr, d);
-#endif
break;
case ICMD_LCONST: /* ... ==> ..., constant */
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = dseg_add_unique_address(cd, NULL);
- /* must be calculated before codegen_add_patch_ref */
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
-
/* PROFILE_CYCLE_STOP; */
codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
-
PROFILE_CYCLE_START;
}
}
break;
case ICMD_PUTSTATIC: /* ..., value ==> ... */
- OOPS();
-#if 0
+
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
- disp = dseg_add_unique_address(cd, NULL);
- disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
-
- /* must be calculated before codegen_add_patch_ref */
+ disp = dseg_add_unique_address(cd, uf);
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
-
-/* PROFILE_CYCLE_STOP; */
-
- codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
-
-/* PROFILE_CYCLE_START; */
+ codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
disp = dseg_add_address(cd, &(fi->value));
- disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
- if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
- PROFILE_CYCLE_STOP;
-
- codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
-
- PROFILE_CYCLE_START;
- }
+ if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
+ codegen_addpatchref(cd, PATCHER_clinit,
+ fi->class, disp);
}
- /* This approach is much faster than moving the field
- address inline into a register. */
-
- M_ALD(REG_ITMP1, RIP, disp);
-
+ M_ALD(REG_ITMP1, REG_PV, disp);
switch (fieldtype) {
case TYPE_INT:
s1 = emit_load_s1(jd, iptr, REG_ITMP2);
M_IST(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
+ s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
+ M_LST(s1, REG_ITMP1, 0);
+ break;
case TYPE_ADR:
s1 = emit_load_s1(jd, iptr, REG_ITMP2);
- M_LST(s1, REG_ITMP1, 0);
+ M_AST(s1, REG_ITMP1, 0);
break;
case TYPE_FLT:
- s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+ s1 = emit_load_s1(jd, iptr, REG_FTMP2);
M_FST(s1, REG_ITMP1, 0);
break;
case TYPE_DBL:
- s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+ s1 = emit_load_s1(jd, iptr, REG_FTMP2);
M_DST(s1, REG_ITMP1, 0);
break;
}
-#endif
break;
case ICMD_PUTSTATICCONST: /* ... ==> ... */
case ICMD_GOTO: /* ... ==> ... */
case ICMD_RET: /* ... ==> ... */
- OOPS();
-#if 0
- M_JMP_IMM(0);
+
+ M_BR(0);
codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
+
break;
case ICMD_JSR: /* ... ==> ... */
break;
case ICMD_IFNONNULL: /* ..., value ==> ... */
- OOPS();
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_TEST(s1);
M_BNE(0);
break;
case ICMD_IFEQ: /* ..., value ==> ... */
- OOPS();
-#if 0
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_ICMP_IMM(iptr->sx.val.i, s1);
- M_BEQ(0);
- codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
- break;
-
case ICMD_IFLT: /* ..., value ==> ... */
- OOPS();
-#if 0
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_ICMP_IMM(iptr->sx.val.i, s1);
- M_BLT(0);
- codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
- break;
-
case ICMD_IFLE: /* ..., value ==> ... */
- OOPS();
-#if 0
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_ICMP_IMM(iptr->sx.val.i, s1);
- M_BLE(0);
- codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
- break;
-
case ICMD_IFNE: /* ..., value ==> ... */
- OOPS();
-#if 0
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_ICMP_IMM(iptr->sx.val.i, s1);
- M_BNE(0);
- codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
- break;
-
case ICMD_IFGT: /* ..., value ==> ... */
- OOPS();
-#if 0
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_ICMP_IMM(iptr->sx.val.i, s1);
- M_BGT(0);
- codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
- break;
-
case ICMD_IFGE: /* ..., value ==> ... */
- OOPS();
-#if 0
+
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- M_ICMP_IMM(iptr->sx.val.i, s1);
- M_BGE(0);
+
+ if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
+ N_CHI(s1, iptr->sx.val.i);
+ else {
+ disp = dseg_add_s4(cd, iptr->sx.val.i);
+ N_LHI(REG_ITMP2, disp);
+ N_CL(s1, 0, REG_ITMP2, REG_PV);
+ }
+
+ switch (iptr->opc) {
+ case ICMD_IFLT:
+ M_BLT(0);
+ break;
+ case ICMD_IFLE:
+ M_BLE(0);
+ break;
+ case ICMD_IFNE:
+ M_BNE(0);
+ break;
+ case ICMD_IFGT:
+ M_BGT(0);
+ break;
+ case ICMD_IFGE:
+ M_BGE(0);
+ break;
+ case ICMD_IFEQ:
+ M_BEQ(0);
+ break;
+ }
codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
+
break;
case ICMD_IF_LEQ: /* ..., value ==> ... */
case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
OOPS();
#if 0
-
- /* val.a: (classinfo *) superclass */
+ /* val.a: (classinfo*) superclass */
/* superclass is an interface:
*
}
#if defined(ENABLE_THREADS)
- codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
+ codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
#endif
-
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if (s1 == d) {
- M_INTMOVE(s1, REG_ITMP1);
+ M_MOV(s1, REG_ITMP1);
s1 = REG_ITMP1;
}
/* calculate interface instanceof code size */
- s2 = 3; /* mov_membase_reg */
- CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
- s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub_imm32 */ +
- 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
- 3 /* test */ + 4 /* setcc */;
-
- if (!super)
- s2 += (opt_shownops ? 5 : 0);
+ s2 = 6;
+ if (super == NULL)
+ s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_shownops ? 1 : 0);
/* calculate class instanceof code size */
-
- s3 = 3; /* mov_membase_reg */
- CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
- s3 += 10; /* mov_imm_reg */
- s3 += 2; /* movl_membase_reg - only if REG_ITMP1 == RAX */
- CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
- s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
- CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
- s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
- CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
- s3 += 3 /* sub */ + 3 /* xor */ + 3 /* cmp */ + 4 /* setcc */;
+ s3 = 7;
if (super == NULL)
- s3 += (opt_shownops ? 5 : 0);
-
- emit_alu_reg_reg(cd, ALU_XOR, d, d);
+ s3 += (opt_shownops ? 1 : 0);
/* if class is not resolved, check which code to call */
if (super == NULL) {
- emit_test_reg_reg(cd, s1, s1);
- emit_jcc(cd, CC_Z, (6 + (opt_shownops ? 5 : 0) +
- 7 + 6 + s2 + 5 + s3));
+ M_CLR(d);
+ M_BEQZ(s1, 4 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
- codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
- iptr->sx.s23.s3.c.ref, 0);
+ disp = dseg_add_unique_s4(cd, 0); /* super->flags */
- emit_movl_imm_reg(cd, 0, REG_ITMP3); /* super->flags */
- emit_alul_imm_reg(cd, ALU_AND, ACC_INTERFACE, REG_ITMP3);
- emit_jcc(cd, CC_Z, s2 + 5);
+ codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
+ iptr->sx.s23.s3.c.ref, disp);
+
+ M_ILD(REG_ITMP3, REG_PV, disp);
+
+ disp = dseg_add_s4(cd, ACC_INTERFACE);
+ M_ILD(REG_ITMP2, REG_PV, disp);
+ M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
+ M_BEQZ(REG_ITMP3, s2 + 1);
}
/* interface instanceof code */
if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
- if (super != NULL) {
- emit_test_reg_reg(cd, s1, s1);
- emit_jcc(cd, CC_Z, s2);
- }
-
- emit_mov_membase_reg(cd, s1,
- OFFSET(java_objectheader, vftbl),
- REG_ITMP1);
-
if (super == NULL) {
+ /* If d == REG_ITMP2, then it's destroyed in check
+ code above. */
+ if (d == REG_ITMP2)
+ M_CLR(d);
+
codegen_add_patch_ref(cd,
PATCHER_checkcast_instanceof_interface,
iptr->sx.s23.s3.c.ref, 0);
}
+ else {
+ M_CLR(d);
+ M_BEQZ(s1, s2);
+ }
- emit_movl_membase32_reg(cd, REG_ITMP1,
- OFFSET(vftbl_t, interfacetablelength),
- REG_ITMP3);
- emit_alu_imm32_reg(cd, ALU_SUB, superindex, REG_ITMP3);
- emit_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
-
- a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
-
- emit_jcc(cd, CC_LE, a);
- emit_mov_membase32_reg(cd, REG_ITMP1,
- OFFSET(vftbl_t, interfacetable[0]) -
- superindex * sizeof(methodptr*),
- REG_ITMP1);
- emit_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
- emit_setcc_reg(cd, CC_NE, d);
+ M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+ M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
+ M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
+ M_BLEZ(REG_ITMP3, 2);
+ M_ALD(REG_ITMP1, REG_ITMP1,
+ (s4) (OFFSET(vftbl_t, interfacetable[0]) -
+ superindex * sizeof(methodptr*)));
+ M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
- if (!super)
- emit_jmp_imm(cd, s3);
+ if (super == NULL)
+ M_BR(s3);
}
/* class instanceof code */
if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
- if (super != NULL) {
- emit_test_reg_reg(cd, s1, s1);
- emit_jcc(cd, CC_E, s3);
- }
+ if (super == NULL) {
+ disp = dseg_add_unique_address(cd, NULL);
- emit_mov_membase_reg(cd, s1,
- OFFSET(java_objectheader, vftbl),
- REG_ITMP1);
+ codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
+ iptr->sx.s23.s3.c.ref,
+ disp);
+ }
+ else {
+ disp = dseg_add_address(cd, supervftbl);
- if (super == NULL) {
- codegen_add_patch_ref(cd, PATCHER_instanceof_class,
- iptr->sx.s23.s3.c.ref, 0);
+ M_CLR(d);
+ M_BEQZ(s1, s3);
}
- emit_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP2);
+ M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_ITMP2, REG_PV, disp);
#if defined(ENABLE_THREADS)
codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
#endif
- emit_movl_membase_reg(cd, REG_ITMP1,
- OFFSET(vftbl_t, baseval),
- REG_ITMP1);
- emit_movl_membase_reg(cd, REG_ITMP2,
- OFFSET(vftbl_t, diffval),
- REG_ITMP3);
- emit_movl_membase_reg(cd, REG_ITMP2,
- OFFSET(vftbl_t, baseval),
- REG_ITMP2);
+ M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
+ M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
+ M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
#if defined(ENABLE_THREADS)
codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
#endif
- emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
- emit_alu_reg_reg(cd, ALU_XOR, d, d); /* may be REG_ITMP2 */
- emit_alu_reg_reg(cd, ALU_CMP, REG_ITMP3, REG_ITMP1);
- emit_setcc_reg(cd, CC_BE, d);
+ M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
+ M_CMPULE(REG_ITMP1, REG_ITMP2, d);
}
- emit_store_dst(jd, iptr, d);
+ emit_store_dst(jd, iptr, d);
}
#endif
break;
Authors: Andreas Krall
Christian Thalinger
- $Id: codegen.h 7283 2007-02-04 19:41:14Z pm $
+ $Id: codegen.h 7300 2007-02-07 22:06:53Z pm $
*/
-#define ICONST(r,c) \
- do { \
- if ((c) == 0) \
- M_CLR((d)); \
- else \
- M_IMOV_IMM((c), (d)); \
- } while (0)
-/* do { \ */
-/* M_IMOV_IMM((c), (d)); \ */
-/* } while (0) */
-
-
#define LCONST(r,c) \
do { \
if ((c) == 0) \
#define BRANCH_NOPS \
do { \
M_NOP; \
- M_NOP; \
- M_NOP; \
- M_NOP; \
- M_NOP; \
} while (0)
/* some patcher defines *******************************************************/
-#define PATCHER_CALL_SIZE 5 /* size in bytes of a patcher call */
+#define PATCHER_CALL_SIZE 4 /* size in bytes of a patcher call */
#define PATCHER_NOPS \
do { \
M_NOP; \
- M_NOP; \
- M_NOP; \
- M_NOP; \
- M_NOP; \
} while (0)
+/* *** BIG TODO ***
+ * Make all this inline functions !!!!!!!!!!
+ */
/* macros to create code ******************************************************/
# define SZ_BCR SZ_RR
# define N_BR(r2) N_BCR(DD_ANY, r2)
# define SZ_BR SZ_BCR
-#define N_BC(m1, d2, x2, b2) N_RS(0x47, m1, d2, x2, b2)
+#define N_BC(m1, d2, x2, b2) N_RX(0x47, m1, d2, x2, b2)
# define SZ_BC SZ_RS
#define N_BCTR(r1, r2) N_RR(0x06, r1, _OR(r2))
#define N_BCT(r1, d2, x2, b2) N_RX(0x46, r1, d2, x2, b2)
#define M_FST(r, b, d) _IFNEG(d, assert(0), N_STE(r, d, RN, b))
#define M_IST(r, b, d) _IFNEG( \
d, \
- N_LHI(r, d); N_S(r, 0, r, b), \
- N_S(r, d, RN, b) \
+ N_LHI(r, d); N_ST(r, 0, r, b), \
+ N_ST(r, d, RN, b) \
)
#define M_AST(r, b, d) M_IST(r, b, d)
#define M_LST(r, b, d) _IFNEG( \
d, \
N_LHI(GET_LOW_REG(r), d); \
- N_S(GET_HIGH_REG(r), 0, GET_LOW_REG(r), b); \
- N_S(GET_LOW_REG(r), 4, GET_LOW_REG(r), b), \
- N_S(GET_HIGH_REG(r), 0, RN, b); N_S(GET_LOW_REG(r), 4, RN, b) \
+ N_ST(GET_HIGH_REG(r), 0, GET_LOW_REG(r), b); \
+ N_ST(GET_LOW_REG(r), 4, GET_LOW_REG(r), b), \
+ N_ST(GET_HIGH_REG(r), 0, RN, b); N_ST(GET_LOW_REG(r), 4, RN, b) \
)
#define M_TEST(r) N_LTR(r, r)
#define M_BEQ(off) N_BRC(DD_E, off)
#define M_BLE(off) N_BRC(DD_LE, off)
#define M_BGT(off) N_BRC(DD_H, off)
#define M_BLT(off) N_BRC(DD_L, off)
+#define M_BGE(off) N_BRC(DD_HE, off)
#define M_CMP(r1, r2) N_CR(r1, r2)
#define M_CLR(r) N_LHI(r, 0)
#define M_IADD_IMM(val, reg) N_AHI(reg, val)
#define M_ASUB_IMM(val, reg) N_AHI(reg, -(val))
#define M_RET N_BCR(DD_ANY, R14)
+#define M_BSR(ret_reg, disp) N_BRAS(ret_reg, disp)
+#define M_BR(disp) N_BRC(DD_ANY, disp)
+#define M_JMP(rd, rs) N_BCR(DD_ANY, rs)
+#define M_NOP N_BC(0, 0, RN, RN)
+
+#define ICONST(reg, i) \
+ do { \
+ if ((i) >= -32768 && (i) <= 32767) { \
+ N_LHI(reg, i); \
+ } else { \
+ disp = dseg_add_s4(cd, (i)); \
+ N_ILD(reg, REG_PV, disp); \
+ } \
+ } while (0)
/* M_INTMOVE:
generates an integer-move from register a to b.
#define M_ICMP_IMM_MEMBASE(a,b,c) _DEPR( M_ICMP_IMM_MEMBASE(a,b,c) )
#define M_ICMP_MEMBASE(a,b,c) _DEPR( M_ICMP_MEMBASE(a,b,c) )
-#define M_BGE(disp) _DEPR( M_BGE(disp) )
#define M_BAE(disp) _DEPR( M_BAE(disp) )
#define M_BA(disp) _DEPR( M_BA(disp) )
#define M_PUSH_IMM(a) _DEPR( M_PUSH_IMM(a) )
#define M_POP(a) _DEPR( M_POP(a) )
-#define M_JMP(a) _DEPR( M_JMP(a) )
#define M_JMP_IMM(a) _DEPR( M_JMP_IMM(a) )
#define M_CALL_IMM(a) _DEPR( M_CALL_IMM(a) )
-#define M_NOP _DEPR( M_NOP )
-
Authors: Christian Thalinger
- $Id: emit.c 7283 2007-02-04 19:41:14Z pm $
+ $Id: emit.c 7300 2007-02-07 22:06:53Z pm $
*/
void emit_exception_stubs(jitdata *jd)
{
+#if 0
codegendata *cd;
registerdata *rd;
exceptionref *er;
(cd->mcodeptr + PATCHER_CALL_SIZE));
}
}
+#endif
}
*******************************************************************************/
-void emit_patcher_stubs(jitdata *jd)
+__PORTED__ void emit_patcher_stubs(jitdata *jd)
{
+
codegendata *cd;
patchref *pref;
- u8 mcode;
+ u4 mcode;
u1 *savedmcodeptr;
u1 *tmpmcodeptr;
s4 targetdisp;
targetdisp = 0;
for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
- /* check size of code segment */
+ /* check code segment size */
- MCODECHECK(512);
+ MCODECHECK(100);
+
+ /* Get machine code which is patched back in later. The
+ call is 1 instruction word long. */
- /* Get machine code which is patched back in later. A
- `call rel32' is 5 bytes long (but read 8 bytes). */
+ tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
- savedmcodeptr = cd->mcodebase + pref->branchpos;
- mcode = *((u8 *) savedmcodeptr);
+ mcode = *((u4 *) tmpmcodeptr);
- /* patch in `call rel32' to call the following code */
+ /* Patch in the call to call the following code (done at
+ compile time). */
- tmpmcodeptr = cd->mcodeptr; /* save current mcodeptr */
- cd->mcodeptr = savedmcodeptr; /* set mcodeptr to patch position */
+ savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
+ cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
- M_CALL_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE));
+ disp = (savedmcodeptr) - (tmpmcodeptr);
+ M_BSR(REG_ITMP3, disp);
- cd->mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
+ cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
+
+ /* create stack frame */
+
+ M_ASUB_IMM(6 * 4, REG_SP);
+
+ /* move return address onto stack */
+
+ M_AST(REG_ITMP3, REG_SP, 5 * 4);
/* move pointer to java_objectheader onto stack */
(void) dseg_add_unique_address(cd, lock_get_initial_lock_word());
disp = dseg_add_unique_address(cd, NULL); /* vftbl */
- emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP3);
- M_PUSH(REG_ITMP3);
+ M_LDA(REG_ITMP3, REG_PV, disp);
+ M_AST(REG_ITMP3, REG_SP, 4 * 4);
#else
- M_PUSH_IMM(0);
+ /* nothing to do */
#endif
- /* move machine code bytes and classinfo pointer into registers */
+ /* move machine code onto stack */
- M_MOV_IMM(mcode, REG_ITMP3);
- M_PUSH(REG_ITMP3);
+ disp = dseg_add_s4(cd, mcode);
+ M_ILD(REG_ITMP3, REG_PV, disp);
+ M_IST(REG_ITMP3, REG_SP, 3 * 4);
- M_MOV_IMM(pref->ref, REG_ITMP3);
- M_PUSH(REG_ITMP3);
+ /* move class/method/field reference onto stack */
- M_MOV_IMM(pref->disp, REG_ITMP3);
- M_PUSH(REG_ITMP3);
+ disp = dseg_add_address(cd, pref->ref);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_AST(REG_ITMP3, REG_SP, 2 * 4);
- M_MOV_IMM(pref->patcher, REG_ITMP3);
- M_PUSH(REG_ITMP3);
+ /* move data segment displacement onto stack */
+
+ disp = dseg_add_s4(cd, pref->disp);
+ M_ILD(REG_ITMP3, REG_PV, disp);
+ M_IST(REG_ITMP3, REG_SP, 1 * 4);
+
+ /* move patcher function pointer onto stack */
+
+ disp = dseg_add_functionptr(cd, pref->patcher);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_AST(REG_ITMP3, REG_SP, 0 * 4);
if (targetdisp == 0) {
- targetdisp = cd->mcodeptr - cd->mcodebase;
+ targetdisp = (cd->mcodeptr) - (cd->mcodebase);
- M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
- M_JMP(REG_ITMP3);
+ disp = dseg_add_functionptr(cd, asm_patcher_wrapper);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_JMP(RN, REG_ITMP3);
}
else {
- M_JMP_IMM((cd->mcodebase + targetdisp) -
- (cd->mcodeptr + PATCHER_CALL_SIZE));
+ disp = ((cd->mcodebase) + targetdisp) -
+ (( cd->mcodeptr) );
+
+ M_BR(disp);
}
}
}
Changes:
- $Id: md-asm.h 7283 2007-02-04 19:41:14Z pm $
+ $Id: md-asm.h 7300 2007-02-07 22:06:53Z pm $
*/
movq (3+(off))*8(sp),ft2 ; \
movq (4+(off))*8(sp),ft3 ;
+#define LOAD_STORE_VOLATILE_FLOAT_REGISTERS(inst, off) \
+ inst %f0, ((0 * 8) + (off))(sp); \
+ inst %f2, ((1 * 8) + (off))(sp); \
+ inst %f1, ((2 * 8) + (off))(sp); \
+ inst %f3, ((3 * 8) + (off))(sp); \
+ inst %f5, ((4 * 8) + (off))(sp); \
+ inst %f7, ((5 * 8) + (off))(sp); \
+ inst %f8, ((6 * 8) + (off))(sp); \
+ inst %f9, ((7 * 8) + (off))(sp); \
+ inst %f10, ((8 * 8) + (off))(sp); \
+ inst %f11, ((9 * 8) + (off))(sp); \
+ inst %f12, ((10 * 8) + (off))(sp); \
+ inst %f13, ((11 * 8) + (off))(sp); \
+ inst %f14, ((12 * 8) + (off))(sp); \
+ inst %f15, ((13 * 8) + (off))(sp);
+
+#define VOLATILE_FLOAT_REGISTERS_SIZE (14 * 8)
+
+#define LOAD_VOLATILE_FLOAT_REGISTERS(off) LOAD_STORE_VOLATILE_FLOAT_REGISTERS(ld, off)
+#define STORE_VOLATILE_FLOAT_REGISTERS(off) LOAD_STORE_VOLATILE_FLOAT_REGISTERS(std, off)
+
+#define LOAD_STORE_VOLATILE_INTEGER_REGISTERS(instm, inst, off) \
+ instm %r0, %r5, ((0 * 4) + (off))(sp); \
+ inst %r14, ((6 * 4) + (off))(sp);
+#define VOLATILE_INTEGER_REGISTERS_SIZE (7 * 4)
+
+#define LOAD_VOLATILE_INTEGER_REGISTERS(off) LOAD_STORE_VOLATILE_INTEGER_REGISTERS(lm, l, off)
+#define STORE_VOLATILE_INTEGER_REGISTERS(off) LOAD_STORE_VOLATILE_INTEGER_REGISTERS(stm, st, off)
+
+
#endif /* _MD_ASM_H */
Changes:
- $Id: patcher.c 7219 2007-01-16 22:18:57Z pm $
+ $Id: patcher.c 7300 2007-02-07 22:06:53Z pm $
*/
#include "vm/resolve.h"
#include "vm/jit/patcher.h"
+#include <assert.h>
+#define OOPS() assert(0);
+#define __PORTED__
/* patcher_wrapper *************************************************************
/* get stuff from the stack */
- xpc = (u1 *) *((ptrint *) (sp + 5 * 8));
- o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
- f = (functionptr) *((ptrint *) (sp + 0 * 8));
+ xpc = (u1 *) *((ptrint *) (sp + 5 * 4));
+ o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
+ f = (functionptr) *((ptrint *) (sp + 0 * 4));
+
+ /* TODO here was PATCHER_CALL_SIZE previously ! */
+ xpc = xpc - 4; /* the patch position is 4 bytes before the RA */
- /* calculate and set the new return address */
+ *((ptrint *) (sp + 5 * 4)) = (ptrint) xpc;
- xpc = xpc - PATCHER_CALL_SIZE;
+ /* store PV into the patcher function position */
- *((ptrint *) (sp + 5 * 8)) = (ptrint) xpc;
+ *((ptrint *) (sp + 0 * 4)) = (ptrint) pv;
/* cast the passed function to a patcher function */
stacktrace_create_extern_stackframeinfo for
md_codegen_get_pv_from_pc. */
- stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 8, xpc, xpc);
+ stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 4, xpc, xpc);
/* call the proper patcher function */
Machine code:
- <patched call position>
- 4d 8b 15 86 fe ff ff mov -378(%rip),%r10
- 49 8b 32 mov (%r10),%rsi
-
*******************************************************************************/
bool patcher_get_putstatic(u1 *sp)
{
u1 *ra;
- u8 mcode;
+ u4 mcode;
unresolved_field *uf;
s4 disp;
fieldinfo *fi;
+ u1 *pv;
/* get stuff from the stack */
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
- disp = *((s4 *) (sp + 1 * 8));
+ ra = (u1 *) *((ptrint *) (sp + 5 * 4));
+ mcode = *((u4 *) (sp + 3 * 4));
+ uf = (unresolved_field *) *((ptrint *) (sp + 2 * 4));
+ disp = *((s4 *) (sp + 1 * 4));
+ pv = (u1 *) *((ptrint *) (sp + 0 * 4));
/* get the fieldinfo */
if (!initialize_class(fi->class))
return false;
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
+ *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
- /* if we show disassembly, we have to skip the nop's */
-
- if (opt_shownops)
- ra = ra + 5;
-
- /* patch the field value's address */
+ /* patch back original code */
- *((ptrint *) (ra + 7 + disp)) = (ptrint) &(fi->value);
+ *((u4 *) ra) = mcode;
return true;
}
bool patcher_get_putfield(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
unresolved_field *uf;
bool patcher_putfieldconst(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
unresolved_field *uf;
bool patcher_aconst(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
constant_classref *cr;
bool patcher_builtin_multianewarray(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
constant_classref *cr;
bool patcher_builtin_arraycheckcast(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
constant_classref *cr;
Machine code:
- <patched call position>
- 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
- 49 ff d2 callq *%r10
-
*******************************************************************************/
-bool patcher_invokestatic_special(u1 *sp)
+__PORTED__ bool patcher_invokestatic_special(u1 *sp)
{
u1 *ra;
- u8 mcode;
+ u4 mcode;
unresolved_method *um;
s4 disp;
+ u1 *pv;
methodinfo *m;
/* get stuff from the stack */
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
- disp = *((s4 *) (sp + 1 * 8));
+ ra = (u1 *) *((ptrint *) (sp + 5 * 4));
+ mcode = *((u4 *) (sp + 3 * 4));
+ um = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
+ disp = *((s4 *) (sp + 1 * 4));
+ pv = (u1 *) *((ptrint *) (sp + 0 * 4));
/* get the fieldinfo */
if (!(m = resolve_method_eager(um)))
return false;
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
+ *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
- /* if we show disassembly, we have to skip the nop's */
+ /* patch back original code */
- if (opt_shownops)
- ra = ra + 5;
+ *((u4 *) ra) = mcode;
/* patch stubroutine */
-/* *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine; */
- *((ptrint *) (ra + 7 + disp)) = (ptrint) m->stubroutine;
-
return true;
}
bool patcher_invokevirtual(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
unresolved_method *um;
bool patcher_invokeinterface(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
unresolved_method *um;
bool patcher_checkcast_instanceof_flags(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
constant_classref *cr;
bool patcher_checkcast_instanceof_interface(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
constant_classref *cr;
bool patcher_checkcast_class(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
constant_classref *cr;
bool patcher_instanceof_class(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
constant_classref *cr;
Machine code:
- <patched call position>
- 4d 8b 15 92 ff ff ff mov -110(%rip),%r10
- 49 89 1a mov %rbx,(%r10)
-
*******************************************************************************/
-bool patcher_clinit(u1 *sp)
+__PORTED__ bool patcher_clinit(u1 *sp)
{
u1 *ra;
- u8 mcode;
+ u4 mcode;
classinfo *c;
/* get stuff from the stack */
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- c = (classinfo *) *((ptrint *) (sp + 2 * 8));
+ ra = (u1 *) *((ptrint *) (sp + 5 * 4));
+ mcode = *((u4 *) (sp + 3 * 4));
+ c = (classinfo *) *((ptrint *) (sp + 2 * 4));
/* check if the class is initialized */
/* patch back original code */
- *((u8 *) ra) = mcode;
+ *((u4 *) ra) = mcode;
return true;
}
#ifdef ENABLE_VERIFIER
bool patcher_athrow_areturn(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
unresolved_class *uc;
#if !defined(WITH_STATIC_CLASSPATH)
bool patcher_resolve_native(u1 *sp)
{
+ OOPS();
u1 *ra;
u8 mcode;
methodinfo *m;