mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-10 14:07:25 +00:00
Vendored
+22
-22
@@ -26,20 +26,20 @@ int main(int argc, char *argv[]) {
|
|||||||
*opc++ = '\0';
|
*opc++ = '\0';
|
||||||
char *sec = strchr(opc, ',');
|
char *sec = strchr(opc, ',');
|
||||||
if (sec) {
|
if (sec) {
|
||||||
struct b_info { const char *s; int o; } infos[] = {
|
struct b_info { const char *s; int o; int p; } infos[] = {
|
||||||
{"",1},
|
{"",1,0},
|
||||||
{"LT",1},
|
{"LT",1,12},
|
||||||
{"LE",2},
|
{"LE",2,4},
|
||||||
{"NG",2},
|
{"NG",2,4},
|
||||||
{"EQ",3},
|
{"EQ",3,12},
|
||||||
{"GE",1},
|
{"GE",1,4},
|
||||||
{"NL",1},
|
{"NL",1,4},
|
||||||
{"GT",2},
|
{"GT",2,12},
|
||||||
{"NE",3},
|
{"NE",3,4},
|
||||||
{"SO",4},
|
{"SO",4,12},
|
||||||
{"UN",4},
|
{"UN",4,12},
|
||||||
{"NS",4},
|
{"NS",4,4},
|
||||||
{"NU",4},
|
{"NU",4,4},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (strchr(mem, '[') != NULL) *strchr(mem, '[') = '\0';
|
if (strchr(mem, '[') != NULL) *strchr(mem, '[') = '\0';
|
||||||
@@ -103,7 +103,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|| !strcmp(mem, "CMP")) {
|
|| !strcmp(mem, "CMP")) {
|
||||||
printf(
|
printf(
|
||||||
"void %s(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) {"
|
"void %s(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) {"
|
||||||
" emit_%s(0x%08x, GPR{(bf << 2) | l}, ra, rb, false); "
|
" emit_%s(0x%08x, ra, GPR{(bf << 2) | l}, rb, false); "
|
||||||
"}\n"
|
"}\n"
|
||||||
, mem, form, i_opcode << 26);
|
, mem, form, i_opcode << 26);
|
||||||
} else if (!strcmp(mem, "CNTLZD") || !strcmp(mem, "CNTLZW")
|
} else if (!strcmp(mem, "CNTLZD") || !strcmp(mem, "CNTLZW")
|
||||||
@@ -133,26 +133,26 @@ int main(int argc, char *argv[]) {
|
|||||||
} else if (!strcmp(form, "I")) {
|
} else if (!strcmp(form, "I")) {
|
||||||
printf(
|
printf(
|
||||||
"void %s(Label const& i) {"
|
"void %s(Label const& i) {"
|
||||||
" emit_reloc_%s(0x%08x, i); "
|
" emit_reloc_%s(0x%08x, i, false); "
|
||||||
"}\n"
|
"}\n"
|
||||||
, mem, form, i_opcode << 26);
|
, mem, form, i_opcode << 26);
|
||||||
printf(
|
printf(
|
||||||
"void %sL(Label const& i) {"
|
"void %sL(Label const& i) {"
|
||||||
" emit_reloc_%s(0x%08x, i); "
|
" emit_reloc_%s(0x%08x, i, true); "
|
||||||
"}\n"
|
"}\n"
|
||||||
, mem, form, i_opcode << 26);
|
, mem, form, i_opcode << 26);
|
||||||
} else if (!strcmp(form, "B")) {
|
} else if (!strcmp(form, "B")) {
|
||||||
for (int i = 0; i < 12; ++i) {
|
for (int i = 0; i < 12; ++i) {
|
||||||
printf(
|
printf(
|
||||||
"void %s%s(CPR const cr, Label const& i) {"
|
"void %s%s(CPR const cr, Label const& i) {"
|
||||||
" emit_reloc_%s(0x%08x, cr.index + %i, i, false); "
|
" emit_reloc_%s(0x%08x, %i, cr.index + %i, i, false); "
|
||||||
"}\n"
|
"}\n"
|
||||||
, mem, infos[i].s, form, i_opcode << 26, infos[i].o);
|
, mem, infos[i].s, form, i_opcode << 26, infos[i].p, infos[i].o - 1);
|
||||||
printf(
|
printf(
|
||||||
"void %s%sL(CPR const cr, Label const& i) {"
|
"void %s%sL(CPR const cr, Label const& i) {"
|
||||||
" emit_reloc_%s(0x%08x, cr.index + %i, i, true); "
|
" emit_reloc_%s(0x%08x, %i, cr.index + %i, i, true); "
|
||||||
"}\n"
|
"}\n"
|
||||||
, mem, infos[i].s, form, i_opcode << 26, infos[i].o);
|
, mem, infos[i].s, form, i_opcode << 26, infos[i].p, infos[i].o - 1);
|
||||||
if (!strcmp(mem, "BC")) mem[1] = '\0';
|
if (!strcmp(mem, "BC")) mem[1] = '\0';
|
||||||
}
|
}
|
||||||
} else if (!strcmp(form, "D")) {
|
} else if (!strcmp(form, "D")) {
|
||||||
@@ -160,7 +160,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|| !strcmp(mem, "CMPI")) {
|
|| !strcmp(mem, "CMPI")) {
|
||||||
printf(
|
printf(
|
||||||
"void %s(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) {"
|
"void %s(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) {"
|
||||||
" emit_%s(0x%08x, GPR{(bf << 2) | l}, ra, d); "
|
" emit_%s(0x%08x, ra, GPR{(bf << 2) | l}, d); "
|
||||||
"}\n"
|
"}\n"
|
||||||
, mem, form, i_opcode << 26);
|
, mem, form, i_opcode << 26);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Vendored
+69
-37
@@ -110,6 +110,15 @@ constexpr inline CPR CR5{20};
|
|||||||
constexpr inline CPR CR6{24};
|
constexpr inline CPR CR6{24};
|
||||||
constexpr inline CPR CR7{28};
|
constexpr inline CPR CR7{28};
|
||||||
|
|
||||||
|
enum class RelocKind : uint8_t {
|
||||||
|
FormB,
|
||||||
|
FormI,
|
||||||
|
};
|
||||||
|
struct RelocInfo {
|
||||||
|
uint32_t offset;
|
||||||
|
RelocKind kind;
|
||||||
|
};
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
Context() = default;
|
Context() = default;
|
||||||
Context(void* ptr, size_t size)
|
Context(void* ptr, size_t size)
|
||||||
@@ -121,10 +130,26 @@ struct Context {
|
|||||||
~Context() = default;
|
~Context() = default;
|
||||||
|
|
||||||
std::vector<uint32_t> labels;
|
std::vector<uint32_t> labels;
|
||||||
|
std::vector<std::pair<uint32_t, RelocInfo>> relocs;
|
||||||
|
|
||||||
Label DefineLabel() {
|
Label DefineLabel() {
|
||||||
labels.push_back(0);
|
labels.push_back(0);
|
||||||
return Label{ uint32_t(labels.size()) };
|
return Label{ uint32_t(labels.size() - 1) };
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyRelocs() {
|
||||||
|
for (auto const [index, info] : relocs) {
|
||||||
|
assert(labels[index] != 0); //label must have an addr
|
||||||
|
switch (info.kind) {
|
||||||
|
case RelocKind::FormB:
|
||||||
|
base[info.offset] |= bitExt(labels[index] - info.offset, 16, 14);
|
||||||
|
break;
|
||||||
|
case RelocKind::FormI:
|
||||||
|
base[info.offset] |= bitExt(labels[index] - info.offset, 6, 24);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relocs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LABEL(Label l) {
|
void LABEL(Label l) {
|
||||||
@@ -155,16 +180,16 @@ struct Context {
|
|||||||
return (value & mask) << (32 - (n + offs));
|
return (value & mask) << (32 - (n + offs));
|
||||||
}
|
}
|
||||||
void emit_XO(uint32_t op, GPR const rt, GPR const ra, GPR const rb, bool oe, bool rc) {
|
void emit_XO(uint32_t op, GPR const rt, GPR const ra, GPR const rb, bool oe, bool rc) {
|
||||||
(void)op;
|
base[offset++] = (op |
|
||||||
(void)rt;
|
bitExt(rt.index, 6, 5)
|
||||||
(void)ra;
|
| bitExt(ra.index, 11, 5)
|
||||||
(void)rb;
|
| bitExt(rb.index, 16, 5)
|
||||||
(void)oe;
|
| bitExt(oe, 21, 1)
|
||||||
(void)rc;
|
| bitExt(rc, 31, 1)
|
||||||
std::abort();
|
);
|
||||||
}
|
}
|
||||||
void emit_D(uint32_t op, GPR const rt, GPR const ra, uint32_t d) {
|
void emit_D(uint32_t op, GPR const rt, GPR const ra, uint32_t d) {
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
(op == 0x74000000
|
(op == 0x74000000
|
||||||
? (bitExt(ra.index, 6, 5) | bitExt(rt.index, 11, 5))
|
? (bitExt(ra.index, 6, 5) | bitExt(rt.index, 11, 5))
|
||||||
: (bitExt(rt.index, 6, 5) | bitExt(ra.index, 11, 5)))
|
: (bitExt(rt.index, 6, 5) | bitExt(ra.index, 11, 5)))
|
||||||
@@ -172,7 +197,7 @@ struct Context {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
void emit_X(uint32_t op, GPR const ra, GPR const rt, GPR const rb, bool rc) {
|
void emit_X(uint32_t op, GPR const ra, GPR const rt, GPR const rb, bool rc) {
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
bitExt(rt.index, 6, 5)
|
bitExt(rt.index, 6, 5)
|
||||||
| bitExt(ra.index, 11, 5)
|
| bitExt(ra.index, 11, 5)
|
||||||
| bitExt(rb.index, 16, 5)
|
| bitExt(rb.index, 16, 5)
|
||||||
@@ -180,7 +205,7 @@ struct Context {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
void emit_XS(uint32_t op, GPR const rt, GPR const ra, uint32_t sh, bool rc) {
|
void emit_XS(uint32_t op, GPR const rt, GPR const ra, uint32_t sh, bool rc) {
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
bitExt(rt.index, 6, 5)
|
bitExt(rt.index, 6, 5)
|
||||||
| bitExt(ra.index, 11, 5)
|
| bitExt(ra.index, 11, 5)
|
||||||
| bitExt(sh, 16, 5)
|
| bitExt(sh, 16, 5)
|
||||||
@@ -188,20 +213,22 @@ struct Context {
|
|||||||
| bitExt(rc, 31, 1)
|
| bitExt(rc, 31, 1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
void emit_reloc_I(uint32_t op, Label const& l) {
|
void emit_reloc_I(uint32_t op, Label const& l, bool lk) {
|
||||||
(void)op;
|
relocs.emplace_back(l.index, RelocInfo{ offset, RelocKind::FormI });
|
||||||
(void)l;
|
base[offset++] = (op |
|
||||||
std::abort();
|
bitExt(lk, 31, 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
void emit_reloc_B(uint32_t op, uint32_t cri, Label const& l, bool lk) {
|
void emit_reloc_B(uint32_t op, uint32_t bo, uint32_t cri, Label const& l, bool lk) {
|
||||||
(void)op;
|
relocs.emplace_back(l.index, RelocInfo{ offset, RelocKind::FormB });
|
||||||
(void)cri;
|
base[offset++] = (op |
|
||||||
(void)l;
|
bitExt(bo, 6, 5)
|
||||||
(void)lk;
|
| bitExt(cri, 11, 5)
|
||||||
std::abort();
|
| bitExt(lk, 31, 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
void emit_XL(uint32_t op, uint32_t bt, uint32_t ba, uint32_t bb, bool lk) {
|
void emit_XL(uint32_t op, uint32_t bt, uint32_t ba, uint32_t bb, bool lk) {
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
bitExt(bt, 6, 5)
|
bitExt(bt, 6, 5)
|
||||||
| bitExt(ba, 11, 5)
|
| bitExt(ba, 11, 5)
|
||||||
| bitExt(bb, 16, 5)
|
| bitExt(bb, 16, 5)
|
||||||
@@ -209,7 +236,7 @@ struct Context {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
void emit_A(uint32_t op, FPR const frt, FPR const fra, FPR const frb, FPR const frc, bool rc) {
|
void emit_A(uint32_t op, FPR const frt, FPR const fra, FPR const frb, FPR const frc, bool rc) {
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
bitExt(frt.index, 6, 5)
|
bitExt(frt.index, 6, 5)
|
||||||
| bitExt(fra.index, 11, 5)
|
| bitExt(fra.index, 11, 5)
|
||||||
| bitExt(frb.index, 16, 5)
|
| bitExt(frb.index, 16, 5)
|
||||||
@@ -219,7 +246,7 @@ struct Context {
|
|||||||
}
|
}
|
||||||
void emit_DS(uint32_t op, GPR const rt, GPR const ra, uint32_t d) {
|
void emit_DS(uint32_t op, GPR const rt, GPR const ra, uint32_t d) {
|
||||||
//assert(d & 0x03 == 0);
|
//assert(d & 0x03 == 0);
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
bitExt(rt.index, 6, 5)
|
bitExt(rt.index, 6, 5)
|
||||||
| bitExt(ra.index, 11, 5)
|
| bitExt(ra.index, 11, 5)
|
||||||
| bitExt(d >> 2, 16, 14)
|
| bitExt(d >> 2, 16, 14)
|
||||||
@@ -237,7 +264,7 @@ struct Context {
|
|||||||
}
|
}
|
||||||
void emit_MD(uint32_t op, GPR const rs, GPR const ra, GPR const rb, uint32_t mb, bool rc) {
|
void emit_MD(uint32_t op, GPR const rs, GPR const ra, GPR const rb, uint32_t mb, bool rc) {
|
||||||
assert(mb <= 0x3f);
|
assert(mb <= 0x3f);
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
bitExt(ra.index, 6, 5)
|
bitExt(ra.index, 6, 5)
|
||||||
| bitExt(rs.index, 11, 5)
|
| bitExt(rs.index, 11, 5)
|
||||||
| bitExt(rb.index, 16, 5)
|
| bitExt(rb.index, 16, 5)
|
||||||
@@ -247,7 +274,7 @@ struct Context {
|
|||||||
}
|
}
|
||||||
void emit_MD(uint32_t op, GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, bool rc) {
|
void emit_MD(uint32_t op, GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, bool rc) {
|
||||||
assert(sh <= 0x3f && mb <= 0x3f);
|
assert(sh <= 0x3f && mb <= 0x3f);
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
bitExt(ra.index, 6, 5)
|
bitExt(ra.index, 6, 5)
|
||||||
| bitExt(rs.index, 11, 5)
|
| bitExt(rs.index, 11, 5)
|
||||||
| ((mb & 0x1f) << 6) | (mb & 0x20)
|
| ((mb & 0x1f) << 6) | (mb & 0x20)
|
||||||
@@ -256,7 +283,7 @@ struct Context {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
void emit_MDS(uint32_t op, GPR const rs, GPR const ra, GPR const rb, uint32_t mb, bool rc) {
|
void emit_MDS(uint32_t op, GPR const rs, GPR const ra, GPR const rb, uint32_t mb, bool rc) {
|
||||||
base[offset++] = __bswap32(op |
|
base[offset++] = (op |
|
||||||
bitExt(ra.index, 6, 5)
|
bitExt(ra.index, 6, 5)
|
||||||
| bitExt(rs.index, 11, 5)
|
| bitExt(rs.index, 11, 5)
|
||||||
| bitExt(rb.index, 16, 5)
|
| bitExt(rb.index, 16, 5)
|
||||||
@@ -312,22 +339,27 @@ struct Context {
|
|||||||
void CRMOVE(CPR const bx, CPR const by) { CROR(bx, by, by); }
|
void CRMOVE(CPR const bx, CPR const by) { CROR(bx, by, by); }
|
||||||
void CRNOT(CPR const bx, CPR const by) { CRNOR(bx, by, by); }
|
void CRNOT(CPR const bx, CPR const by) { CRNOR(bx, by, by); }
|
||||||
|
|
||||||
|
void CMPLDI(CPR const cr, GPR const rx, uint32_t v) { CMPLI(cr.index, 1, rx, v); }
|
||||||
|
void CMPLWI(CPR const cr, GPR const rx, uint32_t v) { CMPLI(cr.index, 0, rx, v); }
|
||||||
|
void CMPLD(CPR const cr, GPR const rx, GPR const ry) { CMPL(cr.index, 1, rx, ry); }
|
||||||
|
void CMPLW(CPR const cr, GPR const rx, GPR const ry) { CMPL(cr.index, 0, rx, ry); }
|
||||||
void CMPLDI(GPR const rx, uint32_t v) { CMPLI(0, 1, rx, v); }
|
void CMPLDI(GPR const rx, uint32_t v) { CMPLI(0, 1, rx, v); }
|
||||||
void CMPLWI(GPR const rx, uint32_t v) { CMPLI(0, 0, rx, v); }
|
void CMPLWI(GPR const rx, uint32_t v) { CMPLI(0, 0, rx, v); }
|
||||||
void CMPLD(GPR const rx, GPR const ry) { CMPL(0, 1, rx, ry); }
|
void CMPLD(GPR const rx, GPR const ry) { CMPL(0, 1, rx, ry); }
|
||||||
void CMPLW(GPR const rx, GPR const ry) { CMPL(0, 0, rx, ry); }
|
void CMPLW(GPR const rx, GPR const ry) { CMPL(0, 0, rx, ry); }
|
||||||
|
|
||||||
void CMPLDI(CPR const cr, GPR const rx, uint32_t v) { CMPLI(cr.index / 4, 1, rx, v); }
|
void CMPWI(CPR const cr, GPR const rx, uint32_t si) { CMPI(cr.index, 0, rx, si); }
|
||||||
void CMPLWI(CPR const cr, GPR const rx, uint32_t v) { CMPLI(cr.index / 4, 0, rx, v); }
|
void CMPW(CPR const cr, GPR const rx, GPR const ry) { CMP(cr.index, 0, rx, ry); }
|
||||||
void CMPLD(CPR const cr, GPR const rx, GPR const ry) { CMPL(cr.index / 4, 1, rx, ry); }
|
void CMPDI(CPR const cr, GPR const rx, uint32_t si) { CMPI(cr.index, 1, rx, si); }
|
||||||
void CMPLW(CPR const cr, GPR const rx, GPR const ry) { CMPL(cr.index / 4, 0, rx, ry); }
|
void CMPD(CPR const cr, GPR const rx, GPR const ry) { CMP(cr.index, 1, rx, ry); }
|
||||||
|
void CMPWI(GPR const rx, uint32_t si) { CMPI(0, 0, rx, si); }
|
||||||
|
void CMPW(GPR const rx, GPR const ry) { CMP(0, 0, rx, ry); }
|
||||||
|
void CMPDI(GPR const rx, uint32_t si) { CMPI(0, 1, rx, si); }
|
||||||
|
void CMPD(GPR const rx, GPR const ry) { CMP(0, 1, rx, ry); }
|
||||||
|
|
||||||
void CMPWI(CPR const cr, GPR const rx, uint32_t si) { CMPI(cr.index / 4, 0, rx, si); }
|
void BLR() {
|
||||||
void CMPW(CPR const cr, GPR const rx, GPR const ry) { CMP(cr.index / 4, 0, rx, ry); }
|
base[offset++] = 0x4e800020; //BCLR(R0, CR0, R0);
|
||||||
void CMPDI(CPR const cr, GPR const rx, uint32_t si) { CMPI(cr.index / 4, 1, rx, si); }
|
}
|
||||||
void CMPD(CPR const cr, GPR const rx, GPR const ry) { CMP(cr.index / 4, 1, rx, ry); }
|
|
||||||
|
|
||||||
void BLR() { BCLR(R0, CR0, R0); }
|
|
||||||
|
|
||||||
// TODO: PowerPC 11 stuff
|
// TODO: PowerPC 11 stuff
|
||||||
void ISEL(GPR const rd, GPR const ra, GPR const rb, uint32_t d) {
|
void ISEL(GPR const rd, GPR const ra, GPR const rb, uint32_t d) {
|
||||||
|
|||||||
Vendored
+30
-30
@@ -30,32 +30,32 @@ void ANDC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000078, rt, ra,
|
|||||||
void ANDC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000078, rt, ra, rb, true); }
|
void ANDC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000078, rt, ra, rb, true); }
|
||||||
void ANDI_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x70000000, rt, ra, d); }
|
void ANDI_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x70000000, rt, ra, d); }
|
||||||
void ANDIS_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x74000000, rt, ra, d); }
|
void ANDIS_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x74000000, rt, ra, d); }
|
||||||
void B(Label const& i) { emit_reloc_I(0x48000000, i); }
|
void B(Label const& i) { emit_reloc_I(0x48000000, i, false); }
|
||||||
void BL(Label const& i) { emit_reloc_I(0x48000000, i); }
|
void BL(Label const& i) { emit_reloc_I(0x48000000, i, true); }
|
||||||
void BC(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 1, i, false); }
|
void BC(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 0, cr.index + 0, i, false); }
|
||||||
void BCL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 1, i, true); }
|
void BCL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 0, cr.index + 0, i, true); }
|
||||||
void BLT(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 1, i, false); }
|
void BLT(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 0, i, false); }
|
||||||
void BLTL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 1, i, true); }
|
void BLTL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 0, i, true); }
|
||||||
void BLE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 2, i, false); }
|
void BLE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, false); }
|
||||||
void BLEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 2, i, true); }
|
void BLEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, true); }
|
||||||
void BNG(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 2, i, false); }
|
void BNG(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, false); }
|
||||||
void BNGL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 2, i, true); }
|
void BNGL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, true); }
|
||||||
void BEQ(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 3, i, false); }
|
void BEQ(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 2, i, false); }
|
||||||
void BEQL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 3, i, true); }
|
void BEQL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 2, i, true); }
|
||||||
void BGE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 1, i, false); }
|
void BGE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, false); }
|
||||||
void BGEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 1, i, true); }
|
void BGEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, true); }
|
||||||
void BNL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 1, i, false); }
|
void BNL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, false); }
|
||||||
void BNLL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 1, i, true); }
|
void BNLL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, true); }
|
||||||
void BGT(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 2, i, false); }
|
void BGT(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 1, i, false); }
|
||||||
void BGTL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 2, i, true); }
|
void BGTL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 1, i, true); }
|
||||||
void BNE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 3, i, false); }
|
void BNE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 2, i, false); }
|
||||||
void BNEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 3, i, true); }
|
void BNEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 2, i, true); }
|
||||||
void BSO(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 4, i, false); }
|
void BSO(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, false); }
|
||||||
void BSOL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 4, i, true); }
|
void BSOL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, true); }
|
||||||
void BUN(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 4, i, false); }
|
void BUN(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, false); }
|
||||||
void BUNL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 4, i, true); }
|
void BUNL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, true); }
|
||||||
void BNS(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 4, i, false); }
|
void BNS(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 3, i, false); }
|
||||||
void BNSL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, cr.index + 4, i, true); }
|
void BNSL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 3, i, true); }
|
||||||
void BCCTR(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, ba.index, bb.index, false); }
|
void BCCTR(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, ba.index, bb.index, false); }
|
||||||
void BCCTRL(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, ba.index, bb.index, true); }
|
void BCCTRL(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, ba.index, bb.index, true); }
|
||||||
void BCCTR(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, cond2offset(ba), bb.index, false); }
|
void BCCTR(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, cond2offset(ba), bb.index, false); }
|
||||||
@@ -64,10 +64,10 @@ void BCLR(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000020, bt.ind
|
|||||||
void BCLRL(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, ba.index, bb.index, true); }
|
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 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 BCLRL(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, cond2offset(ba), bb.index, 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 CMP(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000000, ra, GPR{(bf << 2) | l}, rb, false); }
|
||||||
void CMPI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x2c000000, GPR{(bf << 2) | l}, ra, d); }
|
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 CMPL(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000000, ra, GPR{(bf << 2) | l}, 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 CMPLI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x28000000, ra, GPR{(bf << 2) | l}, d); }
|
||||||
void CNTLZD(GPR const rt, GPR const ra) { emit_X(0x7c000074, rt, ra, R0, false); }
|
void CNTLZD(GPR const rt, GPR const ra) { emit_X(0x7c000074, rt, ra, R0, false); }
|
||||||
void CNTLZD_(GPR const rt, GPR const ra) { emit_X(0x7c000074, rt, ra, R0, true); }
|
void CNTLZD_(GPR const rt, GPR const ra) { emit_X(0x7c000074, rt, ra, R0, true); }
|
||||||
void CNTLZW(GPR const rt, GPR const ra) { emit_X(0x7c000034, rt, ra, R0, false); }
|
void CNTLZW(GPR const rt, GPR const ra) { emit_X(0x7c000034, rt, ra, R0, false); }
|
||||||
|
|||||||
Vendored
+136
-48
@@ -2,16 +2,19 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include "powah_emit.hpp"
|
#include "powah_emit.hpp"
|
||||||
|
|
||||||
|
#define EB32(X) __bswap32(X)
|
||||||
|
|
||||||
TEST_CASE("ppc64: addi", "[ppc64]") {
|
TEST_CASE("ppc64: addi", "[ppc64]") {
|
||||||
std::vector<uint32_t> data(64);
|
std::vector<uint32_t> data(64);
|
||||||
powah::Context ctx(data.data(), data.size());
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
|
||||||
ctx.ADDI(powah::R2, powah::R2, 0);
|
ctx.ADDI(powah::R2, powah::R2, 0);
|
||||||
ctx.ADDIS(powah::R2, powah::R12, 0);
|
ctx.ADDIS(powah::R2, powah::R12, 0);
|
||||||
REQUIRE(data[0] == 0x00004238);
|
REQUIRE(data[0] == EB32(0x00004238));
|
||||||
REQUIRE(data[1] == 0x00004c3c);
|
REQUIRE(data[1] == EB32(0x00004c3c));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ppc64: std/mr", "[ppc64]") {
|
TEST_CASE("ppc64: std/mr", "[ppc64]") {
|
||||||
@@ -24,12 +27,12 @@ TEST_CASE("ppc64: std/mr", "[ppc64]") {
|
|||||||
ctx.MR(powah::R30, powah::R3);
|
ctx.MR(powah::R30, powah::R3);
|
||||||
ctx.RLDICR(powah::R4, powah::R5, 25, 6);
|
ctx.RLDICR(powah::R4, powah::R5, 25, 6);
|
||||||
ctx.STD(powah::R28, powah::R1, 160);
|
ctx.STD(powah::R28, powah::R1, 160);
|
||||||
REQUIRE(data[0] == 0x900041fb);
|
REQUIRE(data[0] == EB32(0x900041fb));
|
||||||
REQUIRE(data[1] == 0x78239a7c);
|
REQUIRE(data[1] == EB32(0x78239a7c));
|
||||||
REQUIRE(data[2] == 0xb000c1fb);
|
REQUIRE(data[2] == EB32(0xb000c1fb));
|
||||||
REQUIRE(data[3] == 0x781b7e7c);
|
REQUIRE(data[3] == EB32(0x781b7e7c));
|
||||||
REQUIRE(data[4] == 0x84c9a478);
|
REQUIRE(data[4] == EB32(0x84c9a478));
|
||||||
REQUIRE(data[5] == 0xa00081fb);
|
REQUIRE(data[5] == EB32(0xa00081fb));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ppc64: sldi", "[ppc64]") {
|
TEST_CASE("ppc64: sldi", "[ppc64]") {
|
||||||
@@ -37,7 +40,7 @@ TEST_CASE("ppc64: sldi", "[ppc64]") {
|
|||||||
powah::Context ctx(data.data(), data.size());
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
|
||||||
ctx.SLDI(powah::R3, powah::R5, 37);
|
ctx.SLDI(powah::R3, powah::R5, 37);
|
||||||
REQUIRE(data[0] == 0x862ea378);
|
REQUIRE(data[0] == EB32(0x862ea378));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ppc64: rldicr", "[ppc64]") {
|
TEST_CASE("ppc64: rldicr", "[ppc64]") {
|
||||||
@@ -48,11 +51,11 @@ TEST_CASE("ppc64: rldicr", "[ppc64]") {
|
|||||||
ctx.RLDICR(powah::R1, powah::R1, 0, 1);
|
ctx.RLDICR(powah::R1, powah::R1, 0, 1);
|
||||||
ctx.RLDICR(powah::R1, powah::R1, 1, 1);
|
ctx.RLDICR(powah::R1, powah::R1, 1, 1);
|
||||||
ctx.RLDICR(powah::R1, powah::R1, 31, 31);
|
ctx.RLDICR(powah::R1, powah::R1, 31, 31);
|
||||||
REQUIRE(data[0] == 0x04002178);
|
REQUIRE(data[0] == EB32(0x04002178));
|
||||||
REQUIRE(data[1] == 0x04082178);
|
REQUIRE(data[1] == EB32(0x04082178));
|
||||||
REQUIRE(data[2] == 0x44002178);
|
REQUIRE(data[2] == EB32(0x44002178));
|
||||||
REQUIRE(data[3] == 0x44082178);
|
REQUIRE(data[3] == EB32(0x44082178));
|
||||||
REQUIRE(data[4] == 0xc4ff2178);
|
REQUIRE(data[4] == EB32(0xc4ff2178));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ppc64: mr/or/std", "[ppc64]") {
|
TEST_CASE("ppc64: mr/or/std", "[ppc64]") {
|
||||||
@@ -67,15 +70,15 @@ TEST_CASE("ppc64: mr/or/std", "[ppc64]") {
|
|||||||
ctx.OR(powah::R3, powah::R3, powah::R26);
|
ctx.OR(powah::R3, powah::R3, powah::R26);
|
||||||
ctx.STD(powah::R3, powah::R1, 56);
|
ctx.STD(powah::R3, powah::R1, 56);
|
||||||
ctx.MR(powah::R3, powah::R30);
|
ctx.MR(powah::R3, powah::R30);
|
||||||
REQUIRE(data[0] == 0x783bfb7c);
|
REQUIRE(data[0] == EB32(0x783bfb7c));
|
||||||
REQUIRE(data[1] == 0x7833dd7c);
|
REQUIRE(data[1] == EB32(0x7833dd7c));
|
||||||
REQUIRE(data[2] == 0x7823637c);
|
REQUIRE(data[2] == EB32(0x7823637c));
|
||||||
REQUIRE(data[3] == 0x78e3847f);
|
REQUIRE(data[3] == EB32(0x78e3847f));
|
||||||
REQUIRE(data[4] == 0x820b014d);
|
REQUIRE(data[4] == EB32(0x820b014d));
|
||||||
REQUIRE(data[5] == 0x782bb97c);
|
REQUIRE(data[5] == EB32(0x782bb97c));
|
||||||
REQUIRE(data[6] == 0x78d3637c);
|
REQUIRE(data[6] == EB32(0x78d3637c));
|
||||||
REQUIRE(data[7] == 0x380061f8);
|
REQUIRE(data[7] == EB32(0x380061f8));
|
||||||
REQUIRE(data[8] == 0x78f3c37f);
|
REQUIRE(data[8] == EB32(0x78f3c37f));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ppc64: ld/crand+addi", "[ppc64]") {
|
TEST_CASE("ppc64: ld/crand+addi", "[ppc64]") {
|
||||||
@@ -93,18 +96,18 @@ TEST_CASE("ppc64: ld/crand+addi", "[ppc64]") {
|
|||||||
ctx.ADDI(powah::R5, powah::R5, 1);
|
ctx.ADDI(powah::R5, powah::R5, 1);
|
||||||
ctx.STD(powah::R26, powah::R1, 72);
|
ctx.STD(powah::R26, powah::R1, 72);
|
||||||
ctx.STD(powah::R5, powah::R30, 1984);
|
ctx.STD(powah::R5, powah::R30, 1984);
|
||||||
REQUIRE(data[0] == 0x480081e8);
|
REQUIRE(data[0] == EB32(0x480081e8));
|
||||||
REQUIRE(data[1] == 0x5000a180);
|
REQUIRE(data[1] == EB32(0x5000a180));
|
||||||
REQUIRE(data[2] == 0x024a8a4e);
|
REQUIRE(data[2] == EB32(0x024a8a4e));
|
||||||
REQUIRE(data[3] == 0x0400c438);
|
REQUIRE(data[3] == EB32(0x0400c438));
|
||||||
REQUIRE(data[4] == 0xc807a474);
|
REQUIRE(data[4] == EB32(0xc807a474));
|
||||||
REQUIRE(data[5] == 0xc007bee8);
|
REQUIRE(data[5] == EB32(0xc007bee8));
|
||||||
REQUIRE(data[6] == 0x54006188);
|
REQUIRE(data[6] == EB32(0x54006188));
|
||||||
REQUIRE(data[7] == 0x0002da78);
|
REQUIRE(data[7] == EB32(0x0002da78));
|
||||||
REQUIRE(data[8] == 0x50008190);
|
REQUIRE(data[8] == EB32(0x50008190));
|
||||||
REQUIRE(data[9] == 0x0100a538);
|
REQUIRE(data[9] == EB32(0x0100a538));
|
||||||
REQUIRE(data[10] == 0x480041fb);
|
REQUIRE(data[10] == EB32(0x480041fb));
|
||||||
REQUIRE(data[11] == 0xc007bef8);
|
REQUIRE(data[11] == EB32(0xc007bef8));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ppc64: rotldi", "[ppc64]") {
|
TEST_CASE("ppc64: rotldi", "[ppc64]") {
|
||||||
@@ -123,17 +126,102 @@ TEST_CASE("ppc64: rotldi", "[ppc64]") {
|
|||||||
ctx.RLDIMI(powah::R4, powah::R5, 48, 8);
|
ctx.RLDIMI(powah::R4, powah::R5, 48, 8);
|
||||||
ctx.RLDIMI(powah::R4, powah::R3, 56, 0);
|
ctx.RLDIMI(powah::R4, powah::R3, 56, 0);
|
||||||
ctx.MR(powah::R3, powah::R4);
|
ctx.MR(powah::R3, powah::R4);
|
||||||
REQUIRE(data[0] == 0x00806578);
|
REQUIRE(data[0] == EB32(0x00806578));
|
||||||
REQUIRE(data[1] == 0x00406478);
|
REQUIRE(data[1] == EB32(0x00406478));
|
||||||
REQUIRE(data[2] == 0x2c44a478);
|
REQUIRE(data[2] == EB32(0x2c44a478));
|
||||||
REQUIRE(data[3] == 0x00c06578);
|
REQUIRE(data[3] == EB32(0x00c06578));
|
||||||
REQUIRE(data[4] == 0x2c82a478);
|
REQUIRE(data[4] == EB32(0x2c82a478));
|
||||||
REQUIRE(data[5] == 0x02006578);
|
REQUIRE(data[5] == EB32(0x02006578));
|
||||||
REQUIRE(data[6] == 0x2cc0a478);
|
REQUIRE(data[6] == EB32(0x2cc0a478));
|
||||||
REQUIRE(data[7] == 0x02806578);
|
REQUIRE(data[7] == EB32(0x02806578));
|
||||||
REQUIRE(data[8] == 0x0e44a478);
|
REQUIRE(data[8] == EB32(0x0e44a478));
|
||||||
REQUIRE(data[9] == 0x02c06578);
|
REQUIRE(data[9] == EB32(0x02c06578));
|
||||||
REQUIRE(data[10] == 0x0e82a478);
|
REQUIRE(data[10] == EB32(0x0e82a478));
|
||||||
REQUIRE(data[11] == 0x0ec06478);
|
REQUIRE(data[11] == EB32(0x0ec06478));
|
||||||
REQUIRE(data[12] == 0x7823837c);
|
REQUIRE(data[12] == EB32(0x7823837c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1 //&& defined(ARCHITECTURE_ppc64)
|
||||||
|
/*
|
||||||
|
0: d619637c mullw 3, 3, 3
|
||||||
|
4: 20006378 clrldi 3, 3, 32
|
||||||
|
8: 2000804e blr
|
||||||
|
*/
|
||||||
|
TEST_CASE("ppc64: live-exec square", "[ppc64]") {
|
||||||
|
uint32_t* data = (uint32_t*)mmap(nullptr, 4096, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
|
REQUIRE(data != nullptr);
|
||||||
|
|
||||||
|
powah::Context ctx((void*)data, 4096);
|
||||||
|
ctx.MULLW(powah::R3, powah::R3, powah::R3);
|
||||||
|
ctx.CLRLDI(powah::R3, powah::R3, 32);
|
||||||
|
ctx.BLR();
|
||||||
|
REQUIRE(data[0] == EB32(0xd619637c));
|
||||||
|
REQUIRE(data[1] == EB32(0x20006378));
|
||||||
|
REQUIRE(data[2] == EB32(0x2000804e));
|
||||||
|
|
||||||
|
auto* fn = (int (*)(int))data;
|
||||||
|
REQUIRE(fn(4) == 4 * 4);
|
||||||
|
REQUIRE(fn(8) == 8 * 8);
|
||||||
|
|
||||||
|
munmap((void*)data, 4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int f(int a, int b, int c) {
|
||||||
|
a += (a > b) ? b - 0xffff : c + 402, b += 2, c &= b*c;
|
||||||
|
return a * a + b ^ c & b;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
TEST_CASE("ppc64: live-exec xoralu", "[ppc64]") {
|
||||||
|
uint32_t* data = (uint32_t*)mmap(nullptr, 4096, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
|
REQUIRE(data != nullptr);
|
||||||
|
|
||||||
|
powah::Context ctx((void*)data, 4096);
|
||||||
|
powah::Label l_2 = ctx.DefineLabel();
|
||||||
|
powah::Label l_3 = ctx.DefineLabel();
|
||||||
|
ctx.CMPW(powah::R3, powah::R4);
|
||||||
|
ctx.BGT(powah::CR0, l_2);
|
||||||
|
ctx.ADDI(powah::R6, powah::R5, 402);
|
||||||
|
ctx.B(l_3);
|
||||||
|
ctx.LABEL(l_2);
|
||||||
|
ctx.ADDI(powah::R6, powah::R4, 1);
|
||||||
|
ctx.ADDIS(powah::R6, powah::R6, -1);
|
||||||
|
ctx.LABEL(l_3);
|
||||||
|
ctx.ADDI(powah::R4, powah::R4, 2);
|
||||||
|
ctx.ADD(powah::R3, powah::R6, powah::R3);
|
||||||
|
ctx.MULLW(powah::R6, powah::R4, powah::R5);
|
||||||
|
ctx.MULLW(powah::R3, powah::R3, powah::R3);
|
||||||
|
ctx.AND(powah::R5, powah::R5, powah::R6);
|
||||||
|
ctx.ADD(powah::R3, powah::R3, powah::R4);
|
||||||
|
ctx.AND(powah::R4, powah::R5, powah::R4);
|
||||||
|
ctx.XOR(powah::R3, powah::R3, powah::R4);
|
||||||
|
ctx.EXTSW(powah::R3, powah::R3);
|
||||||
|
ctx.BLR();
|
||||||
|
ctx.ApplyRelocs();
|
||||||
|
REQUIRE(data[0] == EB32(0x0020037c));
|
||||||
|
REQUIRE(data[1] == EB32(0x0c008141));
|
||||||
|
REQUIRE(data[2] == EB32(0x9201c538));
|
||||||
|
REQUIRE(data[3] == EB32(0x0c000048));
|
||||||
|
REQUIRE(data[4] == EB32(0x0100c438));
|
||||||
|
REQUIRE(data[5] == EB32(0xffffc63c));
|
||||||
|
REQUIRE(data[6] == EB32(0x02008438));
|
||||||
|
REQUIRE(data[7] == EB32(0x141a667c));
|
||||||
|
REQUIRE(data[8] == EB32(0xd629c47c));
|
||||||
|
REQUIRE(data[9] == EB32(0xd619637c));
|
||||||
|
REQUIRE(data[10] == EB32(0x3830a57c));
|
||||||
|
REQUIRE(data[11] == EB32(0x1422637c));
|
||||||
|
REQUIRE(data[12] == EB32(0x3820a47c));
|
||||||
|
REQUIRE(data[13] == EB32(0x7822637c));
|
||||||
|
REQUIRE(data[14] == EB32(0xb407637c));
|
||||||
|
REQUIRE(data[15] == EB32(0x2000804e));
|
||||||
|
|
||||||
|
auto const orig = [](int a, int b, int c) {
|
||||||
|
a += (a > b) ? b - 0xffff : c + 402, b += 2, c &= b*c;
|
||||||
|
return a * a + b ^ c & b;
|
||||||
|
};
|
||||||
|
auto* fn = (int (*)(int, int, int))data;
|
||||||
|
REQUIRE(fn(0, 1, 2) == orig(0, 1, 2));
|
||||||
|
|
||||||
|
munmap((void*)data, 4096);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user