58ddc21d40bae755687d47afab28f68ecf83bb8e
[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 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