Author: Richard Plangger <planri...@gmail.com> Branch: s390x-backend Changeset: r81749:6d185183c341 Date: 2016-01-13 22:01 +0100 http://bitbucket.org/pypy/pypy/changeset/6d185183c341/
Log: seems like i got rid of this nasty SIGFPE (fix point overflow), the register was dirty which could have lead to accidentally setting the FPE bit in PSW copied the stacklet switch header file, saved registers but need to convert the rest as well diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py --- a/rpython/jit/backend/zarch/opassembler.py +++ b/rpython/jit/backend/zarch/opassembler.py @@ -82,6 +82,7 @@ jmp_xor_lr_overflow = mc.get_relative_pos() mc.reserve_cond_jump() # CLGIJ lr > 0 -> (label_overflow) mc.LCGR(lq, lq) # complement the value + mc.XGR(r.SCRATCH, r.SCRATCH) mc.SPM(r.SCRATCH) # 0x80 ... 00 clears the condition code and program mask jmp_no_overflow_xor_neg = mc.get_relative_pos() mc.reserve_cond_jump(short=True) @@ -102,8 +103,8 @@ # set overflow! label_overflow = mc.get_relative_pos() + # set bit 34 & 35 -> indicates overflow mc.XGR(r.SCRATCH, r.SCRATCH) - # set bit 34 & 35 -> indicates overflow mc.OILH(r.SCRATCH, l.imm(0x3000)) # sets OF mc.SPM(r.SCRATCH) diff --git a/rpython/jit/backend/zarch/test/test_assembler.py b/rpython/jit/backend/zarch/test/test_assembler.py --- a/rpython/jit/backend/zarch/test/test_assembler.py +++ b/rpython/jit/backend/zarch/test/test_assembler.py @@ -177,6 +177,16 @@ self.a.jmpto(r.r14) assert run_asm(self.a) == -1 + def test_or_bitpos_0to15(self): + self.a.mc.XGR(r.r2, r.r2) + self.a.mc.OIHH(r.r2, loc.imm(0x0000)) + self.a.mc.OIHL(r.r2, loc.imm(0x0000)) + self.a.mc.OILL(r.r2, loc.imm(0x0000)) + self.a.mc.OILH(r.r2, loc.imm(0x300c)) + self.a.jmpto(r.r14) + res = run_asm(self.a) + assert res == 0x00000000300c0000 + def test_uint_rshift(self): self.a.mc.XGR(r.r4, r.r4) self.a.mc.LGFI(r.r5, loc.imm(63)) @@ -187,6 +197,16 @@ self.a.jmpto(r.r14) assert run_asm(self.a) == 0 + def test_ag_overflow(self): + self.a.mc.BRC(con.ANY, loc.imm(4+8+8)) + self.a.mc.write('\x7f' + '\xff' * 7) + self.a.mc.write('\x7f' + '\xff' * 7) + self.a.mc.LARL(r.r5, loc.imm(-8)) + self.a.mc.LG(r.r4, loc.addr(8,r.r5)) + self.a.mc.AG(r.r4, loc.addr(0,r.r5)) + self.a.jmpto(r.r14) + assert run_asm(self.a) == 0 + def test_xor(self): self.a.mc.XGR(r.r2, r.r2) self.a.jmpto(r.r14) diff --git a/rpython/translator/c/src/stacklet/slp_platformselect.h b/rpython/translator/c/src/stacklet/slp_platformselect.h --- a/rpython/translator/c/src/stacklet/slp_platformselect.h +++ b/rpython/translator/c/src/stacklet/slp_platformselect.h @@ -14,6 +14,8 @@ #include "switch_ppc64_gcc.h" /* gcc on ppc64 */ #elif defined(__GNUC__) && defined(__mips__) && defined(_ABI64) #include "switch_mips64_gcc.h" /* gcc on mips64 */ +#elif defined(__GNUC__) && defined(__s390x__) && defined(_ABI64) +#include "switch_s390x_gcc.h" #else #error "Unsupported platform!" #endif diff --git a/rpython/translator/c/src/stacklet/switch_s390x_gcc.h b/rpython/translator/c/src/stacklet/switch_s390x_gcc.h new file mode 100644 --- /dev/null +++ b/rpython/translator/c/src/stacklet/switch_s390x_gcc.h @@ -0,0 +1,114 @@ +#if !(defined(__LITTLE_ENDIAN__) ^ defined(__BIG_ENDIAN__)) +# error "cannot determine if it is ppc64 or ppc64le" +#endif + +#ifdef __BIG_ENDIAN__ +# define TOC_AREA "40" +#else +# define TOC_AREA "24" +#endif + + +/* This depends on these attributes so that gcc generates a function + with no code before the asm, and only "blr" after. */ +static __attribute__((noinline, optimize("O2"))) +void *slp_switch(void *(*save_state)(void*, void*), + void *(*restore_state)(void*, void*), + void *extra) +{ + void *result; + __asm__ volatile ( + /* By Vaibhav Sood & Armin Rigo, with some copying from + the Stackless version by Kristjan Valur Jonsson */ + + /* Save all 18 volatile GP registers, 18 volatile FP regs, and 12 + volatile vector regs. We need a stack frame of 144 bytes for FPR, + 144 bytes for GPR, 192 bytes for VR plus 48 bytes for the standard + stackframe = 528 bytes (a multiple of 16). */ + + //"mflr 0\n" /* Save LR into 16(r1) */ + //"stg 0, 16(1)\n" + + "stmg 6,15,48(15)\n" + + "std 0,128(15)\n" + "std 2,136(15)\n" + "std 4,144(15)\n" + "std 6,152(15)\n" + + "lay 15,-160(15)\n" /* Create stack frame */ + + "lgr 10, %[restore_state]\n" /* save 'restore_state' for later */ + "lgr 11, %[extra]\n" /* save 'extra' for later */ + "lgr 14, %[save_state]\n" /* move 'save_state' into r14 for branching */ + "mr 2, 15\n" /* arg 1: current (old) stack pointer */ + "mr 3, 11\n" /* arg 2: extra */ + + "stdu 1, -48(1)\n" /* create temp stack space (see below) */ +#ifdef __BIG_ENDIAN__ + "ld 0, 0(12)\n" + "ld 11, 16(12)\n" + "mtctr 0\n" + "ld 2, 8(12)\n" +#else + "mtctr 12\n" /* r12 is fixed by this ABI */ +#endif + "bctrl\n" /* call save_state() */ + "addi 1, 1, 48\n" /* destroy temp stack space */ + + "CGIJ 2, 0, 7, zero\n" /* skip the rest if the return value is null */ + + "lgr 15, 2\n" /* change the stack pointer */ + /* From now on, the stack pointer is modified, but the content of the + stack is not restored yet. It contains only garbage here. */ + + "mr 4, 15\n" /* arg 2: extra */ + /* arg 1: current (new) stack pointer + is already in r3 */ + + "stdu 1, -48(1)\n" /* create temp stack space for callee to use */ + /* ^^^ we have to be careful. The function call will store the link + register in the current frame (as the ABI) dictates. But it will + then trample it with the restore! We fix this by creating a fake + stack frame */ + +#ifdef __BIG_ENDIAN__ + "ld 0, 0(14)\n" /* 'restore_state' is in r14 */ + "ld 11, 16(14)\n" + "mtctr 0\n" + "ld 2, 8(14)\n" +#endif +#ifdef __LITTLE_ENDIAN__ + "mr 12, 14\n" /* copy 'restore_state' */ + "mtctr 12\n" /* r12 is fixed by this ABI */ +#endif + + "bctrl\n" /* call restore_state() */ + "addi 1, 1, 48\n" /* destroy temp stack space */ + + /* The stack's content is now restored. */ + + "zero:\n" + + /* Epilogue */ + + // "mtcrf 0xff, 12\n" + + // "addi 1,1,528\n" + + "lay 15,160(15)\n" /* restore stack pointer */ + + "ld 0,128(15)\n" + "ld 2,136(15)\n" + "ld 4,144(15)\n" + "ld 6,152(15)\n" + + "lmg 6,15,48(15)\n" + + : "=r"(result) /* output variable: expected to be r2 */ + : [restore_state]"r"(restore_state), /* input variables */ + [save_state]"r"(save_state), + [extra]"r"(extra) + ); + return result; +} _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit