* src/vm/jit/codegen-common.c (methodtree_comparator): On s390 compare addresses as 31 bit integers.
* src/vm/jit/s390/md.c,
src/vm/jit/s390/codegen.c,
src/vm/jit/s390/codegen.h,
src/vm/jit/s390/patcher.c,
src/vm/jit/s390/asmpart.S: Changed a lot, working on s390 port.
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 7300 2007-02-07 22:06:53Z pm $
+ $Id: codegen-common.c 7323 2007-02-11 17:52:12Z pm $
*/
#include "vm/jit/dseg.h"
#include "vm/jit/jit.h"
-#include "vm/jit/md.h"
#include "vm/jit/stacktrace.h"
#include "vm/jit/replace.h"
otherwise the avl_probe sometimes thinks the element is already in the
tree */
- if ((long) mte->startpc <= (long) mtepc->startpc &&
- (long) mtepc->startpc <= (long) mte->endpc &&
- (long) mte->startpc <= (long) mtepc->endpc &&
- (long) mtepc->endpc <= (long) mte->endpc) {
+#ifdef __S390__
+ /* On S390 addresses are 31 bit, and therefore are ambigue. */
+# define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
+#else
+# define ADDR_MASK(a) (a)
+#endif
+
+ if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
+ ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
+ ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
+ ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
return 0;
- } else if ((long) mtepc->startpc < (long) mte->startpc) {
+ } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
return -1;
} else {
return 1;
}
+
+# undef ADDR_MASK
}
Changes: Edwin Steiner
- $Id: asmpart.S 7313 2007-02-10 14:31:03Z pm $
+ $Id: asmpart.S 7323 2007-02-11 17:52:12Z pm $
*/
* void *arg1, void *arg2, void *arg3, void *arg4); *
* *
*******************************************************************************/
- .align 8
- .quad 0 /* catch type all */
- .quad 0 /* handler pc */
- .quad 0 /* end pc */
- .quad 0 /* start pc */
+ .long 0 /* catch type all */
+ .long 0 /* handler pc */
+ .long 0 /* end pc */
+ .long 0 /* start pc */
.long 1 /* extable size */
.long 0 /* ALIGNMENT PADDING */
- .quad 0 /* line number table start */
- .quad 0 /* line number table size */
+ .long 0 /* line number table start */
+ .long 0 /* line number table size */
.long 0 /* ALIGNMENT PADDING */
.long 0 /* fltsave */
.long 0 /* intsave */
.long 0 /* isleaf */
.long 0 /* IsSync */
.long 0 /* frame size */
- .quad 0 /* codeinfo pointer */
+ .long 0 /* codeinfo pointer */
asm_vm_call_method:
*/
stm %r6, %r15, 24(sp) /* save callers regiters */
- ahi sp, -16 /* allocate stack space for local variables */
- stm a0, a2, 0(sp) /* save arguments */
+ stm a0, a2, 8(sp) /* save arguments */
+ ahi sp, -4 /* allocate stack space for local variables */
ltr a1, a1 /* maybe we have no args... */
je L_no_args
sr s4, s0 /* - integer arguments in registers */
sr s4, s1 /* - float arguments in registers */
+ lr s3, sp /* backup stack pointer (does not alter CC) */
+
je L_copy_done /* no arguments left for stack */
sll s4, 3 /* allocate 8 bytes per parameter on stack */
- lr s3, sp /* backup stack pointer */
sr sp, s4 /* allocate stack space for arguments */
lr s2, sp /* points now to current argument on stack */
tm offvmargtype(itmp1), 0x01 /* is this a 2 word type ? */
jne L_stack_handle_long
- mvc 0(4, s2), offvmargdata(itmp1) /* copy integer value */
+ mvc 0(4, s2), offvmargdata+4(itmp1) /* copy integer value */
ahi s2, 4
j L_stack_copy_loop
basr mptr, 0 /* store PC */
L_basr:
la mptr, L_asm_call_jit_compiler-L_basr(mptr) /* add offset to PC */
- st mptr, 12(s3) /* store on stack */
+ st mptr, 0(s3) /* store on stack */
- l itmp1, 0(s3) /* load methodinfo for compiler */
- la mptr, 12(s3) /* store **function in mptr for compiler */
+ l itmp1, 4+8(s3) /* load methodinfo for compiler */
+ la mptr, 0(s3) /* store **function in mptr for compiler */
/* call L_asm_call_jit_compiler like JIT code would do */
L_asm_vm_call_method_return:
- ahi sp, 16 /* remove stack space for local variables */
+ ahi sp, 4 /* remove stack space for local variables */
lm %r6, %r15, 24(sp) /* restore callers registers */
br %r14 /* return */
j L_copy_done
L_handle_i0:
- l a0, offvmargdata(itmp1)
+ l a0, offvmargdata+4(itmp1)
j L_register_copy
L_handle_i1:
- l a1, offvmargdata(itmp1)
+ l a1, offvmargdata+4(itmp1)
j L_register_copy
L_handle_i2:
- l a2, offvmargdata(itmp1)
+ l a2, offvmargdata+4(itmp1)
j L_register_copy
L_handle_i3:
- l a3, offvmargdata(itmp1)
+ l a3, offvmargdata+4(itmp1)
j L_register_copy
L_handle_i4:
- l a4, offvmargdata(itmp1)
+ l a4, offvmargdata+4(itmp1)
j L_register_copy
L_handle_l0:
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 7313 2007-02-10 14:31:03Z pm $
+ $Id: codegen.c 7323 2007-02-11 17:52:12Z pm $
*/
s4 i, p, t, l;
s4 savedregs_num;
- savedregs_num = 1; /* space to save RA */
+ savedregs_num = 0;
/* space to save used callee saved registers */
savedregs_num += (INT_SAV_CNT - rd->savintreguse);
savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
- cd->stackframesize = rd->memuse + savedregs_num;
+ cd->stackframesize = rd->memuse + savedregs_num + 1 /* space to save RA */;
/* CAUTION:
* As REG_ITMP3 == REG_RA, do not touch REG_ITMP3, until it has been saved.
(void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync */
else
#endif
- (void) dseg_add_unique_s4(cd, 0); /* IsSync */
-
+/*
+ (void) dseg_add_unique_s4(cd, 0);*/ /* IsSync */
+
+ disp = dseg_add_unique_address(cd, 0);
+
(void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
(void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
(void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
if (cd->stackframesize)
M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
+ N_LHI(REG_ITMP2, disp);
+ N_ST(REG_SP, 0, REG_ITMP2, REG_PV);
+
/* save used callee saved registers and return address */
p = cd->stackframesize;
case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
- OOPS();
-#if 0
+
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_IADD(s2, d);
}
emit_store_dst(jd, iptr, d);
-#endif
+
break;
case ICMD_IINC:
break;
case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
- OOPS();
-#if 0
+
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_ISUB(s2, d);
}
emit_store_dst(jd, iptr, d);
-#endif
+
break;
case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
break;
case ICMD_GETFIELD: /* ... ==> ..., value */
- OOPS();
-#if 0
+
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
disp = 0;
-/* PROFILE_CYCLE_STOP; */
-
- codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
-
-/* PROFILE_CYCLE_START; */
+ codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
}
else {
fi = iptr->sx.s23.s3.fmiref->p.field;
switch (fieldtype) {
case TYPE_INT:
- d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- M_ILD32(d, s1, disp);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+ M_ILD(d, s1, disp);
break;
case TYPE_LNG:
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ if (GET_HIGH_REG(d) == s1) {
+ M_ILD(GET_LOW_REG(d), s1, disp + 4);
+ M_ILD(GET_HIGH_REG(d), s1, disp);
+ }
+ else {
+ M_ILD(GET_HIGH_REG(d), s1, disp);
+ M_ILD(GET_LOW_REG(d), s1, disp + 4);
+ }
+ break;
case TYPE_ADR:
- d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
- M_LLD32(d, s1, disp);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+ M_ALD(d, s1, disp);
break;
case TYPE_FLT:
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- M_FLD32(d, s1, disp);
+ M_FLD(d, s1, disp);
break;
case TYPE_DBL:
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- M_DLD32(d, s1, disp);
+ M_DLD(d, s1, disp);
break;
}
emit_store_dst(jd, iptr, d);
-#endif
break;
case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
/* create method header */
(void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
- (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
+ (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
(void) dseg_add_unique_s4(cd, 0); /* IsSync */
(void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
(void) dseg_add_unique_s4(cd, 0); /* IntSave */
/* get function address (this must happen before the stackframeinfo) */
+ disp = dseg_add_functionptr(cd, f);
+
#if !defined(WITH_STATIC_CLASSPATH)
if (f == NULL)
- codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
+ codegen_add_patch_ref(cd, PATCHER_resolve_native, m, disp);
#endif
- disp = dseg_add_functionptr(cd, f);
M_ILD(REG_ITMP1, REG_PV, disp);
j = 96 + (nmd->memuse * 4);
M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
M_JMP(REG_ITMP3);
+#endif
/* generate patcher stubs */
emit_patcher_stubs(jd);
-#endif
codegen_finish(jd);
return code->entrypoint;
Authors: Andreas Krall
Christian Thalinger
- $Id: codegen.h 7313 2007-02-10 14:31:03Z pm $
+ $Id: codegen.h 7323 2007-02-11 17:52:12Z pm $
*/
N_L(GET_HIGH_REG(r), 0, RN, b); N_L(GET_LOW_REG(r), 4, RN, b) \
)
-#define M_MOV(a, b) N_LR(a, b)
-#define M_FMOV(a, b) N_LDR(a, b)
+/* MOV(a, b) -> mov from A to B */
+
+#define M_MOV(a, b) N_LR(b, a)
+#define M_FMOV(a, b) N_LDR(b, a)
#define M_DST(r, b, d) _IFNEG(d, assert(0), N_STD(r, d, RN, b))
#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_ST(r, 0, r, b), \
+ assert(0), \
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_ST(GET_HIGH_REG(r), 0, GET_LOW_REG(r), b); \
- N_ST(GET_LOW_REG(r), 4, GET_LOW_REG(r), b), \
+ assert(0), \
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_JMP(rd, rs) N_BCR(DD_ANY, rs)
#define M_NOP N_BC(0, 0, RN, RN)
#define M_JSR(reg_ret, reg_addr) N_BASR(reg_ret, reg_addr)
-#define M_ISUB(a, b) N_SR(a, b)
#define M_ICMP(a, b) N_CR(a, b)
#define M_CVTIF(src, dst) N_CEFBR(dst, src)
#define M_CVTID(src, dst) N_CEDBR(dst, src)
#define M_FMUL(a, dest) N_MEEBR(dest, a)
#define M_CVTFI(src, dst) N_CFEBR(dst, 5, src)
+#define M_IADD(a, dest) N_AR(dest, a)
+#define M_ISUB(a, dest) N_SR(dest, a)
#define ICONST(reg, i) \
do { \
#define M_IST32_IMM(a,b,disp) _DEPR( M_IST32_IMM(a,b,disp) )
#define M_LST32_IMM32(a,b,disp) _DEPR( M_LST32_IMM32(a,b,disp) )
-#define M_IADD(a,b) _DEPR( M_IADD(a,b) )
#define M_IMUL(a,b) _DEPR( M_IMUL(a,b) )
#define M_IMUL_IMM(a,b,c) _DEPR( M_IMUL_IMM(a,b,c) )
Changes: Edwin Steiner
- $Id: md.c 7283 2007-02-04 19:41:14Z pm $
+ $Id: md.c 7323 2007-02-11 17:52:12Z pm $
*/
u1 *ra;
/* on S390 the return address is located on the top of the stackframe */
- /* TODO is this true? hope so, copyed from alpha */
ra = *((u1 **) (sp + framesize - SIZEOF_VOID_P));
Changes:
- $Id: patcher.c 7312 2007-02-10 00:49:37Z pm $
+ $Id: patcher.c 7323 2007-02-11 17:52:12Z pm $
*/
/* patcher_resolve_native ******************************************************
- Machine code:
-
- <patched call position>
- 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
- 48 ff d0 callq *%rax
-
*******************************************************************************/
#if !defined(WITH_STATIC_CLASSPATH)
-bool patcher_resolve_native(u1 *sp)
+__PORTED__ bool patcher_resolve_native(u1 *sp)
{
- OOPS();
u1 *ra;
- u8 mcode;
+ u4 mcode;
methodinfo *m;
functionptr f;
+ s4 disp;
+ u1 *pv;
/* get stuff from the stack */
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
+ ra = (u1 *) *((ptrint *) (sp + 5 * 4));
+ mcode = *((u4 *) (sp + 3 * 4));
+ disp = *((s4 *) (sp + 1 * 4));
+ m = (methodinfo *) *((ptrint *) (sp + 2 * 4));
+ pv = (u1 *) *((ptrint *) (sp + 0 * 4));
/* resolve native function */
if (!(f = native_resolve_function(m)))
return false;
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
+ /* patch native function pointer */
- /* if we show disassembly, we have to skip the nop's */
+ *((ptrint *) (pv + disp)) = (ptrint) f;
- if (opt_shownops)
- ra = ra + 5;
-
- /* patch native function pointer */
+ /* patch back original code */
- *((ptrint *) (ra + 2)) = (ptrint) f;
+ *((u4 *) ra) = mcode;
return true;
}
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: stacktrace.c 7246 2007-01-29 18:49:05Z twisti $
+ $Id: stacktrace.c 7323 2007-02-11 17:52:12Z pm $
*/
u1 *sp, u1 *ra, u1 *xpc)
{
stackframeinfo **psfi;
-#if !defined(__I386__) && !defined(__X86_64__)
+#if !defined(__I386__) && !defined(__X86_64__) && !defined(__S390__)
bool isleafmethod;
#endif
#if defined(ENABLE_JIT)
if (!opt_intrp) {
# endif
-# if defined(__I386__) || defined(__X86_64__)
+# if defined(__I386__) || defined(__X86_64__) || defined(__S390__)
/* On i386 and x86_64 we always have to get the return address
from the stack. */
+ /* On S390 we use REG_RA as REG_ITMP3, so we have always to get
+ the RA from stack. */
framesize = *((u4 *) (pv + FrameSize));