{-# LANGUAGE DeriveGeneric #-}
{-# OPTIONS_GHC -Wno-missing-signatures #-}
{-# OPTIONS_GHC -Wno-name-shadowing #-}
{-# OPTIONS_GHC -Wno-partial-fields #-}

-- | Inspired by https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
module Wrench.Isa.RiscIv (
    RiscIvIsa (..),
    RiscIvSt (..),
    Register (..),
    MemRef (..),
) where

import Data.Bits (bit, shiftL, shiftR, (.&.), (.|.))
import Data.Default
import Data.Text qualified as T
import Relude
import Relude.Extra
import Text.Megaparsec (choice, getOffset, setOffset)
import Text.Megaparsec.Char (char, hspace, string)
import Wrench.Machine.Memory
import Wrench.Machine.Types (
    ByteSizeT (..),
    InitState (..),
    Inspectable (..),
    IoMem (..),
    Machine (..),
    MemOf,
    StateEnv (..),
    fromSign,
    halted,
 )
import Wrench.Machine.Word (fitSigned, i12, i13, i21, lShiftR, u20, u5)
import Wrench.Report
import Wrench.Report.View (withRenames)
import Wrench.Translator.Parser.Misc (comma, constantRef, eol', reference, referenceWithDirective, wordLiteral)
import Wrench.Translator.Parser.Types
import Wrench.Translator.Types

-- * ISA

data Register
    = Zero
    | Ra
    | Sp
    | Gp
    | Tp
    | T0
    | T1
    | T2
    | S0Fp
    | S1
    | A0
    | A1
    | A2
    | A3
    | A4
    | A5
    | A6
    | A7
    | S2
    | S3
    | S4
    | S5
    | S6
    | S7
    | S8
    | S9
    | S10
    | S11
    | T3
    | T4
    | T5
    | T6
    deriving (Int -> Register
Register -> Int
Register -> [Register]
Register -> Register
Register -> Register -> [Register]
Register -> Register -> Register -> [Register]
(Register -> Register)
-> (Register -> Register)
-> (Int -> Register)
-> (Register -> Int)
-> (Register -> [Register])
-> (Register -> Register -> [Register])
-> (Register -> Register -> [Register])
-> (Register -> Register -> Register -> [Register])
-> Enum Register
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Register -> Register
succ :: Register -> Register
$cpred :: Register -> Register
pred :: Register -> Register
$ctoEnum :: Int -> Register
toEnum :: Int -> Register
$cfromEnum :: Register -> Int
fromEnum :: Register -> Int
$cenumFrom :: Register -> [Register]
enumFrom :: Register -> [Register]
$cenumFromThen :: Register -> Register -> [Register]
enumFromThen :: Register -> Register -> [Register]
$cenumFromTo :: Register -> Register -> [Register]
enumFromTo :: Register -> Register -> [Register]
$cenumFromThenTo :: Register -> Register -> Register -> [Register]
enumFromThenTo :: Register -> Register -> Register -> [Register]
Enum, Register -> Register -> Bool
(Register -> Register -> Bool)
-> (Register -> Register -> Bool) -> Eq Register
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Register -> Register -> Bool
== :: Register -> Register -> Bool
$c/= :: Register -> Register -> Bool
/= :: Register -> Register -> Bool
Eq, (forall x. Register -> Rep Register x)
-> (forall x. Rep Register x -> Register) -> Generic Register
forall x. Rep Register x -> Register
forall x. Register -> Rep Register x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Register -> Rep Register x
from :: forall x. Register -> Rep Register x
$cto :: forall x. Rep Register x -> Register
to :: forall x. Rep Register x -> Register
Generic, ReadPrec [Register]
ReadPrec Register
Int -> ReadS Register
ReadS [Register]
(Int -> ReadS Register)
-> ReadS [Register]
-> ReadPrec Register
-> ReadPrec [Register]
-> Read Register
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Register
readsPrec :: Int -> ReadS Register
$creadList :: ReadS [Register]
readList :: ReadS [Register]
$creadPrec :: ReadPrec Register
readPrec :: ReadPrec Register
$creadListPrec :: ReadPrec [Register]
readListPrec :: ReadPrec [Register]
Read, Int -> Register -> String -> String
[Register] -> String -> String
Register -> String
(Int -> Register -> String -> String)
-> (Register -> String)
-> ([Register] -> String -> String)
-> Show Register
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Register -> String -> String
showsPrec :: Int -> Register -> String -> String
$cshow :: Register -> String
show :: Register -> String
$cshowList :: [Register] -> String -> String
showList :: [Register] -> String -> String
Show)

allRegisters :: [Register]
allRegisters =
    [ Register
Zero
    , Register
Ra
    , Register
Sp
    , Register
Gp
    , Register
Tp
    , Register
T0
    , Register
T1
    , Register
T2
    , Register
S0Fp
    , Register
S1
    , Register
A0
    , Register
A1
    , Register
A2
    , Register
A3
    , Register
A4
    , Register
A5
    , Register
A6
    , Register
A7
    , Register
S2
    , Register
S3
    , Register
S4
    , Register
S5
    , Register
S6
    , Register
S7
    , Register
S8
    , Register
S9
    , Register
S10
    , Register
S11
    , Register
T3
    , Register
T4
    , Register
T5
    , Register
T6
    ]

instance Hashable Register where
    hashWithSalt :: Int -> Register -> Int
hashWithSalt Int
salt = Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt (Int -> Int) -> (Register -> Int) -> Register -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Register -> Int
forall a. Enum a => a -> Int
fromEnum

instance (Default w) => Default (HashMap Register w) where
    def :: HashMap Register w
def = [Item (HashMap Register w)] -> HashMap Register w
forall l. IsList l => [Item l] -> l
fromList ([Item (HashMap Register w)] -> HashMap Register w)
-> [Item (HashMap Register w)] -> HashMap Register w
forall a b. (a -> b) -> a -> b
$ (Register -> (Register, w)) -> [Register] -> [(Register, w)]
forall a b. (a -> b) -> [a] -> [b]
map (,w
forall a. Default a => a
def) [Register]
allRegisters

data RiscIvIsa w l
    = -- | Add immediate: rd = rs1 + k
      Addi {forall w l. RiscIvIsa w l -> Register
rd, forall w l. RiscIvIsa w l -> Register
rs1 :: Register, forall w l. RiscIvIsa w l -> l
k :: l}
    | -- | Add: rd = rs1 + rs2
      Add {rd, rs1, forall w l. RiscIvIsa w l -> Register
rs2 :: Register}
    | -- | Subtract: rd = rs1 - rs2
      Sub {rd, rs1, rs2 :: Register}
    | -- | Multiply: rd = rs1 * rs2
      Mul {rd, rs1, rs2 :: Register}
    | -- | Multiply high: rd = (rs1 * rs2) >> (word size)
      Mulh {rd, rs1, rs2 :: Register}
    | -- | Divide: rd = rs1 / rs2
      Div {rd, rs1, rs2 :: Register}
    | -- | Remainder: rd = rs1 % rs2
      Rem {rd, rs1, rs2 :: Register}
    | -- | Logical shift left: rd = rs1 << rs2 (5 bit)
      Sll {rd, rs1, rs2 :: Register}
    | -- | Logical shift right: rd = rs1 >> rs2 (5 bit)
      Srl {rd, rs1, rs2 :: Register}
    | -- | Arithmetic shift right: rd = rs1 >> rs2 (5 bit)
      Sra {rd, rs1, rs2 :: Register}
    | -- | Bitwise AND: rd = rs1 & rs2
      And {rd, rs1, rs2 :: Register}
    | -- | Bitwise OR: rd = rs1 | rs2
      Or {rd, rs1, rs2 :: Register}
    | -- | Bitwise XOR: rd = rs1 ^ rs2
      Xor {rd, rs1, rs2 :: Register}
    | -- | Set less than immediate: rd = (rs1 < k) ? 1 : 0
      Slti {rd, rs1 :: Register, k :: l}
    | -- | Logical shift left immediate: rd = rs1 << k (5 bit)
      Slli {rd, rs1 :: Register, k :: l}
    | -- | Logical shift right immediate: rd = rs1 >>> k (5 bit)
      Srli {rd, rs1 :: Register, k :: l}
    | -- | Arithmetic shift right immediate: rd = rs1 >> k (5 bit)
      Srai {rd, rs1 :: Register, k :: l}
    | -- | Bitwise AND immediate: rd = rs1 & k
      Andi {rd, rs1 :: Register, k :: l}
    | -- | Bitwise OR immediate: rd = rs1 | k
      Ori {rd, rs1 :: Register, k :: l}
    | -- | Bitwise XOR immediate: rd = rs1 ^ k
      Xori {rd, rs1 :: Register, k :: l}
    | -- | Move: rd = rs
      Mv {rd, forall w l. RiscIvIsa w l -> Register
rs :: Register}
    | -- | Store word: M[offsetRs1] = rs2
      Sw {rs2 :: Register, forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 :: MemRef w}
    | -- | Store byte: M[offsetRs1] = rs2 (lower 8 bits)
      Sb {rs2 :: Register, offsetRs1 :: MemRef w}
    | -- | Load upper immediate: rd = k << 12
      Lui {rd :: Register, k :: l}
    | -- | Load word: rd = M[offsetRs1]
      Lw {rd :: Register, offsetRs1 :: MemRef w}
    | -- | Load byte (sign-extended): rd = signext(M[offsetRs1][7:0])
      Lb {rd :: Register, offsetRs1 :: MemRef w}
    | -- | Jump: PC = PC + k
      J {k :: l}
    | -- | Jump and Link: rd = PC + 4, PC += k
      Jal {rd :: Register, k :: l}
    | -- | Jump and link register: rd = PC + 4, PC = rs1 + k
      Jalr {rd, rs1 :: Register, k :: l}
    | -- | Branch if equal to zero: if rs1 == 0 then PC += k
      Beqz {rs1 :: Register, k :: l}
    | -- | Branch if not equal to zero: if rs1 /= 0 then PC += k
      Bnez {rs1 :: Register, k :: l}
    | -- | Branch if less than: if rs1 < rs2 then PC += k
      Blt {rs1, rs2 :: Register, k :: l}
    | -- | Branch if greater than or equal: if rs1 >= rs2 then PC += k
      Bge {rs1, rs2 :: Register, k :: l}
    | -- | Branch if less than (unsigned): if rs1 < rs2 then PC += k
      Bltu {rs1, rs2 :: Register, k :: l}
    | -- | Branch if greater than or equal (unsigned): if rs1 >= rs2 then PC += k
      Bgeu {rs1, rs2 :: Register, k :: l}
    | -- | Branch if equal: if rs1 == rs2 then PC += k
      Beq {rs1, rs2 :: Register, k :: l}
    | -- | Branch if not equal: if rs1 /= rs2 then PC += k
      Bne {rs1, rs2 :: Register, k :: l}
    | -- | Halt the machine
      Halt
    deriving (Int -> RiscIvIsa w l -> String -> String
[RiscIvIsa w l] -> String -> String
RiscIvIsa w l -> String
(Int -> RiscIvIsa w l -> String -> String)
-> (RiscIvIsa w l -> String)
-> ([RiscIvIsa w l] -> String -> String)
-> Show (RiscIvIsa w l)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall w l.
(Show w, Show l) =>
Int -> RiscIvIsa w l -> String -> String
forall w l. (Show w, Show l) => [RiscIvIsa w l] -> String -> String
forall w l. (Show w, Show l) => RiscIvIsa w l -> String
$cshowsPrec :: forall w l.
(Show w, Show l) =>
Int -> RiscIvIsa w l -> String -> String
showsPrec :: Int -> RiscIvIsa w l -> String -> String
$cshow :: forall w l. (Show w, Show l) => RiscIvIsa w l -> String
show :: RiscIvIsa w l -> String
$cshowList :: forall w l. (Show w, Show l) => [RiscIvIsa w l] -> String -> String
showList :: [RiscIvIsa w l] -> String -> String
Show)

-- * Parser

-- | Assembly names of the registers, in parser order (@s10@ before @s1@).
registerNames :: [(Text, Register)]
registerNames :: [(Text, Register)]
registerNames =
    [ (Text
"zero", Register
Zero)
    , (Text
"ra", Register
Ra)
    , (Text
"sp", Register
Sp)
    , (Text
"gp", Register
Gp)
    , (Text
"tp", Register
Tp)
    , (Text
"t0", Register
T0)
    , (Text
"t1", Register
T1)
    , (Text
"t2", Register
T2)
    , (Text
"s0", Register
S0Fp)
    , (Text
"fp", Register
S0Fp)
    , (Text
"s10", Register
S10)
    , (Text
"s11", Register
S11)
    , (Text
"s1", Register
S1)
    , (Text
"a0", Register
A0)
    , (Text
"a1", Register
A1)
    , (Text
"a2", Register
A2)
    , (Text
"a3", Register
A3)
    , (Text
"a4", Register
A4)
    , (Text
"a5", Register
A5)
    , (Text
"a6", Register
A6)
    , (Text
"a7", Register
A7)
    , (Text
"s2", Register
S2)
    , (Text
"s3", Register
S3)
    , (Text
"s4", Register
S4)
    , (Text
"s5", Register
S5)
    , (Text
"s6", Register
S6)
    , (Text
"s7", Register
S7)
    , (Text
"s8", Register
S8)
    , (Text
"s9", Register
S9)
    , (Text
"t3", Register
T3)
    , (Text
"t4", Register
T4)
    , (Text
"t5", Register
T5)
    , (Text
"t6", Register
T6)
    ]

register :: Parser Register
register :: Parser Register
register = [Parser Register] -> Parser Register
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [Tokens String -> ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string (Text -> String
forall a. ToString a => a -> String
toString Text
name) ParsecT Void String Identity (Tokens String)
-> Parser Register -> Parser Register
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Parser Register
forall a. a -> ParsecT Void String Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Register
r | (Text
name, Register
r) <- [(Text, Register)]
registerNames]

data MemRef w = MemRef {forall w. MemRef w -> w
mrOffset :: w, forall w. MemRef w -> Register
mrReg :: Register} deriving (Int -> MemRef w -> String -> String
[MemRef w] -> String -> String
MemRef w -> String
(Int -> MemRef w -> String -> String)
-> (MemRef w -> String)
-> ([MemRef w] -> String -> String)
-> Show (MemRef w)
forall w. Show w => Int -> MemRef w -> String -> String
forall w. Show w => [MemRef w] -> String -> String
forall w. Show w => MemRef w -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall w. Show w => Int -> MemRef w -> String -> String
showsPrec :: Int -> MemRef w -> String -> String
$cshow :: forall w. Show w => MemRef w -> String
show :: MemRef w -> String
$cshowList :: forall w. Show w => [MemRef w] -> String -> String
showList :: [MemRef w] -> String -> String
Show)

-- | Width of the signed offset field shared by the I-type (@lw@, @lb@) and
-- S-type (@sw@, @sb@) encodings.
memRefOffsetBits :: Int
memRefOffsetBits :: Int
memRefOffsetBits = Int
12

requireSignedField :: (IsWord w) => Int -> Int -> w -> Parser w
requireSignedField :: forall w. IsWord w => Int -> Int -> w -> Parser w
requireSignedField Int
fieldBits Int
operandPos w
value
    | w
value w -> w -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> w -> w
forall w. IsWord w => Int -> w -> w
fitSigned Int
fieldBits w
value = w -> ParsecT Void String Identity w
forall a. a -> ParsecT Void String Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return w
value
    | Bool
otherwise = do
        Int -> ParsecT Void String Identity ()
forall e s (m :: * -> *). MonadParsec e s m => Int -> m ()
setOffset Int
operandPos
        String -> ParsecT Void String Identity w
forall a. String -> ParsecT Void String Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> ParsecT Void String Identity w)
-> String -> ParsecT Void String Identity w
forall a b. (a -> b) -> a -> b
$
            [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                [ String
"offset "
                , w -> String
forall b a. (Show a, IsString b) => a -> b
show w
value
                , String
" doesn't fit the "
                , Int -> String
forall b a. (Show a, IsString b) => a -> b
show Int
fieldBits
                , String
"-bit signed field of a 4 byte instruction, expected "
                , Integer -> String
forall b a. (Show a, IsString b) => a -> b
show Integer
lo
                , String
".."
                , Integer -> String
forall b a. (Show a, IsString b) => a -> b
show Integer
hi
                ]
    where
        hi :: Integer
hi = Int -> Integer
forall a. Bits a => Int -> a
bit (Int
fieldBits Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1 :: Integer
        lo :: Integer
lo = Integer -> Integer
forall a. Num a => a -> a
negate (Int -> Integer
forall a. Bits a => Int -> a
bit (Int
fieldBits Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) :: Integer

memRef :: (IsWord w) => Parser (MemRef w)
memRef :: forall w. IsWord w => Parser (MemRef w)
memRef = [ParsecT Void String Identity (MemRef w)]
-> ParsecT Void String Identity (MemRef w)
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [ParsecT Void String Identity (MemRef w)
regWithOffset, Parser Register
register Parser Register
-> (Register -> MemRef w)
-> ParsecT Void String Identity (MemRef w)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> w -> Register -> MemRef w
forall w. w -> Register -> MemRef w
MemRef w
0]
    where
        regWithOffset :: ParsecT Void String Identity (MemRef w)
regWithOffset = do
            operandPos <- ParsecT Void String Identity Int
forall e s (m :: * -> *). MonadParsec e s m => m Int
getOffset
            offset <- wordLiteral
            void $ char '('
            mrReg <- register
            void $ char ')'
            mrOffset <- requireSignedField memRefOffsetBits operandPos offset
            return MemRef{mrOffset, mrReg}

instance CommentStart (RiscIvIsa _a _b) where
    commentStart :: String
commentStart = String
";"

instance (IsWord w) => MnemonicParser (RiscIvIsa w (Ref w)) where
    mnemonic :: Parser (RiscIvIsa w (Ref w))
mnemonic =
        ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace ParsecT Void String Identity ()
-> Parser (RiscIvIsa w (Ref w)) -> Parser (RiscIvIsa w (Ref w))
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser (RiscIvIsa w (Ref w))
cmd Parser (RiscIvIsa w (Ref w))
-> ParsecT Void String Identity () -> Parser (RiscIvIsa w (Ref w))
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> ParsecT Void String Identity ()
eol' (forall m. CommentStart m => String
commentStart @(RiscIvIsa _ _))
        where
            cmd :: Parser (RiscIvIsa w (Ref w))
cmd =
                [Parser (RiscIvIsa w (Ref w))] -> Parser (RiscIvIsa w (Ref w))
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
                    [ String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"addi" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Addi Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
referenceWithDirective
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"slti" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Slti Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
referenceWithDirective
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"add" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Add Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"sub" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Sub Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"mul" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Mul Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"mulh" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Mulh Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"div" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Div Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"rem" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Rem Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"slli" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Slli Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"sll" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Sll Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"srli" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Srli Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"srl" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Srl Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"srai" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Srai Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
constantRef
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"sra" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Sra Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"andi" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Andi Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
referenceWithDirective
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"and" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
And Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"ori" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Ori Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
referenceWithDirective
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"or" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Or Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"xori" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Xori Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
referenceWithDirective
                    , String
-> (Register -> Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"xor" Register -> Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> Register -> RiscIvIsa w l
Xor Parser Register
register Parser Register
register Parser Register
register
                    , String
-> (Register -> Register -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"mv" Register -> Register -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> RiscIvIsa w l
Mv Parser Register
register Parser Register
register
                    , String
-> (Register -> MemRef w -> RiscIvIsa w (Ref w))
-> Parser Register
-> ParsecT Void String Identity (MemRef w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"sw" Register -> MemRef w -> RiscIvIsa w (Ref w)
forall w l. Register -> MemRef w -> RiscIvIsa w l
Sw Parser Register
register ParsecT Void String Identity (MemRef w)
forall w. IsWord w => Parser (MemRef w)
memRef
                    , String
-> (Register -> MemRef w -> RiscIvIsa w (Ref w))
-> Parser Register
-> ParsecT Void String Identity (MemRef w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"sb" Register -> MemRef w -> RiscIvIsa w (Ref w)
forall w l. Register -> MemRef w -> RiscIvIsa w l
Sb Parser Register
register ParsecT Void String Identity (MemRef w)
forall w. IsWord w => Parser (MemRef w)
memRef
                    , String
-> (Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"lui" Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> l -> RiscIvIsa w l
Lui Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
referenceWithDirective
                    , String
-> (Register -> MemRef w -> RiscIvIsa w (Ref w))
-> Parser Register
-> ParsecT Void String Identity (MemRef w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"lw" Register -> MemRef w -> RiscIvIsa w (Ref w)
forall w l. Register -> MemRef w -> RiscIvIsa w l
Lw Parser Register
register ParsecT Void String Identity (MemRef w)
forall w. IsWord w => Parser (MemRef w)
memRef
                    , String
-> (Register -> MemRef w -> RiscIvIsa w (Ref w))
-> Parser Register
-> ParsecT Void String Identity (MemRef w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"lb" Register -> MemRef w -> RiscIvIsa w (Ref w)
forall w l. Register -> MemRef w -> RiscIvIsa w l
Lb Parser Register
register ParsecT Void String Identity (MemRef w)
forall w. IsWord w => Parser (MemRef w)
memRef
                    , Tokens String
-> (Ref w -> RiscIvIsa w (Ref w))
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {s} {f :: * -> *} {e} {a} {b}.
(Token s ~ Char, MonadParsec e s f, Semigroup (Tokens s),
 IsString (Tokens s)) =>
Tokens s -> (a -> b) -> f a -> f b
cmd1args Tokens String
"j" Ref w -> RiscIvIsa w (Ref w)
forall w l. l -> RiscIvIsa w l
J ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"jal" Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> l -> RiscIvIsa w l
Jal Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"jalr" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Jalr Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
referenceWithDirective
                    , String
-> (Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"beqz" Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> l -> RiscIvIsa w l
Beqz Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {b}.
String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args String
"bnez" Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> l -> RiscIvIsa w l
Bnez Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"blt" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Blt Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"bge" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Bge Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"bltu" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Bltu Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"bgeu" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Bgeu Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"beq" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Beq Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , String
-> (Register -> Register -> Ref w -> RiscIvIsa w (Ref w))
-> Parser Register
-> Parser Register
-> ParsecT Void String Identity (Ref w)
-> Parser (RiscIvIsa w (Ref w))
forall {a} {a} {a} {b}.
String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args String
"bne" Register -> Register -> Ref w -> RiscIvIsa w (Ref w)
forall w l. Register -> Register -> l -> RiscIvIsa w l
Bne Parser Register
register Parser Register
register ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
                    , Tokens String -> ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string Tokens String
"halt" ParsecT Void String Identity (Tokens String)
-> Parser (RiscIvIsa w (Ref w)) -> Parser (RiscIvIsa w (Ref w))
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> RiscIvIsa w (Ref w) -> Parser (RiscIvIsa w (Ref w))
forall a. a -> ParsecT Void String Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return RiscIvIsa w (Ref w)
forall w l. RiscIvIsa w l
Halt
                    ]

instance (IsWord w) => DerefMnemonic (RiscIvIsa w) w where
    derefMnemonic :: (Text -> Maybe w) -> w -> RiscIvIsa w (Ref w) -> RiscIvIsa w w
derefMnemonic Text -> Maybe w
f w
offset RiscIvIsa w (Ref w)
i =
        let iTypeErr :: a -> a -> a
iTypeErr a
m a
x = a
m a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
": I-type imm " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
" is not in -2048..2047"
            shamtErr :: a -> a -> a
shamtErr a
m a
x = a
m a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
": shift amount " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
" is not in 0..31"
            uTypeErr :: a -> a -> a
uTypeErr a
m a
x = a
m a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
": U-type imm " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
" is not in 0..1048575"
            bTypeErr :: a -> a -> a
bTypeErr a
m a
x = a
m a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
": B-type disp " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
" is not in -4096..4095"
            jTypeErr :: a -> a -> a
jTypeErr a
m a
x = a
m a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
": J-type disp " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
" is not in -1048576..1048575"
         in case RiscIvIsa w (Ref w)
i of
                J{Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> w -> RiscIvIsa w w
forall w l. l -> RiscIvIsa w l
J (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i21 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
jTypeErr Text
"j") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Jal{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> w -> RiscIvIsa w w
forall w l. Register -> l -> RiscIvIsa w l
Jal Register
rd (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i21 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
jTypeErr Text
"jal") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Jalr{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Jalr{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i12 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
iTypeErr Text
"jalr")) Text -> Maybe w
f Ref w
k}
                Addi{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Addi{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i12 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
iTypeErr Text
"addi")) Text -> Maybe w
f Ref w
k}
                Slti{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Slti{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i12 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
iTypeErr Text
"slti")) Text -> Maybe w
f Ref w
k}
                Slli{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Slli{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u5 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
shamtErr Text
"slli")) Text -> Maybe w
f Ref w
k}
                Srli{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Srli{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u5 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
shamtErr Text
"srli")) Text -> Maybe w
f Ref w
k}
                Srai{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Srai{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u5 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
shamtErr Text
"srai")) Text -> Maybe w
f Ref w
k}
                Andi{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Andi{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i12 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
iTypeErr Text
"andi")) Text -> Maybe w
f Ref w
k}
                Ori{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Ori{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i12 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
iTypeErr Text
"ori")) Text -> Maybe w
f Ref w
k}
                Xori{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Xori{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i12 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
iTypeErr Text
"xori")) Text -> Maybe w
f Ref w
k}
                Add{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Add{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Sub{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Sub{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Mul{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Mul{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Mulh{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Mulh{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Div{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Div{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Rem{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Rem{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Sll{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Sll{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Srl{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Srl{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Sra{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Sra{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                And{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> And{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Or{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Or{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Xor{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Xor{Register
rd :: Register
rd :: Register
rd, Register
rs1 :: Register
rs1 :: Register
rs1, Register
rs2 :: Register
rs2 :: Register
rs2}
                Mv{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs :: forall w l. RiscIvIsa w l -> Register
rs :: Register
rs} -> Mv{Register
rd :: Register
rd :: Register
rd, Register
rs :: Register
rs :: Register
rs}
                Sw{Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, MemRef w
offsetRs1 :: forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 :: MemRef w
offsetRs1} -> Sw{Register
rs2 :: Register
rs2 :: Register
rs2, MemRef w
offsetRs1 :: MemRef w
offsetRs1 :: MemRef w
offsetRs1}
                Sb{Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, MemRef w
offsetRs1 :: forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 :: MemRef w
offsetRs1} -> Sb{Register
rs2 :: Register
rs2 :: Register
rs2, MemRef w
offsetRs1 :: MemRef w
offsetRs1 :: MemRef w
offsetRs1}
                Lui{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Lui{Register
rd :: Register
rd :: Register
rd, k :: w
k = (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
u20 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
uTypeErr Text
"lui")) Text -> Maybe w
f Ref w
k}
                Lw{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, MemRef w
offsetRs1 :: forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 :: MemRef w
offsetRs1} -> Lw{Register
rd :: Register
rd :: Register
rd, MemRef w
offsetRs1 :: MemRef w
offsetRs1 :: MemRef w
offsetRs1}
                Lb{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, MemRef w
offsetRs1 :: forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 :: MemRef w
offsetRs1} -> Lb{Register
rd :: Register
rd :: Register
rd, MemRef w
offsetRs1 :: MemRef w
offsetRs1 :: MemRef w
offsetRs1}
                Beqz{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> w -> RiscIvIsa w w
forall w l. Register -> l -> RiscIvIsa w l
Beqz Register
rs1 (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i13 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
bTypeErr Text
"beqz") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Bnez{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> w -> RiscIvIsa w w
forall w l. Register -> l -> RiscIvIsa w l
Bnez Register
rs1 (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i13 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
bTypeErr Text
"bnez") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Blt{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> Register -> w -> RiscIvIsa w w
forall w l. Register -> Register -> l -> RiscIvIsa w l
Blt Register
rs1 Register
rs2 (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i13 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
bTypeErr Text
"blt") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Bge{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> Register -> w -> RiscIvIsa w w
forall w l. Register -> Register -> l -> RiscIvIsa w l
Bge Register
rs1 Register
rs2 (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i13 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
bTypeErr Text
"bge") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Bltu{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> Register -> w -> RiscIvIsa w w
forall w l. Register -> Register -> l -> RiscIvIsa w l
Bltu Register
rs1 Register
rs2 (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i13 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
bTypeErr Text
"bltu") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Bgeu{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> Register -> w -> RiscIvIsa w w
forall w l. Register -> Register -> l -> RiscIvIsa w l
Bgeu Register
rs1 Register
rs2 (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i13 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
bTypeErr Text
"bgeu") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Beq{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> Register -> w -> RiscIvIsa w w
forall w l. Register -> Register -> l -> RiscIvIsa w l
Beq Register
rs1 Register
rs2 (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i13 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
bTypeErr Text
"beq") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                Bne{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, Ref w
k :: forall w l. RiscIvIsa w l -> l
k :: Ref w
k} -> Register -> Register -> w -> RiscIvIsa w w
forall w l. Register -> Register -> l -> RiscIvIsa w l
Bne Register
rs1 Register
rs2 (w -> RiscIvIsa w w) -> w -> RiscIvIsa w w
forall a b. (a -> b) -> a -> b
$ (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
forall w. (w -> Either Text w) -> (Text -> Maybe w) -> Ref w -> w
resolveRef ((Text -> Text) -> w -> Either Text w
forall w. IsWord w => (Text -> Text) -> w -> Either Text w
i13 (Text -> Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a -> a
bTypeErr Text
"bne") (w -> Either Text w) -> (w -> w) -> w -> Either Text w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> w -> w
forall a. Num a => a -> a -> a
subtract w
offset) Text -> Maybe w
f Ref w
k
                RiscIvIsa w (Ref w)
Halt -> RiscIvIsa w w
forall w l. RiscIvIsa w l
Halt

instance ByteSize (RiscIvIsa w l) where
    byteSize :: RiscIvIsa w l -> Int
byteSize RiscIvIsa w l
_ = Int
4

cmdMnemonic :: Tokens s -> f (Tokens s)
cmdMnemonic Tokens s
mnemonic = Tokens s -> f (Tokens s)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string (Tokens s
mnemonic Tokens s -> Tokens s -> Tokens s
forall a. Semigroup a => a -> a -> a
<> Tokens s
" ") f (Tokens s) -> f (Tokens s) -> f (Tokens s)
forall a. f a -> f a -> f a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Tokens s -> f (Tokens s)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string (Tokens s
mnemonic Tokens s -> Tokens s -> Tokens s
forall a. Semigroup a => a -> a -> a
<> Tokens s
"\t")

cmd1args :: Tokens s -> (a -> b) -> f a -> f b
cmd1args Tokens s
mnemonic a -> b
constructor f a
a =
    a -> b
constructor (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Tokens s -> f (Tokens s)
forall {f :: * -> *} {e} {s}.
(MonadParsec e s f, Semigroup (Tokens s), IsString (Tokens s)) =>
Tokens s -> f (Tokens s)
cmdMnemonic Tokens s
mnemonic f (Tokens s) -> f () -> f ()
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> f ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace f () -> f a -> f a
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> f a
a)

cmd2args :: Tokens String
-> (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd2args Tokens String
mnemonic a -> a -> b
constructor ParsecT Void String Identity a
a ParsecT Void String Identity a
b =
    a -> a -> b
constructor
        (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity (a -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Tokens String -> ParsecT Void String Identity (Tokens String)
forall {f :: * -> *} {e} {s}.
(MonadParsec e s f, Semigroup (Tokens s), IsString (Tokens s)) =>
Tokens s -> f (Tokens s)
cmdMnemonic Tokens String
mnemonic ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace ParsecT Void String Identity ()
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void String Identity a
a)
        ParsecT Void String Identity (a -> b)
-> ParsecT Void String Identity a -> ParsecT Void String Identity b
forall a b.
ParsecT Void String Identity (a -> b)
-> ParsecT Void String Identity a -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (ParsecT Void String Identity ()
comma ParsecT Void String Identity ()
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void String Identity a
b)

cmd3args :: Tokens String
-> (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity a
-> ParsecT Void String Identity b
cmd3args Tokens String
mnemonic a -> a -> a -> b
constructor ParsecT Void String Identity a
a ParsecT Void String Identity a
b ParsecT Void String Identity a
c =
    a -> a -> a -> b
constructor
        (a -> a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity (a -> a -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Tokens String -> ParsecT Void String Identity (Tokens String)
forall {f :: * -> *} {e} {s}.
(MonadParsec e s f, Semigroup (Tokens s), IsString (Tokens s)) =>
Tokens s -> f (Tokens s)
cmdMnemonic Tokens String
mnemonic ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace ParsecT Void String Identity ()
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void String Identity a
a)
        ParsecT Void String Identity (a -> a -> b)
-> ParsecT Void String Identity a
-> ParsecT Void String Identity (a -> b)
forall a b.
ParsecT Void String Identity (a -> b)
-> ParsecT Void String Identity a -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (ParsecT Void String Identity ()
comma ParsecT Void String Identity ()
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void String Identity a
b)
        ParsecT Void String Identity (a -> b)
-> ParsecT Void String Identity a -> ParsecT Void String Identity b
forall a b.
ParsecT Void String Identity (a -> b)
-> ParsecT Void String Identity a -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (ParsecT Void String Identity ()
comma ParsecT Void String Identity ()
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void String Identity a
c)

-- * Machine

data RiscIvSt w = RiscIvSt
    { forall w. RiscIvSt w -> Int
pc :: Int
    , forall w. RiscIvSt w -> IoMem (RiscIvIsa w w) w
mem :: IoMem (RiscIvIsa w w) w
    , forall w. RiscIvSt w -> HashMap Register w
regs :: HashMap Register w
    , forall w. RiscIvSt w -> Bool
stopped :: Bool
    , forall w. RiscIvSt w -> Maybe Text
internalError :: Maybe Text
    }
    deriving (Int -> RiscIvSt w -> String -> String
[RiscIvSt w] -> String -> String
RiscIvSt w -> String
(Int -> RiscIvSt w -> String -> String)
-> (RiscIvSt w -> String)
-> ([RiscIvSt w] -> String -> String)
-> Show (RiscIvSt w)
forall w. Show w => Int -> RiscIvSt w -> String -> String
forall w. Show w => [RiscIvSt w] -> String -> String
forall w. Show w => RiscIvSt w -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall w. Show w => Int -> RiscIvSt w -> String -> String
showsPrec :: Int -> RiscIvSt w -> String -> String
$cshow :: forall w. Show w => RiscIvSt w -> String
show :: RiscIvSt w -> String
$cshowList :: forall w. Show w => [RiscIvSt w] -> String -> String
showList :: [RiscIvSt w] -> String -> String
Show)

setPc :: forall w. Int -> State (RiscIvSt w) ()
setPc :: forall w. Int -> State (RiscIvSt w) ()
setPc Int
addr = (RiscIvSt w -> RiscIvSt w) -> StateT (RiscIvSt w) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RiscIvSt w -> RiscIvSt w) -> StateT (RiscIvSt w) Identity ())
-> (RiscIvSt w -> RiscIvSt w) -> StateT (RiscIvSt w) Identity ()
forall a b. (a -> b) -> a -> b
$ \RiscIvSt w
st -> RiscIvSt w
st{pc = addr}

nextPc :: forall w. (ByteSizeT w) => State (RiscIvSt w) ()
nextPc :: forall w. ByteSizeT w => State (RiscIvSt w) ()
nextPc = do
    RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
    setPc (pc + byteSizeT @w)

raiseInternalError :: Text -> State (RiscIvSt w) ()
raiseInternalError :: forall w. Text -> State (RiscIvSt w) ()
raiseInternalError Text
msg = (RiscIvSt w -> RiscIvSt w) -> StateT (RiscIvSt w) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RiscIvSt w -> RiscIvSt w) -> StateT (RiscIvSt w) Identity ())
-> (RiscIvSt w -> RiscIvSt w) -> StateT (RiscIvSt w) Identity ()
forall a b. (a -> b) -> a -> b
$ \RiscIvSt w
st -> RiscIvSt w
st{internalError = Just msg}

getReg :: Register -> StateT (RiscIvSt b) Identity b
getReg Register
r = do
    RiscIvSt{regs} <- StateT (RiscIvSt b) Identity (RiscIvSt b)
forall s (m :: * -> *). MonadState s m => m s
get
    case regs !? r of
        Just Val (HashMap Register b)
value -> b -> StateT (RiscIvSt b) Identity b
forall a. a -> StateT (RiscIvSt b) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return b
Val (HashMap Register b)
value
        Maybe (Val (HashMap Register b))
Nothing -> do
            Text -> State (RiscIvSt b) ()
forall w. Text -> State (RiscIvSt w) ()
raiseInternalError (Text -> State (RiscIvSt b) ()) -> Text -> State (RiscIvSt b) ()
forall a b. (a -> b) -> a -> b
$ Text
"wrong register: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Register -> Text
forall b a. (Show a, IsString b) => a -> b
show Register
r
            b -> StateT (RiscIvSt b) Identity b
forall a. a -> StateT (RiscIvSt b) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return b
forall a. Default a => a
def

setReg :: Register -> w -> m ()
setReg Register
Zero w
_ = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
setReg Register
r w
value = (RiscIvSt w -> RiscIvSt w) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RiscIvSt w -> RiscIvSt w) -> m ())
-> (RiscIvSt w -> RiscIvSt w) -> m ()
forall a b. (a -> b) -> a -> b
$ \st :: RiscIvSt w
st@RiscIvSt{HashMap Register w
regs :: forall w. RiscIvSt w -> HashMap Register w
regs :: HashMap Register w
regs} -> RiscIvSt w
st{regs = insert r value regs}

getWord :: Int -> StateT (RiscIvSt b) Identity b
getWord Int
addr = do
    st@RiscIvSt{mem} <- StateT (RiscIvSt b) Identity (RiscIvSt b)
forall s (m :: * -> *). MonadState s m => m s
get
    case readWord mem addr of
        Right (IoMem (RiscIvIsa b b) b
mem', b
w) -> do
            RiscIvSt b -> StateT (RiscIvSt b) Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put RiscIvSt b
st{mem = mem'}
            b -> StateT (RiscIvSt b) Identity b
forall a. a -> StateT (RiscIvSt b) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return b
w
        Left Text
err -> do
            Text -> StateT (RiscIvSt b) Identity ()
forall w. Text -> State (RiscIvSt w) ()
raiseInternalError (Text -> StateT (RiscIvSt b) Identity ())
-> Text -> StateT (RiscIvSt b) Identity ()
forall a b. (a -> b) -> a -> b
$ Text
"memory access error: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err
            b -> StateT (RiscIvSt b) Identity b
forall a. a -> StateT (RiscIvSt b) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return b
forall a. Default a => a
def

setWord :: Int -> w -> StateT (RiscIvSt w) Identity ()
setWord Int
addr w
w = do
    st@RiscIvSt{mem} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
    case writeWord mem addr w of
        Right IoMem (RiscIvIsa w w) w
mem' -> do
            RiscIvSt w -> StateT (RiscIvSt w) Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put RiscIvSt w
st{mem = mem'}
        Left Text
err -> Text -> StateT (RiscIvSt w) Identity ()
forall w. Text -> State (RiscIvSt w) ()
raiseInternalError (Text -> StateT (RiscIvSt w) Identity ())
-> Text -> StateT (RiscIvSt w) Identity ()
forall a b. (a -> b) -> a -> b
$ Text
"memory access error: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err

getByte :: Int -> StateT (RiscIvSt w) Identity Word8
getByte Int
addr = do
    st@RiscIvSt{mem} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
    case readByte mem addr of
        Right (IoMem (RiscIvIsa w w) w
mem', Word8
b) -> do
            RiscIvSt w -> StateT (RiscIvSt w) Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put RiscIvSt w
st{mem = mem'}
            Word8 -> StateT (RiscIvSt w) Identity Word8
forall a. a -> StateT (RiscIvSt w) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Word8
b
        Left Text
err -> do
            Text -> StateT (RiscIvSt w) Identity ()
forall w. Text -> State (RiscIvSt w) ()
raiseInternalError (Text -> StateT (RiscIvSt w) Identity ())
-> Text -> StateT (RiscIvSt w) Identity ()
forall a b. (a -> b) -> a -> b
$ Text
"memory access error: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err
            Word8 -> StateT (RiscIvSt w) Identity Word8
forall a. a -> StateT (RiscIvSt w) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Word8
0

setByte :: Int -> Word8 -> StateT (RiscIvSt w) Identity ()
setByte Int
addr Word8
byte = do
    st@RiscIvSt{mem} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
    case writeByte mem addr byte of
        Right IoMem (RiscIvIsa w w) w
mem' -> do
            RiscIvSt w -> StateT (RiscIvSt w) Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put RiscIvSt w
st{mem = mem'}
        Left Text
err -> Text -> StateT (RiscIvSt w) Identity ()
forall w. Text -> State (RiscIvSt w) ()
raiseInternalError (Text -> StateT (RiscIvSt w) Identity ())
-> Text -> StateT (RiscIvSt w) Identity ()
forall a b. (a -> b) -> a -> b
$ Text
"memory access error: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err

type instance MemOf (RiscIvSt w) = IoMem (RiscIvIsa w w) w

instance (IsWord w) => InitState (RiscIvSt w) where
    initState :: Int -> MemOf (RiscIvSt w) -> StdGen -> RiscIvSt w
initState Int
pc MemOf (RiscIvSt w)
dump StdGen
_randomGen =
        RiscIvSt
            { Int
pc :: Int
pc :: Int
pc
            , mem :: IoMem (RiscIvIsa w w) w
mem = IoMem (RiscIvIsa w w) w
MemOf (RiscIvSt w)
dump
            , regs :: HashMap Register w
regs = HashMap Register w
forall a. Default a => a
def
            , stopped :: Bool
stopped = Bool
False
            , internalError :: Maybe Text
internalError = Maybe Text
forall a. Maybe a
Nothing
            }

instance (IsWord w) => Inspectable (RiscIvSt w) where
    type WordOf (RiscIvSt w) = w
    type IsaOf (RiscIvSt w) = RiscIvIsa w w

    programCounter :: RiscIvSt w -> Int
programCounter RiscIvSt{Int
pc :: forall w. RiscIvSt w -> Int
pc :: Int
pc} = Int
pc
    memoryDump :: RiscIvSt w -> MemOf (RiscIvSt w)
memoryDump RiscIvSt{IoMem (RiscIvIsa w w) w
mem :: forall w. RiscIvSt w -> IoMem (RiscIvIsa w w) w
mem :: IoMem (RiscIvIsa w w) w
mem} = IoMem (RiscIvIsa w w) w
MemOf (RiscIvSt w)
mem
    ioStreams :: RiscIvSt w -> IntMap ([WordOf (RiscIvSt w)], [WordOf (RiscIvSt w)])
ioStreams RiscIvSt{mem :: forall w. RiscIvSt w -> IoMem (RiscIvIsa w w) w
mem = IoMem{IntMap ([w], [w])
mIoStreams :: IntMap ([w], [w])
mIoStreams :: forall isa w. IoMem isa w -> IntMap ([w], [w])
mIoStreams}} = IntMap ([w], [w])
IntMap ([WordOf (RiscIvSt w)], [WordOf (RiscIvSt w)])
mIoStreams
    isHalted :: RiscIvSt w -> Bool
isHalted RiscIvSt{Bool
stopped :: forall w. RiscIvSt w -> Bool
stopped :: Bool
stopped} = Bool
stopped

    views :: [View (StateEnv (RiscIvSt w))]
views =
        [(Text, Text)]
-> [View (StateEnv (RiscIvSt w))] -> [View (StateEnv (RiscIvSt w))]
forall env. [(Text, Text)] -> [View env] -> [View env]
withRenames
            [(Register -> Text
forall b a. (Show a, IsString b) => a -> b
show Register
r, Text
name) | Register
r <- [Register]
allRegisters, Text
name : [Text]
_ <- [Register -> [Text]
asmNames Register
r]]
            [ Text
-> Text
-> (StateEnv (RiscIvSt w) -> w)
-> View (StateEnv (RiscIvSt w))
forall a env.
(Integral a, Show a) =>
Text -> Text -> (env -> a) -> View env
valueView Text
name (Text
"Register `" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate Text
"`/`" (Register -> [Text]
asmNames Register
r) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"`.") (w -> Maybe w -> w
forall a. a -> Maybe a -> a
fromMaybe w
0 (Maybe w -> w)
-> (StateEnv (RiscIvSt w) -> Maybe w) -> StateEnv (RiscIvSt w) -> w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashMap Register w
-> Key (HashMap Register w) -> Maybe (Val (HashMap Register w))
forall t. StaticMap t => t -> Key t -> Maybe (Val t)
!? Key (HashMap Register w)
Register
r) (HashMap Register w -> Maybe w)
-> (StateEnv (RiscIvSt w) -> HashMap Register w)
-> StateEnv (RiscIvSt w)
-> Maybe w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RiscIvSt w -> HashMap Register w
forall w. RiscIvSt w -> HashMap Register w
regs (RiscIvSt w -> HashMap Register w)
-> (StateEnv (RiscIvSt w) -> RiscIvSt w)
-> StateEnv (RiscIvSt w)
-> HashMap Register w
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateEnv (RiscIvSt w) -> RiscIvSt w
forall st. StateEnv st -> st
seState)
            | Register
r <- [Register]
allRegisters
            , Text
name <- Register -> [Text]
asmNames Register
r
            ]
        where
            asmNames :: Register -> [Text]
asmNames Register
r = [Text
n | (Text
n, Register
r') <- [(Text, Register)]
registerNames, Register
r' Register -> Register -> Bool
forall a. Eq a => a -> a -> Bool
== Register
r]

instance (IsWord w) => Machine (RiscIvSt w) (RiscIvIsa w w) w where
    instructionFetch :: State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
instructionFetch = do
        st <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
        case st of
            RiscIvSt{stopped :: forall w. RiscIvSt w -> Bool
stopped = Bool
True} -> Either Text (Int, RiscIvIsa w w)
-> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
forall a. a -> StateT (RiscIvSt w) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text (Int, RiscIvIsa w w)
 -> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w)))
-> Either Text (Int, RiscIvIsa w w)
-> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
forall a b. (a -> b) -> a -> b
$ Text -> Either Text (Int, RiscIvIsa w w)
forall a b. a -> Either a b
Left Text
halted
            RiscIvSt{internalError :: forall w. RiscIvSt w -> Maybe Text
internalError = Just Text
err} -> Either Text (Int, RiscIvIsa w w)
-> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
forall a. a -> StateT (RiscIvSt w) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text (Int, RiscIvIsa w w)
 -> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w)))
-> Either Text (Int, RiscIvIsa w w)
-> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
forall a b. (a -> b) -> a -> b
$ Text -> Either Text (Int, RiscIvIsa w w)
forall a b. a -> Either a b
Left Text
err
            RiscIvSt{Int
pc :: forall w. RiscIvSt w -> Int
pc :: Int
pc, IoMem (RiscIvIsa w w) w
mem :: forall w. RiscIvSt w -> IoMem (RiscIvIsa w w) w
mem :: IoMem (RiscIvIsa w w) w
mem} ->
                case IoMem (RiscIvIsa w w) w
-> Int -> Either Text (IoMem (RiscIvIsa w w) w, RiscIvIsa w w)
forall m isa w. Memory m isa w => m -> Int -> Either Text (m, isa)
readInstruction IoMem (RiscIvIsa w w) w
mem Int
pc of
                    Left Text
err -> Either Text (Int, RiscIvIsa w w)
-> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
forall a. a -> StateT (RiscIvSt w) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text (Int, RiscIvIsa w w)
 -> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w)))
-> Either Text (Int, RiscIvIsa w w)
-> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
forall a b. (a -> b) -> a -> b
$ Text -> Either Text (Int, RiscIvIsa w w)
forall a b. a -> Either a b
Left Text
err
                    Right (IoMem (RiscIvIsa w w) w
mem', RiscIvIsa w w
instruction) -> do
                        RiscIvSt w -> State (RiscIvSt w) ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put RiscIvSt w
st{mem = mem'}
                        Either Text (Int, RiscIvIsa w w)
-> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
forall a. a -> StateT (RiscIvSt w) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text (Int, RiscIvIsa w w)
 -> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w)))
-> Either Text (Int, RiscIvIsa w w)
-> State (RiscIvSt w) (Either Text (Int, RiscIvIsa w w))
forall a b. (a -> b) -> a -> b
$ (Int, RiscIvIsa w w) -> Either Text (Int, RiscIvIsa w w)
forall a b. b -> Either a b
Right (Int
pc, RiscIvIsa w w
instruction)

    instructionExecute :: Int -> RiscIvIsa w w -> State (RiscIvSt w) ()
instructionExecute Int
_pc RiscIvIsa w w
instruction =
        case RiscIvIsa w w
instruction of
            Addi{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                setReg rd (rs1' + k)
                nextPc
            Slti{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                setReg rd (if rs1' < k then 1 else 0)
                nextPc
            Slli{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                setReg rd (rs1' `shiftL` fromEnum k)
                nextPc
            Srli{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                setReg rd (lShiftR rs1' k)
                nextPc
            Srai{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                setReg rd (rs1' `shiftR` fromEnum k)
                nextPc
            Andi{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                setReg rd (rs1' .&. k)
                nextPc
            Ori{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                setReg rd (rs1' .|. k)
                nextPc
            Xori{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                setReg rd (rs1' `xor` k)
                nextPc
            Add{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id w -> w -> w
forall a. Num a => a -> a -> a
(+)
            Sub{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id (-)
            Mul{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id w -> w -> w
forall a. Num a => a -> a -> a
(*)
            Mulh{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} ->
                Register
-> Register
-> Register
-> (w -> Integer)
-> (w -> Integer)
-> (Integer -> Integer -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation
                    Register
rs1
                    Register
rs2
                    Register
rd
                    w -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral
                    w -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral
                    ( \(Integer
r1 :: Integer) Integer
r2 ->
                        let x :: Integer
x = Integer
r1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
r2
                            shift :: Int
shift = Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* forall t. ByteSizeT t => Int
byteSizeT @w
                         in Integer -> w
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
x Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
shift)
                    )
            Div{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id ((w -> w -> w) -> State (RiscIvSt w) ())
-> (w -> w -> w) -> State (RiscIvSt w) ()
forall a b. (a -> b) -> a -> b
$ \w
r1 w
r2 -> case w
r2 of
                w
0 -> -w
1
                -1 | w
r1 w -> w -> Bool
forall a. Eq a => a -> a -> Bool
== w
forall a. Bounded a => a
minBound -> w
r1
                w
_ -> w -> w -> w
forall a. Integral a => a -> a -> a
quot w
r1 w
r2
            Rem{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id ((w -> w -> w) -> State (RiscIvSt w) ())
-> (w -> w -> w) -> State (RiscIvSt w) ()
forall a b. (a -> b) -> a -> b
$ \w
r1 w
r2 -> case w
r2 of
                w
0 -> w
r1
                -1 | w
r1 w -> w -> Bool
forall a. Eq a => a -> a -> Bool
== w
forall a. Bounded a => a
minBound -> w
0
                w
_ -> w -> w -> w
forall a. Integral a => a -> a -> a
rem w
r1 w
r2
            Sll{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id (\w
r1 w
r2 -> w
r1 w -> Int -> w
forall a. Bits a => a -> Int -> a
`shiftL` (w -> Int
forall a. Enum a => a -> Int
fromEnum w
r2 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x1F))
            Srl{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id (\w
r1 w
r2 -> w -> w -> w
forall w. IsWord w => w -> w -> w
lShiftR w
r1 (w
r2 w -> w -> w
forall a. Bits a => a -> a -> a
.&. w
0x1F))
            Sra{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id (\w
r1 w
r2 -> w
r1 w -> Int -> w
forall a. Bits a => a -> Int -> a
`shiftR` (w -> Int
forall a. Enum a => a -> Int
fromEnum w
r2 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x1F))
            And{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id w -> w -> w
forall a. Bits a => a -> a -> a
(.&.)
            Or{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id w -> w -> w
forall a. Bits a => a -> a -> a
(.|.)
            Xor{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2} -> Register
-> Register
-> Register
-> (w -> w)
-> (w -> w)
-> (w -> w -> w)
-> State (RiscIvSt w) ()
forall {w} {t} {t}.
(Default w, ByteSize w) =>
Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> w
forall a. a -> a
id w -> w
forall a. a -> a
id w -> w -> w
forall a. Bits a => a -> a -> a
xor
            Mv{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs :: forall w l. RiscIvIsa w l -> Register
rs :: Register
rs} -> do
                rs' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs
                setReg rd rs'
                nextPc
            Sw{Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, offsetRs1 :: forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 = MemRef{w
mrOffset :: forall w. MemRef w -> w
mrOffset :: w
mrOffset, Register
mrReg :: forall w. MemRef w -> Register
mrReg :: Register
mrReg}} -> do
                rs2' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs2
                mrReg' <- getReg mrReg
                setWord (fromEnum (mrReg' + mrOffset)) rs2'
                nextPc
            Sb{Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, offsetRs1 :: forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 = MemRef{w
mrOffset :: forall w. MemRef w -> w
mrOffset :: w
mrOffset, Register
mrReg :: forall w. MemRef w -> Register
mrReg :: Register
mrReg}} -> do
                rs2' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs2
                mrReg' <- getReg mrReg
                setByte (fromEnum (mrReg' + mrOffset)) $ fromIntegral rs2'
                nextPc
            Lui{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                Register -> w -> State (RiscIvSt w) ()
forall {m :: * -> *} {w}.
MonadState (RiscIvSt w) m =>
Register -> w -> m ()
setReg Register
rd (w
k w -> Int -> w
forall a. Bits a => a -> Int -> a
`shiftL` Int
12)
                State (RiscIvSt w) ()
forall w. ByteSizeT w => State (RiscIvSt w) ()
nextPc
            Lw{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, offsetRs1 :: forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 = MemRef{w
mrOffset :: forall w. MemRef w -> w
mrOffset :: w
mrOffset, Register
mrReg :: forall w. MemRef w -> Register
mrReg :: Register
mrReg}} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
mrReg
                w <- getWord $ fromEnum (mrOffset + rs1')
                setReg rd w
                nextPc
            Lb{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, offsetRs1 :: forall w l. RiscIvIsa w l -> MemRef w
offsetRs1 = MemRef{w
mrOffset :: forall w. MemRef w -> w
mrOffset :: w
mrOffset, Register
mrReg :: forall w. MemRef w -> Register
mrReg :: Register
mrReg}} -> do
                rs1' <- Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
mrReg
                b <- getByte $ fromEnum (mrOffset + rs1')
                setReg rd (fromIntegral (fromIntegral b :: Int8))
                nextPc
            J{w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                setPc (pc + fromEnum k)
            Jal{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                setReg rd (toEnum pc + 4)
                setPc (pc + fromEnum k)
            Jalr{Register
rd :: forall w l. RiscIvIsa w l -> Register
rd :: Register
rd, Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- getReg rs1
                setReg rd (toEnum pc + 4)
                setPc (fromEnum (rs1' + k))
            Beqz{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- getReg rs1
                if rs1' == 0
                    then setPc (pc + fromEnum k)
                    else nextPc
            Bnez{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- getReg rs1
                if rs1' /= 0
                    then setPc (pc + fromEnum k)
                    else nextPc
            Blt{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- getReg rs1
                rs2' <- getReg rs2
                if rs1' < rs2'
                    then setPc (pc + fromEnum k)
                    else nextPc
            Bge{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- getReg rs1
                rs2' <- getReg rs2
                if rs1' >= rs2'
                    then setPc (pc + fromEnum k)
                    else nextPc
            Bltu{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- fromSign <$> getReg rs1
                rs2' <- fromSign <$> getReg rs2
                if rs1' < rs2'
                    then setPc (pc + fromEnum k)
                    else nextPc
            Bgeu{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- fromSign <$> getReg rs1
                rs2' <- fromSign <$> getReg rs2
                if rs1' >= rs2'
                    then setPc (pc + fromEnum k)
                    else nextPc
            Beq{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- getReg rs1
                rs2' <- getReg rs2
                if rs1' == rs2'
                    then setPc (pc + fromEnum k)
                    else nextPc
            Bne{Register
rs1 :: forall w l. RiscIvIsa w l -> Register
rs1 :: Register
rs1, Register
rs2 :: forall w l. RiscIvIsa w l -> Register
rs2 :: Register
rs2, w
k :: forall w l. RiscIvIsa w l -> l
k :: w
k} -> do
                RiscIvSt{pc} <- StateT (RiscIvSt w) Identity (RiscIvSt w)
forall s (m :: * -> *). MonadState s m => m s
get
                rs1' <- getReg rs1
                rs2' <- getReg rs2
                if rs1' /= rs2'
                    then setPc (pc + fromEnum k)
                    else nextPc
            RiscIvIsa w w
Halt -> (RiscIvSt w -> RiscIvSt w) -> State (RiscIvSt w) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RiscIvSt w -> RiscIvSt w) -> State (RiscIvSt w) ())
-> (RiscIvSt w -> RiscIvSt w) -> State (RiscIvSt w) ()
forall a b. (a -> b) -> a -> b
$ \RiscIvSt w
st -> RiscIvSt w
st{stopped = True}
        where
            rOperation :: Register
-> Register
-> Register
-> (w -> t)
-> (w -> t)
-> (t -> t -> w)
-> StateT (RiscIvSt w) Identity ()
rOperation Register
rs1 Register
rs2 Register
rd w -> t
f1 w -> t
f2 t -> t -> w
fd = do
                r1 <- w -> t
f1 (w -> t)
-> StateT (RiscIvSt w) Identity w -> StateT (RiscIvSt w) Identity t
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Register -> StateT (RiscIvSt w) Identity w
forall {b}. Default b => Register -> StateT (RiscIvSt b) Identity b
getReg Register
rs1
                r2 <- f2 <$> getReg rs2
                setReg rd (fd r1 r2)
                nextPc