module RiscV.RV32I
( Register(..)
, CSRRegister(..)
, Instr(..)
, RegisterImmediateInstr(..)
, IOpcode(..)
, ShiftOpcode(..)
, RegisterRegisterInstr(..)
, ROpcode(..)
, JumpInstr(..)
, BranchInstr(..)
, BranchCond(..)
, MemoryInstr(..)
, Width(..)
, LoadWidth(..)
, SynchronizationInstr(..)
, SyncOrdering(..)
, CSRInstr(..)
, CSRType(..)
, EnvironmentInstr(..)
, Word5(..)
, Word12(..)
, Word20(..)
) where
import Data.Bits
import Data.Word
import Test.QuickCheck (Arbitrary, arbitrary, oneof, elements)
data Instr
= BranchInstr !BranchInstr
| CSRInstr !CSRInstr
| EnvironmentInstr !EnvironmentInstr
| JumpInstr !JumpInstr
| MemoryInstr !MemoryInstr
| RRInstr !RegisterRegisterInstr
| RIInstr !RegisterImmediateInstr
| SyncInstr !SynchronizationInstr
deriving (Show, Eq, Ord)
instance Arbitrary Instr where
arbitrary =
oneof
[ BranchInstr <$> arbitrary
, CSRInstr <$> arbitrary
, EnvironmentInstr <$> arbitrary
, JumpInstr <$> arbitrary
, MemoryInstr <$> arbitrary
, RRInstr <$> arbitrary
, RIInstr <$> arbitrary
, SyncInstr <$> arbitrary
]
data JumpInstr
= JAL !Word20
!Register
| JALR !Word12
!Register
!Register
deriving (Show, Eq, Ord)
instance Arbitrary JumpInstr where
arbitrary =
oneof
[ JAL <$> arbitrary <*> arbitrary
, JALR <$> arbitrary <*> arbitrary <*> arbitrary
]
data BranchCond
= BEQ
| BNE
| BLT
| BLTU
| BGE
| BGEU
deriving (Show, Eq, Ord)
instance Arbitrary BranchCond where
arbitrary = elements [BEQ, BNE, BLT, BLTU, BGE, BGEU]
data BranchInstr =
Branch !Word12
!BranchCond
!Register
!Register
deriving (Show, Eq, Ord)
instance Arbitrary BranchInstr where
arbitrary = Branch <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
data LoadWidth
= Width !Width
| HalfUnsigned
| ByteUnsigned
deriving (Show, Eq, Ord)
instance Arbitrary LoadWidth where
arbitrary = oneof [Width <$> arbitrary, pure HalfUnsigned, pure ByteUnsigned]
data Width
= Byte
| Half
| Word
deriving (Show, Eq, Ord)
instance Arbitrary Width where
arbitrary = elements [Byte, Half, Word]
data MemoryInstr
= LOAD !LoadWidth
!Word12
!Register
!Register
| STORE !Width
!Word12
!Register
!Register
deriving (Show, Eq, Ord)
instance Arbitrary MemoryInstr where
arbitrary =
oneof
[ LOAD <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, STORE <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
]
data IOpcode
= ADDI
| SLTI
| SLTIU
| XORI
| ORI
| ANDI
deriving (Show, Eq, Ord)
instance Arbitrary IOpcode where
arbitrary = elements [ADDI, SLTI, SLTIU, XORI, ORI, ANDI]
data ShiftOpcode
= SLLI
| SRLI
| SRAI
deriving (Show, Eq, Ord)
instance Arbitrary ShiftOpcode where
arbitrary = elements [SLLI, SRLI, SRAI]
data RegisterImmediateInstr
= IInstr !IOpcode
!Word12
!Register
!Register
| ShiftInstr !ShiftOpcode
!Word5
!Register
!Register
| LUI !Word20
!Register
| AUIPC !Word20
!Register
deriving (Show, Eq, Ord)
instance Arbitrary RegisterImmediateInstr where
arbitrary =
oneof
[ IInstr <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, ShiftInstr <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, LUI <$> arbitrary <*> arbitrary
, AUIPC <$> arbitrary <*> arbitrary
]
data ROpcode
= ADD
| SLT
| SLTU
| AND
| OR
| XOR
| SLL
| SRL
| SUB
| SRA
deriving (Show, Eq, Ord)
instance Arbitrary ROpcode where
arbitrary = elements [ADD, SLT, SLTU, AND, OR, XOR, SLL, SRL, SUB, SRA]
data RegisterRegisterInstr =
RInstr !ROpcode
!Register
!Register
!Register
deriving (Show, Eq, Ord)
instance Arbitrary RegisterRegisterInstr where
arbitrary = RInstr <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
data SyncOrdering = SyncOrd
{ deviceInput :: !Bool
, deviceOutput :: !Bool
, memoryReads :: !Bool
, memoryWrites :: !Bool
} deriving (Show, Eq, Ord)
instance Arbitrary SyncOrdering where
arbitrary = SyncOrd <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
data SynchronizationInstr
= FENCE !SyncOrdering
!SyncOrdering
| FENCEI
deriving (Show, Eq, Ord)
instance Arbitrary SynchronizationInstr where
arbitrary = oneof [FENCE <$> arbitrary <*> arbitrary, pure FENCEI]
data EnvironmentInstr
= ECALL
| EBREAK
deriving (Show, Eq, Ord)
instance Arbitrary EnvironmentInstr where
arbitrary = elements [ECALL, EBREAK]
data CSRType
= ReadWrite
| ReadSet
| ReadClear
deriving (Show, Eq, Ord)
instance Arbitrary CSRType where
arbitrary = elements [ReadWrite, ReadSet, ReadClear]
newtype CSRRegister = CSRRegister Word12 deriving (Show, Eq, Ord, Arbitrary)
data CSRInstr
= CSRRInstr !CSRType
!CSRRegister
!Register
!Register
| CSRIInstr !CSRType
!CSRRegister
!Word5
!Register
deriving (Show, Eq, Ord)
instance Arbitrary CSRInstr where
arbitrary =
oneof
[ CSRRInstr <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
, CSRIInstr <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
]
data Register
= X0
| X1
| X2
| X3
| X4
| X5
| X6
| X7
| X8
| X9
| X10
| X11
| X12
| X13
| X14
| X15
| X16
| X17
| X18
| X19
| X20
| X21
| X22
| X23
| X24
| X25
| X26
| X27
| X28
| X29
| X30
| X31
deriving (Show, Eq, Ord)
instance Arbitrary Register where
arbitrary =
elements
[ X0
, X1
, X2
, X3
, X4
, X5
, X6
, X7
, X8
, X9
, X10
, X11
, X12
, X13
, X14
, X15
, X16
, X17
, X18
, X19
, X20
, X21
, X22
, X23
, X24
, X25
, X26
, X27
, X28
, X29
, X30
, X31
]
newtype Word5 = Word5 Word8 deriving (Show, Eq, Ord)
instance Arbitrary Word5 where
arbitrary = do
w8 <- arbitrary
pure (Word5 $ w8 .&. 0x1F)
newtype Word12 = Word12 Word16 deriving (Show, Eq, Ord)
instance Arbitrary Word12 where
arbitrary = do
w16 <- arbitrary
pure (Word12 $ w16 .&. 0x0FFF)
newtype Word20 = Word20 Word32 deriving (Show, Eq, Ord)
instance Arbitrary Word20 where
arbitrary = do
w32 <- arbitrary
pure (Word20 $ w32 .&. 0x000FFFFF)