apple-0.3.0.0: src/Asm/Aarch64/P.hs
module Asm.Aarch64.P ( gallocFrame, gallocOn ) where
import Asm.Aarch64
import Asm.Aarch64.Fr
import Asm.Ar.P
import Asm.G
import Asm.LI
import qualified Data.IntMap as IM
import qualified Data.Set as S
gallocFrame :: Int -- ^ int supply for spilling
-> [AArch64 AbsReg FAbsReg F2Abs ()] -> [AArch64 AReg FAReg F2Reg ()]
gallocFrame u = frameC . mkIntervals . galloc u
galloc :: Int -> [AArch64 AbsReg FAbsReg F2Abs ()] -> [AArch64 AReg FAReg F2Reg ()]
galloc u isns = frame clob'd (fmap (mapR ((regs IM.!).toInt).mapFR ((fregs IM.!).fToInt).mapF2 (simd2.(fregs IM.!).f2ToInt)) isns')
where (regs, fregs, isns') = gallocOn u (isns++[Ret ()])
clob'd = S.fromList $ IM.elems regs
{-# SCC frame #-}
frame :: S.Set AReg -> [AArch64 AReg FAReg F2Reg ()] -> [AArch64 AReg FAReg F2Reg ()]
frame clob asms = pre++asms++post++[Ret ()] where
pre=pus clobs; post=pos clobs
-- https://developer.arm.com/documentation/102374/0101/Procedure-Call-Standard
clobs = S.toList (clob `S.intersection` S.fromList [X18 .. X28])
gallocOn :: Int -> [AArch64 AbsReg FAbsReg F2Abs ()] -> (IM.IntMap AReg, IM.IntMap FAReg, [AArch64 AbsReg FAbsReg F2Abs ()])
gallocOn u = go u 0 pres
where go uϵ offs pres' isns = rmaps
where rmaps = case (regsM, fregsM) of
(Right regs, Right fregs) -> (regs, fregs, init isns)
-- https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Respect-the-purpose-of-specific-CPU-registers
regsM = alloc aIsns (filter (/= X18) [X0 .. X28]) (IM.keysSet pres') pres'
fregsM = allocF aFIsns [D0 .. D30] (IM.keysSet preFs) preFs
(aIsns, aFIsns) = bundle isns
pres :: IM.IntMap AReg
pres = IM.fromList [(0, X0), (1, X1), (2, X2), (3, X3), (4, X4), (5, X5), (6, X6), (7, X7), (8, X30), (9, SP), (18, X29)]
preFs :: IM.IntMap FAReg
preFs = IM.fromList [(10, D0), (11, D1), (12, D2), (13, D3), (14, D4), (15, D5), (16, D6), (17, D7)]