#pragma once #include #include #include #include namespace weee::core { struct mem; struct broadway { broadway(); void set_pc(ircolib::u32); void run(mem &); private: ircolib::u32 fetch(mem &); void print_disasm(ircolib::u32); void execute(ircolib::u32, mem &); bool disasm_available = true; ircolib::u32 pc = 0, lr = 0, ctr = 0, cr = 0, srr0 = 0, fpscr = 0, msr = 0, tbl = 0, tbu = 0; union { struct { unsigned bytecount : 7; unsigned : 22; unsigned ca : 1; unsigned ov : 1; unsigned so : 1; }; ircolib::u32 raw; } xer; void set_cr(ircolib::u8 value, ircolib::u8 index) { cr &= ~(0xffff << index * 4); cr |= (value << index * 4); } bool get_cr_bit(ircolib::u8 index, ircolib::u8 bit) { return (cr >> index * 4) & (1 << (4 - bit)); } // bat registers indexes static constexpr ircolib::u32 BAT_LOWER_OFFSET = 0; static constexpr ircolib::u32 BAT_UPPER_OFFSET = 8; std::array ibat, dbat; std::array gpr{}; struct Fgr { ircolib::u64 ps0, ps1; }; std::array fgrs{}; // ircolib::u32 const_gpr_lookup{}; csh capstone; // Xbyak::CodeGenerator code; // instructions void decode_special1(ircolib::u32, mem &); void decode_special2(ircolib::u32, mem &); void decode_special3(ircolib::u32, mem &); void branch(bool, bool, ircolib::u32); bool test_cond_and_ctr(ircolib::u32); void andi(ircolib::u32); void andis(ircolib::u32); void and(ircolib::u32); void add(ircolib::u32); void addc(ircolib::u32); void adde(ircolib::u32); void addze(ircolib::u32); void addis(ircolib::u32); void addi(ircolib::u32); void addic(ircolib::u32); void addicr(ircolib::u32); void ori(ircolib::u32); void oris(ircolib::u32); void bx(ircolib::u32); void bcx(ircolib::u32); void mftspr(bool, ircolib::u32); void mtcrf(ircolib::u32); void stw(ircolib::u32, mem &); void stb(ircolib::u32, mem &); void stwu(ircolib::u32, mem &); void sthu(ircolib::u32, mem &); void stwx(ircolib::u32, mem &); void stbu(ircolib::u32, mem &); void sth(ircolib::u32, mem &); void lbz(ircolib::u32, mem &); void lwz(ircolib::u32, mem &); void lwzx(ircolib::u32, mem &); void lhz(ircolib::u32, mem &); void lhzx(ircolib::u32, mem &); void lfd(ircolib::u32, mem &); void bclrx(ircolib::u32); void cmpi(ircolib::u32); void cmpli(ircolib::u32); void cmp(ircolib::u32); void cmpl(ircolib::u32); void rlwinm(ircolib::u32); void rlwimi(ircolib::u32); void lwzu(ircolib::u32, mem &); void rfi(ircolib::u32); void mfcr(ircolib::u32); void mtfsf(ircolib::u32); void mtfsb1(ircolib::u32); void mtfsb0(ircolib::u32); void mfmsr(ircolib::u32); void mtmsr(ircolib::u32); void mullw(ircolib::u32); void mulli(ircolib::u32); void nand(ircolib::u32); void subf(ircolib::u32); void subfc(ircolib::u32); void subfic(ircolib::u32); void subfe(ircolib::u32); void or (ircolib::u32); void xori(ircolib::u32); void divwu(ircolib::u32); void mftb(ircolib::u32); void sraw(ircolib::u32); inline void cr0_update(bool condition, ircolib::s32 result) { if (condition) { const bool b0 = result < 0; const bool b1 = result >= 0; const bool b2 = result == 0; const bool b3 = xer.so; set_cr((b0 << 3) | (b1 << 2) | (b2 << 1) | (b3 << 0), 0); } } inline void cr1_update(bool condition) { if (condition) { const ircolib::u8 field = (fpscr >> 28) & 0xf; set_cr(field, 1); } } }; } // namespace weee::core