diff --git a/externals/powah/powah_gen_base.hpp b/externals/powah/powah_gen_base.hpp index 2fcc01ea64..6852da14f4 100644 --- a/externals/powah/powah_gen_base.hpp +++ b/externals/powah/powah_gen_base.hpp @@ -62,12 +62,32 @@ void BCCTR(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000420, bt.i void BCCTRL(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, cond2offset(ba), bb.index, true); } void BCLR(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, ba.index, bb.index, false); } void BCLRL(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, ba.index, bb.index, true); } -void BCLR(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, cond2offset(ba), bb.index, false); } -void BCLRL(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, cond2offset(ba), bb.index, true); } +void BLTLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 0, 0, false); } +void BLTLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 0, 0, true); } +void BLELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, false); } +void BLELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, true); } +void BNGLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, false); } +void BNGLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, true); } +void BEQLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 2, 0, false); } +void BEQLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 2, 0, true); } +void BGELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, false); } +void BGELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, true); } +void BNLLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, false); } +void BNLLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, true); } +void BGTLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 1, 0, false); } +void BGTLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 1, 0, true); } +void BNELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 2, 0, false); } +void BNELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 2, 0, true); } +void BSOLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, false); } +void BSOLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, true); } +void BUNLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, false); } +void BUNLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, true); } +void BNSLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 3, 0, false); } +void BNSLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 3, 0, true); } void CMP(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000000, GPR{(bf << 2) | l}, ra, rb, false); } -void CMPI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x2c000000, ra, GPR{(bf << 2) | l}, d); } -void CMPL(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000000, GPR{(bf << 2) | l}, ra, rb, false); } -void CMPLI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x28000000, ra, GPR{(bf << 2) | l}, d); } +void CMPI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x2c000000, GPR{(bf << 2) | l}, ra, d); } +void CMPL(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000040, GPR{(bf << 2) | l}, ra, rb, false); } +void CMPLI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x28000000, GPR{(bf << 2) | l}, ra, d); } void CNTLZD(GPR const rt, GPR const ra) { emit_X(0x7c000074, ra, rt, R0, false); } void CNTLZD_(GPR const rt, GPR const ra) { emit_X(0x7c000074, ra, rt, R0, true); } void CNTLZW(GPR const rt, GPR const ra) { emit_X(0x7c000034, ra, rt, R0, false); } diff --git a/externals/powah/tests.cpp b/externals/powah/tests.cpp index c60ce0c724..65baedb47b 100644 --- a/externals/powah/tests.cpp +++ b/externals/powah/tests.cpp @@ -153,6 +153,69 @@ TEST_CASE("ppc64: branch-backwards", "[ppc64]") { REQUIRE(data[1] == EB32(0xfcffff4b)); } +TEST_CASE("ppc64: rlwimi madness", "[ppc64]") { + std::vector data(64); + powah::Context ctx(data.data(), data.size()); + ctx.ROTLWI(powah::R10, powah::R3, 24); + ctx.SRDI(powah::R9, powah::R3, 32); + ctx.RLWIMI(powah::R10, powah::R3, 8, 8, 15); + ctx.RLWIMI(powah::R10, powah::R3, 8, 24, 31); + ctx.ROTLWI(powah::R3, powah::R9, 24); + ctx.RLWIMI(powah::R3, powah::R9, 8, 8, 15); + ctx.RLWIMI(powah::R3, powah::R9, 8, 24, 31); + ctx.RLDIMI(powah::R3, powah::R10, 32, 0); + REQUIRE(data[0] == EB32(0x3ec06a54)); + REQUIRE(data[1] == EB32(0x22006978)); + REQUIRE(data[2] == EB32(0x1e426a50)); + REQUIRE(data[3] == EB32(0x3e466a50)); + REQUIRE(data[4] == EB32(0x3ec02355)); + REQUIRE(data[5] == EB32(0x1e422351)); + REQUIRE(data[6] == EB32(0x3e462351)); + REQUIRE(data[7] == EB32(0x0e004379)); +} + +TEST_CASE("ppc64: functor-1", "[ppc64]") { + std::vector data(64); + powah::Context ctx(data.data(), data.size()); + powah::Label l_4 = ctx.DefineLabel(); + powah::Label l_7 = ctx.DefineLabel(); + ctx.CMPLD(powah::CR0, powah::R3, powah::R4); + ctx.MR(powah::R9, powah::R3); + ctx.BGT(powah::CR0, l_7); + ctx.CMPLDI(powah::CR0, powah::R3, 3781); + ctx.LI(powah::R3, 1); + ctx.BGTLR(powah::CR0); + ctx.CMPLD(powah::CR0, powah::R9, powah::R5); + ctx.BLE(powah::CR0, l_4); + ctx.SUBF(powah::R5, powah::R9, powah::R5); + ctx.XOR(powah::R3, powah::R5, powah::R4); + ctx.BLR(); + ctx.LABEL(l_4); + ctx.ADD(powah::R5, powah::R4, powah::R5); + ctx.ADD(powah::R3, powah::R5, powah::R9); + ctx.BLR(); + ctx.LABEL(l_7); + ctx.ADD(powah::R3, powah::R4, powah::R5); + ctx.BLR(); + ctx.ApplyRelocs(); + REQUIRE(data[0] == EB32(0x4020237c)); + REQUIRE(data[1] == EB32(0x781b697c)); + REQUIRE(data[2] == EB32(0x30008141)); + REQUIRE(data[3] == EB32(0xc50e2328)); + REQUIRE(data[4] == EB32(0x01006038)); + REQUIRE(data[5] == EB32(0x2000814d)); + REQUIRE(data[6] == EB32(0x4028297c)); + REQUIRE(data[7] == EB32(0x10008140)); + REQUIRE(data[8] == EB32(0x5028a97c)); + REQUIRE(data[9] == EB32(0x7822a37c)); + REQUIRE(data[10] == EB32(0x2000804e)); + REQUIRE(data[11] == EB32(0x142aa47c)); + REQUIRE(data[12] == EB32(0x144a657c)); + REQUIRE(data[13] == EB32(0x2000804e)); + REQUIRE(data[14] == EB32(0x142a647c)); + REQUIRE(data[15] == EB32(0x2000804e)); +} + #if defined(ARCHITECTURE_ppc64) /* 0: d619637c mullw 3, 3, 3