Inlining performance critical functions

This commit is contained in:
Kevin Hamacher 2016-05-29 14:18:47 +02:00
parent 2499eedfd2
commit 47a4b0c720
3 changed files with 48 additions and 1 deletions

View File

@ -58,10 +58,12 @@ impl CPU {
} }
} }
#[inline]
fn read_byte(&self, addr: u16) -> u8 { fn read_byte(&self, addr: u16) -> u8 {
self.interconnect.read_byte(addr) self.interconnect.read_byte(addr)
} }
#[inline]
fn load_args(&mut self, num_args: u8) -> Box<[u8]> { fn load_args(&mut self, num_args: u8) -> Box<[u8]> {
let mut args = Vec::new(); let mut args = Vec::new();
for i in 0..num_args { for i in 0..num_args {
@ -71,6 +73,7 @@ impl CPU {
args.into_boxed_slice() args.into_boxed_slice()
} }
#[inline]
fn set_8bit_reg(&mut self, reg_id: usize, value: u8) { fn set_8bit_reg(&mut self, reg_id: usize, value: u8) {
// Make sure that we skip the (HL) part. // Make sure that we skip the (HL) part.
if reg_id == REG_N_A { if reg_id == REG_N_A {
@ -85,6 +88,7 @@ impl CPU {
} }
} }
#[inline]
fn get_8bit_reg(&self, reg_id: usize) -> u8 { fn get_8bit_reg(&self, reg_id: usize) -> u8 {
// Make sure that we skip the (HL) part. // Make sure that we skip the (HL) part.
if reg_id == REG_N_A { if reg_id == REG_N_A {
@ -99,6 +103,7 @@ impl CPU {
} }
} }
#[inline]
fn run_prefix_instruction(&mut self) { fn run_prefix_instruction(&mut self) {
let instruction = self.read_byte(self.ip); let instruction = self.read_byte(self.ip);
self.ip += 1; self.ip += 1;
@ -464,10 +469,12 @@ impl CPU {
} }
} }
#[inline]
fn get_pair_value(&self, a: usize, b: usize) -> u16 { fn get_pair_value(&self, a: usize, b: usize) -> u16 {
(self.get_8bit_reg(a) as u16) << 8 | self.get_8bit_reg(b) as u16 (self.get_8bit_reg(a) as u16) << 8 | self.get_8bit_reg(b) as u16
} }
#[inline]
fn set_pair_value(&mut self, a: usize, b: usize, value: u16) { fn set_pair_value(&mut self, a: usize, b: usize, value: u16) {
self.set_8bit_reg(a, (value >> 8) as u8); self.set_8bit_reg(a, (value >> 8) as u8);
self.set_8bit_reg(b, value as u8); self.set_8bit_reg(b, value as u8);
@ -479,6 +486,7 @@ impl CPU {
} }
} }
#[inline]
fn call(&mut self, dst: u16) { fn call(&mut self, dst: u16) {
let ip = self.ip; let ip = self.ip;
self.push(ip); self.push(ip);
@ -486,6 +494,7 @@ impl CPU {
self.ip = dst; self.ip = dst;
} }
#[inline]
fn call_condition(&mut self, cond_str: String, cond: bool) -> u8 { fn call_condition(&mut self, cond_str: String, cond: bool) -> u8 {
let dst = to_u16(self.load_args(2)); let dst = to_u16(self.load_args(2));
if self.debug { if self.debug {
@ -499,6 +508,7 @@ impl CPU {
} }
} }
#[inline]
fn ret_condition(&mut self, cond_str: String, cond: bool) -> u8 { fn ret_condition(&mut self, cond_str: String, cond: bool) -> u8 {
if self.debug { if self.debug {
println!("RET {}", cond_str); println!("RET {}", cond_str);
@ -511,6 +521,7 @@ impl CPU {
} }
} }
#[inline]
fn jmp_r(&mut self, addr: u8) { fn jmp_r(&mut self, addr: u8) {
let off: i8 = addr as i8; let off: i8 = addr as i8;
if off < 0 { if off < 0 {
@ -520,6 +531,7 @@ impl CPU {
} }
} }
#[inline]
fn jmp_r_condition(&mut self, cond_str: String, cond: bool) -> u8 { fn jmp_r_condition(&mut self, cond_str: String, cond: bool) -> u8 {
let t = self.load_args(1)[0]; let t = self.load_args(1)[0];
if self.debug { if self.debug {
@ -533,10 +545,12 @@ impl CPU {
} }
} }
#[inline]
fn jmp_p(&mut self, addr: u16) { fn jmp_p(&mut self, addr: u16) {
self.ip = addr; self.ip = addr;
} }
#[inline]
fn jmp_p_condition(&mut self, cond_str: String, cond: bool) -> u8 { fn jmp_p_condition(&mut self, cond_str: String, cond: bool) -> u8 {
let t = to_u16(self.load_args(2)); let t = to_u16(self.load_args(2));
if self.debug { if self.debug {
@ -550,6 +564,7 @@ impl CPU {
} }
} }
#[inline]
fn rst(&mut self, val: u8) -> u8 { fn rst(&mut self, val: u8) -> u8 {
// Make sure this is correct. // Make sure this is correct.
if self.debug { if self.debug {
@ -559,6 +574,7 @@ impl CPU {
16 16
} }
#[inline]
fn pop_rr(&mut self, r1: usize, r2: usize) -> u8 { fn pop_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug { if self.debug {
println!("POP {}{}", REG_NAMES[r1], REG_NAMES[r2]); println!("POP {}{}", REG_NAMES[r1], REG_NAMES[r2]);
@ -567,6 +583,8 @@ impl CPU {
self.set_pair_value(r1, r2, val); self.set_pair_value(r1, r2, val);
12 12
} }
#[inline]
fn push_rr(&mut self, r1: usize, r2: usize) -> u8 { fn push_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug { if self.debug {
println!("PUSH {}{}", REG_NAMES[r1], REG_NAMES[r2]); println!("PUSH {}{}", REG_NAMES[r1], REG_NAMES[r2]);
@ -576,6 +594,7 @@ impl CPU {
16 16
} }
#[inline]
fn dec_rr(&mut self, r1: usize, r2: usize) -> u8 { fn dec_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug { if self.debug {
println!("DEC {}{}", REG_NAMES[r1], REG_NAMES[r2]); println!("DEC {}{}", REG_NAMES[r1], REG_NAMES[r2]);
@ -586,6 +605,7 @@ impl CPU {
8 8
} }
#[inline]
fn inc_rr(&mut self, r1: usize, r2: usize) -> u8 { fn inc_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug { if self.debug {
println!("INC {}{}", REG_NAMES[r1], REG_NAMES[r2]); println!("INC {}{}", REG_NAMES[r1], REG_NAMES[r2]);
@ -596,17 +616,20 @@ impl CPU {
8 8
} }
#[inline]
fn push(&mut self, val: u16) { fn push(&mut self, val: u16) {
self.interconnect.write_word(self.sp - 1, val); self.interconnect.write_word(self.sp - 1, val);
self.sp -= 2; self.sp -= 2;
} }
#[inline]
fn pop(&mut self) -> u16 { fn pop(&mut self) -> u16 {
let v: u16 = self.interconnect.read_word(self.sp + 1); let v: u16 = self.interconnect.read_word(self.sp + 1);
self.sp += 2; self.sp += 2;
v v
} }
#[inline]
fn ld_r_r(&mut self, reg_dst: usize, reg_src: usize) -> u8 { fn ld_r_r(&mut self, reg_dst: usize, reg_src: usize) -> u8 {
if self.debug { if self.debug {
// println!("LD {}, {}", REG_NAMES[reg_dst], REG_NAMES[reg_src]) // println!("LD {}, {}", REG_NAMES[reg_dst], REG_NAMES[reg_src])
@ -620,6 +643,7 @@ impl CPU {
} }
} }
#[inline]
fn ld_r_v(&mut self, r: usize) -> u8 { fn ld_r_v(&mut self, r: usize) -> u8 {
let val: u8 = self.load_args(1)[0]; let val: u8 = self.load_args(1)[0];
if self.debug { if self.debug {
@ -633,6 +657,7 @@ impl CPU {
} }
} }
#[inline]
fn ld_rr_vv(&mut self, r1: usize, r2: usize) -> u8 { fn ld_rr_vv(&mut self, r1: usize, r2: usize) -> u8 {
let val: u16 = to_u16(self.load_args(2)); let val: u16 = to_u16(self.load_args(2));
if self.debug { if self.debug {
@ -642,6 +667,7 @@ impl CPU {
12 12
} }
#[inline]
fn reg_inc(&mut self, reg_id: usize) -> u8 { fn reg_inc(&mut self, reg_id: usize) -> u8 {
if self.debug { if self.debug {
println!("INC {}", REG_NAMES[reg_id]); println!("INC {}", REG_NAMES[reg_id]);
@ -654,6 +680,7 @@ impl CPU {
4 4
} }
#[inline]
fn add_rr_rr(&mut self, r1: usize, r2: usize, r3: usize, r4: usize) -> u8 { fn add_rr_rr(&mut self, r1: usize, r2: usize, r3: usize, r4: usize) -> u8 {
let val1 = self.get_pair_value(r1, r2); let val1 = self.get_pair_value(r1, r2);
let val2 = self.get_pair_value(r3, r4); let val2 = self.get_pair_value(r3, r4);
@ -661,6 +688,7 @@ impl CPU {
8 8
} }
#[inline]
fn reg_dec(&mut self, reg_id: usize) -> u8 { fn reg_dec(&mut self, reg_id: usize) -> u8 {
if self.debug { if self.debug {
println!("DEC {}", REG_NAMES[reg_id]); println!("DEC {}", REG_NAMES[reg_id]);
@ -674,6 +702,7 @@ impl CPU {
4 4
} }
#[inline]
fn ld_dref_rr_a(&mut self, r1: usize, r2: usize) -> u8 { fn ld_dref_rr_a(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug { if self.debug {
println!("LD ({}{}), A", REG_NAMES[r1], REG_NAMES[r2]); println!("LD ({}{}), A", REG_NAMES[r1], REG_NAMES[r2]);
@ -684,14 +713,17 @@ impl CPU {
8 8
} }
#[inline]
fn set_flag(&mut self, flag: u8) { fn set_flag(&mut self, flag: u8) {
self.flags |= flag; self.flags |= flag;
} }
#[inline]
fn clear_flag(&mut self, flag: u8) { fn clear_flag(&mut self, flag: u8) {
self.flags &= !flag; self.flags &= !flag;
} }
#[inline]
fn set_clear_flag(&mut self, flag: u8, dep: bool) { fn set_clear_flag(&mut self, flag: u8, dep: bool) {
if dep { if dep {
self.set_flag(flag); self.set_flag(flag);
@ -700,6 +732,7 @@ impl CPU {
} }
} }
#[inline]
fn int_(&mut self, val: u8){ fn int_(&mut self, val: u8){
if self.debug { if self.debug {
println!("INT {:02X}", val); println!("INT {:02X}", val);
@ -709,18 +742,21 @@ impl CPU {
self.call(val as u16); self.call(val as u16);
} }
#[inline]
fn ret(&mut self) { fn ret(&mut self) {
let new_ip: u16 = self.pop(); let new_ip: u16 = self.pop();
//self.dump_stack(); //self.dump_stack();
self.ip = new_ip; self.ip = new_ip;
} }
#[inline]
fn reti(&mut self) -> u8 { fn reti(&mut self) -> u8 {
self.ret(); self.ret();
self.ime = true; self.ime = true;
16 16
} }
#[inline]
fn handle_interrupt(&mut self, offset: u8, flag: u8) { fn handle_interrupt(&mut self, offset: u8, flag: u8) {
// Remove interrupt requested flag // Remove interrupt requested flag
let new_flag = self.interconnect.read_byte(0xFF0F) & !flag; let new_flag = self.interconnect.read_byte(0xFF0F) & !flag;

View File

@ -112,11 +112,13 @@ impl Display {
} }
} }
#[inline]
fn set_pixel(&mut self, x: u8, y: u8, color: sdl2::pixels::Color) { fn set_pixel(&mut self, x: u8, y: u8, color: sdl2::pixels::Color) {
self.renderer.set_draw_color(color); self.renderer.set_draw_color(color);
self.renderer.fill_rect(sdl2::rect::Rect::new((x as i32) * SCALE as i32, (y as i32) * SCALE as i32, SCALE as u32, SCALE as u32)); self.renderer.fill_rect(sdl2::rect::Rect::new((x as i32) * SCALE as i32, (y as i32) * SCALE as i32, SCALE as u32, SCALE as u32));
} }
#[inline]
pub fn vblank_interrupt(&mut self) -> bool { pub fn vblank_interrupt(&mut self) -> bool {
// Returns whether or not a vblank interrupt should be done // Returns whether or not a vblank interrupt should be done
// Yes, this is polling, and yes, this sucks.\ // Yes, this is polling, and yes, this sucks.\
@ -128,6 +130,7 @@ impl Display {
} }
} }
#[inline]
pub fn stat_interrupt(&mut self) -> bool { pub fn stat_interrupt(&mut self) -> bool {
if self.stat_interrupt { if self.stat_interrupt {
self.stat_interrupt = false; self.stat_interrupt = false;
@ -137,6 +140,7 @@ impl Display {
} }
} }
#[inline]
pub fn write_byte(&mut self, addr: u16, val: u8) { pub fn write_byte(&mut self, addr: u16, val: u8) {
match addr { match addr {
0x8000 ... 0x9FFF => { 0x8000 ... 0x9FFF => {
@ -162,6 +166,7 @@ impl Display {
} }
} }
#[inline]
pub fn read_byte(&self, addr: u16) -> u8 { pub fn read_byte(&self, addr: u16) -> u8 {
match addr { match addr {
0x8000 ... 0x9FFF => self.vram[(addr - 0x8000) as usize], 0x8000 ... 0x9FFF => self.vram[(addr - 0x8000) as usize],
@ -181,7 +186,7 @@ impl Display {
} }
} }
// Do we want to have a time delta here? #[inline]
pub fn tick(&mut self, ticks: u16) { pub fn tick(&mut self, ticks: u16) {
self.status &= 0xFC; self.status &= 0xFC;
if self.control & CTRL_LCD_DISPLAY_ENABLE == 0 { if self.control & CTRL_LCD_DISPLAY_ENABLE == 0 {
@ -270,6 +275,7 @@ impl Display {
} }
} }
#[inline]
fn renderscan(&mut self) { fn renderscan(&mut self) {
// Points to the background map offset to use. // Points to the background map offset to use.
let background_map: usize; let background_map: usize;

View File

@ -167,10 +167,12 @@ impl Interconnect {
} }
} }
#[inline]
pub fn is_boot_rom(&self) -> bool { pub fn is_boot_rom(&self) -> bool {
self.disable_bootrom == 0 self.disable_bootrom == 0
} }
#[inline]
pub fn read_byte(&self, addr: u16) -> u8 { pub fn read_byte(&self, addr: u16) -> u8 {
// TODO: Make this more beautiful. // TODO: Make this more beautiful.
// TODO: if some flag set, use bios, otherwise only use rom // TODO: if some flag set, use bios, otherwise only use rom
@ -241,6 +243,7 @@ impl Interconnect {
} }
} }
#[inline]
pub fn write_byte(&mut self, addr: u16, val: u8) { pub fn write_byte(&mut self, addr: u16, val: u8) {
// TODO: Make this more beautful // TODO: Make this more beautful
/* /*
@ -336,11 +339,13 @@ impl Interconnect {
} }
} }
#[inline]
pub fn write_word(&mut self, addr: u16, val: u16) { pub fn write_word(&mut self, addr: u16, val: u16) {
self.write_byte(addr, val as u8); self.write_byte(addr, val as u8);
self.write_byte(addr + 1, (val >> 8) as u8); self.write_byte(addr + 1, (val >> 8) as u8);
} }
#[inline]
pub fn read_word(&self, addr: u16) -> u16 { pub fn read_word(&self, addr: u16) -> u16 {
self.read_byte(addr) as u16 | (self.read_byte(addr + 1) as u16) << 8 self.read_byte(addr) as u16 | (self.read_byte(addr + 1) as u16) << 8
// (self.read_byte(addr) as u16) << 8 | (self.read_byte(addr + 1) as u16) // (self.read_byte(addr) as u16) << 8 | (self.read_byte(addr + 1) as u16)