$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';
$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)';
$T_DOT_WORD = '\.(quad|long|value|byte|zero)';
$T_DOT_GLOBAL = '\.global';
+
+ $T_HDR_literal16 = "\.section\t\.rodata.cst16\n\t.align 16\n";
$T_HDR_literal = "\.section\t\.rodata\n";
+
$T_HDR_misc = "\.text\n\t\.align 8\n";
$T_HDR_data = "\.data\n\t\.align 8\n";
$T_HDR_rodata = "\.section\t\.rodata\n\t\.align 8\n";
+
+ # the assembler on x86_64/Linux refuses to generate code for
+ # .quad x - y
+ # where x is in the text section and y in the rodata section.
+ # It works if y is in the text section, though. This is probably
+ # going to cause difficulties for PIC, I imagine.
+ $T_HDR_relrodata= "\.text\n\t\.align 8\n";
+
$T_HDR_closure = "\.data\n\t\.align 8\n";
$T_HDR_info = "\.text\n\t\.align 8\n";
$T_HDR_entry = "\.text\n\t\.align 8\n";
$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.*|\.section.*|\s+\.type.*|\s+\.size.*)\n)';
+ $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_DOT_WORD = '\.(long|word|byte|half|skip|uahalf|uaword)';
$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
} elsif ( /\.\.ng:$/ && $TargetPlatform =~ /^alpha-/ ) {
# Alphas: Local labels not to be confused with new chunks
$chk[$i] .= $_;
- } elsif ( $TargetPlatform =~ /-darwin/
- && /^\t\.subsections_via_symbols/) {
- # 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.
-
# NB: all the rest start with a non-space
} elsif ( $TargetPlatform =~ /^mips-/
# print out all the literal strings next
for ($i = 0; $i < $numchks; $i++) {
if ( $chkcat[$i] eq 'literal' ) {
- print OUTASM $T_HDR_literal, $chk[$i];
+
+ # 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/ ) {
+ $z = $chk[$i];
+ if ($z =~ /(\.long.*\n.*\.long.*\n.*\.long.*\n.*\.long|\.quad.*\n.*\.quad)/) {
+ print OUTASM $T_HDR_literal16;
+ } else {
+ print OUTASM $T_HDR_literal;
+ }
+ } else {
+ print OUTASM $T_HDR_literal;
+ }
+
+ print OUTASM $chk[$i];
print OUTASM "; end literal\n" if $TargetPlatform =~ /^hppa/; # for the splitter
$chkcat[$i] = 'DONE ALREADY';
# 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;
# movl $_blah,<bad-reg>
# jmp *<bad-reg>
#
+ 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;