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.
-----------------------------------------------------------------------------
--- $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
--
| prefixMatch "ia64" cTARGETPLATFORM
= return ( [], ["-fomit-frame-pointer", "-G0"] )
+ | prefixMatch "x86_64" cTARGETPLATFORM
+ = return ( [], ["-fomit-frame-pointer"] )
+
| prefixMatch "mips" cTARGETPLATFORM
= return ( ["-static"], [] )
$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)
$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//;
/* -----------------------------------------------------------------------------
- * $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
/* -----------------------------------------------------------------------------
- * $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
*
#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
-------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
- * $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
*
# 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
/* -----------------------------------------------------------------------------
- * $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
*
# 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