2022-11-09 15:06:22 +01:00
|
|
|
#![allow(dead_code)]
|
|
|
|
#![allow(unused_variables)]
|
2022-10-26 15:06:37 +02:00
|
|
|
use crate::decode::Instruction;
|
2022-10-26 13:31:40 +02:00
|
|
|
|
|
|
|
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 {
|
2022-11-09 14:37:19 +01:00
|
|
|
if ins.funct3 == RISCV_OP_ADD {
|
|
|
|
// Add or Sub
|
|
|
|
if ins.funct7 == RISCV_OP_ADD_ADD {
|
|
|
|
name = "add";
|
|
|
|
} else {
|
|
|
|
name = "sub";
|
|
|
|
}
|
|
|
|
} else if ins.funct3 == RISCV_OP_SR {
|
|
|
|
// Srl or Sra
|
|
|
|
if ins.funct7 == RISCV_OP_SR_SRL {
|
|
|
|
name = "srl";
|
|
|
|
} else {
|
|
|
|
name = "sra";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
name = names_op[ins.funct3 as usize];
|
|
|
|
}
|
2022-10-26 13:31:40 +02:00
|
|
|
}
|
|
|
|
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 => {
|
2022-10-26 15:10:21 +02:00
|
|
|
format!("lui x{}, {:X}", ins.rd.to_string(), ins.imm31_12)
|
2022-10-26 13:31:40 +02:00
|
|
|
},
|
|
|
|
RISCV_AUIPC => {
|
2022-10-26 15:10:21 +02:00
|
|
|
format!("auipc x{}, {:X}", ins.rd.to_string(), ins.imm31_12)
|
2022-10-26 13:31:40 +02:00
|
|
|
},
|
|
|
|
RISCV_JAL => {
|
|
|
|
if ins.rd == 0 {
|
|
|
|
format!("j {}", ins.imm31_12.to_string())
|
|
|
|
} else {
|
2022-10-26 15:10:21 +02:00
|
|
|
format!("jal x{}, {:X}", ins.rd.to_string(), (pc - 4 + ins.imm21_1_signed))
|
2022-10-26 13:31:40 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
RISCV_JALR => {
|
|
|
|
if ins.rd == 0 {
|
|
|
|
if ins.rs1 == 1 {
|
|
|
|
"ret".to_string()
|
|
|
|
} else {
|
2022-10-26 15:10:21 +02:00
|
|
|
format!("jr {:X}", ins.imm31_12)
|
2022-10-26 13:31:40 +02:00
|
|
|
}
|
|
|
|
} 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
|
|
|
|
}
|
|
|
|
|
2022-11-09 15:06:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod Test {
|
|
|
|
use crate::{print, decode};
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test1() {
|
|
|
|
let sub = decode::decode(0b01000001000010001000111000110011);
|
|
|
|
let add = decode::decode(0b00000001000010001000111000110011);
|
|
|
|
let xor = decode::decode(0b00000001000010001100111000110011);
|
|
|
|
let slr = decode::decode(0b00000001000010001101111000110011);
|
|
|
|
let sra = decode::decode(0b01000001000010001101111000110011);
|
|
|
|
|
|
|
|
assert_eq!("sub r28, r17, r16", print::print(sub, 0));
|
|
|
|
assert_eq!("xor r28, r17, r16", print::print(xor, 0));
|
|
|
|
assert_eq!("srl r28, r17, r16", print::print(slr, 0));
|
|
|
|
assert_eq!("sra r28, r17, r16", print::print(sra, 0));
|
|
|
|
assert_eq!("add r28, r17, r16", print::print(add, 0));
|
|
|
|
|
|
|
|
}
|
2022-10-26 13:31:40 +02:00
|
|
|
}
|