From: pm Date: Wed, 7 Feb 2007 22:06:53 +0000 (+0000) Subject: Continued work on S390 port. java.lang.ClassLoader.getSystemClassLoader is now compil... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=336affb205331c3c74f35301afe59ba480137103;p=cacao.git Continued work on S390 port. java.lang.ClassLoader.getSystemClassLoader is now compiled, patched, called and the patcher trigger compilation of another method. * 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. --- diff --git a/src/vm/jit/codegen-common.c b/src/vm/jit/codegen-common.c index 2eb113e71..4b2f40c5e 100644 --- a/src/vm/jit/codegen-common.c +++ b/src/vm/jit/codegen-common.c @@ -39,7 +39,7 @@ 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 $ */ @@ -477,7 +477,7 @@ void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref, 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) diff --git a/src/vm/jit/s390/asmpart.S b/src/vm/jit/s390/asmpart.S index 4884bbe6d..13a4db9e2 100644 --- a/src/vm/jit/s390/asmpart.S +++ b/src/vm/jit/s390/asmpart.S @@ -30,7 +30,7 @@ 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 $ */ @@ -109,7 +109,6 @@ asm_call_jit_compiler: asm_handle_exception: asm_handle_nat_exception: asm_abstractmethoderror: -asm_patcher_wrapper: asm_replacement_out: asm_replacement_in: asm_builtin_f2i: @@ -502,11 +501,11 @@ L_asm_call_jit_compiler: /* 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 */ @@ -693,62 +692,73 @@ asm_abstractmethoderror: 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 ********************************************************* diff --git a/src/vm/jit/s390/codegen.c b/src/vm/jit/s390/codegen.c index 595c48e58..57bc1f200 100644 --- a/src/vm/jit/s390/codegen.c +++ b/src/vm/jit/s390/codegen.c @@ -29,7 +29,7 @@ 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 $ */ @@ -238,7 +238,7 @@ bool codegen(jitdata *jd) 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); @@ -510,12 +510,9 @@ bool codegen(jitdata *jd) /* 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 */ @@ -2152,11 +2149,6 @@ bool codegen(jitdata *jd) 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); @@ -2173,9 +2165,6 @@ bool codegen(jitdata *jd) codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0); - if (opt_shownops) - disp -= PATCHER_CALL_SIZE; - PROFILE_CYCLE_START; } } @@ -2210,68 +2199,47 @@ bool codegen(jitdata *jd) 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: /* ... ==> ... */ @@ -2498,11 +2466,10 @@ bool codegen(jitdata *jd) 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: /* ... ==> ... */ @@ -2521,7 +2488,6 @@ bool codegen(jitdata *jd) break; case ICMD_IFNONNULL: /* ..., value ==> ... */ - OOPS(); s1 = emit_load_s1(jd, iptr, REG_ITMP1); M_TEST(s1); M_BNE(0); @@ -2529,63 +2495,44 @@ bool codegen(jitdata *jd) 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 ==> ... */ @@ -3439,8 +3386,7 @@ gen_method: case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */ OOPS(); #if 0 - - /* val.a: (classinfo *) superclass */ + /* val.a: (classinfo*) superclass */ /* superclass is an interface: * @@ -3472,137 +3418,109 @@ gen_method: } #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; diff --git a/src/vm/jit/s390/codegen.h b/src/vm/jit/s390/codegen.h index 130f4d0a0..6951e5d3f 100644 --- a/src/vm/jit/s390/codegen.h +++ b/src/vm/jit/s390/codegen.h @@ -27,7 +27,7 @@ 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 $ */ @@ -92,18 +92,6 @@ -#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) \ @@ -117,26 +105,21 @@ #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 ******************************************************/ @@ -365,7 +348,7 @@ # 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) @@ -535,16 +518,16 @@ #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) @@ -552,6 +535,7 @@ #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) @@ -559,6 +543,20 @@ #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. @@ -700,7 +698,6 @@ #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) ) @@ -726,12 +723,9 @@ #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 ) - diff --git a/src/vm/jit/s390/emit.c b/src/vm/jit/s390/emit.c index 40444916b..a93fab1d3 100644 --- a/src/vm/jit/s390/emit.c +++ b/src/vm/jit/s390/emit.c @@ -26,7 +26,7 @@ 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 $ */ @@ -212,6 +212,7 @@ void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d) void emit_exception_stubs(jitdata *jd) { +#if 0 codegendata *cd; registerdata *rd; exceptionref *er; @@ -278,6 +279,7 @@ void emit_exception_stubs(jitdata *jd) (cd->mcodeptr + PATCHER_CALL_SIZE)); } } +#endif } @@ -287,11 +289,12 @@ void emit_exception_stubs(jitdata *jd) *******************************************************************************/ -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; @@ -306,24 +309,35 @@ void emit_patcher_stubs(jitdata *jd) 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 */ @@ -334,35 +348,48 @@ void emit_patcher_stubs(jitdata *jd) (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); } } } diff --git a/src/vm/jit/s390/md-asm.h b/src/vm/jit/s390/md-asm.h index a4e5adc36..41447ae18 100644 --- a/src/vm/jit/s390/md-asm.h +++ b/src/vm/jit/s390/md-asm.h @@ -28,7 +28,7 @@ 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 $ */ @@ -178,6 +178,36 @@ 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 */ diff --git a/src/vm/jit/s390/patcher.c b/src/vm/jit/s390/patcher.c index c28528f59..dcef11da2 100644 --- a/src/vm/jit/s390/patcher.c +++ b/src/vm/jit/s390/patcher.c @@ -28,7 +28,7 @@ Changes: - $Id: patcher.c 7219 2007-01-16 22:18:57Z pm $ + $Id: patcher.c 7300 2007-02-07 22:06:53Z pm $ */ @@ -50,6 +50,9 @@ #include "vm/resolve.h" #include "vm/jit/patcher.h" +#include +#define OOPS() assert(0); +#define __PORTED__ /* patcher_wrapper ************************************************************* @@ -77,15 +80,18 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) /* 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 */ @@ -101,7 +107,7 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) 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 */ @@ -131,26 +137,24 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra) Machine code: - - 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 */ @@ -163,18 +167,11 @@ bool patcher_get_putstatic(u1 *sp) 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; } @@ -191,6 +188,7 @@ bool patcher_get_putstatic(u1 *sp) bool patcher_get_putfield(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; unresolved_field *uf; @@ -257,6 +255,7 @@ bool patcher_get_putfield(u1 *sp) bool patcher_putfieldconst(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; unresolved_field *uf; @@ -320,6 +319,7 @@ bool patcher_putfieldconst(u1 *sp) bool patcher_aconst(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; constant_classref *cr; @@ -368,6 +368,7 @@ bool patcher_aconst(u1 *sp) bool patcher_builtin_multianewarray(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; constant_classref *cr; @@ -414,6 +415,7 @@ bool patcher_builtin_multianewarray(u1 *sp) bool patcher_builtin_arraycheckcast(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; constant_classref *cr; @@ -451,46 +453,38 @@ bool patcher_builtin_arraycheckcast(u1 *sp) Machine code: - - 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; } @@ -508,6 +502,7 @@ bool patcher_invokestatic_special(u1 *sp) bool patcher_invokevirtual(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; unresolved_method *um; @@ -556,6 +551,7 @@ bool patcher_invokevirtual(u1 *sp) bool patcher_invokeinterface(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; unresolved_method *um; @@ -608,6 +604,7 @@ bool patcher_invokeinterface(u1 *sp) bool patcher_checkcast_instanceof_flags(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; constant_classref *cr; @@ -656,6 +653,7 @@ bool patcher_checkcast_instanceof_flags(u1 *sp) bool patcher_checkcast_instanceof_interface(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; constant_classref *cr; @@ -708,6 +706,7 @@ bool patcher_checkcast_instanceof_interface(u1 *sp) bool patcher_checkcast_class(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; constant_classref *cr; @@ -753,6 +752,7 @@ bool patcher_checkcast_class(u1 *sp) bool patcher_instanceof_class(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; constant_classref *cr; @@ -792,23 +792,19 @@ bool patcher_instanceof_class(u1 *sp) Machine code: - - 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 */ @@ -818,7 +814,7 @@ bool patcher_clinit(u1 *sp) /* patch back original code */ - *((u8 *) ra) = mcode; + *((u4 *) ra) = mcode; return true; } @@ -835,6 +831,7 @@ bool patcher_clinit(u1 *sp) #ifdef ENABLE_VERIFIER bool patcher_athrow_areturn(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; unresolved_class *uc; @@ -873,6 +870,7 @@ bool patcher_athrow_areturn(u1 *sp) #if !defined(WITH_STATIC_CLASSPATH) bool patcher_resolve_native(u1 *sp) { + OOPS(); u1 *ra; u8 mcode; methodinfo *m;