summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Bridle <bridle.benjamin@gmail.com>2024-09-07 18:21:24 +1200
committerBen Bridle <bridle.benjamin@gmail.com>2024-09-07 18:22:22 +1200
commite4fe2229314411f597e4d20dc64c6fda390e81f2 (patch)
tree28e1b73397cb72786dc5d67931d0469ca514764c /src
parent227df52d0bad2118ec7ae990f17157c1f79ffea9 (diff)
downloadbedrock-core-e4fe2229314411f597e4d20dc64c6fda390e81f2.zip
Implement micro optimisations for unary operators
A 1% speed increase was observed when testing a tight decrementing loop with these optimisations.
Diffstat (limited to 'src')
-rw-r--r--src/processor.rs40
-rw-r--r--src/stack.rs36
2 files changed, 56 insertions, 20 deletions
diff --git a/src/processor.rs b/src/processor.rs
index 82fb3b4..16e5125 100644
--- a/src/processor.rs
+++ b/src/processor.rs
@@ -67,7 +67,7 @@ impl<D: DeviceBus> Processor<D> {
/* LDD */ 0x06 => { w_pop_8!(p); w_psh_8!(d_read_8!(p)); }
/* STD */ 0x07 => { w_pop_8!(p); w_pop_8!(v); d_write_8!(v,p); }
/* PSH */ 0x08 => { r_pop_8!(x); w_psh_8!(x); }
- /* POP */ 0x09 => { w_pop_8!(_x); }
+ /* POP */ 0x09 => { self.wst.sp = self.wst.sp.wrapping_sub(1); }
/* CPY */ 0x0A => { r_get_8!(x); w_psh_8!(x); }
/* SPL */ 0x0B => { w_pop_8!(x); nyb!(x=>a,b); w_psh_8!(a); w_psh_8!(b); }
/* DUP */ 0x0C => { w_get_8!(x); w_psh_8!(x); }
@@ -76,8 +76,8 @@ impl<D: DeviceBus> Processor<D> {
/* ROT */ 0x0F => { w_pop_8!(z); w_pop_8!(y); w_pop_8!(x); w_psh_8!(y); w_psh_8!(z); w_psh_8!(x); }
/* ADD */ 0x10 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(x.wrapping_add(y)); }
/* SUB */ 0x11 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(x.wrapping_sub(y)); }
- /* INC */ 0x12 => { w_pop_8!(x); w_psh_8!(x.wrapping_add(1)); }
- /* DEC */ 0x13 => { w_pop_8!(x); w_psh_8!(x.wrapping_sub(1)); }
+ /* INC */ 0x12 => { self.wst.inc_u8(); }
+ /* DEC */ 0x13 => { self.wst.dec_u8(); }
/* LTH */ 0x14 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(truth!(x < y)); }
/* GTH */ 0x15 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(truth!(x > y)); }
/* EQU */ 0x16 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(truth!(x==y)); }
@@ -85,11 +85,11 @@ impl<D: DeviceBus> Processor<D> {
/* IOR */ 0x18 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(x.bitor(y)); }
/* XOR */ 0x19 => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(x.bitxor(y)); }
/* AND */ 0x1A => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(x.bitand(y)); }
- /* NOT */ 0x1B => { w_pop_8!(x); w_psh_8!(x.not()); }
+ /* NOT */ 0x1B => { self.wst.not_u8(); }
/* SHF */ 0x1C => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(shf!(x,y)); }
/* SHC */ 0x1D => { w_pop_8!(y); w_pop_8!(x); w_psh_8!(shc!(x,y)); }
- /* TAL */ 0x1E => { w_pop_8!(x); w_psh_8!(x.count_ones() as u8); }
- /* REV */ 0x1F => { w_pop_8!(x); w_psh_8!(x.reverse_bits()); }
+ /* TAL */ 0x1E => { self.wst.tal_u8(); }
+ /* REV */ 0x1F => { self.wst.rev_u8(); }
/* NOP */ 0x20 => { }
/* JMS */ 0x21 => { w_pop_16!(a); r_psh_16!(pc!()); jump!(a); }
@@ -100,7 +100,7 @@ impl<D: DeviceBus> Processor<D> {
/* LDD* */ 0x26 => { w_pop_8!(p); w_psh_16!(d_read_16!(p)); }
/* STD* */ 0x27 => { w_pop_8!(p); w_pop_16!(v); d_write_16!(v,p); }
/* PSH* */ 0x28 => { r_pop_16!(x); w_psh_16!(x); }
- /* POP* */ 0x29 => { w_pop_16!(_x); }
+ /* POP* */ 0x29 => { self.wst.sp = self.wst.sp.wrapping_sub(2); }
/* CPY* */ 0x2A => { r_get_16!(x); w_psh_16!(x); }
/* SPL* */ 0x2B => { w_pop_8!(y); w_pop_8!(x); nyb!(x=>a,b); nyb!(y=>c,d); w_psh_8!(a); w_psh_8!(b); w_psh_8!(c); w_psh_8!(d); }
/* DUP* */ 0x2C => { w_get_16!(x); w_psh_16!(x); }
@@ -118,7 +118,7 @@ impl<D: DeviceBus> Processor<D> {
/* IOR* */ 0x38 => { w_pop_16!(y); w_pop_16!(x); w_psh_16!(x.bitor(y)); }
/* XOR* */ 0x39 => { w_pop_16!(y); w_pop_16!(x); w_psh_16!(x.bitxor(y)); }
/* AND* */ 0x3A => { w_pop_16!(y); w_pop_16!(x); w_psh_16!(x.bitand(y)); }
- /* NOT* */ 0x3B => { w_pop_16!(x); w_psh_16!(x.not()); }
+ /* NOT* */ 0x3B => { self.wst.not_u16(); }
/* SHF* */ 0x3C => { w_pop_8!(y); w_pop_16!(x); w_psh_16!(shf!(x,y)); }
/* SHC* */ 0x3D => { w_pop_8!(y); w_pop_16!(x); w_psh_16!(shc!(x,y)); }
/* TAL* */ 0x3E => { w_pop_16!(x); w_psh_8!(x.count_ones() as u8); }
@@ -133,7 +133,7 @@ impl<D: DeviceBus> Processor<D> {
/* LDD: */ 0x46 => { m_lit_8!(p); w_psh_8!(d_read_8!(p)); }
/* STD: */ 0x47 => { m_lit_8!(p); w_pop_8!(v); d_write_8!(v,p); }
/* PSH: */ 0x48 => { m_lit_8!(x); w_psh_8!(x); }
- /* POP: */ 0x49 => { m_lit_8!(_x); }
+ /* POP: */ 0x49 => { self.mem.pc = self.mem.pc.wrapping_add(1); }
/* CPY: */ 0x4A => { m_lit_8!(x); w_psh_8!(x); r_psh_8!(x); }
/* SPL: */ 0x4B => { m_lit_8!(x); nyb!(x=>a,b); w_psh_8!(a); w_psh_8!(b); }
/* DUP: */ 0x4C => { m_lit_8!(x); w_psh_8!(x); w_psh_8!(x); }
@@ -166,7 +166,7 @@ impl<D: DeviceBus> Processor<D> {
/* LDD*: */ 0x66 => { m_lit_8!(p); w_psh_16!(d_read_16!(p)); }
/* STD*: */ 0x67 => { m_lit_8!(p); w_pop_16!(v); d_write_16!(v,p); }
/* PSH*: */ 0x68 => { m_lit_16!(x); w_psh_16!(x); }
- /* POP*: */ 0x69 => { m_lit_16!(_x); }
+ /* POP*: */ 0x69 => { self.mem.pc = self.mem.pc.wrapping_add(2); }
/* CPY*: */ 0x6A => { m_lit_16!(x); w_psh_16!(x); r_psh_16!(x); }
/* SPL*: */ 0x6B => { m_lit_8!(x); m_lit_8!(y); nyb!(x=>a,b); nyb!(y=>c,d); w_psh_8!(a); w_psh_8!(b); w_psh_8!(c); w_psh_8!(d); }
/* DUP*: */ 0x6C => { m_lit_16!(x); w_psh_16!(x); w_psh_16!(x); }
@@ -199,7 +199,7 @@ impl<D: DeviceBus> Processor<D> {
/* LDDr */ 0x86 => { r_pop_8!(p); r_psh_8!(d_read_8!(p)); }
/* STDr */ 0x87 => { r_pop_8!(p); r_pop_8!(v); d_write_8!(v,p); }
/* PSHr */ 0x88 => { w_pop_8!(x); r_psh_8!(x); }
- /* POPr */ 0x89 => { r_pop_8!(_x); }
+ /* POPr */ 0x89 => { self.rst.sp = self.rst.sp.wrapping_sub(1); }
/* CPYr */ 0x8A => { w_get_8!(x); r_psh_8!(x); }
/* SPLr */ 0x8B => { r_pop_8!(x); nyb!(x=>a,b); r_psh_8!(a); r_psh_8!(b); }
/* DUPr */ 0x8C => { r_get_8!(x); r_psh_8!(x); }
@@ -208,8 +208,8 @@ impl<D: DeviceBus> Processor<D> {
/* ROTr */ 0x8F => { r_pop_8!(z); r_pop_8!(y); r_pop_8!(x); r_psh_8!(y); r_psh_8!(z); r_psh_8!(x); }
/* ADDr */ 0x90 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(x.wrapping_add(y)); }
/* SUBr */ 0x91 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(x.wrapping_sub(y)); }
- /* INCr */ 0x92 => { r_pop_8!(x); r_psh_8!(x.wrapping_add(1)); }
- /* DECr */ 0x93 => { r_pop_8!(x); r_psh_8!(x.wrapping_sub(1)); }
+ /* INCr */ 0x92 => { self.rst.inc_u8(); }
+ /* DECr */ 0x93 => { self.rst.dec_u8(); }
/* LTHr */ 0x94 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(truth!(x < y)); }
/* GTHr */ 0x95 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(truth!(x > y)); }
/* EQUr */ 0x96 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(truth!(x==y)); }
@@ -217,11 +217,11 @@ impl<D: DeviceBus> Processor<D> {
/* IORr */ 0x98 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(x.bitor(y)); }
/* XORr */ 0x99 => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(x.bitxor(y)); }
/* ANDr */ 0x9A => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(x.bitand(y)); }
- /* NOTr */ 0x9B => { r_pop_8!(x); r_psh_8!(x.not()); }
+ /* NOTr */ 0x9B => { self.rst.not_u8(); }
/* SHFr */ 0x9C => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(shf!(x,y)); }
/* SHCr */ 0x9D => { r_pop_8!(y); r_pop_8!(x); r_psh_8!(shc!(x,y)); }
- /* TALr */ 0x9E => { r_pop_8!(x); r_psh_8!(x.count_ones() as u8); }
- /* REVr */ 0x9F => { r_pop_8!(x); r_psh_8!(x.reverse_bits()); }
+ /* TALr */ 0x9E => { self.rst.tal_u8(); }
+ /* REVr */ 0x9F => { self.rst.rev_u8(); }
/* DB4 */ 0xA0 => { return Some(Signal::Debug(DebugVariant::DB4)); }
/* JMSr */ 0xA1 => { r_pop_16!(a); w_psh_16!(pc!()); jump!(a); }
@@ -232,7 +232,7 @@ impl<D: DeviceBus> Processor<D> {
/* LDDr* */ 0xA6 => { r_pop_8!(p); r_psh_16!(d_read_16!(p)); }
/* STDr* */ 0xA7 => { r_pop_8!(p); r_pop_16!(v); d_write_16!(v,p); }
/* PSHr* */ 0xA8 => { w_pop_16!(x); r_psh_16!(x); }
- /* POPr* */ 0xA9 => { r_pop_16!(_x); }
+ /* POPr* */ 0xA9 => { self.rst.sp = self.rst.sp.wrapping_sub(2); }
/* CPYr* */ 0xAA => { w_get_16!(x); r_psh_16!(x); }
/* SPLr* */ 0xAB => { r_pop_8!(y); r_pop_8!(x); nyb!(x=>a,b); nyb!(y=>c,d); r_psh_8!(a); r_psh_8!(b); r_psh_8!(c); r_psh_8!(d); }
/* DUPr* */ 0xAC => { r_get_16!(x); r_psh_16!(x); }
@@ -250,7 +250,7 @@ impl<D: DeviceBus> Processor<D> {
/* IORr* */ 0xB8 => { r_pop_16!(y); r_pop_16!(x); r_psh_16!(x.bitor(y)); }
/* XORr* */ 0xB9 => { r_pop_16!(y); r_pop_16!(x); r_psh_16!(x.bitxor(y)); }
/* ANDr* */ 0xBA => { r_pop_16!(y); r_pop_16!(x); r_psh_16!(x.bitand(y)); }
- /* NOTr* */ 0xBB => { r_pop_16!(x); r_psh_16!(x.not()); }
+ /* NOTr* */ 0xBB => { self.rst.not_u16(); }
/* SHFr* */ 0xBC => { r_pop_8!(y); r_pop_16!(x); r_psh_16!(shf!(x,y)); }
/* SHCr* */ 0xBD => { r_pop_8!(y); r_pop_16!(x); r_psh_16!(shc!(x,y)); }
/* TALr* */ 0xBE => { r_pop_16!(x); r_psh_8!(x.count_ones() as u8); }
@@ -265,7 +265,7 @@ impl<D: DeviceBus> Processor<D> {
/* LDDr: */ 0xC6 => { m_lit_8!(p); r_psh_8!(d_read_8!(p)); }
/* STDr: */ 0xC7 => { m_lit_8!(p); r_pop_8!(v); d_write_8!(v,p); }
/* PSHr: */ 0xC8 => { m_lit_8!(x); r_psh_8!(x); }
- /* POPr: */ 0xC9 => { m_lit_8!(_x); }
+ /* POPr: */ 0xC9 => { self.mem.pc = self.mem.pc.wrapping_add(1); }
/* CPYr: */ 0xCA => { m_lit_8!(x); w_psh_8!(x); r_psh_8!(x); }
/* SPLr: */ 0xCB => { m_lit_8!(x); nyb!(x=>a,b); r_psh_8!(a); r_psh_8!(b); }
/* DUPr: */ 0xCC => { m_lit_8!(x); r_psh_8!(x); r_psh_8!(x); }
@@ -298,7 +298,7 @@ impl<D: DeviceBus> Processor<D> {
/* LDDr*: */ 0xE6 => { m_lit_8!(p); r_psh_16!(d_read_16!(p)); }
/* STDr*: */ 0xE7 => { m_lit_8!(p); r_pop_16!(v); d_write_16!(v,p); }
/* PSHr*: */ 0xE8 => { m_lit_16!(x); r_psh_16!(x); }
- /* POPr*: */ 0xE9 => { m_lit_16!(_x); }
+ /* POPr*: */ 0xE9 => { self.mem.pc = self.mem.pc.wrapping_add(2); }
/* CPYr*: */ 0xEA => { m_lit_16!(x); w_psh_16!(x); r_psh_16!(x); }
/* SPLr*: */ 0xEB => { m_lit_8!(x); m_lit_8!(y); nyb!(x=>a,b); nyb!(y=>c,d); r_psh_8!(a); r_psh_8!(b); r_psh_8!(c); r_psh_8!(d); }
/* DUPr*: */ 0xEC => { m_lit_16!(x); r_psh_16!(x); r_psh_16!(x); }
diff --git a/src/stack.rs b/src/stack.rs
index 14e1799..2862b72 100644
--- a/src/stack.rs
+++ b/src/stack.rs
@@ -50,3 +50,39 @@ impl Stack {
self.sp = 0;
}
}
+
+use std::ops::Not;
+
+impl Stack {
+ pub fn inc_u8(&mut self) {
+ let sp = self.sp.wrapping_sub(1) as usize;
+ self.mem[sp] = self.mem[sp].wrapping_add(1);
+ }
+
+ pub fn dec_u8(&mut self) {
+ let sp = self.sp.wrapping_sub(1) as usize;
+ self.mem[sp] = self.mem[sp].wrapping_sub(1);
+ }
+
+ pub fn not_u8(&mut self) {
+ let sp = self.sp.wrapping_sub(1) as usize;
+ self.mem[sp] = self.mem[sp].not();
+ }
+
+ pub fn not_u16(&mut self) {
+ let sp = self.sp.wrapping_sub(1) as usize;
+ self.mem[sp] = self.mem[sp].not();
+ let sp = self.sp.wrapping_sub(2) as usize;
+ self.mem[sp] = self.mem[sp].not();
+ }
+
+ pub fn tal_u8(&mut self) {
+ let sp = self.sp.wrapping_sub(1) as usize;
+ self.mem[sp] = self.mem[sp].count_ones() as u8;
+ }
+
+ pub fn rev_u8(&mut self) {
+ let sp = self.sp.wrapping_sub(1) as usize;
+ self.mem[sp] = self.mem[sp].reverse_bits();
+ }
+}