From b13161f9c2a83c00673a8672f6202b0959658b1f Mon Sep 17 00:00:00 2001 From: iris Date: Mon, 18 May 2026 09:56:15 +0200 Subject: [PATCH] Branches simplified, and working! --- core/broadway.hpp | 3 + core/broadway/instructions.cpp | 133 ++++++--------------------------- 2 files changed, 25 insertions(+), 111 deletions(-) diff --git a/core/broadway.hpp b/core/broadway.hpp index be712a8..2df70b2 100644 --- a/core/broadway.hpp +++ b/core/broadway.hpp @@ -44,6 +44,9 @@ struct broadway { void decode_special1(ircolib::u32, mem &); void decode_special2(ircolib::u32, mem &); + void branch(bool, bool, ircolib::u32); + bool test_cond_and_ctr(ircolib::u32); + void andi(ircolib::u32); void add(ircolib::u32); void addis(ircolib::u32); diff --git a/core/broadway/instructions.cpp b/core/broadway/instructions.cpp index b3f2217..79f608c 100644 --- a/core/broadway/instructions.cpp +++ b/core/broadway/instructions.cpp @@ -28,86 +28,41 @@ void broadway::oris(ircolib::u32 instr) { gpr[utils::RA(instr)] = gpr[utils::RS(instr)] | ((ircolib::u32)utils::UIMM(instr) << 16); } +void broadway::branch(bool aa, bool lk, ircolib::u32 bd) { + if (!aa) + bd += pc - 4; + + if (lk) + lr = pc; + + pc = bd; +} + void broadway::bx(ircolib::u32 instr) { const bool link = instr & 1; const bool absolute = instr & 2; ircolib::s32 li = (ircolib::s32(instr << 6) >> 6) & 0xFFFFFFFC; - if (!absolute) - li += pc - 4; + branch(absolute, link, li); +} - if (link) - lr = pc; +bool broadway::test_cond_and_ctr(ircolib::u32 instr) { + const ircolib::u8 bo = (instr >> 21) & 0x1f; + const ircolib::u8 bi = (instr >> 16) & 0x1f; + const bool ctr_ok = ircolib::is_bit_set(bo, 2) || ((--ctr == 0) == (ircolib::is_bit_set(bo, 1))); + const bool cond_ok = ircolib::is_bit_set(bo, 4) || (ircolib::is_bit_set(cr, 32 - bi) == ircolib::is_bit_set(bo, 3)); - pc = li; + return cond_ok && ctr_ok; } void broadway::bcx(ircolib::u32 instr) { const bool link = instr & 1; const bool absolute = instr & 2; - const ircolib::u8 bi = (instr >> 16) & 0x1f; - const ircolib::u8 bo = (instr >> 11) & 0x1f; - if (ircolib::is_bit_set(bo, 2)) - ctr--; - - const bool ctr_ok = ircolib::is_bit_set(bo, 2) || ((ctr != 0) ^ (ircolib::is_bit_set(bo, 3))); - const bool cond_ok = ircolib::is_bit_set(bo, 0) || (ircolib::is_bit_set(cr, 32 - bi) == ircolib::is_bit_set(bo, 1)); ircolib::s32 bd = (ircolib::s32(instr << 16) >> 16) & 0xFFFFFFFC; - if (ctr_ok && cond_ok) { - if (!absolute) - bd += pc - 4; - - if (link) - lr = pc; - - pc = bd; + if (test_cond_and_ctr(instr)) { + branch(absolute, link, bd); } - - /* - if (!ircolib::is_bit_set(instr)) { - - if (!ircolib::is_bit_set(instr)) { - } - - if (!ircolib::is_bit_set(instr)) - ircolib::panic("broadway::bcx unimplemented variants with bit 23 == 0 (pc 0x{:08X})", pc - 4); - - - if () { - } - - return; - } - - if (ircolib::is_bit_set(instr)) { // always - if (link) - lr = pc; - - pc = bd; - return; - } - - if (ircolib::is_bit_set(instr)) { // --ctr == 0 - if (--ctr != 0) - return; - - if (link) - lr = pc; - - pc = bd; - return; - } - - // --ctr != 0 - if (--ctr == 0) - return; - - if (link) - lr = pc; - - pc = bd; - */ } void broadway::mftspr(bool dir, ircolib::u32 instr) { @@ -224,53 +179,9 @@ void broadway::bclrx(ircolib::u32 instr) { const bool link = instr & 1; ircolib::s32 bd = lr & 0xFFFFFFFC; - - if (!ircolib::is_bit_set(instr)) { - if (!ircolib::is_bit_set(instr)) - ircolib::panic("broadway::bclrx unimplemented variants with bit 24 == 0 (pc 0x{:08X})", pc - 4); - - if (!ircolib::is_bit_set(instr)) - ircolib::panic("broadway::bclrx unimplemented variants with bit 23 == 0 (pc 0x{:08X})", pc - 4); - - const ircolib::u8 bi = (instr >> 16) & 0x1f; - - if (ircolib::is_bit_set(cr, 32 - bi)) { - if (link) - lr = pc; - - pc = bd; - } - - return; + if (test_cond_and_ctr(instr)) { + branch(true, link, bd); } - - if (ircolib::is_bit_set(instr)) { // always - if (link) - lr = pc; - - pc = bd; - return; - } - - if (ircolib::is_bit_set(instr)) { // --ctr == 0 - if (--ctr != 0) - return; - - if (link) - lr = pc; - - pc = bd; - return; - } - - // --ctr != 0 - if (--ctr == 0) - return; - - if (link) - lr = pc; - - pc = bd; } void broadway::cmpi(ircolib::u32 instr) {