Fixed bug + spec update

This commit is contained in:
Erin 2023-07-22 00:46:30 +02:00 committed by ondra05
parent 8212ba2f29
commit d8eb78ff02
2 changed files with 37 additions and 8 deletions

View file

@ -154,6 +154,11 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
SR => binary_op!(self, as_u64, ops::Shr::shr), SR => binary_op!(self, as_u64, ops::Shr::shr),
SRS => binary_op!(self, as_i64, ops::Shr::shr), SRS => binary_op!(self, as_i64, ops::Shr::shr),
CMP => { CMP => {
// Compare a0 <=> a1
// < → -1
// > → 1
// = → 0
let ParamBBB(tg, a0, a1) = param!(self, ParamBBB); let ParamBBB(tg, a0, a1) = param!(self, ParamBBB);
self.write_reg( self.write_reg(
tg, tg,
@ -161,6 +166,7 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
); );
} }
CMPU => { CMPU => {
// Unsigned comparsion
let ParamBBB(tg, a0, a1) = param!(self, ParamBBB); let ParamBBB(tg, a0, a1) = param!(self, ParamBBB);
self.write_reg( self.write_reg(
tg, tg,
@ -168,10 +174,12 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
); );
} }
NOT => { NOT => {
// Logical negation
let param = param!(self, ParamBB); let param = param!(self, ParamBB);
self.write_reg(param.0, !self.read_reg(param.1).as_u64()); self.write_reg(param.0, !self.read_reg(param.1).as_u64());
} }
NEG => { NEG => {
// Bitwise negation
let param = param!(self, ParamBB); let param = param!(self, ParamBB);
self.write_reg( self.write_reg(
param.0, param.0,
@ -182,6 +190,7 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
); );
} }
DIR => { DIR => {
// Fused Division-Remainder
let ParamBBBB(dt, rt, a0, a1) = param!(self, ParamBBBB); let ParamBBBB(dt, rt, a0, a1) = param!(self, ParamBBBB);
let a0 = self.read_reg(a0).as_u64(); let a0 = self.read_reg(a0).as_u64();
let a1 = self.read_reg(a1).as_u64(); let a1 = self.read_reg(a1).as_u64();
@ -212,12 +221,17 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
self.write_reg(param.0, self.read_reg(param.1)); self.write_reg(param.0, self.read_reg(param.1));
} }
SWA => { SWA => {
let ParamBB(src, dst) = param!(self, ParamBB); // Swap registers
if src + dst != 0 { let ParamBB(r0, r1) = param!(self, ParamBB);
core::ptr::swap( match (r0, r1) {
self.registers.get_unchecked_mut(usize::from(src)), (0, 0) => (),
self.registers.get_unchecked_mut(usize::from(dst)), (dst, 0) | (0, dst) => self.write_reg(dst, 0_u64),
); (r0, r1) => {
core::ptr::swap(
self.registers.get_unchecked_mut(usize::from(r0)),
self.registers.get_unchecked_mut(usize::from(r1)),
);
}
} }
} }
LI => { LI => {
@ -225,6 +239,7 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
self.write_reg(param.0, param.1); self.write_reg(param.0, param.1);
} }
LD => { LD => {
// Load. If loading more than register size, continue on adjecent registers
let ParamBBDH(dst, base, off, count) = param!(self, ParamBBDH); let ParamBBDH(dst, base, off, count) = param!(self, ParamBBDH);
let n: usize = match dst { let n: usize = match dst {
0 => 1, 0 => 1,
@ -239,6 +254,7 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
)?; )?;
} }
ST => { ST => {
// Store. Same rules apply as to LD
let ParamBBDH(dst, base, off, count) = param!(self, ParamBBDH); let ParamBBDH(dst, base, off, count) = param!(self, ParamBBDH);
self.memory.store( self.memory.store(
self.read_reg(base).as_u64() + off, self.read_reg(base).as_u64() + off,
@ -248,6 +264,7 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
)?; )?;
} }
BMC => { BMC => {
// Block memory copy
let ParamBBD(src, dst, count) = param!(self, ParamBBD); let ParamBBD(src, dst, count) = param!(self, ParamBBD);
self.memory.block_copy( self.memory.block_copy(
self.read_reg(src).as_u64(), self.read_reg(src).as_u64(),
@ -257,6 +274,7 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
)?; )?;
} }
BRC => { BRC => {
// Block register copy
let ParamBBB(src, dst, count) = param!(self, ParamBBB); let ParamBBB(src, dst, count) = param!(self, ParamBBB);
core::ptr::copy( core::ptr::copy(
self.registers.get_unchecked(usize::from(src)), self.registers.get_unchecked(usize::from(src)),
@ -265,10 +283,13 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
); );
} }
JAL => { JAL => {
// Jump and link. Save PC after this instruction to
// specified register and jump to reg + offset.
let ParamBBD(save, reg, offset) = param!(self, ParamBBD); let ParamBBD(save, reg, offset) = param!(self, ParamBBD);
self.write_reg(save, self.pc as u64); self.write_reg(save, self.pc as u64);
self.pc = (self.read_reg(reg).as_u64() + offset) as usize; self.pc = (self.read_reg(reg).as_u64() + offset) as usize;
} }
// Conditional jumps, jump only to immediates
JEQ => cond_jump!(self, int, Equal), JEQ => cond_jump!(self, int, Equal),
JNE => { JNE => {
let ParamBBD(a0, a1, jt) = param!(self, ParamBBD); let ParamBBD(a0, a1, jt) = param!(self, ParamBBD);
@ -282,6 +303,11 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
JGTU => cond_jump!(self, sint, Greater), JGTU => cond_jump!(self, sint, Greater),
ECALL => { ECALL => {
param!(self, ()); param!(self, ());
// So we don't get timer interrupt after ECALL
if TIMER_QUOTIENT != 0 {
self.timer = self.timer.wrapping_add(1);
}
return Ok(VmRunOk::Ecall); return Ok(VmRunOk::Ecall);
} }
ADDF => binary_op!(self, as_f64, ops::Add::add), ADDF => binary_op!(self, as_f64, ops::Add::add),

View file

@ -124,6 +124,9 @@
### Swap ### Swap
- Type BB - Type BB
- Swap #0 and #1 - Swap #0 and #1
- Zero register rules:
- Both: no-op
- One: Copy zero to the non-zero register
| Opcode | Name | Action | | Opcode | Name | Action |
|:------:|:----:|:------:| |:------:|:----:|:------:|
@ -263,8 +266,8 @@
# Program execution # Program execution
- The way of program execution is implementation defined - The way of program execution is implementation defined
- The order of instruction is arbitrary, as long all observable - The execution is arbitrary, as long all effects are obervable
effects are applied in the program's order in the way as program was executed literally, in order.
# Program validation # Program validation
- Invalid program should cause runtime error: - Invalid program should cause runtime error: