#include #include #include #include #include #include namespace weee::core { broadway::broadway() { if (cs_open(CS_ARCH_PPC, cs_mode(CS_MODE_BIG_ENDIAN | CS_MODE_32), &capstone) != CS_ERR_OK) { std::println("warning: could not initialize capstone. Disassembly is disabled"); disasm_available = false; } } void broadway::set_pc(ircolib::u32 value) { pc = value; } void broadway::run(mem &mem) { for (int i = 0; i < 100000; i++) { execute(fetch(mem), mem); } } ircolib::u32 broadway::fetch(mem &mem) { ircolib::u32 val = mem.read(pc); pc += 4; return val; } void broadway::execute(ircolib::u32 instr, mem &mem) { ircolib::u8 primary = (instr >> 26) & 0x3f; switch (primary) { case 15: // addis rd, ra, simm addis(instr); break; default: std::println("broadway::execute unimplemented instruction 0x{:08X} / 0b{:032b}", instr, instr); std::println("disassembly:"); print_disasm(instr); ircolib::panic(""); } } void broadway::print_disasm(ircolib::u32 instr) { if (!disasm_available) return; cs_insn *insn; auto instr_buff = ircolib::integral_to_slice(std::byteswap(instr)); size_t count = cs_disasm(capstone, instr_buff.data(), instr_buff.size(), pc - 4, 1, &insn); if (count <= 0) return; size_t j; for (j = 0; j < count; j++) { printf("0x%" PRIx64 ":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); } cs_free(insn, count); } } // namespace weee::core