summaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
authorPete Dietl <petedietl@gmail.com>2024-02-18 13:58:38 -0800
committerRusty Wagner <rusty.wagner@gmail.com>2024-03-08 17:49:09 -0500
commita542d0c9cd33fed5919c3cd9d598bb8d1a300ae8 (patch)
tree93019642e1d3bd4abde648b09e8c3ba40c4eaedd /arch/riscv
parentb25a2b9fadddd07cdd85d69264d7be9de16b2537 (diff)
Fix RISC-V CSRRW, CSRRS, and CSRRC instr disass
Make the CSR instructions show the CSR 12-bit immediate operand as an unsigned integer. This is a special case of the I-instruction format, where it is same except that the 12-bit immediate is treated as unsigned rather than signed.
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/disasm/src/lib.rs53
-rw-r--r--arch/riscv/src/lib.rs6
2 files changed, 49 insertions, 10 deletions
diff --git a/arch/riscv/disasm/src/lib.rs b/arch/riscv/disasm/src/lib.rs
index b9505724..af7cd9a6 100644
--- a/arch/riscv/disasm/src/lib.rs
+++ b/arch/riscv/disasm/src/lib.rs
@@ -87,9 +87,9 @@ pub enum Op<D: RiscVDisassembler> {
// SYSTEM
Ecall,
Ebreak,
- Csrrw(ITypeIntInst<D>),
- Csrrs(ITypeIntInst<D>),
- Csrrc(ITypeIntInst<D>),
+ Csrrw(CsrTypeInst<D>),
+ Csrrs(CsrTypeInst<D>),
+ Csrrc(CsrTypeInst<D>),
CsrrwI(CsrITypeInst<D>),
CsrrsI(CsrITypeInst<D>),
CsrrcI(CsrITypeInst<D>),
@@ -733,6 +733,45 @@ impl<D: RiscVDisassembler> CsrITypeInst<D> {
}
#[derive(Copy, Clone, Debug)]
+pub struct CsrTypeInst<D: RiscVDisassembler> {
+ inst: Instr32,
+ _dis: PhantomData<D>,
+ _rs1: PhantomData<IntReg<D>>,
+}
+
+impl<D: RiscVDisassembler> CsrTypeInst<D> {
+ #[inline(always)]
+ fn new(inst: Instr32) -> DisResult<Self> {
+ let ret = Self {
+ inst,
+ _dis: PhantomData,
+ _rs1: PhantomData,
+ };
+
+ if !ret.rd().valid() || !ret.rs1().valid() {
+ return Err(Error::BadRegister);
+ }
+
+ Ok(ret)
+ }
+
+ #[inline(always)]
+ pub fn rd(&self) -> IntReg<D> {
+ IntReg::new(self.inst.rd())
+ }
+
+ #[inline(always)]
+ pub fn rs1(&self) -> IntReg<D> {
+ IntReg::new(self.inst.rs1())
+ }
+
+ #[inline(always)]
+ pub fn csr(&self) -> u32 {
+ self.inst.i_imm() as u32 & 0xfff
+ }
+}
+
+#[derive(Copy, Clone, Debug)]
pub struct RTypeInst<Rd, Rs1, Rs2>
where
Rd: Register,
@@ -1834,7 +1873,7 @@ impl<D: RiscVDisassembler> Instr<D> {
}
Op::Csrrw(ref i) | Op::Csrrs(ref i) | Op::Csrrc(ref i) => {
ops.push(Operand::R(i.rd()));
- ops.push(Operand::I(i.imm()));
+ ops.push(Operand::I(i.csr() as i32));
ops.push(Operand::R(i.rs1()));
}
Op::CsrrwI(ref i) | Op::CsrrsI(ref i) | Op::CsrrcI(ref i) => {
@@ -3111,9 +3150,9 @@ pub trait RiscVDisassembler: Sized + Copy + Clone {
_ => return Err(InvalidSubop),
}
}
- 0b001 => Op::Csrrw(ITypeIntInst::new(inst)?),
- 0b010 => Op::Csrrs(ITypeIntInst::new(inst)?),
- 0b011 => Op::Csrrc(ITypeIntInst::new(inst)?),
+ 0b001 => Op::Csrrw(CsrTypeInst::new(inst)?),
+ 0b010 => Op::Csrrs(CsrTypeInst::new(inst)?),
+ 0b011 => Op::Csrrc(CsrTypeInst::new(inst)?),
0b101 => Op::CsrrwI(CsrITypeInst::new(inst)?),
0b110 => Op::CsrrsI(CsrITypeInst::new(inst)?),
0b111 => Op::CsrrcI(CsrITypeInst::new(inst)?),
diff --git a/arch/riscv/src/lib.rs b/arch/riscv/src/lib.rs
index d8f6cff5..8b9fde31 100644
--- a/arch/riscv/src/lib.rs
+++ b/arch/riscv/src/lib.rs
@@ -1314,7 +1314,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
Op::Csrrw(i) => {
let rd = Register::from(i.rd());
let rs1 = Liftable::lift(il, Register::from(i.rs1()));
- let csr = il.const_int(4, i.imm() as u64);
+ let csr = il.const_int(4, i.csr() as u64);
if i.rd().id() == 0 {
il.intrinsic(Lifter::<Self>::NO_OUTPUTS, Intrinsic::Csrwr, [csr, rs1])
@@ -1326,7 +1326,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
Op::Csrrs(i) => {
let rd = Register::from(i.rd());
let rs1 = Liftable::lift(il, Register::from(i.rs1()));
- let csr = il.const_int(4, i.imm() as u64);
+ let csr = il.const_int(4, i.csr() as u64);
if i.rs1().id() == 0 {
il.intrinsic([rd], Intrinsic::Csrrd, [csr]).append();
@@ -1337,7 +1337,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
Op::Csrrc(i) => {
let rd = Register::from(i.rd());
let rs1 = Liftable::lift(il, Register::from(i.rs1()));
- let csr = il.const_int(4, i.imm() as u64);
+ let csr = il.const_int(4, i.csr() as u64);
if i.rs1().id() == 0 {
il.intrinsic([rd], Intrinsic::Csrrd, [csr]).append();