feat: convert translated instructions from variable in static array

This commit is contained in:
Ran-j
2025-04-14 00:22:53 -03:00
parent e1b74f4493
commit a877f2a33e
+173 -175
View File
@@ -21,7 +21,7 @@ namespace ps2recomp
if (branchInst.opcode == OPCODE_JAL)
{
// For JAL, set the return address
ss << " ctx->r31 = 0x" << std::hex << (branchInst.address + 8) << ";\n"
ss << " ctx->r[31] = 0x" << std::hex << (branchInst.address + 8) << ";\n"
<< std::dec;
}
@@ -49,7 +49,7 @@ namespace ps2recomp
if (branchInst.function == SPECIAL_JALR)
{
// For JALR, set the return address
ss << " ctx->r" << branchInst.rd << " = 0x" << std::hex << (branchInst.address + 8) << ";\n"
ss << " ctx->r[" << branchInst.rd << "] = 0x" << std::hex << (branchInst.address + 8) << ";\n"
<< std::dec;
}
@@ -64,7 +64,7 @@ namespace ps2recomp
}
else
{
ss << " LOOKUP_FUNC(ctx->r" << branchInst.rs << ")(rdram, ctx);\n";
ss << " LOOKUP_FUNC(ctx->r[" << branchInst.rs << "])(rdram, ctx);\n";
ss << " return;\n";
}
}
@@ -76,77 +76,77 @@ namespace ps2recomp
switch (branchInst.opcode)
{
case OPCODE_BEQ:
conditionStr = fmt::format("ctx->r{} == ctx->r{}", branchInst.rs, branchInst.rt);
conditionStr = fmt::format("ctx->r[{}] == ctx->r[{}]", branchInst.rs, branchInst.rt);
break;
case OPCODE_BNE:
conditionStr = fmt::format("ctx->r{} != ctx->r{}", branchInst.rs, branchInst.rt);
conditionStr = fmt::format("ctx->r[{}] != ctx->r[{}]", branchInst.rs, branchInst.rt);
break;
case OPCODE_BLEZ:
conditionStr = fmt::format("(int32_t)ctx->r{} <= 0", branchInst.rs);
conditionStr = fmt::format("(int32_t)ctx->r[{}] <= 0", branchInst.rs);
break;
case OPCODE_BGTZ:
conditionStr = fmt::format("(int32_t)ctx->r{} > 0", branchInst.rs);
conditionStr = fmt::format("(int32_t)ctx->r[{}] > 0", branchInst.rs);
break;
case OPCODE_BEQL:
conditionStr = fmt::format("ctx->r{} == ctx->r{}", branchInst.rs, branchInst.rt);
conditionStr = fmt::format("ctx->r[{}] == ctx->r[{}]", branchInst.rs, branchInst.rt);
break;
case OPCODE_BNEL:
conditionStr = fmt::format("ctx->r{} != ctx->r{}", branchInst.rs, branchInst.rt);
conditionStr = fmt::format("ctx->r[{}] != ctx->r[{}]", branchInst.rs, branchInst.rt);
break;
case OPCODE_BLEZL:
conditionStr = fmt::format("(int32_t)ctx->r{} <= 0", branchInst.rs);
conditionStr = fmt::format("(int32_t)ctx->r[{}] <= 0", branchInst.rs);
break;
case OPCODE_BGTZL:
conditionStr = fmt::format("(int32_t)ctx->r{} > 0", branchInst.rs);
conditionStr = fmt::format("(int32_t)ctx->r[{}] > 0", branchInst.rs);
break;
case OPCODE_REGIMM:
switch (branchInst.rt)
{
case REGIMM_BLTZ:
conditionStr = fmt::format("(int32_t)ctx->r{} < 0", branchInst.rs);
conditionStr = fmt::format("(int32_t)ctx->r[{}] < 0", branchInst.rs);
break;
case REGIMM_BGEZ:
conditionStr = fmt::format("(int32_t)ctx->r{} >= 0", branchInst.rs);
conditionStr = fmt::format("(int32_t)ctx->r[{}] >= 0", branchInst.rs);
break;
case REGIMM_BLTZL:
conditionStr = fmt::format("(int32_t)ctx->r{} < 0", branchInst.rs);
conditionStr = fmt::format("(int32_t)ctx->r[{}] < 0", branchInst.rs);
break;
case REGIMM_BGEZL:
conditionStr = fmt::format("(int32_t)ctx->r{} >= 0", branchInst.rs);
conditionStr = fmt::format("(int32_t)ctx->r[{}] >= 0", branchInst.rs);
break;
case REGIMM_BLTZAL:
conditionStr = fmt::format("(int32_t)ctx->r{} < 0", branchInst.rs);
ss << " ctx->r31 = 0x" << std::hex << (branchInst.address + 8) << ";\n"
conditionStr = fmt::format("(int32_t)ctx->r[{}] < 0", branchInst.rs);
ss << " ctx->r[31] = 0x" << std::hex << (branchInst.address + 8) << ";\n"
<< std::dec;
break;
case REGIMM_BGEZAL:
conditionStr = fmt::format("(int32_t)ctx->r{} >= 0", branchInst.rs);
ss << " ctx->r31 = 0x" << std::hex << (branchInst.address + 8) << ";\n"
conditionStr = fmt::format("(int32_t)ctx->r[{}] >= 0", branchInst.rs);
ss << " ctx->r[31] = 0x" << std::hex << (branchInst.address + 8) << ";\n"
<< std::dec;
break;
case REGIMM_BLTZALL:
conditionStr = fmt::format("(int32_t)ctx->r{} < 0", branchInst.rs);
ss << " ctx->r31 = 0x" << std::hex << (branchInst.address + 8) << ";\n"
conditionStr = fmt::format("(int32_t)ctx->r[{}] < 0", branchInst.rs);
ss << " ctx->r[31] = 0x" << std::hex << (branchInst.address + 8) << ";\n"
<< std::dec;
break;
case REGIMM_BGEZALL:
conditionStr = fmt::format("(int32_t)ctx->r{} >= 0", branchInst.rs);
ss << " ctx->r31 = 0x" << std::hex << (branchInst.address + 8) << ";\n"
conditionStr = fmt::format("(int32_t)ctx->r[{}] >= 0", branchInst.rs);
ss << " ctx->r[31] = 0x" << std::hex << (branchInst.address + 8) << ";\n"
<< std::dec;
break;
@@ -453,98 +453,98 @@ namespace ps2recomp
{
return "// NOP";
}
return fmt::format("ctx->r{} = SLL32(ctx->r{}, {});",
return fmt::format("ctx->r[{}] = SLL32(ctx->r[{}], {});",
inst.rd, inst.rt, inst.sa);
case SPECIAL_SRL:
return fmt::format("ctx->r{} = SRL32(ctx->r{}, {});",
return fmt::format("ctx->r[{}] = SRL32(ctx->r[{}], {});",
inst.rd, inst.rt, inst.sa);
case SPECIAL_SRA:
return fmt::format("ctx->r{} = SRA32(ctx->r{}, {});",
return fmt::format("ctx->r[{}] = SRA32(ctx->r[{}], {});",
inst.rd, inst.rt, inst.sa);
case SPECIAL_SLLV:
return fmt::format("ctx->r{} = SLL32(ctx->r{}, ctx->r{} & 0x1F);",
return fmt::format("ctx->r[{}] = SLL32(ctx->r[{}], ctx->r[{}] & 0x1F);",
inst.rd, inst.rt, inst.rs);
case SPECIAL_SRLV:
return fmt::format("ctx->r{} = SRL32(ctx->r{}, ctx->r{} & 0x1F);",
return fmt::format("ctx->r[{}] = SRL32(ctx->r[{}], ctx->r[{}] & 0x1F);",
inst.rd, inst.rt, inst.rs);
case SPECIAL_SRAV:
return fmt::format("ctx->r{} = SRA32(ctx->r{}, ctx->r{} & 0x1F);",
return fmt::format("ctx->r[{}] = SRA32(ctx->r[{}], ctx->r[{}] & 0x1F);",
inst.rd, inst.rt, inst.rs);
case SPECIAL_MFHI:
return fmt::format("ctx->r{} = ctx->hi;", inst.rd);
return fmt::format("ctx->r[{}] = ctx->hi;", inst.rd);
case SPECIAL_MTHI:
return fmt::format("ctx->hi = ctx->r{};", inst.rs);
return fmt::format("ctx->hi = ctx->r[{}];", inst.rs);
case SPECIAL_MFLO:
return fmt::format("ctx->r{} = ctx->lo;", inst.rd);
return fmt::format("ctx->r[{}] = ctx->lo;", inst.rd);
case SPECIAL_MTLO:
return fmt::format("ctx->lo = ctx->r{};", inst.rs);
return fmt::format("ctx->lo = ctx->r[{}];", inst.rs);
case SPECIAL_MULT:
return fmt::format("{{ int64_t result = (int64_t)(int32_t)ctx->r{} * (int64_t)(int32_t)ctx->r{}; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
return fmt::format("{{ int64_t result = (int64_t)(int32_t)ctx->r[{}] * (int64_t)(int32_t)ctx->r[{}]; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
inst.rs, inst.rt);
case SPECIAL_MULTU:
return fmt::format("{{ uint64_t result = (uint64_t)ctx->r{} * (uint64_t)ctx->r{}; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
return fmt::format("{{ uint64_t result = (uint64_t)ctx->r[{}] * (uint64_t)ctx->r[{}]; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
inst.rs, inst.rt);
case SPECIAL_DIV:
return fmt::format("{{ if (ctx->r{} != 0) {{ ctx->lo = (uint32_t)((int32_t)ctx->r{} / (int32_t)ctx->r{}); ctx->hi = (uint32_t)((int32_t)ctx->r{} % (int32_t)ctx->r{}); }} }}",
return fmt::format("{{ if (ctx->r[{}] != 0) {{ ctx->lo = (uint32_t)((int32_t)ctx->r[{}] / (int32_t)ctx->r[{}]); ctx->hi = (uint32_t)((int32_t)ctx->r[{}] % (int32_t)ctx->r[{}]); }} }}",
inst.rt, inst.rs, inst.rt, inst.rs, inst.rt);
case SPECIAL_DIVU:
return fmt::format("{{ if (ctx->r{} != 0) {{ ctx->lo = ctx->r{} / ctx->r{}; ctx->hi = ctx->r{} % ctx->r{}; }} }}",
return fmt::format("{{ if (ctx->r[{}] != 0) {{ ctx->lo = ctx->r[{}] / ctx->r[{}]; ctx->hi = ctx->r[{}] % ctx->r[{}]; }} }}",
inst.rt, inst.rs, inst.rt, inst.rs, inst.rt);
case SPECIAL_ADD:
case SPECIAL_ADDU:
return fmt::format("ctx->r{} = ADD32(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = ADD32(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case SPECIAL_SUB:
case SPECIAL_SUBU:
return fmt::format("ctx->r{} = SUB32(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = SUB32(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case SPECIAL_AND:
return fmt::format("ctx->r{} = AND32(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = AND32(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case SPECIAL_OR:
return fmt::format("ctx->r{} = OR32(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = OR32(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case SPECIAL_XOR:
return fmt::format("ctx->r{} = XOR32(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = XOR32(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case SPECIAL_NOR:
return fmt::format("ctx->r{} = NOR32(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = NOR32(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case SPECIAL_SLT:
return fmt::format("ctx->r{} = SLT32(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = SLT32(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case SPECIAL_SLTU:
return fmt::format("ctx->r{} = SLTU32(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = SLTU32(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
// PS2-specific instructions
case SPECIAL_MOVZ:
return fmt::format("if (ctx->r{} == 0) ctx->r{} = ctx->r{};",
return fmt::format("if (ctx->r[{}] == 0) ctx->r[{}] = ctx->r[{}];",
inst.rt, inst.rd, inst.rs);
case SPECIAL_MOVN:
return fmt::format("if (ctx->r{} != 0) ctx->r{} = ctx->r{};",
return fmt::format("if (ctx->r[{}] != 0) ctx->r[{}] = ctx->r[{}];",
inst.rt, inst.rd, inst.rs);
default:
@@ -558,72 +558,72 @@ namespace ps2recomp
{
return "// NOP (addiu $zero, ...)";
}
return fmt::format("ctx->r{} = ADD32(ctx->r{}, 0x{:X});",
return fmt::format("ctx->r[{}] = ADD32(ctx->r[{}], 0x{:X});",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_SLTI:
return fmt::format("ctx->r{} = (int32_t)ctx->r{} < (int32_t)0x{:X} ? 1 : 0;",
return fmt::format("ctx->r[{}] = (int32_t)ctx->r[{}] < (int32_t)0x{:X} ? 1 : 0;",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_SLTIU:
return fmt::format("ctx->r{} = ctx->r{} < (uint32_t)0x{:X} ? 1 : 0;",
return fmt::format("ctx->r[{}] = ctx->r[{}] < (uint32_t)0x{:X} ? 1 : 0;",
inst.rt, inst.rs, (uint32_t)(int16_t)inst.immediate);
case OPCODE_ANDI:
return fmt::format("ctx->r{} = AND32(ctx->r{}, 0x{:X});",
return fmt::format("ctx->r[{}] = AND32(ctx->r[{}], 0x{:X});",
inst.rt, inst.rs, inst.immediate);
case OPCODE_ORI:
return fmt::format("ctx->r{} = OR32(ctx->r{}, 0x{:X});",
return fmt::format("ctx->r[{}] = OR32(ctx->r[{}], 0x{:X});",
inst.rt, inst.rs, inst.immediate);
case OPCODE_XORI:
return fmt::format("ctx->r{} = XOR32(ctx->r{}, 0x{:X});",
return fmt::format("ctx->r[{}] = XOR32(ctx->r[{}], 0x{:X});",
inst.rt, inst.rs, inst.immediate);
case OPCODE_LUI:
return fmt::format("ctx->r{} = 0x{:X} << 16;",
return fmt::format("ctx->r[{}] = 0x{:X} << 16;",
inst.rt, inst.immediate);
case OPCODE_LB:
return fmt::format("ctx->r{} = (int32_t)(int8_t)READ8(ADD32(ctx->r{}, 0x{:X}));",
return fmt::format("ctx->r[{}] = (int32_t)(int8_t)READ8(ADD32(ctx->r[{}], 0x{:X}));",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_LH:
return fmt::format("ctx->r{} = (int32_t)(int16_t)READ16(ADD32(ctx->r{}, 0x{:X}));",
return fmt::format("ctx->r[{}] = (int32_t)(int16_t)READ16(ADD32(ctx->r[{}], 0x{:X}));",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_LW:
return fmt::format("ctx->r{} = READ32(ADD32(ctx->r{}, 0x{:X}));",
return fmt::format("ctx->r[{}] = READ32(ADD32(ctx->r[{}], 0x{:X}));",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_LBU:
return fmt::format("ctx->r{} = (uint32_t)READ8(ADD32(ctx->r{}, 0x{:X}));",
return fmt::format("ctx->r[{}] = (uint32_t)READ8(ADD32(ctx->r[{}], 0x{:X}));",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_LHU:
return fmt::format("ctx->r{} = (uint32_t)READ16(ADD32(ctx->r{}, 0x{:X}));",
return fmt::format("ctx->r[{}] = (uint32_t)READ16(ADD32(ctx->r[{}], 0x{:X}));",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_SB:
return fmt::format("WRITE8(ADD32(ctx->r{}, 0x{:X}), (uint8_t)ctx->r{});",
return fmt::format("WRITE8(ADD32(ctx->r[{}], 0x{:X}), (uint8_t)ctx->r[{}]);",
inst.rs, (int16_t)inst.immediate, inst.rt);
case OPCODE_SH:
return fmt::format("WRITE16(ADD32(ctx->r{}, 0x{:X}), (uint16_t)ctx->r{});",
return fmt::format("WRITE16(ADD32(ctx->r[{}], 0x{:X}), (uint16_t)ctx->r[{}]);",
inst.rs, (int16_t)inst.immediate, inst.rt);
case OPCODE_SW:
return fmt::format("WRITE32(ADD32(ctx->r{}, 0x{:X}), ctx->r{});",
return fmt::format("WRITE32(ADD32(ctx->r[{}], 0x{:X}), ctx->r[{}]);",
inst.rs, (int16_t)inst.immediate, inst.rt);
// PS2-specific 128-bit load/store
case OPCODE_LQ:
return fmt::format("ctx->r{} = (__m128i)READ128(ADD32(ctx->r{}, 0x{:X}));",
return fmt::format("ctx->r[{}] = (__m128i)READ128(ADD32(ctx->r[{}], 0x{:X}));",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_SQ:
return fmt::format("WRITE128(ADD32(ctx->r{}, 0x{:X}), (__m128i)ctx->r{});",
return fmt::format("WRITE128(ADD32(ctx->r[{}], 0x{:X}), (__m128i)ctx->r[{}]);",
inst.rs, (int16_t)inst.immediate, inst.rt);
// Special case for R5900
@@ -651,51 +651,51 @@ namespace ps2recomp
switch (function)
{
case MMI_MADD:
return fmt::format("{{ int64_t result = (int64_t)(((int64_t)ctx->hi << 32) | ctx->lo) + (int64_t)(int32_t)ctx->r{} * (int64_t)(int32_t)ctx->r{}; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
return fmt::format("{{ int64_t result = (int64_t)(((int64_t)ctx->hi << 32) | ctx->lo) + (int64_t)(int32_t)ctx->r[{}] * (int64_t)(int32_t)ctx->r[{}]; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
inst.rs, inst.rt);
case MMI_MADDU:
return fmt::format("{{ uint64_t result = (uint64_t)(((uint64_t)ctx->hi << 32) | ctx->lo) + (uint64_t)ctx->r{} * (uint64_t)ctx->r{}; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
return fmt::format("{{ uint64_t result = (uint64_t)(((uint64_t)ctx->hi << 32) | ctx->lo) + (uint64_t)ctx->r[{}] * (uint64_t)ctx->r[{}]; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
inst.rs, inst.rt);
case MMI_PLZCW:
return fmt::format("ctx->r{} = __builtin_clz(ctx->r{});",
return fmt::format("ctx->r[{}] = __builtin_clz(ctx->r[{}]);",
inst.rd, inst.rs);
case MMI_MFHI1:
return fmt::format("ctx->r{} = ctx->hi;", inst.rd);
return fmt::format("ctx->r[{}] = ctx->hi;", inst.rd);
case MMI_MTHI1:
return fmt::format("ctx->hi = ctx->r{};", inst.rs);
return fmt::format("ctx->hi = ctx->r[{}];", inst.rs);
case MMI_MFLO1:
return fmt::format("ctx->r{} = ctx->lo;", inst.rd);
return fmt::format("ctx->r[{}] = ctx->lo;", inst.rd);
case MMI_MTLO1:
return fmt::format("ctx->lo = ctx->r{};", inst.rs);
return fmt::format("ctx->lo = ctx->r[{}];", inst.rs);
case MMI_MULT1:
return fmt::format("{{ int64_t result = (int64_t)(int32_t)ctx->r{} * (int64_t)(int32_t)ctx->r{}; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
return fmt::format("{{ int64_t result = (int64_t)(int32_t)ctx->r[{}] * (int64_t)(int32_t)ctx->r[{}]; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
inst.rs, inst.rt);
case MMI_MULTU1:
return fmt::format("{{ uint64_t result = (uint64_t)ctx->r{} * (uint64_t)ctx->r{}; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
return fmt::format("{{ uint64_t result = (uint64_t)ctx->r[{}] * (uint64_t)ctx->r[{}]; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
inst.rs, inst.rt);
case MMI_DIV1:
return fmt::format("{{ if (ctx->r{} != 0) {{ ctx->lo = (uint32_t)((int32_t)ctx->r{} / (int32_t)ctx->r{}); ctx->hi = (uint32_t)((int32_t)ctx->r{} % (int32_t)ctx->r{}); }} }}",
return fmt::format("{{ if (ctx->r[{}] != 0) {{ ctx->lo = (uint32_t)((int32_t)ctx->r[{}] / (int32_t)ctx->r[{}]); ctx->hi = (uint32_t)((int32_t)ctx->r[{}] % (int32_t)ctx->r[{}]); }} }}",
inst.rt, inst.rs, inst.rt, inst.rs, inst.rt);
case MMI_DIVU1:
return fmt::format("{{ if (ctx->r{} != 0) {{ ctx->lo = ctx->r{} / ctx->r{}; ctx->hi = ctx->r{} % ctx->r{}; }} }}",
return fmt::format("{{ if (ctx->r[{}] != 0) {{ ctx->lo = ctx->r[{}] / ctx->r[{}]; ctx->hi = ctx->r[{}] % ctx->r[{}]; }} }}",
inst.rt, inst.rs, inst.rt, inst.rs, inst.rt);
case MMI_MADD1:
return fmt::format("{{ int64_t result = (int64_t)(((int64_t)ctx->hi << 32) | ctx->lo) + (int64_t)(int32_t)ctx->r{} * (int64_t)(int32_t)ctx->r{}; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
return fmt::format("{{ int64_t result = (int64_t)(((int64_t)ctx->hi << 32) | ctx->lo) + (int64_t)(int32_t)ctx->r[{}] * (int64_t)(int32_t)ctx->r[{}]; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
inst.rs, inst.rt);
case MMI_MADDU1:
return fmt::format("{{ uint64_t result = (uint64_t)(((uint64_t)ctx->hi << 32) | ctx->lo) + (uint64_t)ctx->r{} * (uint64_t)ctx->r{}; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
return fmt::format("{{ uint64_t result = (uint64_t)(((uint64_t)ctx->hi << 32) | ctx->lo) + (uint64_t)ctx->r[{}] * (uint64_t)ctx->r[{}]; ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); }}",
inst.rs, inst.rt);
// MMI0 functions (PADDW, PSUBW, etc.)
@@ -703,67 +703,67 @@ namespace ps2recomp
switch (inst.sa)
{
case MMI0_PADDW:
return fmt::format("ctx->r{} = PS2_PADDW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PADDW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PSUBW:
return fmt::format("ctx->r{} = PS2_PSUBW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSUBW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PCGTW:
return fmt::format("ctx->r{} = PS2_PCGTW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PCGTW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PMAXW:
return fmt::format("ctx->r{} = PS2_PMAXW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PMAXW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PADDH:
return fmt::format("ctx->r{} = PS2_PADDH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PADDH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PSUBH:
return fmt::format("ctx->r{} = PS2_PSUBH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSUBH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PCGTH:
return fmt::format("ctx->r{} = PS2_PCGTH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PCGTH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PMAXH:
return fmt::format("ctx->r{} = PS2_PMAXH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PMAXH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PADDB:
return fmt::format("ctx->r{} = PS2_PADDB(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PADDB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PSUBB:
return fmt::format("ctx->r{} = PS2_PSUBB(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSUBB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PCGTB:
return fmt::format("ctx->r{} = PS2_PCGTB(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PCGTB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PEXTLW:
return fmt::format("ctx->r{} = PS2_PEXTLW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PEXTLW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PPACW:
return fmt::format("ctx->r{} = PS2_PPACW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PPACW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PEXTLH:
return fmt::format("ctx->r{} = PS2_PEXTLH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PEXTLH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PPACH:
return fmt::format("ctx->r{} = PS2_PPACH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PPACH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PEXTLB:
return fmt::format("ctx->r{} = PS2_PEXTLB(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PEXTLB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI0_PPACB:
@@ -779,66 +779,66 @@ namespace ps2recomp
switch (inst.sa)
{
case MMI1_PADDUW:
return fmt::format("ctx->r{} = PS2_PADDW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PADDW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PSUBUW:
return fmt::format("ctx->r{} = PS2_PSUBW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSUBW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PEXTUW:
return fmt::format("ctx->r{} = PS2_PEXTUW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PEXTUW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PADDUH:
return fmt::format("ctx->r{} = PS2_PADDH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PADDH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PSUBUH:
return fmt::format("ctx->r{} = PS2_PSUBH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSUBH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PEXTUH:
return fmt::format("ctx->r{} = PS2_PEXTUH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PEXTUH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PABSW:
return fmt::format("ctx->r{} = PS2_PABSW(ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PABSW(ctx->r[{}]);",
inst.rd, inst.rs);
case MMI1_PABSH:
return fmt::format("ctx->r{} = PS2_PABSH(ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PABSH(ctx->r[{}]);",
inst.rd, inst.rs);
case MMI1_PCEQW:
return fmt::format("ctx->r{} = PS2_PCEQW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PCEQW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PCEQH:
return fmt::format("ctx->r{} = PS2_PCEQH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PCEQH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PCEQB:
return fmt::format("ctx->r{} = PS2_PCEQB(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PCEQB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PMINW:
return fmt::format("ctx->r{} = PS2_PMINW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PMINW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PMINH:
return fmt::format("ctx->r{} = PS2_PMINH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PMINH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PADDUB:
return fmt::format("ctx->r{} = PS2_PADDB(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PADDB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PSUBUB:
return fmt::format("ctx->r{} = PS2_PSUBB(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSUBB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_PEXTUB:
return fmt::format("ctx->r{} = PS2_PEXTUB(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PEXTUB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI1_QFSRV:
@@ -854,27 +854,27 @@ namespace ps2recomp
switch (inst.sa)
{
case MMI2_PMADDW:
return fmt::format("ctx->r{} = PS2_PMADDW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PMADDW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI2_PSLLVW:
return fmt::format("ctx->r{} = PS2_PSLLVW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSLLVW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI2_PSRLVW:
return fmt::format("ctx->r{} = PS2_PSRLVW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSRLVW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI2_PINTH:
return fmt::format("ctx->r{} = PS2_PINTH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PINTH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI2_PAND:
return fmt::format("ctx->r{} = PS2_PAND(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PAND(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI2_PXOR:
return fmt::format("ctx->r{} = PS2_PXOR(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PXOR(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI2_PMULTW:
@@ -920,22 +920,22 @@ namespace ps2recomp
switch (inst.sa)
{
case MMI3_POR:
return fmt::format("ctx->r{} = PS2_POR(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_POR(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI3_PNOR:
return fmt::format("ctx->r{} = PS2_PNOR(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PNOR(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI3_PMADDUW:
return fmt::format("// PS2_PMADDUW - Packed Multiply-Add Unsigned Word");
case MMI3_PSRAVW:
return fmt::format("ctx->r{} = PS2_PSRAVW(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PSRAVW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI3_PINTEH:
return fmt::format("ctx->r{} = PS2_PINTEH(ctx->r{}, ctx->r{});",
return fmt::format("ctx->r[{}] = PS2_PINTEH(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
case MMI3_PMULTUW:
@@ -966,23 +966,23 @@ namespace ps2recomp
switch (inst.pmfhlVariation)
{
case PMFHL_LW:
return fmt::format("ctx->r{} = PS2_PMFHL_LW(ctx->hi, ctx->lo);",
return fmt::format("ctx->r[{}] = PS2_PMFHL_LW(ctx->hi, ctx->lo);",
inst.rd);
case PMFHL_UW:
return fmt::format("ctx->r{} = PS2_PMFHL_UW(ctx->hi, ctx->lo);",
return fmt::format("ctx->r[{}] = PS2_PMFHL_UW(ctx->hi, ctx->lo);",
inst.rd);
case PMFHL_SLW:
return fmt::format("ctx->r{} = PS2_PMFHL_SLW(ctx->hi, ctx->lo);",
return fmt::format("ctx->r[{}] = PS2_PMFHL_SLW(ctx->hi, ctx->lo);",
inst.rd);
case PMFHL_LH:
return fmt::format("ctx->r{} = PS2_PMFHL_LH(ctx->hi, ctx->lo);",
return fmt::format("ctx->r[{}] = PS2_PMFHL_LH(ctx->hi, ctx->lo);",
inst.rd);
case PMFHL_SH:
return fmt::format("ctx->r{} = PS2_PMFHL_SH(ctx->hi, ctx->lo);",
return fmt::format("ctx->r[{}] = PS2_PMFHL_SH(ctx->hi, ctx->lo);",
inst.rd);
default:
@@ -1002,13 +1002,13 @@ namespace ps2recomp
switch (rs)
{
case COP2_QMFC2:
return fmt::format("ctx->r{} = (__m128i)ctx->vu0_vf{};",
return fmt::format("ctx->r[{}] = (__m128i)ctx->vu0_vf[{}];",
inst.rt, inst.rd);
case COP2_CFC2:
if (inst.rd == 0)
{
return fmt::format("ctx->r{} = ctx->vu0_status;", inst.rt);
return fmt::format("ctx->r[{}] = ctx->vu0_status;", inst.rt);
}
else
{
@@ -1016,13 +1016,13 @@ namespace ps2recomp
}
case COP2_QMTC2:
return fmt::format("ctx->vu0_vf{} = (__m128)ctx->r{};",
return fmt::format("ctx->vu0_vf[{}] = (__m128)ctx->r[{}];",
inst.rd, inst.rt);
case COP2_CTC2:
if (inst.rd == 0)
{
return fmt::format("ctx->vu0_status = ctx->r{} & 0xFFFF;", inst.rt);
return fmt::format("ctx->vu0_status = ctx->r[{}] & 0xFFFF;", inst.rt);
}
else
{
@@ -1037,23 +1037,23 @@ namespace ps2recomp
switch (inst.function)
{
case VU0_VADD:
return fmt::format("ctx->vu0_vf{} = PS2_VADD(ctx->vu0_vf{}, ctx->vu0_vf{});",
return fmt::format("ctx->vu0_vf[{}] = PS2_VADD(ctx->vu0_vf[{}], ctx->vu0_vf[{}]);",
inst.rd, inst.rs, inst.rt);
case VU0_VSUB:
return fmt::format("ctx->vu0_vf{} = PS2_VSUB(ctx->vu0_vf{}, ctx->vu0_vf{});",
return fmt::format("ctx->vu0_vf[{}] = PS2_VSUB(ctx->vu0_vf[{}], ctx->vu0_vf[{}]);",
inst.rd, inst.rs, inst.rt);
case VU0_VMUL:
return fmt::format("ctx->vu0_vf{} = PS2_VMUL(ctx->vu0_vf{}, ctx->vu0_vf{});",
return fmt::format("ctx->vu0_vf[{}] = PS2_VMUL(ctx->vu0_vf[{}], ctx->vu0_vf[{}]);",
inst.rd, inst.rs, inst.rt);
case VU0_VDIV:
return fmt::format("ctx->vu0_vf{} = PS2_VDIV(ctx->vu0_vf{}, ctx->vu0_vf{});",
return fmt::format("ctx->vu0_vf[{}] = PS2_VDIV(ctx->vu0_vf[{}], ctx->vu0_vf[{}]);",
inst.rd, inst.rs, inst.rt);
case VU0_VMULQ:
return fmt::format("ctx->vu0_vf{} = PS2_VMULQ(ctx->vu0_vf{}, ctx->vu0_q);",
return fmt::format("ctx->vu0_vf[{}] = PS2_VMULQ(ctx->vu0_vf[{}], ctx->vu0_q);",
inst.rd, inst.rs);
default:
@@ -1077,12 +1077,12 @@ namespace ps2recomp
// For MFC1/MTC1/CFC1/CTC1, the GPR is in rt and the FPR is in rd(fs)
if (rs == COP1_MF)
{
return fmt::format("ctx->r{} = *(uint32_t*)&ctx->f{};",
return fmt::format("ctx->r[{}] = *(uint32_t*)&ctx->f[{}];",
ft, fs);
}
else if (rs == COP1_MT)
{
return fmt::format("*(uint32_t*)&ctx->f{} = ctx->r{};",
return fmt::format("*(uint32_t*)&ctx->f[{}] = ctx->r[{}];",
fs, ft);
}
else if (rs == COP1_CF)
@@ -1090,15 +1090,15 @@ namespace ps2recomp
// CFC1 - Move Control From FPU
if (fs == 31) // FCR31 contains status/control
{
return fmt::format("ctx->r{} = ctx->fcr31;", ft);
return fmt::format("ctx->r[{}] = ctx->fcr31;", ft);
}
else if (fs == 0) // FCR0 is the FPU implementation register
{
return fmt::format("ctx->r{} = 0x00000000; // Emulated FPU implementation", ft);
return fmt::format("ctx->r[{}] = 0x00000000; // Emulated FPU implementation", ft);
}
else
{
return fmt::format("ctx->r{} = 0; // Unimplemented FCR{}", ft, fs);
return fmt::format("ctx->r[{}] = 0; // Unimplemented FCR{}", ft, fs);
}
}
else if (rs == COP1_CT)
@@ -1106,7 +1106,7 @@ namespace ps2recomp
// CTC1 - Move Control To FPU
if (fs == 31) // FCR31 contains status/control
{
return fmt::format("ctx->fcr31 = ctx->r{} & 0x0183FFFF;", ft); // Apply bit mask for valid bits
return fmt::format("ctx->fcr31 = ctx->r[{}] & 0x0183FFFF;", ft); // Apply bit mask for valid bits
}
else
{
@@ -1124,80 +1124,78 @@ namespace ps2recomp
switch (function)
{
case 0x00: // ADD.S
return fmt::format("ctx->f{} = FPU_ADD_S(ctx->f{}, ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_ADD_S(ctx->f[{}], ctx->f[{}]);",
fd, fs, ft);
case 0x01: // SUB.S
return fmt::format("ctx->f{} = FPU_SUB_S(ctx->f{}, ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_SUB_S(ctx->f[{}], ctx->f[{}]);",
fd, fs, ft);
case 0x02: // MUL.S
return fmt::format("ctx->f{} = FPU_MUL_S(ctx->f{}, ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_MUL_S(ctx->f[{}], ctx->f[{}]);",
fd, fs, ft);
case 0x03: // DIV.S
return fmt::format("ctx->f{} = FPU_DIV_S(ctx->f{}, ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_DIV_S(ctx->f[{}], ctx->f[{}]);",
fd, fs, ft);
case 0x04: // SQRT.S
return fmt::format("ctx->f{} = FPU_SQRT_S(ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_SQRT_S(ctx->f[{}]);",
fd, fs);
case 0x05: // ABS.S
return fmt::format("ctx->f{} = FPU_ABS_S(ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_ABS_S(ctx->f[{}]);",
fd, fs);
case 0x06: // MOV.S
return fmt::format("ctx->f{} = FPU_MOV_S(ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_MOV_S(ctx->f[{}]);",
fd, fs);
case 0x07: // NEG.S
return fmt::format("ctx->f{} = FPU_NEG_S(ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_NEG_S(ctx->f[{}]);",
fd, fs);
case 0x08: // ROUND.L.S
return fmt::format("*(int64_t*)&ctx->f{} = FPU_ROUND_L_S(ctx->f{});",
return fmt::format("*(int64_t*)&ctx->f[{}] = FPU_ROUND_L_S(ctx->f[{}]);",
fd, fs);
case 0x09: // TRUNC.L.S
return fmt::format("*(int64_t*)&ctx->f{} = FPU_TRUNC_L_S(ctx->f{});",
return fmt::format("*(int64_t*)&ctx->f[{}] = FPU_TRUNC_L_S(ctx->f[{}]);",
fd, fs);
case 0x0A: // CEIL.L.S
return fmt::format("*(int64_t*)&ctx->f{} = FPU_CEIL_L_S(ctx->f{});",
return fmt::format("*(int64_t*)&ctx->f[{}] = FPU_CEIL_L_S(ctx->f[{}]);",
fd, fs);
case 0x0B: // FLOOR.L.S
return fmt::format("*(int64_t*)&ctx->f{} = FPU_FLOOR_L_S(ctx->f{});",
return fmt::format("*(int64_t*)&ctx->f[{}] = FPU_FLOOR_L_S(ctx->f[{}]);",
fd, fs);
case 0x0C: // ROUND.W.S
return fmt::format("*(int32_t*)&ctx->f{} = FPU_ROUND_W_S(ctx->f{});",
return fmt::format("*(int32_t*)&ctx->f[{}] = FPU_ROUND_W_S(ctx->f[{}]);",
fd, fs);
case 0x0D: // TRUNC.W.S
return fmt::format("*(int32_t*)&ctx->f{} = FPU_TRUNC_W_S(ctx->f{});",
return fmt::format("*(int32_t*)&ctx->f[{}] = FPU_TRUNC_W_S(ctx->f[{}]);",
fd, fs);
case 0x0E: // CEIL.W.S
return fmt::format("*(int32_t*)&ctx->f{} = FPU_CEIL_W_S(ctx->f{});",
return fmt::format("*(int32_t*)&ctx->f[{}] = FPU_CEIL_W_S(ctx->f[{}]);",
fd, fs);
case 0x0F: // FLOOR.W.S
return fmt::format("*(int32_t*)&ctx->f{} = FPU_FLOOR_W_S(ctx->f{});",
return fmt::format("*(int32_t*)&ctx->f[{}] = FPU_FLOOR_W_S(ctx->f[{}]);",
fd, fs);
// Continuing the COP1_S switch case from the previous code:
case 0x21: // CVT.D.S - Convert Single to Double (not commonly used on PS2)
return fmt::format("// CVT.D.S not implemented (PS2 rarely uses double precision)");
case 0x24: // CVT.W.S - Convert Single to Word
return fmt::format("*(int32_t*)&ctx->f{} = FPU_CVT_W_S(ctx->f{});",
return fmt::format("*(int32_t*)&ctx->f[{}] = FPU_CVT_W_S(ctx->f[{}]);",
fd, fs);
case 0x25: // CVT.L.S - Convert Single to Long
return fmt::format("*(int64_t*)&ctx->f{} = FPU_CVT_L_S(ctx->f{});",
return fmt::format("*(int64_t*)&ctx->f[{}] = FPU_CVT_L_S(ctx->f[{}]);",
fd, fs);
case 0x30: // C.F.S - Compare False
@@ -1205,31 +1203,31 @@ namespace ps2recomp
fs, ft);
case 0x31: // C.UN.S - Compare Unordered
return fmt::format("ctx->fcr31 = (FPU_C_UN_S(ctx->f{}, ctx->f{})) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
return fmt::format("ctx->fcr31 = (FPU_C_UN_S(ctx->f[{}], ctx->f[{}])) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
fs, ft);
case 0x32: // C.EQ.S - Compare Equal
return fmt::format("ctx->fcr31 = (FPU_C_EQ_S(ctx->f{}, ctx->f{})) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
return fmt::format("ctx->fcr31 = (FPU_C_EQ_S(ctx->f[{}], ctx->f[{}])) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
fs, ft);
case 0x33: // C.UEQ.S - Compare Unordered or Equal
return fmt::format("ctx->fcr31 = (FPU_C_UEQ_S(ctx->f{}, ctx->f{})) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
return fmt::format("ctx->fcr31 = (FPU_C_UEQ_S(ctx->f[{}], ctx->f[{}])) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
fs, ft);
case 0x34: // C.OLT.S - Compare Ordered Less Than
return fmt::format("ctx->fcr31 = (FPU_C_OLT_S(ctx->f{}, ctx->f{})) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
return fmt::format("ctx->fcr31 = (FPU_C_OLT_S(ctx->f[{}], ctx->f[{}])) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
fs, ft);
case 0x35: // C.ULT.S - Compare Unordered or Less Than
return fmt::format("ctx->fcr31 = (FPU_C_ULT_S(ctx->f{}, ctx->f{})) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
return fmt::format("ctx->fcr31 = (FPU_C_ULT_S(ctx->f[{}], ctx->f[{}])) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
fs, ft);
case 0x36: // C.OLE.S - Compare Ordered Less Than or Equal
return fmt::format("ctx->fcr31 = (FPU_C_OLE_S(ctx->f{}, ctx->f{})) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
return fmt::format("ctx->fcr31 = (FPU_C_OLE_S(ctx->f[{}], ctx->f[{}])) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
fs, ft);
case 0x37: // C.ULE.S - Compare Unordered or Less Than or Equal
return fmt::format("ctx->fcr31 = (FPU_C_ULE_S(ctx->f{}, ctx->f{})) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
return fmt::format("ctx->fcr31 = (FPU_C_ULE_S(ctx->f[{}], ctx->f[{}])) ? (ctx->fcr31 | 0x800000) : (ctx->fcr31 & ~0x800000);",
fs, ft);
default:
@@ -1242,7 +1240,7 @@ namespace ps2recomp
switch (function)
{
case 0x20: // CVT.S.W - Convert Word to Single
return fmt::format("ctx->f{} = FPU_CVT_S_W(*(int32_t*)&ctx->f{});",
return fmt::format("ctx->f[{}] = FPU_CVT_S_W(*(int32_t*)&ctx->f[{}]);",
fd, fs);
default:
@@ -1265,16 +1263,16 @@ namespace ps2recomp
switch (rd)
{
case 12: // Status register
return fmt::format("ctx->r{} = ctx->cop0_status;", rt);
return fmt::format("ctx->r[{}] = ctx->cop0_status;", rt);
case 13: // Cause register
return fmt::format("ctx->r{} = ctx->cop0_cause;", rt);
return fmt::format("ctx->r[{}] = ctx->cop0_cause;", rt);
case 14: // EPC register
return fmt::format("ctx->r{} = ctx->cop0_epc;", rt);
return fmt::format("ctx->r[{}] = ctx->cop0_epc;", rt);
default:
return fmt::format("ctx->r{} = 0; // Unimplemented COP0 register {}", rt, rd);
return fmt::format("ctx->r[{}] = 0; // Unimplemented COP0 register {}", rt, rd);
}
}
else if (rs == COP0_MT)
@@ -1283,13 +1281,13 @@ namespace ps2recomp
switch (rd)
{
case 12: // Status register
return fmt::format("ctx->cop0_status = ctx->r{};", rt);
return fmt::format("ctx->cop0_status = ctx->r[{}];", rt);
case 13: // Cause register
return fmt::format("ctx->cop0_cause = ctx->r{};", rt);
return fmt::format("ctx->cop0_cause = ctx->r[{}];", rt);
case 14: // EPC register
return fmt::format("ctx->cop0_epc = ctx->r{};", rt);
return fmt::format("ctx->cop0_epc = ctx->r[{}];", rt);
default:
return fmt::format("// MTC0 to register {} ignored", rd);
@@ -1338,7 +1336,7 @@ namespace ps2recomp
uint32_t indexReg = inst.rs;
ss << "switch (ctx->r" << indexReg << ") {\n";
ss << "switch (ctx->r[" << indexReg << "]) {\n";
for (const auto &entry : entries)
{