From 149a0d614405c2c37cb943da9c6c516e48a0cf6c Mon Sep 17 00:00:00 2001 From: Mwa Date: Mon, 9 Mar 2026 18:05:07 +0100 Subject: [PATCH] mul/div instruction and nightly toolchain --- rust-toolchain.toml | 2 ++ src/cpu.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/cpu.rs b/src/cpu.rs index df556e3..661080d 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -75,6 +75,12 @@ enum Instruction { Lsl(Reg, Reg, Op2), Lsr(Reg, Reg, Op2), Asr(Reg, Reg, Op2), + Smull(Reg, Reg, Op2), + Smulh(Reg, Reg, Op2), + Umull(Reg, Reg, Op2), + Umulh(Reg, Reg, Op2), + Div(Reg, Reg, Op2), + Mod(Reg, Reg, Op2), Store(Reg, Op2, Reg), Load(Reg, Reg, Op2), Push(Op2), @@ -129,6 +135,12 @@ impl From for Instruction { (1, 0b0110) => Self::Lsl(rd, rx, op2), (1, 0b0111) => Self::Lsr(rd, rx, op2), (1, 0b1000) => Self::Asr(rd, rx, op2), + (1, 0b1001) => Self::Smull(rd, rx, op2), + (1, 0b1010) => Self::Smulh(rd, rx, op2), + (1, 0b1011) => Self::Umull(rd, rx, op2), + (1, 0b1100) => Self::Umulh(rd, rx, op2), + (1, 0b1101) => Self::Div(rd, rx, op2), + (1, 0b1110) => Self::Mod(rd, rx, op2), (2, 0b0000) => Self::Store(rx, op2, rd), (2, 0b0001) => Self::Load(rd, rx, op2), (2, 0b0010) => Self::Push(op2), @@ -219,6 +231,38 @@ impl<'a, 'b> Computer<'a, 'b> { self.rg_wr(reg, (self.rg_r(reg1) as i32 >> self.resolve(op2)) as u32); self.pc += 1; } + Instruction::Umull(reg, reg1, op2) => { + self.rg_wr(reg, self.rg_r(reg1).wrapping_mul(self.resolve(op2))); + self.pc += 1; + } + Instruction::Smull(reg, reg1, op2) => { + self.rg_wr( + reg, + (self.rg_r(reg1) as i32).wrapping_mul(self.resolve(op2) as i32) as u32, + ); + self.pc += 1; + } + Instruction::Umulh(reg, reg1, op2) => { + self.rg_wr(reg, self.rg_r(reg1).widening_mul(self.resolve(op2)).1); + self.pc += 1; + } + Instruction::Smulh(reg, reg1, op2) => { + self.rg_wr( + reg, + (self.rg_r(reg1) as i32) + .widening_mul(self.resolve(op2) as i32) + .1 as u32, + ); + self.pc += 1; + } + Instruction::Div(reg, reg1, op2) => { + self.rg_wr(reg, self.rg_r(reg1) / self.resolve(op2)); + self.pc += 1 + } + Instruction::Mod(reg, reg1, op2) => { + self.rg_wr(reg, self.rg_r(reg1) % self.resolve(op2)); + self.pc += 1 + } Instruction::Store(reg, op2, reg1) => { let addr = (self.rg_r(reg) + self.resolve(op2)) as usize; if !addr.is_multiple_of(4) { @@ -293,7 +337,7 @@ impl<'a, 'b> Computer<'a, 'b> { Instruction::Call(mut addr) => { self.sp -= 1; self.ram[self.sp] = ((self.pc << 2) + 4) as u32; - + if addr & (1 << 28) != 0 { addr += 7 << 29; } else if unlikely(addr == 0) { diff --git a/src/main.rs b/src/main.rs index b14c514..068c29e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -#![feature(likely_unlikely)] +#![feature(likely_unlikely, widening_mul)] #![deny(clippy::all)] use std::env::args;