* in libc.a clobbers $s6.
*/
#include "ghcconfig.h"
+#ifndef USE_MINIINTERPRETER
#ifdef alpha_HOST_ARCH
#define alpha_EXTRA_CAREFUL
register long fake_ra __asm__("$26");
register double fake_f9 __asm__("$f9");
#endif
#endif
+#endif
/* include Stg.h first because we want real machine regs in here: we
* have to get the value of R1 back from Stg land to C land intact.
#else /* !USE_MINIINTERPRETER */
#ifdef LEADING_UNDERSCORE
+#define STG_RUN "_StgRun"
+#else
+#define STG_RUN "StgRun"
+#endif
+
+#ifdef LEADING_UNDERSCORE
#define STG_RETURN "_StgReturn"
#else
#define STG_RETURN "StgReturn"
/*
* save callee-saves registers on behalf of the STG code.
*/
- ".globl StgRun\n"
- "StgRun:\n\t"
+ ".globl " STG_RUN "\n"
+ STG_RUN ":\n\t"
"subq %0, %%rsp\n\t"
"movq %%rsp, %%rax\n\t"
"addq %0-48, %%rax\n\t"
"movq %%rdi,%%rax\n\t"
"jmp *%%rax\n\t"
- ".global " STG_RETURN "\n"
+ ".globl " STG_RETURN "\n"
STG_RETURN ":\n\t"
"movq %%rbx, %%rax\n\t" /* Return value in R1 */
loc29: saved ar.pfs
loc30: saved b0
loc31: saved gp (gcc 3.3 uses this slot)
+ loc32: saved ar.lc
+ loc33: saved pr
+ f2 - f5: preserved floating-point registers
+ f16 - f23: preserved floating-point registers
-------------------------------------------------------------------------- */
#ifdef ia64_HOST_ARCH
#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
+/* We don't spill all the callee-save FP registers, only the ones that
+ * gcc has been observed to use */
+#define PRESERVED_FP_REGISTERS 12
+
+/* We always allocate 34 local and 8 output registers. As long as gcc used
+ * fewer than 32 locals, the mangler will adjust the stack frame accordingly. */
+#define LOCALS 34
static void GNUC3_ATTRIBUTE(used)
StgRunIsImplementedInAssembler(void)
"\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"
+ "\tadds r16 = %0-(%2*16), sp\n"
+ "\tadds r17 = %0-((%2-1)*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 [r17] = f19,32\n"
"\tmov loc30 = b0 ;;\n" /* save return address */
"\tstf.spill [r16] = f20,32\n"
- "\tstf.spill [r17] = f21,32\n"
+ "\tstf.spill [r17] = f21,32 ;;\n"
+ "\tstf.spill [r16] = f22,32\n"
+ "\tstf.spill [r17] = f23,32\n"
+ "\tmov loc32 = ar.lc ;;\n" /* save loop counter */
+ "\tstf.spill [r16] = f2,32\n"
+ "\tstf.spill [r17] = f3,32\n"
+ "\tmov loc33 = pr ;;\n" /* save predicate registers */
+ "\tstf.spill [r16] = f4,32\n"
+ "\tstf.spill [r17] = f5,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"
+ "\tadds r16 = %0-(%2*16), sp\n"
+ "\tadds r17 = %0-((%2-1)*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 */
"\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 */
+ "\tmov ar.lc = loc32 ;;\n" /* restore loop counter */
+ "\tldf.fill f22 = [r16],32\n"
+ "\tldf.fill f23 = [r17],32\n"
+ "\tmov pr = loc33 ;;\n" /* restore predicate registers */
+ "\tldf.fill f2 = [r16],32\n"
+ "\tldf.fill f3 = [r17],32\n"
+ "\tadds sp = %0, sp ;;\n" /* restore stack */
+ "\tldf.fill f4 = [r16],32\n"
+ "\tldf.fill f5 = [r17],32\n"
"\tbr.ret.sptk.many b0 ;;\n" /* return */
- : : "i"(RESERVED_C_STACK_BYTES + 6*16), "i"(LOCALS));
+ : : "i"(RESERVED_C_STACK_BYTES + PRESERVED_FP_REGISTERS*16),
+ "i"(LOCALS),
+ "i"(PRESERVED_FP_REGISTERS));
}
#endif
+/* -----------------------------------------------------------------------------
+ MIPS architecture
+ -------------------------------------------------------------------------- */
+
+#ifdef mips_HOST_ARCH
+
+StgThreadReturnCode
+StgRun(StgFunPtr f, StgRegTable *basereg)
+{
+ register StgThreadReturnCode __v0 __asm__("$2");
+
+ __asm__ __volatile__(
+ " la $25, %1 \n"
+ " move $30, %2 \n"
+ " jr %1 \n"
+ " .align 3 \n"
+ " .globl " STG_RETURN " \n"
+ " .aent " STG_RETURN " \n"
+ STG_RETURN ": \n"
+ " move %0, $16 \n"
+ " move $3, $17 \n"
+ : "=r" (__v0),
+ : "r" (f), "r" (basereg)
+ "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
+ "$25", "$28", "$30",
+ "$f20", "$f22", "$f24", "$f26", "$f28", "$f30",
+ "memory");
+
+ return __v0;
+}
+
+#endif /* mips_HOST_ARCH */
+
#endif /* !USE_MINIINTERPRETER */