[project @ 2005-10-31 11:31:10 by simonmar]
[ghc-hetmet.git] / ghc / driver / mangler / ghc-asm.lprl
index ec12d79..3406419 100644 (file)
@@ -332,7 +332,8 @@ sub init_TARGET_STUFF {
     $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_literal16= "\t\.literal8\n\t\.align 4\n";
+    $T_HDR_literal  = "\t\.const\n\t\.align 4\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";
@@ -399,8 +400,8 @@ sub init_TARGET_STUFF {
     $T_CONST_LBL    = '^\.LLC(\d+):$'; # regexp for what such a lbl looks like
     $T_POST_LBL            = ':';
 
-    $T_MOVE_DIRVS   = '^((\s+\.align\s+\d+|\s+\.proc\s+\d+|\s+\.global\s+\S+|\.text|\.data|\.stab.*|\s*\.section.*|\s+\.type.*|\s+\.size.*)\n)';
-    $T_COPY_DIRVS   = '\.(global|proc|stab)';
+    $T_MOVE_DIRVS   =  '^((\s+\.align\s+\d+|\s+\.proc\s+\d+|\s+\.global\s+\S+|\s+\.local\s+\S+|\.text|\.data|\.stab.*|\s*\.section.*|\s+\.type.*|\s+\.size.*)\n)';
+    $T_COPY_DIRVS   = '\.(global|local|proc|stab)';
 
     $T_DOT_WORD            = '\.(long|word|byte|half|skip|uahalf|uaword)';
     $T_DOT_GLOBAL   = '^\t\.global';
@@ -1211,8 +1212,9 @@ sub mangle_asm {
 
            # HACK: try to detect 16-byte constants and align them
            # on a 16-byte boundary.  x86_64 sometimes needs 128-bit
-           # aligned constants.
-           if ( $TargetPlatform =~ /^x86_64/ ) { 
+           # aligned constants, and so does Darwin/x86.
+           if ( $TargetPlatform =~ /^x86_64/
+                || $TargetPlatform =~ /^i386-apple-darwin/ ) { 
                $z = $chk[$i];
                if ($z =~ /(\.long.*\n.*\.long.*\n.*\.long.*\n.*\.long|\.quad.*\n.*\.quad)/) {
                    print OUTASM $T_HDR_literal16;
@@ -1428,12 +1430,25 @@ sub hppa_mash_prologue { # OK, epilogue, too
 sub print_doctored {
     local($_, $need_fallthru_patch) = @_;
 
+    if ( $TargetPlatform =~ /^x86_64-/ ) {
+           # Catch things like
+           #   
+           #    movq -4(%ebp), %rax
+           #    jmp  *%rax
+           # 
+           # and optimise:
+           #
+           s/^\tmovq\s+(-?\d*\(\%r(bx|bp|13)\)),\s*(\%r(ax|cx|dx|10|11))\n\tjmp\s+\*\3/\tjmp\t\*$1/g;
+           s/^\tmovl\s+\$${T_US}(.*),\s*(\%e(ax|cx|si|di))\n\tjmp\s+\*\%r\3/\tjmp\t$T_US$1/g;
+    }
+
     if ( $TargetPlatform !~ /^i386-/ 
       || ! /^\t[a-z]/  # no instructions in here, apparently
       || /^${T_US}__stginit_[A-Za-z0-9_]+${T_POST_LBL}/) {
        print OUTASM $_;
        return;
     }
+
     # OK, must do some x86 **HACKING**
 
     local($entry_patch)        = '';
@@ -1532,6 +1547,16 @@ sub print_doctored {
 
     # fix _all_ non-local jumps:
 
+    if ( $TargetPlatform =~ /^.*-apple-darwin.*/ ) {
+        # On Darwin, we've got local-looking jumps that are
+        # actually global (i.e. jumps to Lfoo$stub or via
+        # Lfoo$non_lazy_ptr), so we fix those first.
+        # In fact, we just fix everything that contains a dollar
+        # because false positives don't hurt here.
+
+        s/^(\tjmp\s+\*?L.*\$.*\n)/$exit_patch$1/g;
+    }
+
     s/^\tjmp\s+\*${T_X86_PRE_LLBL_PAT}/\tJMP___SL/go;
     s/^\tjmp\s+${T_X86_PRE_LLBL_PAT}/\tJMP___L/go;