X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStgCRun.c;h=fb7179f75eff1e43d2f239c5c5bee0c5f3081b54;hb=2c5525a9fae00927d8068dc5294421868350daf9;hp=3f9273a779e3052ed2b9b31b3b34911f4c1400df;hpb=6e1e8a09b49cf7ceca35d990ad934cfc661e823f;p=ghc-hetmet.git diff --git a/ghc/rts/StgCRun.c b/ghc/rts/StgCRun.c index 3f9273a..fb7179f 100644 --- a/ghc/rts/StgCRun.c +++ b/ghc/rts/StgCRun.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: StgCRun.c,v 1.28 2002/02/06 15:48:56 sewardj Exp $ + * $Id: StgCRun.c,v 1.39 2003/06/09 13:17:41 matthewc Exp $ * * (c) The GHC Team, 1998-2000 * @@ -54,6 +54,7 @@ #ifdef alpha_TARGET_ARCH #define alpha_EXTRA_CAREFUL register long fake_ra __asm__("$26"); +register long fake_gp __asm__("$29"); #ifdef alpha_EXTRA_CAREFUL register long fake_s6 __asm__("$15"); register double fake_f8 __asm__("$f8"); @@ -80,12 +81,12 @@ register double fake_f9 __asm__("$f9"); any architecture (using miniinterpreter) -------------------------------------------------------------------------- */ -extern StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg) +extern StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg STG_UNUSED) { while (f) { - IF_DEBUG(evaluator, + IF_DEBUG(interpreter, fprintf(stderr,"Jumping to "); - printPtr((P_)f); + printPtr((P_)f); fflush(stdout); fprintf(stderr,"\n"); ); f = (StgFunPtr) (f)(); @@ -115,8 +116,6 @@ EXTFUN(StgReturn) StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg) { - static volatile void* stg_esp_saved_before_stack_align; - unsigned char space[ RESERVED_C_STACK_BYTES + 4*sizeof(void *) ]; StgThreadReturnCode r; @@ -125,7 +124,7 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { * save callee-saves registers on behalf of the STG code. */ "movl %%esp, %%eax\n\t" - "addl %5, %%eax\n\t" + "addl %4, %%eax\n\t" "movl %%ebx,0(%%eax)\n\t" "movl %%esi,4(%%eax)\n\t" "movl %%edi,8(%%eax)\n\t" @@ -133,53 +132,30 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { /* * Set BaseReg */ - "movl %4,%%ebx\n\t" + "movl %3,%%ebx\n\t" /* - * grab the function argument from the stack - */ - "movl %3,%%eax\n\t" - /* - * Get %%esp 8-aligned, first saving the current value. This - * moves it down another zero or four bytes, depending on - * whether it was already aligned or not. This is a bit - * subtle -- we must not have a swizzled %esp at any place - * where we might refer to one of the %digit parameters to - * this piece of assembly code, since gcc may generate - * %esp-relative stack offsets which will then be wrong. - */ - "movl %%esp, %6\n\t" - "subl $4, %%esp\n\t" - "andl $0xFFFFFFF8, %%esp\n\t" - /* - * And finally, jump to the function argument. + * grab the function argument from the stack, and jump to it. */ + "movl %2,%%eax\n\t" "jmp *%%eax\n\t" ".global " STG_RETURN "\n" STG_RETURN ":\n\t" - /* - * Restore %%esp to pre-alignment state. - */ - "movl %2, %%esp\n" - /* - * Move return value from R1 to %%eax - */ - "movl %%esi, %%eax\n\t" + + "movl %%esi, %%eax\n\t" /* Return value in R1 */ + /* * restore callee-saves registers. (Don't stomp on %%eax!) */ "movl %%esp, %%edx\n\t" - "addl %5, %%edx\n\t" + "addl %4, %%edx\n\t" "movl 0(%%edx),%%ebx\n\t" /* restore the registers saved above */ "movl 4(%%edx),%%esi\n\t" "movl 8(%%edx),%%edi\n\t" "movl 12(%%edx),%%ebp\n\t" - : "=&a" (r), "=m" (space), - "=m" (stg_esp_saved_before_stack_align) - : "m" (f), "m" (basereg), "i" (RESERVED_C_STACK_BYTES), - "m" (stg_esp_saved_before_stack_align) - + : "=&a" (r), "=m" (space) + : "m" (f), "m" (basereg), "i" (RESERVED_C_STACK_BYTES) : "edx" /* stomps on %edx */ ); @@ -293,6 +269,7 @@ StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg) { register long real_ra __asm__("$26"); volatile long save_ra; + register long real_gp __asm__("$29"); volatile long save_gp; register long real_s0 __asm__("$9" ); volatile long save_s0; register long real_s1 __asm__("$10"); volatile long save_s1; @@ -320,6 +297,7 @@ StgRun(StgFunPtr f, StgRegTable *basereg) StgThreadReturnCode ret; save_ra = real_ra; + save_gp = real_gp; save_s0 = real_s0; save_s1 = real_s1; @@ -376,6 +354,7 @@ StgRun(StgFunPtr f, StgRegTable *basereg) #endif real_ra = save_ra; + real_gp = save_gp; return ret; } @@ -475,4 +454,105 @@ StgRun(StgFunPtr f, StgRegTable *basereg) #endif /* hppa1_1_TARGET_ARCH */ +/* ----------------------------------------------------------------------------- + PowerPC architecture + + Everything is in assembler, so we don't have to deal with GCC... + + -------------------------------------------------------------------------- */ + +#ifdef powerpc_TARGET_ARCH + +extern StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg); + +static void StgRunIsImplementedInAssembler(void) +{ + __asm__ volatile ( + "\n.globl _StgRun\n" + "_StgRun:\n" + "\tmflr r0\n" + "\tbl saveFP # f14\n" + "\tstmw r13,-220(r1)\n" + "\tstwu r1,-%0(r1)\n" + "\tmtctr r3\n" + "\tmr r12,r3\n" + "\tbctr\n" + ".globl _StgReturn\n" + "_StgReturn:\n" + "\tmr r3,r14\n" + "\tla r1,%0(r1)\n" + "\tlmw r13,-220(r1)\n" + "\tb restFP # f14\n" + : : "i"(RESERVED_C_STACK_BYTES+288 /*stack frame size*/)); +} + +#endif + +/* ----------------------------------------------------------------------------- + IA64 architecture + + Again, in assembler - so we can fiddle with the register stack, and because + gcc doesn't handle asm-clobbered callee-saves correctly. + + loc0 - loc15: preserved locals + loc16 - loc28: STG registers + loc29: saved ar.pfs + loc30: saved b0 + loc31: saved gp (gcc 3.3 uses this slot) + -------------------------------------------------------------------------- */ + +#ifdef ia64_TARGET_ARCH + +/* the memory stack is rarely used, so 16K is excessive */ +#undef RESERVED_C_STACK_BYTES +#define RESERVED_C_STACK_BYTES 1024 + +#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3) +/* gcc 3.3+: leave an extra slot for gp saves */ +#define LOCALS 32 +#else +#define LOCALS 31 +#endif + +static void StgRunIsImplementedInAssembler(void) +{ + __asm__ volatile( + ".global StgRun\n" + "StgRun:\n" + "\talloc loc29 = ar.pfs, 0, %1, 8, 0\n" /* setup register frame */ + "\tld8 r18 = [r32],8\n" /* get procedure address */ + "\tadds sp = -%0, sp ;;\n" /* setup stack */ + "\tld8 gp = [r32]\n" /* get procedure GP */ + "\tadds r16 = %0-(6*16), sp\n" + "\tadds r17 = %0-(5*16), sp ;;\n" + "\tstf.spill [r16] = f16,32\n" /* spill callee-saved fp regs */ + "\tstf.spill [r17] = f17,32\n" + "\tmov b6 = r18 ;;\n" /* set target address */ + "\tstf.spill [r16] = f18,32\n" + "\tstf.spill [r17] = f19,32\n" + "\tmov loc30 = b0 ;;\n" /* save return address */ + "\tstf.spill [r16] = f20,32\n" + "\tstf.spill [r17] = f21,32\n" + "\tbr.few b6 ;;\n" /* branch to function */ + ".global StgReturn\n" + "StgReturn:\n" + "\tmov r8 = loc16\n" /* return value in r8 */ + "\tadds r16 = %0-(6*16), sp\n" + "\tadds r17 = %0-(5*16), sp ;;\n" + "\tldf.fill f16 = [r16],32\n" /* start restoring fp regs */ + "\tldf.fill f17 = [r17],32\n" + "\tmov ar.pfs = loc29 ;;\n" /* restore register frame */ + "\tldf.fill f18 = [r16],32\n" + "\tldf.fill f19 = [r17],32\n" + "\tmov b0 = loc30 ;;\n" /* restore return address */ + "\tldf.fill f20 = [r16],32\n" + "\tldf.fill f21 = [r17],32\n" + "\tadds sp = %0, sp\n" /* restore stack */ + "\tbr.ret.sptk.many b0 ;;\n" /* return */ + : : "i"(RESERVED_C_STACK_BYTES + 6*16), "i"(LOCALS)); +} + +#endif + #endif /* !USE_MINIINTERPRETER */ +