$T_HDR_fast = "\.text\n\t\.align 3\n";
$T_HDR_vector = "\.text\n\t\.align 3\n";
$T_HDR_direct = "\.text\n\t\.align 3\n";
+ $T_create_word = "\t.quad";
#--------------------------------------------------------#
} elsif ( $TargetPlatform =~ /^hppa/ ) {
$T_HDR_fast = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
$T_HDR_vector = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
$T_HDR_direct = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
+ $T_create_word = "\t.word";
#--------------------------------------------------------#
} elsif ( $TargetPlatform =~ /^i386-.*-(linuxaout|freebsd2|openbsd|nextstep3|cygwin32|mingw32)$/ ) {
$T_HDR_fast = "\.text\n\t\.align 2,0x90\n";
$T_HDR_vector = "\.text\n\t\.align 2\n"; # NB: requires padding
$T_HDR_direct = "\.text\n\t\.align 2,0x90\n";
+ $T_create_word = "\t.word";
#--------------------------------------------------------#
} elsif ( $TargetPlatform =~ /^i386-.*-(solaris2|linux|freebsd|netbsd)$/ ) {
$T_HDR_fast = "\.text\n\t\.align 4\n";
$T_HDR_vector = "\.text\n\t\.align 4\n"; # NB: requires padding
$T_HDR_direct = "\.text\n\t\.align 4\n";
+ $T_create_word = "\t.word";
#--------------------------------------------------------#
} elsif ( $TargetPlatform =~ /^m68k-.*-sunos4/ ) {
$T_HDR_fast = "\.text\n\t\.even\n";
$T_HDR_vector = "\.text\n\t\.even\n";
$T_HDR_direct = "\.text\n\t\.even\n";
+ $T_create_word = "\t.long";
#--------------------------------------------------------#
} elsif ( $TargetPlatform =~ /^mips-.*/ ) {
$T_HDR_fast = "\t\.text\n\t\.align 2\n";
$T_HDR_vector = "\t\.text\n\t\.align 2\n";
$T_HDR_direct = "\t\.text\n\t\.align 2\n";
+ $T_create_word = "\t.word";
#--------------------------------------------------------#
} elsif ( $TargetPlatform =~ /^powerpc-.*|^rs6000-.*/ ) {
$T_HDR_fast = "# fast\n\.csect \.text[PR]\n\t\.align 2\n";
$T_HDR_vector = "# vector\n\.csect \.data[RW]\n\t\.align 2\n"; #not RO!?
$T_HDR_direct = "# direct\n";
+ $T_create_word = "\t.long";
#--------------------------------------------------------#
} elsif ( $TargetPlatform =~ /^sparc-.*-solaris2/ ) {
$T_HDR_fast = "\.text\n\t\.align 4\n";
$T_HDR_vector = "\.text\n\t\.align 4\n";
$T_HDR_direct = "\.text\n\t\.align 4\n";
+ $T_create_word = "\t.word";
#--------------------------------------------------------#
} elsif ( $TargetPlatform =~ /^sparc-.*-sunos4/ ) {
$T_HDR_fast = "\.text\n\t\.align 4\n";
$T_HDR_vector = "\.text\n\t\.align 4\n";
$T_HDR_direct = "\.text\n\t\.align 4\n";
+ $T_create_word = "\t.word";
#--------------------------------------------------------#
} else {
$i = 0; $chkcat[0] = 'misc'; $chk[0] = '';
while (<INASM>) {
- tr/\r//d if $TargetPlatform =~ /-mingw32$/;
+ tr/\r//d if $TargetPlatform =~ /-mingw32$/; # In case Perl doesn't convert line endings
next if $T_STABBY && /^\.stab.*${T_US}__stg_split_marker/o;
next if $T_STABBY && /^\.stab.*ghc.*c_ID/;
next if /^\t\.def.*endef$/;
local($thing);
chop($thing = $_);
print STDERR "Funny global thing?: $_"
- unless $KNOWN_FUNNY_THING{$thing}
- || /^${T_US}stg_.*${T_POST_LBL}$/o # RTS internals
+ unless # $KNOWN_FUNNY_THING{$thing}
+ /^${T_US}stg_.*${T_POST_LBL}$/o # RTS internals
+ || /^${T_US}__stg_.*${T_POST_LBL}$/o # more RTS internals
|| /^${T_US}__fexp_.*${T_POST_LBL}$/o # foreign export
|| /^${T_US}__stginit.*${T_POST_LBL}$/o # __stginit<module>
|| /^${T_US}.*_btm${T_POST_LBL}$/o # large bitmaps
# 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.frame \$30,0,\$26,0\n\t.prologue" . $r;
+ $c .= "\t.prologue" . $r;
}
$c =~ s/FUNNY#END#THING//;
print OUTASM $chk[$vectorchk{$symb}];
} else {
print OUTASM &rev_tbl($symb, $chk[$vectorchk{$symb}], 0);
+ # DO NOT DELETE THE NEXT LINE. It fixes a rather subtle GC bug
+ # which showed up as a segfault reported by Ryszard Kubiak.
+ # Problem is with vector tables. They wind up as follows:
+ # .word some-word
+ # .word some-other-word
+ # fooble_vtbl:
+ # Problem is that we want the label fooble_vtbl to be considered
+ # in the same section as the vtbl itself, but the label actually
+ # lives at the next word along. If a data segment should happen
+ # to immediately follow the vtbl, as it can in GHCi, the label will
+ # be malclassified as in the data rather than text segment (during
+ # GC), and so we will regard references to it as static closure
+ # pointers rather than as code pointers, which is an error which
+ # usually crashes the garbage collectors.
+ # To fix this, we place a dummy word after the label, so as to
+ # ensure that the label is in the same segment as the vtbl proper.
+ # The native code generator has an analogous fix; see
+ # ghc/compiler/nativeGen/AbsCStixGen.lhs line 107.
+ print OUTASM "${T_create_word} 0\n";
}
# direct return code will be put here!
$chkcat[$vectorchk{$symb}] = 'DONE ALREADY';
local(@words) = ();
local($after) = '';
local(@lines) = split(/\n/, $tbl);
- local($i, $j); #local ($i, $extra, $words_to_pad, $j);
+ local($i, $j);
# Deal with the header...
for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t?${T_DOT_WORD}\s+/o; $i++) {
shift(@words)
}
-# Padding removed to reduce code size and improve performance on Pentiums.
-# Simon M. 13/4/96
- # for 486-cache-friendliness, we want our tables aligned
- # on 16-byte boundaries (.align 4). Let's pad:
-# $extra = ($#words + 1) % 4;
-# $words_to_pad = ($extra == 0) ? 0 : 4 - $extra;
-# for ($j = 0; $j < $words_to_pad; $j++) { push(@words, "\t${T_DOT_WORD} 0"); }
-
for (; $i <= $#lines; $i++) {
$after .= $lines[$i] . "\n";
}
- # Alphas:If we have anonymous text (not part of a procedure), the
+ # Alphas: If we have anonymous text (not part of a procedure), the
# linker may complain about missing exception information. Bleh.
# To suppress this, we place a .ent/.end pair around the code.
# At the same time, we have to be careful and not enclose any leading
$after .= "\t.end $ident\n";
}
+ # Alphas: The heroic Simon Marlow found a bug in the Digital UNIX
+ # assembler (!) wherein .quad constants inside .text sections are
+ # first narrowed to 32 bits then sign-extended back to 64 bits.
+ # This obviously screws up our 64-bit bitmaps, so we work around
+ # the bug by replacing .quad with .align 3 + .long + .long [ccshan]
+ if ( $TargetPlatform =~ /^alpha-/ ) {
+ foreach (@words) {
+ if (/^\s*\.quad\s+([-+0-9].*\S)\s*$/ && length $1 >= 10) {
+ local ($number) = $1;
+ if ($number =~ /^([-+])?(0x?)?([0-9]+)$/) {
+ local ($sign, $base, $digits) = ($1, $2, $3);
+ $base = (10, 8, 16)[length $base];
+ local ($hi, $lo) = (0, 0);
+ foreach $i (split(//, $digits)) {
+ $j = $lo * $base + $i;
+ $lo = $j % 4294967296;
+ $hi = $hi * $base + ($j - $lo) / 4294967296;
+ }
+ ($hi, $lo) = (4294967295 - $hi, 4294967296 - $lo)
+ if $sign eq "-";
+ $_ = "\t.align 3\n\t.long $lo\n\t.long $hi\n";
+ # printf STDERR "TURNING %s into 0x %08x %08x\n", $number, $hi, $lo;
+ } else {
+ print STDERR "Cannot handle \".quad $number\" in info table\n";
+ exit 1;
+ }
+ }
+ }
+ }
+
$tbl = $before
. (($TargetPlatform !~ /^hppa/) ? '' : join("\n", @imports) . "\n")
. join("\n", @words) . "\n"