[project @ 2005-06-09 05:55:40 by wolfgang]
authorwolfgang <unknown>
Thu, 9 Jun 2005 05:55:42 +0000 (05:55 +0000)
committerwolfgang <unknown>
Thu, 9 Jun 2005 05:55:42 +0000 (05:55 +0000)
Registerised support for Darwin/x86, both NCG and mangled.

*) -fPIC doesn't work yet with -fvia-C.
*) Apple officially requires the stack to be 16-byte-aligned,
   GHC ignores this for now.

ghc/compiler/nativeGen/MachInstrs.hs
ghc/compiler/nativeGen/PositionIndependentCode.hs
ghc/compiler/nativeGen/PprMach.hs
ghc/compiler/nativeGen/RegAllocInfo.hs
ghc/driver/mangler/ghc-asm.lprl
ghc/rts/StgCRun.c

index eda78e2..84ff2b2 100644 (file)
@@ -509,12 +509,17 @@ bit or 64 bit precision.
 -- Other things.
        | CLTD MachRep   -- sign extend %eax into %edx:%eax
 
-       | FETCHGOT    Reg  -- pseudo-insn for position-independent code
+       | FETCHGOT    Reg  -- pseudo-insn for ELF position-independent code
                            -- pretty-prints as
                            --       call 1f
                            -- 1:    popl %reg
                            --       addl __GLOBAL_OFFSET_TABLE__+.-1b, %reg
-                    
+       | FETCHPC     Reg  -- pseudo-insn for Darwin position-independent code
+                           -- pretty-prints as
+                           --       call 1f
+                           -- 1:    popl %reg
+        
+          
 data Operand
   = OpReg  Reg         -- register
   | OpImm  Imm         -- immediate value
index 0a70b2d..c6f439e 100644 (file)
@@ -321,12 +321,29 @@ pprCLabel_asm l = asmSDoc (pprCLabel l)
 
 needImportedSymbols = True
 
--- We don't need to declare any offset tables
+-- We don't need to declare any offset tables.
+-- However, for PIC on x86, we need a small helper function.
+#if i386_TARGET_ARCH
+pprGotDeclaration
+    | opt_PIC
+    = vcat [
+        ptext SLIT(".section __TEXT,__textcoal_nt,coalesced,no_toc"),
+        ptext SLIT(".weak_definition ___i686.get_pc_thunk.ax"),
+        ptext SLIT(".private_extern ___i686.get_pc_thunk.ax"),
+        ptext SLIT("___i686.get_pc_thunk.ax:"),
+            ptext SLIT("\tmovl (%esp), %eax"),
+            ptext SLIT("\tret")
+    ]
+    | otherwise = Pretty.empty
+#else
 pprGotDeclaration = Pretty.empty
+#endif
 
 -- On Darwin, we have to generate our own stub code for lazy binding..
--- There are two versions, one for PIC and one for non-PIC.
+-- For each processor architecture, there are two versions, one for PIC
+-- and one for non-PIC.
 pprImportedSymbol importedLbl
+#if powerpc_TARGET_ARCH
     | Just (CodeStub, lbl) <- dynamicLinkerLabelInfo importedLbl
     = case opt_PIC of
         False ->
@@ -369,7 +386,49 @@ pprImportedSymbol importedLbl
             ptext SLIT("\t.indirect_symbol") <+> pprCLabel_asm lbl,
             ptext SLIT("\t.long dyld_stub_binding_helper")
     ]
-
+#elif i386_TARGET_ARCH
+    | Just (CodeStub, lbl) <- dynamicLinkerLabelInfo importedLbl
+    = case opt_PIC of
+        False ->
+            vcat [
+                ptext SLIT(".symbol_stub"),
+                ptext SLIT("L") <> pprCLabel_asm lbl <> ptext SLIT("$stub:"),
+                    ptext SLIT("\t.indirect_symbol") <+> pprCLabel_asm lbl,
+                    ptext SLIT("\tjmp *L") <> pprCLabel_asm lbl
+                        <> ptext SLIT("$lazy_ptr"),
+                ptext SLIT("L") <> pprCLabel_asm lbl
+                    <> ptext SLIT("$stub_binder:"),
+                    ptext SLIT("\tpushl $L") <> pprCLabel_asm lbl
+                        <> ptext SLIT("$lazy_ptr"),
+                    ptext SLIT("\tjmp dyld_stub_binding_helper")
+            ]
+        True ->
+            vcat [
+                ptext SLIT(".section __TEXT,__picsymbolstub2,")
+                    <> ptext SLIT("symbol_stubs,pure_instructions,25"),
+                ptext SLIT("L") <> pprCLabel_asm lbl <> ptext SLIT("$stub:"),
+                    ptext SLIT("\t.indirect_symbol") <+> pprCLabel_asm lbl,
+                    ptext SLIT("\tcall ___i686.get_pc_thunk.ax"),
+                ptext SLIT("1:"),
+                    ptext SLIT("\tmovl L") <> pprCLabel_asm lbl
+                        <> ptext SLIT("$lazy_ptr-1b(%eax),%edx"),
+                    ptext SLIT("\tjmp %edx"),
+                ptext SLIT("L") <> pprCLabel_asm lbl
+                    <> ptext SLIT("$stub_binder:"),
+                    ptext SLIT("\tlea L") <> pprCLabel_asm lbl
+                        <> ptext SLIT("$lazy_ptr-1b(%eax),%eax"),
+                    ptext SLIT("\tpushl %eax"),
+                    ptext SLIT("\tjmp dyld_stub_binding_helper")
+            ]
+    $+$ vcat [        ptext SLIT(".section __DATA, __la_sym_ptr")
+                    <> (if opt_PIC then int 2 else int 3)
+                    <> ptext SLIT(",lazy_symbol_pointers"),
+        ptext SLIT("L") <> pprCLabel_asm lbl <> ptext SLIT("$lazy_ptr:"),
+            ptext SLIT("\t.indirect_symbol") <+> pprCLabel_asm lbl,
+            ptext SLIT("\t.long L") <> pprCLabel_asm lbl
+                    <> ptext SLIT("$stub_binder")
+    ]
+#endif
 -- We also have to declare our symbol pointers ourselves:
     | Just (SymbolPtr, lbl) <- dynamicLinkerLabelInfo importedLbl
     = vcat [
@@ -475,9 +534,21 @@ pprImportedSymbol _ = empty
 
 initializePicBase :: Reg -> [NatCmmTop] -> NatM [NatCmmTop]
 
-#if powerpc_TARGET_ARCH && darwin_TARGET_OS
+#if darwin_TARGET_OS
 
 -- Darwin is simple: just fetch the address of a local label.
+-- The FETCHPC pseudo-instruction is expanded to multiple instructions
+-- during pretty-printing so that we don't have to deal with the
+-- local label:
+
+-- PowerPC version:
+--          bcl 20,31,1f.
+--      1:  mflr picReg
+
+-- i386 version:
+--          call 1f
+--      1:  popl %picReg
+
 initializePicBase picReg (CmmProc info lab params blocks : statics)
     = return (CmmProc info lab params (b':tail blocks) : statics)
     where BasicBlock bID insns = head blocks
@@ -531,9 +602,4 @@ initializePicBase picReg (CmmProc info lab params blocks : statics)
 initializePicBase picReg proc = panic "initializePicBase"
 
 -- mingw32_TARGET_OS: not needed, won't be called
-
--- i386_TARGET_ARCH && darwin_TARGET_OS:
--- (just for completeness ;-)
---              call 1f
--- 1:           popl %picReg
 #endif
index 61faf24..381c76f 100644 (file)
@@ -617,7 +617,9 @@ pprSectionHeader Text
     = ptext
        IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
        ,IF_ARCH_sparc(SLIT(".text\n\t.align 4") {-word boundary-}
-       ,IF_ARCH_i386(SLIT(".text\n\t.align 4,0x90") {-needs per-OS variation!-}
+       ,IF_ARCH_i386(IF_OS_darwin(SLIT(".text\n\t.align 2"),
+                                  SLIT(".text\n\t.align 4,0x90"))
+                                  {-needs per-OS variation!-}
        ,IF_ARCH_x86_64(SLIT(".text\n\t.align 8") {-needs per-OS variation!-}
        ,IF_ARCH_powerpc(SLIT(".text\n.align 2")
        ,)))))
@@ -625,7 +627,8 @@ pprSectionHeader Data
     = ptext
         IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
        ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
-       ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
+       ,IF_ARCH_i386(IF_OS_darwin(SLIT(".data\n\t.align 2"),
+                                   SLIT(".data\n\t.align 4"))
        ,IF_ARCH_x86_64(SLIT(".data\n\t.align 8")
         ,IF_ARCH_powerpc(SLIT(".data\n.align 2")
        ,)))))
@@ -633,7 +636,8 @@ pprSectionHeader ReadOnlyData
     = ptext
         IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
        ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
-       ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
+       ,IF_ARCH_i386(IF_OS_darwin(SLIT(".const\n.align 2"),
+                                   SLIT(".section .rodata\n\t.align 4"))
        ,IF_ARCH_x86_64(SLIT(".section .rodata\n\t.align 8")
         ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const\n.align 2"),
                                       SLIT(".section .rodata\n\t.align 2"))
@@ -642,7 +646,8 @@ pprSectionHeader RelocatableReadOnlyData
     = ptext
         IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
        ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
-       ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
+       ,IF_ARCH_i386(IF_OS_darwin(SLIT(".const_data\n.align 2"),
+                                   SLIT(".section .rodata\n\t.align 4"))
        ,IF_ARCH_x86_64(SLIT(".section .rodata\n\t.align 8")
         ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
                                       SLIT(".data\n\t.align 2"))
@@ -651,7 +656,8 @@ pprSectionHeader UninitialisedData
     = ptext
         IF_ARCH_alpha(SLIT("\t.bss\n\t.align 3")
        ,IF_ARCH_sparc(SLIT(".bss\n\t.align 8") {-<8 will break double constants -}
-       ,IF_ARCH_i386(SLIT(".section .bss\n\t.align 4")
+       ,IF_ARCH_i386(IF_OS_darwin(SLIT(".const_data\n\t.align 2"),
+                                   SLIT(".section .bss\n\t.align 4"))
        ,IF_ARCH_x86_64(SLIT(".section .bss\n\t.align 8")
         ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
                                       SLIT(".section .bss\n\t.align 2"))
@@ -660,7 +666,8 @@ pprSectionHeader ReadOnlyData16
     = ptext
         IF_ARCH_alpha(SLIT("\t.data\n\t.align 4")
        ,IF_ARCH_sparc(SLIT(".data\n\t.align 16")
-       ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 16")
+       ,IF_ARCH_i386(IF_OS_darwin(SLIT(".const\n.align 4"),
+                                   SLIT(".section .rodata\n\t.align 16"))
        ,IF_ARCH_x86_64(SLIT(".section .rodata.cst16\n\t.align 16")
         ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const\n.align 4"),
                                       SLIT(".section .rodata\n\t.align 4"))
@@ -701,7 +708,7 @@ pprASCII str
 
 pprAlign bytes =
        IF_ARCH_alpha(ptextSLIT(".align ") <> int pow2,
-       IF_ARCH_i386(ptext SLIT(".align ") <> int bytes,
+       IF_ARCH_i386(ptext SLIT(".align ") <> int IF_OS_darwin(pow2,bytes),
        IF_ARCH_x86_64(ptext SLIT(".align ") <> int bytes,
        IF_ARCH_sparc(ptext SLIT(".align ") <> int bytes,
        IF_ARCH_powerpc(ptext SLIT(".align ") <> int pow2,)))))
@@ -1303,6 +1310,7 @@ pprInstr (CVTSI2SS from to) = pprOpReg  SLIT("cvtsi2ss") from to
 pprInstr (CVTSI2SD from to) = pprOpReg  SLIT("cvtsi2sd") from to
 #endif
 
+    -- FETCHGOT for PIC on ELF platforms
 pprInstr (FETCHGOT reg)
    = vcat [ ptext SLIT("\tcall 1f"),
             hcat [ ptext SLIT("1:\tpopl\t"), pprReg I32 reg ],
@@ -1310,6 +1318,17 @@ pprInstr (FETCHGOT reg)
                    pprReg I32 reg ]
           ]
 
+    -- FETCHPC for PIC on Darwin/x86
+    -- get the instruction pointer into a register
+    -- (Terminology note: the IP is called Program Counter on PPC,
+    --  and it's a good thing to use the same name on both platforms)
+pprInstr (FETCHPC reg)
+   = vcat [ ptext SLIT("\tcall 1f"),
+            hcat [ ptext SLIT("1:\tpopl\t"), pprReg I32 reg ]
+          ]
+
+
+
 #endif
 
 -- -----------------------------------------------------------------------------
index 1987c28..bea7af0 100644 (file)
@@ -215,6 +215,7 @@ regUsage instr = case instr of
 #endif    
 
     FETCHGOT reg        -> mkRU [] [reg]
+    FETCHPC  reg        -> mkRU [] [reg]
 
     COMMENT _          -> noUsage
     DELTA   _           -> noUsage
@@ -539,7 +540,8 @@ patchRegs instr env = case instr of
     CALL (Right reg) p -> CALL (Right (env reg)) p
     
     FETCHGOT reg        -> FETCHGOT (env reg)
-    
+    FETCHPC  reg        -> FETCHPC  (env reg)
+   
     NOP                        -> instr
     COMMENT _          -> instr
     DELTA _            -> instr
index 007acca..ec12d79 100644 (file)
@@ -290,7 +290,7 @@ sub init_TARGET_STUFF {
     $T_HDR_vector   = "\t\.text\n\t\.align 2\n";
 
     #--------------------------------------------------------#
-    } elsif ( $TargetPlatform =~ /^powerpc-apple-.*/ ) {
+    } elsif ( $TargetPlatform =~ /^powerpc-apple-darwin.*/ ) {
                                # Apple PowerPC Darwin/MacOS X.
     $T_STABBY      = 0; # 1 iff .stab things (usually if a.out format)
     $T_US          = '_'; # _ if symbols have an underscore on the front
@@ -315,6 +315,34 @@ sub init_TARGET_STUFF {
     $T_HDR_vector   = "\t\.text\n\t\.align 2\n";
 
     #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^i386-apple-darwin.*/ ) {
+                               # Apple PowerPC Darwin/MacOS X.
+    $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     = 'DOESNT APPLY'; # regexp that says what comes before APP/NO_APP
+    $T_CONST_LBL    = '^\LC\d+:'; # regexp for what such a lbl looks like
+    $T_POST_LBL            = ':';
+    $T_X86_PRE_LLBL_PAT = 'L';
+    $T_X86_PRE_LLBL        = 'L';
+    $T_X86_BADJMP   = '^\tjmp [^L\*]';
+
+    $T_MOVE_DIRVS   = '^(\s*(\.align \d+|\.text|\.data|\.const_data|\.cstring|\.non_lazy_symbol_pointer|\.const|\.static_const|\.literal4|\.literal8|\.static_data|\.globl \S+|\.section .*|\.lcomm.*)\n)';
+    $T_COPY_DIRVS   = '\.(globl|lcomm)';
+
+    $T_DOT_WORD            = '\.(long|short|byte|fill|space)';
+    $T_DOT_GLOBAL   = '\.globl';
+    $T_HDR_toc      = "\.toc\n";
+    $T_HDR_literal  = "\t\.const\n\t\.align 2\n";
+    $T_HDR_misc            = "\t\.text\n\t\.align 2\n";
+    $T_HDR_data            = "\t\.data\n\t\.align 2\n";
+    $T_HDR_rodata   = "\t\.const\n\t\.align 2\n";
+    $T_HDR_relrodata= "\t\.const_data\n\t\.align 2\n";
+    $T_HDR_closure  = "\t\.data\n\t\.align 2\n";
+    $T_HDR_info            = "\t\.text\n\t\.align 2\n";
+    $T_HDR_entry    = "\t\.text\n\t\.align 2\n";
+    $T_HDR_vector   = "\t\.text\n\t\.align 2\n";
+
+    #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^powerpc-.*-linux/ ) {
                                # PowerPC Linux
     $T_STABBY      = 0; # 1 iff .stab things (usually if a.out format)
@@ -551,13 +579,13 @@ sub mangle_asm {
             # The .no_dead_strip directives are actually put there by
             # the gcc3 "used" attribute on entry points.
         
-        } elsif ( $TargetPlatform =~ /^powerpc-apple-.*/ && ( 
+        } elsif ( $TargetPlatform =~ /^.*-apple-darwin.*/ && ( 
                   /^\s*\.picsymbol_stub/
-               || /^\s*\.section __TEXT,__picsymbol_stub1,.*/
-               || /^\s*\.section __TEXT,__picsymbolstub1,.*/
+               || /^\s*\.section __TEXT,__picsymbol_stub\d,.*/
+               || /^\s*\.section __TEXT,__picsymbolstub\d,.*/
                || /^\s*\.symbol_stub/
-               || /^\s*\.section __TEXT,__symbol_stub1,.*/
-               || /^\s*\.section __TEXT,__symbolstub1,.*/
+               || /^\s*\.section __TEXT,__symbol_stub\d,.*/
+               || /^\s*\.section __TEXT,__symbolstub\d,.*/
                || /^\s*\.lazy_symbol_pointer/
                || /^\s*\.non_lazy_symbol_pointer/ ))
        {
@@ -565,7 +593,7 @@ sub mangle_asm {
            $chkcat[$i]  = 'dyld';
            $chksymb[$i] = '';
 
-       } elsif ( $TargetPlatform =~ /^powerpc-apple-.*/ && $chkcat[$i] eq 'dyld' && /^\s*\.data/)
+       } elsif ( $TargetPlatform =~ /^.*-apple-darwin.*/ && $chkcat[$i] eq 'dyld' && /^\s*\.data/)
        {       # non_lazy_symbol_ptrs that point to local symbols
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'dyld';
@@ -683,6 +711,15 @@ sub mangle_asm {
            $chkcat[$i]  = 'misc';
            $chksymb[$i] = $1;
 
+        } elsif ( $TargetPlatform =~ /^i386-apple-darwin/ && /^(___i686\.get_pc_thunk\.[abcd]x):/o) {
+                # To handle PIC on Darwin/x86, we need to appropriately pass through
+                # the get_pc_thunk functions. The need to be put into a special section
+                # marked as coalesced (otherwise the .weak_definition doesn't work
+                # on Darwin).
+            $chk[++$i]   = $_;
+            $chkcat[$i]  = 'get_pc_thunk';
+            $chksymb[$i] = $1;
+
        } elsif ( /^${T_US}[A-Za-z0-9_]/o
                && ( $TargetPlatform !~ /^hppa/ # need to avoid local labels in this case
                   || ! /^L\$\d+$/ ) 
@@ -801,6 +838,20 @@ sub mangle_asm {
                          $r = $& . $r;
                    }
 
+                    if ($TargetPlatform =~ /^i386-apple-darwin/) {
+                        $pcrel_label = $p;
+                        $pcrel_label =~ s/(.|\n)*^(\"?L\d+\$pb\"?):\n(.|\n)*/$2/ or $pcrel_label = "";
+                        $pcrel_reg = $p;
+                        $pcrel_reg =~ s/(.|\n)*.*___i686\.get_pc_thunk\.([abcd]x)\n(.|\n)*/$2/ or $pcrel_reg = "";
+                        $p =~ s/^\s+call\s+___i686\.get_pc_thunk\..x//;
+                        $p =~ s/^\"?L\d+\$pb\"?:\n//;
+
+                        if ($pcrel_reg eq "bx") {
+                            # Bad gcc. Goes and uses %ebx, our BaseReg, for PIC. Bad gcc.
+                            die "Darwin/x86: -fPIC -via-C doesn't work yet, use -fasm. Aborting."
+                        }
+                    }
+
                } 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;
@@ -843,7 +894,7 @@ sub mangle_asm {
                    $p =~ s/^\tsw\t\$fp,\d+\(\$sp\)\n//;
                    $p =~ s/^\tsw\t\$28,\d+\(\$sp\)\n//;
                    $p =~ s/__FRAME__/$FRAME/;
-               } elsif ($TargetPlatform =~ /^powerpc-apple-.*/) {
+               } elsif ($TargetPlatform =~ /^powerpc-apple-darwin.*/) {
                    $pcrel_label = $p;
                    $pcrel_label =~ s/(.|\n)*^(\"?L\d+\$pb\"?):\n(.|\n)*/$2/ or $pcrel_label = "";
 
@@ -921,7 +972,7 @@ sub mangle_asm {
                die "Prologue junk?: $p\n" if $p =~ /^\s+[^\s\.]/;
                
                 # For PIC, we want to keep part of the prologue
-               if ($TargetPlatform =~ /^powerpc-apple-.*/ && $pcrel_label ne "") {
+               if ($TargetPlatform =~ /^powerpc-apple-darwin.*/ && $pcrel_label ne "") {
                    # Darwin: load the current instruction pointer into register r31
                    $p .= "bcl 20,31,$pcrel_label\n";
                    $p .= "$pcrel_label:\n";
@@ -933,6 +984,9 @@ sub mangle_asm {
                     $p .= "\tmflr 30\n";
                     $p .= "\tlwz 0,.LCL$pcrel_label-.LCF$pcrel_label(30)\n";
                     $p .= "\tadd 30,0,30\n";
+                } elsif ($TargetPlatform =~ /^i386-apple-darwin.*/ && $pcrel_label ne "") {
+                    $p .= "\tcall ___i686.get_pc_thunk.$pcrel_reg\n";
+                    $p .= "$pcrel_label:\n";
                 }
                
                # glue together what's left
@@ -972,7 +1026,7 @@ sub mangle_asm {
                    $e =~ s/^\tlw\t\$fp,\d+\(\$sp\)\n//;
                    $e =~ s/^\taddu\t\$sp,\$sp,\d+\n//;
                    $e =~ s/^\tj\t\$31\n//;
-               } elsif ($TargetPlatform =~ /^powerpc-apple-.*/) {
+               } elsif ($TargetPlatform =~ /^powerpc-apple-darwin.*/) {
                    $e =~ s/^\taddi r1,r1,\d+\n//;
                    $e =~ s/^\tlwz r\d+,\d+\(r1\)\n//; 
                    $e =~ s/^\tlmw r\d+,-\d+\(r1\)\n//;
@@ -1023,9 +1077,10 @@ sub mangle_asm {
        # toss all calls to __DISCARD__
        $c =~ s/^\t(call|jbsr|jal)\s+${T_US}__DISCARD__\n//go;
        $c =~ s/^\tjsr\s+\$26\s*,\s*${T_US}__DISCARD__\n//go if $TargetPlatform =~ /^alpha-/;
-       $c =~ s/^\tbl\s+L___DISCARD__\$stub\n//go if $TargetPlatform =~ /^powerpc-apple-.*/;
+       $c =~ s/^\tbl\s+L___DISCARD__\$stub\n//go if $TargetPlatform =~ /^powerpc-apple-darwin.*/;
        $c =~ s/^\tbl\s+__DISCARD__(\@plt)?\n//go if $TargetPlatform =~ /^powerpc-.*-linux/;
        $c =~ s/^\tbl\s+\.__DISCARD__\n\s+nop\n//go if $TargetPlatform =~ /^powerpc64-.*-linux/;
+       $c =~ s/^\tcall\s+L___DISCARD__\$stub\n//go if $TargetPlatform =~ /i386-apple-darwin.*/;
 
        # IA64: mangle tailcalls into jumps here
        if ($TargetPlatform =~ /^ia64-/) {
@@ -1321,12 +1376,16 @@ sub mangle_asm {
                 $j++;
            }
            
-       } elsif ( $TargetPlatform =~ /^powerpc-apple-.*/ && $chkcat[$i] eq 'dyld' ) {
-           # powerpc-apple: dynamic linker stubs
+       } elsif ( $TargetPlatform =~ /^.*-apple-darwin.*/ && $chkcat[$i] eq 'dyld' ) {
+           # apple-darwin: dynamic linker stubs
            if($chk[$i] !~ /\.indirect_symbol ___DISCARD__/)
            {   # print them out unchanged, but remove the stubs for __DISCARD__
                print OUTASM $chk[$i];
            }
+        } elsif ( $TargetPlatform =~ /^i386-apple-darwin.*/ && $chkcat[$i] eq 'get_pc_thunk' ) {
+            # i386-apple-darwin: __i686.get_pc_thunk.[abcd]x
+            print OUTASM ".section __TEXT,__textcoal_nt,coalesced,no_toc\n";
+            print OUTASM $chk[$i];
        } else {
            &tidy_up_and_die(1,"$Pgm: unknown chkcat (ghc-asm: $TargetPlatform)\n$chkcat[$i]\n$chk[$i]\n");
        }
index 4d5136f..46e573c 100644 (file)
@@ -114,6 +114,12 @@ StgFunPtr StgReturn(void)
 
 #ifdef i386_HOST_ARCH
 
+#ifdef darwin_TARGET_OS
+#define STG_GLOBAL ".globl "
+#else
+#define STG_GLOBAL ".global "
+#endif
+
 StgThreadReturnCode
 StgRun(StgFunPtr f, StgRegTable *basereg) {
 
@@ -140,7 +146,7 @@ StgRun(StgFunPtr f, StgRegTable *basereg) {
         "movl %2,%%eax\n\t"
         "jmp *%%eax\n\t"
 
-       ".global " STG_RETURN "\n"
+       STG_GLOBAL STG_RETURN "\n"
                STG_RETURN ":\n\t"
 
        "movl %%esi, %%eax\n\t"   /* Return value in R1  */