From 0c5012c16217a96aa9fb058a7a1f6b1c66b975eb Mon Sep 17 00:00:00 2001 From: Samy Solhi Date: Wed, 26 Oct 2022 13:31:40 +0200 Subject: [PATCH] add print.rs file --- src/print.rs | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 src/print.rs diff --git a/src/print.rs b/src/print.rs new file mode 100644 index 0000000..13a54d0 --- /dev/null +++ b/src/print.rs @@ -0,0 +1,267 @@ +pub struct Instruction { + value : u64, + + opcode : u8, + rs1 : u8, + rs2 : u8, + rs3 : u8, + rd : u8, + funct7 : u8, + funct7_smaller : u8, + funct3 : u8, + shamt : u8, + + imm12_I : u16, + imm12_S : u16, + + imm12_I_signed : i16, + imm12_S_signed : i16, + imm13 : i16, + imm13_signed : i16, + + imm31_12 : u32, + imm21_1 : u32, + + imm31_12_signed : i32, + imm21_1_signed : i32, +} + +const RISCV_LUI: u8 = 0x37; +const RISCV_AUIPC: u8 = 0x17; +const RISCV_JAL: u8 = 0x6f; +const RISCV_JALR: u8 = 0x67; +const RISCV_BR: u8 = 0x63; +const RISCV_LD: u8 = 0x3; +const RISCV_ST: u8 = 0x23; +const RISCV_OPI: u8 = 0x13; +const RISCV_OP: u8 = 0x33; +const RISCV_OPIW: u8 = 0x1b; +const RISCV_OPW: u8 = 0x3b; + + +const RISCV_BR_BEQ: u8 = 0x0; +const RISCV_BR_BNE: u8 = 0x1; +const RISCV_BR_BLT: u8 = 0x4; +const RISCV_BR_BGE: u8 = 0x5; +const RISCV_BR_BLTU: u8 = 0x6; +const RISCV_BR_BGEU: u8 = 0x7; + +const RISCV_LD_LB: u8 = 0x0; +const RISCV_LD_LH: u8 = 0x1; +const RISCV_LD_LW: u8 = 0x2; +const RISCV_LD_LD: u8 = 0x3; +const RISCV_LD_LBU: u8 = 0x4; +const RISCV_LD_LHU: u8 = 0x5; +const RISCV_LD_LWU: u8 = 0x6; + +const RISCV_ST_STB: u8 = 0x0; +const RISCV_ST_STH: u8 = 0x1; +const RISCV_ST_STW: u8 = 0x2; +const RISCV_ST_STD: u8 = 0x3; + +const RISCV_OPI_ADDI: u8 = 0x0; +const RISCV_OPI_SLTI: u8 = 0x2; +const RISCV_OPI_SLTIU: u8 = 0x3; +const RISCV_OPI_XORI: u8 = 0x4; +const RISCV_OPI_ORI: u8 = 0x6; +const RISCV_OPI_ANDI: u8 = 0x7; +const RISCV_OPI_SLLI: u8 = 0x1; +const RISCV_OPI_SRI: u8 = 0x5; +const RISCV_OPI_SRI_SRAI: u8 = 0x20; +const RISCV_OPI_SRI_SRLI: u8 = 0x0; + +const RISCV_OP_ADD: u8 = 0x0; +const RISCV_OP_SLL: u8 = 0x1; +const RISCV_OP_SLT: u8 = 0x2; +const RISCV_OP_SLTU: u8 = 0x3; +const RISCV_OP_XOR: u8 = 0x4; +const RISCV_OP_SR: u8 = 0x5; +const RISCV_OP_OR: u8 = 0x6; +const RISCV_OP_AND: u8 = 0x7; +const RISCV_OP_ADD_ADD: u8 = 0x0; +const RISCV_OP_ADD_SUB: u8 = 0x20; +const RISCV_OP_SR_SRL: u8 = 0x0; +const RISCV_OP_SR_SRA: u8 = 0x20; + +const RISCV_SYSTEM: u8 = 0x73; + +const RISCV_OPIW_ADDIW: u8 = 0x0; +const RISCV_OPIW_SLLIW: u8 = 0x1; +const RISCV_OPIW_SRW: u8 = 0x5; +const RISCV_OPIW_SRW_SRLIW: u8 = 0x0; +const RISCV_OPIW_SRW_SRAIW: u8 = 0x20; + +const RISCV_OPW_ADDSUBW: u8 = 0x0; +const RISCV_OPW_SLLW: u8 = 0x1; +const RISCV_OPW_SRW: u8 = 0x5; +const RISCV_OPW_ADDSUBW_ADDW: u8 = 0x0; +const RISCV_OPW_ADDSUBW_SUBW: u8 = 0x20; +const RISCV_OPW_SRW_SRLW: u8 = 0x0; +const RISCV_OPW_SRW_SRAW: u8 = 0x20; + +const RISCV_SYSTEM_ENV: u8 = 0x0; +const RISCV_SYSTEM_ENV_ECALL: u8 = 0x0; +const RISCV_SYSTEM_ENV_EBREAK: u8 = 0x1; +const RISCV_SYSTEM_CSRRS: u8 = 0x2; +const RISCV_SYSTEM_CSRRW: u8 = 0x1; +const RISCV_SYSTEM_CSRRC: u8 = 0x3; +const RISCV_SYSTEM_CSRRWI: u8 = 0x5; +const RISCV_SYSTEM_CSRRSI: u8 = 0x6; +const RISCV_SYSTEM_CSRRCI: u8 = 0x7; + +const RISCV_FLW: u8 = 0x07; +const RISCV_FSW: u8 = 0x27; +const RISCV_FMADD: u8 = 0x43; +const RISCV_FMSUB: u8 = 0x47; +const RISCV_FNMSUB: u8 = 0x4b; +const RISCV_FNMADD: u8 = 0x4f; +const RISCV_FP: u8 = 0x53; + +const RISCV_FP_ADD: u8 = 0x0; +const RISCV_FP_SUB: u8 = 0x4; +const RISCV_FP_MUL: u8 = 0x8; +const RISCV_FP_DIV: u8 = 0xc; +const RISCV_FP_SQRT: u8 = 0x2c; +const RISCV_FP_FSGN: u8 = 0x10; +const RISCV_FP_MINMAX: u8 = 0x14; +const RISCV_FP_FCVTW: u8 = 0x60; +const RISCV_FP_FMVXFCLASS: u8 = 0x70; +const RISCV_FP_FCMP: u8 = 0x50; +const RISCV_FP_FEQS: u8 = 0x53; +const RISCV_FP_FCVTS: u8 = 0x68; +const RISCV_FP_FCVTDS: u8 = 0x21; + +const RISCV_FP_FSGN_J: u8 = 0x0; +const RISCV_FP_FSGN_JN: u8 = 0x1; +const RISCV_FP_FSGN_JX: u8 = 0x2; + +const RISCV_FP_MINMAX_MIN: u8 = 0x0; +const RISCV_FP_MINMAX_MAX: u8 = 0x1; + +const RISCV_FP_FCVTW_W: u8 = 0x0; +const RISCV_FP_FCVTW_WU: u8 = 0x1; + +const RISCV_FP_FCVTS_W: u8 = 0x0; +const RISCV_FP_FCVTS_WU: u8 = 0x1; + +const RISCV_FP_FMVXFCLASS_FMVX: u8 = 0x0; +const RISCV_FP_FMVXFCLASS_FCLASS: u8 = 0x1; + +const RISCV_FP_FCMP_FEQ: u8 = 2; +const RISCV_FP_FCMP_FLT: u8 = 1; +const RISCV_FP_FCMP_FLE: u8 = 0; + +const RISCV_FP_FMVW: u8 = 0x78; + + +const names_op: [&str; 8] = ["add", "sll", "slt", "sltu", "xor", "sr", "or", "and"]; +const names_opi: [&str; 8] = ["addi", "slli", "slti", "cmpltuii", "xori", "slri", "ori", "andi"]; +const names_mul: [&str; 8] = ["mpylo", "mpyhi", "mpyhi", "mpyhi", "divhi", "divhi", "divlo", "divlo"]; +const names_br: [&str; 8] = ["beq", "bne", "", "", "blt", "bge", "bltu", "bgeu"]; +const names_st: [&str; 4] = ["sb", "sh", "sw", "sd"]; +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] = ["addwi", "sllwi", "", "", "", "sri", "", ""]; + + + +pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64 + + match ins.opcode { + RISCV_OP => { + let name: &str; + if ins.funct7 == 1 { // Use mul array + name = names_mul[ins.funct3 as usize] + } else { + name = names_op[ins.funct3 as usize]; + } + format!("{} r{}, r{}, r{}", name.to_string(), &ins.rd.to_string(), &ins.rs1.to_string(), &ins.rs2.to_string()) + }, + RISCV_OPI => { + // SHAMT OR IMM + if ins.funct3 == RISCV_OPI_SRI { + if ins.funct7 == RISCV_OPI_SRI_SRLI { + format!("slrii x{}, x{}, {}", ins.rd.to_string(), ins.rs1.to_string(), ins.shamt.to_string()) + } else { + format!("srai x{}, x{}, {}", ins.rd.to_string(), ins.rs1.to_string(), ins.shamt.to_string()) + } + } else if ins.funct3 == RISCV_OPI_SLLI { + format!("{} x{}, x{}, {}", names_opi[ins.funct3 as usize], ins.rd.to_string(), ins.rs1.to_string(), ins.shamt.to_string()) + } else { + format!("{} x{}, x{}, {}", names_opi[ins.funct3 as usize], ins.rd.to_string(), ins.rs1.to_string(), ins.imm12_I_signed.to_string()) + } + }, + RISCV_LUI => { + format!("lui x{}, {}", ins.rd.to_string(), ins.imm31_12.to_string()) //TODO Value is supposed to be in hex + }, + RISCV_AUIPC => { + format!("auipc x{}, {}", ins.rd.to_string(), ins.imm31_12.to_string()) // TODO Value is supposed to be in hex + }, + RISCV_JAL => { + if ins.rd == 0 { + format!("j {}", ins.imm31_12.to_string()) + } else { + format!("jal x{}, {}", ins.rd.to_string(), (pc - 4 + ins.imm21_1_signed).to_string()) // TODO Value is supposed to be in hex + } + }, + RISCV_JALR => { + if ins.rd == 0 { + if ins.rs1 == 1 { + "ret".to_string() + } else { + format!("jr {}", ins.imm31_12.to_string()) // TODO Value is supposed to be in hex + } + } else { + format!("jalr {}, (r{})", ins.imm12_I_signed.to_string(), ins.rs1.to_string()) + } + }, + RISCV_BR => { + format!("{} r{} x{} {}", names_br[ins.funct3 as usize].to_string(), ins.rs1.to_string(), ins.rs2.to_string(), ins.imm13_signed.to_string()) + }, + RISCV_LD => { + format!("{} x{}, {}(x{})", names_ld[ins.funct3 as usize].to_string(), ins.rd.to_string(), ins.imm12_I_signed.to_string(), ins.rs1.to_string()) + }, + RISCV_ST => { + format!("{} x{}, {}(x{})", names_st[ins.funct3 as usize].to_string(), ins.rs2.to_string(), ins.imm12_S_signed.to_string(), ins.rs1.to_string()) + }, + RISCV_OPIW => { + if ins.funct3 == RISCV_OPIW_SRW { + if ins.funct7 == RISCV_OPIW_SRW_SRLIW { + format!("srlwi x{}, x{}, x{}", ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } else { + format!("srawi x{}, x{}, x{}", ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } + } else if ins.funct3 == RISCV_OPIW_SLLIW { + format!("{} x{}, x{}, x{}", names_opi[ins.funct3 as usize], ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } else { + format!("{} x{}, x{}, x{}", names_opiw[ins.funct3 as usize], ins.rd.to_string(), ins.rs1.to_string(), ins.imm12_I_signed.to_string()) + } + }, + RISCV_OPW => { + if ins.funct7 == 1 { + format!("{}w x{}, x{}, x{}", names_mul[ins.funct3 as usize].to_string(), ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } else { + if ins.funct3 == RISCV_OP_ADD { + if ins.funct7 == RISCV_OPW_ADDSUBW_ADDW { + format!("addw x{}, x{}, x{}", ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } else { + format!("subw x{}, x{}, x{}", ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } + } else if ins.funct3 == RISCV_OPW_SRW { + if ins.funct7 == RISCV_OPW_SRW_SRLW { + format!("srlw x{}, x{}, x{}", ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } else { + format!("sraw x{}, x{}, x{}", ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } + } else { + format!("{} x{}, x{}, x{}", names_opw[ins.funct3 as usize], ins.rd.to_string(), ins.rs1.to_string(), ins.rs2.to_string()) + } + } + }, + RISCV_SYSTEM => { + "ecall".to_string() + }, + _ => "Unknown".to_string() // Error + } + +} \ No newline at end of file