Commit 7dc97354 authored by simonmar's avatar simonmar

[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.
parent f16020a8
-----------------------------------------------------------------------------
-- $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"], [] )
......
......@@ -229,6 +229,32 @@ sub init_TARGET_STUFF {
$T_HDR_vector = "\.text\n\t\.align 8\n";
$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/ ) {
......@@ -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//;
......
/* -----------------------------------------------------------------------------
* $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
*
......@@ -219,6 +219,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
......
/* -----------------------------------------------------------------------------
* $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
*
......@@ -59,6 +59,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
-------------------------------------------------------------------------- */
......
/* -----------------------------------------------------------------------------
* $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
......
/* -----------------------------------------------------------------------------
* $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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment