X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdriver%2Fmangler%2Fghc-asm.lprl;h=6e292791782b41151217a6a6290af35a239f1f2f;hb=5c26ae929ebdf93b0a7d4b153805ad3118256344;hp=259d6add56afac457545d1ff6e5cd05cec7e6515;hpb=b4d045ae655e5eae25b88917cfe75d7dc7689c21;p=ghc-hetmet.git diff --git a/ghc/driver/mangler/ghc-asm.lprl b/ghc/driver/mangler/ghc-asm.lprl index 259d6ad..6e29279 100644 --- a/ghc/driver/mangler/ghc-asm.lprl +++ b/ghc/driver/mangler/ghc-asm.lprl @@ -146,7 +146,7 @@ sub init_TARGET_STUFF { $T_X86_PRE_LLBL = 'L'; $T_X86_BADJMP = '^\tjmp [^L\*]'; - $T_MOVE_DIRVS = '^(\s*(\.(p2)?align\s+\d+(,0x90)?|\.globl\s+\S+|\.text|\.data|\.stab[^n].*|\.type\s+.*|\.size\s+.*|\.lcomm.*)\n)'; + $T_MOVE_DIRVS = '^(\s*(\.(p2)?align\s.*|\.globl\s+\S+|\.text|\.data|\.stab[^n].*|\.type\s+.*|\.size\s+.*|\.lcomm.*)\n)'; $T_COPY_DIRVS = '\.(globl|stab|lcomm)'; $T_DOT_WORD = '\.(long|word|value|byte|space)'; $T_DOT_GLOBAL = '\.globl'; @@ -172,7 +172,7 @@ 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+.*|\.size\s+\S+\s*,\s*\d+|\.ident.*|\.local.*)\n)'; + $T_MOVE_DIRVS = '^(\s*(\.(p2)?align\s.*|\.globl\s+\S+|\.text|\.data|\.section\s+.*|\.type\s+.*|\.size\s+\S+\s*,\s*\d+|\.ident.*|\.local.*)\n)'; $T_COPY_DIRVS = '^\s*\.(globl|type|size|local)'; $T_DOT_WORD = '\.(long|value|word|byte|zero)'; @@ -293,11 +293,12 @@ 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_data\n\t\.align 2\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_data\n\t\.align 2\n"; - $T_HDR_closure = "\t\.const_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"; @@ -327,6 +328,30 @@ sub init_TARGET_STUFF { $T_HDR_vector = "\t\.text\n\t\.align 2\n"; #--------------------------------------------------------# + } elsif ( $TargetPlatform =~ /^powerpc64-.*-linux/ ) { + # PowerPC 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 = '^#'; # 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_MOVE_DIRVS = '^(\s*(\.(p2)?align\s+\d+(,\s*0x90)?|\.globl\s+\S+|\.text|\.data|\.section\s+.*|\.type\s+.*|\.size\s+\S+\s*,\s*\d+|\.ident.*|\.local.*)\n)'; + $T_COPY_DIRVS = '^\s*\.(globl|type|size|local)'; + + $T_DOT_WORD = '\.(long|short|byte|fill|space)'; + $T_DOT_GLOBAL = '\.globl'; + $T_HDR_toc = "\.toc\n"; + $T_HDR_literal = "\t\.section\t\".toc\",\"aw\"\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\.section\t.rodata\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 =~ /^sparc-.*-(solaris2|openbsd)/ ) { $T_STABBY = 0; # 1 iff .stab things (usually if a.out format) @@ -381,7 +406,7 @@ 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|\.seg|\.stab.*|\t?\.section.*|\s+\.type.*|\s+\.size.*)\n)'; + $T_MOVE_DIRVS = '^((\s+\.align\s+\d+|\s+\.proc\s+\d+|\s+\.global\s+\S+|\.text|\.data|\.seg|\.stab.*|\s+?\.section.*|\s+\.type.*|\s+\.size.*)\n)'; $T_COPY_DIRVS = '\.(global|globl|proc|stab)'; $T_DOT_WORD = '\.(long|word|nword|xword|byte|half|short|skip|uahalf|uaword)'; @@ -401,6 +426,12 @@ sub init_TARGET_STUFF { exit 1; } + if($T_HDR_relrodata eq "") { + # default values: + # relrodata defaults to rodata. + $T_HDR_relrodata = $T_HDR_rodata; + } + if ( 0 ) { print STDERR "T_STABBY: $T_STABBY\n"; print STDERR "T_US: $T_US\n"; @@ -500,7 +531,14 @@ sub mangle_asm { $chk[++$i] = $_; $chkcat[$i] = 'rodata'; $chksymb[$i] = ''; - + } elsif ( $TargetPlatform =~ /-darwin/ + && (/^\s*\.subsections_via_symbols/ + ||/^\s*\.no_dead_strip.*/)) { + # Don't allow Apple's linker to do any dead-stripping of symbols + # in this file, because it will mess up info-tables in mangled + # code. + # The .no_dead_strip directives are actually put there by + # the gcc3 "used" attribute on entry points. } elsif ( /^\s+/ ) { # most common case first -- a simple line! # duplicated from the bottom @@ -509,7 +547,6 @@ sub mangle_asm { } elsif ( /\.\.ng:$/ && $TargetPlatform =~ /^alpha-/ ) { # Alphas: Local labels not to be confused with new chunks $chk[$i] .= $_; - # NB: all the rest start with a non-space } elsif ( $TargetPlatform =~ /^mips-/ @@ -616,7 +653,9 @@ sub mangle_asm { } elsif ( /^${T_US}[A-Za-z0-9_]/o && ( $TargetPlatform !~ /^hppa/ # need to avoid local labels in this case - || ! /^L\$\d+$/ ) ) { + || ! /^L\$\d+$/ ) + && ( $TargetPlatform !~ /^powerpc64/ # we need to avoid local labels in this case + || ! /^\.L\d+:$/ ) ) { local($thing); chop($thing = $_); $thing =~ s/:$//; @@ -629,16 +668,22 @@ sub mangle_asm { || /^${T_US}.*_slow${T_POST_LBL}$/o # slow entry || /^${T_US}__stginit.*${T_POST_LBL}$/o # __stginit || /^${T_US}.*_btm${T_POST_LBL}$/o # large bitmaps - || /^${T_US}.*_srtd${T_POST_LBL}$/o # large bitmaps || /^${T_US}.*_fast${T_POST_LBL}$/o # primops - || /^${T_US}.*_closure_tbl${T_POST_LBL}$/o # closure tables || /^_uname:/o # x86/Solaris2 - ) { - $chkcat[$i] = 'misc'; - } else { - print STDERR "Warning: retaining unknown function \`$thing' in output from C compiler\n"; - $chkcat[$i] = 'unknown'; - } + ) + { + $chkcat[$i] = 'misc'; + } elsif ( + /^${T_US}.*_srtd${T_POST_LBL}$/o # large bitmaps + || /^${T_US}.*_closure_tbl${T_POST_LBL}$/o # closure tables + ) + { + $chkcat[$i] = 'relrodata'; + } else + { + print STDERR "Warning: retaining unknown function \`$thing' in output from C compiler\n"; + $chkcat[$i] = 'unknown'; + } } elsif ( $TargetPlatform =~ /^powerpc-apple-.*/ && ( /^\.picsymbol_stub/ @@ -823,6 +868,30 @@ sub mangle_asm { # I have no idea why, and I don't think it is necessary, so let's toss it. $p =~ s/^\tli \d+,0\n//g; $p =~ s/^\tstw \d+,\d+\(1\)\n//g; + } elsif ($TargetPlatform =~ /^powerpc64-.*-linux/) { + $p =~ s/^\tmr 31,1\n//; + $p =~ s/^\tmflr 0\n//; + $p =~ s/^\tstmw \d+,\d+\(1\)\n//; + $p =~ s/^\tstfd \d+,-?\d+\(1\)\n//g; + $p =~ s/^\tstd r0,8\(1\)\n//; + $p =~ s/^\tstdu 1,-\d+\(1\)\n//; + $p =~ s/^\tstd \d+,-?\d+\(1\)\n//g; + + # GCC's "large-model" PIC (-fPIC) + $pcrel_label = $p; + $pcrel_label =~ s/(.|\n)*^.LCF(\d+):\n(.|\n)*/$2/ or $pcrel_label = ""; + + $p =~ s/^\tbcl 20,31,.LCF\d+\n//; + $p =~ s/^.LCF\d+:\n//; + $p =~ s/^\tmflr 30\n//; + $p =~ s/^\tlwz 0,\.LCL\d+-\.LCF\d+\(30\)\n//; + $p =~ s/^\tadd 30,0,30\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 \d+,0\n//g; + $p =~ s/^\tstd \d+,\d+\(1\)\n//g; } else { print STDERR "$Pgm: unknown prologue mangling? $TargetPlatform\n"; } @@ -890,6 +959,21 @@ sub mangle_asm { $e =~ s/^\tmtlr r0\n//; $e =~ s/^\tblr\n//; $e =~ s/^\tb restFP ;.*\n//; + } elsif ($TargetPlatform =~ /^powerpc64-.*-linux/) { + $e =~ s/^\tmr 3,0\n//; + $e =~ s/^\taddi 1,1,\d+\n//; + $e =~ s/^\tld 0,16\(1\)\n//; + $e =~ s/^\tmtlr 0\n//; + + # callee-save registers + $e =~ s/^\tld \d+,-?\d+\(1\)\n//g; + $e =~ s/^\tlfd \d+,-?\d+\(1\)\n//g; + + # get rid of the debug junk along with the blr + $e =~ s/^\tblr\n\t.long .*\n\t.byte .*\n//; + + # incase we missed it with the last one get the blr alone + $e =~ s/^\tblr\n//; } else { print STDERR "$Pgm: unknown epilogue mangling? $TargetPlatform\n"; } @@ -921,6 +1005,7 @@ sub mangle_asm { $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+__DISCARD__(\@plt)?\n//go if $TargetPlatform =~ /^powerpc-.*-linux/; + $c =~ s/^\tbl\s+\.__DISCARD__\n\s+nop\n//go if $TargetPlatform =~ /^powerpc64-.*-linux/; # IA64: mangle tailcalls into jumps here if ($TargetPlatform =~ /^ia64-/) { @@ -1108,7 +1193,7 @@ sub mangle_asm { # SRT if ( defined($srtchk{$symb}) ) { - print OUTASM $T_HDR_rodata; + print OUTASM $T_HDR_relrodata; print OUTASM $chk[$srtchk{$symb}]; $chkcat[$srtchk{$symb}] = 'DONE ALREADY'; } @@ -1132,8 +1217,23 @@ sub mangle_asm { # If this is an entry point with an info table, # eliminate the entry symbol and all directives involving it. if (defined($infochk{$symb}) && $TargetPlatform !~ /^ia64-/) { - $c =~ s/^.*$symb_(entry|ret)${T_POST_LBL}\n//; - $c =~ s/^\s*\..*$symb.*\n//g; + @o = (); + foreach $l (split(/\n/,$c)) { + next if $l =~ /^.*$symb_(entry|ret)${T_POST_LBL}/; + + # If we have .type/.size direrctives involving foo_entry, + # then make them refer to foo_info instead. The information + # in these directives is used by the cachegrind annotator, + # so it is worthwhile keeping. + if ($l =~ /^\s*\.(type|size).*$symb_(entry|ret)/) { + $l =~ s/$symb(_entry|_ret)/${symb}_info/g; + push(@o,$l); + next; + } + next if $l =~ /^\s*\..*$symb.*\n?/; + push(@o,$l); + } + $c = join("\n",@o) . "\n"; } print OUTASM $T_HDR_entry; @@ -1168,7 +1268,10 @@ sub mangle_asm { print OUTASM $T_HDR_rodata; print OUTASM $chk[$i]; $chkcat[$i] = 'DONE ALREADY'; - + } elsif ( $chkcat[$i] eq 'relrodata' ) { + print OUTASM $T_HDR_relrodata; + print OUTASM $chk[$i]; + $chkcat[$i] = 'DONE ALREADY'; } elsif ( $chkcat[$i] eq 'toc' ) { # silly optimisation to print tocs, since they come in groups... print OUTASM $T_HDR_toc; @@ -1275,8 +1378,16 @@ sub print_doctored { # movl $_blah, # jmp * # + s/^\tmovl\s+\$${T_US}(.*),\s*(\%e[acd]x)\n\tjmp\s+\*\2/\tjmp $T_US$1/g; - s/^\tmovl\s+\$${T_US}(.*),\s*(\%e[abcd]x)\n\tjmp\s+\*\2/\tjmp $T_US$1/g; + # Catch things like + # + # movl -4(%ebx), %eax + # jmp *%eax + # + # and optimise: + # + s/^\tmovl\s+(-?\d*\(\%e(bx|si)\)),\s*(\%e[acd]x)\n\tjmp\s+\*\3/\tjmp\t\*$1/g; if ($StolenX86Regs <= 2 ) { # YURGH! spurious uses of esi? s/^\tmovl\s+(.*),\s*\%esi\n\tjmp\s+\*%esi\n/\tmovl $1,\%eax\n\tjmp \*\%eax\n/g;