Move const to simulator/mod.rs

This commit is contained in:
Quentin Legot 2023-01-20 18:21:32 +01:00
parent f7f66d31e0
commit 55f5726197
3 changed files with 531 additions and 344 deletions

View File

@ -1,7 +1,7 @@
use super::{decode::{Instruction, decode}, print::*}; use super::{decode::{Instruction, decode}};
use super::global::*;
/// doit disparaitre /// doit disparaitre
const MEM_SIZE : usize= 4096; const MEM_SIZE : usize = 4096;
pub struct Machine { pub struct Machine {
pub pc : u64, pub pc : u64,

View File

@ -1,3 +1,528 @@
pub mod machine; pub mod machine;
pub mod decode; pub mod decode;
pub mod print; pub mod print;
pub mod global {
#![allow(dead_code)]
#![allow(unused_variables)]
// Instructions type:
// - R: Register / register
// - I: Immediate
// - U: Upper-Immediate
// - S: Store
// - B: Branch (conditional branches...)
// - J: Jump
// xlen = i64::MAX_VALUE on rv64 and i32::MAX_VALUE on rv32
/// Type: U
///
/// Load upper immediate
///
/// `LUI rd, imm31_12` => `rd <- imm31_12 << 12`
///
pub const RISCV_LUI: u8 = 0x37;
/// Type: U
///
/// Add upper immediate to PC
///
/// `AUIP rd, imm31_12` => `rd <- PC + imm31_12 << 12`
pub const RISCV_AUIPC: u8 = 0x17;
/// Type: J
///
/// Jump and link
///
/// `JAL rd, imm20(rs1)` => `rd <- pc + 4; pc <- rs1 + imm12`
pub const RISCV_JAL: u8 = 0x6f;
/// type: J
///
/// Jump and link register
///
/// `JALR rd, imm12(rs1)` => `rd <- pc + 4; pc <- rs1 + imm12`
pub const RISCV_JALR: u8 = 0x67;
pub const RISCV_BR: u8 = 0x63;
/// Load instructions
///
/// See func3 to know the type of instruction (LD, LW, LH, LB, LWU, LHU, LBU)
pub const RISCV_LD: u8 = 0x3;
// Store instructions
pub const RISCV_ST: u8 = 0x23;
// immediate Arithmetic operations
pub const RISCV_OPI: u8 = 0x13;
// Arithmetic operations
pub const RISCV_OP: u8 = 0x33;
/// Immediate arithmetic operations for rv64i
pub const RISCV_OPIW: u8 = 0x1b;
// Arithmetic operations for rv64i
pub const RISCV_OPW: u8 = 0x3b;
/// Type: B
///
/// Branch equal
///
/// `BEQ rs1, rs2, imm12` => `if rs1 = rs2 then pc <- pc + imm12`
pub const RISCV_BR_BEQ: u8 = 0x0;
/// Type: B
///
/// Branch not equal
///
/// `BNE rs1, rs2, imm12` => `if rs1 != rs2 then pc <- pc + imm12`
pub const RISCV_BR_BNE: u8 = 0x1;
/// Type: B
///
/// Branch less than
///
/// `BLT rs1, rs2, imm12` => `if rs1 < rs2 then pc <- pc + imm12`
pub const RISCV_BR_BLT: u8 = 0x4;
/// Type: B
///
/// Branch greater than or equal
///
/// `BGE rs1, rs2, imm12` => `if rs1 >= rs2 then pc <- pc + imm12`
pub const RISCV_BR_BGE: u8 = 0x5;
/// Type: B
///
/// Branch less than unsigned
///
/// Same as BLT but for unsigned values
pub const RISCV_BR_BLTU: u8 = 0x6;
/// Type: B
///
/// Greater than or equal unsigned
///
/// Same as BGE but for unsigned values
pub const RISCV_BR_BGEU: u8 = 0x7;
/// Type: I
///
/// Load byte (8 bits word)
///
/// `LB rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LB: u8 = 0x0;
/// Type: I
///
/// Load halfword (16 bits word)
///
/// `LH rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LH: u8 = 0x1;
/// Type: I
///
/// Load word (32 bits word)
///
/// `LW rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LW: u8 = 0x2;
/// Type: I
///
/// Load doubleword (64-bits word)
///
/// `LD rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LD: u8 = 0x3;
/// Type: I
///
/// Load byte unsigned
///
/// `LBU rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LBU: u8 = 0x4;
/// Type: I
///
/// Load halfword unsigned
///
/// `LHU rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LHU: u8 = 0x5;
/// Type: I
///
/// Load word unsigned (64 bits word)
///
/// `LW rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LWU: u8 = 0x6;
/// Type: S
///
/// Store halfword (SH) (16 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 16 bits values are stored
///
/// `SH rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STH: u8 = 0x1;
/// Type: S
///
/// Store word (SW) (32 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 32 bits values are stored
///
/// `SW rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STW: u8 = 0x2;
/// Type: S
///
/// Store byte (SB) (8 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 8 bits values are stored
///
/// `SB rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STB: u8 = 0x0;
/// Type: S
///
/// Store doubleword (SD) (64 bits)
///
/// `SD rs2, imm12(rs1` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STD: u8 = 0x3;
/// Type: I
///
/// Add immediate
///
/// `addi rd, rs1, imm12` => `rd <- rs1 + imm12`
pub const RISCV_OPI_ADDI: u8 = 0x0;
/// Type: I
///
/// Set less than immediate: set rd to 1 if rs1 < imm12, 0 otherwise
///
/// `SLT rd, rs1, imm12` => `rd <- rs1 < imm12 ? 1 : 0`
pub const RISCV_OPI_SLTI: u8 = 0x2;
/// Type: I
///
/// Set less than immediate unsigned : same than SLTI but for unsigned values
pub const RISCV_OPI_SLTIU: u8 = 0x3;
/// Type: I
///
/// XOR immediate instruction
///
/// `XORI rd, rs1, imm12` => `rd <- rs1 ^ imm12`
pub const RISCV_OPI_XORI: u8 = 0x4;
/// Type: I
///
/// OR immediate instruction
///
/// `ORI rd, rs1, imm12` => `rd <- rs1 | imm12`
pub const RISCV_OPI_ORI: u8 = 0x6;
/// Type: I
///
/// AND immediate instruction
///
/// `ANDI rd, rs1, imm12` => `rd <- rs1 & imm12`
pub const RISCV_OPI_ANDI: u8 = 0x7;
/// Type: I
///
/// Shift left logical immediate
///
/// `SLLI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SLLI: u8 = 0x1;
/// Shift right immediate, may be SRAI or SRLI
pub const RISCV_OPI_SRI: u8 = 0x5;
/// type: I
///
/// Shift right arithmetic immediate
///
/// `SRAI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SRI_SRAI: u8 = 0x20;
/// type: I
///
/// Shift right logical immediate
///
/// `SRLI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SRI_SRLI: u8 = 0x0;
/// Type: R
///
/// Add or sub (see RISCV_OP_ADD_ADD or RISCV_OP_ADD_SUB) depending of func7 value
pub const RISCV_OP_ADD: u8 = 0x0;
/// Type: R
///
/// Shift left logical, add a 0 on right of the word
///
/// `SLL rd, rs1, rs2` => `rs <- rs1 << rs2`
pub const RISCV_OP_SLL: u8 = 0x1;
/// Type: R
///
/// Set less than : set rd to 1 if rs1 < rs2, 0 otherwise
///
/// `SLT rd, rs1, rs2` => `rd <- rs1 < rs2 ? 1 : 0`
pub const RISCV_OP_SLT: u8 = 0x2;
/// Type: R
///
/// Set less than unsigned : same than SLT but for unsigned values
pub const RISCV_OP_SLTU: u8 = 0x3;
/// Type: R
///
/// XOR instruction
///
/// `XOR rd, rs1, rs2` => `rd <- rs1 ^ rs2`
pub const RISCV_OP_XOR: u8 = 0x4;
pub const RISCV_OP_SR: u8 = 0x5;
/// Type: R
///
/// OR instruction
///
/// `OR rd, rs1, rs2` => `rd <- rs1 | rs2`
pub const RISCV_OP_OR: u8 = 0x6;
/// Type: R
///
/// AND instruction
///
/// `AND rd, rs1, rs2` => `rd <- rs1 & rs2`
pub const RISCV_OP_AND: u8 = 0x7;
/// Type : R
///
/// Addition
///
/// `ADD rd, rs1, rs2` => `rd <- rs1 + rs2`
pub const RISCV_OP_ADD_ADD: u8 = 0x0;
/// Type: R
///
/// Substract
///
/// `SUB rd, rs1, rs2` => `rd <- rs1 - rs2`
pub const RISCV_OP_ADD_SUB: u8 = 0x20;
/// Type: R
///
/// Shift right logical, add a 0 at the left of the word (should not used for signed values in most cases)
///
/// `SRL rd, rs1, rs2` => `rd <- rs1 >> rs2`
pub const RISCV_OP_SR_SRL: u8 = 0x0;
/// Type: R
///
/// Shift right arithmetic, add a 1 at the left of the word(useful for signed values bacause it keep signed value)
///
/// `SRA rd, rs1, rs2` => `rd <- rs1 >> rs2`
pub const RISCV_OP_SR_SRA: u8 = 0x20;
// ECALL or EBREAK from base instructions
/// or instructions from Ricsr extension
pub const RISCV_SYSTEM: u8 = 0x73;
/// Type: I
///
/// Add immediate word (RV64I only)
///
/// `ADDIW rd, rs1, imm12` => `rd <- rs1 + imm12`
pub const RISCV_OPIW_ADDIW: u8 = 0x0;
/// Type: I
///
/// Shift right logical immediate word (RV64I only)
///
/// `SLLIW rd, rs1, imm12` => `rd <- rs1 >> imm12`
pub const RISCV_OPIW_SLLIW: u8 = 0x1;
/// Shift right immediate instructions (logical or arithmetic depend of func7)
pub const RISCV_OPIW_SRW: u8 = 0x5;
/// Type: I
///
/// Shift right logical immediate word (RV64I only)
///
/// `SRLIW rd, rs1, imm12` => `rd <- rs1 >> imm12`
///
/// Complete left bits by a zero, should be used with an unsigned value in most case
pub const RISCV_OPIW_SRW_SRLIW: u8 = 0x0;
/// Type: I
///
/// Shift right arithmetic immediate word (RV64I only)
///
/// `SRAIW rd, rs1, imm12` => `rd <- rs1 >> imm12`
///
/// Keep sign bit
pub const RISCV_OPIW_SRW_SRAIW: u8 = 0x20;
// ADD or SUB immediate instructions, depend of func7 value
pub const RISCV_OPW_ADDSUBW: u8 = 0x0;
/// Type: R
///
/// Shift left logical word (RV64I only)
///
/// `SLLW rd, rs1, rs2` => `rd <- rs1 << rs2`
pub const RISCV_OPW_SLLW: u8 = 0x1;
/// Shift right word instructions (logical or arithmetic depend of func3)
pub const RISCV_OPW_SRW: u8 = 0x5;
/// Type: R
///
/// Add word (rv64I only)
///
/// `ADDW rd, rs1, rs2` => `rd <- rs1 + rs2`
pub const RISCV_OPW_ADDSUBW_ADDW: u8 = 0x0;
/// Type: R
///
/// Subtract word (rv64I only)
///
/// `SUBW rd, rs1, rs2` => `rd <- rs1 - rs2`
pub const RISCV_OPW_ADDSUBW_SUBW: u8 = 0x20;
/// Type: R
///
/// Shift right logical word (rv64I only)
///
/// rd <- rs1 >> rs2
///
/// Complete left bits by a 0, should be used with an unsigned value
pub const RISCV_OPW_SRW_SRLW: u8 = 0x0;
/// Type: R
///
/// Shift right arithmetic word (rv64I only)
///
/// `SRAW rd, rs1, rs2` => `rd <- rs1 >> rs2`
///
/// Keep sign bit
pub const RISCV_OPW_SRW_SRAW: u8 = 0x20;
pub const RISCV_SYSTEM_ENV: u8 = 0x0;
pub const RISCV_SYSTEM_ENV_ECALL: u8 = 0x0;
pub const RISCV_SYSTEM_ENV_EBREAK: u8 = 0x1;
pub const RISCV_SYSTEM_CSRRS: u8 = 0x2;
pub const RISCV_SYSTEM_CSRRW: u8 = 0x1;
pub const RISCV_SYSTEM_CSRRC: u8 = 0x3;
pub const RISCV_SYSTEM_CSRRWI: u8 = 0x5;
pub const RISCV_SYSTEM_CSRRSI: u8 = 0x6;
pub const RISCV_SYSTEM_CSRRCI: u8 = 0x7;
pub const RISCV_FLW: u8 = 0x07;
pub const RISCV_FSW: u8 = 0x27;
pub const RISCV_FMADD: u8 = 0x43;
pub const RISCV_FMSUB: u8 = 0x47;
pub const RISCV_FNMSUB: u8 = 0x4b;
pub const RISCV_FNMADD: u8 = 0x4f;
/// Simple floating point extension
pub const RISCV_FP: u8 = 0x53;
pub const RISCV_FP_ADD: u8 = 0x0;
pub const RISCV_FP_SUB: u8 = 0x4;
pub const RISCV_FP_MUL: u8 = 0x8;
pub const RISCV_FP_DIV: u8 = 0xc;
pub const RISCV_FP_SQRT: u8 = 0x2c;
pub const RISCV_FP_FSGN: u8 = 0x10;
pub const RISCV_FP_MINMAX: u8 = 0x14;
pub const RISCV_FP_FCVTW: u8 = 0x60;
pub const RISCV_FP_FMVXFCLASS: u8 = 0x70;
pub const RISCV_FP_FCMP: u8 = 0x50;
pub const RISCV_FP_FEQS: u8 = 0x53;
pub const RISCV_FP_FCVTS: u8 = 0x68;
pub const RISCV_FP_FCVTDS: u8 = 0x21;
pub const RISCV_FP_FSGN_J: u8 = 0x0;
pub const RISCV_FP_FSGN_JN: u8 = 0x1;
pub const RISCV_FP_FSGN_JX: u8 = 0x2;
pub const RISCV_FP_MINMAX_MIN: u8 = 0x0;
pub const RISCV_FP_MINMAX_MAX: u8 = 0x1;
pub const RISCV_FP_FCVTW_W: u8 = 0x0;
pub const RISCV_FP_FCVTW_WU: u8 = 0x1;
pub const RISCV_FP_FCVTS_W: u8 = 0x0;
pub const RISCV_FP_FCVTS_WU: u8 = 0x1;
pub const RISCV_FP_FMVXFCLASS_FMVX: u8 = 0x0;
pub const RISCV_FP_FMVXFCLASS_FCLASS: u8 = 0x1;
pub const RISCV_FP_FCMP_FEQ: u8 = 2;
pub const RISCV_FP_FCMP_FLT: u8 = 1;
pub const RISCV_FP_FCMP_FLE: u8 = 0;
pub const RISCV_FP_FMVW: u8 = 0x78;
/// Integer, multiplication and division extension
pub const RISCV_OP_M: u8 = 0x1;
/// Type: R
///
/// Multiply
///
/// `MUL rd, rs1, rs2` => `rd <- rs1 * rs2`
pub const RISCV_OP_M_MUL: u8 = 0x0;
/// Type: R
///
/// Multiply high signed signed
///
/// `MULH rd, rs1, rs2` => `rd <- (rs1 * rs2) >> xlen`
///
/// rs1 and rs2 signed
pub const RISCV_OP_M_MULH: u8 = 0x1;
/// Type: R
///
/// Multiply high signed unsigned
///
/// `MULHSU rd, rs1, rs2` => `rd <- (rs1 x rs2) >> xlen`
///
/// rs1 is signed and rs2 is unsigned
pub const RISCV_OP_M_MULHSU: u8 = 0x2;
/// Type: R
///
/// Multiply high unsigned unsigned
///
/// `MULHU rd, rs1, rs2` => `rd <- (rs1 × rs2) >> xlen`
///
/// rs1 and rs2 unsigned
pub const RISCV_OP_M_MULHU: u8 = 0x3;
/// Type: R
///
/// Divide signed
///
/// `DIV rd, rs1, rs2` => `rd <- r1 / rs2`
pub const RISCV_OP_M_DIV: u8 = 0x4;
/// Type: R
///
/// Divide unsigned
///
/// `DIVU rd, rs1, rs2` => `rd <- rs1 / rs2`
pub const RISCV_OP_M_DIVU: u8 = 0x5;
/// Type: R
///
/// Remainder signed
///
/// `REM rd, rs1, rs2` => `rd <- rs1 % rs2`
pub const RISCV_OP_M_REM: u8 = 0x6;
/// Type: R
///
/// Remaindder unsigned
///
/// `REMU rd, rs1, rs2` => `rd <- rs1 % rs2`
pub const RISCV_OP_M_REMU: u8 = 0x7;
/// Type: R
///
/// Multiply Word (rv64M only)
///
/// `MULW rd, rs1, rs2` => `rd <- rs1 * rs2`
pub const RISCV_OPW_M_MULW: u8 = 0x0;
/// Type: R
///
/// Divide signed word (RV64M only)
///
/// `DIVW rd, rs1, rs2` => `rd <- rs1 / rs2`
pub const RISCV_OPW_M_DIVW: u8 = 0x4;
/// Type: R
///
/// Divide unsigned word
///
/// `DIVUW rd, rs1, rs2` => `red <- rs1 / rs2`
pub const RISCV_OPW_M_DIVUW: u8 = 0x5;
/// Type: R
///
/// Remainder signed word (RV64M only)
///
/// `REMW rd, rs1, rs2` => `rd <- rs1 % rs2`
pub const RISCV_OPW_M_REMW: u8 = 0x6;
/// Type: R
///
/// Remainder unsigned word (RV64M only)
///
/// `REMUW rd, rs1, rs2` => `rd <- rs1 % rs2`
pub const RISCV_OPW_M_REMUW: u8 = 0x7;
/// Instruction from Zifencei extension
pub const RISCV_FENCE: u8 = 0x0f;
/// Atomic instructions extension
pub const RISCV_ATOM: u8 = 0x2f;
pub const RISCV_ATOM_LR: u8 = 0x2;
pub const RISCV_ATOM_SC: u8 = 0x3;
pub const RISCV_ATOM_SWAP: u8 = 0x1;
pub const RISCV_ATOM_ADD: u8 = 0;
pub const RISCV_ATOM_XOR: u8 = 0x4;
pub const RISCV_ATOM_AND: u8 = 0xc;
pub const RISCV_ATOM_OR: u8 = 0x8;
pub const RISCV_ATOM_MIN: u8 = 0x10;
pub const RISCV_ATOM_MAX: u8 = 0x14;
pub const RISCV_ATOM_MINU: u8 = 0x18;
pub const RISCV_ATOM_MAXU: u8 = 0x1c;
}

View File

@ -1,345 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
#![allow(unused_variables)] #![allow(unused_variables)]
use super::decode::{Instruction}; use super::decode::{Instruction};
use super::global::*;
// Instructions type:
// - R: Register / register
// - I: Immediate
// - U: Upper-Immediate
// - S: Store
// - B: Branch (conditional branches...)
// - J: Jump
/// Type: U
///
/// Load upper immediate
///
/// `LUI rd, imm31_12` => `rd <- imm31_12 << 12`
///
pub const RISCV_LUI: u8 = 0x37;
/// Type: U
///
/// Add upper immediate to PC
///
/// `AUIP rd, imm31_12` => `rd <- PC + imm31_12 << 12`
pub const RISCV_AUIPC: u8 = 0x17;
pub const RISCV_JAL: u8 = 0x6f;
pub const RISCV_JALR: u8 = 0x67;
pub const RISCV_BR: u8 = 0x63;
/// Load instruction
///
/// See func3 to know the type of instruction (LD, LW, LH, LB, LWU, LHU, LBU)
pub const RISCV_LD: u8 = 0x3;
pub const RISCV_ST: u8 = 0x23;
pub const RISCV_OPI: u8 = 0x13;
pub const RISCV_OP: u8 = 0x33;
pub const RISCV_OPIW: u8 = 0x1b;
pub const RISCV_OPW: u8 = 0x3b;
pub const RISCV_BR_BEQ: u8 = 0x0;
pub const RISCV_BR_BNE: u8 = 0x1;
pub const RISCV_BR_BLT: u8 = 0x4;
pub const RISCV_BR_BGE: u8 = 0x5;
pub const RISCV_BR_BLTU: u8 = 0x6;
pub const RISCV_BR_BGEU: u8 = 0x7;
/// Type: I
///
/// Load byte (8 bits word)
///
/// `LB rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LB: u8 = 0x0;
/// Type: I
///
/// Load halfword (16 bits word)
///
/// `LH rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LH: u8 = 0x1;
/// Type: I
///
/// Load word (32 bits word)
///
/// `LW rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LW: u8 = 0x2;
/// Type: I
///
/// Load doubleword (64-bits word)
///
/// `LD rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LD: u8 = 0x3;
/// Type: I
///
/// Load byte unsigned
///
/// `LBU rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LBU: u8 = 0x4;
/// Type: I
///
/// Load halfword unsigned
///
/// `LHU rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LHU: u8 = 0x5;
/// Type: I
///
/// Load word unsigned (64 bits word)
///
/// `LW rd, imm12(rs1)` => `rd <- mem[rs1 + imm12]`
pub const RISCV_LD_LWU: u8 = 0x6;
/// Type: S
///
/// Store halfword (SH) (16 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 16 bits values are stored
///
/// `SH rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STH: u8 = 0x1;
/// Type: S
///
/// Store word (SW) (32 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 32 bits values are stored
///
/// `SW rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STW: u8 = 0x2;
/// Type: S
///
/// Store byte (SB) (8 bits)
///
/// In case of overflow (rs2 is a 64 bits reg), only the first 8 bits values are stored
///
/// `SB rs2, imm12(rs1)` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STB: u8 = 0x0;
/// Type: S
///
/// Store doubleword (SD) (64 bits)
///
/// `SD rs2, imm12(rs1` => `rs2 -> mem[rs1 + imm12]`
pub const RISCV_ST_STD: u8 = 0x3;
/// Type: I
///
/// Add immediate
///
/// `addi rd, rs1, imm12` => `rd <- rs1 + imm12`
pub const RISCV_OPI_ADDI: u8 = 0x0;
/// Type: I
///
/// Set less than immediate: set rd to 1 if rs1 < imm12, 0 otherwise
///
/// `SLT rd, rs1, imm12` => `rd <- rs1 < imm12 ? 1 : 0`
pub const RISCV_OPI_SLTI: u8 = 0x2;
/// Type: I
///
/// Set less than immediate unsigned : same than SLTI but for unsigned values
pub const RISCV_OPI_SLTIU: u8 = 0x3;
/// Type: I
///
/// XOR immediate instruction
///
/// `XORI rd, rs1, imm12` => `rd <- rs1 ^ imm12`
pub const RISCV_OPI_XORI: u8 = 0x4;
/// Type: I
///
/// OR immediate instruction
///
/// `ORI rd, rs1, imm12` => `rd <- rs1 | imm12`
pub const RISCV_OPI_ORI: u8 = 0x6;
/// Type: I
///
/// AND immediate instruction
///
/// `ANDI rd, rs1, imm12` => `rd <- rs1 & imm12`
pub const RISCV_OPI_ANDI: u8 = 0x7;
/// Type: I
///
/// Shift left logical immediate
///
/// `SLLI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SLLI: u8 = 0x1;
/// Shift right immediate, may be SRAI or SRLI
pub const RISCV_OPI_SRI: u8 = 0x5;
/// type: I
///
/// Shift right arithmetic immediate
///
/// `SRAI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SRI_SRAI: u8 = 0x20;
/// type: I
///
/// Shift right logical immediate
///
/// `SRLI rd, rs1, shamt` => `rd <- rs1 >> shamt`
pub const RISCV_OPI_SRI_SRLI: u8 = 0x0;
/// Type: R
///
/// Add or sub (see RISCV_OP_ADD_ADD or RISCV_OP_ADD_SUB) depending of func7 value
pub const RISCV_OP_ADD: u8 = 0x0;
/// Type: R
///
/// Shift left logical, add a 0 on right of the word
///
/// `SLL rd, rs1, rs2` => `rs <- rs1 << rs2`
pub const RISCV_OP_SLL: u8 = 0x1;
/// Type: R
///
/// Set less than : set rd to 1 if rs1 < rs2, 0 otherwise
///
/// `SLT rd, rs1, rs2` => `rd <- rs1 < rs2 ? 1 : 0`
pub const RISCV_OP_SLT: u8 = 0x2;
/// Type: R
///
/// Set less than unsigned : same than SLT but for unsigned values
pub const RISCV_OP_SLTU: u8 = 0x3;
/// Type: R
///
/// XOR instruction
///
/// `XOR rd, rs1, rs2` => `rd <- rs1 ^ rs2`
pub const RISCV_OP_XOR: u8 = 0x4;
pub const RISCV_OP_SR: u8 = 0x5;
/// Type: R
///
/// OR instruction
///
/// `OR rd, rs1, rs2` => `rd <- rs1 | rs2`
pub const RISCV_OP_OR: u8 = 0x6;
/// Type: R
///
/// AND instruction
///
/// `AND rd, rs1, rs2` => `rd <- rs1 & rs2`
pub const RISCV_OP_AND: u8 = 0x7;
/// Type : R
///
/// Addition
///
/// `ADD rd, rs1, rs2` => `rd <- rs1 + rs2`
pub const RISCV_OP_ADD_ADD: u8 = 0x0;
/// Type: R
///
/// Substract
///
/// `SUB rd, rs1, rs2` => `rd <- rs1 - rs2`
pub const RISCV_OP_ADD_SUB: u8 = 0x20;
/// Type: R
///
/// Shift right logical, add a 0 at the left of the word (should not used for signed values in most cases)
///
/// `SRL rd, rs1, rs2` => `rd <- rs1 >> rs2`
pub const RISCV_OP_SR_SRL: u8 = 0x0;
/// Type: R
///
/// Shift right arithmetic, add a 1 at the left of the word(useful for signed values bacause it keep signed value)
///
/// `SRA rd, rs1, rs2` => `rd <- rs1 >> rs2`
pub const RISCV_OP_SR_SRA: u8 = 0x20;
pub const RISCV_SYSTEM: u8 = 0x73;
pub const RISCV_OPIW_ADDIW: u8 = 0x0;
pub const RISCV_OPIW_SLLIW: u8 = 0x1;
pub const RISCV_OPIW_SRW: u8 = 0x5;
pub const RISCV_OPIW_SRW_SRLIW: u8 = 0x0;
pub const RISCV_OPIW_SRW_SRAIW: u8 = 0x20;
pub const RISCV_OPW_ADDSUBW: u8 = 0x0;
pub const RISCV_OPW_SLLW: u8 = 0x1;
pub const RISCV_OPW_SRW: u8 = 0x5;
pub const RISCV_OPW_ADDSUBW_ADDW: u8 = 0x0;
pub const RISCV_OPW_ADDSUBW_SUBW: u8 = 0x20;
pub const RISCV_OPW_SRW_SRLW: u8 = 0x0;
pub const RISCV_OPW_SRW_SRAW: u8 = 0x20;
pub const RISCV_SYSTEM_ENV: u8 = 0x0;
pub const RISCV_SYSTEM_ENV_ECALL: u8 = 0x0;
pub const RISCV_SYSTEM_ENV_EBREAK: u8 = 0x1;
pub const RISCV_SYSTEM_CSRRS: u8 = 0x2;
pub const RISCV_SYSTEM_CSRRW: u8 = 0x1;
pub const RISCV_SYSTEM_CSRRC: u8 = 0x3;
pub const RISCV_SYSTEM_CSRRWI: u8 = 0x5;
pub const RISCV_SYSTEM_CSRRSI: u8 = 0x6;
pub const RISCV_SYSTEM_CSRRCI: u8 = 0x7;
pub const RISCV_FLW: u8 = 0x07;
pub const RISCV_FSW: u8 = 0x27;
pub const RISCV_FMADD: u8 = 0x43;
pub const RISCV_FMSUB: u8 = 0x47;
pub const RISCV_FNMSUB: u8 = 0x4b;
pub const RISCV_FNMADD: u8 = 0x4f;
pub const RISCV_FP: u8 = 0x53;
pub const RISCV_FP_ADD: u8 = 0x0;
pub const RISCV_FP_SUB: u8 = 0x4;
pub const RISCV_FP_MUL: u8 = 0x8;
pub const RISCV_FP_DIV: u8 = 0xc;
pub const RISCV_FP_SQRT: u8 = 0x2c;
pub const RISCV_FP_FSGN: u8 = 0x10;
pub const RISCV_FP_MINMAX: u8 = 0x14;
pub const RISCV_FP_FCVTW: u8 = 0x60;
pub const RISCV_FP_FMVXFCLASS: u8 = 0x70;
pub const RISCV_FP_FCMP: u8 = 0x50;
pub const RISCV_FP_FEQS: u8 = 0x53;
pub const RISCV_FP_FCVTS: u8 = 0x68;
pub const RISCV_FP_FCVTDS: u8 = 0x21;
pub const RISCV_FP_FSGN_J: u8 = 0x0;
pub const RISCV_FP_FSGN_JN: u8 = 0x1;
pub const RISCV_FP_FSGN_JX: u8 = 0x2;
pub const RISCV_FP_MINMAX_MIN: u8 = 0x0;
pub const RISCV_FP_MINMAX_MAX: u8 = 0x1;
pub const RISCV_FP_FCVTW_W: u8 = 0x0;
pub const RISCV_FP_FCVTW_WU: u8 = 0x1;
pub const RISCV_FP_FCVTS_W: u8 = 0x0;
pub const RISCV_FP_FCVTS_WU: u8 = 0x1;
pub const RISCV_FP_FMVXFCLASS_FMVX: u8 = 0x0;
pub const RISCV_FP_FMVXFCLASS_FCLASS: u8 = 0x1;
pub const RISCV_FP_FCMP_FEQ: u8 = 2;
pub const RISCV_FP_FCMP_FLT: u8 = 1;
pub const RISCV_FP_FCMP_FLE: u8 = 0;
pub const RISCV_FP_FMVW: u8 = 0x78;
pub const RISCV_OP_M: u8 = 0x1;
pub const RISCV_OP_M_MUL: u8 = 0x0;
pub const RISCV_OP_M_MULH: u8 = 0x1;
pub const RISCV_OP_M_MULHSU: u8 = 0x2;
pub const RISCV_OP_M_MULHU: u8 = 0x3;
pub const RISCV_OP_M_DIV: u8 = 0x4;
pub const RISCV_OP_M_DIVU: u8 = 0x5;
pub const RISCV_OP_M_REM: u8 = 0x6;
pub const RISCV_OP_M_REMU: u8 = 0x7;
pub const RISCV_OPW_M_MULW: u8 = 0x0;
pub const RISCV_OPW_M_DIVW: u8 = 0x4;
pub const RISCV_OPW_M_DIVUW: u8 = 0x5;
pub const RISCV_OPW_M_REMW: u8 = 0x6;
pub const RISCV_OPW_M_REMUW: u8 = 0x7;
pub const RISCV_FENCE: u8 = 0x0f;
pub const RISCV_ATOM: u8 = 0x2f;
pub const RISCV_ATOM_LR: u8 = 0x2;
pub const RISCV_ATOM_SC: u8 = 0x3;
pub const RISCV_ATOM_SWAP: u8 = 0x1;
pub const RISCV_ATOM_ADD: u8 = 0;
pub const RISCV_ATOM_XOR: u8 = 0x4;
pub const RISCV_ATOM_AND: u8 = 0xc;
pub const RISCV_ATOM_OR: u8 = 0x8;
pub const RISCV_ATOM_MIN: u8 = 0x10;
pub const RISCV_ATOM_MAX: u8 = 0x14;
pub const RISCV_ATOM_MINU: u8 = 0x18;
pub const RISCV_ATOM_MAXU: u8 = 0x1c;
const NAMES_OP: [&str; 8] = ["add", "sll", "slt", "sltu", "xor", "sr", "or", "and"]; const NAMES_OP: [&str; 8] = ["add", "sll", "slt", "sltu", "xor", "sr", "or", "and"];
const NAMES_OPI: [&str; 8] = ["addi", "slli", "slti", "sltiu", "xori", "slri", "ori", "andi"]; const NAMES_OPI: [&str; 8] = ["addi", "slli", "slti", "sltiu", "xori", "slri", "ori", "andi"];
@ -481,8 +143,8 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64
#[cfg(test)] #[cfg(test)]
mod test { mod test {
#![allow(clippy::unusual_byte_groupings)] #![allow(clippy::unusual_byte_groupings)]
use crate::simulator::{decode, print}; use crate::simulator::{decode, print};