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