10
externals/powah/data2code.c
vendored
10
externals/powah/data2code.c
vendored
@@ -43,6 +43,7 @@ int main(int argc, char *argv[]) {
|
||||
};
|
||||
|
||||
#define OP_EXT ((i_opcode << 26) | (i_extopc << 1))
|
||||
#define OP_EXT_XS ((i_opcode << 26) | (i_extopc << 2))
|
||||
|
||||
if (strchr(mem, '[') != NULL) *strchr(mem, '[') = '\0';
|
||||
if (strchr(mem, '.') != NULL) *strchr(mem, '.') = '_';
|
||||
@@ -186,16 +187,17 @@ int main(int argc, char *argv[]) {
|
||||
"}\n"
|
||||
, mem, form, OP_EXT);
|
||||
} else if (!strcmp(form, "XS")) {
|
||||
/* HUGE DIFFERENCE DO NOT REMOVE */
|
||||
printf(
|
||||
"void %s(GPR const rt, GPR const ra, uint32_t sh) {"
|
||||
" emit_%s(0x%08x, rt, ra, sh, false); "
|
||||
" emit_%s(0x%08x, ra, rt, sh, false); "
|
||||
"}\n"
|
||||
, mem, form, OP_EXT);
|
||||
, mem, form, OP_EXT_XS);
|
||||
printf(
|
||||
"void %s_(GPR const rt, GPR const ra, uint32_t sh) {"
|
||||
" emit_%s(0x%08x, rt, ra, sh, true); "
|
||||
" emit_%s(0x%08x, ra, rt, sh, true); "
|
||||
"}\n"
|
||||
, mem, form, OP_EXT);
|
||||
, mem, form, OP_EXT_XS);
|
||||
} else if (!strcmp(form, "XL")) {
|
||||
if (!strcmp(mem, "BCLR")) {
|
||||
printf(
|
||||
|
||||
8
externals/powah/powah_emit.hpp
vendored
8
externals/powah/powah_emit.hpp
vendored
@@ -211,10 +211,10 @@ struct Context {
|
||||
}
|
||||
void emit_XS(uint32_t op, GPR const rt, GPR const ra, uint32_t sh, bool rc) {
|
||||
base[offset++] = (op |
|
||||
bitExt(rt.index, 6, 5)
|
||||
| bitExt(ra.index, 11, 5)
|
||||
| bitExt(sh, 16, 5)
|
||||
| bitExt(sh >> 5, 30, 1)
|
||||
((rt.index & 0x1f) << 16)
|
||||
| ((ra.index & 0x1f) << 21)
|
||||
| ((sh & 0x1f) << 11)
|
||||
| ((sh >> 4) & 0x02)
|
||||
| bitExt(rc, 31, 1)
|
||||
);
|
||||
}
|
||||
|
||||
4
externals/powah/powah_gen_base.hpp
vendored
4
externals/powah/powah_gen_base.hpp
vendored
@@ -384,8 +384,8 @@ void SLW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000030, ra, rt,
|
||||
void SLW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000030, ra, rt, rb, true); }
|
||||
void SRAD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000634, ra, rt, rb, false); }
|
||||
void SRAD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000634, ra, rt, rb, true); }
|
||||
void SRADI(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c00033a, rt, ra, sh, false); }
|
||||
void SRADI_(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c00033a, rt, ra, sh, true); }
|
||||
void SRADI(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, ra, rt, sh, false); }
|
||||
void SRADI_(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, ra, rt, sh, true); }
|
||||
void SRD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000436, ra, rt, rb, false); }
|
||||
void SRD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000436, ra, rt, rb, true); }
|
||||
void SRAW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000630, ra, rt, rb, false); }
|
||||
|
||||
37
externals/powah/tests.cpp
vendored
37
externals/powah/tests.cpp
vendored
@@ -174,6 +174,43 @@ TEST_CASE("ppc64: rlwimi madness", "[ppc64]") {
|
||||
REQUIRE(data[7] == EB32(0x0e004379));
|
||||
}
|
||||
|
||||
/*
|
||||
0: 78 1b 68 7c mr 8, 3
|
||||
4: 38 28 83 7c and 3, 4, 5
|
||||
8: 74 00 6a 7c cntlzd 10, 3
|
||||
c: 76 06 69 7c sradi 9, 3, 32
|
||||
10: 82 d1 4a 79 rldicl 10, 10, 58, 6
|
||||
14: 00 00 29 55 rlwinm 9, 9, 0, 0, 0
|
||||
18: 64 f0 4a 79 sldi 10, 10, 30
|
||||
1c: 78 53 29 7d or 9, 9, 10
|
||||
20: 00 00 28 f9 std 9, 0(8)
|
||||
24: 20 00 80 4e blr
|
||||
*/
|
||||
TEST_CASE("ppc64: functor-2", "[ppc64]") {
|
||||
std::vector<uint32_t> data(64);
|
||||
powah::Context ctx(data.data(), data.size());
|
||||
ctx.MR(powah::R8, powah::R3);
|
||||
ctx.AND(powah::R3, powah::R4, powah::R5);
|
||||
ctx.CNTLZD(powah::R10, powah::R3);
|
||||
ctx.SRADI(powah::R9, powah::R3, 32);
|
||||
ctx.RLDICL(powah::R10, powah::R10, 58, 6);
|
||||
ctx.RLWINM(powah::R9, powah::R9, 0, 0, 0);
|
||||
ctx.SLDI(powah::R10, powah::R10, 30);
|
||||
ctx.OR(powah::R9, powah::R9, powah::R10);
|
||||
ctx.STD(powah::R9, powah::R8, 8);
|
||||
ctx.BLR();
|
||||
REQUIRE(data[0] == EB32(0x781b687c));
|
||||
REQUIRE(data[1] == EB32(0x3828837c));
|
||||
REQUIRE(data[2] == EB32(0x74006a7c));
|
||||
REQUIRE(data[3] == EB32(0x7606697c));
|
||||
REQUIRE(data[4] == EB32(0x82d14a79));
|
||||
REQUIRE(data[5] == EB32(0x00002955));
|
||||
REQUIRE(data[6] == EB32(0x64f04a79));
|
||||
REQUIRE(data[7] == EB32(0x7853297d));
|
||||
REQUIRE(data[8] == EB32(0x000028f9));
|
||||
REQUIRE(data[9] == EB32(0x2000804e));
|
||||
}
|
||||
|
||||
TEST_CASE("ppc64: functor-1", "[ppc64]") {
|
||||
std::vector<uint32_t> data(64);
|
||||
powah::Context ctx(data.data(), data.size());
|
||||
|
||||
@@ -562,7 +562,9 @@ void EmitIR<IR::Opcode::And32>(powah::Context& code, EmitContext& ctx, IR::Inst*
|
||||
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
|
||||
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
|
||||
code.RLDICL(result, src_a, 0, 32); // Truncate
|
||||
code.AND_(result, result, src_b);
|
||||
code.AND(result, result, src_b);
|
||||
auto const tmp = ctx.reg_alloc.ScratchGpr();
|
||||
code.ANDI_(tmp, result, 0);
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user