Skip to content

Commit

Permalink
Merge pull request #8 from Alignof/develop
Browse files Browse the repository at this point in the history
Ver 0.1.3
  • Loading branch information
Alignof authored Oct 17, 2023
2 parents 352a0ed + 761e7a8 commit b044a2e
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 60 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
- run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
[package]
name = "raki"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
authors = ["Norimasa Takana <[email protected]>"]
repository = "https://github.com/Alignof/raki"
keywords = ["risc-v", "docoder"]
description = "RISC-V instruction decoder written in Rust."
license = "MIT"

Expand Down
4 changes: 3 additions & 1 deletion src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ pub enum DecodingError {
InvalidFunct7,
/// Has an opcode that cannot be decoded.
InvalidOpcode,
/// This instruction is included in the unknown extension.
UnknownExtension,
/// Illegal instruction (e.g. all zero value instruction)
IllegalInstruction,
/// This instruction is only for Rv64 but appeared at Rv32.
Expand Down Expand Up @@ -110,7 +112,7 @@ trait DecodeUtil {
fn set(self, mask: &[u32]) -> u32;

/// Get `Extensions` from a u16/u32 value.
fn extension(self) -> Extensions;
fn extension(self) -> Result<Extensions, DecodingError>;

/// Convert i32 to a sign-extended any size number.
/// # Arguments
Expand Down
14 changes: 7 additions & 7 deletions src/decode/inst_16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,35 +32,35 @@ impl Decode for u16 {

fn parse_opcode(self, isa: Isa) -> Result<OpcodeKind, DecodingError> {
match self.extension() {
Extensions::C => c_extension::parse_opcode(self, isa),
Ok(Extensions::C) => c_extension::parse_opcode(self, isa),
_ => Err(DecodingError::Not16BitInst),
}
}

fn parse_rd(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError> {
match self.extension() {
Extensions::C => c_extension::parse_rd(self, opkind),
Ok(Extensions::C) => c_extension::parse_rd(self, opkind),
_ => Err(DecodingError::Not16BitInst),
}
}

fn parse_rs1(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError> {
match self.extension() {
Extensions::C => c_extension::parse_rs1(self, opkind),
Ok(Extensions::C) => c_extension::parse_rs1(self, opkind),
_ => Err(DecodingError::Not16BitInst),
}
}

fn parse_rs2(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError> {
match self.extension() {
Extensions::C => c_extension::parse_rs2(self, opkind),
Ok(Extensions::C) => c_extension::parse_rs2(self, opkind),
_ => Err(DecodingError::Not16BitInst),
}
}

fn parse_imm(self, opkind: &OpcodeKind, _isa: Isa) -> Result<Option<i32>, DecodingError> {
match self.extension() {
Extensions::C => c_extension::parse_imm(self, opkind),
Ok(Extensions::C) => c_extension::parse_imm(self, opkind),
_ => Err(DecodingError::Not16BitInst),
}
}
Expand All @@ -80,8 +80,8 @@ impl DecodeUtil for u16 {
inst
}

fn extension(self) -> Extensions {
Extensions::C
fn extension(self) -> Result<Extensions, DecodingError> {
Ok(Extensions::C)
}
}

Expand Down
87 changes: 46 additions & 41 deletions src/decode/inst_32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,56 +32,61 @@ impl Decode for u32 {

fn parse_opcode(self, isa: Isa) -> Result<OpcodeKind, DecodingError> {
match self.extension() {
Extensions::BaseI => base_i::parse_opcode(self, isa),
Extensions::M => m_extension::parse_opcode(self, isa),
Extensions::A => a_extension::parse_opcode(self, isa),
Extensions::Zicsr => zicsr_extension::parse_opcode(self),
Extensions::Priv => priv_extension::parse_opcode(self),
Extensions::C => Err(DecodingError::Not32BitInst),
Ok(Extensions::BaseI) => base_i::parse_opcode(self, isa),
Ok(Extensions::M) => m_extension::parse_opcode(self, isa),
Ok(Extensions::A) => a_extension::parse_opcode(self, isa),
Ok(Extensions::Zicsr) => zicsr_extension::parse_opcode(self),
Ok(Extensions::Priv) => priv_extension::parse_opcode(self),
Ok(Extensions::C) => Err(DecodingError::Not32BitInst),
Err(decoding_err) => Err(decoding_err),
}
}

fn parse_rd(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError> {
match self.extension() {
Extensions::BaseI => base_i::parse_rd(self, opkind),
Extensions::M => m_extension::parse_rd(self, opkind),
Extensions::A => a_extension::parse_rd(self, opkind),
Extensions::Zicsr => zicsr_extension::parse_rd(self, opkind),
Extensions::Priv => priv_extension::parse_rd(self, opkind),
Extensions::C => Err(DecodingError::Not32BitInst),
Ok(Extensions::BaseI) => base_i::parse_rd(self, opkind),
Ok(Extensions::M) => m_extension::parse_rd(self, opkind),
Ok(Extensions::A) => a_extension::parse_rd(self, opkind),
Ok(Extensions::Zicsr) => zicsr_extension::parse_rd(self, opkind),
Ok(Extensions::Priv) => priv_extension::parse_rd(self, opkind),
Ok(Extensions::C) => Err(DecodingError::Not32BitInst),
Err(decoding_err) => Err(decoding_err),
}
}

fn parse_rs1(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError> {
match self.extension() {
Extensions::BaseI => base_i::parse_rs1(self, opkind),
Extensions::M => m_extension::parse_rs1(self, opkind),
Extensions::A => a_extension::parse_rs1(self, opkind),
Extensions::Zicsr => zicsr_extension::parse_rs1(self, opkind),
Extensions::Priv => priv_extension::parse_rs1(self, opkind),
Extensions::C => Err(DecodingError::Not32BitInst),
Ok(Extensions::BaseI) => base_i::parse_rs1(self, opkind),
Ok(Extensions::M) => m_extension::parse_rs1(self, opkind),
Ok(Extensions::A) => a_extension::parse_rs1(self, opkind),
Ok(Extensions::Zicsr) => zicsr_extension::parse_rs1(self, opkind),
Ok(Extensions::Priv) => priv_extension::parse_rs1(self, opkind),
Ok(Extensions::C) => Err(DecodingError::Not32BitInst),
Err(decoding_err) => Err(decoding_err),
}
}

fn parse_rs2(self, opkind: &OpcodeKind) -> Result<Option<usize>, DecodingError> {
match self.extension() {
Extensions::BaseI => base_i::parse_rs2(self, opkind),
Extensions::M => m_extension::parse_rs2(self, opkind),
Extensions::A => a_extension::parse_rs2(self, opkind),
Extensions::Zicsr => zicsr_extension::parse_rs2(self, opkind),
Extensions::Priv => priv_extension::parse_rs2(self, opkind),
Extensions::C => Err(DecodingError::Not32BitInst),
Ok(Extensions::BaseI) => base_i::parse_rs2(self, opkind),
Ok(Extensions::M) => m_extension::parse_rs2(self, opkind),
Ok(Extensions::A) => a_extension::parse_rs2(self, opkind),
Ok(Extensions::Zicsr) => zicsr_extension::parse_rs2(self, opkind),
Ok(Extensions::Priv) => priv_extension::parse_rs2(self, opkind),
Ok(Extensions::C) => Err(DecodingError::Not32BitInst),
Err(decoding_err) => Err(decoding_err),
}
}

fn parse_imm(self, opkind: &OpcodeKind, isa: Isa) -> Result<Option<i32>, DecodingError> {
match self.extension() {
Extensions::BaseI => base_i::parse_imm(self, opkind, isa),
Extensions::M => m_extension::parse_imm(self, opkind),
Extensions::A => a_extension::parse_imm(self, opkind),
Extensions::Zicsr => zicsr_extension::parse_imm(self, opkind),
Extensions::Priv => priv_extension::parse_imm(self, opkind),
Extensions::C => Err(DecodingError::Not32BitInst),
Ok(Extensions::BaseI) => base_i::parse_imm(self, opkind, isa),
Ok(Extensions::M) => m_extension::parse_imm(self, opkind),
Ok(Extensions::A) => a_extension::parse_imm(self, opkind),
Ok(Extensions::Zicsr) => zicsr_extension::parse_imm(self, opkind),
Ok(Extensions::Priv) => priv_extension::parse_imm(self, opkind),
Ok(Extensions::C) => Err(DecodingError::Not32BitInst),
Err(decoding_err) => Err(decoding_err),
}
}
}
Expand All @@ -100,30 +105,30 @@ impl DecodeUtil for u32 {
inst
}

fn extension(self) -> Extensions {
fn extension(self) -> Result<Extensions, DecodingError> {
let opmap: u8 = self.slice(6, 0) as u8;
let funct3: u8 = self.slice(14, 12) as u8;
let funct7: u8 = self.slice(31, 25) as u8;

match opmap {
0b010_1111 => Extensions::A,
0b010_1111 => Ok(Extensions::A),
0b011_0011 => match funct7 {
0b000_0001 => Extensions::M,
_ => Extensions::BaseI,
0b000_0001 => Ok(Extensions::M),
_ => Ok(Extensions::BaseI),
},
0b011_1011 => match funct7 {
0b000_0000 | 0b010_0000 => Extensions::BaseI,
0b000_0001 => Extensions::M,
_ => unreachable!(),
0b000_0000 | 0b010_0000 => Ok(Extensions::BaseI),
0b000_0001 => Ok(Extensions::M),
_ => Err(DecodingError::UnknownExtension),
},
0b111_0011 => match funct3 {
0b000 => match funct7 {
0b000_0000 => Extensions::BaseI,
_ => Extensions::Priv,
0b000_0000 => Ok(Extensions::BaseI),
_ => Ok(Extensions::Priv),
},
_ => Extensions::Zicsr,
_ => Ok(Extensions::Zicsr),
},
_ => Extensions::BaseI,
_ => Ok(Extensions::BaseI),
}
}
}
Expand Down
32 changes: 28 additions & 4 deletions src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct Instruction {
impl Display for Instruction {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.inst_format {
InstFormat::Rformat | InstFormat::Mformat | InstFormat::Aformat => {
InstFormat::Rformat | InstFormat::Mformat => {
write!(
f,
"{} {}, {}, {}",
Expand All @@ -36,6 +36,23 @@ impl Display for Instruction {
reg2str(self.rs2.unwrap())
)
}
InstFormat::Aformat => match self.opc {
OpcodeKind::LR_W | OpcodeKind::LR_D => write!(
f,
"{} {}, {}",
self.opc.to_string(),
reg2str(self.rd.unwrap()),
reg2str(self.rs1.unwrap()),
),
_ => write!(
f,
"{} {}, {}, {}",
self.opc.to_string(),
reg2str(self.rd.unwrap()),
reg2str(self.rs1.unwrap()),
reg2str(self.rs2.unwrap())
),
},
InstFormat::R_SHAMTformat => {
write!(
f,
Expand Down Expand Up @@ -102,13 +119,20 @@ impl Display for Instruction {
)
}
InstFormat::CRformat => match self.opc {
OpcodeKind::C_JR | OpcodeKind::C_JALR => {
OpcodeKind::C_JR => {
write!(
f,
"{} zero, 0({})",
self.opc.to_string(),
reg2str(self.rs1.unwrap()),
)
}
OpcodeKind::C_JALR => {
write!(
f,
"{} {}, 0({})",
"{} ra, 0({})",
self.opc.to_string(),
reg2str(self.rs1.unwrap()),
self.rs2.unwrap()
)
}
OpcodeKind::C_MV => write!(
Expand Down
8 changes: 2 additions & 6 deletions src/instruction/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,8 @@ impl OpcodeKind {
OpcodeKind::ECALL | OpcodeKind::FENCE | OpcodeKind::EBREAK => InstFormat::Uncategorized,

// Zicsr
OpcodeKind::CSRRW
| OpcodeKind::CSRRS
| OpcodeKind::CSRRC
| OpcodeKind::CSRRWI
| OpcodeKind::CSRRSI
| OpcodeKind::CSRRCI => InstFormat::CSRuiformat,
OpcodeKind::CSRRW | OpcodeKind::CSRRS | OpcodeKind::CSRRC => InstFormat::CSRformat,
OpcodeKind::CSRRWI | OpcodeKind::CSRRSI | OpcodeKind::CSRRCI => InstFormat::CSRuiformat,

// Privileged
OpcodeKind::SRET | OpcodeKind::MRET | OpcodeKind::WFI => InstFormat::Uncategorized,
Expand Down

0 comments on commit b044a2e

Please sign in to comment.