{-# LANGUAGE FlexibleContexts #-}
module LibRISCV.Effects.Operations.Default.Machine.Register where
import Control.Monad (unless)
import Data.Array.IO (
MArray (newArray),
getElems,
readArray,
writeArray,
)
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import Data.Word (Word32)
import LibRISCV
data RegisterFile t a = RegisterFile
{ forall (t :: * -> * -> *) a. RegisterFile t a -> IORef Word32
pc :: IORef Word32
, forall (t :: * -> * -> *) a. RegisterFile t a -> t RegIdx a
regs :: t RegIdx a
}
mkRegFile :: (MArray t a IO) => a -> IO (RegisterFile t a)
mkRegFile :: forall (t :: * -> * -> *) a.
MArray t a IO =>
a -> IO (RegisterFile t a)
mkRegFile a
defValue = IORef Word32 -> t RegIdx a -> RegisterFile t a
forall (t :: * -> * -> *) a.
IORef Word32 -> t RegIdx a -> RegisterFile t a
RegisterFile (IORef Word32 -> t RegIdx a -> RegisterFile t a)
-> IO (IORef Word32) -> IO (t RegIdx a -> RegisterFile t a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word32 -> IO (IORef Word32)
forall a. a -> IO (IORef a)
newIORef Word32
0 IO (t RegIdx a -> RegisterFile t a)
-> IO (t RegIdx a) -> IO (RegisterFile t a)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (RegIdx, RegIdx) -> a -> IO (t RegIdx a)
forall i. Ix i => (i, i) -> a -> IO (t i a)
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
(i, i) -> e -> m (a i e)
newArray (RegIdx
forall a. Bounded a => a
minBound, RegIdx
forall a. Bounded a => a
maxBound) a
defValue
dumpRegs :: (MArray t a IO) => (a -> ShowS) -> RegisterFile t a -> IO String
dumpRegs :: forall (t :: * -> * -> *) a.
MArray t a IO =>
(a -> ShowS) -> RegisterFile t a -> IO String
dumpRegs a -> ShowS
sh =
([a] -> String) -> IO [a] -> IO String
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( ((RegIdx, a) -> ShowS) -> String -> [(RegIdx, a)] -> String
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(RegIdx
a, a
v) String
s -> RegIdx -> String
forall a. Show a => a -> String
show RegIdx
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\t= 0x" String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> ShowS
sh a
v String
"\n" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s) String
""
([(RegIdx, a)] -> String)
-> ([a] -> [(RegIdx, a)]) -> [a] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RegIdx] -> [a] -> [(RegIdx, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [(RegIdx
forall a. Bounded a => a
minBound :: RegIdx) .. RegIdx
forall a. Bounded a => a
maxBound]
)
(IO [a] -> IO String)
-> (RegisterFile t a -> IO [a]) -> RegisterFile t a -> IO String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t RegIdx a -> IO [a]
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> m [e]
getElems
(t RegIdx a -> IO [a])
-> (RegisterFile t a -> t RegIdx a) -> RegisterFile t a -> IO [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegisterFile t a -> t RegIdx a
forall (t :: * -> * -> *) a. RegisterFile t a -> t RegIdx a
regs
readRegister :: (MArray t a IO) => RegisterFile t a -> RegIdx -> IO a
readRegister :: forall (t :: * -> * -> *) a.
MArray t a IO =>
RegisterFile t a -> RegIdx -> IO a
readRegister = t RegIdx a -> RegIdx -> IO a
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> m e
readArray (t RegIdx a -> RegIdx -> IO a)
-> (RegisterFile t a -> t RegIdx a)
-> RegisterFile t a
-> RegIdx
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegisterFile t a -> t RegIdx a
forall (t :: * -> * -> *) a. RegisterFile t a -> t RegIdx a
regs
writeRegister :: (MArray t a IO) => RegisterFile t a -> RegIdx -> a -> IO ()
writeRegister :: forall (t :: * -> * -> *) a.
MArray t a IO =>
RegisterFile t a -> RegIdx -> a -> IO ()
writeRegister RegisterFile{regs :: forall (t :: * -> * -> *) a. RegisterFile t a -> t RegIdx a
regs = t RegIdx a
r} RegIdx
idx a
val = Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (RegIdx
idx RegIdx -> RegIdx -> Bool
forall a. Eq a => a -> a -> Bool
== RegIdx
Zero) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ t RegIdx a -> RegIdx -> a -> IO ()
forall (a :: * -> * -> *) e (m :: * -> *) i.
(MArray a e m, Ix i) =>
a i e -> i -> e -> m ()
writeArray t RegIdx a
r RegIdx
idx a
val
readPC :: RegisterFile t a -> IO Word32
readPC :: forall (t :: * -> * -> *) a. RegisterFile t a -> IO Word32
readPC = IORef Word32 -> IO Word32
forall a. IORef a -> IO a
readIORef (IORef Word32 -> IO Word32)
-> (RegisterFile t a -> IORef Word32)
-> RegisterFile t a
-> IO Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegisterFile t a -> IORef Word32
forall (t :: * -> * -> *) a. RegisterFile t a -> IORef Word32
pc
writePC :: RegisterFile t a -> Word32 -> IO ()
writePC :: forall (t :: * -> * -> *) a. RegisterFile t a -> Word32 -> IO ()
writePC = IORef Word32 -> Word32 -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef (IORef Word32 -> Word32 -> IO ())
-> (RegisterFile t a -> IORef Word32)
-> RegisterFile t a
-> Word32
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegisterFile t a -> IORef Word32
forall (t :: * -> * -> *) a. RegisterFile t a -> IORef Word32
pc