From 7dc97354e24071c4ece647b918cd5eb1d0cd85ed Mon Sep 17 00:00:00 2001 From: simonmar Date: Fri, 29 Aug 2003 16:00:29 +0000 Subject: [PATCH] [project @ 2003-08-29 16:00:25 by simonmar] 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 | 5 ++++- ghc/driver/mangler/ghc-asm.lprl | 31 +++++++++++++++++++++++++++ ghc/includes/MachRegs.h | 43 +++++++++++++++++++++++++++++++++++++- ghc/includes/TailCalls.h | 17 ++++++++++++++- ghc/rts/Linker.c | 5 ++++- ghc/rts/MBlock.h | 13 +++++++++++- 6 files changed, 109 insertions(+), 5 deletions(-) diff --git a/ghc/compiler/main/DriverFlags.hs b/ghc/compiler/main/DriverFlags.hs index 074ba93..38210a7 100644 --- a/ghc/compiler/main/DriverFlags.hs +++ b/ghc/compiler/main/DriverFlags.hs @@ -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"], [] ) diff --git a/ghc/driver/mangler/ghc-asm.lprl b/ghc/driver/mangler/ghc-asm.lprl index 71334e9..1878895 100644 --- a/ghc/driver/mangler/ghc-asm.lprl +++ b/ghc/driver/mangler/ghc-asm.lprl @@ -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//; diff --git a/ghc/includes/MachRegs.h b/ghc/includes/MachRegs.h index f183ffe..0c25a61 100644 --- a/ghc/includes/MachRegs.h +++ b/ghc/includes/MachRegs.h @@ -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 * @@ -220,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 diff --git a/ghc/includes/TailCalls.h b/ghc/includes/TailCalls.h index 1f562eb..950d8f1 100644 --- a/ghc/includes/TailCalls.h +++ b/ghc/includes/TailCalls.h @@ -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 -------------------------------------------------------------------------- */ diff --git a/ghc/rts/Linker.c b/ghc/rts/Linker.c index 61b0034..15ea803 100644 --- a/ghc/rts/Linker.c +++ b/ghc/rts/Linker.c @@ -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 */ #elif defined(i386_TARGET_ARCH) # define ELF_TARGET_386 /* Used inside */ +#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 */ # define ELF_64BIT diff --git a/ghc/rts/MBlock.h b/ghc/rts/MBlock.h index de5d0b4..f528354 100644 --- a/ghc/rts/MBlock.h +++ b/ghc/rts/MBlock.h @@ -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 -- 1.7.10.4