diff options
author | Sergei Trofimovich <siarheit@google.com> | 2014-12-14 14:30:12 +0000 |
---|---|---|
committer | Sergei Trofimovich <siarheit@google.com> | 2014-12-14 14:30:12 +0000 |
commit | fa31e8f4a0f853848d96549a429083941877bf8d (patch) | |
tree | c45f86f090dd27aae6dbe522336ab6e74e13fbb4 /compiler/nativeGen/PIC.hs | |
parent | ef7eb8f30532c8f85f05b318c85c7d819f61d715 (diff) | |
download | haskell-fa31e8f4a0f853848d96549a429083941877bf8d.tar.gz |
powerpc: fix and enable shared libraries by default on linux
Summary:
And fix things all the way down to it. Namely:
- remove 'r30' from free registers, it's an .LCTOC1 register
for gcc. generated .plt stubs expect it to be initialised.
- fix PicBase computation, which originally forgot to use 'tmp'
reg in 'initializePicBase_ppc.fetchPC'
- mark 'ForeighTarget's as implicitly using 'PicBase' register
(see comment for details)
- add 64-bit MO_Sub and test on alloclimit3/4 regtests
- fix dynamic label offsets to match with .LCTOC1 offset
Signed-off-by: Sergei Trofimovich <siarheit@google.com>
Test Plan: validate passes equal amount of vanilla/dyn tests
Reviewers: simonmar, erikd, austin
Reviewed By: erikd, austin
Subscribers: carter, thomie
Differential Revision: https://phabricator.haskell.org/D560
GHC Trac Issues: #8024, #9831
Diffstat (limited to 'compiler/nativeGen/PIC.hs')
-rw-r--r-- | compiler/nativeGen/PIC.hs | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/compiler/nativeGen/PIC.hs b/compiler/nativeGen/PIC.hs index 9b5c080b5b..6326a8bdaf 100644 --- a/compiler/nativeGen/PIC.hs +++ b/compiler/nativeGen/PIC.hs @@ -54,7 +54,6 @@ import qualified X86.Instr as X86 import Platform import Instruction -import Size import Reg import NCGMonad @@ -468,11 +467,8 @@ pprGotDeclaration dflags ArchX86 OSDarwin pprGotDeclaration _ _ OSDarwin = empty --- pprGotDeclaration +-- Emit GOT declaration -- Output whatever needs to be output once per .s file. --- The .LCTOC1 label is defined to point 32768 bytes into the table, --- to make the most of the PPC's 16-bit displacements. --- Only needed for PIC. pprGotDeclaration dflags arch os | osElfTarget os , arch /= ArchPPC_64 @@ -482,6 +478,7 @@ pprGotDeclaration dflags arch os | osElfTarget os , arch /= ArchPPC_64 = vcat [ + -- See Note [.LCTOC1 in PPC PIC code] ptext (sLit ".section \".got2\",\"aw\""), ptext (sLit ".LCTOC1 = .+32768") ] @@ -688,12 +685,7 @@ pprImportedSymbol _ _ _ -- Get a pointer to our own fake GOT, which is defined on a per-module basis. --- This is exactly how GCC does it, and it's quite horrible: --- We first fetch the address of a local label (mkPicBaseLabel). --- Then we add a 16-bit offset to that to get the address of a .long that we --- define in .text space right next to the proc. This .long literal contains --- the (32-bit) offset from our local label to our global offset table --- (.LCTOC1 aka gotOffLabel). +-- This is exactly how GCC does it in linux. initializePicBase_ppc :: Arch -> OS -> Reg @@ -704,18 +696,9 @@ initializePicBase_ppc ArchPPC os picReg (CmmProc info lab live (ListGraph blocks) : statics) | osElfTarget os = do - dflags <- getDynFlags - gotOffLabel <- getNewLabelNat - tmp <- getNewRegNat $ intSize (wordWidth dflags) let - gotOffset = CmmData Text $ Statics gotOffLabel [ - CmmStaticLit (CmmLabelDiffOff gotLabel - mkPicBaseLabel - 0) - ] - offsetToOffset - = PPC.ImmConstantDiff - (PPC.ImmCLbl gotOffLabel) + gotOffset = PPC.ImmConstantDiff + (PPC.ImmCLbl gotLabel) (PPC.ImmCLbl mkPicBaseLabel) blocks' = case blocks of @@ -726,15 +709,23 @@ initializePicBase_ppc ArchPPC os picReg | bID `mapMember` info = fetchPC b | otherwise = b + -- GCC does PIC prologs thusly: + -- bcl 20,31,.L1 + -- .L1: + -- mflr 30 + -- addis 30,30,.LCTOC1-.L1@ha + -- addi 30,30,.LCTOC1-.L1@l + -- TODO: below we use it over temporary register, + -- it can and should be optimised by picking + -- correct PIC reg. fetchPC (BasicBlock bID insns) = BasicBlock bID (PPC.FETCHPC picReg - : PPC.ADDIS tmp picReg (PPC.HI offsetToOffset) - : PPC.LD PPC.archWordSize tmp - (PPC.AddrRegImm tmp (PPC.LO offsetToOffset)) - : PPC.ADD picReg picReg (PPC.RIReg picReg) + : PPC.ADDIS picReg picReg (PPC.HA gotOffset) + : PPC.ADDI picReg picReg (PPC.LO gotOffset) + : PPC.MR PPC.r30 picReg : insns) - return (CmmProc info lab live (ListGraph blocks') : gotOffset : statics) + return (CmmProc info lab live (ListGraph blocks') : statics) initializePicBase_ppc ArchPPC OSDarwin picReg |