refactor: added more instructions decoder

This commit is contained in:
Ran-j
2025-04-16 01:45:13 -03:00
parent 7353b966f2
commit 23bb92bd4a
5 changed files with 463 additions and 57 deletions
+97 -13
View File
@@ -465,6 +465,11 @@ namespace ps2recomp
{
return "// NOP (addiu $zero, ...)";
}
if (inst.modificationInfo.modifiesGPR)
{
return fmt::format("ctx->r[{}] = ADD32(ctx->r[{}], 0x{:X}); // Modifies GPR",
inst.rt, inst.rs, (int16_t)inst.immediate);
}
return fmt::format("ctx->r[{}] = ADD32(ctx->r[{}], 0x{:X});",
inst.rt, inst.rs, (int16_t)inst.immediate);
@@ -526,10 +531,20 @@ namespace ps2recomp
// PS2-specific 128-bit load/store
case OPCODE_LQ:
if (inst.vectorInfo.isVector)
{
return fmt::format("ctx->r[{}] = (__m128i)READ128(ADD32(ctx->r[{}], 0x{:X})); // Vector load",
inst.rt, inst.rs, (int16_t)inst.immediate);
}
return fmt::format("ctx->r[{}] = (__m128i)READ128(ADD32(ctx->r[{}], 0x{:X}));",
inst.rt, inst.rs, (int16_t)inst.immediate);
case OPCODE_SQ:
if (inst.vectorInfo.isVector)
{
return fmt::format("WRITE128(ADD32(ctx->r[{}], 0x{:X}), (__m128i)ctx->r[{}]); // Vector store",
inst.rs, (int16_t)inst.immediate, inst.rt);
}
return fmt::format("WRITE128(ADD32(ctx->r[{}], 0x{:X}), (__m128i)ctx->r[{}]);",
inst.rs, (int16_t)inst.immediate, inst.rt);
@@ -553,6 +568,14 @@ namespace ps2recomp
return fmt::format("WRITE128(ADD32(ctx->r[{}], 0x{:X}), (__m128i)ctx->vu0_vf[{}]);",
inst.rs, (int16_t)inst.immediate, inst.rt);
case OPCODE_J:
return fmt::format("// J 0x{:X} - Handled by branch logic",
(inst.address & 0xF0000000) | (inst.target << 2));
case OPCODE_JAL:
return fmt::format("// JAL 0x{:X} - Handled by branch logic",
(inst.address & 0xF0000000) | (inst.target << 2));
case OPCODE_LWC1:
return fmt::format("{{ uint32_t val = READ32(ADD32(ctx->r[{}], 0x{:X})); ctx->f[{}] = *(float*)&val; }}",
inst.rs, (int16_t)inst.immediate, inst.rt);
@@ -579,20 +602,17 @@ namespace ps2recomp
switch (inst.rt)
{
case REGIMM_BLTZ:
return fmt::format("// BLTZ r{}, 0x{:X} - Handled by branch logic",
inst.rs, inst.address + 4 + ((int16_t)inst.immediate << 2));
case REGIMM_BGEZ:
return fmt::format("// BGEZ r{}, 0x{:X} - Handled by branch logic",
inst.rs, inst.address + 4 + ((int16_t)inst.immediate << 2));
case REGIMM_BLTZL:
case REGIMM_BGEZL:
case REGIMM_BLTZAL:
return fmt::format("// BLTZAL r{}, 0x{:X} - Handled by branch logic",
inst.rs, inst.address + 4 + ((int16_t)inst.immediate << 2));
case REGIMM_BGEZAL:
return fmt::format("// BGEZAL r{}, 0x{:X} - Handled by branch logic",
inst.rs, inst.address + 4 + ((int16_t)inst.immediate << 2));
case REGIMM_BLTZALL:
case REGIMM_BGEZALL:
{
uint32_t target = inst.address + 4 + ((int16_t)inst.immediate << 2);
return fmt::format("// REGIMM branch instruction to 0x{:X} - Handled by branch logic", target);
}
case REGIMM_MTSAB:
return fmt::format("ctx->sa = (ctx->r[{}] + 0x{:X}) & 0x0F;",
@@ -631,6 +651,10 @@ namespace ps2recomp
}
// MIPS-IV special format opcodes
case OPCODE_BEQ:
case OPCODE_BNE:
case OPCODE_BLEZ:
case OPCODE_BGTZ:
case OPCODE_BEQL:
case OPCODE_BNEL:
case OPCODE_BLEZL:
@@ -1128,6 +1152,15 @@ namespace ps2recomp
switch (inst.sa)
{
case MMI0_PADDW:
if (inst.vectorInfo.isVector && inst.vectorInfo.vectorField != 0xF)
{
return fmt::format("{{ __m128i mask = _mm_set_epi32({}, {}, {}, {}); ctx->r[{}] = _mm_blendv_epi8(ctx->r[{}], PS2_PADDW(ctx->r[{}], ctx->r[{}]), mask); }}",
(inst.vectorInfo.vectorField & 0x8) ? 0xFFFFFFFF : 0,
(inst.vectorInfo.vectorField & 0x4) ? 0xFFFFFFFF : 0,
(inst.vectorInfo.vectorField & 0x2) ? 0xFFFFFFFF : 0,
(inst.vectorInfo.vectorField & 0x1) ? 0xFFFFFFFF : 0,
inst.rd, inst.rd, inst.rs, inst.rt);
}
return fmt::format("ctx->r[{}] = PS2_PADDW(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
@@ -1192,7 +1225,8 @@ namespace ps2recomp
inst.rd, inst.rs, inst.rt);
case MMI0_PPACB:
return fmt::format("// PS2_PPACB not implemented");
return fmt::format("ctx->r[{}] = PS2_PPACB(ctx->r[{}], ctx->r[{}]);",
inst.rd, inst.rs, inst.rt);
default:
return fmt::format("// Unhandled MMI0 function: 0x{:X}", inst.sa);
@@ -1316,6 +1350,36 @@ namespace ps2recomp
case MMI2_PHMADH:
return translatePHMADH(inst);
case MMI2_PMSUBH:
return fmt::format("{{ __m128i product = _mm_mullo_epi16(ctx->r[{}], ctx->r[{}]); "
"// Convert products to 32-bit\n"
"__m128i prod_lo = _mm_unpacklo_epi16(product, _mm_srai_epi16(product, 15));\n"
"__m128i prod_hi = _mm_unpackhi_epi16(product, _mm_srai_epi16(product, 15));\n"
"// Subtract from accumulator\n"
"__m128i acc = _mm_set_epi32(0, ctx->hi, 0, ctx->lo);\n"
"__m128i result = _mm_sub_epi32(acc, _mm_add_epi32(prod_lo, prod_hi));\n"
"ctx->r[{}] = result;\n"
"ctx->lo = _mm_extract_epi32(result, 0);\n"
"ctx->hi = _mm_extract_epi32(result, 1); }}",
inst.rs, inst.rt, inst.rd);
case MMI2_PHMSBH:
return fmt::format("{{ // Multiply horizontally adjacent halfwords\n"
"__m128i rtEven = _mm_shuffle_epi32(ctx->r[{}], _MM_SHUFFLE(2, 0, 2, 0));\n"
"__m128i rtOdd = _mm_shuffle_epi32(ctx->r[{}], _MM_SHUFFLE(3, 1, 3, 1));\n"
"__m128i rsEven = _mm_shuffle_epi32(ctx->r[{}], _MM_SHUFFLE(2, 0, 2, 0));\n"
"__m128i rsOdd = _mm_shuffle_epi32(ctx->r[{}], _MM_SHUFFLE(3, 1, 3, 1));\n"
"__m128i prod1 = _mm_mullo_epi16(rtEven, rsEven);\n"
"__m128i prod2 = _mm_mullo_epi16(rtOdd, rsOdd);\n"
"__m128i sum = _mm_add_epi16(prod1, prod2);\n"
"// Convert to 32-bit and subtract from accumulator\n"
"__m128i acc = _mm_set_epi32(0, ctx->hi, 0, ctx->lo);\n"
"__m128i result = _mm_sub_epi32(acc, _mm_unpacklo_epi16(sum, _mm_srai_epi16(sum, 15)));\n"
"ctx->r[{}] = result;\n"
"ctx->lo = _mm_extract_epi32(result, 0);\n"
"ctx->hi = _mm_extract_epi32(result, 1); }}",
inst.rt, inst.rt, inst.rs, inst.rs, inst.rd);
case MMI2_PEXEH:
return translatePEXEH(inst);
@@ -1352,7 +1416,11 @@ namespace ps2recomp
inst.rd, inst.rs, inst.rt);
case MMI3_PMADDUW:
return fmt::format("// PS2_PMADDUW - Packed Multiply-Add Unsigned Word");
return fmt::format("{{ uint64_t result = (uint64_t)(((uint64_t)ctx->hi << 32) | ctx->lo) + "
"(uint64_t)_mm_extract_epi32(ctx->r[{}], 0) * (uint64_t)_mm_extract_epi32(ctx->r[{}], 0); "
"ctx->lo = (uint32_t)result; ctx->hi = (uint32_t)(result >> 32); "
"ctx->r[{}] = _mm_set_epi32(0, 0, ctx->hi, ctx->lo); }}",
inst.rs, inst.rt, inst.rd);
case MMI3_PSRAVW:
return fmt::format("ctx->r[{}] = PS2_PSRAVW(ctx->r[{}], ctx->r[{}]);",
@@ -1380,6 +1448,12 @@ namespace ps2recomp
case MMI3_PEXCW:
return translatePEXCW(inst);
case MMI3_PMTHI:
return translatePMTHI(inst);
case MMI3_PMTLO:
return translatePMTLO(inst);
default:
return fmt::format("// Unhandled MMI3 function: 0x{:X}", inst.sa);
}
@@ -2258,6 +2332,16 @@ namespace ps2recomp
inst.rs, inst.rd);
}
std::string CodeGenerator::translatePMTHI(const Instruction &inst)
{
return fmt::format("ctx->hi = _mm_extract_epi32(ctx->r[{}], 0);", inst.rs);
}
std::string CodeGenerator::translatePMTLO(const Instruction &inst)
{
return fmt::format("ctx->lo = _mm_extract_epi32(ctx->r[{}], 0);", inst.rs);
}
std::string CodeGenerator::generateJumpTableSwitch(const Instruction &inst, uint32_t tableAddress,
const std::vector<JumpTableEntry> &entries)
{