diff options
Diffstat (limited to 'lib/Language/Elna/Architecture')
| -rw-r--r-- | lib/Language/Elna/Architecture/RiscV.hs | 286 |
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 |
