[project @ 2002-09-25 21:30:26 by wolfgang]
[ghc-hetmet.git] / ghc / driver / mangler / ghc-asm.lprl
index 1edd32f..6d227df 100644 (file)
@@ -96,8 +96,8 @@ sub init_TARGET_STUFF {
     $T_CONST_LBL    = '^\$L?C(\d+):$'; # regexp for what such a lbl looks like
     $T_POST_LBL            = ':';
 
-    $T_MOVE_DIRVS   = '^(\s*(\.align\s+\d+|\.(globl|ent)\s+\S+|\#.*|\.(file|loc)\s+\S+\s+\S+|\.text|\.r?data)\n)';
-    $T_COPY_DIRVS   = '^\s*(\#|\.(file|globl|ent|loc))';
+    $T_MOVE_DIRVS   = '^(\s*(\$.*\.\.ng:|\.align\s+\d+|\.(globl|ent)\s+\S+|\#.*|\.(file|loc)\s+\S+\s+\S+|\.text|\.r?data)\n)';
+    $T_COPY_DIRVS   = '^\s*(\$.*\.\.ng:|\#|\.(file|globl|ent|loc))';
 
     $T_hsc_cc_PAT   = '\.ascii.*\)(hsc|cc) (.*)\\\\11"\n\t\.ascii\s+"(.*)\\\\0"';
     $T_DOT_WORD            = '\.(long|quad|byte|word)';
@@ -188,8 +188,8 @@ sub init_TARGET_STUFF {
     $T_X86_PRE_LLBL        = '.L';
     $T_X86_BADJMP   = '^\tjmp\s+[^\.\*]';
 
-    $T_MOVE_DIRVS   = '^(\s*(\.(p2)?align\s+\d+(,\s*0x90)?|\.globl\s+\S+|\.text|\.data|\.section\s+.*|\.type\s+.*|\.Lfe.*\n\s*\.size\s+.*|\.size\s+.*|\.ident.*)\n)';
-    $T_COPY_DIRVS   = '\.(globl)';
+    $T_MOVE_DIRVS   = '^(\s*(\.(p2)?align\s+\d+(,\s*0x90)?|\.globl\s+\S+|\.text|\.data|\.section\s+.*|\.type\s+.*|\.size\s+\S+,\d+|\.ident.*)\n)';
+    $T_COPY_DIRVS   = '^\s*\.(globl|type|size)';
 
     if ( $TargetPlatform =~ /freebsd|netbsd/ ) {
         $T_hsc_cc_PAT   = '\.ascii.*\)(hsc|cc) (.*)\\\\11"\n\t\.ascii\s+"(.*)\\\\0"';
@@ -613,7 +613,8 @@ sub mangle_asm {
                   || ! /^L\$\d+$/ ) ) {
            local($thing);
            chop($thing = $_);
-           print STDERR "Funny global thing?: $_"
+           $thing =~ s/:$//;
+           print STDERR "Warning: retaining unknown function \`$thing' in output from C compiler\n"
                unless # $KNOWN_FUNNY_THING{$thing}
                       /^${T_US}stg_.*${T_POST_LBL}$/o          # RTS internals
                    || /^${T_US}__stg_.*${T_POST_LBL}$/o        # more RTS internals
@@ -631,6 +632,11 @@ sub mangle_asm {
            $chk[++$i]   = $_;
            $chkcat[$i]  = 'dyld';
            $chksymb[$i] = '';
+       } elsif ( $TargetPlatform =~ /^powerpc-apple-.*/ && /^\.symbol_stub/ )
+       {
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'dyld';
+           $chksymb[$i] = '';
        } elsif ( $TargetPlatform =~ /^powerpc-apple-.*/ && /^\.lazy_symbol_pointer/ )
        {
            $chk[++$i]   = $_;
@@ -700,13 +706,15 @@ sub mangle_asm {
                    $p =~ s/^\tpushl\s+\%edi\n//;
                    $p =~ s/^\tpushl\s+\%esi\n//;
                    $p =~ s/^\tpushl\s+\%ebx\n//;
+                   $p =~ s/^\tmovl\s+\%esi,\s*\d*\(\%esp\)\n//;
+                   $p =~ s/^\tmovl\s+\%edi,\s*\d*\(\%esp\)\n//;
                    $p =~ s/^\tsubl\s+\$\d+,\s*\%esp\n//;
                     $p =~ s/^\tmovl\s+\$\d+,\s*\%eax\n\tcall\s+__alloca\n// if ($TargetPlatform =~ /^.*-cygwin32/);
 
                    # GCC 3.1 is in the habit of adding spurious writes to the
                    # stack in the prologue.  Just to be on the safe side,
                    # chuck these over the fence into the main code.
-                   while ($p =~ /^\tmovl\s+(\$\d+|\%edi),\s*\d*\(\%esp\)\n/) {
+                   while ($p =~ /^\tmovl\s+\$\d+,\s*\d*\(\%esp\)\n/) {
                          # print "Spurious instruction: $&";
                          $p = $` . $';
                          $r = $& . $r;
@@ -759,6 +767,12 @@ sub mangle_asm {
                    $p =~ s/^\tbcl 20,31,L\d+\$pb\n//;
                    $p =~ s/^L\d+\$pb:\n//;
                    $p =~ s/^\tmflr r31\n//;
+
+                   # This is bad: GCC 3 seems to zero-fill some local variables in the prologue
+                   # under some circumstances, only when generating position dependent code.
+                   # I have no idea why, and I don't think it is necessary, so let's toss it.
+                   $p =~ s/^\tli r\d+,0\n//g;
+                   $p =~ s/^\tstw r\d+,\d+\(r1\)\n//g;
                } else {
                    print STDERR "$Pgm: unknown prologue mangling? $TargetPlatform\n";
                }
@@ -908,16 +922,18 @@ sub mangle_asm {
        if ( $TargetPlatform =~ /^alpha-/ && $c =~ /^\t\.ent\s+(\S+)/ ) {
            $ent = $1;
            # toss all prologue stuff, except for loading gp, and the ..ng address
-           if (($p, $r) = split(/^\t\.prologue/, $c)) {
-               if (($keep, $junk) = split(/\.\.ng:/, $p)) {
-                   $keep =~ s/^\t\.frame.*\n/\t.frame \$30,0,\$26,0\n/;
-                   $keep =~ s/^\t\.(mask|fmask).*\n//g;
-                   $c = $keep . "..ng:\n";
-               } else {
-                   print STDERR "malformed code block ($ent)?\n"
-               }
-           }
-           $c .= "\t.prologue" . $r;
+           unless ($c =~ /\.ent.*\n\$.*\.\.ng:/) {
+               if (($p, $r) = split(/^\t\.prologue/, $c)) {
+                   if (($keep, $junk) = split(/\.\.ng:/, $p)) {
+                       $keep =~ s/^\t\.frame.*\n/\t.frame \$30,0,\$26,0\n/;
+                       $keep =~ s/^\t\.(mask|fmask).*\n//g;
+                       $c = $keep . "..ng:\n";
+                   } else {
+                       print STDERR "malformed code block ($ent)?\n"
+                   }
+               }
+               $c .= "\t.prologue" . $r;
+           }
        }
   
        $c =~ s/FUNNY#END#THING//;
@@ -1107,11 +1123,37 @@ sub mangle_asm {
                        $c =~ s/^\tjmp ${T_US}${symb}_fast\d+.*\n\tnop\n//;
                        $c =~ s/^\tjmp ${T_US}${symb}_fast\d+.*\n//;
                    } elsif ( $TargetPlatform =~ /^powerpc-apple-.*/ ) {
-                       $c =~ s/^\taddis r9,r31,ha16\(L_${symb}_fast\d*\$non_lazy_ptr-L\d+\$pb\)\n\tlwz r9,lo16\(L_${symb}_fast\d*\$non_lazy_ptr-L\d+\$pb\)\(r9\)\n\tmtctr r9\n\tbctr\n//;
-                               #       addis r9,r31,ha16(L_XXXX_fast3$non_lazy_ptr-L32$pb)
-                               #       lwz r9,lo16(L_XXXX_fast3$non_lazy_ptr-L32$pb)(r9)
+                       if ( $c =~ s/^\taddis r9,r31,ha16\(L_${symb}_fast\d*\$non_lazy_ptr-L\d+\$pb\)\n\tlwz r9,lo16\(L_${symb}_fast\d*\$non_lazy_ptr-L\d+\$pb\)\(r9\)\n\tmtctr r9\n\tbctr$// ) {
+                               #       for Position-Independent Code, GCC 2:
+                               #       addis r9,r31,ha16(L_XXXX_fast3$non_lazy_ptr-Lxxx$pb)
+                               #       lwz r9,lo16(L_XXXX_fast3$non_lazy_ptr-Lxxx$pb)(r9)
                                #       mtctr r9
                                #       bctr
+                       
+                       } elsif ( $c =~ s/^\taddis r9,r31,ha16\(L_${symb}_fast\d*\$non_lazy_ptr-L\d+\$pb\)\n\tlwz r29,lo16\(L_${symb}_fast\d*\$non_lazy_ptr-L\d+\$pb\)\(r9\)\nL(\d+):\n\tmtctr r29\n\tbctr$// ) {
+                               #       for Position-Independent Code, GCC 3:
+                               #       addis r9,r31,ha16(L_XXXX_fast3$non_lazy_ptr-Lxxx$pb)
+                               #       lwz r29,lo16(L_XXXX_fast3$non_lazy_ptr-Lxxx$pb)(r9)
+                               # Lyyy:
+                               #       mtctr r29
+                               #       bctr
+                           $label = $1;
+                           $c =~ s/^\tb L${label}\n/\tmtctr r29\n\tbctr\n/g;
+                       } elsif ( $c =~ s/^\tlis r9,ha16\(L_${symb}_fast\d*\$non_lazy_ptr\)\n\tlwz r31,lo16\(L_${symb}_fast\d*\$non_lazy_ptr\)\(r9\)\nL(\d+):\n\tmtctr r31\n\tbctr$// ) {
+                               #       for -mdynamic-no-pic Code, GCC 3:
+                               #       lis r9,ha16(L_XXXX_fast3$non_lazy_ptr)
+                               #       lwz r31,lo16(L_XXXX_fast3$non_lazy_ptr-Lxxx$pb)(r9)
+                               # Lyyy:
+                               #       mtctr r31
+                               #       bctr
+                           $label = $1;
+                           $c =~ s/^\tb L${label}\n/\tmtctr r31\n\tbctr\n/g;
+                       } else {
+                           
+                           print STDERR "slow-fast dropthrough not mangled\n";
+                           print STDERR $c;
+                           print STDERR "\n\n";
+                       }
                    } elsif ( $TargetPlatform =~ /^sparc-/ ) {
                        $c =~ s/^\tcall\s+${T_US}${symb}_fast\d+,.*\n\t\s*nop\n//;
                        $c =~ s/^\tcall\s+${T_US}${symb}_fast\d+,.*\n(\t\s*[a-z].*\n)/$1/;