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