diff --git a/src/decode.rs b/src/decode.rs index 31a7bd2..fd12d6b 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -52,12 +52,12 @@ impl Instruction { #[inline] pub fn imm_i(self) -> DWord { - (self.0 as i64 >> 20) as DWord + (self.0 as i32 as i64 >> 20) as DWord } #[inline] pub fn imm_s(self) -> DWord { - (self.0 as i64 >> (25 - 5) & (0x7f << 5)) as DWord | (self.0 >> 7 & 0b1111) as DWord + (self.0 as i32 as i64 >> (25 - 5) & (0x7f << 5)) as DWord | (self.0 >> 7 & 0b1111) as DWord } #[inline] @@ -88,12 +88,12 @@ impl Instruction { // The following are AFAIK only used for shift by immediate operations #[inline] - fn funct6(self) -> u8 { + pub fn funct6(self) -> u8 { (self.0 >> 26 & 0x3f) as u8 } #[inline] - fn imm_shamt(self) -> usize { + pub fn imm_shamt(self) -> usize { (self.0 >> 20 & 0x3f) as usize } } diff --git a/src/instructions.rs b/src/instructions.rs index bfedaee..fc270dc 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -16,6 +16,11 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Option match instr.funct3() { // OP_IMM 0b000 => Some(rvi::addi(core, instr)), + 0b001 => match instr.funct6() { + // left-shift immediate + 0b000000 => Some(rvi::slli(core, instr)), + _ => None, + }, _ => None, }, 0b00110 => match instr.funct3() { diff --git a/src/instructions/rvi.rs b/src/instructions/rvi.rs index 2d342df..2eb48f9 100644 --- a/src/instructions/rvi.rs +++ b/src/instructions/rvi.rs @@ -64,3 +64,18 @@ pub fn jal(core: &mut Core, instr: Instruction) -> InstructionResult { core.pc = core.pc.wrapping_add(instr.imm_j()); InstructionResult::Normal } + +pub fn slli(core: &mut Core, instr: Instruction) -> InstructionResult { + core.reg_write(instr.rd(), core.reg_read(instr.rs1()) << instr.imm_shamt()); + + eprintln!( + "slli x{}, x{}, {}", + instr.rd(), + instr.rs1(), + instr.imm_shamt() + ); + + core.pc = core.pc.wrapping_add(4); + + InstructionResult::Normal +}