$p =~ s/^\tsw\t\$28,\d+\(\$sp\)\n//;
$p =~ s/__FRAME__/$FRAME/;
} elsif ($TargetPlatform =~ /^powerpc-apple-.*/) {
- $p =~ s/^\tmflr r0\n//;
+ $pcrel_label = $p;
+ $pcrel_label =~ s/(.|\n)*^(L\d+\$pb):\n(.|\n)*/$2/ or $pcrel_label = "";
+
+ $p =~ s/^\tmflr r0\n//;
$p =~ s/^\tbl saveFP # f\d+\n//;
+ $p =~ s/^\tbl saveFP ; save f\d+-f\d+\n//;
+ $p =~ s/^L\d+\$pb:\n//;
$p =~ s/^\tstmw r\d+,-\d+\(r1\)\n//;
$p =~ s/^\tstfd f\d+,-\d+\(r1\)\n//g;
$p =~ s/^\tstw r0,\d+\(r1\)\n//g;
$p =~ s/^\tstwu r1,-\d+\(r1\)\n//;
$p =~ s/^\tstw r\d+,-\d+\(r1\)\n//g;
+ $p =~ s/^\tbcl 20,31,L\d+\$pb\n//;
+ $p =~ s/^L\d+\$pb:\n//;
+ $p =~ s/^\tmflr r31\n//;
} else {
print STDERR "$Pgm: unknown prologue mangling? $TargetPlatform\n";
}
-
- if ($TargetPlatform =~ /^powerpc-apple-.*/) {
- # on PowerPC, we have to keep a part of the prologue
- # (which loads the current instruction pointer into register r31)
- $u_p = $p; # $u_p is for unexpected prologue
- $u_p =~ s/^\tbcl 20,31,L\d+\$pb\n//;
- $u_p =~ s/^L\d+\$pb:\n//;
- $u_p =~ s/^\tmflr r31\n//;
- die "Prologue junk?: $u_p\n" if $u_p =~ /^\t[^\.]/
- } else {
- # HWL HACK: dont die, just print a warning
- #print stderr "HWL: this should die! Prologue junk?: $p\n" if $p =~ /^\t[^\.]/;
- die "Prologue junk?: $p\n" if $p =~ /^\t[^\.]/;
+
+ # HWL HACK: dont die, just print a warning
+ #print stderr "HWL: this should die! Prologue junk?: $p\n" if $p =~ /^\t[^\.]/;
+ die "Prologue junk?: $p\n" if $p =~ /^\t[^\.]/;
+
+ if ($TargetPlatform =~ /^powerpc-apple-.*/ && $pcrel_label ne "") {
+ # on PowerPC, we have to keep a part of the prologue
+ # (which loads the current instruction pointer into register r31)
+ $p .= "bcl 20,31,$pcrel_label\n";
+ $p .= "$pcrel_label:\n";
+ $p .= "\tmflr r31";
}
+
# glue together what's left
$c = $p . $r;
$c =~ s/\n\t\n/\n/; # junk blank line
/* -----------------------------------------------------------------------------
- * $Id: TailCalls.h,v 1.8 2002/03/26 10:30:44 simonmar Exp $
+ * $Id: TailCalls.h,v 1.9 2002/05/28 09:22:08 wolfgang Exp $
*
* (c) The GHC Team, 1998-1999
*
{ \
void *target; \
target = (void *)(cont); \
+ __DISCARD__(); \
goto *target; \
}
/*
+ The __DISCARD__ is there because Apple's April 2002 Beta of GCC 3.1
+ sometimes generates incorrect code otherwise.
+ It tends to "forget" to update global register variables in the presence
+ of decrement/increment operators:
+ JMP_(*(--Sp)) is wrongly compiled as JMP_(Sp[-1]).
+ Calling __DISCARD__ in between works around this problem.
+*/
+
+/*
I would _love_ to use the following instead,
- but GCC fails to generate code for it if it is called for a casted
- data pointer - which is exactly what we are going to do...
+ but some versions of Apple's GCC fail to generate code for it
+ if it is called for a casted data pointer - which is exactly what
+ we are going to do...
#define JMP_(cont) ((F_) (cont))()
*/
-
-#endif /* sparc_TARGET_ARCH */
+#endif /* powerpc_TARGET_ARCH */
/* -----------------------------------------------------------------------------
FUNBEGIN and FUNEND.