module GHC.CmmToAsm.SPARC.CodeGen.Amode (
getAmode
)
where
import GHC.Prelude
import {-# SOURCE #-} GHC.CmmToAsm.SPARC.CodeGen.Gen32
import GHC.CmmToAsm.SPARC.CodeGen.Base
import GHC.CmmToAsm.SPARC.AddrMode
import GHC.CmmToAsm.SPARC.Imm
import GHC.CmmToAsm.SPARC.Instr
import GHC.CmmToAsm.SPARC.Regs
import GHC.CmmToAsm.SPARC.Base
import GHC.CmmToAsm.Monad
import GHC.CmmToAsm.Format
import GHC.Cmm
import GHC.Data.OrdList
getAmode
:: CmmExpr
-> NatM Amode
getAmode :: CmmExpr -> NatM Amode
getAmode tree :: CmmExpr
tree@(CmmRegOff CmmReg
_ Int
_)
= do Platform
platform <- NatM Platform
getPlatform
CmmExpr -> NatM Amode
getAmode (Platform -> CmmExpr -> CmmExpr
mangleIndexTree Platform
platform CmmExpr
tree)
getAmode (CmmMachOp (MO_Sub Width
_) [CmmExpr
x, CmmLit (CmmInt Integer
i Width
_)])
| Integer -> Bool
forall a. Integral a => a -> Bool
fits13Bits (-Integer
i)
= do
(Reg
reg, InstrBlock
code) <- CmmExpr -> NatM (Reg, InstrBlock)
getSomeReg CmmExpr
x
let
off :: Imm
off = Int -> Imm
ImmInt (-(Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
i))
Amode -> NatM Amode
forall (m :: * -> *) a. Monad m => a -> m a
return (AddrMode -> InstrBlock -> Amode
Amode (Reg -> Imm -> AddrMode
AddrRegImm Reg
reg Imm
off) InstrBlock
code)
getAmode (CmmMachOp (MO_Add Width
_) [CmmExpr
x, CmmLit (CmmInt Integer
i Width
_)])
| Integer -> Bool
forall a. Integral a => a -> Bool
fits13Bits Integer
i
= do
(Reg
reg, InstrBlock
code) <- CmmExpr -> NatM (Reg, InstrBlock)
getSomeReg CmmExpr
x
let
off :: Imm
off = Int -> Imm
ImmInt (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
i)
Amode -> NatM Amode
forall (m :: * -> *) a. Monad m => a -> m a
return (AddrMode -> InstrBlock -> Amode
Amode (Reg -> Imm -> AddrMode
AddrRegImm Reg
reg Imm
off) InstrBlock
code)
getAmode (CmmMachOp (MO_Add Width
_) [CmmExpr
x, CmmExpr
y])
= do
(Reg
regX, InstrBlock
codeX) <- CmmExpr -> NatM (Reg, InstrBlock)
getSomeReg CmmExpr
x
(Reg
regY, InstrBlock
codeY) <- CmmExpr -> NatM (Reg, InstrBlock)
getSomeReg CmmExpr
y
let
code :: InstrBlock
code = InstrBlock
codeX InstrBlock -> InstrBlock -> InstrBlock
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` InstrBlock
codeY
Amode -> NatM Amode
forall (m :: * -> *) a. Monad m => a -> m a
return (AddrMode -> InstrBlock -> Amode
Amode (Reg -> Reg -> AddrMode
AddrRegReg Reg
regX Reg
regY) InstrBlock
code)
getAmode (CmmLit CmmLit
lit)
= do
let imm__2 :: Imm
imm__2 = CmmLit -> Imm
litToImm CmmLit
lit
Reg
tmp1 <- Format -> NatM Reg
getNewRegNat Format
II32
Reg
tmp2 <- Format -> NatM Reg
getNewRegNat Format
II32
let code :: InstrBlock
code = [Instr] -> InstrBlock
forall a. [a] -> OrdList a
toOL [ Imm -> Reg -> Instr
SETHI (Imm -> Imm
HI Imm
imm__2) Reg
tmp1
, Bool -> Reg -> RI -> Reg -> Instr
OR Bool
False Reg
tmp1 (Imm -> RI
RIImm (Imm -> Imm
LO Imm
imm__2)) Reg
tmp2]
Amode -> NatM Amode
forall (m :: * -> *) a. Monad m => a -> m a
return (AddrMode -> InstrBlock -> Amode
Amode (Reg -> Reg -> AddrMode
AddrRegReg Reg
tmp2 Reg
g0) InstrBlock
code)
getAmode CmmExpr
other
= do
(Reg
reg, InstrBlock
code) <- CmmExpr -> NatM (Reg, InstrBlock)
getSomeReg CmmExpr
other
let
off :: Imm
off = Int -> Imm
ImmInt Int
0
Amode -> NatM Amode
forall (m :: * -> *) a. Monad m => a -> m a
return (AddrMode -> InstrBlock -> Amode
Amode (Reg -> Imm -> AddrMode
AddrRegImm Reg
reg Imm
off) InstrBlock
code)