mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-09-26 08:51:05 -04:00
feat: convert translated instructions from variable in static array
This commit is contained in:
+173
-175
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user