mul/div instruction and nightly toolchain
This commit is contained in:
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
||||||
46
src/cpu.rs
46
src/cpu.rs
@@ -75,6 +75,12 @@ enum Instruction {
|
|||||||
Lsl(Reg, Reg, Op2),
|
Lsl(Reg, Reg, Op2),
|
||||||
Lsr(Reg, Reg, Op2),
|
Lsr(Reg, Reg, Op2),
|
||||||
Asr(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),
|
Store(Reg, Op2, Reg),
|
||||||
Load(Reg, Reg, Op2),
|
Load(Reg, Reg, Op2),
|
||||||
Push(Op2),
|
Push(Op2),
|
||||||
@@ -129,6 +135,12 @@ impl From<u32> for Instruction {
|
|||||||
(1, 0b0110) => Self::Lsl(rd, rx, op2),
|
(1, 0b0110) => Self::Lsl(rd, rx, op2),
|
||||||
(1, 0b0111) => Self::Lsr(rd, rx, op2),
|
(1, 0b0111) => Self::Lsr(rd, rx, op2),
|
||||||
(1, 0b1000) => Self::Asr(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, 0b0000) => Self::Store(rx, op2, rd),
|
||||||
(2, 0b0001) => Self::Load(rd, rx, op2),
|
(2, 0b0001) => Self::Load(rd, rx, op2),
|
||||||
(2, 0b0010) => Self::Push(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.rg_wr(reg, (self.rg_r(reg1) as i32 >> self.resolve(op2)) as u32);
|
||||||
self.pc += 1;
|
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) => {
|
Instruction::Store(reg, op2, reg1) => {
|
||||||
let addr = (self.rg_r(reg) + self.resolve(op2)) as usize;
|
let addr = (self.rg_r(reg) + self.resolve(op2)) as usize;
|
||||||
if !addr.is_multiple_of(4) {
|
if !addr.is_multiple_of(4) {
|
||||||
@@ -293,7 +337,7 @@ impl<'a, 'b> Computer<'a, 'b> {
|
|||||||
Instruction::Call(mut addr) => {
|
Instruction::Call(mut addr) => {
|
||||||
self.sp -= 1;
|
self.sp -= 1;
|
||||||
self.ram[self.sp] = ((self.pc << 2) + 4) as u32;
|
self.ram[self.sp] = ((self.pc << 2) + 4) as u32;
|
||||||
|
|
||||||
if addr & (1 << 28) != 0 {
|
if addr & (1 << 28) != 0 {
|
||||||
addr += 7 << 29;
|
addr += 7 << 29;
|
||||||
} else if unlikely(addr == 0) {
|
} else if unlikely(addr == 0) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![feature(likely_unlikely)]
|
#![feature(likely_unlikely, widening_mul)]
|
||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
|
|
||||||
use std::env::args;
|
use std::env::args;
|
||||||
|
|||||||
Reference in New Issue
Block a user