summaryrefslogtreecommitdiff
path: root/lib/Language/Elna/Architecture
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Language/Elna/Architecture')
-rw-r--r--lib/Language/Elna/Architecture/RiscV.hs286
1 files changed, 286 insertions, 0 deletions
diff --git a/lib/Language/Elna/Architecture/RiscV.hs b/lib/Language/Elna/Architecture/RiscV.hs
new file mode 100644
index 0000000..5d8c247
--- /dev/null
+++ b/lib/Language/Elna/Architecture/RiscV.hs
@@ -0,0 +1,286 @@
+module Language.Elna.Architecture.RiscV
+ ( BaseOpcode(..)
+ , Funct3(..)
+ , Funct7(..)
+ , Funct12(..)
+ , Instruction(..)
+ , Type(..)
+ , XRegister(..)
+ , baseOpcode
+ , funct3
+ , funct12
+ , instruction
+ , xRegister
+ ) where
+
+import qualified Data.ByteString.Builder as ByteString.Builder
+import Data.Bits (Bits(..))
+import Data.Word (Word8, Word32)
+
+data XRegister
+ = Zero
+ | RA
+ | SP
+ | GP
+ | TP
+ | T0
+ | T1
+ | T2
+ | S0
+ | S1
+ | A0
+ | A1
+ | A2
+ | A3
+ | A4
+ | A5
+ | A6
+ | A7
+ | S2
+ | S3
+ | S4
+ | S5
+ | S6
+ | S7
+ | S8
+ | S9
+ | S10
+ | S11
+ | T3
+ | T4
+ | T5
+ | T6
+ deriving Eq
+
+data Funct3
+ = ADDI
+ | SLTI
+ | SLTIU
+ | ANDI
+ | ORI
+ | XORI
+ | SLLI
+ | SRLI
+ | SRAI
+ | ADD
+ | SLT
+ | SLTU
+ | AND
+ | OR
+ | XOR
+ | SLL
+ | SRL
+ | SUB
+ | SRA
+ | BEQ
+ | BNE
+ | BLT
+ | BLTU
+ | BGE
+ | BGEU
+ | FENCE
+ | FENCEI
+ | CSRRW
+ | CSRRS
+ | CSRRC
+ | CSRRWI
+ | CSRRSI
+ | CSRRCI
+ | PRIV
+ | SB
+ | SH
+ | SW
+ | LB
+ | LH
+ | LW
+ | LBU
+ | LHU
+ | JALR
+ | MUL
+ | MULH
+ | MULHSU
+ | MULHU
+ | DIV
+ | DIVU
+ | REM
+ | REMU
+ deriving Eq
+
+data Funct12
+ = ECALL
+ | EBREAK
+ deriving Eq
+
+newtype Funct7 = Funct7
+ { funct7 :: Word8
+ } deriving Eq
+
+data BaseOpcode
+ = OpImm
+ | Lui
+ | Auipc
+ | Op
+ | Jal
+ | Jalr
+ | Branch
+ | Load
+ | Store
+ | MiscMem
+ | System
+ deriving Eq
+
+data Type
+ = I XRegister Funct3 XRegister Word32
+ | S Word32 Funct3 XRegister XRegister
+ | B Word32 Funct3 XRegister XRegister
+ | R XRegister Funct3 XRegister XRegister Funct7
+ | U XRegister Word32
+ | J XRegister Word32
+
+data Instruction = Instruction BaseOpcode Type
+
+xRegister :: XRegister -> Word8
+xRegister Zero = 0
+xRegister RA = 1
+xRegister SP = 2
+xRegister GP = 3
+xRegister TP = 4
+xRegister T0 = 5
+xRegister T1 = 6
+xRegister T2 = 7
+xRegister S0 = 8
+xRegister S1 = 9
+xRegister A0 = 10
+xRegister A1 = 11
+xRegister A2 = 12
+xRegister A3 = 13
+xRegister A4 = 14
+xRegister A5 = 15
+xRegister A6 = 16
+xRegister A7 = 17
+xRegister S2 = 18
+xRegister S3 = 19
+xRegister S4 = 20
+xRegister S5 = 21
+xRegister S6 = 22
+xRegister S7 = 23
+xRegister S8 = 24
+xRegister S9 = 25
+xRegister S10 = 26
+xRegister S11 = 27
+xRegister T3 = 28
+xRegister T4 = 29
+xRegister T5 = 30
+xRegister T6 = 31
+
+funct3 :: Funct3 -> Word8
+funct3 ADDI = 0b000
+funct3 SLTI = 0b001
+funct3 SLTIU = 0b011
+funct3 ANDI = 0b111
+funct3 ORI = 0b110
+funct3 XORI = 0b100
+funct3 SLLI = 0b000
+funct3 SRLI = 0b101
+funct3 SRAI = 0b101
+funct3 ADD = 0b000
+funct3 SLT = 0b010
+funct3 SLTU = 0b011
+funct3 AND = 0b111
+funct3 OR = 0b110
+funct3 XOR = 0b100
+funct3 SLL = 0b001
+funct3 SRL = 0b101
+funct3 SUB = 0b000
+funct3 SRA = 0b101
+funct3 BEQ = 0b000
+funct3 BNE = 0b001
+funct3 BLT = 0b100
+funct3 BLTU = 0b110
+funct3 BGE = 0b101
+funct3 BGEU = 0b111
+funct3 FENCE = 0b000
+funct3 FENCEI = 0b001
+funct3 CSRRW = 0b001
+funct3 CSRRS = 0b010
+funct3 CSRRC = 0b011
+funct3 CSRRWI = 0b101
+funct3 CSRRSI = 0b110
+funct3 CSRRCI = 0b111
+funct3 PRIV = 0b000
+funct3 SB = 0b000
+funct3 SH = 0b001
+funct3 SW = 0b010
+funct3 LB = 0b000
+funct3 LH = 0b001
+funct3 LW = 0b010
+funct3 LBU = 0b100
+funct3 LHU = 0b101
+funct3 JALR = 0b000
+funct3 MUL = 0b000
+funct3 MULH = 0b001
+funct3 MULHSU = 0b010
+funct3 MULHU = 0b011
+funct3 DIV = 0b100
+funct3 DIVU = 0b101
+funct3 REM = 0b110
+funct3 REMU = 0b111
+
+funct12 :: Funct12 -> Word8
+funct12 ECALL = 0b000000000000
+funct12 EBREAK = 0b000000000001
+
+baseOpcode :: BaseOpcode -> Word8
+baseOpcode OpImm = 0b0010011
+baseOpcode Lui = 0b0110111
+baseOpcode Auipc = 0b0010111
+baseOpcode Op = 0b0110011
+baseOpcode Jal = 0b1101111
+baseOpcode Jalr = 0b1100111
+baseOpcode Branch = 0b1100011
+baseOpcode Load = 0b0000011
+baseOpcode Store = 0b0100011
+baseOpcode MiscMem = 0b0001111
+baseOpcode System = 0b1110011
+
+type' :: Type -> Word32
+type' (I rd funct3' rs1 immediate)
+ = (fromIntegral (xRegister rd) `shiftL` 7)
+ .|. (fromIntegral (funct3 funct3') `shiftL` 12)
+ .|. (fromIntegral (xRegister rs1) `shiftL` 15)
+ .|. (immediate `shiftL` 20);
+type' (S immediate funct3' rs1 rs2)
+ = ((immediate .&. 0x1f) `shiftL` 7)
+ .|. (fromIntegral (funct3 funct3') `shiftL` 12)
+ .|. (fromIntegral (xRegister rs1) `shiftL` 15)
+ .|. (fromIntegral (xRegister rs2) `shiftL` 20)
+ .|. ((immediate .&. 0xfe0) `shiftL` 20)
+type' (B immediate funct3' rs1 rs2)
+ = ((immediate .&. 0x800) `shiftR` 4)
+ .|. ((immediate .&. 0x1e) `shiftL` 7)
+ .|. (fromIntegral (funct3 funct3') `shiftL` 12)
+ .|. (fromIntegral (xRegister rs1) `shiftL` 15)
+ .|. (fromIntegral (xRegister rs2) `shiftL` 20)
+ .|. ((immediate .&. 0x7e0) `shiftL` 20)
+ .|. ((immediate .&. 0x1000) `shiftL` 19)
+type' (R rd funct3' rs1 rs2 funct7')
+ = (fromIntegral (xRegister rd) `shiftL` 7)
+ .|. (fromIntegral (funct3 funct3') `shiftL` 12)
+ .|. (fromIntegral (xRegister rs1) `shiftL` 15)
+ .|. (fromIntegral (xRegister rs2) `shiftL` 20)
+ .|. (fromIntegral (funct7 funct7') `shiftL` 25);
+type' (U rd immediate)
+ = (fromIntegral (xRegister rd) `shiftL` 7)
+ .|. (immediate `shiftL` 12)
+type' (J rd immediate)
+ = (fromIntegral (xRegister rd) `shiftL` 7)
+ .|. (immediate .&. 0xff000)
+ .|. ((immediate .&. 0x800) `shiftL` 9)
+ .|. ((immediate .&. 0x7fe) `shiftL` 20)
+ .|. ((immediate .&. 0x100000) `shiftL` 11);
+
+instruction :: Instruction -> ByteString.Builder.Builder
+instruction (Instruction base instructionType)
+ = ByteString.Builder.word32LE
+ $ fromIntegral (baseOpcode base)
+ .|. type' instructionType