From 4a58d25d4ab325d397b230e567cdea4864c764f5 Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Mon, 18 Mar 2024 20:56:29 +0800 Subject: [PATCH] Add RV64F floating-point instructions --- src/cpu.rs | 2 +- src/instructions.rs | 33 +++++++++++++++++++++++++++++++++ src/instructions/rv64f.rs | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/instructions/rv64f.rs diff --git a/src/cpu.rs b/src/cpu.rs index 2b4edf3..be6e765 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -480,7 +480,7 @@ impl Cpu { /// Execute a compressed instruction. Raised an exception if something is wrong, otherwise, /// returns a fetched instruction. It also increments the program counter by 2 bytes. - pub fn execute_compressed(&mut self, inst: u64) -> Result<(), Exception> { + fn execute_compressed(&mut self, inst: u64) -> Result<(), Exception> { // 2. Decode. let opcode = inst & 0x3; let funct3 = (inst >> 13) & 0x7; diff --git a/src/instructions.rs b/src/instructions.rs index 90ac453..4eaf309 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -1,9 +1,11 @@ mod rv64i; mod rv64m; mod rv64a; +mod rv64f; use rv64i::rv64i; use rv64m::rv64m; use rv64a::rv64a; +use rv64f::rv64f; #[derive(Copy, Clone, Debug)] pub enum Instruction { @@ -82,6 +84,31 @@ pub enum RegisterType { AMOMAX_D, AMOMINU_D, AMOMAXU_D, + + // RV32F + FADD_S, + FSUB_S, + FMUL_S, + FDIV_S, + FSQRT_S, + FSGNJ_S, + FSGNJN_S, + FSGNJX_S, + FMIN_S, + FMAX_S, + FCVT_W_S, + FMV_X_W, + FEQ_S, + FLT_S, + FLE_S, + FCLASS_S, + FCVT_S_W, + + // RV64F + FCVT_L_S, + FCVT_LU_S, + FCVT_S_L, + FCVT_S_LU, } #[allow(non_camel_case_types)] @@ -124,6 +151,9 @@ pub enum ImmediateType { SLLIW, SRLIW, SRAIW, + + // RV32F + FLW, } #[derive(Copy, Clone, Debug)] @@ -134,6 +164,8 @@ pub enum StoreType { SW, // RV64I SD, + // RV64D + FSW, } #[derive(Copy, Clone, Debug)] @@ -199,6 +231,7 @@ impl Inst { ipt.extend(rv64i()); ipt.extend(rv64m()); ipt.extend(rv64a()); + ipt.extend(rv64f()); // self Inst { diff --git a/src/instructions/rv64f.rs b/src/instructions/rv64f.rs new file mode 100644 index 0000000..8acb0b7 --- /dev/null +++ b/src/instructions/rv64f.rs @@ -0,0 +1,38 @@ +use super::*; + +#[rustfmt::skip] +fn rv32f() -> Vec { + vec![ + InstPattern::new("fadd.s", "0000000 ????? ????? ??? ????? 1010011", Instruction::Register(RegisterType::FADD_S)), + InstPattern::new("fsub.s", "0000100 ????? ????? ??? ????? 1010011", Instruction::Register(RegisterType::FSUB_S)), + InstPattern::new("fmul.s", "0001000 ????? ????? ??? ????? 1010011", Instruction::Register(RegisterType::FMUL_S)), + InstPattern::new("fdiv.s", "0001100 ????? ????? ??? ????? 1010011", Instruction::Register(RegisterType::FDIV_S)), + InstPattern::new("fsqrt.s", "0001100 00000 ????? ??? ????? 1010011", Instruction::Register(RegisterType::FSQRT_S)), + InstPattern::new("fsgnj.s", "0010000 ????? ????? 000 ????? 1010011", Instruction::Register(RegisterType::FSGNJ_S)), + InstPattern::new("fsgnjn.s", "0010000 ????? ????? 001 ????? 1010011", Instruction::Register(RegisterType::FSGNJN_S)), + InstPattern::new("fsgnjx.s", "0010000 ????? ????? 010 ????? 1010011", Instruction::Register(RegisterType::FSGNJX_S)), + InstPattern::new("fmin.s", "0010100 ????? ????? 000 ????? 1010011", Instruction::Register(RegisterType::FMIN_S)), + InstPattern::new("fmax.s", "0010100 ????? ????? 001 ????? 1010011", Instruction::Register(RegisterType::FMAX_S)), + InstPattern::new("fcvt.w.s", "1100000 ????? ????? ??? ????? 1010011", Instruction::Register(RegisterType::FCVT_W_S)), + InstPattern::new("fmv.x.w", "1110000 00000 ????? 000 ????? 1010011", Instruction::Register(RegisterType::FMV_X_W)), + InstPattern::new("feq.s", "1010000 ????? ????? 010 ????? 1010011", Instruction::Register(RegisterType::FEQ_S)), + InstPattern::new("flt.s", "1010000 ????? ????? 001 ????? 1010011", Instruction::Register(RegisterType::FLT_S)), + InstPattern::new("fle.s", "1010000 ????? ????? 000 ????? 1010011", Instruction::Register(RegisterType::FLE_S)), + InstPattern::new("fclass.s", "1110000 00000 ????? 001 ????? 1010011", Instruction::Register(RegisterType::FCLASS_S)), + InstPattern::new("fcvt.s.w", "1101000 00000 ????? ??? ????? 1010011", Instruction::Register(RegisterType::FCVT_S_W)), + InstPattern::new("fmv.w.x", "1111000 00000 ????? 000 ????? 1010011", Instruction::Register(RegisterType::FMV_X_W)), + ] +} + +#[rustfmt::skip] +pub fn rv64f() -> Vec { + let mut f = vec![ + // rv64f + InstPattern::new("fcvt.l.s", "1100000 00010 ????? ??? ????? 1010011", Instruction::Register(RegisterType::FCVT_L_S)), + InstPattern::new("fcvt.lu.s", "1100000 00011 ????? ??? ????? 1010011", Instruction::Register(RegisterType::FCVT_LU_S)), + InstPattern::new("fcvt.s.l", "1101000 00010 ????? ??? ????? 1010011", Instruction::Register(RegisterType::FCVT_S_L)), + InstPattern::new("fcvt.s.lu", "1101000 00011 ????? ??? ????? 1010011", Instruction::Register(RegisterType::FCVT_S_LU)), + ]; + f.extend(rv32f()); + f +}