module GHC.CmmToAsm.SPARC.AddrMode (
        AddrMode(..),
        addrOffset
)

where

import GHC.Prelude

import GHC.CmmToAsm.SPARC.Imm
import GHC.CmmToAsm.SPARC.Base
import GHC.Platform.Reg

-- addressing modes ------------------------------------------------------------

-- | Represents a memory address in an instruction.
--      Being a RISC machine, the SPARC addressing modes are very regular.
--
data AddrMode
        = AddrRegReg    Reg Reg         -- addr = r1 + r2
        | AddrRegImm    Reg Imm         -- addr = r1 + imm


-- | Add an integer offset to the address in an AddrMode.
--
addrOffset :: AddrMode -> Int -> Maybe AddrMode
addrOffset :: AddrMode -> Int -> Maybe AddrMode
addrOffset AddrMode
addr Int
off
  = case AddrMode
addr of
      AddrRegImm Reg
r (ImmInt Int
n)
       | forall a. Integral a => a -> Bool
fits13Bits Int
n2 -> forall a. a -> Maybe a
Just (Reg -> Imm -> AddrMode
AddrRegImm Reg
r (Int -> Imm
ImmInt Int
n2))
       | Bool
otherwise     -> forall a. Maybe a
Nothing
       where n2 :: Int
n2 = Int
n forall a. Num a => a -> a -> a
+ Int
off

      AddrRegImm Reg
r (ImmInteger Integer
n)
       | forall a. Integral a => a -> Bool
fits13Bits Integer
n2 -> forall a. a -> Maybe a
Just (Reg -> Imm -> AddrMode
AddrRegImm Reg
r (Int -> Imm
ImmInt (forall a. Num a => Integer -> a
fromInteger Integer
n2)))
       | Bool
otherwise     -> forall a. Maybe a
Nothing
       where n2 :: Integer
n2 = Integer
n forall a. Num a => a -> a -> a
+ forall a. Integral a => a -> Integer
toInteger Int
off

      AddrRegReg Reg
r (RegReal (RealRegSingle Int
0))
       | forall a. Integral a => a -> Bool
fits13Bits Int
off -> forall a. a -> Maybe a
Just (Reg -> Imm -> AddrMode
AddrRegImm Reg
r (Int -> Imm
ImmInt Int
off))
       | Bool
otherwise     -> forall a. Maybe a
Nothing

      AddrMode
_ -> forall a. Maybe a
Nothing