module GHC.CmmToAsm.Reg.Linear.AArch64 where
import GHC.Prelude
import GHC.CmmToAsm.AArch64.Regs
import GHC.Platform.Reg.Class
import GHC.Platform.Reg
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Platform
import Data.Word
import GHC.Stack
data FreeRegs = FreeRegs !Word32 !Word32
instance Show FreeRegs where
show :: FreeRegs -> String
show (FreeRegs Word32
g Word32
f) = String
"FreeRegs: " forall a. [a] -> [a] -> [a]
++ Word32 -> String
showBits Word32
g forall a. [a] -> [a] -> [a]
++ String
"; " forall a. [a] -> [a] -> [a]
++ Word32 -> String
showBits Word32
f
instance Outputable FreeRegs where
ppr :: FreeRegs -> SDoc
ppr (FreeRegs Word32
g Word32
f) = String -> SDoc
text String
" " SDoc -> SDoc -> SDoc
<+> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Int
i SDoc
x -> Int -> SDoc
pad_int Int
i SDoc -> SDoc -> SDoc
<+> SDoc
x) (String -> SDoc
text String
"") [Int
0..Int
31]
SDoc -> SDoc -> SDoc
$$ String -> SDoc
text String
"GPR" SDoc -> SDoc -> SDoc
<+> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Int
i SDoc
x -> forall {a}. Bits a => a -> Int -> SDoc
show_bit Word32
g Int
i SDoc -> SDoc -> SDoc
<+> SDoc
x) (String -> SDoc
text String
"") [Int
0..Int
31]
SDoc -> SDoc -> SDoc
$$ String -> SDoc
text String
"FPR" SDoc -> SDoc -> SDoc
<+> forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Int
i SDoc
x -> forall {a}. Bits a => a -> Int -> SDoc
show_bit Word32
f Int
i SDoc -> SDoc -> SDoc
<+> SDoc
x) (String -> SDoc
text String
"") [Int
0..Int
31]
where pad_int :: Int -> SDoc
pad_int Int
i | Int
i forall a. Ord a => a -> a -> Bool
< Int
10 = Char -> SDoc
char Char
' ' SDoc -> SDoc -> SDoc
<> Int -> SDoc
int Int
i
pad_int Int
i = Int -> SDoc
int Int
i
show_bit :: a -> Int -> SDoc
show_bit a
bits Int
bit | forall a. Bits a => a -> Int -> Bool
testBit a
bits Int
bit = String -> SDoc
text String
" "
show_bit a
_ Int
_ = String -> SDoc
text String
" x"
noFreeRegs :: FreeRegs
noFreeRegs :: FreeRegs
noFreeRegs = Word32 -> Word32 -> FreeRegs
FreeRegs Word32
0 Word32
0
showBits :: Word32 -> String
showBits :: Word32 -> String
showBits Word32
w = forall a b. (a -> b) -> [a] -> [b]
map (\Int
i -> if forall a. Bits a => a -> Int -> Bool
testBit Word32
w Int
i then Char
'1' else Char
'0') [Int
0..Int
31]
allocateReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs
allocateReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs
allocateReg (RealRegSingle Int
r) (FreeRegs Word32
g Word32
f)
| Int
r forall a. Ord a => a -> a -> Bool
> Int
31 Bool -> Bool -> Bool
&& forall a. Bits a => a -> Int -> Bool
testBit Word32
f (Int
r forall a. Num a => a -> a -> a
- Int
32) = Word32 -> Word32 -> FreeRegs
FreeRegs Word32
g (forall a. Bits a => a -> Int -> a
clearBit Word32
f (Int
r forall a. Num a => a -> a -> a
- Int
32))
| Int
r forall a. Ord a => a -> a -> Bool
< Int
32 Bool -> Bool -> Bool
&& forall a. Bits a => a -> Int -> Bool
testBit Word32
g Int
r = Word32 -> Word32 -> FreeRegs
FreeRegs (forall a. Bits a => a -> Int -> a
clearBit Word32
g Int
r) Word32
f
| Int
r forall a. Ord a => a -> a -> Bool
> Int
31 = forall a. String -> a
panic forall a b. (a -> b) -> a -> b
$ String
"Linear.AArch64.allocReg: double allocation of float reg v" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
r forall a. Num a => a -> a -> a
- Int
32) forall a. [a] -> [a] -> [a]
++ String
"; " forall a. [a] -> [a] -> [a]
++ Word32 -> String
showBits Word32
f
| Bool
otherwise = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Linear.AArch64.allocReg" forall a b. (a -> b) -> a -> b
$ String -> SDoc
text (String
"double allocation of gp reg x" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
r forall a. [a] -> [a] -> [a]
++ String
"; " forall a. [a] -> [a] -> [a]
++ Word32 -> String
showBits Word32
g)
allocateReg RealReg
_ FreeRegs
_ = forall a. String -> a
panic String
"Linear.AArch64.allocReg: bad reg"
getFreeRegs :: RegClass -> FreeRegs -> [RealReg]
getFreeRegs :: RegClass -> FreeRegs -> [RealReg]
getFreeRegs RegClass
cls (FreeRegs Word32
g Word32
f)
| RegClass
RcFloat <- RegClass
cls = []
| RegClass
RcDouble <- RegClass
cls = forall {t}. Bits t => Int -> t -> Int -> [RealReg]
go Int
32 Word32
f Int
31
| RegClass
RcInteger <- RegClass
cls = forall {t}. Bits t => Int -> t -> Int -> [RealReg]
go Int
0 Word32
g Int
18
where
go :: Int -> t -> Int -> [RealReg]
go Int
_ t
_ Int
i | Int
i forall a. Ord a => a -> a -> Bool
< Int
0 = []
go Int
off t
x Int
i | forall a. Bits a => a -> Int -> Bool
testBit t
x Int
i = Int -> RealReg
RealRegSingle (Int
off forall a. Num a => a -> a -> a
+ Int
i) forall a. a -> [a] -> [a]
: (Int -> t -> Int -> [RealReg]
go Int
off t
x forall a b. (a -> b) -> a -> b
$! Int
i forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise = Int -> t -> Int -> [RealReg]
go Int
off t
x forall a b. (a -> b) -> a -> b
$! Int
i forall a. Num a => a -> a -> a
- Int
1
initFreeRegs :: Platform -> FreeRegs
initFreeRegs :: Platform -> FreeRegs
initFreeRegs Platform
platform = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip HasCallStack => RealReg -> FreeRegs -> FreeRegs
releaseReg) FreeRegs
noFreeRegs (Platform -> [RealReg]
allocatableRegs Platform
platform)
releaseReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs
releaseReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs
releaseReg (RealRegSingle Int
r) (FreeRegs Word32
g Word32
f)
| Int
r forall a. Ord a => a -> a -> Bool
> Int
31 Bool -> Bool -> Bool
&& forall a. Bits a => a -> Int -> Bool
testBit Word32
f (Int
r forall a. Num a => a -> a -> a
- Int
32) = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Linear.AArch64.releaseReg" (String -> SDoc
text String
"can't release non-allocated reg v" SDoc -> SDoc -> SDoc
<> Int -> SDoc
int (Int
r forall a. Num a => a -> a -> a
- Int
32))
| Int
r forall a. Ord a => a -> a -> Bool
< Int
32 Bool -> Bool -> Bool
&& forall a. Bits a => a -> Int -> Bool
testBit Word32
g Int
r = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Linear.AArch64.releaseReg" (String -> SDoc
text String
"can't release non-allocated reg x" SDoc -> SDoc -> SDoc
<> Int -> SDoc
int Int
r)
| Int
r forall a. Ord a => a -> a -> Bool
> Int
31 = Word32 -> Word32 -> FreeRegs
FreeRegs Word32
g (forall a. Bits a => a -> Int -> a
setBit Word32
f (Int
r forall a. Num a => a -> a -> a
- Int
32))
| Bool
otherwise = Word32 -> Word32 -> FreeRegs
FreeRegs (forall a. Bits a => a -> Int -> a
setBit Word32
g Int
r) Word32
f
releaseReg RealReg
_ FreeRegs
_ = forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"Linear.AArch64.releaseReg" (String -> SDoc
text String
"bad reg")