{-# OPTIONS_GHC -fno-warn-orphans #-}
module GHC.CmmToAsm.AArch64.Instr
where
import GHC.Prelude
import GHC.CmmToAsm.AArch64.Cond
import GHC.CmmToAsm.AArch64.Regs
import GHC.CmmToAsm.Instr (RegUsage(..))
import GHC.CmmToAsm.Format
import GHC.CmmToAsm.Types
import GHC.CmmToAsm.Utils
import GHC.CmmToAsm.Config
import GHC.CmmToAsm.Reg.Target (targetClassOfReg)
import GHC.Platform.Reg
import GHC.Platform.Reg.Class.Unified
import GHC.Platform.Regs
import GHC.Cmm.BlockId
import GHC.Cmm.Dataflow.Label
import GHC.Cmm
import GHC.Cmm.CLabel
import GHC.Utils.Outputable
import GHC.Platform
import GHC.Types.Unique.DSM
import GHC.Utils.Panic
import Data.Maybe (fromMaybe, catMaybes)
import GHC.Stack
stackFrameHeaderSize :: Int
= Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8
spillSlotSize :: Int
spillSlotSize :: Int
spillSlotSize = Int
8
stackAlign :: Int
stackAlign :: Int
stackAlign = Int
16
maxSpillSlots :: NCGConfig -> Int
maxSpillSlots :: NCGConfig -> Int
maxSpillSlots NCGConfig
config
= ((NCGConfig -> Int
ncgSpillPreallocSize NCGConfig
config Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
stackFrameHeaderSize)
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
spillSlotToOffset :: NCGConfig -> Int -> Int
spillSlotToOffset :: NCGConfig -> Int -> Int
spillSlotToOffset NCGConfig
_ Int
slot
= Int
stackFrameHeaderSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
spillSlotSize Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
slot
instance Outputable RegUsage where
ppr :: RegUsage -> SDoc
ppr (RU [RegWithFormat]
reads [RegWithFormat]
writes) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"RegUsage(reads:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [RegWithFormat] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [RegWithFormat]
reads SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"writes:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [RegWithFormat] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [RegWithFormat]
writes SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
')'
regUsageOfInstr :: Platform -> Instr -> RegUsage
regUsageOfInstr :: Platform -> Instr -> RegUsage
regUsageOfInstr Platform
platform Instr
instr = case Instr
instr of
ANN SDoc
_ Instr
i -> Platform -> Instr -> RegUsage
regUsageOfInstr Platform
platform Instr
i
COMMENT{} -> ([Reg], [Reg]) -> RegUsage
usage ([], [])
MULTILINE_COMMENT{} -> ([Reg], [Reg]) -> RegUsage
usage ([], [])
Instr
PUSH_STACK_FRAME -> ([Reg], [Reg]) -> RegUsage
usage ([], [])
Instr
POP_STACK_FRAME -> ([Reg], [Reg]) -> RegUsage
usage ([], [])
DELTA{} -> ([Reg], [Reg]) -> RegUsage
usage ([], [])
ADD Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
CMP Operand
l Operand
r -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
l [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
r, [])
CMN Operand
l Operand
r -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
l [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
r, [])
MSUB Operand
dst Operand
src1 Operand
src2 Operand
src3 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src3, Operand -> [Reg]
regOp Operand
dst)
MUL Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
NEG Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
SMULH Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
SMULL Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
UMULH Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
UMULL Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
SDIV Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
SUB Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
UDIV Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
SBFM Operand
dst Operand
src Operand
_ Operand
_ -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
UBFM Operand
dst Operand
src Operand
_ Operand
_ -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
SBFX Operand
dst Operand
src Operand
_ Operand
_ -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
UBFX Operand
dst Operand
src Operand
_ Operand
_ -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
SXTB Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
UXTB Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
SXTH Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
UXTH Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
CLZ Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
RBIT Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
REV Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
REV16 Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
AND Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
ASR Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
EOR Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
LSL Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
LSR Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
MOV Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
MOVK Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
MOVZ Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
MVN Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
ORR Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
J Target
t -> ([Reg], [Reg]) -> RegUsage
usage (Target -> [Reg]
regTarget Target
t, [])
J_TBL [Maybe BlockId]
_ Maybe CLabel
_ Reg
t -> ([Reg], [Reg]) -> RegUsage
usage ([Reg
t], [])
B Target
t -> ([Reg], [Reg]) -> RegUsage
usage (Target -> [Reg]
regTarget Target
t, [])
BCOND Cond
_ Target
t -> ([Reg], [Reg]) -> RegUsage
usage (Target -> [Reg]
regTarget Target
t, [])
BL Target
t [Reg]
ps -> ([Reg], [Reg]) -> RegUsage
usage (Target -> [Reg]
regTarget Target
t [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ [Reg]
ps, [Reg]
callerSavedRegisters)
CSET Operand
dst Cond
_ -> ([Reg], [Reg]) -> RegUsage
usage ([], Operand -> [Reg]
regOp Operand
dst)
CBZ Operand
src Target
_ -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, [])
CBNZ Operand
src Target
_ -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, [])
STR Format
_ Operand
src Operand
dst -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
dst, [])
STLR Format
_ Operand
src Operand
dst -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
dst, [])
LDR Format
_ Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
LDAR Format
_ Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
DMBISH DMBISHFlags
_ -> ([Reg], [Reg]) -> RegUsage
usage ([], [])
FMOV Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
FCVT Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
SCVTF Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
FCVTZS Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
FABS Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
FSQRT Operand
dst Operand
src -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src, Operand -> [Reg]
regOp Operand
dst)
FMIN Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
FMAX Operand
dst Operand
src1 Operand
src2 -> ([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2, Operand -> [Reg]
regOp Operand
dst)
FMA FMASign
_ Operand
dst Operand
src1 Operand
src2 Operand
src3 ->
([Reg], [Reg]) -> RegUsage
usage (Operand -> [Reg]
regOp Operand
src1 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src2 [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ Operand -> [Reg]
regOp Operand
src3, Operand -> [Reg]
regOp Operand
dst)
LOCATION{} -> String -> RegUsage
forall a. HasCallStack => String -> a
panic (String -> RegUsage) -> String -> RegUsage
forall a b. (a -> b) -> a -> b
$ String
"regUsageOfInstr: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Instr -> String
instrCon Instr
instr
NEWBLOCK{} -> String -> RegUsage
forall a. HasCallStack => String -> a
panic (String -> RegUsage) -> String -> RegUsage
forall a b. (a -> b) -> a -> b
$ String
"regUsageOfInstr: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Instr -> String
instrCon Instr
instr
where
usage :: ([Reg], [Reg]) -> RegUsage
usage ([Reg]
src, [Reg]
dst) = [RegWithFormat] -> [RegWithFormat] -> RegUsage
RU ((Reg -> RegWithFormat) -> [Reg] -> [RegWithFormat]
forall a b. (a -> b) -> [a] -> [b]
map Reg -> RegWithFormat
mkFmt ([Reg] -> [RegWithFormat]) -> [Reg] -> [RegWithFormat]
forall a b. (a -> b) -> a -> b
$ (Reg -> Bool) -> [Reg] -> [Reg]
forall a. (a -> Bool) -> [a] -> [a]
filter (Platform -> Reg -> Bool
interesting Platform
platform) [Reg]
src)
((Reg -> RegWithFormat) -> [Reg] -> [RegWithFormat]
forall a b. (a -> b) -> [a] -> [b]
map Reg -> RegWithFormat
mkFmt ([Reg] -> [RegWithFormat]) -> [Reg] -> [RegWithFormat]
forall a b. (a -> b) -> a -> b
$ (Reg -> Bool) -> [Reg] -> [Reg]
forall a. (a -> Bool) -> [a] -> [a]
filter (Platform -> Reg -> Bool
interesting Platform
platform) [Reg]
dst)
mkFmt :: Reg -> RegWithFormat
mkFmt Reg
r = Reg -> Format -> RegWithFormat
RegWithFormat Reg
r Format
fmt
where fmt :: Format
fmt = case Platform -> Reg -> RegClass
targetClassOfReg Platform
platform Reg
r of
RegClass
RcInteger -> Format
II64
RegClass
RcFloatOrVector -> Format
FF64
regAddr :: AddrMode -> [Reg]
regAddr :: AddrMode -> [Reg]
regAddr (AddrRegReg Reg
r1 Reg
r2) = [Reg
r1, Reg
r2]
regAddr (AddrRegImm Reg
r1 Imm
_) = [Reg
r1]
regAddr (AddrReg Reg
r1) = [Reg
r1]
regOp :: Operand -> [Reg]
regOp :: Operand -> [Reg]
regOp (OpReg Width
_ Reg
r1) = [Reg
r1]
regOp (OpRegExt Width
_ Reg
r1 ExtMode
_ Int
_) = [Reg
r1]
regOp (OpRegShift Width
_ Reg
r1 ShiftMode
_ Int
_) = [Reg
r1]
regOp (OpAddr AddrMode
a) = AddrMode -> [Reg]
regAddr AddrMode
a
regOp (OpImm Imm
_) = []
regOp (OpImmShift Imm
_ ShiftMode
_ Int
_) = []
regTarget :: Target -> [Reg]
regTarget :: Target -> [Reg]
regTarget (TBlock BlockId
_) = []
regTarget (TLabel CLabel
_) = []
regTarget (TReg Reg
r1) = [Reg
r1]
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
callerSavedRegisters :: [Reg]
callerSavedRegisters :: [Reg]
callerSavedRegisters
= (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
0..Int
18]
[Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
32..Int
39]
[Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
48..Int
63]
patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
patchRegsOfInstr Instr
instr Reg -> Reg
env = case Instr
instr of
ANN SDoc
d Instr
i -> SDoc -> Instr -> Instr
ANN SDoc
d (Instr -> (Reg -> Reg) -> Instr
patchRegsOfInstr Instr
i Reg -> Reg
env)
COMMENT{} -> Instr
instr
MULTILINE_COMMENT{} -> Instr
instr
Instr
PUSH_STACK_FRAME -> Instr
instr
Instr
POP_STACK_FRAME -> Instr
instr
DELTA{} -> Instr
instr
ADD Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
ADD (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
CMP Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
CMP (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
CMN Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
CMN (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
MSUB Operand
o1 Operand
o2 Operand
o3 Operand
o4 -> Operand -> Operand -> Operand -> Operand -> Instr
MSUB (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3) (Operand -> Operand
patchOp Operand
o4)
MUL Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
MUL (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
NEG Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
NEG (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
SMULH Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
SMULH (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
SMULL Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
SMULL (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
UMULH Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
UMULH (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
UMULL Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
UMULL (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
SDIV Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
SDIV (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
SUB Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
SUB (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
UDIV Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
UDIV (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
SBFM Operand
o1 Operand
o2 Operand
o3 Operand
o4 -> Operand -> Operand -> Operand -> Operand -> Instr
SBFM (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3) (Operand -> Operand
patchOp Operand
o4)
UBFM Operand
o1 Operand
o2 Operand
o3 Operand
o4 -> Operand -> Operand -> Operand -> Operand -> Instr
UBFM (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3) (Operand -> Operand
patchOp Operand
o4)
SBFX Operand
o1 Operand
o2 Operand
o3 Operand
o4 -> Operand -> Operand -> Operand -> Operand -> Instr
SBFX (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3) (Operand -> Operand
patchOp Operand
o4)
UBFX Operand
o1 Operand
o2 Operand
o3 Operand
o4 -> Operand -> Operand -> Operand -> Operand -> Instr
UBFX (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3) (Operand -> Operand
patchOp Operand
o4)
SXTB Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
SXTB (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
UXTB Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
UXTB (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
SXTH Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
SXTH (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
UXTH Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
UXTH (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
CLZ Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
CLZ (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
RBIT Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
RBIT (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
REV Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
REV (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
REV16 Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
REV16 (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
AND Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
AND (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
ASR Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
ASR (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
EOR Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
EOR (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
LSL Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
LSL (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
LSR Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
LSR (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
MOV Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
MOV (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
MOVK Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
MOVK (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
MOVZ Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
MOVZ (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
MVN Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
MVN (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
ORR Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
ORR (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
J Target
t -> Target -> Instr
J (Target -> Target
patchTarget Target
t)
J_TBL [Maybe BlockId]
ids Maybe CLabel
mbLbl Reg
t -> [Maybe BlockId] -> Maybe CLabel -> Reg -> Instr
J_TBL [Maybe BlockId]
ids Maybe CLabel
mbLbl (Reg -> Reg
env Reg
t)
B Target
t -> Target -> Instr
B (Target -> Target
patchTarget Target
t)
BL Target
t [Reg]
rs -> Target -> [Reg] -> Instr
BL (Target -> Target
patchTarget Target
t) [Reg]
rs
BCOND Cond
c Target
t -> Cond -> Target -> Instr
BCOND Cond
c (Target -> Target
patchTarget Target
t)
CSET Operand
o Cond
c -> Operand -> Cond -> Instr
CSET (Operand -> Operand
patchOp Operand
o) Cond
c
CBZ Operand
o Target
l -> Operand -> Target -> Instr
CBZ (Operand -> Operand
patchOp Operand
o) Target
l
CBNZ Operand
o Target
l -> Operand -> Target -> Instr
CBNZ (Operand -> Operand
patchOp Operand
o) Target
l
STR Format
f Operand
o1 Operand
o2 -> Format -> Operand -> Operand -> Instr
STR Format
f (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
STLR Format
f Operand
o1 Operand
o2 -> Format -> Operand -> Operand -> Instr
STLR Format
f (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
LDR Format
f Operand
o1 Operand
o2 -> Format -> Operand -> Operand -> Instr
LDR Format
f (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
LDAR Format
f Operand
o1 Operand
o2 -> Format -> Operand -> Operand -> Instr
LDAR Format
f (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
DMBISH DMBISHFlags
c -> DMBISHFlags -> Instr
DMBISH DMBISHFlags
c
FMOV Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
FMOV (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
FCVT Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
FCVT (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
SCVTF Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
SCVTF (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
FCVTZS Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
FCVTZS (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
FABS Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
FABS (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
FSQRT Operand
o1 Operand
o2 -> Operand -> Operand -> Instr
FSQRT (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2)
FMIN Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
FMIN (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
FMAX Operand
o1 Operand
o2 Operand
o3 -> Operand -> Operand -> Operand -> Instr
FMAX (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3)
FMA FMASign
s Operand
o1 Operand
o2 Operand
o3 Operand
o4 ->
FMASign -> Operand -> Operand -> Operand -> Operand -> Instr
FMA FMASign
s (Operand -> Operand
patchOp Operand
o1) (Operand -> Operand
patchOp Operand
o2) (Operand -> Operand
patchOp Operand
o3) (Operand -> Operand
patchOp Operand
o4)
NEWBLOCK{} -> String -> Instr
forall a. HasCallStack => String -> a
panic (String -> Instr) -> String -> Instr
forall a b. (a -> b) -> a -> b
$ String
"patchRegsOfInstr: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Instr -> String
instrCon Instr
instr
LOCATION{} -> String -> Instr
forall a. HasCallStack => String -> a
panic (String -> Instr) -> String -> Instr
forall a b. (a -> b) -> a -> b
$ String
"patchRegsOfInstr: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Instr -> String
instrCon Instr
instr
where
patchOp :: Operand -> Operand
patchOp :: Operand -> Operand
patchOp (OpReg Width
w Reg
r) = Width -> Reg -> Operand
OpReg Width
w (Reg -> Reg
env Reg
r)
patchOp (OpRegExt Width
w Reg
r ExtMode
x Int
s) = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
w (Reg -> Reg
env Reg
r) ExtMode
x Int
s
patchOp (OpRegShift Width
w Reg
r ShiftMode
m Int
s) = Width -> Reg -> ShiftMode -> Int -> Operand
OpRegShift Width
w (Reg -> Reg
env Reg
r) ShiftMode
m Int
s
patchOp (OpAddr AddrMode
a) = AddrMode -> Operand
OpAddr (AddrMode -> AddrMode
patchAddr AddrMode
a)
patchOp Operand
op = Operand
op
patchTarget :: Target -> Target
patchTarget :: Target -> Target
patchTarget (TReg Reg
r) = Reg -> Target
TReg (Reg -> Reg
env Reg
r)
patchTarget Target
t = Target
t
patchAddr :: AddrMode -> AddrMode
patchAddr :: AddrMode -> AddrMode
patchAddr (AddrRegReg Reg
r1 Reg
r2) = Reg -> Reg -> AddrMode
AddrRegReg (Reg -> Reg
env Reg
r1) (Reg -> Reg
env Reg
r2)
patchAddr (AddrRegImm Reg
r1 Imm
i) = Reg -> Imm -> AddrMode
AddrRegImm (Reg -> Reg
env Reg
r1) Imm
i
patchAddr (AddrReg Reg
r) = Reg -> AddrMode
AddrReg (Reg -> Reg
env Reg
r)
isJumpishInstr :: Instr -> Bool
isJumpishInstr :: Instr -> Bool
isJumpishInstr Instr
instr = case Instr
instr of
ANN SDoc
_ Instr
i -> Instr -> Bool
isJumpishInstr Instr
i
CBZ{} -> Bool
True
CBNZ{} -> Bool
True
J{} -> Bool
True
J_TBL{} -> Bool
True
B{} -> Bool
True
BL{} -> Bool
True
BCOND{} -> Bool
True
Instr
_ -> Bool
False
jumpDestsOfInstr :: Instr -> [BlockId]
jumpDestsOfInstr :: Instr -> [BlockId]
jumpDestsOfInstr (ANN SDoc
_ Instr
i) = Instr -> [BlockId]
jumpDestsOfInstr Instr
i
jumpDestsOfInstr (CBZ Operand
_ Target
t) = [ BlockId
id | TBlock BlockId
id <- [Target
t]]
jumpDestsOfInstr (CBNZ Operand
_ Target
t) = [ BlockId
id | TBlock BlockId
id <- [Target
t]]
jumpDestsOfInstr (J Target
t) = [BlockId
id | TBlock BlockId
id <- [Target
t]]
jumpDestsOfInstr (J_TBL [Maybe BlockId]
ids Maybe CLabel
_mbLbl Reg
_r) = [Maybe BlockId] -> [BlockId]
forall a. [Maybe a] -> [a]
catMaybes [Maybe BlockId]
ids
jumpDestsOfInstr (B Target
t) = [BlockId
id | TBlock BlockId
id <- [Target
t]]
jumpDestsOfInstr (BL Target
t [Reg]
_) = [ BlockId
id | TBlock BlockId
id <- [Target
t]]
jumpDestsOfInstr (BCOND Cond
_ Target
t) = [ BlockId
id | TBlock BlockId
id <- [Target
t]]
jumpDestsOfInstr Instr
_ = []
canFallthroughTo :: Instr -> BlockId -> Bool
canFallthroughTo :: Instr -> BlockId -> Bool
canFallthroughTo (ANN SDoc
_ Instr
i) BlockId
bid = Instr -> BlockId -> Bool
canFallthroughTo Instr
i BlockId
bid
canFallthroughTo (J (TBlock BlockId
target)) BlockId
bid = BlockId
bid BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
target
canFallthroughTo (J_TBL [Maybe BlockId]
targets Maybe CLabel
_ Reg
_) BlockId
bid = (Maybe BlockId -> Bool) -> [Maybe BlockId] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Maybe BlockId -> Bool
isTargetBid [Maybe BlockId]
targets
where
isTargetBid :: Maybe BlockId -> Bool
isTargetBid Maybe BlockId
target = case Maybe BlockId
target of
Maybe BlockId
Nothing -> Bool
True
Just BlockId
target -> BlockId
target BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
bid
canFallthroughTo (B (TBlock BlockId
target)) BlockId
bid = BlockId
bid BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
target
canFallthroughTo Instr
_ BlockId
_ = Bool
False
patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
patchJumpInstr Instr
instr BlockId -> BlockId
patchF
= case Instr
instr of
ANN SDoc
d Instr
i -> SDoc -> Instr -> Instr
ANN SDoc
d (Instr -> (BlockId -> BlockId) -> Instr
patchJumpInstr Instr
i BlockId -> BlockId
patchF)
CBZ Operand
r (TBlock BlockId
bid) -> Operand -> Target -> Instr
CBZ Operand
r (BlockId -> Target
TBlock (BlockId -> BlockId
patchF BlockId
bid))
CBNZ Operand
r (TBlock BlockId
bid) -> Operand -> Target -> Instr
CBNZ Operand
r (BlockId -> Target
TBlock (BlockId -> BlockId
patchF BlockId
bid))
J (TBlock BlockId
bid) -> Target -> Instr
J (BlockId -> Target
TBlock (BlockId -> BlockId
patchF BlockId
bid))
J_TBL [Maybe BlockId]
ids Maybe CLabel
mbLbl Reg
r -> [Maybe BlockId] -> Maybe CLabel -> Reg -> Instr
J_TBL ((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
mbLbl Reg
r
B (TBlock BlockId
bid) -> Target -> Instr
B (BlockId -> Target
TBlock (BlockId -> BlockId
patchF BlockId
bid))
BL (TBlock BlockId
bid) [Reg]
ps -> Target -> [Reg] -> Instr
BL (BlockId -> Target
TBlock (BlockId -> BlockId
patchF BlockId
bid)) [Reg]
ps
BCOND Cond
c (TBlock BlockId
bid) -> Cond -> Target -> Instr
BCOND Cond
c (BlockId -> Target
TBlock (BlockId -> BlockId
patchF BlockId
bid))
Instr
_ -> String -> Instr
forall a. HasCallStack => String -> a
panic (String -> Instr) -> String -> Instr
forall a b. (a -> b) -> a -> b
$ String
"patchJumpInstr: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Instr -> String
instrCon Instr
instr
mkSpillInstr
:: HasCallStack
=> NCGConfig
-> RegWithFormat
-> Int
-> Int
-> [Instr]
mkSpillInstr :: HasCallStack => NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
mkSpillInstr NCGConfig
config (RegWithFormat Reg
reg Format
fmt) Int
delta Int
slot =
case Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
delta of
Int
imm | -Int
256 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
imm Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 -> [ Int -> Instr
mkStrSp Int
imm ]
Int
imm | Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x7 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0x0 Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xfff -> [ Int -> Instr
mkStrSp Int
imm ]
Int
imm | Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0xfff Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xffffff Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x7 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0x0 -> [ Int -> Instr
mkIp0SpillAddr (Int
imm Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&~. Int
0xfff)
, Int -> Instr
mkStrIp0 (Int
imm Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xfff)
]
Int
imm -> String -> SDoc -> [Instr]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"mkSpillInstr" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Unable to spill register into" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
imm)
where
a
a .&~. :: a -> a -> a
.&~. a
b = a
a a -> a -> a
forall a. Bits a => a -> a -> a
.&. (a -> a
forall a. Bits a => a -> a
complement a
b)
mkIp0SpillAddr :: Int -> Instr
mkIp0SpillAddr Int
imm = SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Spill: IP0 <- SP + " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
imm) (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> Operand -> Instr
ADD Operand
ip0 Operand
sp (Imm -> Operand
OpImm (Int -> Imm
ImmInt Int
imm))
mkStrSp :: Int -> Instr
mkStrSp Int
imm = SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Spill@" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
delta)) (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Format -> Operand -> Operand -> Instr
STR Format
fmt (Width -> Reg -> Operand
OpReg Width
W64 Reg
reg) (AddrMode -> Operand
OpAddr (Reg -> Imm -> AddrMode
AddrRegImm (Int -> Reg
regSingle Int
31) (Int -> Imm
ImmInt Int
imm)))
mkStrIp0 :: Int -> Instr
mkStrIp0 Int
imm = SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Spill@" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
delta)) (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Format -> Operand -> Operand -> Instr
STR Format
fmt (Width -> Reg -> Operand
OpReg Width
W64 Reg
reg) (AddrMode -> Operand
OpAddr (Reg -> Imm -> AddrMode
AddrRegImm (Int -> Reg
regSingle Int
16) (Int -> Imm
ImmInt Int
imm)))
off :: Int
off = NCGConfig -> Int -> Int
spillSlotToOffset NCGConfig
config Int
slot
mkLoadInstr
:: NCGConfig
-> RegWithFormat
-> Int
-> Int
-> [Instr]
mkLoadInstr :: NCGConfig -> RegWithFormat -> Int -> Int -> [Instr]
mkLoadInstr NCGConfig
config (RegWithFormat Reg
reg Format
fmt) Int
delta Int
slot =
case Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
delta of
Int
imm | -Int
256 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
imm Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 -> [ Int -> Instr
mkLdrSp Int
imm ]
Int
imm | Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x7 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0x0 Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xfff -> [ Int -> Instr
mkLdrSp Int
imm ]
Int
imm | Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0xfff Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xffffff Bool -> Bool -> Bool
&& Int
imm Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x7 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0x0 -> [ Int -> Instr
mkIp0SpillAddr (Int
imm Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&~. Int
0xfff)
, Int -> Instr
mkLdrIp0 (Int
imm Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xfff)
]
Int
imm -> String -> SDoc -> [Instr]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"mkLoadInstr" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Unable to load spilled register at" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
imm)
where
a
a .&~. :: a -> a -> a
.&~. a
b = a
a a -> a -> a
forall a. Bits a => a -> a -> a
.&. (a -> a
forall a. Bits a => a -> a
complement a
b)
mkIp0SpillAddr :: Int -> Instr
mkIp0SpillAddr Int
imm = SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Reload: IP0 <- SP + " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
imm) (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> Operand -> Instr
ADD Operand
ip0 Operand
sp (Imm -> Operand
OpImm (Int -> Imm
ImmInt Int
imm))
mkLdrSp :: Int -> Instr
mkLdrSp Int
imm = SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Reload@" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
delta)) (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Format -> Operand -> Operand -> Instr
LDR Format
fmt (Width -> Reg -> Operand
OpReg Width
W64 Reg
reg) (AddrMode -> Operand
OpAddr (Reg -> Imm -> AddrMode
AddrRegImm (Int -> Reg
regSingle Int
31) (Int -> Imm
ImmInt Int
imm)))
mkLdrIp0 :: Int -> Instr
mkLdrIp0 Int
imm = SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Reload@" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
delta)) (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Format -> Operand -> Operand -> Instr
LDR Format
fmt (Width -> Reg -> Operand
OpReg Width
W64 Reg
reg) (AddrMode -> Operand
OpAddr (Reg -> Imm -> AddrMode
AddrRegImm (Int -> Reg
regSingle Int
16) (Int -> Imm
ImmInt Int
imm)))
off :: Int
off = NCGConfig -> Int -> Int
spillSlotToOffset NCGConfig
config Int
slot
takeDeltaInstr :: Instr -> Maybe Int
takeDeltaInstr :: Instr -> Maybe Int
takeDeltaInstr (ANN SDoc
_ Instr
i) = Instr -> Maybe Int
takeDeltaInstr Instr
i
takeDeltaInstr (DELTA Int
i) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i
takeDeltaInstr Instr
_ = Maybe Int
forall a. Maybe a
Nothing
isMetaInstr :: Instr -> Bool
isMetaInstr :: Instr -> Bool
isMetaInstr Instr
instr
= case Instr
instr of
ANN SDoc
_ Instr
i -> Instr -> Bool
isMetaInstr Instr
i
COMMENT{} -> Bool
True
MULTILINE_COMMENT{} -> Bool
True
LOCATION{} -> Bool
True
NEWBLOCK{} -> Bool
True
DELTA{} -> Bool
True
Instr
PUSH_STACK_FRAME -> Bool
True
Instr
POP_STACK_FRAME -> Bool
True
Instr
_ -> Bool
False
mkRegRegMoveInstr :: Format -> Reg -> Reg -> Instr
mkRegRegMoveInstr :: Format -> Reg -> Reg -> Instr
mkRegRegMoveInstr Format
_fmt Reg
src Reg
dst
= SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Reg->Reg Move: " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Reg -> SDoc
forall a. Outputable a => a -> SDoc
ppr Reg
src SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" -> " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Reg -> SDoc
forall a. Outputable a => a -> SDoc
ppr Reg
dst) (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> Instr
MOV (Width -> Reg -> Operand
OpReg Width
W64 Reg
dst) (Width -> Reg -> Operand
OpReg Width
W64 Reg
src)
takeRegRegMoveInstr :: Instr -> Maybe (Reg,Reg)
takeRegRegMoveInstr :: Instr -> Maybe (Reg, Reg)
takeRegRegMoveInstr (MOV (OpReg Width
_fmt Reg
dst) (OpReg Width
_fmt' Reg
src))
| Reg -> RegClass
classOfReg Reg
dst RegClass -> RegClass -> Bool
forall a. Eq a => a -> a -> Bool
== Reg -> RegClass
classOfReg Reg
src = (Reg, Reg) -> Maybe (Reg, Reg)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Reg
src, Reg
dst)
where
classOfReg :: Reg -> RegClass
classOfReg :: Reg -> RegClass
classOfReg Reg
reg
= case Reg
reg of
RegVirtual VirtualReg
vr -> Arch -> VirtualReg -> RegClass
classOfVirtualReg Arch
ArchAArch64 VirtualReg
vr
RegReal RealReg
rr -> RealReg -> RegClass
classOfRealReg RealReg
rr
takeRegRegMoveInstr Instr
_ = Maybe (Reg, Reg)
forall a. Maybe a
Nothing
mkJumpInstr :: BlockId -> [Instr]
mkJumpInstr :: BlockId -> [Instr]
mkJumpInstr BlockId
id = [Target -> Instr
B (BlockId -> Target
TBlock BlockId
id)]
mkStackAllocInstr :: Platform -> Int -> [Instr]
mkStackAllocInstr :: Platform -> Int -> [Instr]
mkStackAllocInstr Platform
platform Int
n
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = []
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
4096 = [ SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Alloc More Stack") (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> Operand -> Instr
SUB Operand
sp Operand
sp (Imm -> Operand
OpImm (Int -> Imm
ImmInt Int
n)) ]
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Alloc More Stack") (Operand -> Operand -> Operand -> Instr
SUB Operand
sp Operand
sp (Imm -> Operand
OpImm (Int -> Imm
ImmInt Int
4095))) Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: Platform -> Int -> [Instr]
mkStackAllocInstr Platform
platform (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
4095)
mkStackAllocInstr Platform
_platform Int
n = String -> SDoc -> [Instr]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"mkStackAllocInstr" (Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
n)
mkStackDeallocInstr :: Platform -> Int -> [Instr]
mkStackDeallocInstr :: Platform -> Int -> [Instr]
mkStackDeallocInstr Platform
platform Int
n
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = []
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
4096 = [ SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Dealloc More Stack") (Instr -> Instr) -> Instr -> Instr
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> Operand -> Instr
ADD Operand
sp Operand
sp (Imm -> Operand
OpImm (Int -> Imm
ImmInt Int
n)) ]
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = SDoc -> Instr -> Instr
ANN (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Dealloc More Stack") (Operand -> Operand -> Operand -> Instr
ADD Operand
sp Operand
sp (Imm -> Operand
OpImm (Int -> Imm
ImmInt Int
4095))) Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: Platform -> Int -> [Instr]
mkStackDeallocInstr Platform
platform (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
4095)
mkStackDeallocInstr Platform
_platform Int
n = String -> SDoc -> [Instr]
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"mkStackDeallocInstr" (Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
n)
allocMoreStack
:: Platform
-> Int
-> NatCmmDecl statics GHC.CmmToAsm.AArch64.Instr.Instr
-> UniqDSM (NatCmmDecl statics GHC.CmmToAsm.AArch64.Instr.Instr, [(BlockId,BlockId)])
allocMoreStack :: forall statics.
Platform
-> Int
-> NatCmmDecl statics Instr
-> UniqDSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
allocMoreStack Platform
_ Int
_ top :: NatCmmDecl statics Instr
top@(CmmData Section
_ statics
_) = (NatCmmDecl statics Instr, [(BlockId, BlockId)])
-> UniqDSM (NatCmmDecl statics Instr, [(BlockId, BlockId)])
forall a. a -> UniqDSM a
forall (m :: * -> *) a. Monad m => a -> m a
return (NatCmmDecl statics Instr
top,[])
allocMoreStack Platform
platform Int
slots proc :: NatCmmDecl statics Instr
proc@(CmmProc LabelMap RawCmmStatics
info CLabel
lbl [GlobalRegUse]
live (ListGraph [GenBasicBlock Instr]
code)) = do
let entries :: [BlockId]
entries = NatCmmDecl statics Instr -> [BlockId]
forall a i b. GenCmmDecl a (LabelMap i) (ListGraph b) -> [BlockId]
entryBlocks NatCmmDecl statics Instr
proc
retargetList <- (BlockId -> UniqDSM (BlockId, BlockId))
-> [BlockId] -> UniqDSM [(BlockId, BlockId)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\BlockId
e -> (BlockId
e,) (BlockId -> (BlockId, BlockId))
-> UniqDSM BlockId -> UniqDSM (BlockId, BlockId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UniqDSM BlockId
forall (m :: * -> *). MonadGetUnique m => m BlockId
newBlockId) [BlockId]
entries
let
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 = Platform -> Int -> [Instr]
mkStackAllocInstr Platform
platform Int
delta
dealloc = Platform -> Int -> [Instr]
mkStackDeallocInstr Platform
platform Int
delta
new_blockmap :: LabelMap BlockId
new_blockmap = [(BlockId, BlockId)] -> LabelMap BlockId
forall v. [(BlockId, v)] -> LabelMap v
mapFromList [(BlockId, BlockId)]
retargetList
insert_stack_insn (BasicBlock BlockId
id [Instr]
insns)
| Just BlockId
new_blockid <- BlockId -> LabelMap BlockId -> Maybe BlockId
forall a. BlockId -> LabelMap a -> Maybe a
mapLookup 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]
++ [ Target -> Instr
B (BlockId -> Target
TBlock BlockId
new_blockid) ]
, 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
insn [Instr]
r = case Instr
insn of
J Target
_ -> [Instr]
dealloc [Instr] -> [Instr] -> [Instr]
forall a. [a] -> [a] -> [a]
++ (Instr
insn Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r)
J_TBL {} -> [Instr]
dealloc [Instr] -> [Instr] -> [Instr]
forall a. [a] -> [a] -> [a]
++ (Instr
insn Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r)
ANN SDoc
_ (J Target
_) -> [Instr]
dealloc [Instr] -> [Instr] -> [Instr]
forall a. [a] -> [a] -> [a]
++ (Instr
insn Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r)
Instr
_other | Instr -> [BlockId]
jumpDestsOfInstr Instr
insn [BlockId] -> [BlockId] -> Bool
forall a. Eq a => a -> a -> Bool
/= []
-> Instr -> (BlockId -> BlockId) -> Instr
patchJumpInstr Instr
insn BlockId -> BlockId
retarget Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r
Instr
_other -> Instr
insn Instr -> [Instr] -> [Instr]
forall a. a -> [a] -> [a]
: [Instr]
r
where retarget :: BlockId -> BlockId
retarget BlockId
b = BlockId -> Maybe BlockId -> BlockId
forall a. a -> Maybe a -> a
fromMaybe BlockId
b (BlockId -> LabelMap BlockId -> Maybe BlockId
forall a. BlockId -> LabelMap a -> Maybe a
mapLookup BlockId
b LabelMap BlockId
new_blockmap)
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_insn [GenBasicBlock Instr]
code
return (CmmProc info lbl live (ListGraph new_code), retargetList)
data Instr
= SDoc
| SDoc
| ANN SDoc Instr
| LOCATION Int Int Int String
| NEWBLOCK BlockId
| DELTA Int
| SXTB Operand Operand
| UXTB Operand Operand
| SXTH Operand Operand
| UXTH Operand Operand
| PUSH_STACK_FRAME
| POP_STACK_FRAME
| ADD Operand Operand Operand
| CMP Operand Operand
| CMN Operand Operand
| MSUB Operand Operand Operand Operand
| MUL Operand Operand Operand
| NEG Operand Operand
| SDIV Operand Operand Operand
| SMULH Operand Operand Operand
| SMULL Operand Operand Operand
| SUB Operand Operand Operand
| UDIV Operand Operand Operand
| UMULH Operand Operand Operand
| UMULL Operand Operand Operand
| SBFM Operand Operand Operand Operand
| UBFM Operand Operand Operand Operand
| SBFX Operand Operand Operand Operand
| UBFX Operand Operand Operand Operand
| CLZ Operand Operand
| RBIT Operand Operand
| REV Operand Operand
| REV16 Operand Operand
| AND Operand Operand Operand
| ASR Operand Operand Operand
| EOR Operand Operand Operand
| LSL Operand Operand Operand
| LSR Operand Operand Operand
| MOV Operand Operand
| MOVK Operand Operand
| MOVZ Operand Operand
| MVN Operand Operand
| ORR Operand Operand Operand
| STR Format Operand Operand
| STLR Format Operand Operand
| LDR Format Operand Operand
| LDAR Format Operand Operand
| CSET Operand Cond
| CBZ Operand Target
| CBNZ Operand Target
| J Target
| J_TBL [Maybe BlockId] (Maybe CLabel) Reg
| B Target
| BL Target [Reg]
| BCOND Cond Target
| DMBISH DMBISHFlags
| FMOV Operand Operand
| FCVT Operand Operand
| SCVTF Operand Operand
| FCVTZS Operand Operand
| FABS Operand Operand
| FMIN Operand Operand Operand
| FMAX Operand Operand Operand
| FSQRT Operand Operand
| FMA FMASign Operand Operand Operand Operand
data DMBISHFlags = DmbLoad | DmbLoadStore
deriving (DMBISHFlags -> DMBISHFlags -> Bool
(DMBISHFlags -> DMBISHFlags -> Bool)
-> (DMBISHFlags -> DMBISHFlags -> Bool) -> Eq DMBISHFlags
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DMBISHFlags -> DMBISHFlags -> Bool
== :: DMBISHFlags -> DMBISHFlags -> Bool
$c/= :: DMBISHFlags -> DMBISHFlags -> Bool
/= :: DMBISHFlags -> DMBISHFlags -> Bool
Eq, Int -> DMBISHFlags -> String -> String
[DMBISHFlags] -> String -> String
DMBISHFlags -> String
(Int -> DMBISHFlags -> String -> String)
-> (DMBISHFlags -> String)
-> ([DMBISHFlags] -> String -> String)
-> Show DMBISHFlags
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> DMBISHFlags -> String -> String
showsPrec :: Int -> DMBISHFlags -> String -> String
$cshow :: DMBISHFlags -> String
show :: DMBISHFlags -> String
$cshowList :: [DMBISHFlags] -> String -> String
showList :: [DMBISHFlags] -> String -> String
Show)
instrCon :: Instr -> String
instrCon :: Instr -> String
instrCon Instr
i =
case Instr
i of
COMMENT{} -> String
"COMMENT"
MULTILINE_COMMENT{} -> String
"COMMENT"
ANN{} -> String
"ANN"
LOCATION{} -> String
"LOCATION"
NEWBLOCK{} -> String
"NEWBLOCK"
DELTA{} -> String
"DELTA"
SXTB{} -> String
"SXTB"
UXTB{} -> String
"UXTB"
SXTH{} -> String
"SXTH"
UXTH{} -> String
"UXTH"
PUSH_STACK_FRAME{} -> String
"PUSH_STACK_FRAME"
POP_STACK_FRAME{} -> String
"POP_STACK_FRAME"
ADD{} -> String
"ADD"
CMP{} -> String
"CMP"
CMN{} -> String
"CMN"
MSUB{} -> String
"MSUB"
MUL{} -> String
"MUL"
NEG{} -> String
"NEG"
SDIV{} -> String
"SDIV"
SMULH{} -> String
"SMULH"
SMULL{} -> String
"SMULL"
UMULH{} -> String
"UMULH"
UMULL{} -> String
"UMULL"
SUB{} -> String
"SUB"
UDIV{} -> String
"UDIV"
SBFM{} -> String
"SBFM"
UBFM{} -> String
"UBFM"
SBFX{} -> String
"SBFX"
UBFX{} -> String
"UBFX"
CLZ{} -> String
"CLZ"
RBIT{} -> String
"RBIT"
REV{} -> String
"REV"
REV16{} -> String
"REV16"
AND{} -> String
"AND"
ASR{} -> String
"ASR"
EOR{} -> String
"EOR"
LSL{} -> String
"LSL"
LSR{} -> String
"LSR"
MOV{} -> String
"MOV"
MOVK{} -> String
"MOVK"
MOVZ{} -> String
"MOVZ"
MVN{} -> String
"MVN"
ORR{} -> String
"ORR"
STR{} -> String
"STR"
STLR{} -> String
"STLR"
LDR{} -> String
"LDR"
LDAR{} -> String
"LDAR"
CSET{} -> String
"CSET"
CBZ{} -> String
"CBZ"
CBNZ{} -> String
"CBNZ"
J{} -> String
"J"
J_TBL {} -> String
"J_TBL"
B{} -> String
"B"
BL{} -> String
"BL"
BCOND{} -> String
"BCOND"
DMBISH{} -> String
"DMBISH"
FMOV{} -> String
"FMOV"
FCVT{} -> String
"FCVT"
SCVTF{} -> String
"SCVTF"
FCVTZS{} -> String
"FCVTZS"
FABS{} -> String
"FABS"
FSQRT{} -> String
"FSQRT"
FMIN {} -> String
"FMIN"
FMAX {} -> String
"FMAX"
FMA FMASign
variant Operand
_ Operand
_ Operand
_ Operand
_ ->
case FMASign
variant of
FMASign
FMAdd -> String
"FMADD"
FMASign
FMSub -> String
"FMSUB"
FMASign
FNMAdd -> String
"FNMADD"
FMASign
FNMSub -> String
"FNMSUB"
data Target
= TBlock BlockId
| TLabel CLabel
| TReg Reg
deriving (Target -> Target -> Bool
(Target -> Target -> Bool)
-> (Target -> Target -> Bool) -> Eq Target
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Target -> Target -> Bool
== :: Target -> Target -> Bool
$c/= :: Target -> Target -> Bool
/= :: Target -> Target -> Bool
Eq, Eq Target
Eq Target =>
(Target -> Target -> Ordering)
-> (Target -> Target -> Bool)
-> (Target -> Target -> Bool)
-> (Target -> Target -> Bool)
-> (Target -> Target -> Bool)
-> (Target -> Target -> Target)
-> (Target -> Target -> Target)
-> Ord Target
Target -> Target -> Bool
Target -> Target -> Ordering
Target -> Target -> Target
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Target -> Target -> Ordering
compare :: Target -> Target -> Ordering
$c< :: Target -> Target -> Bool
< :: Target -> Target -> Bool
$c<= :: Target -> Target -> Bool
<= :: Target -> Target -> Bool
$c> :: Target -> Target -> Bool
> :: Target -> Target -> Bool
$c>= :: Target -> Target -> Bool
>= :: Target -> Target -> Bool
$cmax :: Target -> Target -> Target
max :: Target -> Target -> Target
$cmin :: Target -> Target -> Target
min :: Target -> Target -> Target
Ord)
data ExtMode
= EUXTB | EUXTH | EUXTW | EUXTX
| ESXTB | ESXTH | ESXTW | ESXTX
deriving (ExtMode -> ExtMode -> Bool
(ExtMode -> ExtMode -> Bool)
-> (ExtMode -> ExtMode -> Bool) -> Eq ExtMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ExtMode -> ExtMode -> Bool
== :: ExtMode -> ExtMode -> Bool
$c/= :: ExtMode -> ExtMode -> Bool
/= :: ExtMode -> ExtMode -> Bool
Eq, Int -> ExtMode -> String -> String
[ExtMode] -> String -> String
ExtMode -> String
(Int -> ExtMode -> String -> String)
-> (ExtMode -> String)
-> ([ExtMode] -> String -> String)
-> Show ExtMode
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ExtMode -> String -> String
showsPrec :: Int -> ExtMode -> String -> String
$cshow :: ExtMode -> String
show :: ExtMode -> String
$cshowList :: [ExtMode] -> String -> String
showList :: [ExtMode] -> String -> String
Show)
data ShiftMode
= SLSL | SLSR | SASR | SROR
deriving (ShiftMode -> ShiftMode -> Bool
(ShiftMode -> ShiftMode -> Bool)
-> (ShiftMode -> ShiftMode -> Bool) -> Eq ShiftMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ShiftMode -> ShiftMode -> Bool
== :: ShiftMode -> ShiftMode -> Bool
$c/= :: ShiftMode -> ShiftMode -> Bool
/= :: ShiftMode -> ShiftMode -> Bool
Eq, Int -> ShiftMode -> String -> String
[ShiftMode] -> String -> String
ShiftMode -> String
(Int -> ShiftMode -> String -> String)
-> (ShiftMode -> String)
-> ([ShiftMode] -> String -> String)
-> Show ShiftMode
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> ShiftMode -> String -> String
showsPrec :: Int -> ShiftMode -> String -> String
$cshow :: ShiftMode -> String
show :: ShiftMode -> String
$cshowList :: [ShiftMode] -> String -> String
showList :: [ShiftMode] -> String -> String
Show)
type ExtShift = Int
type RegShift = Int
data Operand
= OpReg Width Reg
| OpRegExt Width Reg ExtMode ExtShift
| OpRegShift Width Reg ShiftMode RegShift
| OpImm Imm
| OpImmShift Imm ShiftMode RegShift
| OpAddr AddrMode
deriving (Operand -> Operand -> Bool
(Operand -> Operand -> Bool)
-> (Operand -> Operand -> Bool) -> Eq Operand
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Operand -> Operand -> Bool
== :: Operand -> Operand -> Bool
$c/= :: Operand -> Operand -> Bool
/= :: Operand -> Operand -> Bool
Eq, Int -> Operand -> String -> String
[Operand] -> String -> String
Operand -> String
(Int -> Operand -> String -> String)
-> (Operand -> String)
-> ([Operand] -> String -> String)
-> Show Operand
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Operand -> String -> String
showsPrec :: Int -> Operand -> String -> String
$cshow :: Operand -> String
show :: Operand -> String
$cshowList :: [Operand] -> String -> String
showList :: [Operand] -> String -> String
Show)
opReg :: Width -> Reg -> Operand
opReg :: Width -> Reg -> Operand
opReg = Width -> Reg -> Operand
OpReg
sp, ip0 :: Operand
sp :: Operand
sp = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
31))
ip0 :: Operand
ip0 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
16))
_x :: Int -> Operand
_x :: Int -> Operand
_x Int
i = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
i))
x0, x1, x2, x3, x4, x5, x6, x7 :: Operand
x8, x9, x10, x11, x12, x13, x14, x15 :: Operand
x16, x17, x18, x19, x20, x21, x22, x23 :: Operand
x24, x25, x26, x27, x28, x29, x30, x31 :: Operand
x0 :: Operand
x0 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
0))
x1 :: Operand
x1 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
1))
x2 :: Operand
x2 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
2))
x3 :: Operand
x3 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
3))
x4 :: Operand
x4 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
4))
x5 :: Operand
x5 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
5))
x6 :: Operand
x6 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
6))
x7 :: Operand
x7 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
7))
x8 :: Operand
x8 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
8))
x9 :: Operand
x9 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
9))
x10 :: Operand
x10 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
10))
x11 :: Operand
x11 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
11))
x12 :: Operand
x12 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
12))
x13 :: Operand
x13 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
13))
x14 :: Operand
x14 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
14))
x15 :: Operand
x15 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
15))
x16 :: Operand
x16 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
16))
x17 :: Operand
x17 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
17))
x18 :: Operand
x18 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
18))
x19 :: Operand
x19 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
19))
x20 :: Operand
x20 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
20))
x21 :: Operand
x21 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
21))
x22 :: Operand
x22 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
22))
x23 :: Operand
x23 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
23))
x24 :: Operand
x24 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
24))
x25 :: Operand
x25 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
25))
x26 :: Operand
x26 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
26))
x27 :: Operand
x27 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
27))
x28 :: Operand
x28 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
28))
x29 :: Operand
x29 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
29))
x30 :: Operand
x30 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
30))
x31 :: Operand
x31 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
31))
_d :: Int -> Operand
_d :: Int -> Operand
_d = Width -> Reg -> Operand
OpReg Width
W64 (Reg -> Operand) -> (Int -> Reg) -> Int -> Operand
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RealReg -> Reg
RegReal (RealReg -> Reg) -> (Int -> RealReg) -> Int -> Reg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> RealReg
RealRegSingle
d0, d1, d2, d3, d4, d5, d6, d7 :: Operand
d8, d9, d10, d11, d12, d13, d14, d15 :: Operand
d16, d17, d18, d19, d20, d21, d22, d23 :: Operand
d24, d25, d26, d27, d28, d29, d30, d31 :: Operand
d0 :: Operand
d0 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
32))
d1 :: Operand
d1 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
33))
d2 :: Operand
d2 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
34))
d3 :: Operand
d3 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
35))
d4 :: Operand
d4 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
36))
d5 :: Operand
d5 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
37))
d6 :: Operand
d6 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
38))
d7 :: Operand
d7 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
39))
d8 :: Operand
d8 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
40))
d9 :: Operand
d9 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
41))
d10 :: Operand
d10 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
42))
d11 :: Operand
d11 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
43))
d12 :: Operand
d12 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
44))
d13 :: Operand
d13 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
45))
d14 :: Operand
d14 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
46))
d15 :: Operand
d15 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
47))
d16 :: Operand
d16 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
48))
d17 :: Operand
d17 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
49))
d18 :: Operand
d18 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
50))
d19 :: Operand
d19 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
51))
d20 :: Operand
d20 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
52))
d21 :: Operand
d21 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
53))
d22 :: Operand
d22 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
54))
d23 :: Operand
d23 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
55))
d24 :: Operand
d24 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
56))
d25 :: Operand
d25 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
57))
d26 :: Operand
d26 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
58))
d27 :: Operand
d27 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
59))
d28 :: Operand
d28 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
60))
d29 :: Operand
d29 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
61))
d30 :: Operand
d30 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
62))
d31 :: Operand
d31 = Width -> Reg -> Operand
OpReg Width
W64 (RealReg -> Reg
RegReal (Int -> RealReg
RealRegSingle Int
63))
opRegUExt :: Width -> Reg -> Operand
opRegUExt :: Width -> Reg -> Operand
opRegUExt Width
W64 Reg
r = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
W64 Reg
r ExtMode
EUXTX Int
0
opRegUExt Width
W32 Reg
r = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
W32 Reg
r ExtMode
EUXTW Int
0
opRegUExt Width
W16 Reg
r = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
W16 Reg
r ExtMode
EUXTH Int
0
opRegUExt Width
W8 Reg
r = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
W8 Reg
r ExtMode
EUXTB Int
0
opRegUExt Width
w Reg
_r = String -> SDoc -> Operand
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"opRegUExt" (Width -> SDoc
forall a. Outputable a => a -> SDoc
ppr Width
w)
opRegSExt :: Width -> Reg -> Operand
opRegSExt :: Width -> Reg -> Operand
opRegSExt Width
W64 Reg
r = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
W64 Reg
r ExtMode
ESXTX Int
0
opRegSExt Width
W32 Reg
r = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
W32 Reg
r ExtMode
ESXTW Int
0
opRegSExt Width
W16 Reg
r = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
W16 Reg
r ExtMode
ESXTH Int
0
opRegSExt Width
W8 Reg
r = Width -> Reg -> ExtMode -> Int -> Operand
OpRegExt Width
W8 Reg
r ExtMode
ESXTB Int
0
opRegSExt Width
w Reg
_r = String -> SDoc -> Operand
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"opRegSExt" (Width -> SDoc
forall a. Outputable a => a -> SDoc
ppr Width
w)