Skip to content

Commit fea1f67

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

File tree

1 file changed

+64
-2
lines changed

1 file changed

+64
-2
lines changed

PowerRecomp/recompiler.cpp

Lines changed: 64 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,20 @@ 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+
{
722+
constexpr std::string_view fields[] = { "lt", "gt", "eq", "so" };
723+
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]);
724+
break;
725+
}
726+
727+
case PPC_INST_CRORC:
728+
{
729+
constexpr std::string_view fields[] = { "lt", "gt", "eq", "so" };
730+
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]);
731+
break;
732+
}
733+
687734
case PPC_INST_DB16CYC:
688735
// no op
689736
break;
@@ -744,6 +791,13 @@ bool Recompiler::Recompile(
744791
// no op
745792
break;
746793

794+
case PPC_INST_EQV:
795+
println("\t{}.u64 = ~({}.u32 ^ {}.u32);", r(insn.operands[0]), r(insn.operands[1]), r(insn.operands[2]));
796+
if (strchr(insn.opcode->name, '.'))
797+
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
798+
799+
break;
800+
747801
case PPC_INST_EXTSB:
748802
println("\t{}.s64 = {}.s8;", r(insn.operands[0]), r(insn.operands[1]));
749803
if (strchr(insn.opcode->name, '.'))
@@ -1711,6 +1765,14 @@ bool Recompiler::Recompile(
17111765
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
17121766
break;
17131767

1768+
case PPC_INST_SUBFZE:
1769+
println("\t{}.u8 = (~{}.u32 < ~{}.u32) | (~{}.u32 + {}.ca < {}.ca);", temp(), r(insn.operands[1]), r(insn.operands[1]), r(insn.operands[1]), xer(), xer());
1770+
println("\t{}.u64 = ~{}.u64 + {}.ca;", r(insn.operands[0]), r(insn.operands[1]), xer());
1771+
println("\t{}.ca = {}.u8;", xer(), temp());
1772+
if (strchr(insn.opcode->name, '.'))
1773+
println("\t{}.compare<int32_t>({}.s32, 0, {});", cr(0), r(insn.operands[0]), xer());
1774+
break;
1775+
17141776
case PPC_INST_SUBFIC:
17151777
println("\t{}.ca = {}.u32 <= {};", xer(), r(insn.operands[1]), insn.operands[2]);
17161778
println("\t{}.s64 = {} - {}.s64;", r(insn.operands[0]), int32_t(insn.operands[2]), r(insn.operands[1]));

0 commit comments

Comments
 (0)