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

where

import GhcPrelude

import SPARC.Imm
import SPARC.Base
import 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 addr :: AddrMode
addr off :: Int
off
  = case AddrMode
addr of
      AddrRegImm r :: Reg
r (ImmInt n :: Int
n)
       | Int -> Bool
forall a. Integral a => a -> Bool
fits13Bits Int
n2 -> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (Reg -> Imm -> AddrMode
AddrRegImm Reg
r (Int -> Imm
ImmInt Int
n2))
       | Bool
otherwise     -> Maybe AddrMode
forall a. Maybe a
Nothing
       where n2 :: Int
n2 = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off

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

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

      _ -> Maybe AddrMode
forall a. Maybe a
Nothing