[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / includes / MachRegs.h
index 35db1c0..8297023 100644 (file)
@@ -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<n>, 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
 #  define REG_D2       f7
   
 #  define REG_Sp       9
-#  define REG_Su       10
 #  define REG_SpLim     11
 
 #  define REG_Hp       12
 #define REG_D2         fr21    /* L & R */
 
 #define REG_Sp         r4
-#define REG_Su         r5
 #define REG_SpLim      r6
 
 #define REG_Hp         r7
    esi     R1
    edi     Hp
 
-   Leaving Su, SpLim, and HpLim out of the picture.
+   Leaving SpLim, and HpLim out of the picture.
    -------------------------------------------------------------------------- */
 
 
 #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
 #define REG_Base       a2
 
 #define REG_Sp         a3
-#define REG_Su         a4
 #define REG_SpLim      d3
 
 #define REG_Hp         d4
 #define REG_D2         f30
 
 #define REG_Sp         16
-#define REG_Su         17
 #define REG_SpLim      18
 
 #define REG_Hp         19
 #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
 #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
    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
 #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 */