diff --git a/src/crab/common/util.cr b/src/crab/common/util.cr index 4602951..b3e53d9 100644 --- a/src/crab/common/util.cr +++ b/src/crab/common/util.cr @@ -81,3 +81,15 @@ macro log(value, newline = true) {% end %} {% end %} end + +lib LibIntrinsics + fun expect_i1 = "llvm.expect.i1"(value : Bool, expected_value : Bool) : Bool +end + +def likely(value : Bool) + LibIntrinsics.expect_i1(value, true) +end + +def unlikely(value : Bool) + LibIntrinsics.expect_i1(value, false) +end diff --git a/src/crab/gba/bus.cr b/src/crab/gba/bus.cr index 0e8a207..57a20d6 100644 --- a/src/crab/gba/bus.cr +++ b/src/crab/gba/bus.cr @@ -161,8 +161,8 @@ module GBA @[AlwaysInline] private def write_byte_internal(index : Int, value : Byte) : Nil - return if bits(index, 28..31) > 0 - @gba.cpu.fill_pipeline if index <= @gba.cpu.r[15] && index >= @gba.cpu.r[15] &- 4 # detect writes near pc + return if unlikely(bits(index, 28..31) > 0) + @gba.cpu.fill_pipeline if unlikely(index <= @gba.cpu.r[15] && index >= @gba.cpu.r[15] &- 4) # detect writes near pc case bits(index, 24..27) when 0x2 then @wram_board[index & 0x3FFFF] = value when 0x3 then @wram_chip[index & 0x7FFF] = value @@ -181,9 +181,9 @@ module GBA @[AlwaysInline] private def write_half_internal(index : Int, value : HalfWord) : Nil - return if bits(index, 28..31) > 0 + return if unlikely(bits(index, 28..31) > 0) index &= ~1 - @gba.cpu.fill_pipeline if index <= @gba.cpu.r[15] && index >= @gba.cpu.r[15] &- 4 # detect writes near pc + @gba.cpu.fill_pipeline if unlikely(index <= @gba.cpu.r[15] && index >= @gba.cpu.r[15] &- 4) # detect writes near pc case bits(index, 24..27) when 0x2 then (@wram_board.to_unsafe + (index & 0x3FFFF)).as(HalfWord*).value = value when 0x3 then (@wram_chip.to_unsafe + (index & 0x7FFF)).as(HalfWord*).value = value @@ -202,9 +202,9 @@ module GBA @[AlwaysInline] private def write_word_internal(index : Int, value : Word) : Nil - return if bits(index, 28..31) > 0 + return if unlikely(bits(index, 28..31) > 0) index &= ~3 - @gba.cpu.fill_pipeline if index <= @gba.cpu.r[15] && index >= @gba.cpu.r[15] &- 4 # detect writes near pc + @gba.cpu.fill_pipeline if unlikely(index <= @gba.cpu.r[15] && index >= @gba.cpu.r[15] &- 4) # detect writes near pc case bits(index, 24..27) when 0x2 then (@wram_board.to_unsafe + (index & 0x3FFFF)).as(Word*).value = value when 0x3 then (@wram_chip.to_unsafe + (index & 0x7FFF)).as(Word*).value = value diff --git a/src/crab/gba/cpu.cr b/src/crab/gba/cpu.cr index 90ff63e..41880af 100644 --- a/src/crab/gba/cpu.cr +++ b/src/crab/gba/cpu.cr @@ -119,7 +119,7 @@ module GBA end def read_instr : Word - if @pipeline.size == 0 + if likely(@pipeline.size == 0) if @cpsr.thumb @r[15] &= ~1 @gba.bus.read_half(@r[15] &- 4).to_u32! @@ -133,7 +133,7 @@ module GBA end def tick : Nil - unless @halted + unless unlikely(@halted) instr = read_instr {% if flag? :trace %} print_state instr {% end %} if @cpsr.thumb @@ -150,6 +150,7 @@ module GBA def check_cond(cond : Word) : Bool case cond + when 0xE then true when 0x0 then @cpsr.zero when 0x1 then !@cpsr.zero when 0x2 then @cpsr.carry @@ -164,7 +165,6 @@ module GBA when 0xB then @cpsr.negative != @cpsr.overflow when 0xC then !@cpsr.zero && @cpsr.negative == @cpsr.overflow when 0xD then @cpsr.zero || @cpsr.negative != @cpsr.overflow - when 0xE then true else raise "Cond 0xF is reserved" end end @@ -180,7 +180,7 @@ module GBA @[AlwaysInline] def set_reg(reg : Int, value : Int) : UInt32 @r[reg] = value.to_u32! - clear_pipeline if reg == 15 + clear_pipeline if unlikely(reg == 15) value.to_u32! end