merge GHC HEAD
[ghc-hetmet.git] / compiler / nativeGen / PPC / Instr.hs
1 -----------------------------------------------------------------------------
2 --
3 -- Machine-dependent assembly language
4 --
5 -- (c) The University of Glasgow 1993-2004
6 --
7 -----------------------------------------------------------------------------
8
9 #include "HsVersions.h"
10 #include "nativeGen/NCG.h"
11
12 module PPC.Instr (
13         archWordSize,
14         RI(..),
15         Instr(..),
16         maxSpillSlots
17 )
18
19 where
20
21 import PPC.Regs
22 import PPC.Cond
23 import Instruction
24 import Size
25 import TargetReg
26 import RegClass
27 import Reg
28
29 import Constants        (rESERVED_C_STACK_BYTES)
30 import BlockId
31 import OldCmm
32 import FastString
33 import CLabel
34 import Outputable
35 import FastBool
36
37 --------------------------------------------------------------------------------
38 -- Size of a PPC memory address, in bytes.
39 --
40 archWordSize    :: Size
41 archWordSize    = II32
42
43
44 -- | Instruction instance for powerpc
45 instance Instruction Instr where
46         regUsageOfInstr         = ppc_regUsageOfInstr
47         patchRegsOfInstr        = ppc_patchRegsOfInstr
48         isJumpishInstr          = ppc_isJumpishInstr
49         jumpDestsOfInstr        = ppc_jumpDestsOfInstr
50         patchJumpInstr          = ppc_patchJumpInstr
51         mkSpillInstr            = ppc_mkSpillInstr
52         mkLoadInstr             = ppc_mkLoadInstr
53         takeDeltaInstr          = ppc_takeDeltaInstr
54         isMetaInstr             = ppc_isMetaInstr
55         mkRegRegMoveInstr       = ppc_mkRegRegMoveInstr
56         takeRegRegMoveInstr     = ppc_takeRegRegMoveInstr
57         mkJumpInstr             = ppc_mkJumpInstr
58
59
60 -- -----------------------------------------------------------------------------
61 -- Machine's assembly language
62
63 -- We have a few common "instructions" (nearly all the pseudo-ops) but
64 -- mostly all of 'Instr' is machine-specific.
65
66 -- Register or immediate
67 data RI 
68         = RIReg Reg
69         | RIImm Imm
70
71 data Instr
72         -- comment pseudo-op
73         = COMMENT FastString            
74
75         -- some static data spat out during code
76         -- generation.  Will be extracted before
77         -- pretty-printing.
78         | LDATA   Section [CmmStatic]   
79
80         -- start a new basic block.  Useful during
81         -- codegen, removed later.  Preceding 
82         -- instruction should be a jump, as per the
83         -- invariants for a BasicBlock (see Cmm).
84         | NEWBLOCK BlockId              
85
86         -- specify current stack offset for
87         -- benefit of subsequent passes
88         | DELTA   Int
89
90         -- Loads and stores.
91         | LD    Size Reg AddrMode       -- Load size, dst, src
92         | LA      Size Reg AddrMode     -- Load arithmetic size, dst, src
93         | ST    Size Reg AddrMode       -- Store size, src, dst 
94         | STU   Size Reg AddrMode       -- Store with Update size, src, dst 
95         | LIS   Reg Imm                 -- Load Immediate Shifted dst, src
96         | LI    Reg Imm                 -- Load Immediate dst, src
97         | MR    Reg Reg                 -- Move Register dst, src -- also for fmr
98               
99         | CMP     Size Reg RI           --- size, src1, src2
100         | CMPL    Size Reg RI           --- size, src1, src2
101               
102         | BCC     Cond BlockId
103         | BCCFAR  Cond BlockId
104         | JMP     CLabel                -- same as branch,
105                                         -- but with CLabel instead of block ID
106         | MTCTR Reg
107         | BCTR [Maybe BlockId] (Maybe CLabel) -- with list of local destinations, and jump table location if necessary
108         | BL    CLabel [Reg]            -- with list of argument regs
109         | BCTRL [Reg]
110               
111         | ADD     Reg Reg RI            -- dst, src1, src2
112         | ADDC    Reg Reg Reg           -- (carrying) dst, src1, src2
113         | ADDE    Reg Reg Reg           -- (extend) dst, src1, src2
114         | ADDIS   Reg Reg Imm           -- Add Immediate Shifted dst, src1, src2
115         | SUBF    Reg Reg Reg           -- dst, src1, src2 ; dst = src2 - src1  
116         | MULLW Reg Reg RI
117         | DIVW  Reg Reg Reg
118         | DIVWU Reg Reg Reg
119
120         | MULLW_MayOflo Reg Reg Reg
121                                         -- dst = 1 if src1 * src2 overflows
122                                         -- pseudo-instruction; pretty-printed as:
123                                         -- mullwo. dst, src1, src2
124                                         -- mfxer dst
125                                         -- rlwinm dst, dst, 2, 31,31
126               
127         | AND   Reg Reg RI              -- dst, src1, src2
128         | OR    Reg Reg RI              -- dst, src1, src2
129         | XOR   Reg Reg RI              -- dst, src1, src2
130         | XORIS Reg Reg Imm             -- XOR Immediate Shifted dst, src1, src2
131               
132         | EXTS    Size Reg Reg
133                   
134         | NEG   Reg Reg
135         | NOT   Reg Reg
136               
137         | SLW   Reg Reg RI              -- shift left word
138         | SRW   Reg Reg RI              -- shift right word
139         | SRAW  Reg Reg RI              -- shift right arithmetic word
140               
141                                         -- Rotate Left Word Immediate then AND with Mask
142         | RLWINM  Reg Reg Int Int Int
143               
144         | FADD  Size Reg Reg Reg
145         | FSUB  Size Reg Reg Reg
146         | FMUL  Size Reg Reg Reg
147         | FDIV  Size Reg Reg Reg
148         | FNEG  Reg Reg                 -- negate is the same for single and double prec.
149               
150         | FCMP  Reg Reg
151               
152         | FCTIWZ        Reg Reg         -- convert to integer word
153         | FRSP          Reg Reg         -- reduce to single precision
154                                         -- (but destination is a FP register)
155               
156         | CRNOR   Int Int Int           -- condition register nor
157         | MFCR    Reg                   -- move from condition register
158               
159         | MFLR    Reg                   -- move from link register
160         | FETCHPC Reg                   -- pseudo-instruction:
161                                         -- bcl to next insn, mflr reg
162               
163         | LWSYNC -- memory barrier
164
165
166 -- | Get the registers that are being used by this instruction.
167 --      regUsage doesn't need to do any trickery for jumps and such.  
168 --      Just state precisely the regs read and written by that insn.  
169 --      The consequences of control flow transfers, as far as register
170 --      allocation goes, are taken care of by the register allocator.
171 --
172 ppc_regUsageOfInstr :: Instr -> RegUsage
173 ppc_regUsageOfInstr instr 
174  = case instr of
175     LD    _ reg addr    -> usage (regAddr addr, [reg])
176     LA    _ reg addr    -> usage (regAddr addr, [reg])
177     ST    _ reg addr    -> usage (reg : regAddr addr, [])
178     STU    _ reg addr   -> usage (reg : regAddr addr, [])
179     LIS   reg _         -> usage ([], [reg])
180     LI    reg _         -> usage ([], [reg])
181     MR    reg1 reg2     -> usage ([reg2], [reg1])
182     CMP   _ reg ri      -> usage (reg : regRI ri,[])
183     CMPL  _ reg ri      -> usage (reg : regRI ri,[])
184     BCC    _ _          -> noUsage
185     BCCFAR _ _          -> noUsage
186     MTCTR reg           -> usage ([reg],[])
187     BCTR  _ _           -> noUsage
188     BL    _ params      -> usage (params, callClobberedRegs)
189     BCTRL params        -> usage (params, callClobberedRegs)
190     ADD   reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
191     ADDC  reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
192     ADDE  reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
193     ADDIS reg1 reg2 _   -> usage ([reg2], [reg1])
194     SUBF  reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
195     MULLW reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
196     DIVW  reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
197     DIVWU reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
198     MULLW_MayOflo reg1 reg2 reg3        
199                         -> usage ([reg2,reg3], [reg1])
200     AND   reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
201     OR    reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
202     XOR   reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
203     XORIS reg1 reg2 _   -> usage ([reg2], [reg1])
204     EXTS  _  reg1 reg2 -> usage ([reg2], [reg1])
205     NEG   reg1 reg2     -> usage ([reg2], [reg1])
206     NOT   reg1 reg2     -> usage ([reg2], [reg1])
207     SLW   reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
208     SRW   reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
209     SRAW  reg1 reg2 ri  -> usage (reg2 : regRI ri, [reg1])
210     RLWINM reg1 reg2 _ _ _
211                         -> usage ([reg2], [reg1])
212     FADD  _ r1 r2 r3   -> usage ([r2,r3], [r1])
213     FSUB  _ r1 r2 r3   -> usage ([r2,r3], [r1])
214     FMUL  _ r1 r2 r3   -> usage ([r2,r3], [r1])
215     FDIV  _ r1 r2 r3   -> usage ([r2,r3], [r1])
216     FNEG  r1 r2         -> usage ([r2], [r1])
217     FCMP  r1 r2         -> usage ([r1,r2], [])
218     FCTIWZ r1 r2        -> usage ([r2], [r1])
219     FRSP r1 r2          -> usage ([r2], [r1])
220     MFCR reg            -> usage ([], [reg])
221     MFLR reg            -> usage ([], [reg])
222     FETCHPC reg         -> usage ([], [reg])
223     _                   -> noUsage
224   where
225     usage (src, dst) = RU (filter interesting src)
226                           (filter interesting dst)
227     regAddr (AddrRegReg r1 r2) = [r1, r2]
228     regAddr (AddrRegImm r1 _)  = [r1]
229
230     regRI (RIReg r) = [r]
231     regRI  _    = []
232
233 interesting :: Reg -> Bool
234 interesting (RegVirtual _)              = True
235 interesting (RegReal (RealRegSingle i)) 
236         = isFastTrue (freeReg i)
237
238 interesting (RegReal (RealRegPair{}))   
239         = panic "PPC.Instr.interesting: no reg pairs on this arch"
240
241
242
243 -- | Apply a given mapping to all the register references in this
244 --      instruction.
245 ppc_patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
246 ppc_patchRegsOfInstr instr env 
247  = case instr of
248     LD    sz reg addr   -> LD sz (env reg) (fixAddr addr)
249     LA    sz reg addr   -> LA sz (env reg) (fixAddr addr)
250     ST    sz reg addr   -> ST sz (env reg) (fixAddr addr)
251     STU    sz reg addr  -> STU sz (env reg) (fixAddr addr)
252     LIS   reg imm       -> LIS (env reg) imm
253     LI    reg imm       -> LI (env reg) imm
254     MR    reg1 reg2     -> MR (env reg1) (env reg2)
255     CMP   sz reg ri     -> CMP sz (env reg) (fixRI ri)
256     CMPL  sz reg ri     -> CMPL sz (env reg) (fixRI ri)
257     BCC   cond lbl      -> BCC cond lbl
258     BCCFAR cond lbl     -> BCCFAR cond lbl
259     MTCTR reg           -> MTCTR (env reg)
260     BCTR  targets lbl   -> BCTR targets lbl
261     BL    imm argRegs   -> BL imm argRegs       -- argument regs
262     BCTRL argRegs       -> BCTRL argRegs        -- cannot be remapped
263     ADD   reg1 reg2 ri  -> ADD (env reg1) (env reg2) (fixRI ri)
264     ADDC  reg1 reg2 reg3-> ADDC (env reg1) (env reg2) (env reg3)
265     ADDE  reg1 reg2 reg3-> ADDE (env reg1) (env reg2) (env reg3)
266     ADDIS reg1 reg2 imm -> ADDIS (env reg1) (env reg2) imm
267     SUBF  reg1 reg2 reg3-> SUBF (env reg1) (env reg2) (env reg3)
268     MULLW reg1 reg2 ri  -> MULLW (env reg1) (env reg2) (fixRI ri)
269     DIVW  reg1 reg2 reg3-> DIVW (env reg1) (env reg2) (env reg3)
270     DIVWU reg1 reg2 reg3-> DIVWU (env reg1) (env reg2) (env reg3)
271     MULLW_MayOflo reg1 reg2 reg3
272                         -> MULLW_MayOflo (env reg1) (env reg2) (env reg3)
273     AND   reg1 reg2 ri  -> AND (env reg1) (env reg2) (fixRI ri)
274     OR    reg1 reg2 ri  -> OR  (env reg1) (env reg2) (fixRI ri)
275     XOR   reg1 reg2 ri  -> XOR (env reg1) (env reg2) (fixRI ri)
276     XORIS reg1 reg2 imm -> XORIS (env reg1) (env reg2) imm
277     EXTS  sz reg1 reg2 -> EXTS sz (env reg1) (env reg2)
278     NEG   reg1 reg2     -> NEG (env reg1) (env reg2)
279     NOT   reg1 reg2     -> NOT (env reg1) (env reg2)
280     SLW   reg1 reg2 ri  -> SLW (env reg1) (env reg2) (fixRI ri)
281     SRW   reg1 reg2 ri  -> SRW (env reg1) (env reg2) (fixRI ri)
282     SRAW  reg1 reg2 ri  -> SRAW (env reg1) (env reg2) (fixRI ri)
283     RLWINM reg1 reg2 sh mb me
284                         -> RLWINM (env reg1) (env reg2) sh mb me
285     FADD  sz r1 r2 r3   -> FADD sz (env r1) (env r2) (env r3)
286     FSUB  sz r1 r2 r3   -> FSUB sz (env r1) (env r2) (env r3)
287     FMUL  sz r1 r2 r3   -> FMUL sz (env r1) (env r2) (env r3)
288     FDIV  sz r1 r2 r3   -> FDIV sz (env r1) (env r2) (env r3)
289     FNEG  r1 r2         -> FNEG (env r1) (env r2)
290     FCMP  r1 r2         -> FCMP (env r1) (env r2)
291     FCTIWZ r1 r2        -> FCTIWZ (env r1) (env r2)
292     FRSP r1 r2          -> FRSP (env r1) (env r2)
293     MFCR reg            -> MFCR (env reg)
294     MFLR reg            -> MFLR (env reg)
295     FETCHPC reg         -> FETCHPC (env reg)
296     _ -> instr
297   where
298     fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
299     fixAddr (AddrRegImm r1 i)  = AddrRegImm (env r1) i
300
301     fixRI (RIReg r) = RIReg (env r)
302     fixRI other = other
303
304
305 --------------------------------------------------------------------------------
306 -- | Checks whether this instruction is a jump/branch instruction. 
307 --      One that can change the flow of control in a way that the 
308 --      register allocator needs to worry about. 
309 ppc_isJumpishInstr :: Instr -> Bool
310 ppc_isJumpishInstr instr
311  = case instr of
312         BCC{}           -> True
313         BCCFAR{}        -> True
314         BCTR{}          -> True
315         BCTRL{}         -> True
316         BL{}            -> True
317         JMP{}           -> True
318         _               -> False
319
320
321 -- | Checks whether this instruction is a jump/branch instruction. 
322 --      One that can change the flow of control in a way that the 
323 --      register allocator needs to worry about. 
324 ppc_jumpDestsOfInstr :: Instr -> [BlockId] 
325 ppc_jumpDestsOfInstr insn 
326   = case insn of
327         BCC _ id        -> [id]
328         BCCFAR _ id     -> [id]
329         BCTR targets _  -> [id | Just id <- targets]
330         _               -> []
331         
332         
333 -- | Change the destination of this jump instruction.
334 --      Used in the linear allocator when adding fixup blocks for join
335 --      points.
336 ppc_patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
337 ppc_patchJumpInstr insn patchF
338   = case insn of
339         BCC cc id       -> BCC cc (patchF id)
340         BCCFAR cc id    -> BCCFAR cc (patchF id)
341         BCTR ids lbl    -> BCTR (map (fmap patchF) ids) lbl
342         _               -> insn
343
344
345 -- -----------------------------------------------------------------------------
346
347 -- | An instruction to spill a register into a spill slot.
348 ppc_mkSpillInstr
349    :: Reg               -- register to spill
350    -> Int               -- current stack delta
351    -> Int               -- spill slot to use
352    -> Instr
353
354 ppc_mkSpillInstr reg delta slot
355   = let off     = spillSlotToOffset slot
356     in
357     let sz = case targetClassOfReg reg of
358                 RcInteger -> II32
359                 RcDouble  -> FF64
360                 _         -> panic "PPC.Instr.mkSpillInstr: no match"
361     in ST sz reg (AddrRegImm sp (ImmInt (off-delta)))
362
363
364 ppc_mkLoadInstr
365    :: Reg               -- register to load
366    -> Int               -- current stack delta
367    -> Int               -- spill slot to use
368    -> Instr
369
370 ppc_mkLoadInstr reg delta slot
371   = let off     = spillSlotToOffset slot
372     in
373     let sz = case targetClassOfReg reg of
374                 RcInteger -> II32
375                 RcDouble  -> FF64
376                 _         -> panic "PPC.Instr.mkLoadInstr: no match"
377     in LD sz reg (AddrRegImm sp (ImmInt (off-delta)))
378
379
380 spillSlotSize :: Int
381 spillSlotSize = 8
382
383 maxSpillSlots :: Int
384 maxSpillSlots = ((rESERVED_C_STACK_BYTES - 64) `div` spillSlotSize) - 1
385
386 -- convert a spill slot number to a *byte* offset, with no sign:
387 -- decide on a per arch basis whether you are spilling above or below
388 -- the C stack pointer.
389 spillSlotToOffset :: Int -> Int
390 spillSlotToOffset slot
391    | slot >= 0 && slot < maxSpillSlots
392    = 64 + spillSlotSize * slot
393    | otherwise
394    = pprPanic "spillSlotToOffset:" 
395               (   text "invalid spill location: " <> int slot
396               $$  text "maxSpillSlots:          " <> int maxSpillSlots)
397
398
399 --------------------------------------------------------------------------------
400 -- | See if this instruction is telling us the current C stack delta
401 ppc_takeDeltaInstr
402         :: Instr
403         -> Maybe Int
404         
405 ppc_takeDeltaInstr instr
406  = case instr of
407         DELTA i         -> Just i
408         _               -> Nothing
409
410
411 ppc_isMetaInstr
412         :: Instr
413         -> Bool
414         
415 ppc_isMetaInstr instr
416  = case instr of
417         COMMENT{}       -> True
418         LDATA{}         -> True
419         NEWBLOCK{}      -> True
420         DELTA{}         -> True
421         _               -> False
422
423
424 -- | Copy the value in a register to another one.
425 --      Must work for all register classes.
426 ppc_mkRegRegMoveInstr
427         :: Reg
428         -> Reg
429         -> Instr
430
431 ppc_mkRegRegMoveInstr src dst
432         = MR dst src
433
434
435 -- | Make an unconditional jump instruction.
436 --      For architectures with branch delay slots, its ok to put
437 --      a NOP after the jump. Don't fill the delay slot with an
438 --      instruction that references regs or you'll confuse the 
439 --      linear allocator.
440 ppc_mkJumpInstr
441         :: BlockId
442         -> [Instr]
443
444 ppc_mkJumpInstr id 
445         = [BCC ALWAYS id]
446
447
448 -- | Take the source and destination from this reg -> reg move instruction
449 --      or Nothing if it's not one
450 ppc_takeRegRegMoveInstr :: Instr -> Maybe (Reg,Reg)
451 ppc_takeRegRegMoveInstr (MR dst src) = Just (src,dst)
452 ppc_takeRegRegMoveInstr _  = Nothing
453