[project @ 2003-08-29 16:00:25 by simonmar]
authorsimonmar <unknown>
Fri, 29 Aug 2003 16:00:29 +0000 (16:00 +0000)
committersimonmar <unknown>
Fri, 29 Aug 2003 16:00:29 +0000 (16:00 +0000)
Initial x86-64 (aka amd64) support.

Unregisterised it works perfectly.  Registerised, I think it's almost
there, except that I seem to be running into the known codegen bug in
GCC with register variables (bug #7871 in the gcc bugzilla), which
means registerised support is basically hosed until the GCC folks
can get their act together.

We get 8 more registers on amd64, but only 2 more callee-saves
registers.  The calling convention seems to pass args in registers by
default, using the previously-callee-saves %rsi and %rdi as two of the
new arg registers.

I think GHCi should work, since we already have 64-bit ELF support
thanks to Mat Chapman's work on the IA64 port.  I haven't tried GHCi,
though.

The native code generator should be a breeze, because it's so similar
to plain x86.

ghc/compiler/main/DriverFlags.hs
ghc/driver/mangler/ghc-asm.lprl
ghc/includes/MachRegs.h
ghc/includes/TailCalls.h
ghc/rts/Linker.c
ghc/rts/MBlock.h

index 074ba93..38210a7 100644 (file)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------------------
--- $Id: DriverFlags.hs,v 1.121 2003/08/27 13:28:01 panne Exp $
+-- $Id: DriverFlags.hs,v 1.122 2003/08/29 16:00:25 simonmar Exp $
 --
 -- Driver flags
 --
@@ -600,6 +600,9 @@ machdepCCOpts
    | prefixMatch "ia64"    cTARGETPLATFORM  
        = return ( [], ["-fomit-frame-pointer", "-G0"] )
 
+   | prefixMatch "x86_64"  cTARGETPLATFORM
+       = return ( [], ["-fomit-frame-pointer"] )
+
    | prefixMatch "mips"    cTARGETPLATFORM
        = return ( ["-static"], [] )
 
index 71334e9..1878895 100644 (file)
@@ -230,6 +230,32 @@ sub init_TARGET_STUFF {
     $T_HDR_direct   = "\.text\n\t\.align 8\n";
 
     #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^x86_64-.*-linux$/ ) {
+
+    $T_STABBY       = 0; # 1 iff .stab things (usually if a.out format)
+    $T_US           = ''; # _ if symbols have an underscore on the front
+    $T_PRE_APP      = '#';
+    $T_CONST_LBL    = '^\.LC(\d+):$'; # regexp for what such a lbl looks like
+    $T_POST_LBL     = ':';
+
+    $T_MOVE_DIRVS   = '^(\s*\.(globl|text|data|section|align|size|type|ident|local)\s+.*\n)';
+    $T_COPY_DIRVS   = '\.(globl|local)';
+
+    $T_hsc_cc_PAT   = '\.string.*\)(hsc|cc) (.*)\\\\t(.*)"';
+    $T_DOT_WORD     = '\.(quad|long|value|byte|zero)';
+    $T_DOT_GLOBAL   = '\.global';
+    $T_HDR_literal  = "\.section\t\.rodata\n";
+    $T_HDR_misc     = "\.text\n\t\.align 8\n";
+    $T_HDR_data     = "\.data\n\t\.align 8\n";
+    $T_HDR_consist  = "\.text\n";
+    $T_HDR_closure  = "\.data\n\t\.align 8\n";
+    $T_HDR_srt      = "\.text\n\t\.align 8\n";
+    $T_HDR_info     = "\.text\n\t\.align 8\n";
+    $T_HDR_entry    = "\.text\n\t\.align 8\n";
+    $T_HDR_vector   = "\.text\n\t\.align 8\n";
+    $T_HDR_direct   = "\.text\n\t\.align 8\n";
+
+    #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^m68k-.*-sunos4/ ) {
 
     $T_STABBY      = 1; # 1 iff .stab things (usually if a.out format)
@@ -702,6 +728,11 @@ sub mangle_asm {
                          $r = $& . $r;
                    }
 
+               } elsif ($TargetPlatform =~ /^x86_64-/) {
+                   $p =~ s/^\tpushq\s+\%r(bx|bp|12|13|14)\n//g;
+                   $p =~ s/^\tmovq\s+\%r(bx|bp|12|13|14),\s*\d*\(\%rsp\)\n//g;
+                   $p =~ s/^\tsubq\s+\$\d+,\s*\%rsp\n//;
+
                } elsif ($TargetPlatform =~ /^ia64-/) {
                    $p =~ s/^\t\.prologue .*\n//;
                    $p =~ s/^\t\.save ar\.pfs, r\d+\n\talloc r\d+ = ar\.pfs, 0, 3[12], \d+, 0\n//;
index f183ffe..0c25a61 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: MachRegs.h,v 1.13 2002/12/11 15:36:37 simonmar Exp $
+ * $Id: MachRegs.h,v 1.14 2003/08/29 16:00:26 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
 #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
index 1f562eb..950d8f1 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: TailCalls.h,v 1.12 2003/01/06 13:11:26 simonmar Exp $
+ * $Id: TailCalls.h,v 1.13 2003/08/29 16:00:26 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -60,6 +60,21 @@ extern void __DISCARD__(void);
 #endif /* i386_TARGET_ARCH */
 
 /* -----------------------------------------------------------------------------
+   Tail calling on x86_64
+   -------------------------------------------------------------------------- */
+
+#if x86_64_TARGET_ARCH
+
+#define JMP_(cont)                     \
+    {                                  \
+      void *__target;                  \
+      __target = (void *)(cont);       \
+      goto *__target;                  \
+    }
+
+#endif /* x86_64_TARGET_ARCH */
+
+/* -----------------------------------------------------------------------------
    Tail calling on Sparc
    -------------------------------------------------------------------------- */
 
index 61b0034..15ea803 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Linker.c,v 1.126 2003/08/18 09:27:54 dons Exp $
+ * $Id: Linker.c,v 1.127 2003/08/29 16:00:26 simonmar Exp $
  *
  * (c) The GHC Team, 2000-2003
  *
@@ -2008,6 +2008,9 @@ ocResolve_PEi386 ( ObjectCode* oc )
 #  define ELF_TARGET_SPARC  /* Used inside <elf.h> */
 #elif defined(i386_TARGET_ARCH)
 #  define ELF_TARGET_386    /* Used inside <elf.h> */
+#elif defined(x86_64_TARGET_ARCH)
+#  define ELF_TARGET_X64_64
+#  define ELF_64BIT
 #elif defined (ia64_TARGET_ARCH)
 #  define ELF_TARGET_IA64   /* Used inside <elf.h> */
 #  define ELF_64BIT
index de5d0b4..f528354 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: MBlock.h,v 1.17 2003/07/30 10:38:42 simonmar Exp $
+ * $Id: MBlock.h,v 1.18 2003/08/29 16:00:29 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -70,6 +70,17 @@ extern StgWord8 mblock_map[];
 # define MARK_HEAP_ALLOCED(p)  ((MBLOCK_MAP_ENTRY(p) < MBLOCK_MAP_SIZE) \
                                        && (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1))
 
+#elif defined(x86_64_TARGET_ARCH)
+/* XXX: This is a HACK, and will not work in general!  We just use the
+ * lower 32 bits of the address, and do the same as for the 32-bit
+ * version.  As long as the OS gives us memory in a roughly linear
+ * fashion, it won't go wrong until we've allocated 4G.  */
+# define MBLOCK_MAP_SIZE       4096
+# define MBLOCK_MAP_ENTRY(p)   (((StgWord)(p) & 0xffffffff) >> MBLOCK_SHIFT)
+# define HEAP_ALLOCED(p)       (mblock_map[MBLOCK_MAP_ENTRY(p)])
+# define MARK_HEAP_ALLOCED(p)  (mblock_map[MBLOCK_MAP_ENTRY(p)] = 1)
+
+
 #else
 # error HEAP_ALLOCED not defined
 #endif