diff options
Diffstat (limited to 'arch/riscv')
| -rw-r--r-- | arch/riscv/disasm/src/lib.rs | 53 | ||||
| -rw-r--r-- | arch/riscv/src/lib.rs | 6 |
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(); |
