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