Skip to content

Commit

Permalink
Adding aliases to MIPS inline encoder.
Browse files Browse the repository at this point in the history
Also adding a couple of aliases to the disassembler.
  • Loading branch information
nicolasnoble committed Jan 19, 2025
1 parent 06fdac5 commit ee5c53b
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 50 deletions.
26 changes: 22 additions & 4 deletions src/core/disr3000a.cc
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,14 @@ declare(disBEQ) {
if (_Rs_ == _Rt_) {
dOpCode("b");
dBranch();
} else if (_Rs_ == 0) {
dOpCode("beqz");
GPR(_Rt_);
dBranch();
} else if (_Rt_ == 0) {
dOpCode("beqz");
GPR(_Rs_);
dBranch();
} else {
dOpCode("beq");
GPR(_Rs_);
Expand All @@ -791,10 +799,20 @@ declare(disBEQ) {
}
declare(disBNE) {
if (delaySlotNext) *delaySlotNext = true;
dOpCode("bne");
GPR(_Rs_);
GPR(_Rt_);
dBranch();
if (_Rs_ == 0) {
dOpCode("bnez");
GPR(_Rt_);
dBranch();
} else if (_Rt_ == 0) {
dOpCode("bnez");
GPR(_Rs_);
dBranch();
} else {
dOpCode("bne");
GPR(_Rs_);
GPR(_Rt_);
dBranch();
}
}

/*********************************************************
Expand Down
34 changes: 34 additions & 0 deletions src/mips/common/util/encoder.hh
Original file line number Diff line number Diff line change
Expand Up @@ -47,51 +47,74 @@ constexpr uint32_t srcVal(Reg r) { return uint32_t(r) << 21; }

// ALU
constexpr uint32_t add(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100000; }
constexpr uint32_t add(Reg dst, Reg tgt) { return add(dst, dst, tgt); }
constexpr uint32_t addu(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100001; }
constexpr uint32_t addu(Reg dst, Reg tgt) { return addu(dst, dst, tgt); }
constexpr uint32_t addi(Reg tgt, Reg src, int16_t value) {
uint32_t v = value;
v &= 0xffff;
return iclass(0b001000) | srcVal(src) | tgtVal(tgt) | v;
}
constexpr uint32_t addi(Reg tgt, int16_t value) { return addi(tgt, tgt, value); }
constexpr uint32_t addiu(Reg tgt, Reg src, int16_t value) {
uint32_t v = value;
v &= 0xffff;
return iclass(0b001001) | srcVal(src) | tgtVal(tgt) | v;
}
constexpr uint32_t addiu(Reg tgt, int16_t value) { return addiu(tgt, tgt, value); }
constexpr uint32_t andd(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100100; }
constexpr uint32_t andd(Reg dst, Reg tgt) { return andd(dst, dst, tgt); }
constexpr uint32_t andi(Reg tgt, Reg src, uint16_t value) {
return iclass(0b001100) | srcVal(src) | tgtVal(tgt) | value;
}
constexpr uint32_t andi(Reg tgt, uint16_t value) { return andi(tgt, tgt, value); }
constexpr uint32_t lui(Reg tgt, uint16_t value) { return iclass(0b001111) | tgtVal(tgt) | value; }
constexpr uint32_t nor(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100111; }
constexpr uint32_t nor(Reg dst, Reg tgt) { return nor(dst, dst, tgt); }
constexpr uint32_t orr(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100101; }
constexpr uint32_t orr(Reg dst, Reg tgt) { return orr(dst, dst, tgt); }
constexpr uint32_t ori(Reg tgt, Reg src, uint16_t value) {
return iclass(0b001101) | srcVal(src) | tgtVal(tgt) | value;
}
constexpr uint32_t ori(Reg tgt, uint16_t value) { return ori(tgt, tgt, value); }
constexpr uint32_t slt(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b101010; }
constexpr uint32_t slt(Reg dst, Reg tgt) { return slt(dst, dst, tgt); }
constexpr uint32_t sltu(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b101011; }
constexpr uint32_t sltu(Reg dst, Reg tgt) { return sltu(dst, dst, tgt); }
constexpr uint32_t slti(Reg tgt, Reg src, int16_t value) {
uint32_t v = value;
v &= 0xffff;
return iclass(0b001010) | srcVal(src) | tgtVal(tgt) | v;
}
constexpr uint32_t slti(Reg tgt, int16_t value) { return slti(tgt, tgt, value); }
constexpr uint32_t sltiu(Reg tgt, Reg src, uint16_t value) {
return iclass(0b001011) | srcVal(src) | tgtVal(tgt) | value;
}
constexpr uint32_t sltiu(Reg tgt, uint16_t value) { return sltiu(tgt, tgt, value); }
constexpr uint32_t sub(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100010; }
constexpr uint32_t sub(Reg dst, Reg tgt) { return sub(dst, dst, tgt); }
constexpr uint32_t subu(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100011; }
constexpr uint32_t subu(Reg dst, Reg tgt) { return subu(dst, dst, tgt); }
constexpr uint32_t xorr(Reg dst, Reg src, Reg tgt) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b100110; }
constexpr uint32_t xorr(Reg dst, Reg tgt) { return xorr(dst, dst, tgt); }
constexpr uint32_t xori(Reg tgt, Reg src, uint16_t value) {
return iclass(0b001110) | srcVal(src) | tgtVal(tgt) | value;
}
constexpr uint32_t xori(Reg tgt, uint16_t value) { return xori(tgt, tgt, value); }

// shifts
constexpr uint32_t sll(Reg dst, Reg tgt, uint16_t sa) { return dstVal(dst) | tgtVal(tgt) | (sa << 6) | 0b000000; }
constexpr uint32_t sll(Reg dst, uint16_t sa) { return sll(dst, dst, sa); }
constexpr uint32_t sllv(Reg dst, Reg tgt, Reg src) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b000100; }
constexpr uint32_t sllv(Reg dst, Reg src) { return sllv(dst, dst, src); }
constexpr uint32_t sra(Reg dst, Reg tgt, uint16_t sa) { return dstVal(dst) | tgtVal(tgt) | (sa << 6) | 0b000011; }
constexpr uint32_t sra(Reg dst, uint16_t sa) { return sra(dst, dst, sa); }
constexpr uint32_t srav(Reg dst, Reg tgt, Reg src) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b000111; }
constexpr uint32_t srav(Reg dst, Reg src) { return srav(dst, dst, src); }
constexpr uint32_t srl(Reg dst, Reg tgt, uint16_t sa) { return dstVal(dst) | tgtVal(tgt) | (sa << 6) | 0b000010; }
constexpr uint32_t srl(Reg dst, uint16_t sa) { return srl(dst, dst, sa); }
constexpr uint32_t srlv(Reg dst, Reg tgt, Reg src) { return dstVal(dst) | tgtVal(tgt) | srcVal(src) | 0b000110; }
constexpr uint32_t srlv(Reg dst, Reg src) { return srlv(dst, dst, src); }

// mults
constexpr uint32_t div(Reg src, Reg tgt) { return tgtVal(tgt) | srcVal(src) | 0b011010; }
Expand Down Expand Up @@ -220,6 +243,17 @@ constexpr uint32_t rfe() { return 0x42000010; }

// pseudo
constexpr uint32_t nop() { return 0; }
constexpr uint32_t li(Reg tgt, int16_t value) { return addiu(tgt, Reg::R0, value); }
constexpr uint32_t liu(Reg tgt, uint16_t value) { return ori(tgt, Reg::R0, value); }
constexpr uint32_t move(Reg tgt, Reg src) { return addu(tgt, Reg::R0, src); }
constexpr uint32_t nott(Reg tgt, Reg src) { return nor(tgt, src, Reg::R0); }
constexpr uint32_t nott(Reg tgt) { return nott(tgt, tgt); }
constexpr uint32_t neg(Reg tgt, Reg src) { return subu(tgt, Reg::R0, src); }
constexpr uint32_t neg(Reg tgt) { return neg(tgt, tgt); }
constexpr uint32_t b(int16_t offset) { return bgez(Reg::R0, offset); }
constexpr uint32_t beqz(Reg tgt, int16_t offset) { return beq(tgt, Reg::R0, offset); }
constexpr uint32_t bnez(Reg tgt, int16_t offset) { return bne(tgt, Reg::R0, offset); }
constexpr uint32_t bal(int16_t offset) { return bgezal(Reg::R0, offset); }

} // namespace Encoder
} // namespace Mips
4 changes: 2 additions & 2 deletions src/mips/psyqo/src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,13 @@ void psyqo::Kernel::takeOverKernel() {
uint16_t lo = printfAddr & 0xffff;
if (lo >= 0x8000) hi++;
// a0
handlers[0] = Mips::Encoder::addiu(Mips::Encoder::Reg::T0, Mips::Encoder::Reg::R0, 0x3f);
handlers[0] = Mips::Encoder::li(Mips::Encoder::Reg::T0, 0x3f);
handlers[1] = Mips::Encoder::beq(Mips::Encoder::Reg::T1, Mips::Encoder::Reg::T0, 12);
handlers[2] = Mips::Encoder::lui(Mips::Encoder::Reg::T0, hi);
handlers[3] = Mips::Encoder::nop();
// b0
handlers[4] = Mips::Encoder::jr(Mips::Encoder::Reg::RA);
handlers[5] = Mips::Encoder::addiu(Mips::Encoder::Reg::T0, Mips::Encoder::Reg::T0, lo);
handlers[5] = Mips::Encoder::li(Mips::Encoder::Reg::T0, lo);
handlers[6] = Mips::Encoder::jr(Mips::Encoder::Reg::T0);
handlers[7] = Mips::Encoder::nop();
// c0
Expand Down
4 changes: 2 additions & 2 deletions src/mips/tests/cop0/exceptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ struct Handler {
uint16_t high = value >> 16;
int16_t low = value & 0xffff;
dst[0] = lui(Reg::K0, high);
dst[1] = ori(Reg::K0, Reg::K0, low);
dst[1] = ori(Reg::K0, low);
dst[2] = jr(Reg::K0);
dst[3] = ori(Reg::K1, Reg::R0, addr);
dst[3] = li(Reg::K1, addr);
}

void restore() {
Expand Down
84 changes: 42 additions & 42 deletions src/supportpsx/ps1-packer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,14 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
pushBytes(stub, addiu(Reg::T8, Reg::RA, 0));
}
pushBytes(stub, lui(Reg::T1, getHI(offset)));
pushBytes(stub, bgezal(Reg::R0, 4));
pushBytes(stub, addiu(Reg::T1, Reg::T1, getLO(offset)));
pushBytes(stub, bal(4));
pushBytes(stub, addiu(Reg::T1, getLO(offset)));
pushBytes(stub, lui(Reg::T0, 0x1fff));
pushBytes(stub, ori(Reg::T0, Reg::T0, 0xffff));
pushBytes(stub, andd(Reg::RA, Reg::RA, Reg::T0));
pushBytes(stub, ori(Reg::T0, 0xffff));
pushBytes(stub, andd(Reg::RA, Reg::T0));
pushBytes(stub, lui(Reg::T0, 0x8000));
pushBytes(stub, orr(Reg::RA, Reg::RA, Reg::T0));
pushBytes(stub, addu(Reg::T0, Reg::RA, Reg::T1));
pushBytes(stub, orr(Reg::RA, Reg::T0));
pushBytes(stub, addu(Reg::T0, Reg::T1));
pushBytes(stub, jr(Reg::T0));
pushBytes(stub, addiu(Reg::A0, Reg::RA, 32));

Expand Down Expand Up @@ -196,11 +196,11 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
// Calls the ucl-nrv2e decompressor.
if (!options.raw) {
pushBytes(dataOut, lui(Reg::A0, getHI(compLoad)));
pushBytes(dataOut, addiu(Reg::A0, Reg::A0, getLO(compLoad)));
pushBytes(dataOut, addiu(Reg::A0, getLO(compLoad)));
}
pushBytes(dataOut, lui(Reg::A1, getHI(addr)));
pushBytes(dataOut, bgezal(Reg::R0, -((int16_t)(dataOut.size() + 4 - n2estart))));
pushBytes(dataOut, addiu(Reg::A1, Reg::A1, getLO(addr)));
pushBytes(dataOut, bal(-((int16_t)(dataOut.size() + 4 - n2estart))));
pushBytes(dataOut, addiu(Reg::A1, getLO(addr)));

// Then, bootstrap our newly-decompressed binary.
if (options.shell) {
Expand All @@ -218,16 +218,16 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
// binary in memory.
pushBytes(shellCode, nop());
pushBytes(shellCode, lui(Reg::T0, getHI(pc)));
pushBytes(shellCode, addiu(Reg::T0, Reg::T0, getLO(pc)));
pushBytes(shellCode, addiu(Reg::T0, getLO(pc)));
pushBytes(shellCode, lui(Reg::GP, getHI(gp)));
pushBytes(shellCode, jr(Reg::T0));
pushBytes(shellCode, addiu(Reg::GP, Reg::GP, getLO(gp)));
pushBytes(shellCode, addiu(Reg::GP, getLO(gp)));

// Jumps over the two blocks of code above, grabbing their address
// in $ra using bal.
pushBytes(dataOut, bgezal(Reg::R0, breakHandler.size() + shellCode.size()));
pushBytes(dataOut, bal(breakHandler.size() + shellCode.size()));
// $s0 = 0xa0
pushBytes(dataOut, addiu(Reg::S0, Reg::R0, 0xa0));
pushBytes(dataOut, li(Reg::S0, 0xa0));

// Insert the two pieces of code we need to copy.
pushBytes(dataOut, breakHandler);
Expand All @@ -237,30 +237,30 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
// $s1 = address of the break handler.
pushBytes(dataOut, addiu(Reg::S1, Reg::RA, 0));

pushBytes(dataOut, addiu(Reg::A0, Reg::R0, 0x40));
pushBytes(dataOut, li(Reg::A0, 0x40));
pushBytes(dataOut, addiu(Reg::A1, Reg::S1, 0));
pushBytes(dataOut, addiu(Reg::A2, Reg::R0, breakHandler.size()));
pushBytes(dataOut, li(Reg::A2, breakHandler.size()));
// Call A0:2A - memcpy.
pushBytes(dataOut, jalr(Reg::S0));
pushBytes(dataOut, addiu(Reg::T1, Reg::R0, 0x2a));
pushBytes(dataOut, li(Reg::T1, 0x2a));

pushBytes(dataOut, lui(Reg::A0, 0x8003));
pushBytes(dataOut, addiu(Reg::A1, Reg::S1, breakHandler.size()));
pushBytes(dataOut, addiu(Reg::A2, Reg::R0, shellCode.size()));
pushBytes(dataOut, li(Reg::A2, shellCode.size()));
// Call A0:2A - memcpy.
pushBytes(dataOut, jalr(Reg::S0));
pushBytes(dataOut, addiu(Reg::T1, Reg::R0, 0x2a));
pushBytes(dataOut, li(Reg::T1, 0x2a));

// And reboot, leaving cop0's registers set to break
// on writes to 0x80030000.
constexpr uint32_t partialReboot = 0xbfc00390;

pushBytes(dataOut, lui(Reg::RA, getHI(partialReboot)));
pushBytes(dataOut, addiu(Reg::RA, Reg::RA, getLO(partialReboot)));
pushBytes(dataOut, addiu(Reg::RA, getLO(partialReboot)));

pushBytes(dataOut, lui(Reg::T0, 0b1100101010000000));
pushBytes(dataOut, lui(Reg::T1, 0x8003));
pushBytes(dataOut, addiu(Reg::T2, Reg::R0, -1));
pushBytes(dataOut, li(Reg::T2, -1));
pushBytes(dataOut, mtc0(Reg::R0, 7));
pushBytes(dataOut, mtc0(Reg::T1, 5));
pushBytes(dataOut, mtc0(Reg::T2, 9));
Expand All @@ -271,35 +271,35 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
// skipping over SBUS settings, and the resetting
// of all the cop0 registers.
pushBytes(dataOut, jr(Reg::S0));
pushBytes(dataOut, addiu(Reg::T1, Reg::R0, 0x44));
pushBytes(dataOut, li(Reg::T1, 0x44));
} else if (options.nokernel) {
// We can't call into the kernel, so we need to
// flush the cache ourselves first.
pushBytes(dataOut, bgezal(Reg::R0, 4));
pushBytes(dataOut, bal(4));
pushBytes(dataOut, lui(Reg::T1, 0xa000));
pushBytes(dataOut, orr(Reg::T1, Reg::RA, Reg::T1));
pushBytes(dataOut, addiu(Reg::T1, Reg::T1, 16));
pushBytes(dataOut, addiu(Reg::T1, 16));
pushBytes(dataOut, jr(Reg::T1));
pushBytes(dataOut, mtc0(Reg::R0, 12));
pushBytes(dataOut, lui(Reg::T5, 0xfffe));
pushBytes(dataOut, lui(Reg::T2, 0x0001));
pushBytes(dataOut, ori(Reg::T2, Reg::T2, 0xe90c));
pushBytes(dataOut, ori(Reg::T2, 0xe90c));
pushBytes(dataOut, sw(Reg::T2, 0x0130, Reg::T5));
pushBytes(dataOut, lui(Reg::T1, 1));
pushBytes(dataOut, mtc0(Reg::T1, 12));
pushBytes(dataOut, addu(Reg::T3, Reg::R0, Reg::R0));
pushBytes(dataOut, addiu(Reg::T4, Reg::R0, 0x0ff0));
pushBytes(dataOut, move(Reg::T3, Reg::R0));
pushBytes(dataOut, li(Reg::T4, 0x0ff0));
pushBytes(dataOut, sw(Reg::R0, 0, Reg::T3));
pushBytes(dataOut, bne(Reg::T3, Reg::T4, -8));
pushBytes(dataOut, addiu(Reg::T3, Reg::T3, 0x10));
pushBytes(dataOut, addiu(Reg::T3, 0x10));
pushBytes(dataOut, mtc0(Reg::R0, 12));
pushBytes(dataOut, addiu(Reg::T2, Reg::T2, 0x7c));
pushBytes(dataOut, addiu(Reg::T2, 0x7c));
pushBytes(dataOut, sw(Reg::T2, 0x0130, Reg::T5));
// Then jumps into the decompressed binary, restoring
// $ra if needed, so the decompressed binary can return
// to the caller gracefully.
pushBytes(dataOut, lui(Reg::T0, getHI(pc)));
pushBytes(dataOut, addiu(Reg::T0, Reg::T0, getLO(pc)));
pushBytes(dataOut, addiu(Reg::T0, getLO(pc)));
pushBytes(dataOut, jr(Reg::T0));
if (options.resetstack) {
pushBytes(dataOut, ori(Reg::SP, Reg::SP, 0xfff0));
Expand All @@ -308,17 +308,17 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
}
} else {
// Calls A0:44 - FlushCache
pushBytes(dataOut, addiu(Reg::T0, Reg::R0, 0xa0));
pushBytes(dataOut, li(Reg::T0, 0xa0));
pushBytes(dataOut, jalr(Reg::T0));
pushBytes(dataOut, addiu(Reg::T1, Reg::R0, 0x44));
pushBytes(dataOut, li(Reg::T1, 0x44));
// Then jumps into the decompressed binary, restoring
// $ra if needed, so the decompressed binary can return
// to the caller gracefully.
pushBytes(dataOut, lui(Reg::T0, getHI(pc)));
pushBytes(dataOut, addiu(Reg::T0, Reg::T0, getLO(pc)));
pushBytes(dataOut, addiu(Reg::T0, getLO(pc)));
pushBytes(dataOut, jr(Reg::T0));
if (options.resetstack) {
pushBytes(dataOut, ori(Reg::SP, Reg::SP, 0xfff0));
pushBytes(dataOut, ori(Reg::SP, 0xfff0));
} else {
pushBytes(dataOut, addiu(Reg::RA, Reg::T8, 0));
}
Expand Down Expand Up @@ -351,21 +351,21 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
// in RAM. Once it's done, it'll jump to the start of
// the compressed binary through FlushCache.
/* 0x24 */ stage2.push_back(lw(Reg::A3, 0, Reg::A1));
/* 0x28 */ stage2.push_back(addiu(Reg::A2, Reg::A2, -1));
/* 0x28 */ stage2.push_back(addiu(Reg::A2, -1));
/* 0x2c */ stage2.push_back(sw(Reg::A3, 0, Reg::A0));
/* 0x30 */ stage2.push_back(bne(Reg::A2, Reg::R0, -16));
/* 0x34 */ stage2.push_back(addiu(Reg::A0, Reg::A0, 4));
/* 0x30 */ stage2.push_back(bnez(Reg::A2, -16));
/* 0x34 */ stage2.push_back(addiu(Reg::A0, 4));
/* 0x38 */ stage2.push_back(j(0xa0));
/* 0x3c */ stage2.push_back(addiu(Reg::T1, Reg::R0, 0x44));
/* 0x3c */ stage2.push_back(li(Reg::T1, 0x44));
// This is actually the entry point.
/* 0x40 */ stage2.push_back(mtc0(Reg::R0, 7));
/* 0x44 */ stage2.push_back(lui(Reg::A0, compLoad >> 16));
if ((compLoad & 0xffff) != 0) {
/* 0x48 */ stage2.push_back(ori(Reg::A0, Reg::A0, compLoad));
/* 0x48 */ stage2.push_back(ori(Reg::A0, compLoad));
}
/* 0x4c */ stage2.push_back(lui(Reg::RA, newPC >> 16));
if ((newPC & 0xffff) != 0) {
/* 0x50 */ stage2.push_back(ori(Reg::RA, Reg::RA, newPC));
/* 0x50 */ stage2.push_back(ori(Reg::RA, newPC & 0xffff));
}
/* 0x54 */ stage2.push_back(lui(Reg::A1, 0xbf00));
/* 0x58 */ stage2.push_back(j(0x24));
Expand All @@ -376,7 +376,7 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
// need roughly 3 or 4 instructions.
stage2.push_back(lui(Reg::V0, newPC >> 16));
if ((newPC & 0xffff) != 0) {
stage2.push_back(ori(Reg::V0, Reg::V0, newPC & 0xffff));
stage2.push_back(ori(Reg::V0, newPC & 0xffff));
}
stage2.push_back(jr(Reg::V0));
stage2.push_back(mtc0(Reg::R0, 7));
Expand Down Expand Up @@ -408,7 +408,7 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
// Break on writes and/or exec, to call our break handler which we
// will place in memory next.
pushBytes(header, mtc0(Reg::R0, 7));
pushBytes(header, addiu(Reg::T2, Reg::R0, -1));
pushBytes(header, li(Reg::T2, -1));
pushBytes(header, lui(Reg::T1, 0x8003));
pushBytes(header, lui(Reg::T0, 0b1100101010000000));
pushBytes(header, mtc0(Reg::T2, 11));
Expand All @@ -430,7 +430,7 @@ void PCSX::PS1Packer::pack(IO<File> src, IO<File> dest, uint32_t addr, uint32_t
pushBytes(header, lui(Reg::T0, b >> 16));
uint16_t rest = b;
if (rest != 0) {
pushBytes(header, ori(Reg::T0, Reg::T0, rest));
pushBytes(header, ori(Reg::T0, rest));
}
last = sw(Reg::T0, base, Reg::R0);
}
Expand Down

0 comments on commit ee5c53b

Please sign in to comment.