Add a lot of comments, fix SRLI instruction in print,
This commit is contained in:
parent
559f94ca21
commit
f7f66d31e0
@ -13,7 +13,7 @@ pub struct Instruction {
|
|||||||
pub funct7 : u8,
|
pub funct7 : u8,
|
||||||
pub funct7_smaller : u8,
|
pub funct7_smaller : u8,
|
||||||
pub funct3 : u8,
|
pub funct3 : u8,
|
||||||
pub shamt : u8,
|
pub shamt : u8, // shamt = imm[5:0] or imm[4:0] (depend of opcode)
|
||||||
|
|
||||||
pub imm12_I : u16,
|
pub imm12_I : u16,
|
||||||
pub imm12_S : u16,
|
pub imm12_S : u16,
|
||||||
|
@ -206,7 +206,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
//TODO store instructions
|
// store instructions
|
||||||
RISCV_ST => {
|
RISCV_ST => {
|
||||||
match inst.funct3 {
|
match inst.funct3 {
|
||||||
RISCV_ST_STB => {
|
RISCV_ST_STB => {
|
||||||
|
@ -2,12 +2,34 @@
|
|||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
use super::decode::{Instruction};
|
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;
|
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_AUIPC: u8 = 0x17;
|
||||||
pub const RISCV_JAL: u8 = 0x6f;
|
pub const RISCV_JAL: u8 = 0x6f;
|
||||||
pub const RISCV_JALR: u8 = 0x67;
|
pub const RISCV_JALR: u8 = 0x67;
|
||||||
pub const RISCV_BR: u8 = 0x63;
|
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_LD: u8 = 0x3;
|
||||||
pub const RISCV_ST: u8 = 0x23;
|
pub const RISCV_ST: u8 = 0x23;
|
||||||
pub const RISCV_OPI: u8 = 0x13;
|
pub const RISCV_OPI: u8 = 0x13;
|
||||||
@ -23,41 +45,197 @@ pub const RISCV_BR_BGE: u8 = 0x5;
|
|||||||
pub const RISCV_BR_BLTU: u8 = 0x6;
|
pub const RISCV_BR_BLTU: u8 = 0x6;
|
||||||
pub const RISCV_BR_BGEU: u8 = 0x7;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
pub const RISCV_OPI_SLLI: u8 = 0x1;
|
||||||
|
/// Shift right immediate, may be SRAI or SRLI
|
||||||
pub const RISCV_OPI_SRI: u8 = 0x5;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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_XOR: u8 = 0x4;
|
||||||
pub const RISCV_OP_SR: u8 = 0x5;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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_OP_SR_SRA: u8 = 0x20;
|
||||||
|
|
||||||
pub const RISCV_SYSTEM: u8 = 0x73;
|
pub const RISCV_SYSTEM: u8 = 0x73;
|
||||||
@ -217,7 +395,7 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64
|
|||||||
// SHAMT OR IMM
|
// SHAMT OR IMM
|
||||||
if ins.funct3 == RISCV_OPI_SRI {
|
if ins.funct3 == RISCV_OPI_SRI {
|
||||||
if ins.funct7 == RISCV_OPI_SRI_SRLI {
|
if ins.funct7 == RISCV_OPI_SRI_SRLI {
|
||||||
format!("slrii\t{}, {}, {}", REG_X[rd], REG_X[rs1], ins.shamt)
|
format!("srli\t{}, {}, {}", REG_X[rd], REG_X[rs1], ins.shamt)
|
||||||
} else {
|
} else {
|
||||||
format!("srai\t{}, {}, {}", REG_X[rd], REG_X[rs1], ins.shamt)
|
format!("srai\t{}, {}, {}", REG_X[rd], REG_X[rs1], ins.shamt)
|
||||||
}
|
}
|
||||||
@ -295,7 +473,7 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64
|
|||||||
RISCV_SYSTEM => {
|
RISCV_SYSTEM => {
|
||||||
"ecall".to_string()
|
"ecall".to_string()
|
||||||
},
|
},
|
||||||
_ => "Unknown".to_string() // Error
|
_ => todo!("Unknown or currently unsupported opcode") // Change todo! to panic! in the future, I put todo! because there's a lot of opcode currently not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user