getting floating point stuff now

This commit is contained in:
2026-05-18 12:06:03 +02:00
parent b13161f9c2
commit aeb5094b05
8 changed files with 77 additions and 36 deletions
+15 -12
View File
@@ -31,7 +31,7 @@ ircolib::u32 broadway::fetch(mem &mem) {
void broadway::decode_special2(ircolib::u32 instr, mem &mem) {
auto secondary = utils::secondary(instr);
switch (secondary) {
case 0x0D2: // mtsr
case 0x0D2:
ircolib::warn("broadway TODO mtsr (pc 0x{:08X})", pc - 4);
break;
case 0x153:
@@ -66,19 +66,19 @@ void broadway::decode_special1(ircolib::u32 instr, mem &mem) {
void broadway::execute(ircolib::u32 instr, mem &mem) {
switch (utils::primary(instr)) {
case 11: // cmpi crfD, L, rA, simm
case 11:
cmpi(instr);
break;
case 14: // addi rd, ra, simm
case 14:
addi(instr);
break;
case 15: // addis rd, ra, simm
case 15:
addis(instr);
break;
case 16: // bcx BO, BI, target
case 16:
bcx(instr);
break;
case 18: // bx target
case 18:
bx(instr);
break;
case 19:
@@ -87,7 +87,7 @@ void broadway::execute(ircolib::u32 instr, mem &mem) {
case 21:
rlwinm(instr);
break;
case 24: // ori ra, rs, uimm
case 24:
ori(instr);
break;
case 25:
@@ -99,21 +99,24 @@ void broadway::execute(ircolib::u32 instr, mem &mem) {
case 31:
decode_special2(instr, mem);
break;
case 32: // lwz rd, d(ra)
case 32:
lwz(instr, mem);
break;
case 33: // lwz rd, d(ra)
case 33:
lwzu(instr, mem);
break;
case 36: // stw rs, d(ra)
case 36:
stw(instr, mem);
break;
case 37: // stwu rs, d(ra)
case 37:
stwu(instr, mem);
break;
case 44: // stwu rs, d(ra)
case 44:
sth(instr, mem);
break;
case 50:
lfd(instr, mem);
break;
default:
std::println("broadway::execute unimplemented instruction 0x{:08X} / 0b{:032b}", instr, instr);
std::println("disassembly:");
+19
View File
@@ -30,12 +30,20 @@ struct broadway {
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{};
std::array<double, 32> fpr{};
// ircolib::u32 const_gpr_lookup{};
csh capstone;
// Xbyak::CodeGenerator code;
@@ -60,10 +68,21 @@ struct broadway {
void stwu(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 rlwinm(ircolib::u32);
void lwzu(ircolib::u32, mem &);
void rfi(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);
}
}
};
} // namespace weee::core
+18 -5
View File
@@ -50,7 +50,7 @@ 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));
const bool cond_ok = ircolib::is_bit_set(bo, 4) || (get_cr_bit(0, bi) == ircolib::is_bit_set(bo, 3));
return cond_ok && ctr_ok;
}
@@ -175,6 +175,18 @@ void broadway::lwz(ircolib::u32 instr, mem &mem) {
gpr[utils::RD(instr)] = mem.read32(ea);
}
void broadway::lfd(ircolib::u32 instr, mem &mem) {
ircolib::u32 b = gpr[utils::RA(instr)];
if (utils::RA(instr) == 0)
b = 0;
ircolib::u32 ea = ircolib::s32(b) + utils::SIMM(instr);
double val;
ircolib::u64 read = mem.read64(ea);
memcpy(&val, &read, 8);
fpr[utils::RD(instr)] = val;
}
void broadway::bclrx(ircolib::u32 instr) {
const bool link = instr & 1;
@@ -195,9 +207,8 @@ void broadway::cmpi(ircolib::u32 instr) {
else
c = 0b100;
const ircolib::u32 result = ((xer.so << 3) | c) << (28 - 4 * utils::crfD(instr));
cr &= ~(0xffff << (28 - 4 * utils::crfD(instr)));
cr |= result;
const ircolib::u8 result = (xer.so << 3) | c;
set_cr(result, utils::crfD(instr));
}
void broadway::rlwinm(ircolib::u32 instr) {
@@ -222,6 +233,8 @@ void broadway::lwzu(ircolib::u32 instr, mem &mem) {
void broadway::rfi(ircolib::u32 instr) { pc = srr0; }
void broadway::andi(ircolib::u32 instr) {
gpr[utils::RA(instr)] = gpr[utils::RS(instr)] & (ircolib::u32(utils::UIMM(instr)) << 16);
const ircolib::s32 result = gpr[utils::RS(instr)] & utils::UIMM(instr);
gpr[utils::RA(instr)] = result;
cr0_update(true, result);
}
} // namespace weee::core
+2 -2
View File
@@ -55,10 +55,10 @@ void video_interface::write32(ircolib::u32 addr, ircolib::u32 value) {
bboi.raw = value;
break;
case 0x1c:
tfbl.raw = value;
tfbl.raw = value & 0x1ffffe00;
break;
case 0x24:
bfbl.raw = value;
bfbl.raw = value & 0x10fffe00;
break;
case 0x4c:
case 0x50:
+13 -16
View File
@@ -8,6 +8,14 @@ struct video_interface {
video_interface(mem &);
void write16(ircolib::u32, ircolib::u16);
void write32(ircolib::u32, ircolib::u32);
ircolib::u32 xfb_top_addr() {
auto addr = tfbl.fbb;
if (tfbl.page) {
addr <<= 5;
}
return addr + tfbl.xof;
}
union DCR {
struct {
@@ -80,26 +88,15 @@ struct video_interface {
ircolib::u32 raw;
} bbei, bboi;
union TFBL {
union FBR {
struct {
unsigned : 9;
unsigned fbb : 15;
unsigned : 3;
unsigned page : 1;
unsigned xof : 4;
unsigned : 4;
unsigned fbb : 24;
};
ircolib::u32 raw;
} tfbl;
union BFBL {
struct {
unsigned : 9;
unsigned fbb : 15;
unsigned y : 8;
};
ircolib::u32 raw;
} bfbl;
} tfbl, bfbl;
union FCT012 {
struct {
+7
View File
@@ -13,6 +13,9 @@ mem::mem() : vi(*this) {
register_read32_handler(0x00000000, 0x017fffff,
[&](ircolib::u32 addr) { return ircolib::read_access<ircolib::u32>(mem1, addr); });
register_read64_handler(0x00000000, 0x017fffff,
[&](ircolib::u32 addr) { return ircolib::read_access<ircolib::u64>(mem1, addr); });
register_write16_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u16 value) {
ircolib::write_access<ircolib::u16>(mem1, addr, value);
});
@@ -20,6 +23,10 @@ mem::mem() : vi(*this) {
register_write32_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u32 value) {
ircolib::write_access<ircolib::u32>(mem1, addr, value);
});
register_write64_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u32 value) {
ircolib::write_access<ircolib::u64>(mem1, addr, value);
});
}
void mem::copy(std::vector<ircolib::u8> &src, const ircolib::u32 offset) {
+1
View File
@@ -78,6 +78,7 @@ struct mem {
std::vector<write_handler<ircolib::u32>> write32_handlers{};
std::vector<write_handler<ircolib::u64>> write64_handlers{};
public:
video_interface vi;
};
} // namespace weee::core