diff --git a/src/simulator/instruction.rs b/src/simulator/instruction.rs index bc64f4b..f85f5ac 100644 --- a/src/simulator/instruction.rs +++ b/src/simulator/instruction.rs @@ -1,33 +1,49 @@ +//! # Instruction +//! +//! This module describes the internal representation of a RISC-V Instruction, +//! its constructor from raw data, and a debug print method. +#![allow(clippy::missing_docs_in_private_items, non_snake_case)] + use core::num::Wrapping; // Permet d'autoriser les overflow pour les opérations voulues use super::global::*; +/// OP instruction name mapping const NAMES_OP: [&str; 8] = ["add", "sll", "slt", "sltu", "xor", "sr", "or", "and"]; +/// OPI instruction name mapping const NAMES_OPI: [&str; 8] = ["addi", "slli", "slti", "sltiu", "xori", "slri", "ori", "andi"]; -const NAMES_MUL: [&str; 8] = ["mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu"]; -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"]; +/// OPW instruction name mapping const NAMES_OPW: [&str; 8] = ["addw", "sllw", "", "", "", "srw", "", ""]; +/// OPIW instruction name mapping const NAMES_OPIW: [&str; 8] = ["addiw", "slliw", "", "", "", "sri", "", ""]; +/// MUL instruction name mapping +const NAMES_MUL: [&str; 8] = ["mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu"]; +/// BR instruction name mapping +const NAMES_BR: [&str; 8] = ["beq", "bne", "", "", "blt", "bge", "bltu", "bgeu"]; +/// ST instruction name mapping +const NAMES_ST: [&str; 4] = ["sb", "sh", "sw", "sd"]; +/// LD instruction name mapping +const NAMES_LD: [&str; 7] = ["lb", "lh", "lw", "ld", "lbu", "lhu", "lwu"]; -// Register name mapping +/// Integer register name mapping pub const REG_X: [&str; 32] = ["zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"]; +/// Floating-point register name mapping const REG_F: [&str; 32] = ["ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"]; -#[allow(non_snake_case)] // supprimer le warning snake case (quand les noms de variables ont des majuscules) -#[derive(Debug)] +/// RISC-V Instruction +#[derive(Debug)] pub struct Instruction { + /// Original value used to construct self pub value : u64, - pub opcode : u8, + pub opcode : u8, pub rs1 : u8, pub rs2 : u8, pub rs3 : u8, @@ -52,71 +68,82 @@ pub struct Instruction { pub imm21_1_signed : i32, } -#[allow(non_snake_case)] -pub fn decode(val : u64) -> Instruction { +impl Instruction { - let value = val; - - let opcode = (val & 0x7f) as u8; - let rs1 = ((val >> 15) & 0x1f) as u8; - let rs2 = ((val >> 20) & 0x1f) as u8; - let rs3 = ((val >> 27) & 0x1f) as u8; - let rd = ((val >> 7) & 0x1f) as u8; - let funct7 = ((val >> 25) & 0x7f) as u8; - let funct7_smaller = funct7 & 0x3e; + /// Construct a new instruction from a big endian raw binary instruction + pub fn new(value : u64) -> Self { - let funct3 = ((val >> 12) & 0x7) as u8; - let imm12_I = ((val >> 20) & 0xfff) as u16; - let imm12_S = (((val >> 20) & 0xfe0) + ((val >> 7) & 0x1f)) as u16; + let opcode = (value & 0x7f) as u8; + let rs1 = ((value >> 15) & 0x1f) as u8; + let rs2 = ((value >> 20) & 0x1f) as u8; + let rs3 = ((value >> 27) & 0x1f) as u8; + let rd = ((value >> 7) & 0x1f) as u8; + let funct7 = ((value >> 25) & 0x7f) as u8; + let funct7_smaller = funct7 & 0x3e; + + let funct3 = ((value >> 12) & 0x7) as u8; + let imm12_I = ((value >> 20) & 0xfff) as u16; + let imm12_S = (((value >> 20) & 0xfe0) + ((value >> 7) & 0x1f)) as u16; + + let imm12_I_signed = if imm12_I >= 2048 { (Wrapping(imm12_I) - Wrapping(4096)).0 } else { imm12_I } as i16; + let imm12_S_signed = if imm12_S >= 2048 { (Wrapping(imm12_S) - Wrapping(4096)).0 } else { imm12_S } as i16; + + let imm13 = (((value >> 19) & 0x1000) + ((value >> 20) & 0x7e0) + + ((value >> 7) & 0x1e) + ((value << 4) & 0x800)) as i16; + let imm13_signed = if imm13 >= 4096 { imm13 - 8192 } else { imm13 }; + + let imm31_12 = (value & 0xfffff000) as u32; + let imm31_12_signed = imm31_12 as i32; + + let imm21_1 = ((value & 0xff000) + ((value >> 9) & 0x800) + + ((value >> 20) & 0x7fe) + ((value >> 11) & 0x100000)) as u32; + let imm21_1_signed = if imm21_1 >= 1048576 { (Wrapping(imm21_1) - Wrapping(2097152)).0 } else { imm21_1 } as i32; + + let shamt = ((value >> 20) & 0x3f) as u8; + + Instruction { + value, - let imm12_I_signed = if imm12_I >= 2048 { (Wrapping(imm12_I) - Wrapping(4096)).0 } else { imm12_I } as i16; - let imm12_S_signed = if imm12_S >= 2048 { (Wrapping(imm12_S) - Wrapping(4096)).0 } else { imm12_S } as i16; - - let imm13 = (((val >> 19) & 0x1000) + ((val >> 20) & 0x7e0) + - ((val >> 7) & 0x1e) + ((val << 4) & 0x800)) as i16; - let imm13_signed = if imm13 >= 4096 { imm13 - 8192 } else { imm13 }; - - let imm31_12 = (val & 0xfffff000) as u32; - let imm31_12_signed = imm31_12 as i32; - - let imm21_1 = ((val & 0xff000) + ((val >> 9) & 0x800) + - ((val >> 20) & 0x7fe) + ((val >> 11) & 0x100000)) as u32; - let imm21_1_signed = if imm21_1 >= 1048576 { (Wrapping(imm21_1) - Wrapping(2097152)).0 } else { imm21_1 } as i32; - - let shamt = ((val >> 20) & 0x3f) as u8; - - Instruction { - value, - - opcode, - rs1, - rs2, - rs3, - rd, - funct7, - funct7_smaller, - - funct3, - imm12_I, - imm12_S, - - imm12_I_signed, - imm12_S_signed, - - imm13, - imm13_signed, - - imm31_12, - imm31_12_signed, - - imm21_1, - imm21_1_signed, - - shamt + opcode, + rs1, + rs2, + rs3, + rd, + funct7, + funct7_smaller, + + funct3, + imm12_I, + imm12_S, + + imm12_I_signed, + imm12_S_signed, + + imm13, + imm13_signed, + + imm31_12, + imm31_12_signed, + + imm21_1, + imm21_1_signed, + + shamt + } } + } -pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64 +/// Converts an Instruction to a prettified debug String +/// +/// ### Usage +/// +/// ``` +/// let m = Machine::new(); +/// let i = Instruction::new(inst); +/// println!("{}", instruction_debug(i, m.pc)); +/// ``` +pub fn instruction_debug(ins: &Instruction, pc: i32) -> String { let rd = ins.rd as usize; let rs1 = ins.rs1 as usize; let rs2 = ins.rs2 as usize; @@ -313,6 +340,7 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64 } + #[cfg(test)] mod test { #![allow(clippy::unusual_byte_groupings)] @@ -321,106 +349,106 @@ mod test { #[test] fn test_op() { - let sub = decode(0b0100000_10000_10001_000_11100_0110011); - let add = decode(0b0000000_10000_10001_000_11100_0110011); - let xor = decode(0b0000000_10000_10001_100_11100_0110011); - let slr = decode(0b0000000_10000_10001_101_11100_0110011); - let sra = decode(0b0100000_10000_10001_101_11100_0110011); + let sub = Instruction::new(0b0100000_10000_10001_000_11100_0110011); + let add = Instruction::new(0b0000000_10000_10001_000_11100_0110011); + let xor = Instruction::new(0b0000000_10000_10001_100_11100_0110011); + let slr = Instruction::new(0b0000000_10000_10001_101_11100_0110011); + let sra = Instruction::new(0b0100000_10000_10001_101_11100_0110011); - assert_eq!("sub\tt3,a7,a6", print(sub, 0)); - assert_eq!("xor\tt3,a7,a6", print(xor, 0)); - assert_eq!("srl\tt3,a7,a6", print(slr, 0)); - assert_eq!("sra\tt3,a7,a6", print(sra, 0)); - assert_eq!("add\tt3,a7,a6", print(add, 0)); + assert_eq!("sub\tt3,a7,a6", instruction_debug(&sub, 0)); + assert_eq!("xor\tt3,a7,a6", instruction_debug(&xor, 0)); + assert_eq!("srl\tt3,a7,a6", instruction_debug(&slr, 0)); + assert_eq!("sra\tt3,a7,a6", instruction_debug(&sra, 0)); + assert_eq!("add\tt3,a7,a6", instruction_debug(&add, 0)); } #[test] fn test_opi() { - let addi = decode(0b0000000000_10001_000_11100_0010011); - let slli = decode(0b0000000000_10001_001_11100_0010011); - let slti = decode(0b0000000000_10001_010_11100_0010011); - let sltiu = decode(0b0000000000_10001_011_11100_0010011); - let xori = decode(0b_0000000000010001_100_11100_0010011); - let ori = decode(0b00000000000_10001_110_11100_0010011); - let andi = decode(0b000000000000_10001_111_11100_0010011); - assert_eq!("andi\tt3,a7,0", print(andi, 0)); - assert_eq!("addi\tt3,a7,0", print(addi, 0)); - assert_eq!("slli\tt3,a7,0", print(slli, 0)); - assert_eq!("slti\tt3,a7,0", print(slti, 0)); - assert_eq!("sltiu\tt3,a7,0", print(sltiu, 0)); - assert_eq!("xori\tt3,a7,0", print(xori, 0)); - assert_eq!("ori\tt3,a7,0", print(ori, 0)); + let addi = Instruction::new(0b0000000000_10001_000_11100_0010011); + let slli = Instruction::new(0b0000000000_10001_001_11100_0010011); + let slti = Instruction::new(0b0000000000_10001_010_11100_0010011); + let sltiu = Instruction::new(0b0000000000_10001_011_11100_0010011); + let xori = Instruction::new(0b_0000000000010001_100_11100_0010011); + let ori = Instruction::new(0b00000000000_10001_110_11100_0010011); + let andi = Instruction::new(0b000000000000_10001_111_11100_0010011); + assert_eq!("andi\tt3,a7,0", instruction_debug(&andi, 0)); + assert_eq!("addi\tt3,a7,0", instruction_debug(&addi, 0)); + assert_eq!("slli\tt3,a7,0", instruction_debug(&slli, 0)); + assert_eq!("slti\tt3,a7,0", instruction_debug(&slti, 0)); + assert_eq!("sltiu\tt3,a7,0", instruction_debug(&sltiu, 0)); + assert_eq!("xori\tt3,a7,0", instruction_debug(&xori, 0)); + assert_eq!("ori\tt3,a7,0", instruction_debug(&ori, 0)); } #[test] fn test_lui() { - let lui = decode(0b01110001000011111000_11100_0110111); - let lui_negatif = decode(0b11110001000011111000_11100_0110111); - assert_eq!("lui\tt3,710f8000", print(lui, 0)); - assert_eq!("lui\tt3,f10f8000", print(lui_negatif, 0)); + let lui = Instruction::new(0b01110001000011111000_11100_0110111); + let lui_negatif = Instruction::new(0b11110001000011111000_11100_0110111); + assert_eq!("lui\tt3,710f8000", instruction_debug(&lui, 0)); + assert_eq!("lui\tt3,f10f8000", instruction_debug(&lui_negatif, 0)); } #[test] fn test_ld() { // imm rs1 f3 rd opcode - let lb = decode(0b010111110000_10001_000_11100_0000011); - let lh = decode(0b010111110000_10001_001_11100_0000011); - let lw = decode(0b010111110000_10001_010_11100_0000011); - let lbu = decode(0b010111110000_10001_100_11100_0000011); - let lhu = decode(0b010111110000_10001_101_11100_0000011); - let ld = decode(0b010111110000_10001_011_11100_0000011); - let lwu = decode(0b010111110000_10001_110_11100_0000011); + let lb = Instruction::new(0b010111110000_10001_000_11100_0000011); + let lh = Instruction::new(0b010111110000_10001_001_11100_0000011); + let lw = Instruction::new(0b010111110000_10001_010_11100_0000011); + let lbu = Instruction::new(0b010111110000_10001_100_11100_0000011); + let lhu = Instruction::new(0b010111110000_10001_101_11100_0000011); + let ld = Instruction::new(0b010111110000_10001_011_11100_0000011); + let lwu = Instruction::new(0b010111110000_10001_110_11100_0000011); - assert_eq!("lb\tt3,1520(a7)", print(lb, 0)); - assert_eq!("lh\tt3,1520(a7)", print(lh, 0)); - assert_eq!("lw\tt3,1520(a7)", print(lw, 0)); - assert_eq!("lbu\tt3,1520(a7)", print(lbu, 0)); - assert_eq!("lhu\tt3,1520(a7)", print(lhu, 0)); - assert_eq!("ld\tt3,1520(a7)", print(ld, 0)); - assert_eq!("lwu\tt3,1520(a7)", print(lwu, 0)); + assert_eq!("lb\tt3,1520(a7)", instruction_debug(&lb, 0)); + assert_eq!("lh\tt3,1520(a7)", instruction_debug(&lh, 0)); + assert_eq!("lw\tt3,1520(a7)", instruction_debug(&lw, 0)); + assert_eq!("lbu\tt3,1520(a7)", instruction_debug(&lbu, 0)); + assert_eq!("lhu\tt3,1520(a7)", instruction_debug(&lhu, 0)); + assert_eq!("ld\tt3,1520(a7)", instruction_debug(&ld, 0)); + assert_eq!("lwu\tt3,1520(a7)", instruction_debug(&lwu, 0)); } #[test] fn test_opw() { - let addw: Instruction = decode(0b0000000_10000_10001_000_11100_0111011); - let sllw: Instruction = decode(0b0000000_10000_10001_001_11100_0111011); - let srlw: Instruction = decode(0b0000000_10000_10001_101_11100_0111011); - let sraw: Instruction = decode(0b0100000_10000_10001_101_11100_0111011); + let addw: Instruction = Instruction::new(0b0000000_10000_10001_000_11100_0111011); + let sllw: Instruction = Instruction::new(0b0000000_10000_10001_001_11100_0111011); + let srlw: Instruction = Instruction::new(0b0000000_10000_10001_101_11100_0111011); + let sraw: Instruction = Instruction::new(0b0100000_10000_10001_101_11100_0111011); - assert_eq!("addw\tt3,a7,a6", print(addw, 0)); - assert_eq!("sllw\tt3,a7,a6", print(sllw, 0)); - assert_eq!("srlw\tt3,a7,a6", print(srlw, 0)); - assert_eq!("sraw\tt3,a7,a6", print(sraw, 0)); + assert_eq!("addw\tt3,a7,a6", instruction_debug(&addw, 0)); + assert_eq!("sllw\tt3,a7,a6", instruction_debug(&sllw, 0)); + assert_eq!("srlw\tt3,a7,a6", instruction_debug(&srlw, 0)); + assert_eq!("sraw\tt3,a7,a6", instruction_debug(&sraw, 0)); } #[test] fn test_opwi() { - let addiw: Instruction =decode(0b000000000000_10001_000_11100_0011011); - let slliw: Instruction = decode(0b0000000_10000_10001_001_11100_0011011); - let srai: Instruction = decode(0b010000010001_10001_101_11100_0010011); - assert_eq!("addiw\tt3,a7,0x0", print(addiw, 0)); - assert_eq!("slliw\tt3,a7,0x10", print(slliw, 0)); - assert_eq!("srai\tt3,a7,17", print(srai, 0)); + let addiw: Instruction =Instruction::new(0b000000000000_10001_000_11100_0011011); + let slliw: Instruction = Instruction::new(0b0000000_10000_10001_001_11100_0011011); + let srai: Instruction = Instruction::new(0b010000010001_10001_101_11100_0010011); + assert_eq!("addiw\tt3,a7,0x0", instruction_debug(&addiw, 0)); + assert_eq!("slliw\tt3,a7,0x10", instruction_debug(&slliw, 0)); + assert_eq!("srai\tt3,a7,17", instruction_debug(&srai, 0)); } #[test] fn test_br() { - let beq: Instruction = decode(0b0000000_10000_10001_000_00000_1100011); - let bne: Instruction = decode(0b0000000_10000_10001_001_00000_1100011); - let blt: Instruction = decode(0b0000000_10000_10001_100_00000_1100011); - let bge: Instruction = decode(0b0000000_10000_10001_101_00000_1100011); - let bge2: Instruction = decode(0x00f75863); - let bltu: Instruction = decode(0b0000000_10000_10001_110_00000_1100011); - let bgeu: Instruction = decode(0b0000000_10000_10001_111_00000_1100011); - assert_eq!("blt\ta7,a6,0", print(blt, 0)); - assert_eq!("bge\ta7,a6,0", print(bge, 0)); - assert_eq!("bge\ta4,a5,104d4", print(bge2, 0x104c4)); - assert_eq!("bltu\ta7,a6,0", print(bltu, 0)); - assert_eq!("bgeu\ta7,a6,0", print(bgeu, 0)); - assert_eq!("bne\ta7,a6,0", print(bne, 0)); - assert_eq!("beq\ta7,a6,0", print(beq, 0)); + let beq: Instruction = Instruction::new(0b0000000_10000_10001_000_00000_1100011); + let bne: Instruction = Instruction::new(0b0000000_10000_10001_001_00000_1100011); + let blt: Instruction = Instruction::new(0b0000000_10000_10001_100_00000_1100011); + let bge: Instruction = Instruction::new(0b0000000_10000_10001_101_00000_1100011); + let bge2: Instruction = Instruction::new(0x00f75863); + let bltu: Instruction = Instruction::new(0b0000000_10000_10001_110_00000_1100011); + let bgeu: Instruction = Instruction::new(0b0000000_10000_10001_111_00000_1100011); + assert_eq!("blt\ta7,a6,0", instruction_debug(&blt, 0)); + assert_eq!("bge\ta7,a6,0", instruction_debug(&bge, 0)); + assert_eq!("bge\ta4,a5,104d4", instruction_debug(&bge2, 0x104c4)); + assert_eq!("bltu\ta7,a6,0", instruction_debug(&bltu, 0)); + assert_eq!("bgeu\ta7,a6,0", instruction_debug(&bgeu, 0)); + assert_eq!("bne\ta7,a6,0", instruction_debug(&bne, 0)); + assert_eq!("beq\ta7,a6,0", instruction_debug(&beq, 0)); } #[test] @@ -433,72 +461,72 @@ mod test { a = a + b; b = a - b; */ - assert_eq!("addi sp,sp,-32", print(decode(0xfe010113), 0)); - assert_eq!("sd s0,24(sp)", print(decode(0x00813c23), 0)); - assert_eq!("addi s0,sp,32", print(decode(0x02010413), 0)); - assert_eq!("sw zero,-20(s0)", print(decode(0xfe042623), 0)); - assert_eq!("addi a5,zero,5", print(decode(0x00500793), 0)); - assert_eq!("sw a5,-24(s0)", print(decode(0xfef42423), 0)); - assert_eq!("lw a5,-24(s0)", print(decode(0xfe842783), 0)); - assert_eq!("sw a5,-20(s0)", print(decode(0xfef42623), 0)); - assert_eq!("lw a5,-20(s0)", print(decode(0xfec42783), 0)); - assert_eq!("addi a4,a5,0", print(decode(0x00078713), 0)); - assert_eq!("lw a5,-24(s0)", print(decode(0xfe842783), 0)); - assert_eq!("mulw a5,a4,a5", print(decode(0x02f707bb), 0)); - assert_eq!("sw a5,-20(s0)", print(decode(0xfef42623), 0)); - assert_eq!("lw a5,-20(s0)", print(decode(0xfec42783), 0)); - assert_eq!("addi a4,a5,0", print(decode(0x00078713), 0)); - assert_eq!("lw a5,-24(s0)", print(decode(0xfe842783), 0)); - assert_eq!("addw a5,a4,a5", print(decode(0x00f707bb), 0)); - assert_eq!("sw a5,-20(s0)", print(decode(0xfef42623), 0)); - assert_eq!("lw a5,-20(s0)", print(decode(0xfec42783), 0)); - assert_eq!("addi a4,a5,0", print(decode(0x00078713), 0)); - assert_eq!("lw a5,-24(s0)", print(decode(0xfe842783), 0)); - assert_eq!("subw a5,a4,a5", print(decode(0x40f707bb), 0)); - assert_eq!("sw a5,-24(s0)", print(decode(0xfef42423), 0)); - assert_eq!("addi a5,zero,0", print(decode(0x00000793), 0)); - assert_eq!("addi a0,a5,0", print(decode(0x00078513), 0)); - assert_eq!("ld s0,24(sp)", print(decode(0x01813403), 0)); - assert_eq!("addi sp,sp,32", print(decode(0x02010113), 0)); - assert_eq!("jalr zero,0(ra)", print(decode(0x00008067), 0)); + assert_eq!("addi sp,sp,-32", instruction_debug(&Instruction::new(0xfe010113), 0)); + assert_eq!("sd s0,24(sp)", instruction_debug(&Instruction::new(0x00813c23), 0)); + assert_eq!("addi s0,sp,32", instruction_debug(&Instruction::new(0x02010413), 0)); + assert_eq!("sw zero,-20(s0)", instruction_debug(&Instruction::new(0xfe042623), 0)); + assert_eq!("addi a5,zero,5", instruction_debug(&Instruction::new(0x00500793), 0)); + assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423), 0)); + assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0)); + assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0)); + assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0)); + assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0)); + assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0)); + assert_eq!("mulw a5,a4,a5", instruction_debug(&Instruction::new(0x02f707bb), 0)); + assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0)); + assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0)); + assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0)); + assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0)); + assert_eq!("addw a5,a4,a5", instruction_debug(&Instruction::new(0x00f707bb), 0)); + assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0)); + assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0)); + assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0)); + assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0)); + assert_eq!("subw a5,a4,a5", instruction_debug(&Instruction::new(0x40f707bb), 0)); + assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423), 0)); + assert_eq!("addi a5,zero,0", instruction_debug(&Instruction::new(0x00000793), 0)); + assert_eq!("addi a0,a5,0", instruction_debug(&Instruction::new(0x00078513), 0)); + assert_eq!("ld s0,24(sp)", instruction_debug(&Instruction::new(0x01813403), 0)); + assert_eq!("addi sp,sp,32", instruction_debug(&Instruction::new(0x02010113), 0)); + assert_eq!("jalr zero,0(ra)", instruction_debug(&Instruction::new(0x00008067), 0)); } #[test] fn test_fibo() { - assert_eq!("jal zero,10504", print(decode(0x0500006f), 0x104b4)); - assert_eq!("blt a4,a5,104b8", print(decode(0xfaf740e3), 0x10518)); + assert_eq!("jal zero,10504", instruction_debug(&Instruction::new(0x0500006f), 0x104b4)); + assert_eq!("blt a4,a5,104b8", instruction_debug(&Instruction::new(0xfaf740e3), 0x10518)); } #[test] fn test_mul_prog() { - assert_eq!("addi sp,sp,-32", print(decode(0xfe010113), 0)); - assert_eq!("sd s0,24(sp)", print(decode(0x00813c23), 0)); - assert_eq!("addi s0,sp,32", print(decode(0x02010413), 0)); - assert_eq!("addi a5,zero,5", print(decode(0x00500793), 0)); - assert_eq!("sw a5,-20(s0)", print(decode(0xfef42623), 0)); - assert_eq!("lw a5,-20(s0)", print(decode(0xfec42783), 0)); - assert_eq!("addi a4,a5,0", print(decode(0x00078713), 0)); - assert_eq!("addi a5,a4,0", print(decode(0x00070793), 0)); - assert_eq!("slliw a5,a5,0x2", print(decode(0x0027979b), 0)); - assert_eq!("addw a5,a5,a4", print(decode(0x00e787bb), 0)); - assert_eq!("sw a5,-24(s0)", print(decode(0xfef42423), 0)); - assert_eq!("lw a5,-20(s0)", print(decode(0xfec42783), 0)); - assert_eq!("addi a4,a5,0", print(decode(0x00078713), 0)); - assert_eq!("lw a5,-24(s0)", print(decode(0xfe842783), 0)); - assert_eq!("mulw a5,a4,a5", print(decode(0x02f707bb), 0)); - assert_eq!("sw a5,-28(s0)", print(decode(0xfef42223), 0)); - assert_eq!("lw a5,-28(s0)", print(decode(0xfe442783), 0)); - assert_eq!("addi a4,a5,0", print(decode(0x00078713), 0)); - assert_eq!("lw a5,-24(s0)", print(decode(0xfe842783), 0)); - assert_eq!("divw a5,a4,a5", print(decode(0x02f747bb), 0)); - assert_eq!("sw a5,-20(s0)", print(decode(0xfef42623), 0)); - assert_eq!("addi a5,zero,0", print(decode(0x00000793), 0)); - assert_eq!("addi a0,a5,0", print(decode(0x00078513), 0)); - assert_eq!("ld s0,24(sp)", print(decode(0x01813403), 0)); - assert_eq!("addi sp,sp,32", print(decode(0x02010113), 0)); - assert_eq!("jalr zero,0(ra)", print(decode(0x00008067), 0)); + assert_eq!("addi sp,sp,-32", instruction_debug(&Instruction::new(0xfe010113), 0)); + assert_eq!("sd s0,24(sp)", instruction_debug(&Instruction::new(0x00813c23), 0)); + assert_eq!("addi s0,sp,32", instruction_debug(&Instruction::new(0x02010413), 0)); + assert_eq!("addi a5,zero,5", instruction_debug(&Instruction::new(0x00500793), 0)); + assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0)); + assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0)); + assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0)); + assert_eq!("addi a5,a4,0", instruction_debug(&Instruction::new(0x00070793), 0)); + assert_eq!("slliw a5,a5,0x2", instruction_debug(&Instruction::new(0x0027979b), 0)); + assert_eq!("addw a5,a5,a4", instruction_debug(&Instruction::new(0x00e787bb), 0)); + assert_eq!("sw a5,-24(s0)", instruction_debug(&Instruction::new(0xfef42423), 0)); + assert_eq!("lw a5,-20(s0)", instruction_debug(&Instruction::new(0xfec42783), 0)); + assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0)); + assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0)); + assert_eq!("mulw a5,a4,a5", instruction_debug(&Instruction::new(0x02f707bb), 0)); + assert_eq!("sw a5,-28(s0)", instruction_debug(&Instruction::new(0xfef42223), 0)); + assert_eq!("lw a5,-28(s0)", instruction_debug(&Instruction::new(0xfe442783), 0)); + assert_eq!("addi a4,a5,0", instruction_debug(&Instruction::new(0x00078713), 0)); + assert_eq!("lw a5,-24(s0)", instruction_debug(&Instruction::new(0xfe842783), 0)); + assert_eq!("divw a5,a4,a5", instruction_debug(&Instruction::new(0x02f747bb), 0)); + assert_eq!("sw a5,-20(s0)", instruction_debug(&Instruction::new(0xfef42623), 0)); + assert_eq!("addi a5,zero,0", instruction_debug(&Instruction::new(0x00000793), 0)); + assert_eq!("addi a0,a5,0", instruction_debug(&Instruction::new(0x00078513), 0)); + assert_eq!("ld s0,24(sp)", instruction_debug(&Instruction::new(0x01813403), 0)); + assert_eq!("addi sp,sp,32", instruction_debug(&Instruction::new(0x02010113), 0)); + assert_eq!("jalr zero,0(ra)", instruction_debug(&Instruction::new(0x00008067), 0)); } } \ No newline at end of file diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index 6f07fa7..a4bcdaa 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -265,10 +265,10 @@ impl Machine { } let val = u32::from_be_bytes(val) as u64; - let inst : Instruction = decode(val); + let inst : Instruction = Instruction::new(val); self.print_status(); println!("executing instruction : {:016x} at pc {:x}", val, self.pc); - println!("{}", instruction::print(decode(val), self.pc as i32)); + println!("{}", instruction::instruction_debug(&inst, self.pc as i32)); let trace = Self::string_registers(self); self.registers_trace.push_str(format!("{}\n", trace).as_str());