X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdriver%2Fmangler%2Fghc-asm.lprl;h=760175a5751c22f47fe5e305db24f1ccec8af787;hb=6f917d9600e7e5ba63a33f4079bcbc6ebbdb10fb;hp=cd142dbad32184f472ecb2371aab1730d2acf38d;hpb=4302b12e6fd876a190ce6091e6ce14dbeb15bc00;p=ghc-hetmet.git diff --git a/ghc/driver/mangler/ghc-asm.lprl b/ghc/driver/mangler/ghc-asm.lprl index cd142db..760175a 100644 --- a/ghc/driver/mangler/ghc-asm.lprl +++ b/ghc/driver/mangler/ghc-asm.lprl @@ -160,7 +160,7 @@ sub init_TARGET_STUFF { $T_HDR_vector = "\.text\n\t\.align 2\n"; # NB: requires padding #--------------------------------------------------------# - } elsif ( $TargetPlatform =~ /^i386-.*-(solaris2|linux|gnu|freebsd|netbsd|openbsd)$/ ) { + } elsif ( $TargetPlatform =~ /^i386-.*-(solaris2|linux|gnu|freebsd|netbsd|openbsd|kfreebsdgnu)$/ ) { $T_STABBY = 0; # 1 iff .stab things (usually if a.out format) $T_US = ''; # _ if symbols have an underscore on the front @@ -400,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'; @@ -822,23 +822,27 @@ 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//; + # gcc 3.4.3 puts this kind of stuff in the prologue, eg. + # when compiling PrimOps.cmm with -optc-O2: + # xorl %ecx, %ecx + # xorl %edx, %edx + # movl %ecx, 16(%esp) + # movl %edx, 20(%esp) + # but then the code of the function doesn't assume + # anything about the contnets of these stack locations. + # I think it's to do with the use of inline functions for + # PK_Word64() and friends, where gcc is initialising the + # contents of the struct to zero, and failing to optimise + # away the initialisation. Let's live dangerously and + # discard these initalisations. + + $p =~ s/^\tpushl\s+\%e(di|si|bx)\n//g; + $p =~ s/^\txorl\s+\%e(ax|cx|dx),\s*\%e(ax|cx|dx)\n//g; + $p =~ s/^\tmovl\s+\%e(ax|cx|dx|si|di),\s*\d*\(\%esp\)\n//g; + $p =~ s/^\tmovl\s+\$\d+,\s*\d*\(\%esp\)\n//g; $p =~ s/^\tsubl\s+\$\d+,\s*\%esp\n//; $p =~ s/^\tmovl\s+\$\d+,\s*\%eax\n\tcall\s+__alloca\n// if ($TargetPlatform =~ /^.*-(cygwin32|mingw32)/); - # 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+,\s*\d*\(\%esp\)\n/) { - # print "Spurious instruction: $&"; - $p = $` . $'; - $r = $& . $r; - } - if ($TargetPlatform =~ /^i386-apple-darwin/) { $pcrel_label = $p; $pcrel_label =~ s/(.|\n)*^(\"?L\d+\$pb\"?):\n(.|\n)*/$2/ or $pcrel_label = ""; @@ -1430,12 +1434,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) = '';