{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module GHC.CmmToAsm.PPC.Instr
( Instr(..)
, RI(..)
, archWordFormat
, stackFrameHeaderSize
, maxSpillSlots
, allocMoreStack
, makeFarBranches
, mkJumpInstr
, mkLoadInstr
, mkSpillInstr
, patchJumpInstr
, patchRegsOfInstr
, jumpDestsOfInstr
, canFallthroughTo
, takeRegRegMoveInstr
, takeDeltaInstr
, mkRegRegMoveInstr
, mkStackAllocInstr
, mkStackDeallocInstr
, regUsageOfInstr
, isJumpishInstr
, isMetaInstr
)
where
import GHC.Prelude hiding (head, init, last, tail)
import GHC.CmmToAsm.PPC.Regs
import GHC.CmmToAsm.PPC.Cond
import GHC.CmmToAsm.Types
import GHC.CmmToAsm.Instr (RegUsage(..), noUsage)
import GHC.CmmToAsm.Format
import GHC.CmmToAsm.Reg.Target
import GHC.CmmToAsm.Config
import GHC.Platform.Reg.Class
import GHC.Platform.Reg
import GHC.Platform.Regs
import GHC.Cmm.BlockId
import GHC.Cmm.Dataflow.Collections
import GHC.Cmm.Dataflow.Label
import GHC.Cmm
import GHC.Cmm.Info
import GHC.Cmm.CLabel
import GHC.Utils.Panic
import GHC.Platform
import GHC.Types.Unique.FM (listToUFM, lookupUFM)
import GHC.Types.Unique.Supply
import Data.Foldable (toList)
import qualified Data.List.NonEmpty as NE
import GHC.Data.FastString (FastString)
import Data.Maybe (fromMaybe)
archWordFormat :: Bool -> Format
archWordFormat :: Bool -> Format
archWordFormat Bool
is32Bit
| Bool
is32Bit = Format
II32
| Bool
otherwise = Format
II64
mkStackAllocInstr :: Platform -> Int -> [Instr]
mkStackAllocInstr :: Platform -> Int -> [Instr]
mkStackAllocInstr Platform
platform Int
amount
= Platform -> Int -> [Instr]
mkStackAllocInstr' Platform
platform (-Int
amount)
mkStackDeallocInstr :: Platform -> Int -> [Instr]
mkStackDeallocInstr :: Platform -> Int -> [Instr]
mkStackDeallocInstr Platform
platform Int
amount
= Platform -> Int -> [Instr]
mkStackAllocInstr' Platform
platform Int
amount
mkStackAllocInstr' :: Platform -> Int -> [Instr]
mkStackAllocInstr' :: Platform -> Int -> [Instr]
mkStackAllocInstr' Platform
platform Int
amount
| Int -> Bool
forall a. Integral a => a -> Bool
fits16Bits Int
amount
= [ Format -> Reg -> AddrMode -> Instr
LD Format
fmt Reg
r0 (Reg -> Imm -> AddrMode
AddrRegImm Reg
sp Imm
zero)
, Format -> Reg -> AddrMode -> Instr
STU Format
fmt Reg
r0 (Reg -> Imm -> AddrMode
AddrRegImm Reg
sp Imm
immAmount)
]
| Bool
otherwise
= [ Format -> Reg -> AddrMode -> Instr
LD Format
fmt Reg
r0 (Reg -> Imm -> AddrMode
AddrRegImm Reg
sp Imm
zero)
, Reg -> Reg -> Imm -> Instr
ADDIS Reg
tmp Reg
sp (Imm -> Imm
HA Imm
immAmount)
, Reg -> Reg -> RI -> Instr
ADD Reg
tmp Reg
tmp (Imm -> RI
RIImm (Imm -> Imm
LO Imm
immAmount))
, Format -> Reg -> AddrMode -> Instr
STU Format
fmt Reg
r0 (Reg -> Reg -> AddrMode
AddrRegReg Reg
sp Reg
tmp)
]
where
fmt :: Format
fmt = Width -> Format
intFormat (Width -> Format) -> Width -> Format
forall a b. (a -> b) -> a -> b
$ Int -> Width
widthFromBytes (Platform -> Int
platformWordSizeInBytes Platform
platform)
zero :: Imm
zero = Int -> Imm
ImmInt Int
0
tmp :: Reg
tmp = Platform -> Reg
tmpReg Platform
platform
immAmount :: Imm
immAmount = Int -> Imm
ImmInt Int
amount
allocMoreStack
:: Platform
-> Int
-> NatCmmDecl statics GHC.CmmToAsm.PPC.Instr.Instr
-> UniqSM (NatCmmDecl statics GHC.CmmToAsm.PPC.Instr.Instr, [(BlockId,BlockId)])
allocMoreStack :: forall statics.
Platform
-> Int
-> NatCmmDecl statics Instr
-> UniqSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
allocMoreStack Platform
_ Int
_ top :: NatCmmDecl statics Instr
top@(CmmData Section
_ statics
_) = (NatCmmDecl statics Instr, [(BlockId, BlockId)])
-> UniqSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (NatCmmDecl statics Instr
top,[])
allocMoreStack Platform
platform Int
slots (CmmProc LabelMap RawCmmStatics
info CLabel
lbl [GlobalReg]
live (ListGraph [GenBasicBlock Instr]
code)) = do
let
infos :: [KeyOf LabelMap]
infos = LabelMap RawCmmStatics -> [KeyOf LabelMap]
forall a. LabelMap a -> [KeyOf LabelMap]
forall (map :: * -> *) a. IsMap map => map a -> [KeyOf map]
mapKeys LabelMap RawCmmStatics
info
entries :: [KeyOf LabelMap]
entries = case [GenBasicBlock Instr]
code of
[] -> [KeyOf LabelMap]
infos
BasicBlock BlockId
entry [Instr]
_ : [GenBasicBlock Instr]
_
| BlockId
entry BlockId -> [BlockId] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [KeyOf LabelMap]
[BlockId]
infos -> [KeyOf LabelMap]
infos
| Bool
otherwise -> BlockId
entry BlockId -> [BlockId] -> [BlockId]
forall a. a -> [a] -> [a]
: [KeyOf LabelMap]
[BlockId]
infos
[Unique]
uniqs <- UniqSM [Unique]
forall (m :: * -> *). MonadUnique m => m [Unique]
getUniquesM
let
delta :: Int
delta = ((Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
stackAlign Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
stackAlign) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
stackAlign
where x :: Int
x = Int
slots Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
spillSlotSize
alloc :: [Instr]
alloc = Platform -> Int -> [Instr]
mkStackAllocInstr Platform
platform Int
delta
dealloc :: [Instr]
dealloc = Platform -> Int -> [Instr]
mkStackDeallocInstr Platform
platform Int
delta
retargetList :: [(BlockId, BlockId)]
retargetList = ([BlockId] -> [BlockId] -> [(BlockId, BlockId)]
forall a b. [a] -> [b] -> [(a, b)]
zip [KeyOf LabelMap]
[BlockId]
entries ((Unique -> BlockId) -> [Unique] -> [BlockId]
forall a b. (a -> b) -> [a] -> [b]
map Unique -> BlockId
mkBlockId [Unique]
uniqs))
new_blockmap :: LabelMap BlockId
new_blockmap :: LabelMap BlockId
new_blockmap = [(KeyOf LabelMap, BlockId)] -> LabelMap BlockId
forall a. [(KeyOf LabelMap, a)] -> LabelMap a
forall (map :: * -> *) a. IsMap map => [(KeyOf map, a)] -> map a
mapFromList [(KeyOf LabelMap, BlockId)]
[(BlockId, BlockId)]
retargetList
insert_stack_insns :: GenBasicBlock Instr -> [GenBasicBlock Instr]
insert_stack_insns (BasicBlock BlockId
id [Instr]
insns)
| Just BlockId
new_blockid <- KeyOf LabelMap -> LabelMap BlockId -> Maybe BlockId
forall a. KeyOf LabelMap -> LabelMap a -> Maybe a
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
id LabelMap BlockId
new_blockmap
= [ BlockId -> [Instr] -> GenBasicBlock Instr
forall i. BlockId -> [i] -> GenBasicBlock i
BasicBlock BlockId
id ([Instr] -> GenBasicBlock Instr) -> [Instr] -> GenBasicBlock Instr
forall a b. (a -> b) -> a -> b
$ [Instr]
alloc [Instr] -> [Instr] -> [Instr]
forall a. [a] -> [a] -> [a]
++ [Cond -> BlockId -> Maybe Bool -> Instr
BCC Cond
ALWAYS BlockId
new_blockid Maybe Bool
forall a. Maybe a
Nothing]
, BlockId -> [Instr] -> GenBasicBlock Instr
forall i. BlockId -> [i] -> GenBasicBlock i
BasicBlock BlockId
new_blockid [Instr]
block'
]
| Bool
otherwise
= [ BlockId -> [Instr] -> GenBasicBlock Instr
forall i. BlockId -> [i] -> GenBasicBlock i
BasicBlock BlockId
id [Instr]
block' ]
where
block' :: [Instr]
block' = (Instr -> [Instr] -> [Instr]) -> [Instr] -> [Instr] -> [Instr]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Instr -> [Instr] -> [Instr]
insert_dealloc [] [Instr]
insns
insert_dealloc :: Instr -> [Instr] -> [Instr]
insert_dealloc Instr
insn [Instr]
r
= case Instr
insn of
JMP CLabel
_ [Reg]
_ -> [Instr]
dealloc [Instr] -> [Instr] -> [Instr]
forall a. [a] -> [a] -> [a]
++ (Instr
insn Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r)
BCTR [] Maybe CLabel
Nothing [Reg]
_ -> [Instr]
dealloc [Instr] -> [Instr] -> [Instr]
forall a. [a] -> [a] -> [a]
++ (Instr
insn Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r)
BCTR [Maybe BlockId]
ids Maybe CLabel
label [Reg]
rs -> [Maybe BlockId] -> Maybe CLabel -> [Reg] -> Instr
BCTR ((Maybe BlockId -> Maybe BlockId)
-> [Maybe BlockId] -> [Maybe BlockId]
forall a b. (a -> b) -> [a] -> [b]
map ((BlockId -> BlockId) -> Maybe BlockId -> Maybe BlockId
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap BlockId -> BlockId
retarget) [Maybe BlockId]
ids) Maybe CLabel
label [Reg]
rs Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r
BCCFAR Cond
cond BlockId
b Maybe Bool
p -> Cond -> BlockId -> Maybe Bool -> Instr
BCCFAR Cond
cond (BlockId -> BlockId
retarget BlockId
b) Maybe Bool
p Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r
BCC Cond
cond BlockId
b Maybe Bool
p -> Cond -> BlockId -> Maybe Bool -> Instr
BCC Cond
cond (BlockId -> BlockId
retarget BlockId
b) Maybe Bool
p Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r
Instr
_ -> Instr
insn Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r
retarget :: BlockId -> BlockId
retarget :: BlockId -> BlockId
retarget BlockId
b
= BlockId -> Maybe BlockId -> BlockId
forall a. a -> Maybe a -> a
fromMaybe BlockId
b (KeyOf LabelMap -> LabelMap BlockId -> Maybe BlockId
forall a. KeyOf LabelMap -> LabelMap a -> Maybe a
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
b LabelMap BlockId
new_blockmap)
new_code :: [GenBasicBlock Instr]
new_code
= (GenBasicBlock Instr -> [GenBasicBlock Instr])
-> [GenBasicBlock Instr] -> [GenBasicBlock Instr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap GenBasicBlock Instr -> [GenBasicBlock Instr]
insert_stack_insns [GenBasicBlock Instr]
code
(NatCmmDecl statics Instr, [(BlockId, BlockId)])
-> UniqSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (LabelMap RawCmmStatics
-> CLabel
-> [GlobalReg]
-> ListGraph Instr
-> NatCmmDecl statics Instr
forall d h g. h -> CLabel -> [GlobalReg] -> g -> GenCmmDecl d h g
CmmProc LabelMap RawCmmStatics
info CLabel
lbl [GlobalReg]
live ([GenBasicBlock Instr] -> ListGraph Instr
forall i. [GenBasicBlock i] -> ListGraph i
ListGraph [GenBasicBlock Instr]
new_code),[(BlockId, BlockId)]
retargetList)
data RI
= RIReg Reg
| RIImm Imm
data Instr
= FastString
| LOCATION Int Int Int String
| LDATA Section RawCmmStatics
| NEWBLOCK BlockId
| DELTA Int
| LD Format Reg AddrMode
| LDFAR Format Reg AddrMode
| LDR Format Reg AddrMode
| LA Format Reg AddrMode
| ST Format Reg AddrMode
| STFAR Format Reg AddrMode
| STU Format Reg AddrMode
| STC Format Reg AddrMode
| LIS Reg Imm
| LI Reg Imm
| MR Reg Reg
| CMP Format Reg RI
| CMPL Format Reg RI
| BCC Cond BlockId (Maybe Bool)
| BCCFAR Cond BlockId (Maybe Bool)
| JMP CLabel [Reg]
| MTCTR Reg
| BCTR [Maybe BlockId] (Maybe CLabel) [Reg]
| BL CLabel [Reg]
| BCTRL [Reg]
| ADD Reg Reg RI
| ADDO Reg Reg Reg
| ADDC Reg Reg Reg
| ADDE Reg Reg Reg
| ADDZE Reg Reg
| ADDIS Reg Reg Imm
| SUBF Reg Reg Reg
| SUBFO Reg Reg Reg
| SUBFC Reg Reg RI
| SUBFE Reg Reg Reg
| MULL Format Reg Reg RI
| MULLO Format Reg Reg Reg
| MFOV Format Reg
| MULHU Format Reg Reg Reg
| DIV Format Bool Reg Reg Reg
| AND Reg Reg RI
| ANDC Reg Reg Reg
| NAND Reg Reg Reg
| OR Reg Reg RI
| ORIS Reg Reg Imm
| XOR Reg Reg RI
| XORIS Reg Reg Imm
| EXTS Format Reg Reg
| CNTLZ Format Reg Reg
| NEG Reg Reg
| NOT Reg Reg
| SL Format Reg Reg RI
| SR Format Reg Reg RI
| SRA Format Reg Reg RI
| RLWINM Reg Reg Int Int Int
| CLRLI Format Reg Reg Int
| CLRRI Format Reg Reg Int
| FADD Format Reg Reg Reg
| FSUB Format Reg Reg Reg
| FMUL Format Reg Reg Reg
| FDIV Format Reg Reg Reg
| FABS Reg Reg
| FNEG Reg Reg
| FCMP Reg Reg
| FCTIWZ Reg Reg
| FCTIDZ Reg Reg
| FCFID Reg Reg
| FRSP Reg Reg
| CRNOR Int Int Int
| MFCR Reg
| MFLR Reg
| FETCHPC Reg
| HWSYNC
| ISYNC
| LWSYNC
| NOP
regUsageOfInstr :: Platform -> Instr -> RegUsage
regUsageOfInstr :: Platform -> Instr -> RegUsage
regUsageOfInstr Platform
platform Instr
instr
= case Instr
instr of
LD Format
_ Reg
reg AddrMode
addr -> ([Reg], [Reg]) -> RegUsage
usage (AddrMode -> [Reg]
regAddr AddrMode
addr, [Reg
reg])
LDFAR Format
_ Reg
reg AddrMode
addr -> ([Reg], [Reg]) -> RegUsage
usage (AddrMode -> [Reg]
regAddr AddrMode
addr, [Reg
reg])
LDR Format
_ Reg
reg AddrMode
addr -> ([Reg], [Reg]) -> RegUsage
usage (AddrMode -> [Reg]
regAddr AddrMode
addr, [Reg
reg])
LA Format
_ Reg
reg AddrMode
addr -> ([Reg], [Reg]) -> RegUsage
usage (AddrMode -> [Reg]
regAddr AddrMode
addr, [Reg
reg])
ST Format
_ Reg
reg AddrMode
addr -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: AddrMode -> [Reg]
regAddr AddrMode
addr, [])
STFAR Format
_ Reg
reg AddrMode
addr -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: AddrMode -> [Reg]
regAddr AddrMode
addr, [])
STU Format
_ Reg
reg AddrMode
addr -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: AddrMode -> [Reg]
regAddr AddrMode
addr, [])
STC Format
_ Reg
reg AddrMode
addr -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: AddrMode -> [Reg]
regAddr AddrMode
addr, [])
LIS Reg
reg Imm
_ -> ([Reg], [Reg]) -> RegUsage
usage ([], [Reg
reg])
LI Reg
reg Imm
_ -> ([Reg], [Reg]) -> RegUsage
usage ([], [Reg
reg])
MR Reg
reg1 Reg
reg2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
CMP Format
_ Reg
reg RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri,[])
CMPL Format
_ Reg
reg RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri,[])
BCC Cond
_ BlockId
_ Maybe Bool
_ -> RegUsage
noUsage
BCCFAR Cond
_ BlockId
_ Maybe Bool
_ -> RegUsage
noUsage
JMP CLabel
_ [Reg]
regs -> ([Reg], [Reg]) -> RegUsage
usage ([Reg]
regs, [])
MTCTR Reg
reg -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg],[])
BCTR [Maybe BlockId]
_ Maybe CLabel
_ [Reg]
regs -> ([Reg], [Reg]) -> RegUsage
usage ([Reg]
regs, [])
BL CLabel
_ [Reg]
params -> ([Reg], [Reg]) -> RegUsage
usage ([Reg]
params, Platform -> [Reg]
callClobberedRegs Platform
platform)
BCTRL [Reg]
params -> ([Reg], [Reg]) -> RegUsage
usage ([Reg]
params, Platform -> [Reg]
callClobberedRegs Platform
platform)
ADD Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
ADDO Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
ADDC Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
ADDE Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
ADDZE Reg
reg1 Reg
reg2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
ADDIS Reg
reg1 Reg
reg2 Imm
_ -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
SUBF Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
SUBFO Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
SUBFC Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
SUBFE Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
MULL Format
_ Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
MULLO Format
_ Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
MFOV Format
_ Reg
reg -> ([Reg], [Reg]) -> RegUsage
usage ([], [Reg
reg])
MULHU Format
_ Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
DIV Format
_ Bool
_ Reg
reg1 Reg
reg2 Reg
reg3
-> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
AND Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
ANDC Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
NAND Reg
reg1 Reg
reg2 Reg
reg3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2,Reg
reg3], [Reg
reg1])
OR Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
ORIS Reg
reg1 Reg
reg2 Imm
_ -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
XOR Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
XORIS Reg
reg1 Reg
reg2 Imm
_ -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
EXTS Format
_ Reg
reg1 Reg
reg2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
CNTLZ Format
_ Reg
reg1 Reg
reg2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
NEG Reg
reg1 Reg
reg2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
NOT Reg
reg1 Reg
reg2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
SL Format
_ Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
SR Format
_ Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
SRA Format
_ Reg
reg1 Reg
reg2 RI
ri -> ([Reg], [Reg]) -> RegUsage
usage (Reg
reg2 Reg -> [Reg] -> [Reg]
forall a. a -> [a] -> [a]
: RI -> [Reg]
regRI RI
ri, [Reg
reg1])
RLWINM Reg
reg1 Reg
reg2 Int
_ Int
_ Int
_ -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
CLRLI Format
_ Reg
reg1 Reg
reg2 Int
_ -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
CLRRI Format
_ Reg
reg1 Reg
reg2 Int
_ -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
reg2], [Reg
reg1])
FADD Format
_ Reg
r1 Reg
r2 Reg
r3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2,Reg
r3], [Reg
r1])
FSUB Format
_ Reg
r1 Reg
r2 Reg
r3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2,Reg
r3], [Reg
r1])
FMUL Format
_ Reg
r1 Reg
r2 Reg
r3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2,Reg
r3], [Reg
r1])
FDIV Format
_ Reg
r1 Reg
r2 Reg
r3 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2,Reg
r3], [Reg
r1])
FABS Reg
r1 Reg
r2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2], [Reg
r1])
FNEG Reg
r1 Reg
r2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2], [Reg
r1])
FCMP Reg
r1 Reg
r2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r1,Reg
r2], [])
FCTIWZ Reg
r1 Reg
r2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2], [Reg
r1])
FCTIDZ Reg
r1 Reg
r2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2], [Reg
r1])
FCFID Reg
r1 Reg
r2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2], [Reg
r1])
FRSP Reg
r1 Reg
r2 -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
r2], [Reg
r1])
MFCR Reg
reg -> ([Reg], [Reg]) -> RegUsage
usage ([], [Reg
reg])
MFLR Reg
reg -> ([Reg], [Reg]) -> RegUsage
usage ([], [Reg
reg])
FETCHPC Reg
reg -> ([Reg], [Reg]) -> RegUsage
usage ([], [Reg
reg])
Instr
_ -> RegUsage
noUsage
where
usage :: ([Reg], [Reg]) -> RegUsage
usage ([Reg]
src, [Reg]
dst) = [Reg] -> [Reg] -> RegUsage
RU ((Reg -> Bool) -> [Reg] -> [Reg]
forall a. (a -> Bool) -> [a] -> [a]
filter (Platform -> Reg -> Bool
interesting Platform
platform) [Reg]
src)
((Reg -> Bool) -> [Reg] -> [Reg]
forall a. (a -> Bool) -> [a] -> [a]
filter (Platform -> Reg -> Bool
interesting Platform
platform) [Reg]
dst)
regAddr :: AddrMode -> [Reg]
regAddr (AddrRegReg Reg
r1 Reg
r2) = [Reg
r1, Reg
r2]
regAddr (AddrRegImm Reg
r1 Imm
_) = [Reg
r1]
regRI :: RI -> [Reg]
regRI (RIReg Reg
r) = [Reg
r]
regRI RI
_ = []
interesting :: Platform -> Reg -> Bool
interesting :: Platform -> Reg -> Bool
interesting Platform
_ (RegVirtual VirtualReg
_) = Bool
True
interesting Platform
platform (RegReal (RealRegSingle Int
i)) = Platform -> Int -> Bool
freeReg Platform
platform Int
i
patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
patchRegsOfInstr Instr
instr Reg -> Reg
env
= case Instr
instr of
LD Format
fmt Reg
reg AddrMode
addr -> Format -> Reg -> AddrMode -> Instr
LD Format
fmt (Reg -> Reg
env Reg
reg) (AddrMode -> AddrMode
fixAddr AddrMode
addr)
LDFAR Format
fmt Reg
reg AddrMode
addr -> Format -> Reg -> AddrMode -> Instr
LDFAR Format
fmt (Reg -> Reg
env Reg
reg) (AddrMode -> AddrMode
fixAddr AddrMode
addr)
LDR Format
fmt Reg
reg AddrMode
addr -> Format -> Reg -> AddrMode -> Instr
LDR Format
fmt (Reg -> Reg
env Reg
reg) (AddrMode -> AddrMode
fixAddr AddrMode
addr)
LA Format
fmt Reg
reg AddrMode
addr -> Format -> Reg -> AddrMode -> Instr
LA Format
fmt (Reg -> Reg
env Reg
reg) (AddrMode -> AddrMode
fixAddr AddrMode
addr)
ST Format
fmt Reg
reg AddrMode
addr -> Format -> Reg -> AddrMode -> Instr
ST Format
fmt (Reg -> Reg
env Reg
reg) (AddrMode -> AddrMode
fixAddr AddrMode
addr)
STFAR Format
fmt Reg
reg AddrMode
addr -> Format -> Reg -> AddrMode -> Instr
STFAR Format
fmt (Reg -> Reg
env Reg
reg) (AddrMode -> AddrMode
fixAddr AddrMode
addr)
STU Format
fmt Reg
reg AddrMode
addr -> Format -> Reg -> AddrMode -> Instr
STU Format
fmt (Reg -> Reg
env Reg
reg) (AddrMode -> AddrMode
fixAddr AddrMode
addr)
STC Format
fmt Reg
reg AddrMode
addr -> Format -> Reg -> AddrMode -> Instr
STC Format
fmt (Reg -> Reg
env Reg
reg) (AddrMode -> AddrMode
fixAddr AddrMode
addr)
LIS Reg
reg Imm
imm -> Reg -> Imm -> Instr
LIS (Reg -> Reg
env Reg
reg) Imm
imm
LI Reg
reg Imm
imm -> Reg -> Imm -> Instr
LI (Reg -> Reg
env Reg
reg) Imm
imm
MR Reg
reg1 Reg
reg2 -> Reg -> Reg -> Instr
MR (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2)
CMP Format
fmt Reg
reg RI
ri -> Format -> Reg -> RI -> Instr
CMP Format
fmt (Reg -> Reg
env Reg
reg) (RI -> RI
fixRI RI
ri)
CMPL Format
fmt Reg
reg RI
ri -> Format -> Reg -> RI -> Instr
CMPL Format
fmt (Reg -> Reg
env Reg
reg) (RI -> RI
fixRI RI
ri)
BCC Cond
cond BlockId
lbl Maybe Bool
p -> Cond -> BlockId -> Maybe Bool -> Instr
BCC Cond
cond BlockId
lbl Maybe Bool
p
BCCFAR Cond
cond BlockId
lbl Maybe Bool
p -> Cond -> BlockId -> Maybe Bool -> Instr
BCCFAR Cond
cond BlockId
lbl Maybe Bool
p
JMP CLabel
l [Reg]
regs -> CLabel -> [Reg] -> Instr
JMP CLabel
l [Reg]
regs
MTCTR Reg
reg -> Reg -> Instr
MTCTR (Reg -> Reg
env Reg
reg)
BCTR [Maybe BlockId]
targets Maybe CLabel
lbl [Reg]
rs -> [Maybe BlockId] -> Maybe CLabel -> [Reg] -> Instr
BCTR [Maybe BlockId]
targets Maybe CLabel
lbl [Reg]
rs
BL CLabel
imm [Reg]
argRegs -> CLabel -> [Reg] -> Instr
BL CLabel
imm [Reg]
argRegs
BCTRL [Reg]
argRegs -> [Reg] -> Instr
BCTRL [Reg]
argRegs
ADD Reg
reg1 Reg
reg2 RI
ri -> Reg -> Reg -> RI -> Instr
ADD (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
ADDO Reg
reg1 Reg
reg2 Reg
reg3 -> Reg -> Reg -> Reg -> Instr
ADDO (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
ADDC Reg
reg1 Reg
reg2 Reg
reg3 -> Reg -> Reg -> Reg -> Instr
ADDC (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
ADDE Reg
reg1 Reg
reg2 Reg
reg3 -> Reg -> Reg -> Reg -> Instr
ADDE (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
ADDZE Reg
reg1 Reg
reg2 -> Reg -> Reg -> Instr
ADDZE (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2)
ADDIS Reg
reg1 Reg
reg2 Imm
imm -> Reg -> Reg -> Imm -> Instr
ADDIS (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) Imm
imm
SUBF Reg
reg1 Reg
reg2 Reg
reg3 -> Reg -> Reg -> Reg -> Instr
SUBF (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
SUBFO Reg
reg1 Reg
reg2 Reg
reg3 -> Reg -> Reg -> Reg -> Instr
SUBFO (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
SUBFC Reg
reg1 Reg
reg2 RI
ri -> Reg -> Reg -> RI -> Instr
SUBFC (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
SUBFE Reg
reg1 Reg
reg2 Reg
reg3 -> Reg -> Reg -> Reg -> Instr
SUBFE (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
MULL Format
fmt Reg
reg1 Reg
reg2 RI
ri
-> Format -> Reg -> Reg -> RI -> Instr
MULL Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
MULLO Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
-> Format -> Reg -> Reg -> Reg -> Instr
MULLO Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
MFOV Format
fmt Reg
reg -> Format -> Reg -> Instr
MFOV Format
fmt (Reg -> Reg
env Reg
reg)
MULHU Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
-> Format -> Reg -> Reg -> Reg -> Instr
MULHU Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
DIV Format
fmt Bool
sgn Reg
reg1 Reg
reg2 Reg
reg3
-> Format -> Bool -> Reg -> Reg -> Reg -> Instr
DIV Format
fmt Bool
sgn (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
AND Reg
reg1 Reg
reg2 RI
ri -> Reg -> Reg -> RI -> Instr
AND (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
ANDC Reg
reg1 Reg
reg2 Reg
reg3 -> Reg -> Reg -> Reg -> Instr
ANDC (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
NAND Reg
reg1 Reg
reg2 Reg
reg3 -> Reg -> Reg -> Reg -> Instr
NAND (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (Reg -> Reg
env Reg
reg3)
OR Reg
reg1 Reg
reg2 RI
ri -> Reg -> Reg -> RI -> Instr
OR (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
ORIS Reg
reg1 Reg
reg2 Imm
imm -> Reg -> Reg -> Imm -> Instr
ORIS (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) Imm
imm
XOR Reg
reg1 Reg
reg2 RI
ri -> Reg -> Reg -> RI -> Instr
XOR (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
XORIS Reg
reg1 Reg
reg2 Imm
imm -> Reg -> Reg -> Imm -> Instr
XORIS (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) Imm
imm
EXTS Format
fmt Reg
reg1 Reg
reg2 -> Format -> Reg -> Reg -> Instr
EXTS Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2)
CNTLZ Format
fmt Reg
reg1 Reg
reg2 -> Format -> Reg -> Reg -> Instr
CNTLZ Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2)
NEG Reg
reg1 Reg
reg2 -> Reg -> Reg -> Instr
NEG (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2)
NOT Reg
reg1 Reg
reg2 -> Reg -> Reg -> Instr
NOT (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2)
SL Format
fmt Reg
reg1 Reg
reg2 RI
ri
-> Format -> Reg -> Reg -> RI -> Instr
SL Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
SR Format
fmt Reg
reg1 Reg
reg2 RI
ri
-> Format -> Reg -> Reg -> RI -> Instr
SR Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
SRA Format
fmt Reg
reg1 Reg
reg2 RI
ri
-> Format -> Reg -> Reg -> RI -> Instr
SRA Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) (RI -> RI
fixRI RI
ri)
RLWINM Reg
reg1 Reg
reg2 Int
sh Int
mb Int
me
-> Reg -> Reg -> Int -> Int -> Int -> Instr
RLWINM (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) Int
sh Int
mb Int
me
CLRLI Format
fmt Reg
reg1 Reg
reg2 Int
n -> Format -> Reg -> Reg -> Int -> Instr
CLRLI Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) Int
n
CLRRI Format
fmt Reg
reg1 Reg
reg2 Int
n -> Format -> Reg -> Reg -> Int -> Instr
CLRRI Format
fmt (Reg -> Reg
env Reg
reg1) (Reg -> Reg
env Reg
reg2) Int
n
FADD Format
fmt Reg
r1 Reg
r2 Reg
r3 -> Format -> Reg -> Reg -> Reg -> Instr
FADD Format
fmt (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2) (Reg -> Reg
env Reg
r3)
FSUB Format
fmt Reg
r1 Reg
r2 Reg
r3 -> Format -> Reg -> Reg -> Reg -> Instr
FSUB Format
fmt (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2) (Reg -> Reg
env Reg
r3)
FMUL Format
fmt Reg
r1 Reg
r2 Reg
r3 -> Format -> Reg -> Reg -> Reg -> Instr
FMUL Format
fmt (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2) (Reg -> Reg
env Reg
r3)
FDIV Format
fmt Reg
r1 Reg
r2 Reg
r3 -> Format -> Reg -> Reg -> Reg -> Instr
FDIV Format
fmt (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2) (Reg -> Reg
env Reg
r3)
FABS Reg
r1 Reg
r2 -> Reg -> Reg -> Instr
FABS (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
FNEG Reg
r1 Reg
r2 -> Reg -> Reg -> Instr
FNEG (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
FCMP Reg
r1 Reg
r2 -> Reg -> Reg -> Instr
FCMP (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
FCTIWZ Reg
r1 Reg
r2 -> Reg -> Reg -> Instr
FCTIWZ (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
FCTIDZ Reg
r1 Reg
r2 -> Reg -> Reg -> Instr
FCTIDZ (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
FCFID Reg
r1 Reg
r2 -> Reg -> Reg -> Instr
FCFID (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
FRSP Reg
r1 Reg
r2 -> Reg -> Reg -> Instr
FRSP (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
MFCR Reg
reg -> Reg -> Instr
MFCR (Reg -> Reg
env Reg
reg)
MFLR Reg
reg -> Reg -> Instr
MFLR (Reg -> Reg
env Reg
reg)
FETCHPC Reg
reg -> Reg -> Instr
FETCHPC (Reg -> Reg
env Reg
reg)
Instr
_ -> Instr
instr
where
fixAddr :: AddrMode -> AddrMode
fixAddr (AddrRegReg Reg
r1 Reg
r2) = Reg -> Reg -> AddrMode
AddrRegReg (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
fixAddr (AddrRegImm Reg
r1 Imm
i) = Reg -> Imm -> AddrMode
AddrRegImm (Reg -> Reg
env Reg
r1) Imm
i
fixRI :: RI -> RI
fixRI (RIReg Reg
r) = Reg -> RI
RIReg (Reg -> Reg
env Reg
r)
fixRI RI
other = RI
other
isJumpishInstr :: Instr -> Bool
isJumpishInstr :: Instr -> Bool
isJumpishInstr Instr
instr
= case Instr
instr of
BCC{} -> Bool
True
BCCFAR{} -> Bool
True
BCTR{} -> Bool
True
BCTRL{} -> Bool
True
BL{} -> Bool
True
JMP{} -> Bool
True
Instr
_ -> Bool
False
canFallthroughTo :: Instr -> BlockId -> Bool
canFallthroughTo :: Instr -> BlockId -> Bool
canFallthroughTo Instr
instr BlockId
bid
= case Instr
instr of
BCC Cond
_ BlockId
target Maybe Bool
_ -> BlockId
target BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
bid
BCCFAR Cond
_ BlockId
target Maybe Bool
_ -> BlockId
target BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
bid
Instr
_ -> Bool
False
jumpDestsOfInstr :: Instr -> [BlockId]
jumpDestsOfInstr :: Instr -> [BlockId]
jumpDestsOfInstr Instr
insn
= case Instr
insn of
BCC Cond
_ BlockId
id Maybe Bool
_ -> [BlockId
id]
BCCFAR Cond
_ BlockId
id Maybe Bool
_ -> [BlockId
id]
BCTR [Maybe BlockId]
targets Maybe CLabel
_ [Reg]
_ -> [BlockId
id | Just BlockId
id <- [Maybe BlockId]
targets]
Instr
_ -> []
patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
patchJumpInstr Instr
insn BlockId -> BlockId
patchF
= case Instr
insn of
BCC Cond
cc BlockId
id Maybe Bool
p -> Cond -> BlockId -> Maybe Bool -> Instr
BCC Cond
cc (BlockId -> BlockId
patchF BlockId
id) Maybe Bool
p
BCCFAR Cond
cc BlockId
id Maybe Bool
p -> Cond -> BlockId -> Maybe Bool -> Instr
BCCFAR Cond
cc (BlockId -> BlockId
patchF BlockId
id) Maybe Bool
p
BCTR [Maybe BlockId]
ids Maybe CLabel
lbl [Reg]
rs -> [Maybe BlockId] -> Maybe CLabel -> [Reg] -> Instr
BCTR ((Maybe BlockId -> Maybe BlockId)
-> [Maybe BlockId] -> [Maybe BlockId]
forall a b. (a -> b) -> [a] -> [b]
map ((BlockId -> BlockId) -> Maybe BlockId -> Maybe BlockId
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap BlockId -> BlockId
patchF) [Maybe BlockId]
ids) Maybe CLabel
lbl [Reg]
rs
Instr
_ -> Instr
insn
mkSpillInstr
:: NCGConfig
-> Reg
-> Int
-> Int
-> [Instr]
mkSpillInstr :: NCGConfig -> Reg -> Int -> Int -> [Instr]
mkSpillInstr NCGConfig
config Reg
reg Int
delta Int
slot
= let platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
off :: Int
off = Platform -> Int -> Int
spillSlotToOffset Platform
platform Int
slot
arch :: Arch
arch = Platform -> Arch
platformArch Platform
platform
in
let fmt :: Format
fmt = case Platform -> Reg -> RegClass
targetClassOfReg Platform
platform Reg
reg of
RegClass
RcInteger -> case Arch
arch of
Arch
ArchPPC -> Format
II32
Arch
_ -> Format
II64
RegClass
RcDouble -> Format
FF64
RegClass
_ -> String -> Format
forall a. HasCallStack => String -> a
panic String
"PPC.Instr.mkSpillInstr: no match"
instr :: Format -> Reg -> AddrMode -> Instr
instr = case Width -> Bool -> Int -> Maybe Imm
forall a. Integral a => Width -> Bool -> a -> Maybe Imm
makeImmediate Width
W32 Bool
True (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
delta) of
Just Imm
_ -> Format -> Reg -> AddrMode -> Instr
ST
Maybe Imm
Nothing -> Format -> Reg -> AddrMode -> Instr
STFAR
in [Format -> Reg -> AddrMode -> Instr
instr Format
fmt Reg
reg (Reg -> Imm -> AddrMode
AddrRegImm Reg
sp (Int -> Imm
ImmInt (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
delta)))]
mkLoadInstr
:: NCGConfig
-> Reg
-> Int
-> Int
-> [Instr]
mkLoadInstr :: NCGConfig -> Reg -> Int -> Int -> [Instr]
mkLoadInstr NCGConfig
config Reg
reg Int
delta Int
slot
= let platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
off :: Int
off = Platform -> Int -> Int
spillSlotToOffset Platform
platform Int
slot
arch :: Arch
arch = Platform -> Arch
platformArch Platform
platform
in
let fmt :: Format
fmt = case Platform -> Reg -> RegClass
targetClassOfReg Platform
platform Reg
reg of
RegClass
RcInteger -> case Arch
arch of
Arch
ArchPPC -> Format
II32
Arch
_ -> Format
II64
RegClass
RcDouble -> Format
FF64
RegClass
_ -> String -> Format
forall a. HasCallStack => String -> a
panic String
"PPC.Instr.mkLoadInstr: no match"
instr :: Format -> Reg -> AddrMode -> Instr
instr = case Width -> Bool -> Int -> Maybe Imm
forall a. Integral a => Width -> Bool -> a -> Maybe Imm
makeImmediate Width
W32 Bool
True (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
delta) of
Just Imm
_ -> Format -> Reg -> AddrMode -> Instr
LD
Maybe Imm
Nothing -> Format -> Reg -> AddrMode -> Instr
LDFAR
in [Format -> Reg -> AddrMode -> Instr
instr Format
fmt Reg
reg (Reg -> Imm -> AddrMode
AddrRegImm Reg
sp (Int -> Imm
ImmInt (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
delta)))]
stackFrameHeaderSize :: Platform -> Int
Platform
platform
= case Platform -> OS
platformOS Platform
platform of
OS
OSAIX -> Int
24 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
4
OS
_ -> case Platform -> Arch
platformArch Platform
platform of
Arch
ArchPPC -> Int
64
ArchPPC_64 PPC_64ABI
ELF_V1 -> Int
48 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8
ArchPPC_64 PPC_64ABI
ELF_V2 -> Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8
Arch
_ -> String -> Int
forall a. HasCallStack => String -> a
panic String
"PPC.stackFrameHeaderSize: not defined for this OS"
spillSlotSize :: Int
spillSlotSize :: Int
spillSlotSize = Int
8
maxSpillSlots :: NCGConfig -> Int
maxSpillSlots :: NCGConfig -> Int
maxSpillSlots NCGConfig
config
= let platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
in ((NCGConfig -> Int
ncgSpillPreallocSize NCGConfig
config Int -> Int -> Int
forall a. Num a => a -> a -> a
- Platform -> Int
stackFrameHeaderSize Platform
platform)
Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
spillSlotSize) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
stackAlign :: Int
stackAlign :: Int
stackAlign = Int
16
spillSlotToOffset :: Platform -> Int -> Int
spillSlotToOffset :: Platform -> Int -> Int
spillSlotToOffset Platform
platform Int
slot
= Platform -> Int
stackFrameHeaderSize Platform
platform Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
spillSlotSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
slot
takeDeltaInstr
:: Instr
-> Maybe Int
takeDeltaInstr :: Instr -> Maybe Int
takeDeltaInstr Instr
instr
= case Instr
instr of
DELTA Int
i -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i
Instr
_ -> Maybe Int
forall a. Maybe a
Nothing
isMetaInstr
:: Instr
-> Bool
isMetaInstr :: Instr -> Bool
isMetaInstr Instr
instr
= case Instr
instr of
COMMENT{} -> Bool
True
LOCATION{} -> Bool
True
LDATA{} -> Bool
True
NEWBLOCK{} -> Bool
True
DELTA{} -> Bool
True
Instr
_ -> Bool
False
mkRegRegMoveInstr
:: Reg
-> Reg
-> Instr
mkRegRegMoveInstr :: Reg -> Reg -> Instr
mkRegRegMoveInstr Reg
src Reg
dst
= Reg -> Reg -> Instr
MR Reg
dst Reg
src
mkJumpInstr
:: BlockId
-> [Instr]
mkJumpInstr :: BlockId -> [Instr]
mkJumpInstr BlockId
id
= [Cond -> BlockId -> Maybe Bool -> Instr
BCC Cond
ALWAYS BlockId
id Maybe Bool
forall a. Maybe a
Nothing]
takeRegRegMoveInstr :: Instr -> Maybe (Reg,Reg)
takeRegRegMoveInstr :: Instr -> Maybe (Reg, Reg)
takeRegRegMoveInstr (MR Reg
dst Reg
src) = (Reg, Reg) -> Maybe (Reg, Reg)
forall a. a -> Maybe a
Just (Reg
src,Reg
dst)
takeRegRegMoveInstr Instr
_ = Maybe (Reg, Reg)
forall a. Maybe a
Nothing
makeFarBranches
:: Platform
-> LabelMap RawCmmStatics
-> [NatBasicBlock Instr]
-> UniqSM [NatBasicBlock Instr]
makeFarBranches :: Platform
-> LabelMap RawCmmStatics
-> [GenBasicBlock Instr]
-> UniqSM [GenBasicBlock Instr]
makeFarBranches Platform
_platform LabelMap RawCmmStatics
info_env [GenBasicBlock Instr]
blocks
| NonEmpty Int -> Int
forall a. NonEmpty a -> a
NE.last NonEmpty Int
blockAddresses Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
nearLimit = [GenBasicBlock Instr] -> UniqSM [GenBasicBlock Instr]
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return [GenBasicBlock Instr]
blocks
| Bool
otherwise = [GenBasicBlock Instr] -> UniqSM [GenBasicBlock Instr]
forall a. a -> UniqSM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([GenBasicBlock Instr] -> UniqSM [GenBasicBlock Instr])
-> [GenBasicBlock Instr] -> UniqSM [GenBasicBlock Instr]
forall a b. (a -> b) -> a -> b
$ (Int -> GenBasicBlock Instr -> GenBasicBlock Instr)
-> [Int] -> [GenBasicBlock Instr] -> [GenBasicBlock Instr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> GenBasicBlock Instr -> GenBasicBlock Instr
handleBlock [Int]
blockAddressList [GenBasicBlock Instr]
blocks
where
blockAddresses :: NonEmpty Int
blockAddresses = (Int -> Int -> Int) -> Int -> [Int] -> NonEmpty Int
forall (f :: * -> *) b a.
Foldable f =>
(b -> a -> b) -> b -> f a -> NonEmpty b
NE.scanl Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Int
0 ([Int] -> NonEmpty Int) -> [Int] -> NonEmpty Int
forall a b. (a -> b) -> a -> b
$ (GenBasicBlock Instr -> Int) -> [GenBasicBlock Instr] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map GenBasicBlock Instr -> Int
forall {a}. GenBasicBlock a -> Int
blockLen [GenBasicBlock Instr]
blocks
blockAddressList :: [Int]
blockAddressList = NonEmpty Int -> [Int]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Int
blockAddresses
blockLen :: GenBasicBlock a -> Int
blockLen (BasicBlock BlockId
_ [a]
instrs) = [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
instrs
handleBlock :: Int -> GenBasicBlock Instr -> GenBasicBlock Instr
handleBlock Int
addr (BasicBlock BlockId
id [Instr]
instrs)
= BlockId -> [Instr] -> GenBasicBlock Instr
forall i. BlockId -> [i] -> GenBasicBlock i
BasicBlock BlockId
id ((Int -> Instr -> Instr) -> [Int] -> [Instr] -> [Instr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Instr -> Instr
makeFar [Int
addr..] [Instr]
instrs)
makeFar :: Int -> Instr -> Instr
makeFar Int
_ (BCC Cond
ALWAYS BlockId
tgt Maybe Bool
_) = Cond -> BlockId -> Maybe Bool -> Instr
BCC Cond
ALWAYS BlockId
tgt Maybe Bool
forall a. Maybe a
Nothing
makeFar Int
addr (BCC Cond
cond BlockId
tgt Maybe Bool
p)
| Int -> Int
forall a. Num a => a -> a
abs (Int
addr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
targetAddr) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
nearLimit
= Cond -> BlockId -> Maybe Bool -> Instr
BCCFAR Cond
cond BlockId
tgt Maybe Bool
p
| Bool
otherwise
= Cond -> BlockId -> Maybe Bool -> Instr
BCC Cond
cond BlockId
tgt Maybe Bool
p
where Just Int
targetAddr = UniqFM BlockId Int -> BlockId -> Maybe Int
forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
lookupUFM UniqFM BlockId Int
blockAddressMap BlockId
tgt
makeFar Int
_ Instr
other = Instr
other
nearLimit :: Int
nearLimit = Int
7000 Int -> Int -> Int
forall a. Num a => a -> a -> a
- LabelMap RawCmmStatics -> Int
forall a. LabelMap a -> Int
forall (map :: * -> *) a. IsMap map => map a -> Int
mapSize LabelMap RawCmmStatics
info_env Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
maxRetInfoTableSizeW
blockAddressMap :: UniqFM BlockId Int
blockAddressMap = [(BlockId, Int)] -> UniqFM BlockId Int
forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
listToUFM ([(BlockId, Int)] -> UniqFM BlockId Int)
-> [(BlockId, Int)] -> UniqFM BlockId Int
forall a b. (a -> b) -> a -> b
$ [BlockId] -> [Int] -> [(BlockId, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((GenBasicBlock Instr -> BlockId)
-> [GenBasicBlock Instr] -> [BlockId]
forall a b. (a -> b) -> [a] -> [b]
map GenBasicBlock Instr -> BlockId
forall i. GenBasicBlock i -> BlockId
blockId [GenBasicBlock Instr]
blocks) [Int]
blockAddressList