Files
weee/core/broadway.hpp
T

114 lines
3.0 KiB
C++

#pragma once
#include <ircolib/types.hpp>
#include <capstone/capstone.h>
#include <xbyak/xbyak.h>
#include <array>
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;
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 std::size_t BAT_LOWER_OFFSET = 0;
static constexpr std::size_t BAT_UPPER_OFFSET = 8;
std::array<ircolib::u32, 16> ibat, dbat;
std::array<ircolib::u32, 32> gpr{};
struct Fgr {
ircolib::u64 ps0, ps1;
};
std::array<Fgr, 32> 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 add(ircolib::u32);
void addis(ircolib::u32);
void addi(ircolib::u32);
void ori(ircolib::u32);
void oris(ircolib::u32);
void bx(ircolib::u32);
void bcx(ircolib::u32);
void mftspr(bool, ircolib::u32);
void stw(ircolib::u32, mem &);
void stwu(ircolib::u32, mem &);
void stbu(ircolib::u32, mem &);
void sth(ircolib::u32, mem &);
void lwz(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 lwzu(ircolib::u32, mem &);
void rfi(ircolib::u32);
void mtfsf(ircolib::u32);
void mtfsb1(ircolib::u32);
void mtfsb0(ircolib::u32);
void mfmsr(ircolib::u32);
void nand(ircolib::u32);
void subf(ircolib::u32);
void or (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