From 6829858f18935779d41b0acc3523cf070f0487c9 Mon Sep 17 00:00:00 2001 From: plucky Date: Wed, 15 Nov 2023 11:13:34 +0800 Subject: [PATCH] =?UTF-8?q?asm/rvzicsr:=20=E6=B7=BB=E5=8A=A0CSR=E6=8C=87?= =?UTF-8?q?=E4=BB=A4=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为了实现构造函数,完善了其他相关模块的内容 为IType实现new_csr_uimm,csr,uimm5 为IntUsigned实现了fmt::Debug Signed-off-by: plucky --- src/asm.rs | 24 ++++++++- src/asm/rv32i.rs | 2 +- src/asm/rvzicsr.rs | 124 ++++++++++++++++++++++++++++++++++++++++++++- src/value/int.rs | 14 +++++ 4 files changed, 161 insertions(+), 3 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index c15e4f7..de6e67d 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -3,7 +3,7 @@ pub mod rv32i; pub mod rv64i; pub mod rvzicsr; -use crate::value::IntSigned; +use crate::value::{IntSigned, IntUnsigned}; use core::fmt; #[derive(Clone, Copy, PartialEq, Eq)] @@ -105,6 +105,22 @@ impl IType { | opcode.bits() as u32, ) } + + pub fn new_csr_uimm( + opcode: Opcode, + funct3: Funct3, + rd: RegInteger, + csr: IntUnsigned<12, 0>, + uimm5: IntUnsigned<5, 0>, + ) -> Self { + Self( + (u32::try_from(csr).unwrap() << 20) + | (u32::try_from(uimm5).unwrap() << 15) + | (funct3.bits() as u32) << 12 + | ((rd as u32) << 7) + | opcode.bits() as u32, + ) + } pub const fn from_bits(bits: u32) -> Self { Self(bits) } @@ -129,6 +145,12 @@ impl IType { pub const fn shamt5(self) -> IntSigned<5, 0> { IntSigned::new_lsb(self.0 >> 20) } + pub const fn csr(self) -> IntUnsigned<12, 0> { + IntUnsigned::new_lsb(self.0 >> 20) + } + pub const fn uimm5(self) -> IntUnsigned<5, 0> { + IntUnsigned::new_lsb((self.0 >> 15) & 0b1_1111) + } } impl fmt::Debug for IType { diff --git a/src/asm/rv32i.rs b/src/asm/rv32i.rs index 56bc456..816da78 100644 --- a/src/asm/rv32i.rs +++ b/src/asm/rv32i.rs @@ -11,7 +11,7 @@ const OPCODE_LUI: Opcode = Opcode::from_bits(0b011_0111); const OPCODE_BRANCH: Opcode = Opcode::from_bits(0b110_0011); const OPCODE_JALR: Opcode = Opcode::from_bits(0b110_0111); const OPCODE_JAL: Opcode = Opcode::from_bits(0b110_1111); -const OPCODE_SYSTEM: Opcode = Opcode::from_bits(0b111_0011); +pub(crate) const OPCODE_SYSTEM: Opcode = Opcode::from_bits(0b111_0011); const FUNCT3_JALR_JALR: Funct3 = Funct3::from_bits(0b000); const FUNCT3_BRANCH_BEQ: Funct3 = Funct3::from_bits(0b000); diff --git a/src/asm/rvzicsr.rs b/src/asm/rvzicsr.rs index 348d0d3..cbd779c 100644 --- a/src/asm/rvzicsr.rs +++ b/src/asm/rvzicsr.rs @@ -1,7 +1,10 @@ // csrrw, csrrs, csrrc // csrriw, csrrsi, csrrci -use super::Funct3; +use super::{Funct3, IType, RegInteger}; +use crate::asm::rv32i::OPCODE_SYSTEM; +use crate::value::IntUnsigned; +use core::fmt; const FUNCT3_SYSTEM_CSRRW: Funct3 = Funct3::from_bits(0b001); const FUNCT3_SYSTEM_CSRRS: Funct3 = Funct3::from_bits(0b010); @@ -9,3 +12,122 @@ const FUNCT3_SYSTEM_CSRRC: Funct3 = Funct3::from_bits(0b011); const FUNCT3_SYSTEM_CSRRWI: Funct3 = Funct3::from_bits(0b101); const FUNCT3_SYSTEM_CSRRSI: Funct3 = Funct3::from_bits(0b110); const FUNCT3_SYSTEM_CSRRCI: Funct3 = Funct3::from_bits(0b111); + +#[derive(Clone, Copy)] +pub enum InsnRVZicsr { + Csrrw(IType), + Csrrs(IType), + Csrrc(IType), + Csrrwi(IType), + Csrrsi(IType), + Csrrci(IType), +} + +impl fmt::Debug for InsnRVZicsr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Csrrw(i) => write!(f, "csrrw {:?}, {:?}, {:?}", i.rd(), i.csr(), i.rs1()), + Self::Csrrs(i) => write!(f, "csrri {:?}, {:?}, {:?}", i.rd(), i.csr(), i.rs1()), + Self::Csrrc(i) => write!(f, "csrrc {:?}, {:?}, {:?}", i.rd(), i.csr(), i.rs1()), + Self::Csrrwi(i) => write!(f, "csrrc {:?}, {:?}, {:?}", i.rd(), i.csr(), i.uimm5()), + Self::Csrrsi(i) => write!(f, "csrrc {:?}, {:?}, {:?}", i.rd(), i.csr(), i.uimm5()), + Self::Csrrci(i) => write!(f, "csrrc {:?}, {:?}, {:?}", i.rd(), i.csr(), i.uimm5()), + } + } +} + +pub fn csrrw(rd: RegInteger, csr: impl Into>, rs: RegInteger) -> T +where + InsnRVZicsr: Into, +{ + InsnRVZicsr::Csrrw(IType::new( + OPCODE_SYSTEM, + FUNCT3_SYSTEM_CSRRW, + rd, + rs, + csr.into().signed(), + )) + .into() +} + +pub fn csrrs(rd: RegInteger, csr: impl Into>, rs: RegInteger) -> T +where + InsnRVZicsr: Into, +{ + InsnRVZicsr::Csrrs(IType::new( + OPCODE_SYSTEM, + FUNCT3_SYSTEM_CSRRS, + rd, + rs, + csr.into().signed(), + )) + .into() +} + +pub fn csrrc(rd: RegInteger, csr: impl Into>, rs: RegInteger) -> T +where + InsnRVZicsr: Into, +{ + InsnRVZicsr::Csrrc(IType::new( + OPCODE_SYSTEM, + FUNCT3_SYSTEM_CSRRC, + rd, + rs, + csr.into().signed(), + )) + .into() +} + +pub fn csrrwi( + rd: RegInteger, + csr: impl Into>, + uimm: impl Into>, +) -> T +where + InsnRVZicsr: Into, +{ + InsnRVZicsr::Csrrwi(IType::new_csr_uimm( + OPCODE_SYSTEM, + FUNCT3_SYSTEM_CSRRWI, + rd, + csr.into(), + uimm.into(), + )) + .into() +} + +pub fn csrrsi( + rd: RegInteger, + csr: impl Into>, + uimm: impl Into>, +) -> T +where + InsnRVZicsr: Into, +{ + InsnRVZicsr::Csrrsi(IType::new_csr_uimm( + OPCODE_SYSTEM, + FUNCT3_SYSTEM_CSRRSI, + rd, + csr.into(), + uimm.into(), + )) + .into() +} + +pub fn csrrci( + rd: RegInteger, + csr: impl Into>, + uimm: impl Into>, +) -> T +where + InsnRVZicsr: Into, +{ + InsnRVZicsr::Csrrci(IType::new_csr_uimm( + OPCODE_SYSTEM, + FUNCT3_SYSTEM_CSRRCI, + rd, + csr.into(), + uimm.into(), + )) + .into() +} diff --git a/src/value/int.rs b/src/value/int.rs index b79b43e..0423183 100644 --- a/src/value/int.rs +++ b/src/value/int.rs @@ -35,6 +35,12 @@ impl fmt::Debug for IntSigned { } } +impl fmt::Debug for IntUnsigned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.value.fmt(f) + } +} + impl SignExtend for IntSigned { fn sext(self) -> IntSigned { let mut ans = self.value; @@ -100,6 +106,14 @@ impl TryFrom> for u32 { } } +impl TryFrom> for u32 { + type Error = TryFromIntError; + + fn try_from(src: IntUnsigned) -> Result { + Ok(src.value) + } +} + impl TryFrom for IntSigned { type Error = TryFromIntError; -- Gitee