#!/bin/ksh HOST="$1" OS="$2" OS_VERSION="$3" OS_VERSION_MINOR="$4" patch_aix() { /usr/local/bin/patch -p0 -N -b -V numbered <<\EOF --- mk/target.mk.~1~ 2005-03-09 05:28:13.000000000 -0500 +++ mk/target.mk 2007-06-22 17:31:40.000000000 -0400 @@ -235,11 +235,11 @@ ifneq "$(BootingFromHc)" "YES" $(HS_PROG) :: $(OBJS) - $(HC) -o $@ $(HC_OPTS) $(LD_OPTS) $(OBJS) + $(HC) -optl-Wl,-bbigtoc -o $@ $(HC_OPTS) $(LD_OPTS) $(OBJS) else # see bootstrap.mk $(HS_PROG) :: $(OBJS) - $(CC) -o $@ $(HC_BOOT_CC_OPTS) $(HC_BOOT_LD_OPTS) $(OBJS) $(HC_BOOT_LIBS) + $(CC) -optl-Wl,-bbigtoc -o $@ $(HC_BOOT_CC_OPTS) $(HC_BOOT_LD_OPTS) $(OBJS) $(HC_BOOT_LIBS) endif endif EOF } patch_hpux() { /usr/local/bin/patch -p0 -N -b -V numbered <<\EOF --- ./compiler/main/DriverPhases.hs.~1~ 2007-04-25 13:10:39.000000000 -0400 +++ ./compiler/main/DriverPhases.hs 2007-07-31 20:07:05.000000000 -0400 @@ -75,6 +75,7 @@ | Cc | HCc -- Haskellised C (as opposed to vanilla C) compilation | Mangle -- assembly mangling, now done by a separate script. + | MiniMangle -- assembly mangling for hppa RTS C files | SplitMangle -- after mangler if splitting | SplitAs | As @@ -104,6 +105,7 @@ eqPhase Cc Cc = True eqPhase HCc HCc = True eqPhase Mangle Mangle = True +eqPhase MiniMangle MiniMangle = True eqPhase SplitMangle SplitMangle = True eqPhase SplitAs SplitAs = True eqPhase As As = True @@ -132,7 +134,12 @@ nextPhase As = SplitAs nextPhase SplitAs = StopLn nextPhase Ccpp = As +#if hppa1_1_TARGET_ARCH || hppa2_0_TARGET_ARCH +nextPhase Cc = MiniMangle +#else nextPhase Cc = As +#endif +nextPhase MiniMangle = As nextPhase CmmCpp = Cmm nextPhase Cmm = HCc nextPhase StopLn = panic "nextPhase: nothing after StopLn" @@ -153,6 +160,7 @@ startPhase "cc" = Ccpp startPhase "cxx" = Ccpp startPhase "raw_s" = Mangle +startPhase "mini_s" = MiniMangle startPhase "split_s" = SplitMangle startPhase "s" = As startPhase "S" = As @@ -177,6 +185,7 @@ phaseInputExt Ccpp = "cpp" phaseInputExt Cc = "c" phaseInputExt Mangle = "raw_s" +phaseInputExt MiniMangle = "mini_s" phaseInputExt SplitMangle = "split_s" -- not really generated phaseInputExt As = "s" phaseInputExt SplitAs = "split_s" -- not really generated @@ -190,7 +199,7 @@ haskellish_src_suffixes = haskellish_user_src_suffixes ++ [ "hspp", "hscpp", "hcr", "cmm" ] -haskellish_suffixes = haskellish_src_suffixes ++ ["hc", "raw_s"] +haskellish_suffixes = haskellish_src_suffixes ++ ["hc", "raw_s", "mini_s"] cish_suffixes = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ] extcoreish_suffixes = [ "hcr" ] haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ] -- Will not be deleted as temp files --- ./compiler/main/DriverPipeline.hs.~1~ 2007-04-25 13:10:40.000000000 -0400 +++ ./compiler/main/DriverPipeline.hs 2007-07-31 22:07:28.000000000 -0400 @@ -835,7 +835,11 @@ let mangle = dopt Opt_DoAsmMangling dflags next_phase | hcc && mangle = Mangle +#if hppa1_1_TARGET_ARCH || hppa2_0_TARGET_ARCH + | otherwise = MiniMangle +#else | otherwise = As +#endif output_fn <- get_output_fn dflags next_phase maybe_loc let @@ -884,7 +888,14 @@ ++ (if hcc then more_hcc_opts else []) +#if hppa1_1_TARGET_ARCH || hppa2_0_TARGET_ARCH + -- gcc optimizer is badly broken (gcc bug 32820) + -- long-calls because hppa static binary is big + -- inline to eliminate static wrapper functions in hpux headers + ++ [ verb, "-S", "-Wimplicit", cc_opt, "-O0", "-mlong-calls", "-fomit-frame-pointer", "-finline" ] +#else ++ [ verb, "-S", "-Wimplicit", cc_opt ] +#endif ++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ] ++ cc_opts ++ split_opt @@ -927,6 +938,38 @@ return (next_phase, dflags, maybe_loc, output_fn) ----------------------------------------------------------------------------- +-- MiniMangle phase for hppa + +-- The hppa architecture distinguishes between code and data addresses +-- because the top 2 bits of the 32 bit address are actually segment +-- selectors. The assembler and linker enforce the distinction so you +-- have to declare references as either code or data references. + +-- When using the mangler, some tables get moved from data to text by +-- the mangler. The problem is that you then have to change all the +-- references in the RTS code so that they refer to these tables in +-- text and not data. That is what the MiniMangle phase does. + +runPhase MiniMangle stop dflags _basename _suff input_fn get_output_fn maybe_loc + = do let mangler_opts = getOpts dflags opt_m + + machdep_opts <- return ["--mini"] + + let split = dopt Opt_SplitObjs dflags + next_phase + | split = SplitMangle + | otherwise = As + output_fn <- get_output_fn dflags next_phase maybe_loc + + SysTools.runMangle dflags (map SysTools.Option mangler_opts + ++ [ SysTools.FileOption "" input_fn + , SysTools.FileOption "" output_fn + ] + ++ map SysTools.Option machdep_opts) + + return (next_phase, dflags, maybe_loc, output_fn) + +----------------------------------------------------------------------------- -- Splitting phase runPhase SplitMangle stop dflags _basename _suff input_fn get_output_fn maybe_loc --- ./configure.~1~ 2007-04-25 13:29:16.000000000 -0400 +++ ./configure 2007-07-27 20:47:37.000000000 -0400 @@ -1674,6 +1674,15 @@ HostVendor_CPP='hp' HostOS_CPP='hpux' ;; +hppa2.0*-hp-hpux*) + HostPlatform=hppa2.0-hp-hpux # canonicalise for our purposes (hack) + TargetPlatform=hppa2.0-hp-hpux + BuildPlatform=hppa2.0-hp-hpux + HostPlatform_CPP='hppa2_0_hp_hpux' + HostArch_CPP='hppa2_0' + HostVendor_CPP='hp' + HostOS_CPP='hpux' + ;; i[3456]86-*-linuxaout*) HostPlatform=i386-unknown-linuxaout # hack again TargetPlatform=i386-unknown-linuxaout --- ./configure.ac.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./configure.ac 2007-07-27 20:47:37.000000000 -0400 @@ -219,6 +219,15 @@ HostVendor_CPP='hp' HostOS_CPP='hpux' ;; +hppa2.0*-hp-hpux*) + HostPlatform=hppa2.0-hp-hpux # canonicalise for our purposes (hack) + TargetPlatform=hppa2.0-hp-hpux + BuildPlatform=hppa2.0-hp-hpux + HostPlatform_CPP='hppa2_0_hp_hpux' + HostArch_CPP='hppa2_0' + HostVendor_CPP='hp' + HostOS_CPP='hpux' + ;; i[[3456]]86-*-linuxaout*) HostPlatform=i386-unknown-linuxaout # hack again TargetPlatform=i386-unknown-linuxaout --- ./distrib/configure-bin.ac.~1~ 2007-04-25 13:10:40.000000000 -0400 +++ ./distrib/configure-bin.ac 2007-07-27 20:47:37.000000000 -0400 @@ -34,6 +34,8 @@ TargetPlatform=alpha-unknown-freebsd;; hppa1.1-hp-hpux*) TargetPlatform=hppa1.1-hp-hpux;; +hppa2.0*-hp-hpux*) + TargetPlatform=hppa2.0-hp-hpux;; i[[3456]]86-*-linuxaout*) TargetPlatform=i386-unknown-linuxaout;; i[[3456]]86-*-linux*) --- ./driver/mangler/ghc-asm.lprl.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./driver/mangler/ghc-asm.lprl 2007-07-31 20:11:28.000000000 -0400 @@ -65,6 +65,8 @@ $ifile = $ARGV[0]; $ofile = $ARGV[1]; +my %NO_WARNING; + if ( $TargetPlatform =~ /^i386-/ ) { if ($ARGV[2] eq '') { $StolenX86Regs = 4; @@ -73,7 +75,12 @@ } } -&mangle_asm($ifile,$ofile); +if ($TargetPlatform =~ /^hppa/ && $ARGV[2] eq "--mini") { + # fixup references to _info symbols, which are now in text, not data + &mini_mangle_asm_hppa($ifile,$ofile); +} else { + &mangle_asm($ifile,$ofile); +} exit(0); \end{code} @@ -116,8 +123,8 @@ $T_STABBY = 0; # 1 iff .stab things (usually if a.out format) $T_US = ''; # _ if symbols have an underscore on the front $T_PRE_APP = 'DONT THINK THIS APPLIES'; # regexp that says what comes before APP/NO_APP - $T_CONST_LBL = '^L\$C(\d+)$'; # regexp for what such a lbl looks like - $T_POST_LBL = ''; + $T_CONST_LBL = '^L\$C(\d+):?$'; # regexp for what such a lbl looks like + $T_POST_LBL = ':?'; $T_MOVE_DIRVS = '^((\s+\.(IMPORT|EXPORT|PARAM).*|\s+\.align\s+\d+|\s+\.(SPACE|SUBSPA)\s+\S+|\s*)\n)'; $T_COPY_DIRVS = '^\s+\.(IMPORT|EXPORT)'; @@ -127,12 +134,47 @@ $T_HDR_literal = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$LIT\$\n"; $T_HDR_misc = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n"; $T_HDR_data = "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$DATA\$\n\t\.align 4\n"; - $T_HDR_rodata = "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$DATA\$\n\t\.align 4\n"; + $T_HDR_rodata = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n"; $T_HDR_closure = "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$DATA\$\n\t\.align 4\n"; $T_HDR_info = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n"; $T_HDR_entry = "\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"; + # HPUX 11.0 has a nasty hack in its header files -- some standard + # functions are not *declared*, but actually *defined* as small + # static wrapper functions. When gcc optimization is off, these + # wrapper functions get inserted into many object files even + # though they are not used, causing serious binary bloat. The fix + # is to convert these functions to static *inline* so gcc can + # eliminate them. If you don't apply this fix to the headers that + # gcc uses then you get the bloat, but also a *lot* of warnings + # because the mangler does not expect these functions. Uncomment + # the following lines to turn off warnings for those functions + # known to be involved. Leave them commented if you want the + # warnings, presumably to remind you that you need to fix the gcc + # headers. + + # These functions are declared static in HPUX 11.0 headers. + #$NO_WARNING{"creat"} = 1; + #$NO_WARNING{"fgetpos"} = 1; + #$NO_WARNING{"fopen"} = 1; + #$NO_WARNING{"freopen"} = 1; + #$NO_WARNING{"fsetpos"} = 1; + #$NO_WARNING{"fstat"} = 1; + #$NO_WARNING{"ftruncate"} = 1; + #$NO_WARNING{"getrlimit"} = 1; + #$NO_WARNING{"lockf"} = 1; + #$NO_WARNING{"lseek"} = 1; + #$NO_WARNING{"lstat"} = 1; + #$NO_WARNING{"open"} = 1; + #$NO_WARNING{"prealloc"} = 1; + #$NO_WARNING{"pthread_attr_init"} = 1; + #$NO_WARNING{"pthread_create"} = 1; + #$NO_WARNING{"setrlimit"} = 1; + #$NO_WARNING{"stat"} = 1; + #$NO_WARNING{"tmpfile"} = 1; + #$NO_WARNING{"truncate"} = 1; + #--------------------------------------------------------# } elsif ( $TargetPlatform =~ /^i386-.*-(linuxaout|freebsd2|nextstep3|cygwin32|mingw32)$/ ) { # NeXT added but not tested. CaS @@ -548,6 +590,10 @@ next if /^\t\.def.*endef$/; next if /${T_PRE_APP}(NO_)?APP/o; next if /^;/ && $TargetPlatform =~ /^hppa/; + # Compiling with -mlong-calls generates pointers to __DISCARD__ that must be removed. + s/^(\s+.word\s+)P\%__DISCARD__\s*\n/${1}0\n/o if $TargetPlatform =~ /^hppa/; + # info tables have been moved to the text segment + s/^(\s+\.EXPORT\s+\S+_info,)DATA/${1}CODE/o if $TargetPlatform =~ /^hppa/; next if /(^$|^\t\.file\t|^ # )/ && $TargetPlatform =~ /^(mips|ia64)-/; @@ -737,7 +783,7 @@ } elsif ( /^${T_US}[A-Za-z0-9_]/o && ( $TargetPlatform !~ /^hppa/ # need to avoid local labels in this case - || ! /^L\$\d+$/ ) + || ! /^L\$\d+:?$/ ) && ( $TargetPlatform !~ /^powerpc64/ # we need to avoid local labels in this case || ! /^\.L\d+:$/ ) ) { local($thing); @@ -765,7 +811,8 @@ $chkcat[$i] = 'relrodata'; } else { - print STDERR "Warning: retaining unknown function \`$thing' in output from C compiler\n"; + print STDERR "Warning: retaining unknown function \`$thing' in output from C compiler\n" + if !exists $NO_WARNING{$thing}; $chkcat[$i] = 'unknown'; } @@ -820,7 +867,7 @@ # toss all prologue stuff; HPPA is pretty weird # (see elsewhere) - $c = &hppa_mash_prologue($c) if $TargetPlatform =~ /^hppa-/; + $c = &hppa_mash_prologue($c) if $TargetPlatform =~ /^hppa/; undef $ia64_locnum; undef $ia64_outnum; @@ -1174,6 +1221,8 @@ $c =~ s/^\tbl\s+__DISCARD__(\@plt)?\n//go if $TargetPlatform =~ /^powerpc-.*-linux/; $c =~ s/^\tbl\s+\.__DISCARD__\n\s+nop\n//go if $TargetPlatform =~ /^powerpc64-.*-linux/; $c =~ s/^\tcall\s+L___DISCARD__\$stub\n//go if $TargetPlatform =~ /i386-apple-darwin.*/; + # This is the hppa/hpux form used when -mlong-calls is not in effect. + $c =~ s/^[\t]+\.CALL[ \t]*\n[ \t]+bl\s+${T_US}__DISCARD__,\%r\d+\n[\t]+nop[ \t]*\n//go if $TargetPlatform =~ /^hppa/; # IA64: fix register allocation; mangle tailcalls into jumps if ($TargetPlatform =~ /^ia64-/) { @@ -1239,6 +1288,14 @@ # otherwise they're tossed } + # gcc 4.0.1 for hppa-hpux was observed to place .IMPORT + # statements at the end of the file instead of the + # beginning; they need to be retained because of hppa + # text/data strong pointer typing, so don't discard them + + if ($i == ($numchks - 1) && $TargetPlatform =~ /^hppa/) { + last; + } $c =~ s/${T_MOVE_DIRVS}FUNNY#END#THING/FUNNY#END#THING/o; } @@ -1410,13 +1467,13 @@ if (defined($infochk{$symb}) && $TargetPlatform !~ /^ia64-/) { @o = (); foreach $l (split(/\n/,$c)) { - next if $l =~ /^.*$symb_(entry|ret)${T_POST_LBL}/; + 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)/) { + if ($l =~ /^\s*\.(type|size).*${symb}_(entry|ret)/) { $l =~ s/$symb(_entry|_ret)/${symb}_info/g; push(@o,$l); next; @@ -1640,7 +1697,42 @@ local($_) = @_; # toss all prologue stuff - s/^\s+\.ENTRY[^\0]*--- BEGIN ---/\t.ENTRY/; + + s/^ + \s+\.ENTRY(.|\n)*---[ ]BEGIN[ ]--- + ( + +# This is what the call to __DISCARD__ looks like when using -O0 -mlong-calls. +# Strip it here while we're at it. +# .CALL +# addil LR'L$0073-$global$,%r27 ; get upper part of __DISCARD__ +# ldw RR'L$0073-$global$(%r1),%r1 ; get lower part of __DISCARD__ +# bb,>=,n %r1,30,.+16 +# depi 0,31,2,%r1 +# ldw 4(%sr0,%r1),%r19 +# ldw 0(%sr0,%r1),%r1 +# bl .+8,%r2 +# addi 16,%r2,%r2 +# ldsid (%r1),%r31 +# mtsp %r31,%sr0 +# ble 0(%sr0,%r1) +# stw %r31,-24(%sp) + + \s+\.CALL + \s+addil\s+\S+-\$global\$,\%r\d+ + \s+ldw\s+\S+-\$global\$\(\%r\d+\),\%r\d+ + \s+bb\S*\s+\%r\d+,\d+,\.\+\d+ + \s+depi\s+\d+,\d+,\d+,\%r\d+ + \s+ldw\s+\d+\(\%sr\d+,\%r\d+\),\%r\d+ + \s+ldw\s+\d+\(\%sr\d+,\%r\d+\),\%r\d+ + \s+bl\s+.+\d+,\%r\d+ + \s+addi\s+\d+,\%r\d+,\%r\d+ + \s+ldsid\s+\(\%r\d+\),\%r\d+ + \s+mtsp\s+\%r\d+,\%sr\d+ + \s+ble\s+\d+\(\%sr\d+,\%r\d+\) + \s+stw\s+\%r\d+,-\d+\(\%sp\) + + )?/\t.ENTRY/x; # Lie about our .CALLINFO s/^\s+\.CALLINFO.*$/\t.CALLINFO NO_CALLS,NO_UNWIND/; @@ -1860,8 +1952,8 @@ $before .= $lines[$i] . "\n"; # otherwise... } - $infoname = $label; - $infoname =~ s/(.|\n)*^([A-Za-z0-9_]+_info)${T_POST_LBL}$(.|\n)*/\2/; + $label =~ m/^([A-Za-z0-9_]+_info)${T_POST_LBL}/m; + $infoname = $1; # Grab the table data... if ( $TargetPlatform !~ /^hppa/ ) { @@ -1871,27 +1963,34 @@ # to offsets (relative to the info label), # in order to support position independent code. $line =~ s/$infoname/0/ - || $line =~ s/([A-Za-z0-9_]+_srtd)$/\1 - $infoname/ - || $line =~ s/([A-Za-z0-9_]+_srt(\+\d+)?)$/\1 - $infoname/ - || $line =~ s/([A-Za-z0-9_]+_slow)$/\1 - $infoname/ - || $line =~ s/([A-Za-z0-9_]+_btm)$/\1 - $infoname/ - || $line =~ s/([A-Za-z0-9_]+_alt)$/\1 - $infoname/ - || $line =~ s/([A-Za-z0-9_]+_dflt)$/\1 - $infoname/ - || $line =~ s/([A-Za-z0-9_]+_ret)$/\1 - $infoname/; + || $line =~ s/([A-Za-z0-9_]+_srtd)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_srt(\+\d+)?)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_slow)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_btm)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_alt)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_dflt)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_ret)$/$1 - $infoname/; push(@words, $line); } } else { # hppa weirdness for ( ; $i <= $#lines && $lines[$i] =~ /^\s+(${T_DOT_WORD}|\.IMPORT)/; $i++) { - # FIXME: the RTS now expects offsets instead of addresses - # for all labels in info tables. - if ($lines[$i] =~ /^\s+\.IMPORT/) { - push(@imports, $lines[$i]); - } else { - # We don't use HP's ``function pointers'' - # We just use labels in code space, like normal people - $lines[$i] =~ s/P%//; - push(@words, $lines[$i]); - } + $line = $lines[$i]; + if ($line =~ /^\s+\.IMPORT/) { + push(@imports, $line); + next; + } + $line =~ s/$infoname/0/ + || $line =~ s/([A-Za-z0-9_]+_srtd)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_srt(\+\d+)?)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_slow)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_btm)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_alt)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_dflt)$/$1 - $infoname/ + || $line =~ s/([A-Za-z0-9_]+_ret)$/$1 - $infoname/; + # We don't use HP's ``function pointers'' + # We just use labels in code space, like normal people + $line =~ s/P%//; + push(@words, $line); } } --- ./includes/MachRegs.h.~1~ 2007-04-25 13:10:40.000000000 -0400 +++ ./includes/MachRegs.h 2007-07-27 20:47:38.000000000 -0400 @@ -35,6 +35,7 @@ #ifdef COMPILING_GHC #define alpha_REGS alpha_TARGET_ARCH #define hppa1_1_REGS hppa1_1_TARGET_ARCH +#define hppa2_0_REGS hppa2_0_TARGET_ARCH #define i386_REGS i386_TARGET_ARCH #define x86_64_REGS x86_64_TARGET_ARCH #define m68k_REGS m68k_TARGET_ARCH @@ -46,6 +47,7 @@ #else #define alpha_REGS alpha_HOST_ARCH #define hppa1_1_REGS hppa1_1_HOST_ARCH +#define hppa2_0_REGS hppa2_0_HOST_ARCH #define i386_REGS i386_HOST_ARCH #define x86_64_REGS x86_64_HOST_ARCH #define m68k_REGS m68k_HOST_ARCH @@ -164,7 +166,7 @@ \tr{%fr8}--\tr{%fr11} are some available caller-save fl-pt registers. -------------------------------------------------------------------------- */ -#if hppa1_1_REGS +#if hppa1_1_REGS || hppa2_0_REGS #define REG(x) __asm__("%" #x) --- ./includes/Regs.h.~1~ 2007-04-25 13:10:40.000000000 -0400 +++ ./includes/Regs.h 2007-07-29 07:46:09.000000000 -0400 @@ -64,7 +64,11 @@ StgAddr a; StgChar c; StgInt8 i8; +#if !defined(hppa1_1_hp_hpux_TARGET) && !defined(hppa2_0_hp_hpux_TARGET) + /* hppa does not allow floats in a general-purpose register so + this causes a compilation error. */ StgFloat f; +#endif StgInt i; StgPtr p; StgClosurePtr cl; --- ./includes/TailCalls.h.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./includes/TailCalls.h 2007-07-27 20:47:39.000000000 -0400 @@ -177,7 +177,7 @@ -------------------------------------------------------------------------- */ -#ifdef hppa1_1_hp_hpux_TARGET +#if defined(hppa1_1_hp_hpux_TARGET) || defined(hppa2_0_hp_hpux_TARGET) #define JMP_(cont) \ do { void *_procedure = (void *)(cont); \ @@ -186,7 +186,7 @@ goto *_procedure; \ } while(0) -#endif /* hppa1_1_hp_hpux_TARGET */ +#endif /* hppa1_1_hp_hpux_TARGET || hppa2_0_hp_hpux_TARGET */ /* ----------------------------------------------------------------------------- Tail calling on PowerPC --- ./libraries/X11/include/HsXlib.h.~1~ 2007-04-25 13:26:11.000000000 -0400 +++ ./libraries/X11/include/HsXlib.h 2007-07-29 07:13:33.000000000 -0400 @@ -44,7 +44,10 @@ extern int defaultErrorHandler(Display *, XErrorEvent *); /* Used in waitForEvent */ +#ifndef __hpux +/* This header file does not exist under HPUX 11.0. */ #include +#endif #include #include #include --- ./libraries/base/include/HsBase.h.~1~ 2007-04-25 13:17:00.000000000 -0400 +++ ./libraries/base/include/HsBase.h 2007-07-29 07:14:49.000000000 -0400 @@ -114,6 +114,9 @@ # include # if defined(SYS_GETRUSAGE) /* hpux_HOST_OS */ # define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b) +# ifdef HAVE_GETRUSAGE +# undef HAVE_GETRUSAGE +# endif # define HAVE_GETRUSAGE 1 # endif #endif --- ./libraries/network/Network/Socket.hsc.~1~ 2007-04-25 13:27:41.000000000 -0400 +++ ./libraries/network/Network/Socket.hsc 2007-07-27 20:47:39.000000000 -0400 @@ -345,7 +345,7 @@ INSTANCE_TYPEABLE0(SockAddr,sockAddrTc,"SockAddr") -#if defined(WITH_WINSOCK) || defined(cygwin32_HOST_OS) +#if defined(WITH_WINSOCK) || defined(cygwin32_HOST_OS) || defined(hpux_HOST_OS) type CSaFamily = (#type unsigned short) #elif defined(darwin_HOST_OS) type CSaFamily = (#type u_char) --- ./libraries/time/cbits/HsTime.c.~1~ 2007-04-25 13:28:32.000000000 -0400 +++ ./libraries/time/cbits/HsTime.c 2007-07-29 21:52:53.000000000 -0400 @@ -1,6 +1,13 @@ #include "HsTime.h" #include +#ifdef __hpux +/* HPUX 11.0 only declares localtime_r if you have _REENTRANT on. */ +#ifndef _LOCALTIME_R +extern struct tm *localtime_r(const time_t *, struct tm *); +#endif +#endif + long int get_current_timezone_seconds (time_t t,int* pdst,char const* * pname) { #if HAVE_LOCALTIME_R --- ./mk/config.mk.in.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./mk/config.mk.in 2007-07-29 12:59:45.000000000 -0400 @@ -230,7 +230,7 @@ # the compiler you build with is generating registerised binaries), but # the stage2 compiler will be an unregisterised binary. # -ifneq "$(findstring $(HostArch_CPP), alpha hppa)" "" +ifneq "$(findstring $(HostArch_CPP), alpha)" "" GhcUnregisterised=YES else GhcUnregisterised=NO @@ -418,7 +418,12 @@ # For an optimised RTS (you probably don't want to change these; we build # a debugging RTS by default now. Use -debug to get it). +ifeq "$(findstring hppa, $(HOSTPLATFORM) $(TARGETPLATFORM))" "" GhcRtsHcOpts=-optc-O2 +else +# gcc optimizer is badly broken (gcc bug 32820) +GhcRtsHcOpts=-O2 +endif GhcRtsCcOpts=-fomit-frame-pointer # Include the front panel code? Needs GTK+. @@ -850,7 +855,14 @@ endif # default C compiler flags +ifeq "$(findstring hppa, $(HOSTPLATFORM) $(TARGETPLATFORM))" "" SRC_CC_OPTS = @SRC_CC_OPTS@ +else +# gcc optimizer is badly broken (gcc bug 32820) +# long-calls because hppa static binary is big +# inline to eliminate static wrapper functions in hpux headers +SRC_CC_OPTS = @SRC_CC_OPTS@ -O0 -mlong-calls -fomit-frame-pointer -finline +endif ifeq "$(TARGETPLATFORM)" "ia64-unknown-linux" SRC_CC_OPTS += -G0 --- ./rts/Linker.c.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./rts/Linker.c 2007-07-31 22:13:20.000000000 -0400 @@ -154,11 +154,18 @@ #endif #if !defined (mingw32_HOST_OS) +#if defined(hppa1_1_HOST_ARCH) || defined(hppa2_0_HOST_ARCH) +#define RTS_POSIX_ONLY_SYMBOLS \ + SymX(signal_handlers) \ + SymX(stg_sig_install) \ + SymD(nocldstop) +#else #define RTS_POSIX_ONLY_SYMBOLS \ SymX(signal_handlers) \ SymX(stg_sig_install) \ Sym(nocldstop) #endif +#endif #if defined (cygwin32_HOST_OS) #define RTS_MINGW_ONLY_SYMBOLS /**/ @@ -767,6 +774,9 @@ #define Sym(vvv) extern void vvv(void); #define SymX(vvv) /**/ #define SymX_redirect(vvv,xxx) /**/ +/* hppa distinguishes between code and data symbols so though the + declaration is "bogus" it must be of the right kind. */ +#define SymD(vvv) extern int vvv; RTS_SYMBOLS RTS_RET_SYMBOLS RTS_LONG_LONG_SYMS @@ -776,6 +786,7 @@ RTS_DARWIN_ONLY_SYMBOLS RTS_LIBGCC_SYMBOLS #undef Sym +#undef SymD #undef SymX #undef SymX_redirect @@ -788,6 +799,7 @@ #define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \ (void*)(&(vvv)) }, #define SymX(vvv) Sym(vvv) +#define SymD(vvv) Sym(vvv) // SymX_redirect allows us to redirect references to one symbol to // another symbol. See newCAF/newDynCAF for an example. --- ./rts/Makefile.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./rts/Makefile 2007-07-29 12:50:21.000000000 -0400 @@ -338,7 +338,12 @@ endif # -O3 helps unroll some loops (especially in copy() with a constant argument). +ifeq "$(findstring hppa, $(HOSTPLATFORM) $(TARGETPLATFORM))" "" GC_HC_OPTS += -optc-O3 +else +# gcc optimizer is badly broken (gcc bug 32820) +GC_HC_OPTS += +endif # Without this, thread_obj will not be inlined (at least on x86 with GCC 4.1.0) GCCompact_HC_OPTS += -optc-finline-limit=2500 --- ./rts/RtsUtils.c.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./rts/RtsUtils.c 2007-07-27 20:47:40.000000000 -0400 @@ -382,7 +382,7 @@ ullong msTime(void) { -# if defined(HAVE_GETCLOCK) && !defined(alpha_HOST_ARCH) && !defined(hppa1_1_HOST_ARCH) +# if defined(HAVE_GETCLOCK) && !defined(alpha_HOST_ARCH) && !defined(hppa1_1_HOST_ARCH) && !defined(hppa2_0_HOST_ARCH) struct timespec tv; if (getclock(TIMEOFDAY, &tv) != 0) { --- ./rts/StgCRun.c.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./rts/StgCRun.c 2007-07-31 21:06:26.000000000 -0400 @@ -108,8 +108,10 @@ #ifdef LEADING_UNDERSCORE #define STG_RETURN "_StgReturn" +#define STG_RUN "_StgRun" #else #define STG_RETURN "StgReturn" +#define STG_RUN "StgRun" #endif /* ----------------------------------------------------------------------------- @@ -490,94 +492,133 @@ HP-PA architecture -------------------------------------------------------------------------- */ -#ifdef hppa1_1_HOST_ARCH +#if defined(hppa1_1_HOST_ARCH) || defined(hppa2_0_HOST_ARCH) -StgRegTable * -StgRun(StgFunPtr f, StgRegTable *basereg) -{ - StgChar space[RESERVED_C_STACK_BYTES+16*sizeof(long)+10*sizeof(double)]; - StgRegTable * ret; +extern StgRegTable *StgRun(StgFunPtr f, StgRegTable *basereg); - __asm__ volatile ("ldo %0(%%r30),%%r19\n" - "\tstw %%r3, 0(0,%%r19)\n" - "\tstw %%r4, 4(0,%%r19)\n" - "\tstw %%r5, 8(0,%%r19)\n" - "\tstw %%r6,12(0,%%r19)\n" - "\tstw %%r7,16(0,%%r19)\n" - "\tstw %%r8,20(0,%%r19)\n" - "\tstw %%r9,24(0,%%r19)\n" - "\tstw %%r10,28(0,%%r19)\n" - "\tstw %%r11,32(0,%%r19)\n" - "\tstw %%r12,36(0,%%r19)\n" - "\tstw %%r13,40(0,%%r19)\n" - "\tstw %%r14,44(0,%%r19)\n" - "\tstw %%r15,48(0,%%r19)\n" - "\tstw %%r16,52(0,%%r19)\n" - "\tstw %%r17,56(0,%%r19)\n" - "\tstw %%r18,60(0,%%r19)\n" - "\tldo 80(%%r19),%%r19\n" - "\tfstds %%fr12,-16(0,%%r19)\n" - "\tfstds %%fr13, -8(0,%%r19)\n" - "\tfstds %%fr14, 0(0,%%r19)\n" - "\tfstds %%fr15, 8(0,%%r19)\n" - "\tldo 32(%%r19),%%r19\n" - "\tfstds %%fr16,-16(0,%%r19)\n" - "\tfstds %%fr17, -8(0,%%r19)\n" - "\tfstds %%fr18, 0(0,%%r19)\n" - "\tfstds %%fr19, 8(0,%%r19)\n" - "\tldo 32(%%r19),%%r19\n" - "\tfstds %%fr20,-16(0,%%r19)\n" - "\tfstds %%fr21, -8(0,%%r19)\n" : : - "n" (-(116 * sizeof(long) + 10 * sizeof(double))) : "%r19" - ); +/* The purpose of StgRun is to push machine registers onto the stack, + then allocate RESERVED_C_STACK_BYTES on the stack, then jump into + the STG routine that the caller wants to run. */ - f(); +/* StgReturn pops RESERVED_C_STACK_BYTES and restores the registers + after the STG routine is done. +/* Rather than fighting gcc to get the code correct, just write the + whole thing in assembly. */ + +static void GNUC3_ATTRIBUTE(used) +StgRunIsImplementedInAssembler(void) +{ __asm__ volatile (".align 4\n" + "\t.EXPORT " STG_RUN ",CODE\n" + "\t.EXPORT " STG_RUN ",ENTRY,PRIV_LEV=3\n" + STG_RUN "\n" + + /* save pointer to start of allocated space */ + "\tldo 0(%%r30),%%r19\n" + + /* allocate stack space */ + "\tldil L'%0,%%r1\n" + "\tldo R'%0(%%r1),%%r1\n" + "\tadd %%r1,%%r30,%%r30\n" + + /* save integer registers */ + "\tstws,ma %%rp,4(0,%%r19)\n" /* return address */ + "\tstws,ma %%r3,4(0,%%r19)\n" + "\tstws,ma %%r4,4(0,%%r19)\n" + "\tstws,ma %%r5,4(0,%%r19)\n" + "\tstws,ma %%r6,4(0,%%r19)\n" + "\tstws,ma %%r7,4(0,%%r19)\n" + "\tstws,ma %%r8,4(0,%%r19)\n" + "\tstws,ma %%r9,4(0,%%r19)\n" + "\tstws,ma %%r10,4(0,%%r19)\n" + "\tstws,ma %%r11,4(0,%%r19)\n" + "\tstws,ma %%r12,4(0,%%r19)\n" + "\tstws,ma %%r13,4(0,%%r19)\n" + "\tstws,ma %%r14,4(0,%%r19)\n" + "\tstws,ma %%r15,4(0,%%r19)\n" + "\tstws,ma %%r16,4(0,%%r19)\n" + "\tstws,ma %%r17,4(0,%%r19)\n" + "\tstws,ma %%r18,4(0,%%r19)\n" + + /* keep stack alignment for floats */ + "\tldo 4(%%r19),%%r19\n" + + /* save float registers */ + "\tfstds,ma %%fr12,8(0,%%r19)\n" + "\tfstds,ma %%fr13,8(0,%%r19)\n" + "\tfstds,ma %%fr14,8(0,%%r19)\n" + "\tfstds,ma %%fr15,8(0,%%r19)\n" + "\tfstds,ma %%fr16,8(0,%%r19)\n" + "\tfstds,ma %%fr17,8(0,%%r19)\n" + "\tfstds,ma %%fr18,8(0,%%r19)\n" + "\tfstds,ma %%fr19,8(0,%%r19)\n" + "\tfstds,ma %%fr20,8(0,%%r19)\n" + "\tfstds,ma %%fr21,8(0,%%r19)\n" + + /* jump to f */ + /* This is the gcc code generated by "JMP_(f)". */ + "\textrw,s,>= %%r26,30,1,%%r0\n" + "\tldw -2(%%r26),%%r26\n" + "\tbv,n %%r0(%%r26)\n" + + "\t.align 4\n" "\t.EXPORT " STG_RETURN ",CODE\n" "\t.EXPORT " STG_RETURN ",ENTRY,PRIV_LEV=3\n" STG_RETURN "\n" - /* "\tldo %0(%%r3),%%r19\n" */ - "\tldo %1(%%r30),%%r19\n" - "\tcopy %%r11, %0\n" /* save R1 */ - "\tldw 0(0,%%r19),%%r3\n" - "\tldw 4(0,%%r19),%%r4\n" - "\tldw 8(0,%%r19),%%r5\n" - "\tldw 12(0,%%r19),%%r6\n" - "\tldw 16(0,%%r19),%%r7\n" - "\tldw 20(0,%%r19),%%r8\n" - "\tldw 24(0,%%r19),%%r9\n" - "\tldw 28(0,%%r19),%%r10\n" - "\tldw 32(0,%%r19),%%r11\n" - "\tldw 36(0,%%r19),%%r12\n" - "\tldw 40(0,%%r19),%%r13\n" - "\tldw 44(0,%%r19),%%r14\n" - "\tldw 48(0,%%r19),%%r15\n" - "\tldw 52(0,%%r19),%%r16\n" - "\tldw 56(0,%%r19),%%r17\n" - "\tldw 60(0,%%r19),%%r18\n" - "\tldo 80(%%r19),%%r19\n" - "\tfldds -16(0,%%r19),%%fr12\n" - "\tfldds -8(0,%%r19),%%fr13\n" - "\tfldds 0(0,%%r19),%%fr14\n" - "\tfldds 8(0,%%r19),%%fr15\n" - "\tldo 32(%%r19),%%r19\n" - "\tfldds -16(0,%%r19),%%fr16\n" - "\tfldds -8(0,%%r19),%%fr17\n" - "\tfldds 0(0,%%r19),%%fr18\n" - "\tfldds 8(0,%%r19),%%fr19\n" - "\tldo 32(%%r19),%%r19\n" - "\tfldds -16(0,%%r19),%%fr20\n" - "\tfldds -8(0,%%r19),%%fr21\n" - : "=r" (ret) - : "n" (-(116 * sizeof(long) + 10 * sizeof(double))) - : "%r19" - ); + "\tcopy %%r11,%%ret0\n" /* save R1 */ - return ret; + /* get pointer to allocated space */ + "\tldil L'-%0,%%r1\n" + "\tldo R'-%0(%%r1),%%r1\n" + "\tadd %%r1,%%r30,%%r1\n" + "\tldo 0(%%r1),%%r19\n" + + /* restore integer registers */ + "\tldws,ma 4(0,%%r19),%%rp\n" /* return address */ + "\tldws,ma 4(0,%%r19),%%r3\n" + "\tldws,ma 4(0,%%r19),%%r4\n" + "\tldws,ma 4(0,%%r19),%%r5\n" + "\tldws,ma 4(0,%%r19),%%r6\n" + "\tldws,ma 4(0,%%r19),%%r7\n" + "\tldws,ma 4(0,%%r19),%%r8\n" + "\tldws,ma 4(0,%%r19),%%r9\n" + "\tldws,ma 4(0,%%r19),%%r10\n" + "\tldws,ma 4(0,%%r19),%%r11\n" + "\tldws,ma 4(0,%%r19),%%r12\n" + "\tldws,ma 4(0,%%r19),%%r13\n" + "\tldws,ma 4(0,%%r19),%%r14\n" + "\tldws,ma 4(0,%%r19),%%r15\n" + "\tldws,ma 4(0,%%r19),%%r16\n" + "\tldws,ma 4(0,%%r19),%%r17\n" + "\tldws,ma 4(0,%%r19),%%r18\n" + + /* keep stack alignment for floats */ + "\tldo 4(%%r19),%%r19\n" + + /* restore float registers */ + "\tfldds,ma 8(0,%%r19),%%fr12\n" + "\tfldds,ma 8(0,%%r19),%%fr13\n" + "\tfldds,ma 8(0,%%r19),%%fr14\n" + "\tfldds,ma 8(0,%%r19),%%fr15\n" + "\tfldds,ma 8(0,%%r19),%%fr16\n" + "\tfldds,ma 8(0,%%r19),%%fr17\n" + "\tfldds,ma 8(0,%%r19),%%fr18\n" + "\tfldds,ma 8(0,%%r19),%%fr19\n" + "\tfldds,ma 8(0,%%r19),%%fr20\n" + "\tfldds,ma 8(0,%%r19),%%fr21\n" + + /* deallocate stack space and return */ + "\tldil L'-%0,%%r1\n" + "\tldo R'-%0(%%r1),%%r1\n" + "\tbv %%r0(%%rp)\n" + "\tadd %%r1,%%r30,%%r30\n" + + : : "n" (RESERVED_C_STACK_BYTES+18*sizeof(long)+10*sizeof(double)) + ); } -#endif /* hppa1_1_HOST_ARCH */ +#endif /* hppa1_1_HOST_ARCH || hppa2_0_HOST_ARCH */ /* ----------------------------------------------------------------------------- PowerPC architecture --- ./rts/posix/OSMem.c.~1~ 2007-04-25 13:10:40.000000000 -0400 +++ ./rts/posix/OSMem.c 2007-07-29 13:12:55.000000000 -0400 @@ -14,7 +14,8 @@ #include /* no C99 header stdint.h on OpenBSD? */ -#if defined(openbsd_HOST_OS) +/* (definitely not for HPUX 11.0) */ +#if defined(openbsd_HOST_OS) || defined(hpux_HOST_OS) typedef unsigned long my_uintptr_t; #else #include EOF } patch_local() { /usr/local/bin/patch -p0 -N -b -V numbered <<\EOF --- ./mk/bootstrap.mk.~1~ 2007-04-25 13:10:40.000000000 -0400 +++ ./mk/bootstrap.mk 2007-07-27 20:47:41.000000000 -0400 @@ -83,6 +83,8 @@ ifeq "$(HaveLibGmp)" "NO" DASH_L_GHC_RTS_GMP_DIR=-L$(FPTOOLS_TOP_ABS)/$(GHC_RTS_DIR_REL)/gmp +else +DASH_L_GHC_RTS_GMP_DIR=-L/usr/local/gmp/4.1.4/lib endif HC_BOOT_LD_OPTS = \ --- ./mk/config.mk.in.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./mk/config.mk.in 2007-07-29 12:59:45.000000000 -0400 @@ -604,7 +609,7 @@ # These flags make flex 8-bit SRC_FLEX_OPTS += -8 -SRC_INSTALL_BIN_OPTS += -s +SRC_INSTALL_BIN_OPTS += # lint gets all CPP's flags too SRC_LINT_OPTS += -axz -DLINT $(SRC_CPP_OPTS) --- ./rts/package.conf.in.~1~ 2007-04-25 13:10:41.000000000 -0400 +++ ./rts/package.conf.in 2007-07-27 20:47:41.000000000 -0400 @@ -16,12 +16,14 @@ #ifdef INSTALLING library-dirs: LIB_DIR GMP_LIB_DIRS + , "/usr/local/gmp/4.1.4/lib" # ifdef mingw32_HOST_OS , LIB_DIR"/gcc-lib" /* force the dist-provided gcc-lib/ into scope. */ # endif #else /* !INSTALLING */ library-dirs: FPTOOLS_TOP_ABS"/rts" GMP_LIB_DIRS + , "/usr/local/gmp/4.1.4/lib" # if !defined(HAVE_LIBGMP) && !defined(HAVE_FRAMEWORK_GMP) , FPTOOLS_TOP_ABS"/rts/gmp" # endif EOF } export CONFIG_SHELL=/bin/ksh export PATH="/usr/local/perl-5.8.0/bin:$PATH" export HOME="$PWD" PADDING=////////////////////////////////////////////////////////////////// ( cd .. && gtar -xjf /usr/local/src/haskell/ghc-6.6.1-src-extralibs.tar.bz2 ) && case "$OS" in aix) export LDFLAGS=-Wl,-bbigtoc patch_aix ;; hpux) patch_hpux ;; esac && patch_local && CPPFLAGS=-I/usr/local/gmp/4.1.4/include \ LDFLAGS=-L/usr/local/gmp/4.1.4/lib \ ./configure \ --prefix=$PADDING/usr/local/ghc-6.6.1 \ --with-gcc=$PADDING/usr/local/gcc-4.0.4/bin/gcc \ --with-ghc=/usr/local/ghc-6.4.2/bin/ghc \ $(: --with-ghc=/home/project-releases/ghc-build2/ghc-6.4.2/ghc/compiler/ghc-inplace) && gmake -j4 && gmake install && #rm -f /usr/local/ghc-6.6.1/lib/ghc-6.6.1/libgmp.a && #cp -p /usr/local/gmp/4.1.4/lib/libgmp.a /usr/local/ghc-6.6.1/lib/ghc-6.6.1/ && true exit 1