From 55f5726197d650b440e67f80a4a78dd566f3f0e7 Mon Sep 17 00:00:00 2001 From: Quentin Legot Date: Fri, 20 Jan 2023 18:21:32 +0100 Subject: [PATCH] Move const to simulator/mod.rs --- src/simulator/machine.rs | 6 +- src/simulator/mod.rs | 527 ++++++++++++++++++++++++++++++++++++++- src/simulator/print.rs | 342 +------------------------ 3 files changed, 531 insertions(+), 344 deletions(-) diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index d191b74..83be4a4 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -1,7 +1,7 @@ -use super::{decode::{Instruction, decode}, print::*}; - +use super::{decode::{Instruction, decode}}; +use super::global::*; /// doit disparaitre -const MEM_SIZE : usize= 4096; +const MEM_SIZE : usize = 4096; pub struct Machine { pub pc : u64, diff --git a/src/simulator/mod.rs b/src/simulator/mod.rs index 581621e..3124579 100644 --- a/src/simulator/mod.rs +++ b/src/simulator/mod.rs @@ -1,3 +1,528 @@ pub mod machine; pub mod decode; -pub mod print; \ No newline at end of file +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; + +} \ No newline at end of file diff --git a/src/simulator/print.rs b/src/simulator/print.rs index 2e37d7a..8544334 100644 --- a/src/simulator/print.rs +++ b/src/simulator/print.rs @@ -1,345 +1,7 @@ #![allow(dead_code)] #![allow(unused_variables)] use super::decode::{Instruction}; - -// 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; - +use super::global::*; 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"]; @@ -481,8 +143,8 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64 #[cfg(test)] mod test { - #![allow(clippy::unusual_byte_groupings)] + use crate::simulator::{decode, print};