1{-# LANGUAGE CPP #-}
2
3-----------------------------------------------------------------------------
4--
5-- Machine-dependent assembly language
6--
7-- (c) The University of Glasgow 1993-2004
8--
9-----------------------------------------------------------------------------
10
11#include "HsVersions.h"
12
13module PPC.Instr (
14    archWordFormat,
15    RI(..),
16    Instr(..),
17    stackFrameHeaderSize,
18    maxSpillSlots,
19    allocMoreStack,
20    makeFarBranches
21)
22
23where
24
25import GhcPrelude
26
27import PPC.Regs
28import PPC.Cond
29import Instruction
30import Format
31import TargetReg
32import RegClass
33import Reg
34
35import GHC.Platform.Regs
36import BlockId
37import Hoopl.Collections
38import Hoopl.Label
39import DynFlags
40import Cmm
41import CmmInfo
42import FastString
43import CLabel
44import Outputable
45import GHC.Platform
46import UniqFM (listToUFM, lookupUFM)
47import UniqSupply
48
49import Control.Monad (replicateM)
50import Data.Maybe (fromMaybe)
51
52--------------------------------------------------------------------------------
53-- Format of a PPC memory address.
54--
55archWordFormat :: Bool -> Format
56archWordFormat is32Bit
57 | is32Bit   = II32
58 | otherwise = II64
59
60
61-- | Instruction instance for powerpc
62instance Instruction Instr where
63        regUsageOfInstr         = ppc_regUsageOfInstr
64        patchRegsOfInstr        = ppc_patchRegsOfInstr
65        isJumpishInstr          = ppc_isJumpishInstr
66        jumpDestsOfInstr        = ppc_jumpDestsOfInstr
67        patchJumpInstr          = ppc_patchJumpInstr
68        mkSpillInstr            = ppc_mkSpillInstr
69        mkLoadInstr             = ppc_mkLoadInstr
70        takeDeltaInstr          = ppc_takeDeltaInstr
71        isMetaInstr             = ppc_isMetaInstr
72        mkRegRegMoveInstr _     = ppc_mkRegRegMoveInstr
73        takeRegRegMoveInstr     = ppc_takeRegRegMoveInstr
74        mkJumpInstr             = ppc_mkJumpInstr
75        mkStackAllocInstr       = ppc_mkStackAllocInstr
76        mkStackDeallocInstr     = ppc_mkStackDeallocInstr
77
78
79ppc_mkStackAllocInstr :: Platform -> Int -> [Instr]
80ppc_mkStackAllocInstr platform amount
81  = ppc_mkStackAllocInstr' platform (-amount)
82
83ppc_mkStackDeallocInstr :: Platform -> Int -> [Instr]
84ppc_mkStackDeallocInstr platform amount
85  = ppc_mkStackAllocInstr' platform amount
86
87ppc_mkStackAllocInstr' :: Platform -> Int -> [Instr]
88ppc_mkStackAllocInstr' platform amount
89  | fits16Bits amount
90  = [ LD fmt r0 (AddrRegImm sp zero)
91    , STU fmt r0 (AddrRegImm sp immAmount)
92    ]
93  | otherwise
94  = [ LD fmt r0 (AddrRegImm sp zero)
95    , ADDIS tmp sp (HA immAmount)
96    , ADD tmp tmp (RIImm (LO immAmount))
97    , STU fmt r0 (AddrRegReg sp tmp)
98    ]
99  where
100    fmt = intFormat $ widthFromBytes (platformWordSizeInBytes platform)
101    zero = ImmInt 0
102    tmp = tmpReg platform
103    immAmount = ImmInt amount
104
105--
106-- See note [extra spill slots] in X86/Instr.hs
107--
108allocMoreStack
109  :: Platform
110  -> Int
111  -> NatCmmDecl statics PPC.Instr.Instr
112  -> UniqSM (NatCmmDecl statics PPC.Instr.Instr, [(BlockId,BlockId)])
113
114allocMoreStack _ _ top@(CmmData _ _) = return (top,[])
115allocMoreStack platform slots (CmmProc info lbl live (ListGraph code)) = do
116    let
117        infos   = mapKeys info
118        entries = case code of
119                    [] -> infos
120                    BasicBlock entry _ : _ -- first block is the entry point
121                        | entry `elem` infos -> infos
122                        | otherwise          -> entry : infos
123
124    uniqs <- replicateM (length entries) getUniqueM
125
126    let
127        delta = ((x + stackAlign - 1) `quot` stackAlign) * stackAlign -- round up
128            where x = slots * spillSlotSize -- sp delta
129
130        alloc   = mkStackAllocInstr   platform delta
131        dealloc = mkStackDeallocInstr platform delta
132
133        retargetList = (zip entries (map mkBlockId uniqs))
134
135        new_blockmap :: LabelMap BlockId
136        new_blockmap = mapFromList retargetList
137
138        insert_stack_insns (BasicBlock id insns)
139            | Just new_blockid <- mapLookup id new_blockmap
140                = [ BasicBlock id $ alloc ++ [BCC ALWAYS new_blockid Nothing]
141                  , BasicBlock new_blockid block'
142                  ]
143            | otherwise
144                = [ BasicBlock id block' ]
145            where
146              block' = foldr insert_dealloc [] insns
147
148        insert_dealloc insn r
149            -- BCTR might or might not be a non-local jump. For
150            -- "labeled-goto" we use JMP, and for "computed-goto" we
151            -- use MTCTR followed by BCTR. See 'PPC.CodeGen.genJump'.
152            = case insn of
153                JMP _ _           -> dealloc ++ (insn : r)
154                BCTR [] Nothing _ -> dealloc ++ (insn : r)
155                BCTR ids label rs -> BCTR (map (fmap retarget) ids) label rs : r
156                BCCFAR cond b p   -> BCCFAR cond (retarget b) p : r
157                BCC    cond b p   -> BCC    cond (retarget b) p : r
158                _                 -> insn : r
159            -- BL and BCTRL are call-like instructions rather than
160            -- jumps, and are used only for C calls.
161
162        retarget :: BlockId -> BlockId
163        retarget b
164            = fromMaybe b (mapLookup b new_blockmap)
165
166        new_code
167            = concatMap insert_stack_insns code
168
169    -- in
170    return (CmmProc info lbl live (ListGraph new_code),retargetList)
171
172
173-- -----------------------------------------------------------------------------
174-- Machine's assembly language
175
176-- We have a few common "instructions" (nearly all the pseudo-ops) but
177-- mostly all of 'Instr' is machine-specific.
178
179-- Register or immediate
180data RI
181    = RIReg Reg
182    | RIImm Imm
183
184data Instr
185    -- comment pseudo-op
186    = COMMENT FastString
187
188    -- some static data spat out during code
189    -- generation.  Will be extracted before
190    -- pretty-printing.
191    | LDATA   Section CmmStatics
192
193    -- start a new basic block.  Useful during
194    -- codegen, removed later.  Preceding
195    -- instruction should be a jump, as per the
196    -- invariants for a BasicBlock (see Cmm).
197    | NEWBLOCK BlockId
198
199    -- specify current stack offset for
200    -- benefit of subsequent passes
201    | DELTA   Int
202
203    -- Loads and stores.
204    | LD      Format Reg AddrMode   -- Load format, dst, src
205    | LDFAR   Format Reg AddrMode   -- Load format, dst, src 32 bit offset
206    | LDR     Format Reg AddrMode   -- Load and reserve format, dst, src
207    | LA      Format Reg AddrMode   -- Load arithmetic format, dst, src
208    | ST      Format Reg AddrMode   -- Store format, src, dst
209    | STFAR   Format Reg AddrMode   -- Store format, src, dst 32 bit offset
210    | STU     Format Reg AddrMode   -- Store with Update format, src, dst
211    | STC     Format Reg AddrMode   -- Store conditional format, src, dst
212    | LIS     Reg Imm               -- Load Immediate Shifted dst, src
213    | LI      Reg Imm               -- Load Immediate dst, src
214    | MR      Reg Reg               -- Move Register dst, src -- also for fmr
215
216    | CMP     Format Reg RI         -- format, src1, src2
217    | CMPL    Format Reg RI         -- format, src1, src2
218
219    | BCC     Cond BlockId (Maybe Bool) -- cond, block, hint
220    | BCCFAR  Cond BlockId (Maybe Bool) -- cond, block, hint
221                                    --   hint:
222                                    --    Just True:  branch likely taken
223                                    --    Just False: branch likely not taken
224                                    --    Nothing:    no hint
225    | JMP     CLabel [Reg]          -- same as branch,
226                                    -- but with CLabel instead of block ID
227                                    -- and live global registers
228    | MTCTR   Reg
229    | BCTR    [Maybe BlockId] (Maybe CLabel) [Reg]
230                                    -- with list of local destinations, and
231                                    -- jump table location if necessary
232    | BL      CLabel [Reg]          -- with list of argument regs
233    | BCTRL   [Reg]
234
235    | ADD     Reg Reg RI            -- dst, src1, src2
236    | ADDO    Reg Reg Reg           -- add and set overflow
237    | ADDC    Reg Reg Reg           -- (carrying) dst, src1, src2
238    | ADDE    Reg Reg Reg           -- (extended) dst, src1, src2
239    | ADDZE   Reg Reg               -- (to zero extended) dst, src
240    | ADDIS   Reg Reg Imm           -- Add Immediate Shifted dst, src1, src2
241    | SUBF    Reg Reg Reg           -- dst, src1, src2 ; dst = src2 - src1
242    | SUBFO   Reg Reg Reg           -- subtract from and set overflow
243    | SUBFC   Reg Reg RI            -- (carrying) dst, src1, src2 ;
244                                    -- dst = src2 - src1
245    | SUBFE   Reg Reg Reg           -- (extended) dst, src1, src2 ;
246                                    -- dst = src2 - src1
247    | MULL    Format Reg Reg RI
248    | MULLO   Format Reg Reg Reg    -- multiply and set overflow
249    | MFOV    Format Reg            -- move overflow bit (1|33) to register
250                                    -- pseudo-instruction; pretty printed as
251                                    -- mfxer dst
252                                    -- extr[w|d]i dst, dst, 1, [1|33]
253    | MULHU   Format Reg Reg Reg
254    | DIV     Format Bool Reg Reg Reg
255    | AND     Reg Reg RI            -- dst, src1, src2
256    | ANDC    Reg Reg Reg           -- AND with complement, dst = src1 & ~ src2
257    | NAND    Reg Reg Reg           -- dst, src1, src2
258    | OR      Reg Reg RI            -- dst, src1, src2
259    | ORIS    Reg Reg Imm           -- OR Immediate Shifted dst, src1, src2
260    | XOR     Reg Reg RI            -- dst, src1, src2
261    | XORIS   Reg Reg Imm           -- XOR Immediate Shifted dst, src1, src2
262
263    | EXTS    Format Reg Reg
264    | CNTLZ   Format Reg Reg
265
266    | NEG     Reg Reg
267    | NOT     Reg Reg
268
269    | SL      Format Reg Reg RI            -- shift left
270    | SR      Format Reg Reg RI            -- shift right
271    | SRA     Format Reg Reg RI            -- shift right arithmetic
272
273    | RLWINM  Reg Reg Int Int Int   -- Rotate Left Word Immediate then AND with Mask
274    | CLRLI   Format Reg Reg Int    -- clear left immediate (extended mnemonic)
275    | CLRRI   Format Reg Reg Int    -- clear right immediate (extended mnemonic)
276
277    | FADD    Format Reg Reg Reg
278    | FSUB    Format Reg Reg Reg
279    | FMUL    Format Reg Reg Reg
280    | FDIV    Format Reg Reg Reg
281    | FABS    Reg Reg               -- abs is the same for single and double
282    | FNEG    Reg Reg               -- negate is the same for single and double prec.
283
284    | FCMP    Reg Reg
285
286    | FCTIWZ  Reg Reg           -- convert to integer word
287    | FCTIDZ  Reg Reg           -- convert to integer double word
288    | FCFID   Reg Reg           -- convert from integer double word
289    | FRSP    Reg Reg           -- reduce to single precision
290                                -- (but destination is a FP register)
291
292    | CRNOR   Int Int Int       -- condition register nor
293    | MFCR    Reg               -- move from condition register
294
295    | MFLR    Reg               -- move from link register
296    | FETCHPC Reg               -- pseudo-instruction:
297                                -- bcl to next insn, mflr reg
298    | HWSYNC                    -- heavy weight sync
299    | ISYNC                     -- instruction synchronize
300    | LWSYNC                    -- memory barrier
301    | NOP                       -- no operation, PowerPC 64 bit
302                                -- needs this as place holder to
303                                -- reload TOC pointer
304
305-- | Get the registers that are being used by this instruction.
306-- regUsage doesn't need to do any trickery for jumps and such.
307-- Just state precisely the regs read and written by that insn.
308-- The consequences of control flow transfers, as far as register
309-- allocation goes, are taken care of by the register allocator.
310--
311ppc_regUsageOfInstr :: Platform -> Instr -> RegUsage
312ppc_regUsageOfInstr platform instr
313 = case instr of
314    LD      _ reg addr       -> usage (regAddr addr, [reg])
315    LDFAR   _ reg addr       -> usage (regAddr addr, [reg])
316    LDR     _ reg addr       -> usage (regAddr addr, [reg])
317    LA      _ reg addr       -> usage (regAddr addr, [reg])
318    ST      _ reg addr       -> usage (reg : regAddr addr, [])
319    STFAR   _ reg addr       -> usage (reg : regAddr addr, [])
320    STU     _ reg addr       -> usage (reg : regAddr addr, [])
321    STC     _ reg addr       -> usage (reg : regAddr addr, [])
322    LIS     reg _            -> usage ([], [reg])
323    LI      reg _            -> usage ([], [reg])
324    MR      reg1 reg2        -> usage ([reg2], [reg1])
325    CMP     _ reg ri         -> usage (reg : regRI ri,[])
326    CMPL    _ reg ri         -> usage (reg : regRI ri,[])
327    BCC     _ _ _            -> noUsage
328    BCCFAR  _ _ _            -> noUsage
329    JMP     _ regs           -> usage (regs, [])
330    MTCTR   reg              -> usage ([reg],[])
331    BCTR    _ _ regs         -> usage (regs, [])
332    BL      _ params         -> usage (params, callClobberedRegs platform)
333    BCTRL   params           -> usage (params, callClobberedRegs platform)
334
335    ADD     reg1 reg2 ri     -> usage (reg2 : regRI ri, [reg1])
336    ADDO    reg1 reg2 reg3   -> usage ([reg2,reg3], [reg1])
337    ADDC    reg1 reg2 reg3   -> usage ([reg2,reg3], [reg1])
338    ADDE    reg1 reg2 reg3   -> usage ([reg2,reg3], [reg1])
339    ADDZE   reg1 reg2        -> usage ([reg2], [reg1])
340    ADDIS   reg1 reg2 _      -> usage ([reg2], [reg1])
341    SUBF    reg1 reg2 reg3   -> usage ([reg2,reg3], [reg1])
342    SUBFO   reg1 reg2 reg3   -> usage ([reg2,reg3], [reg1])
343    SUBFC   reg1 reg2 ri     -> usage (reg2 : regRI ri, [reg1])
344    SUBFE   reg1 reg2 reg3   -> usage ([reg2,reg3], [reg1])
345    MULL    _ reg1 reg2 ri   -> usage (reg2 : regRI ri, [reg1])
346    MULLO   _ reg1 reg2 reg3 -> usage ([reg2,reg3], [reg1])
347    MFOV    _ reg            -> usage ([], [reg])
348    MULHU   _ reg1 reg2 reg3 -> usage ([reg2,reg3], [reg1])
349    DIV     _ _ reg1 reg2 reg3
350                             -> usage ([reg2,reg3], [reg1])
351
352    AND     reg1 reg2 ri    -> usage (reg2 : regRI ri, [reg1])
353    ANDC    reg1 reg2 reg3  -> usage ([reg2,reg3], [reg1])
354    NAND    reg1 reg2 reg3  -> usage ([reg2,reg3], [reg1])
355    OR      reg1 reg2 ri    -> usage (reg2 : regRI ri, [reg1])
356    ORIS    reg1 reg2 _     -> usage ([reg2], [reg1])
357    XOR     reg1 reg2 ri    -> usage (reg2 : regRI ri, [reg1])
358    XORIS   reg1 reg2 _     -> usage ([reg2], [reg1])
359    EXTS    _  reg1 reg2    -> usage ([reg2], [reg1])
360    CNTLZ   _  reg1 reg2    -> usage ([reg2], [reg1])
361    NEG     reg1 reg2       -> usage ([reg2], [reg1])
362    NOT     reg1 reg2       -> usage ([reg2], [reg1])
363    SL      _ reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
364    SR      _ reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
365    SRA     _ reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
366    RLWINM  reg1 reg2 _ _ _ -> usage ([reg2], [reg1])
367    CLRLI   _ reg1 reg2 _   -> usage ([reg2], [reg1])
368    CLRRI   _ reg1 reg2 _   -> usage ([reg2], [reg1])
369
370    FADD    _ r1 r2 r3      -> usage ([r2,r3], [r1])
371    FSUB    _ r1 r2 r3      -> usage ([r2,r3], [r1])
372    FMUL    _ r1 r2 r3      -> usage ([r2,r3], [r1])
373    FDIV    _ r1 r2 r3      -> usage ([r2,r3], [r1])
374    FABS    r1 r2           -> usage ([r2], [r1])
375    FNEG    r1 r2           -> usage ([r2], [r1])
376    FCMP    r1 r2           -> usage ([r1,r2], [])
377    FCTIWZ  r1 r2           -> usage ([r2], [r1])
378    FCTIDZ  r1 r2           -> usage ([r2], [r1])
379    FCFID   r1 r2           -> usage ([r2], [r1])
380    FRSP    r1 r2           -> usage ([r2], [r1])
381    MFCR    reg             -> usage ([], [reg])
382    MFLR    reg             -> usage ([], [reg])
383    FETCHPC reg             -> usage ([], [reg])
384    _                       -> noUsage
385  where
386    usage (src, dst) = RU (filter (interesting platform) src)
387                          (filter (interesting platform) dst)
388    regAddr (AddrRegReg r1 r2) = [r1, r2]
389    regAddr (AddrRegImm r1 _)  = [r1]
390
391    regRI (RIReg r) = [r]
392    regRI  _        = []
393
394interesting :: Platform -> Reg -> Bool
395interesting _        (RegVirtual _)              = True
396interesting platform (RegReal (RealRegSingle i)) = freeReg platform i
397interesting _        (RegReal (RealRegPair{}))
398    = panic "PPC.Instr.interesting: no reg pairs on this arch"
399
400
401
402-- | Apply a given mapping to all the register references in this
403-- instruction.
404ppc_patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
405ppc_patchRegsOfInstr instr env
406 = case instr of
407    LD      fmt reg addr    -> LD fmt (env reg) (fixAddr addr)
408    LDFAR   fmt reg addr    -> LDFAR fmt (env reg) (fixAddr addr)
409    LDR     fmt reg addr    -> LDR fmt (env reg) (fixAddr addr)
410    LA      fmt reg addr    -> LA fmt (env reg) (fixAddr addr)
411    ST      fmt reg addr    -> ST fmt (env reg) (fixAddr addr)
412    STFAR   fmt reg addr    -> STFAR fmt (env reg) (fixAddr addr)
413    STU     fmt reg addr    -> STU fmt (env reg) (fixAddr addr)
414    STC     fmt reg addr    -> STC fmt (env reg) (fixAddr addr)
415    LIS     reg imm         -> LIS (env reg) imm
416    LI      reg imm         -> LI (env reg) imm
417    MR      reg1 reg2       -> MR (env reg1) (env reg2)
418    CMP     fmt reg ri      -> CMP fmt (env reg) (fixRI ri)
419    CMPL    fmt reg ri      -> CMPL fmt (env reg) (fixRI ri)
420    BCC     cond lbl p      -> BCC cond lbl p
421    BCCFAR  cond lbl p      -> BCCFAR cond lbl p
422    JMP     l regs          -> JMP l regs -- global regs will not be remapped
423    MTCTR   reg             -> MTCTR (env reg)
424    BCTR    targets lbl rs  -> BCTR targets lbl rs
425    BL      imm argRegs     -> BL imm argRegs    -- argument regs
426    BCTRL   argRegs         -> BCTRL argRegs     -- cannot be remapped
427    ADD     reg1 reg2 ri    -> ADD (env reg1) (env reg2) (fixRI ri)
428    ADDO    reg1 reg2 reg3  -> ADDO (env reg1) (env reg2) (env reg3)
429    ADDC    reg1 reg2 reg3  -> ADDC (env reg1) (env reg2) (env reg3)
430    ADDE    reg1 reg2 reg3  -> ADDE (env reg1) (env reg2) (env reg3)
431    ADDZE   reg1 reg2       -> ADDZE (env reg1) (env reg2)
432    ADDIS   reg1 reg2 imm   -> ADDIS (env reg1) (env reg2) imm
433    SUBF    reg1 reg2 reg3  -> SUBF (env reg1) (env reg2) (env reg3)
434    SUBFO   reg1 reg2 reg3  -> SUBFO (env reg1) (env reg2) (env reg3)
435    SUBFC   reg1 reg2 ri    -> SUBFC (env reg1) (env reg2) (fixRI ri)
436    SUBFE   reg1 reg2 reg3  -> SUBFE (env reg1) (env reg2) (env reg3)
437    MULL    fmt reg1 reg2 ri
438                            -> MULL fmt (env reg1) (env reg2) (fixRI ri)
439    MULLO   fmt reg1 reg2 reg3
440                            -> MULLO fmt (env reg1) (env reg2) (env reg3)
441    MFOV    fmt reg         -> MFOV fmt (env reg)
442    MULHU   fmt reg1 reg2 reg3
443                            -> MULHU fmt (env reg1) (env reg2) (env reg3)
444    DIV     fmt sgn reg1 reg2 reg3
445                            -> DIV fmt sgn (env reg1) (env reg2) (env reg3)
446
447    AND     reg1 reg2 ri    -> AND (env reg1) (env reg2) (fixRI ri)
448    ANDC    reg1 reg2 reg3  -> ANDC (env reg1) (env reg2) (env reg3)
449    NAND    reg1 reg2 reg3  -> NAND (env reg1) (env reg2) (env reg3)
450    OR      reg1 reg2 ri    -> OR  (env reg1) (env reg2) (fixRI ri)
451    ORIS    reg1 reg2 imm   -> ORIS (env reg1) (env reg2) imm
452    XOR     reg1 reg2 ri    -> XOR (env reg1) (env reg2) (fixRI ri)
453    XORIS   reg1 reg2 imm   -> XORIS (env reg1) (env reg2) imm
454    EXTS    fmt reg1 reg2   -> EXTS fmt (env reg1) (env reg2)
455    CNTLZ   fmt reg1 reg2   -> CNTLZ fmt (env reg1) (env reg2)
456    NEG     reg1 reg2       -> NEG (env reg1) (env reg2)
457    NOT     reg1 reg2       -> NOT (env reg1) (env reg2)
458    SL      fmt reg1 reg2 ri
459                            -> SL fmt (env reg1) (env reg2) (fixRI ri)
460    SR      fmt reg1 reg2 ri
461                            -> SR fmt (env reg1) (env reg2) (fixRI ri)
462    SRA     fmt reg1 reg2 ri
463                            -> SRA fmt (env reg1) (env reg2) (fixRI ri)
464    RLWINM  reg1 reg2 sh mb me
465                            -> RLWINM (env reg1) (env reg2) sh mb me
466    CLRLI   fmt reg1 reg2 n -> CLRLI fmt (env reg1) (env reg2) n
467    CLRRI   fmt reg1 reg2 n -> CLRRI fmt (env reg1) (env reg2) n
468    FADD    fmt r1 r2 r3    -> FADD fmt (env r1) (env r2) (env r3)
469    FSUB    fmt r1 r2 r3    -> FSUB fmt (env r1) (env r2) (env r3)
470    FMUL    fmt r1 r2 r3    -> FMUL fmt (env r1) (env r2) (env r3)
471    FDIV    fmt r1 r2 r3    -> FDIV fmt (env r1) (env r2) (env r3)
472    FABS    r1 r2           -> FABS (env r1) (env r2)
473    FNEG    r1 r2           -> FNEG (env r1) (env r2)
474    FCMP    r1 r2           -> FCMP (env r1) (env r2)
475    FCTIWZ  r1 r2           -> FCTIWZ (env r1) (env r2)
476    FCTIDZ  r1 r2           -> FCTIDZ (env r1) (env r2)
477    FCFID   r1 r2           -> FCFID (env r1) (env r2)
478    FRSP    r1 r2           -> FRSP (env r1) (env r2)
479    MFCR    reg             -> MFCR (env reg)
480    MFLR    reg             -> MFLR (env reg)
481    FETCHPC reg             -> FETCHPC (env reg)
482    _                       -> instr
483  where
484    fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
485    fixAddr (AddrRegImm r1 i)  = AddrRegImm (env r1) i
486
487    fixRI (RIReg r) = RIReg (env r)
488    fixRI other     = other
489
490
491--------------------------------------------------------------------------------
492-- | Checks whether this instruction is a jump/branch instruction.
493-- One that can change the flow of control in a way that the
494-- register allocator needs to worry about.
495ppc_isJumpishInstr :: Instr -> Bool
496ppc_isJumpishInstr instr
497 = case instr of
498    BCC{}       -> True
499    BCCFAR{}    -> True
500    BCTR{}      -> True
501    BCTRL{}     -> True
502    BL{}        -> True
503    JMP{}       -> True
504    _           -> False
505
506
507-- | Checks whether this instruction is a jump/branch instruction.
508-- One that can change the flow of control in a way that the
509-- register allocator needs to worry about.
510ppc_jumpDestsOfInstr :: Instr -> [BlockId]
511ppc_jumpDestsOfInstr insn
512  = case insn of
513        BCC _ id _       -> [id]
514        BCCFAR _ id _    -> [id]
515        BCTR targets _ _ -> [id | Just id <- targets]
516        _                -> []
517
518
519-- | Change the destination of this jump instruction.
520-- Used in the linear allocator when adding fixup blocks for join
521-- points.
522ppc_patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
523ppc_patchJumpInstr insn patchF
524  = case insn of
525        BCC cc id p     -> BCC cc (patchF id) p
526        BCCFAR cc id p  -> BCCFAR cc (patchF id) p
527        BCTR ids lbl rs -> BCTR (map (fmap patchF) ids) lbl rs
528        _               -> insn
529
530
531-- -----------------------------------------------------------------------------
532
533-- | An instruction to spill a register into a spill slot.
534ppc_mkSpillInstr
535   :: DynFlags
536   -> Reg       -- register to spill
537   -> Int       -- current stack delta
538   -> Int       -- spill slot to use
539   -> Instr
540
541ppc_mkSpillInstr dflags reg delta slot
542  = let platform = targetPlatform dflags
543        off      = spillSlotToOffset dflags slot
544        arch     = platformArch platform
545    in
546    let fmt = case targetClassOfReg platform reg of
547                RcInteger -> case arch of
548                                ArchPPC -> II32
549                                _       -> II64
550                RcDouble  -> FF64
551                _         -> panic "PPC.Instr.mkSpillInstr: no match"
552        instr = case makeImmediate W32 True (off-delta) of
553                Just _  -> ST
554                Nothing -> STFAR -- pseudo instruction: 32 bit offsets
555
556    in instr fmt reg (AddrRegImm sp (ImmInt (off-delta)))
557
558
559ppc_mkLoadInstr
560   :: DynFlags
561   -> Reg       -- register to load
562   -> Int       -- current stack delta
563   -> Int       -- spill slot to use
564   -> Instr
565
566ppc_mkLoadInstr dflags reg delta slot
567  = let platform = targetPlatform dflags
568        off      = spillSlotToOffset dflags slot
569        arch     = platformArch platform
570    in
571    let fmt = case targetClassOfReg platform reg of
572                RcInteger ->  case arch of
573                                 ArchPPC -> II32
574                                 _       -> II64
575                RcDouble  -> FF64
576                _         -> panic "PPC.Instr.mkLoadInstr: no match"
577        instr = case makeImmediate W32 True (off-delta) of
578                Just _  -> LD
579                Nothing -> LDFAR -- pseudo instruction: 32 bit offsets
580
581    in instr fmt reg (AddrRegImm sp (ImmInt (off-delta)))
582
583
584-- | The size of a minimal stackframe header including minimal
585-- parameter save area.
586stackFrameHeaderSize :: DynFlags -> Int
587stackFrameHeaderSize dflags
588  = case platformOS platform of
589      OSAIX    -> 24 + 8 * 4
590      _ -> case platformArch platform of
591                             -- header + parameter save area
592             ArchPPC           -> 64 -- TODO: check ABI spec
593             ArchPPC_64 ELF_V1 -> 48 + 8 * 8
594             ArchPPC_64 ELF_V2 -> 32 + 8 * 8
595             _ -> panic "PPC.stackFrameHeaderSize: not defined for this OS"
596     where platform = targetPlatform dflags
597
598-- | The maximum number of bytes required to spill a register. PPC32
599-- has 32-bit GPRs and 64-bit FPRs, while PPC64 has 64-bit GPRs and
600-- 64-bit FPRs. So the maximum is 8 regardless of platforms unlike
601-- x86. Note that AltiVec's vector registers are 128-bit wide so we
602-- must not use this to spill them.
603spillSlotSize :: Int
604spillSlotSize = 8
605
606-- | The number of spill slots available without allocating more.
607maxSpillSlots :: DynFlags -> Int
608maxSpillSlots dflags
609    = ((rESERVED_C_STACK_BYTES dflags - stackFrameHeaderSize dflags)
610       `div` spillSlotSize) - 1
611--     = 0 -- useful for testing allocMoreStack
612
613-- | The number of bytes that the stack pointer should be aligned
614-- to. This is 16 both on PPC32 and PPC64 ELF (see ELF processor
615-- specific supplements).
616stackAlign :: Int
617stackAlign = 16
618
619-- | Convert a spill slot number to a *byte* offset, with no sign.
620spillSlotToOffset :: DynFlags -> Int -> Int
621spillSlotToOffset dflags slot
622   = stackFrameHeaderSize dflags + spillSlotSize * slot
623
624
625--------------------------------------------------------------------------------
626-- | See if this instruction is telling us the current C stack delta
627ppc_takeDeltaInstr
628    :: Instr
629    -> Maybe Int
630
631ppc_takeDeltaInstr instr
632 = case instr of
633     DELTA i  -> Just i
634     _        -> Nothing
635
636
637ppc_isMetaInstr
638    :: Instr
639    -> Bool
640
641ppc_isMetaInstr instr
642 = case instr of
643    COMMENT{}   -> True
644    LDATA{}     -> True
645    NEWBLOCK{}  -> True
646    DELTA{}     -> True
647    _           -> False
648
649
650-- | Copy the value in a register to another one.
651-- Must work for all register classes.
652ppc_mkRegRegMoveInstr
653    :: Reg
654    -> Reg
655    -> Instr
656
657ppc_mkRegRegMoveInstr src dst
658    = MR dst src
659
660
661-- | Make an unconditional jump instruction.
662ppc_mkJumpInstr
663    :: BlockId
664    -> [Instr]
665
666ppc_mkJumpInstr id
667    = [BCC ALWAYS id Nothing]
668
669
670-- | Take the source and destination from this reg -> reg move instruction
671-- or Nothing if it's not one
672ppc_takeRegRegMoveInstr :: Instr -> Maybe (Reg,Reg)
673ppc_takeRegRegMoveInstr (MR dst src) = Just (src,dst)
674ppc_takeRegRegMoveInstr _  = Nothing
675
676-- -----------------------------------------------------------------------------
677-- Making far branches
678
679-- Conditional branches on PowerPC are limited to +-32KB; if our Procs get too
680-- big, we have to work around this limitation.
681
682makeFarBranches
683        :: LabelMap CmmStatics
684        -> [NatBasicBlock Instr]
685        -> [NatBasicBlock Instr]
686makeFarBranches info_env blocks
687    | last blockAddresses < nearLimit = blocks
688    | otherwise = zipWith handleBlock blockAddresses blocks
689    where
690        blockAddresses = scanl (+) 0 $ map blockLen blocks
691        blockLen (BasicBlock _ instrs) = length instrs
692
693        handleBlock addr (BasicBlock id instrs)
694                = BasicBlock id (zipWith makeFar [addr..] instrs)
695
696        makeFar _ (BCC ALWAYS tgt _) = BCC ALWAYS tgt Nothing
697        makeFar addr (BCC cond tgt p)
698            | abs (addr - targetAddr) >= nearLimit
699            = BCCFAR cond tgt p
700            | otherwise
701            = BCC cond tgt p
702            where Just targetAddr = lookupUFM blockAddressMap tgt
703        makeFar _ other            = other
704
705        -- 8192 instructions are allowed; let's keep some distance, as
706        -- we have a few pseudo-insns that are pretty-printed as
707        -- multiple instructions, and it's just not worth the effort
708        -- to calculate things exactly
709        nearLimit = 7000 - mapSize info_env * maxRetInfoTableSizeW
710
711        blockAddressMap = listToUFM $ zip (map blockId blocks) blockAddresses
712