Skip to content

Commit

Permalink
Fix support for Linux/S390 zSeries
Browse files Browse the repository at this point in the history
  • Loading branch information
snaury committed Jan 25, 2012
1 parent bd29a4b commit cd1d887
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
43 changes: 37 additions & 6 deletions platform/switch_s390_unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
* this is the internal transfer function.
*
* HISTORY
* 25-Jan-12 Alexey Borzenkov <[email protected]>
* Fixed Linux/S390 port to work correctly with
* different optimization options both on 31-bit
* and 64-bit. Thanks to Stefan Raabe for lots
* of testing.
* 24-Nov-02 Christian Tismer <[email protected]>
* needed to add another magic constant to insure
* that f in slp_eval_frame(PyFrameObject *f)
Expand All @@ -15,24 +20,50 @@

#ifdef SLP_EVAL

#define STACK_MAGIC 0
#ifdef __s390x__
#define STACK_MAGIC 20 /* 20 * 8 = 160 bytes of function call area */
#else
#define STACK_MAGIC 24 /* 24 * 4 = 96 bytes of function call area */
#endif

#define REGS_TO_SAVE "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r14", \
/* Technically, r11-r13 also need saving, but function prolog starts
with stm(g) and since there are so many saved registers already
it won't be optimized, resulting in all r6-r15 being saved */
#define REGS_TO_SAVE "r6", "r7", "r8", "r9", "r10", "r14", \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15"

static int
slp_switch(void)
{
register int *stackref, stsizediff;
register long *stackref, stsizediff;
__asm__ volatile ("" : : : REGS_TO_SAVE);
__asm__ ("lr %0, 15" : "=g" (stackref) : );
#ifdef __s390x__
__asm__ volatile ("lgr %0, 15" : "=r" (stackref) : );
#else
__asm__ volatile ("lr %0, 15" : "=r" (stackref) : );
#endif
{
SLP_SAVE_STATE(stackref, stsizediff);
/* N.B.
r11 may be used as the frame pointer, and in that case it cannot be
clobbered and needs offsetting just like the stack pointer (but in cases
where frame pointer isn't used we might clobber it accidentally). What's
scary is that r11 is 2nd (and even 1st when GOT is used) callee saved
register that gcc would chose for surviving function calls. However,
since r6-r10 are clobbered above, their cost for reuse is reduced, so
gcc IRA will chose them over r11 (not seeing r11 is implicitly saved),
making it relatively safe to offset in all cases. :) */
__asm__ volatile (
"ar 15, %0"
#ifdef __s390x__
"agr 15, %0\n\t"
"agr 11, %0"
#else
"ar 15, %0\n\t"
"ar 11, %0"
#endif
: /* no outputs */
: "g" (stsizediff)
: "r" (stsizediff)
);
SLP_RESTORE_STATE();
}
Expand Down
2 changes: 1 addition & 1 deletion slp_platformselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#elif defined(__GNUC__) && defined(__s390__) && defined(__linux__)
#include "platform/switch_s390_unix.h" /* Linux/S390 */
#elif defined(__GNUC__) && defined(__s390x__) && defined(__linux__)
#include "platform/switch_s390_unix.h" /* Linux/S390 zSeries (identical) */
#include "platform/switch_s390_unix.h" /* Linux/S390 zSeries (64-bit) */
#elif defined(__GNUC__) && defined(__arm__)
#include "platform/switch_arm32_gcc.h" /* gcc using arm32 */
#elif defined(__GNUC__) && defined(__mips__) && defined(__linux__)
Expand Down

0 comments on commit cd1d887

Please sign in to comment.