Skip to content

Commit

Permalink
Add RV_C disassembly
Browse files Browse the repository at this point in the history
Implement basic disassembly for RV_C (compressed instructions).
Only the compressed instruction and given operands are shown
in the printed output. No expansion to non-compressed instructions or
insertion of implicit operands is performed.
Simplicity was the aim, given the high number array of special cases.
  • Loading branch information
elliotb-lowrisc committed Aug 2, 2024
1 parent 52a4e6e commit f5cee0c
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 3 deletions.
113 changes: 113 additions & 0 deletions src/RISCV/Helpers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,26 @@ module RISCV.Helpers (
, prettyR_rm
, prettyR4_rm
, prettyS_F
, prettyCR
, prettyCR_1op
, prettyCI
, prettyCI_sig
, prettyCI_F
, prettyCI_reg
, prettyCI_imm
, prettyCI_sig_imm
, prettyCSS
, prettyCSS_F
, prettyCIW
, prettyCL
, prettyCL_F
, prettyCS
, prettyCS_F
, prettyCA
, prettyCB
, prettyCB_sig
, prettyCB_reg
, prettyCJ
-- * Others
, reg
, int
Expand Down Expand Up @@ -204,6 +224,28 @@ toSigned :: (Ord a, Num a) => Int -> a -> a
toSigned w x | x >= 0 = if x >= 2^(w-1) then x - 2^w else x
| otherwise = error $ "cannot toSigned on negative number"

-- | RVC compressed integer register pretty printer
reg' :: Integer -> String
reg' = cIntReg

-- | Gives a RISCV register name 'String' when provided an RVC compressed
-- integer register index
cIntReg :: Integer -> String
cIntReg i
| i >= 0 && i < 8 = intReg (i + 8)
| otherwise = "unknownCompressedRegIdx" ++ show i

-- | RVC compressed floating-point register pretty printer
fpReg' :: Integer -> String
fpReg' = cFpReg

-- | Gives a RISCV floating point register name 'String' when provided an
-- RVC compressed floating-point register index
cFpReg :: Integer -> String
cFpReg i
| i >= 0 && i < 8 = fpReg (i + 8)
| otherwise = "unknownCompressedRegIdx" ++ show i


-- ** Instructions

Expand Down Expand Up @@ -326,6 +368,77 @@ prettyR4_rm instr rs3 rs2 rs1 rm rd =
prettyS_F instr imm rs2 rs1 =
concat [instr, " ", fpReg rs2, ", ", reg rs1, "(", int imm, ")"]

-- ** Compressed Instructions

-- | CR-type 'Register' compressed instruction pretty printer
prettyCR instr rs2 rs1_rd =
concat [instr, " ", reg rs1_rd, ", ", reg rs2]
-- | CR-type (single-operand variant)
prettyCR_1op instr rs1_rd =
concat [instr, " ", reg rs1_rd]

-- | CI-type 'Immediate' compressed instruction pretty printer
prettyCI instr imm rs1_rd =
concat [instr, " ", reg rs1_rd, ", ", int imm]
-- | CI-type (signed variant)
prettyCI_sig ise instr imm rs1_rd =
concat [instr, " ", reg rs1_rd, ", ", int $ toSigned ise imm]
-- | CI-type (floating-point variant)
prettyCI_F instr imm rs1_rd =
concat [instr, " ", fpReg rs1_rd, ", ", int imm]
-- | CI-type (register-only variant)
prettyCI_reg instr rs1_rd =
concat [instr, " ", reg rs1_rd]
-- | CI-type (immediate-only variant)
prettyCI_imm instr imm =
concat [instr, " ", int imm]
-- | CI-type (signed immediate-only variant)
prettyCI_sig_imm ise instr imm =
concat [instr, " ", int $ toSigned ise imm]

-- | CSS-type 'Stack-relative Store' compressed instruction pretty printer
prettyCSS instr imm rs2 =
concat [instr, " ", reg rs2, ", ", int imm]
-- | CSS-type (floating-point variant)
prettyCSS_F instr imm rs2 =
concat [instr, " ", fpReg rs2, ", ", int imm]

-- | CIW-type 'Wide-Immediate' compressed instruction pretty printer
prettyCIW instr imm rd' =
concat [instr, " ", reg' rd', ", ", int imm]

-- | CL-type 'Load' compressed instruction pretty printer
prettyCL instr imm rd' rs1' =
concat [instr, " ", reg' rd', ", ", reg' rs1', "[", int imm, "]"]
-- | CL-type (floating-point variant)
prettyCL_F instr imm rd' rs1' =
concat [instr, " ", fpReg' rd', ", ", reg' rs1', "[", int imm, "]"]

-- | CS-type 'Store' compressed instruction pretty printer
prettyCS instr imm rs1' rs2' =
concat [instr, " ", reg' rs2', ", ", reg' rs1', "[", int imm, "]"]
-- | CS-type (floating-point variant)
prettyCS_F instr imm rs1' rs2' =
concat [instr, " ", fpReg' rs2', ", ", reg' rs1', "[", int imm, "]"]

-- | CA-type 'Arithmetic' compressed instruction pretty printer
prettyCA instr rs1_rd' rs2' =
concat [instr, " ", reg' rs1_rd', ", ", reg' rs2']

-- | CB-type 'Branch' compressed instruction pretty printer
prettyCB instr imm rs1' =
concat [instr, " ", reg' rs1', ", ", int imm]
-- | CB-type (signed variant)
prettyCB_sig ise instr imm rs1' =
concat [instr, " ", reg' rs1', ", ", int $ toSigned ise imm]
-- | CB-type (register-only variant)
prettyCB_reg instr rs1' =
concat [instr, " ", reg' rs1']

-- | CJ-type 'Jump' compressed instruction pretty printer
prettyCJ instr imm =
concat [instr, " ", int $ toSigned 12 imm]

type ExtractedRegs = ( Bool -- ^ is_bypass
, Maybe Integer -- ^ rs2
, Maybe Integer -- ^ rs1
Expand Down
2 changes: 2 additions & 0 deletions src/RISCV/InstInspect.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import RISCV.RV64_M
import RISCV.RV64_A
import RISCV.RV64_F
import RISCV.RV64_D
import RISCV.RV_C
import RISCV.Helpers

import Text.Printf
Expand All @@ -85,6 +86,7 @@ rv_pretty instr = case decode 32 instr instList of
++ rv32_zicsr_disass
++ rv32_zifencei_disass
++ rv32_xcheri_disass
++ rv_c_disass

instance Show Instruction where
show i@(MkInstruction v) = printf ".4byte 0x%08x # %s" v (rv_pretty i)
Expand Down
73 changes: 70 additions & 3 deletions src/RISCV/RV_C.hs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ module RISCV.RV_C (
, rv_c
) where

import RISCV.Helpers (prettyCR, prettyCR_1op,
prettyCI, prettyCI_sig, prettyCI_F, prettyCI_reg,prettyCI_imm, prettyCI_sig_imm,
prettyCSS, prettyCSS_F,
prettyCIW,
prettyCL, prettyCL_F,
prettyCS, prettyCS_F,
prettyCA,
prettyCB, prettyCB_sig, prettyCB_reg,
prettyCJ)
import InstrCodec (DecodeBranch, (-->), encode, Instruction)

c_illegal_raw = "000 00000000 000 00"
Expand Down Expand Up @@ -210,11 +219,69 @@ c_fswsp rs2 uimm = encode c_fswsp_raw uimm
c_sdsp_raw = "111 uimm[5:3] uimm[8:6] rs2[4:0] 10"
c_sdsp rs2 uimm = encode c_sdsp_raw uimm rs2

-- | TODO Dissassembly of RISC-V compressed instructions
-- | Dissassembly of RISC-V compressed instructions padded to 32-bits.
-- | No instruction expansion or implicit operands are shown.
-- |
-- | Note: left-shifting of RV_C immediates is done in `decode`,
-- | not in the pretty printing functions.
pad :: String -> String
pad = (++) "0000000000000000"
rv_c_disass :: [DecodeBranch String]
rv_c_disass = []
rv_c_disass = [ pad c_illegal_raw --> "c.illegal"
, pad c_addi4spn_raw --> prettyCIW "c.addi4spn"
, pad c_fld_raw --> prettyCL_F "c.fld"
, pad c_flq_raw --> prettyCL_F "c.flq"
, pad c_lw_raw --> prettyCL "c.lw"
, pad c_flw_raw --> prettyCL_F "c.flw"
, pad c_ld_raw --> prettyCL "c.ld"
-- , c_res_a_raw
, pad c_fsd_raw --> prettyCS_F "c.fsd"
, pad c_fsq_raw --> prettyCS_F "c.fsq"
, pad c_sw_raw --> prettyCS "c.sw"
, pad c_fsw_raw --> prettyCS_F "c.fsw"
, pad c_sd_raw --> prettyCS "c.sd"
, pad c_nop_raw --> prettyCI_imm "c.nop"
, pad c_addi_raw --> prettyCI_sig 6 "c.addi"
, pad c_jal_raw --> prettyCJ "c.jal"
, pad c_addiw_raw --> prettyCI_sig 6 "c.addiw"
, pad c_li_raw --> prettyCI_sig 6 "c.li"
, pad c_addi16sp_raw --> prettyCI_sig_imm 10 "c.addi16sp"
, pad c_lui_raw --> prettyCI_sig 18 "c.lui"
, pad c_srli64_raw --> prettyCB_reg "c.srli64"
, pad c_srli_raw --> prettyCB "c.srli"
, pad c_srai64_raw --> prettyCB_reg "c.srai64"
, pad c_srai_raw --> prettyCB "c.srai"
, pad c_andi_raw --> prettyCB_sig 6 "c.andi"
, pad c_sub_raw --> prettyCA "c.sub"
, pad c_xor_raw --> prettyCA "c.xor"
, pad c_or_raw --> prettyCA "c.or"
, pad c_and_raw --> prettyCA "c.and"
, pad c_subw_raw --> prettyCA "c.subw"
, pad c_addw_raw --> prettyCA "c.addw"
-- , c_res_b_raw
-- , c_res_c_raw
, pad c_j_raw --> prettyCJ "c.j"
, pad c_beqz_raw --> prettyCB_sig 9 "c.beqz"
, pad c_bnez_raw --> prettyCB_sig 9 "c.bnez"
, pad c_slli64_raw --> prettyCI_reg "c.slli64"
, pad c_slli_raw --> prettyCI "c.slli"
, pad c_fldsp_raw --> prettyCI_F "c.fldsp"
, pad c_lqsp_raw --> prettyCI "c.lqsp"
, pad c_lwsp_raw --> prettyCI "c.lwsp"
, pad c_flwsp_raw --> prettyCI_F "c.flwsp"
, pad c_ldsp_raw --> prettyCI "c.ldsp"
, pad c_jr_raw --> prettyCR_1op "c.jr"
, pad c_mv_raw --> prettyCR "c.mv"
, pad c_ebreak_raw --> "c.ebreak"
, pad c_jalr_raw --> prettyCR_1op "c.jalr"
, pad c_add_raw --> prettyCR "c.add"
, pad c_fsdsp_raw --> prettyCSS_F "c.fsdsp"
, pad c_sqsp_raw --> prettyCSS "c.sqsp"
, pad c_swsp_raw --> prettyCSS "c.swsp"
, pad c_fswsp_raw --> prettyCSS_F "c.fswsp"
, pad c_sdsp_raw --> prettyCSS "c.sdsp" ]

-- | TODO List of RISC-V compressed instructions
-- | List of RISC-V compressed instructions
rv_c :: Integer -> Integer -> Integer -> Integer
-> Integer -> Integer -> Integer -> Integer
-> Integer -> Integer -> Integer
Expand Down

0 comments on commit f5cee0c

Please sign in to comment.