diff --git a/src/simulator/print.rs b/src/simulator/print.rs index 451d3ef..0567fef 100644 --- a/src/simulator/print.rs +++ b/src/simulator/print.rs @@ -1,5 +1,4 @@ #![allow(dead_code)] -#![allow(unused_variables)] use super::decode::{Instruction}; use super::global::*; @@ -12,6 +11,7 @@ const NAMES_LD: [&str; 7] = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]; const NAMES_OPW: [&str; 8] = ["addw", "sllw", "", "", "", "srw", "", ""]; const NAMES_OPIW: [&str; 8] = ["addiw", "slliw", "", "", "", "sri", "", ""]; + // Register name mapping const REG_X: [&str; 32] = ["zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", @@ -28,6 +28,7 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64 let rd = ins.rd as usize; let rs1 = ins.rs1 as usize; let rs2 = ins.rs2 as usize; + let rs3 = ins.rs3 as usize; match ins.opcode { RISCV_OP => { @@ -118,6 +119,104 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64 format!("{}\t{},{},{}", NAMES_OPW[ins.funct3 as usize], REG_X[rd], REG_X[rs1], REG_X[rs2]) } }, + // RV32F Standard Extension + RISCV_FLW => { + format!("flw\t{},{},({})", REG_F[rd], ins.imm12_I_signed, REG_F[rs1]) + }, + RISCV_FSW => { + format!("fsw\t{},{},({})", REG_F[rs2], "OFFSET TODO", REG_F[rs1]) // TODO Offset in decode + }, + RISCV_FMADD => { + format!("fmadd\t{}{}{}{}", REG_F[rd], REG_F[rs1], REG_F[rs2], REG_F[rs3]) + }, + RISCV_FMSUB => { + format!("fmsub\t{}{}{}{}", REG_F[rd], REG_F[rs1], REG_F[rs2], REG_F[rs3]) + }, + RISCV_FNMSUB => { + format!("fnmsub\t{}{}{}{}", REG_F[rd], REG_F[rs1], REG_F[rs2], REG_F[rs3]) + }, + RISCV_FNMADD => { + format!("fnmadd\t{}{}{}{}", REG_F[rd], REG_F[rs1], REG_F[rs2], REG_F[rs3]) + }, + RISCV_FP => { + let name: &str; + match ins.funct7 { + RISCV_FP_ADD => { + name = "fadd"; + }, + RISCV_FP_SUB => { + name = "fsub"; + }, + RISCV_FP_MUL => { + name = "fmul"; + }, + RISCV_FP_DIV => { + name = "fdiv"; + }, + RISCV_FP_SQRT => { + name = "fsqrt"; + }, + RISCV_FP_FSGN => { + + match ins.funct3 { + RISCV_FP_FSGN_J => { + name = "fsgnj"; + }, + RISCV_FP_FSGN_JN => { + name = "fsgnn"; + }, + RISCV_FP_FSGN_JX => { + name = "fsgnx"; + }, + _ => name = "fsgn" + } + }, + RISCV_FP_MINMAX => { + if ins.funct3 == 0 { + name = "fmin"; + } else { + name = "fmax"; + } + }, + RISCV_FP_FCVTW => { + if rs2 == 0 { + name = "fcvt.w.s"; + } else { + name = "fcvt.wu.s"; + } + + }, + RISCV_FP_FMVXFCLASS => { + if ins.funct3 == 0 { + name = "fmv.x.w"; + } else { + name = "fclass.s"; + } + }, + RISCV_FP_FCMP => { + if ins.funct3 == 0 { + name = "fle.s"; + } else if ins.funct3 == 1 { + name = "flt.s"; + } else { + name = "feq.s"; + } + }, + RISCV_FP_FCVTS => { + if rs2 == 0 { + name = "fcvt.s.w" + } else { + name = "fcvt.s.wu" + } + }, + RISCV_FP_FMVW => { + name = "fmv.w.x"; + }, + _ => name = "todo" + } + format!("{}\t{}{}{}", name, REG_F[rd], REG_F[rs1], REG_F[rs2]) + }, + RISCV_SYSTEM => { "ecall".to_string() }, @@ -226,10 +325,12 @@ mod test { let bne: decode::Instruction = decode::decode(0b0000000_10000_10001_001_00000_1100011); let blt: decode::Instruction = decode::decode(0b0000000_10000_10001_100_00000_1100011); let bge: decode::Instruction = decode::decode(0b0000000_10000_10001_101_00000_1100011); + let bge2: decode::Instruction = decode::decode(0x00f75863); let bltu: decode::Instruction = decode::decode(0b0000000_10000_10001_110_00000_1100011); let bgeu: decode::Instruction = decode::decode(0b0000000_10000_10001_111_00000_1100011); assert_eq!("blt\ta7,a6,0", print::print(blt, 0)); assert_eq!("bge\ta7,a6,0", print::print(bge, 0)); + assert_eq!("bge\ta4,a5,104d4", print::print(bge2, 0x104c4)); assert_eq!("bltu\ta7,a6,0", print::print(bltu, 0)); assert_eq!("bgeu\ta7,a6,0", print::print(bgeu, 0)); assert_eq!("bne\ta7,a6,0", print::print(bne, 0)); @@ -257,10 +358,7 @@ mod test { assert_eq!("lw a5,-20(s0)", print::print(decode::decode(0xfec42783), 0)); assert_eq!("addi a4,a5,0", print::print(decode::decode(0x00078713), 0)); assert_eq!("lw a5,-24(s0)", print::print(decode::decode(0xfe842783), 0)); - - //Waiting for mulw implementation - assert_eq!("mulw a5,a4,a5", print::print(decode::decode(0x02f707bb), 0)); - + assert_eq!("mulw a5,a4,a5", print::print(decode::decode(0x02f707bb), 0)); assert_eq!("sw a5,-20(s0)", print::print(decode::decode(0xfef42623), 0)); assert_eq!("lw a5,-20(s0)", print::print(decode::decode(0xfec42783), 0)); assert_eq!("addi a4,a5,0", print::print(decode::decode(0x00078713), 0));