Skip to content

Commit

Permalink
Add RV64F floating-point instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
Clo91eaf committed Mar 18, 2024
1 parent a4dbc88 commit 4a58d25
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
33 changes: 33 additions & 0 deletions src/instructions.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -124,6 +151,9 @@ pub enum ImmediateType {
SLLIW,
SRLIW,
SRAIW,

// RV32F
FLW,
}

#[derive(Copy, Clone, Debug)]
Expand All @@ -134,6 +164,8 @@ pub enum StoreType {
SW,
// RV64I
SD,
// RV64D
FSW,
}

#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -199,6 +231,7 @@ impl Inst {
ipt.extend(rv64i());
ipt.extend(rv64m());
ipt.extend(rv64a());
ipt.extend(rv64f());

// self
Inst {
Expand Down
38 changes: 38 additions & 0 deletions src/instructions/rv64f.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use super::*;

#[rustfmt::skip]
fn rv32f() -> Vec<InstPattern> {
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<InstPattern> {
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
}

0 comments on commit 4a58d25

Please sign in to comment.