diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2024-09-07 18:21:24 +1200 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2024-09-07 18:22:22 +1200 |
commit | e4fe2229314411f597e4d20dc64c6fda390e81f2 (patch) | |
tree | 28e1b73397cb72786dc5d67931d0469ca514764c /src | |
parent | 227df52d0bad2118ec7ae990f17157c1f79ffea9 (diff) | |
download | bedrock-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.rs | 40 | ||||
-rw-r--r-- | src/stack.rs | 36 |
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(); + } +} |