Follow vreg/hreg patch in PPC NCG
[ghc.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 Cmm
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 [BlockId] -- with list of local destinations
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 -> BCTR targets
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 -> 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 _ -> error "Cannot patch BCTR"
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