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 {
self.interconnect.read_byte(addr)
}
#[inline]
fn load_args(&mut self, num_args: u8) -> Box<[u8]> {
let mut args = Vec::new();
for i in 0..num_args {
@ -71,6 +73,7 @@ impl CPU {
args.into_boxed_slice()
}
#[inline]
fn set_8bit_reg(&mut self, reg_id: usize, value: u8) {
// Make sure that we skip the (HL) part.
if reg_id == REG_N_A {
@ -85,6 +88,7 @@ impl CPU {
}
}
#[inline]
fn get_8bit_reg(&self, reg_id: usize) -> u8 {
// Make sure that we skip the (HL) part.
if reg_id == REG_N_A {
@ -99,6 +103,7 @@ impl CPU {
}
}
#[inline]
fn run_prefix_instruction(&mut self) {
let instruction = self.read_byte(self.ip);
self.ip += 1;
@ -464,10 +469,12 @@ impl CPU {
}
}
#[inline]
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
}
#[inline]
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(b, value as u8);
@ -479,6 +486,7 @@ impl CPU {
}
}
#[inline]
fn call(&mut self, dst: u16) {
let ip = self.ip;
self.push(ip);
@ -486,6 +494,7 @@ impl CPU {
self.ip = dst;
}
#[inline]
fn call_condition(&mut self, cond_str: String, cond: bool) -> u8 {
let dst = to_u16(self.load_args(2));
if self.debug {
@ -499,6 +508,7 @@ impl CPU {
}
}
#[inline]
fn ret_condition(&mut self, cond_str: String, cond: bool) -> u8 {
if self.debug {
println!("RET {}", cond_str);
@ -511,6 +521,7 @@ impl CPU {
}
}
#[inline]
fn jmp_r(&mut self, addr: u8) {
let off: i8 = addr as i8;
if off < 0 {
@ -520,6 +531,7 @@ impl CPU {
}
}
#[inline]
fn jmp_r_condition(&mut self, cond_str: String, cond: bool) -> u8 {
let t = self.load_args(1)[0];
if self.debug {
@ -533,10 +545,12 @@ impl CPU {
}
}
#[inline]
fn jmp_p(&mut self, addr: u16) {
self.ip = addr;
}
#[inline]
fn jmp_p_condition(&mut self, cond_str: String, cond: bool) -> u8 {
let t = to_u16(self.load_args(2));
if self.debug {
@ -550,6 +564,7 @@ impl CPU {
}
}
#[inline]
fn rst(&mut self, val: u8) -> u8 {
// Make sure this is correct.
if self.debug {
@ -559,6 +574,7 @@ impl CPU {
16
}
#[inline]
fn pop_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug {
println!("POP {}{}", REG_NAMES[r1], REG_NAMES[r2]);
@ -567,6 +583,8 @@ impl CPU {
self.set_pair_value(r1, r2, val);
12
}
#[inline]
fn push_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug {
println!("PUSH {}{}", REG_NAMES[r1], REG_NAMES[r2]);
@ -576,6 +594,7 @@ impl CPU {
16
}
#[inline]
fn dec_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug {
println!("DEC {}{}", REG_NAMES[r1], REG_NAMES[r2]);
@ -586,6 +605,7 @@ impl CPU {
8
}
#[inline]
fn inc_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug {
println!("INC {}{}", REG_NAMES[r1], REG_NAMES[r2]);
@ -596,17 +616,20 @@ impl CPU {
8
}
#[inline]
fn push(&mut self, val: u16) {
self.interconnect.write_word(self.sp - 1, val);
self.sp -= 2;
}
#[inline]
fn pop(&mut self) -> u16 {
let v: u16 = self.interconnect.read_word(self.sp + 1);
self.sp += 2;
v
}
#[inline]
fn ld_r_r(&mut self, reg_dst: usize, reg_src: usize) -> u8 {
if self.debug {
// 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 {
let val: u8 = self.load_args(1)[0];
if self.debug {
@ -633,6 +657,7 @@ impl CPU {
}
}
#[inline]
fn ld_rr_vv(&mut self, r1: usize, r2: usize) -> u8 {
let val: u16 = to_u16(self.load_args(2));
if self.debug {
@ -642,6 +667,7 @@ impl CPU {
12
}
#[inline]
fn reg_inc(&mut self, reg_id: usize) -> u8 {
if self.debug {
println!("INC {}", REG_NAMES[reg_id]);
@ -654,6 +680,7 @@ impl CPU {
4
}
#[inline]
fn add_rr_rr(&mut self, r1: usize, r2: usize, r3: usize, r4: usize) -> u8 {
let val1 = self.get_pair_value(r1, r2);
let val2 = self.get_pair_value(r3, r4);
@ -661,6 +688,7 @@ impl CPU {
8
}
#[inline]
fn reg_dec(&mut self, reg_id: usize) -> u8 {
if self.debug {
println!("DEC {}", REG_NAMES[reg_id]);
@ -674,6 +702,7 @@ impl CPU {
4
}
#[inline]
fn ld_dref_rr_a(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug {
println!("LD ({}{}), A", REG_NAMES[r1], REG_NAMES[r2]);
@ -684,14 +713,17 @@ impl CPU {
8
}
#[inline]
fn set_flag(&mut self, flag: u8) {
self.flags |= flag;
}
#[inline]
fn clear_flag(&mut self, flag: u8) {
self.flags &= !flag;
}
#[inline]
fn set_clear_flag(&mut self, flag: u8, dep: bool) {
if dep {
self.set_flag(flag);
@ -700,6 +732,7 @@ impl CPU {
}
}
#[inline]
fn int_(&mut self, val: u8){
if self.debug {
println!("INT {:02X}", val);
@ -709,18 +742,21 @@ impl CPU {
self.call(val as u16);
}
#[inline]
fn ret(&mut self) {
let new_ip: u16 = self.pop();
//self.dump_stack();
self.ip = new_ip;
}
#[inline]
fn reti(&mut self) -> u8 {
self.ret();
self.ime = true;
16
}
#[inline]
fn handle_interrupt(&mut self, offset: u8, flag: u8) {
// Remove interrupt requested 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) {
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));
}
#[inline]
pub fn vblank_interrupt(&mut self) -> bool {
// Returns whether or not a vblank interrupt should be done
// Yes, this is polling, and yes, this sucks.\
@ -128,6 +130,7 @@ impl Display {
}
}
#[inline]
pub fn stat_interrupt(&mut self) -> bool {
if self.stat_interrupt {
self.stat_interrupt = false;
@ -137,6 +140,7 @@ impl Display {
}
}
#[inline]
pub fn write_byte(&mut self, addr: u16, val: u8) {
match addr {
0x8000 ... 0x9FFF => {
@ -162,6 +166,7 @@ impl Display {
}
}
#[inline]
pub fn read_byte(&self, addr: u16) -> u8 {
match addr {
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) {
self.status &= 0xFC;
if self.control & CTRL_LCD_DISPLAY_ENABLE == 0 {
@ -270,6 +275,7 @@ impl Display {
}
}
#[inline]
fn renderscan(&mut self) {
// Points to the background map offset to use.
let background_map: usize;

View File

@ -167,10 +167,12 @@ impl Interconnect {
}
}
#[inline]
pub fn is_boot_rom(&self) -> bool {
self.disable_bootrom == 0
}
#[inline]
pub fn read_byte(&self, addr: u16) -> u8 {
// TODO: Make this more beautiful.
// 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) {
// TODO: Make this more beautful
/*
@ -336,11 +339,13 @@ impl Interconnect {
}
}
#[inline]
pub fn write_word(&mut self, addr: u16, val: u16) {
self.write_byte(addr, val as u8);
self.write_byte(addr + 1, (val >> 8) as u8);
}
#[inline]
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) << 8 | (self.read_byte(addr + 1) as u16)