X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FMachRegs.h;h=8297023dfd67c02c7f9e6d83257e3e26e5936bee;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=35db1c0f28acf31e03f171cdbdee59ecd34557e5;hpb=6d40c9e64a408c0de2b60a26dbc8c437433b095c;p=ghc-hetmet.git diff --git a/ghc/includes/MachRegs.h b/ghc/includes/MachRegs.h index 35db1c0..8297023 100644 --- a/ghc/includes/MachRegs.h +++ b/ghc/includes/MachRegs.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: MachRegs.h,v 1.5 1999/06/25 09:13:38 simonmar Exp $ + * $Id: MachRegs.h,v 1.16 2004/08/13 13:09:18 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -33,7 +33,7 @@ CALLER_SAVES_USER one or more of R, F, D are caller-saves. - CALLER_SAVES_SYSTEM one or more of Sp, Su, SpLim, Hp, HpLim + CALLER_SAVES_SYSTEM one or more of Sp, SpLim, Hp, HpLim are caller-saves. This is so that the callWrapper mechanism knows which kind of @@ -69,7 +69,6 @@ t6 $7 R7 t7 $8 R8 s0 $9 Sp - s1 $10 Su s2 $11 SpLim s3 $12 Hp s4 $13 HpLim @@ -108,7 +107,6 @@ # define REG_D2 f7 # define REG_Sp 9 -# define REG_Su 10 # define REG_SpLim 11 # define REG_Hp 12 @@ -164,7 +162,6 @@ #define REG_D2 fr21 /* L & R */ #define REG_Sp r4 -#define REG_Su r5 #define REG_SpLim r6 #define REG_Hp r7 @@ -194,7 +191,7 @@ esi R1 edi Hp - Leaving Su, SpLim, and HpLim out of the picture. + Leaving SpLim, and HpLim out of the picture. -------------------------------------------------------------------------- */ @@ -223,6 +220,47 @@ #endif /* iX86 */ /* ----------------------------------------------------------------------------- + The x86-64 register mapping + + callee-saves + %rax + %rbx YES + %rcx + %rdx (seem to be used as arg regs on x86-64) + %rsi (seem to be used as arg regs on x86-64) + %rdi (seem to be used as arg regs on x86-64) + %rbp YES + %rsp (unavailable - stack pointer) + %r8 + %r9 + %r10 + %r11 + %r12 YES + %r13 YES + %r14 YES + %r15 YES + --------------------------------------------------------------------------- */ + +#if x86_64_TARGET_ARCH + +#define REG(x) __asm__("%" #x) + +#define REG_Base rbx +#define REG_Sp rbp +#define REG_Hp r12 +#define REG_R1 r13 +#define REG_SpLim r14 +#define REG_HpLim r15 +/* ToDo: try R2/R3 instead of SpLim/HpLim? */ + +#define MAX_REAL_VANILLA_REG 1 +#define MAX_REAL_FLOAT_REG 0 +#define MAX_REAL_DOUBLE_REG 0 +#define MAX_REAL_LONG_REG 0 + +#endif /* x86_64 */ + +/* ----------------------------------------------------------------------------- The Motorola 680x0 register mapping A Sun3 (mc680x0) has eight address registers, \tr{a0} to \tr{a7}, and @@ -261,7 +299,6 @@ #define REG_Base a2 #define REG_Sp a3 -#define REG_Su a4 #define REG_SpLim d3 #define REG_Hp d4 @@ -330,7 +367,6 @@ #define REG_D2 f30 #define REG_Sp 16 -#define REG_Su 17 #define REG_SpLim 18 #define REG_Hp 19 @@ -373,6 +409,18 @@ #define REG_R7 r20 #define REG_R8 r21 +#ifdef darwin_TARGET_OS + +#define REG_F1 f14 +#define REG_F2 f15 +#define REG_F3 f16 +#define REG_F4 f17 + +#define REG_D1 f18 +#define REG_D2 f19 + +#else + #define REG_F1 fr14 #define REG_F2 fr15 #define REG_F3 fr16 @@ -381,16 +429,60 @@ #define REG_D1 fr18 #define REG_D2 fr19 +#endif + #define REG_Sp r22 -#define REG_Su r23 #define REG_SpLim r24 #define REG_Hp r25 #define REG_HpLim r26 +#define REG_Base r27 + #endif /* powerpc */ /* ----------------------------------------------------------------------------- + The IA64 register mapping + + We place the general registers in the locals area of the register stack, + so that the call mechanism takes care of saving them for us. We reserve + the first 16 for gcc's use - since gcc uses the highest used register to + determine the register stack frame size, this gives us a constant size + register stack frame. + + \tr{f16-f32} are the callee-saved floating point registers. + -------------------------------------------------------------------------- */ + +#ifdef ia64_TARGET_ARCH + +#define REG(x) __asm__(#x) + +#define REG_R1 loc16 +#define REG_R2 loc17 +#define REG_R3 loc18 +#define REG_R4 loc19 +#define REG_R5 loc20 +#define REG_R6 loc21 +#define REG_R7 loc22 +#define REG_R8 loc23 + +#define REG_F1 f16 +#define REG_F2 f17 +#define REG_F3 f18 +#define REG_F4 f19 + +#define REG_D1 f20 +#define REG_D2 f21 + +#define REG_Sp loc24 +#define REG_SpLim loc26 + +#define REG_Hp loc27 +#define REG_HpLim loc28 + +#endif /* ia64 */ + +/* ----------------------------------------------------------------------------- The Sun SPARC register mapping The SPARC register (window) story: Remember, within the Haskell @@ -413,6 +505,37 @@ Note: %g3 is *definitely* clobbered in the builtin divide code (and our save/restore machinery is NOT GOOD ENOUGH for that); discretion being the better part of valor, we also don't take %g4. + + The paired nature of the floating point registers causes complications for + the native code generator. For convenience, we pretend that the first 22 + fp regs %f0 .. %f21 are actually 11 double regs, and the remaining 10 are + float (single) regs. The NCG acts accordingly. That means that the + following FP assignment is rather fragile, and should only be changed + with extreme care. The current scheme is: + + %f0 /%f1 FP return from C + %f2 /%f3 D1 + %f4 /%f5 D2 + %f6 /%f7 ncg double spill tmp #1 + %f8 /%f9 ncg double spill tmp #2 + %f10/%f11 allocatable + %f12/%f13 allocatable + %f14/%f15 allocatable + %f16/%f17 allocatable + %f18/%f19 allocatable + %f20/%f21 allocatable + + %f22 F1 + %f23 F2 + %f24 F3 + %f25 F4 + %f26 ncg single spill tmp #1 + %f27 ncg single spill tmp #2 + %f28 allocatable + %f29 allocatable + %f30 allocatable + %f31 allocatable + -------------------------------------------------------------------------- */ #if sparc_TARGET_ARCH @@ -437,50 +560,108 @@ #define REG_R7 l7 #define REG_R8 i5 -#define REG_F1 f2 -#define REG_F2 f3 -#define REG_F3 f4 -#define REG_F4 f5 -#define REG_D1 f6 -#define REG_D2 f8 +#define REG_F1 f22 +#define REG_F2 f23 +#define REG_F3 f24 +#define REG_F4 f25 +#define REG_D1 f2 +#define REG_D2 f4 #define REG_Sp i0 -#define REG_Su i1 #define REG_SpLim i2 #define REG_Hp i3 #define REG_HpLim i4 -#define NCG_Reserved_I1 g1 -#define NCG_Reserved_I2 g2 -#define NCG_Reserved_F1 f14 -#define NCG_Reserved_F2 f15 -#define NCG_Reserved_D1 f16 -#define NCG_Reserved_D2 f18 +#define NCG_SpillTmp_I1 g1 +#define NCG_SpillTmp_I2 g2 +#define NCG_SpillTmp_F1 f26 +#define NCG_SpillTmp_F2 f27 +#define NCG_SpillTmp_D1 f6 +#define NCG_SpillTmp_D2 f8 + +#define NCG_FirstFloatReg f22 #endif /* sparc */ -/* These constants define how many stg registers are *actually* in - * registers: the code generator uses this information to avoid - * generating code to load/store registers which are really offsets - * from BaseReg. +#endif /* NO_REGS */ + +/* ----------------------------------------------------------------------------- + * These constants define how many stg registers will be used for + * passing arguments (and results, in the case of an unboxed-tuple + * return). + * + * We usually set MAX_REAL_VANILLA_REG and co. to be the number of the + * highest STG register to occupy a real machine register, otherwise + * the calling conventions will needlessly shuffle data between the + * stack and memory-resident STG registers. We might occasionally + * set these macros to other values for testing, though. * * Registers above these values might still be used, for instance to * communicate with PrimOps and RTS functions. */ #ifndef MAX_REAL_VANILLA_REG -#define MAX_REAL_VANILLA_REG 8 +# if defined(REG_R8) +# define MAX_REAL_VANILLA_REG 8 +# elif defined(REG_R7) +# define MAX_REAL_VANILLA_REG 7 +# elif defined(REG_R6) +# define MAX_REAL_VANILLA_REG 6 +# elif defined(REG_R5) +# define MAX_REAL_VANILLA_REG 5 +# elif defined(REG_R4) +# define MAX_REAL_VANILLA_REG 4 +# elif defined(REG_R3) +# define MAX_REAL_VANILLA_REG 3 +# elif defined(REG_R2) +# define MAX_REAL_VANILLA_REG 2 +# elif defined(REG_R1) +# define MAX_REAL_VANILLA_REG 1 +# else +# define MAX_REAL_VANILLA_REG 0 +# endif #endif #ifndef MAX_REAL_FLOAT_REG -#define MAX_REAL_FLOAT_REG 4 +# if defined(REG_F4) +# define MAX_REAL_FLOAT_REG 4 +# elif defined(REG_F3) +# define MAX_REAL_FLOAT_REG 3 +# elif defined(REG_F2) +# define MAX_REAL_FLOAT_REG 2 +# elif defined(REG_F1) +# define MAX_REAL_FLOAT_REG 1 +# else +# define MAX_REAL_FLOAT_REG 0 +# endif #endif #ifndef MAX_REAL_DOUBLE_REG -#define MAX_REAL_DOUBLE_REG 2 +# if defined(REG_D2) +# define MAX_REAL_DOUBLE_REG 2 +# elif defined(REG_D1) +# define MAX_REAL_DOUBLE_REG 1 +# else +# define MAX_REAL_DOUBLE_REG 0 +# endif #endif -#endif /* NO_REGS */ +#ifndef MAX_REAL_LONG_REG +# if defined(REG_L1) +# define MAX_REAL_LONG_REG 1 +# else +# define MAX_REAL_LONG_REG 0 +# endif +#endif + +/* define NO_ARG_REGS if we have no argument registers at all (we can + * optimise certain code paths using this predicate). + */ +#if MAX_REAL_VANILLA_REG < 2 +#define NO_ARG_REGS +#else +#undef NO_ARG_REGS +#endif #endif /* MACHREGS_H */