Skip to content

Commit 254a97c

Browse files
committed
add more basic instructions
1 parent 7ef5da6 commit 254a97c

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

PowerRecomp/recompiler.cpp

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,13 @@ bool Recompiler::Recompile(
419419
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
420420
break;
421421

422+
case PPC_INST_ADDC:
423+
println("\t{}.ca = {}.u32 >= ~{}.u32;", xer(), r(insn.operands[2]), r(insn.operands[1]));
424+
println("\t{}.u64 = {}.u64 + {}.u64;", r(insn.operands[0]), r(insn.operands[1]), r(insn.operands[2]));
425+
if (strchr(insn.opcode->name, '.'))
426+
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
427+
break;
428+
422429
case PPC_INST_ADDE:
423430
println("\t{}.u8 = ({}.u32 + {}.u32 < {}.u32) | ({}.u32 + {}.u32 + {}.ca < {}.ca);", temp(), r(insn.operands[1]), r(insn.operands[2]), r(insn.operands[1]), r(insn.operands[1]), r(insn.operands[2]), xer(), xer());
424431
println("\t{}.u64 = {}.u64 + {}.u64 + {}.ca;", r(insn.operands[0]), r(insn.operands[1]), r(insn.operands[2]), xer());
@@ -427,6 +434,14 @@ bool Recompiler::Recompile(
427434
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
428435
break;
429436

437+
case PPC_INST_ADDME:
438+
println("\t{}.u8 = ({}.u32 - 1 < {}.u32) | ({}.u32 - 1 + {}.ca < {}.ca);", temp(), r(insn.operands[1]), r(insn.operands[1]), r(insn.operands[1]), xer(), xer());
439+
println("\t{}.u64 = {}.u64 - 1 + {}.ca;", r(insn.operands[0]), r(insn.operands[1]), xer());
440+
println("\t{}.ca = {}.u8;", xer(), temp());
441+
if (strchr(insn.opcode->name, '.'))
442+
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
443+
break;
444+
430445
case PPC_INST_ADDI:
431446
print("\t{}.s64 = ", r(insn.operands[0]));
432447
if (insn.operands[1] != 0)
@@ -540,6 +555,14 @@ bool Recompiler::Recompile(
540555
println("\tif ({}.u32 == 0) goto loc_{:X};", ctr(), insn.operands[0]);
541556
break;
542557

558+
case PPC_INST_BDZF:
559+
{
560+
constexpr std::string_view fields[] = { "lt", "gt", "eq", "so" };
561+
println("\t--{}.u64;", ctr());
562+
println("\tif ({}.u32 == 0 && !{}.{}) goto loc_{:X};", ctr(), cr(insn.operands[0] / 4), fields[insn.operands[0] % 4], insn.operands[1]);
563+
break;
564+
}
565+
543566
case PPC_INST_BDZLR:
544567
println("\t--{}.u64;", ctr());
545568
println("\tif ({}.u32 == 0) return;", ctr(), insn.operands[0]);
@@ -551,10 +574,20 @@ bool Recompiler::Recompile(
551574
break;
552575

553576
case PPC_INST_BDNZF:
554-
// NOTE: assuming eq here as a shortcut because all the instructions in the game do that
577+
{
578+
constexpr std::string_view fields[] = { "lt", "gt", "eq", "so" };
579+
println("\t--{}.u64;", ctr());
580+
println("\tif ({}.u32 != 0 && !{}.{}) goto loc_{:X};", ctr(), cr(insn.operands[0] / 4), fields[insn.operands[0] % 4], insn.operands[1]);
581+
break;
582+
}
583+
584+
case PPC_INST_BDNZT:
585+
{
586+
constexpr std::string_view fields[] = { "lt", "gt", "eq", "so" };
555587
println("\t--{}.u64;", ctr());
556-
println("\tif ({}.u32 != 0 && !{}.eq) goto loc_{:X};", ctr(), cr(insn.operands[0] / 4), insn.operands[1]);
588+
println("\tif ({}.u32 != 0 && {}.{}) goto loc_{:X};", ctr(), cr(insn.operands[0] / 4), fields[insn.operands[0] % 4], insn.operands[1]);
557589
break;
590+
}
558591

559592
case PPC_INST_BEQ:
560593
printConditionalBranch(false, "eq");
@@ -684,6 +717,16 @@ bool Recompiler::Recompile(
684717
println("\t{}.u64 = __lzcnt({}.u32);", r(insn.operands[0]), r(insn.operands[1]));
685718
break;
686719

720+
case PPC_INST_CROR:
721+
constexpr std::string_view fields[] = { "lt", "gt", "eq", "so" };
722+
println("\t{}.{} = {}.{} | {}.{};", cr(insn.operands[0] / 4), fields[insn.operands[0] % 4], cr(insn.operands[1] / 4), fields[insn.operands[1] % 4], cr(insn.operands[2] / 4), fields[insn.operands[2] % 4]);
723+
break;
724+
725+
case PPC_INST_CRORC:
726+
constexpr std::string_view fields[] = { "lt", "gt", "eq", "so" };
727+
println("\t{}.{} = {}.{} | (~{}.{} & 1);", cr(insn.operands[0] / 4), fields[insn.operands[0] % 4], cr(insn.operands[1] / 4), fields[insn.operands[1] % 4], cr(insn.operands[2] / 4), fields[insn.operands[2] % 4]);
728+
break;
729+
687730
case PPC_INST_DB16CYC:
688731
// no op
689732
break;
@@ -744,6 +787,13 @@ bool Recompiler::Recompile(
744787
// no op
745788
break;
746789

790+
case PPC_INST_EQV:
791+
println("\t{}.u64 = ~({}.u32 ^ {}.u32);", r(insn.operands[0]), r(insn.operands[1]), r(insn.operands[2]));
792+
if (strchr(insn.opcode->name, '.'))
793+
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
794+
795+
break;
796+
747797
case PPC_INST_EXTSB:
748798
println("\t{}.s64 = {}.s8;", r(insn.operands[0]), r(insn.operands[1]));
749799
if (strchr(insn.opcode->name, '.'))
@@ -1711,6 +1761,14 @@ bool Recompiler::Recompile(
17111761
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
17121762
break;
17131763

1764+
case PPC_INST_SUBFZE:
1765+
println("\t{}.u8 = (~{}.u32 < ~{}.u32) | (~{}.u32 + {}.ca < {}.ca);", temp(), r(insn.operands[1]), r(insn.operands[1]), r(insn.operands[1]), xer(), xer());
1766+
println("\t{}.u64 = ~{}.u64 + {}.ca;", r(insn.operands[0]), r(insn.operands[1]), xer());
1767+
println("\t{}.ca = {}.u8;", xer(), temp());
1768+
if (strchr(insn.opcode->name, '.'))
1769+
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
1770+
break;
1771+
17141772
case PPC_INST_SUBFIC:
17151773
println("\t{}.ca = {}.u32 <= {};", xer(), r(insn.operands[1]), insn.operands[2]);
17161774
println("\t{}.s64 = {} - {}.s64;", r(insn.operands[0]), int32_t(insn.operands[2]), r(insn.operands[1]));

0 commit comments

Comments
 (0)