From 19f8036efd024ccf19cdf8426853b21e0467d0c5 Mon Sep 17 00:00:00 2001 From: wolfgang Date: Tue, 28 May 2002 09:22:08 +0000 Subject: [PATCH] [project @ 2002-05-28 09:22:08 by wolfgang] Preliminary support for GCC 3.1 on MacOS X --- ghc/driver/mangler/ghc-asm.lprl | 35 +++++++++++++++++++++-------------- ghc/includes/TailCalls.h | 20 +++++++++++++++----- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/ghc/driver/mangler/ghc-asm.lprl b/ghc/driver/mangler/ghc-asm.lprl index a3504d3..96e9858 100644 --- a/ghc/driver/mangler/ghc-asm.lprl +++ b/ghc/driver/mangler/ghc-asm.lprl @@ -694,30 +694,37 @@ sub mangle_asm { $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 diff --git a/ghc/includes/TailCalls.h b/ghc/includes/TailCalls.h index 92d4f72..2dbd99c 100644 --- a/ghc/includes/TailCalls.h +++ b/ghc/includes/TailCalls.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $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 * @@ -161,19 +161,29 @@ but uses $$dyncall if necessary to cope, just in case you aren't. { \ 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. -- 1.7.10.4