Browse Source

C -> O for ppc64; impl NZCV?

Signed-off-by: lizzie <lizzie@eden-emu.dev>
dynarmic-ppc64
lizzie 2 months ago
parent
commit
0fc37f3b10
No known key found for this signature in database GPG Key ID: 287378CADCAB13
  1. 13
      externals/powah/powah_emit.hpp
  2. 92
      externals/powah/powah_gen_base.hpp
  3. 50
      src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp
  4. 6
      src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_a64.cpp
  5. 55
      src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_data_processing.cpp

13
externals/powah/powah_emit.hpp

@ -31,6 +31,7 @@ enum class Cond : uint8_t {
struct GPR { uint32_t index; };
struct FPR { uint32_t index; };
struct VPR { uint32_t index; };
struct CPR { uint32_t index; };
struct Label { uint32_t index; };
@ -110,6 +111,10 @@ constexpr inline CPR CR5{20};
constexpr inline CPR CR6{24};
constexpr inline CPR CR7{28};
constexpr uint32_t XER_SO = 32;
constexpr uint32_t XER_OV = 33;
constexpr uint32_t XER_CA = 34;
enum class RelocKind : uint8_t {
FormB,
FormI,
@ -298,10 +303,10 @@ struct Context {
std::abort();
}
void emit_XFX(uint32_t op, GPR const rt, uint32_t spr) {
(void)op;
(void)rt;
(void)spr;
std::abort();
base[offset++] = (op |
(rt.index & 0x1f) << 21
| ((spr & 0xff) << 12)
);
}
void emit_SC(uint32_t op, uint32_t lev) {
(void)op;

92
externals/powah/powah_gen_base.hpp

@ -1,29 +1,29 @@
// this file is autogenerated DO NOT MODIFY
#pragma once
void ADD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, false, false); }
void ADDC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, true, false); }
void ADDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, true, false); }
void ADD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, false, true); }
void ADDC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, true, true); }
//void ADDC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, false, false); }
void ADDCC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, true, false); }
//void ADDC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, false, true); }
void ADDCC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, true, true); }
void ADDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, true, true); }
void ADDC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, false, false); }
void ADDCO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, true, false); }
void ADDC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, false, true); }
void ADDCO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, true, true); }
void ADDE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, false, false); }
void ADDEC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, true, false); }
void ADDEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, true, false); }
void ADDE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, false, true); }
void ADDEC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, true, true); }
void ADDEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, true, true); }
void ADDI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x38000000, rt, ra, d); }
void ADDIC(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x30000000, rt, ra, d); }
void ADDIC_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x34000000, rt, ra, d); }
void ADDIS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x3c000000, rt, ra, d); }
void ADDME(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, false, false); }
void ADDMEC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, true, false); }
void ADDMEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, true, false); }
void ADDME_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, false, true); }
void ADDMEC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, true, true); }
void ADDMEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, true, true); }
void ADDZE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, false, false); }
void ADDZEC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, true, false); }
void ADDZEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, true, false); }
void ADDZE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, false, true); }
void ADDZEC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, true, true); }
void ADDZEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, true, true); }
void AND(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000038, rt, ra, rb, false); }
void AND_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000038, rt, ra, rb, true); }
void ANDC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000078, rt, ra, rb, false); }
@ -101,21 +101,21 @@ void DCBTST_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ec, rt,
void DCBZ(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ec, rt, ra, rb, false); }
void DCBZ_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ec, rt, ra, rb, true); }
void DIVD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, false, false); }
void DIVDC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, true, false); }
void DIVDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, true, false); }
void DIVD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, false, true); }
void DIVDC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, true, true); }
void DIVDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, true, true); }
void DIVDU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, false, false); }
void DIVDUC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, true, false); }
void DIVDUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, true, false); }
void DIVDU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, false, true); }
void DIVDUC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, true, true); }
void DIVDUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, true, true); }
void DIVW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, false, false); }
void DIVWC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, true, false); }
void DIVWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, true, false); }
void DIVW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, false, true); }
void DIVWC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, true, true); }
void DIVWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, true, true); }
void DIVWU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, false, false); }
void DIVWUC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, true, false); }
void DIVWUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, true, false); }
void DIVWU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, false, true); }
void DIVWUC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, true, true); }
void DIVWUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, true, true); }
void ECIWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00026c, rt, ra, rb, false); }
void ECIWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00026c, rt, ra, rb, true); }
void ECOWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036c, rt, ra, rb, false); }
@ -293,36 +293,36 @@ void MTSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001a4, rt, ra
void MTSRIN(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001e4, rt, ra, rb, false); }
void MTSRIN_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001e4, rt, ra, rb, true); }
void MULHD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, false, false); }
void MULHDC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, true, false); }
void MULHDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, true, false); }
void MULHD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, false, true); }
void MULHDC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, true, true); }
void MULHDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, true, true); }
void MULHDU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, false, false); }
void MULHDUC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, true, false); }
void MULHDUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, true, false); }
void MULHDU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, false, true); }
void MULHDUC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, true, true); }
void MULHDUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, true, true); }
void MULHW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, false, false); }
void MULHWC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, true, false); }
void MULHWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, true, false); }
void MULHW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, false, true); }
void MULHWC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, true, true); }
void MULHWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, true, true); }
void MULHWU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, false, false); }
void MULHWUC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, true, false); }
void MULHWUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, true, false); }
void MULHWU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, false, true); }
void MULHWUC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, true, true); }
void MULHWUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, true, true); }
void MULLD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, false, false); }
void MULLDC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, true, false); }
void MULLDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, true, false); }
void MULLD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, false, true); }
void MULLDC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, true, true); }
void MULLDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, true, true); }
void MULLI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x1c000000, rt, ra, d); }
void MULLW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, false, false); }
void MULLWC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, true, false); }
void MULLWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, true, false); }
void MULLW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, false, true); }
void MULLWC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, true, true); }
void MULLWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, true, true); }
void NAND(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003b8, rt, ra, rb, false); }
void NAND_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003b8, rt, ra, rb, true); }
void NEG(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, false, false); }
void NEGC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, true, false); }
void NEGO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, true, false); }
void NEG_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, false, true); }
void NEGC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, true, true); }
void NEGO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, true, true); }
void NOR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000f8, rt, ra, rb, false); }
void NOR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000f8, rt, ra, rb, true); }
void OR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000378, rt, ra, rb, false); }
@ -426,26 +426,26 @@ void STWUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016e, rt, r
void STWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012e, rt, ra, rb, false); }
void STWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012e, rt, ra, rb, true); }
void SUBF(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, false, false); }
void SUBFC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, true, false); }
void SUBFO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, true, false); }
void SUBF_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, false, true); }
void SUBFC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, true, true); }
//void SUBFC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, false, false); }
void SUBFCC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, true, false); }
//void SUBFC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, false, true); }
void SUBFCC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, true, true); }
void SUBFO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, true, true); }
void SUBFC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, false, false); }
void SUBFCO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, true, false); }
void SUBFC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, false, true); }
void SUBFCO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, true, true); }
void SUBFE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, false, false); }
void SUBFEC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, true, false); }
void SUBFEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, true, false); }
void SUBFE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, false, true); }
void SUBFEC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, true, true); }
void SUBFEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, true, true); }
void SUBFIC(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x20000000, rt, ra, d); }
void SUBFME(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, false, false); }
void SUBFMEC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, true, false); }
void SUBFMEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, true, false); }
void SUBFME_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, false, true); }
void SUBFMEC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, true, true); }
void SUBFMEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, true, true); }
void SUBFZE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, false, false); }
void SUBFZEC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, true, false); }
void SUBFZEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, true, false); }
void SUBFZE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, false, true); }
void SUBFZEC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, true, true); }
void SUBFZEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, true, true); }
void SYNC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ac, rt, ra, rb, false); }
void SYNC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ac, rt, ra, rb, true); }
void TD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000088, rt, ra, rb, false); }

50
src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp

@ -62,8 +62,53 @@ void EmitIR<IR::Opcode::GetGEFromOp>(powah::Context&, EmitContext&, IR::Inst*) {
}
template<>
void EmitIR<IR::Opcode::GetNZCVFromOp>(powah::Context&, EmitContext& ctx, IR::Inst* inst) {
ASSERT(false && "unimp");
void EmitIR<IR::Opcode::GetNZCVFromOp>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
if (ctx.reg_alloc.IsValueLive(inst)) {
ASSERT(false && "unimp value live");
return;
}
// CR0:
// 0 - N/LT, result is negative
// 1 - P/GT, result is positive
// 2 - Z/EQ, result is zero
// 3 - S/SO, summary overflow (carry?)
// XER:
// 32 - SO
// 33 - Overflow
// 34 - Carry
// NZCV -> (CR0.0, CR0.2, XER.34, XER.33)
if (false) {
//code.MFSPR(powah::GPR{1}, tmp4, powah::R0); // From XER
/*uint64_t nzcv(uint64_t cr0, uint64_t xer) {
return ((xer >> 33) & 1)
| (((xer >> 34) & 1) << 1)
| (((cr0 >> (32 + 2)) & 1) << 2)
| (((cr0 >> (32 + 0)) & 1) << 3);
}*/
// auto const tmp9 = ctx.reg_alloc.ScratchGpr();
// auto const tmp10 = ctx.reg_alloc.ScratchGpr();
// code.SRDI(tmp9, tmp3, 34);
// code.RLDICL(tmp10, tmp4, 31, 63);
// code.SRDI(tmp3, tmp3, 32);
// code.RLDIC(tmp9, tmp9, 2, 61);
// code.OR(tmp9, tmp9, tmp10);
// code.RLDIC(tmp3, tmp3, 3, 60);
// code.SRDI(tmp4, tmp4, 34);
// code.OR(tmp3, tmp9, tmp3);
// code.RLDIC(tmp4, tmp4, 1, 62);
// code.OR(tmp3, tmp3, tmp4);
} else {
// MFCR Fills RT 32:63, RT 0:31 left blank
auto const source = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const tmp3 = ctx.reg_alloc.ScratchGpr();
auto const tmp = ctx.reg_alloc.ScratchGpr();
code.LI(tmp, -1);
code.RLDICR(tmp, tmp, 0, 0);
code.MFCR(powah::R0, tmp3, powah::R0);
code.CMPW(tmp, source);
code.MFCR(powah::R0, tmp3, powah::R0);
ctx.reg_alloc.DefineValue(inst, tmp3);
}
}
template<>
@ -185,6 +230,7 @@ EmittedBlockInfo EmitPPC64(powah::Context& code, IR::Block block, const EmitConf
for (size_t i = 0; i < gpr_order.size(); ++i)
code.LD(powah::GPR{gpr_order[i]}, powah::R1, -(i * 8));
code.BLR();
code.ApplyRelocs();
/*
llvm-objcopy -I binary -O elf64-powerpc --rename-section=.data=.text,code test.bin test.elf && llvm-objdump -d test.elf

6
src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_a64.cpp

@ -38,7 +38,8 @@ void EmitIR<IR::Opcode::A64SetNZCVRaw>(powah::Context& code, EmitContext& ctx, I
template<>
void EmitIR<IR::Opcode::A64SetNZCV>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
ASSERT(false && "unimp");
auto const value = ctx.reg_alloc.UseGpr(inst->GetArg(0));
code.STW(value, PPC64::RJIT, offsetof(A64JitState, pstate));
}
template<>
@ -111,8 +112,7 @@ void EmitIR<IR::Opcode::A64SetW>(powah::Context& code, EmitContext& ctx, IR::Ins
auto const tmp = ctx.reg_alloc.ScratchGpr();
auto const offs = offsetof(A64JitState, regs)
+ A64::RegNumber(inst->GetArg(0).GetA64RegRef()) * sizeof(u64);
code.MR(tmp, value);
code.RLDICL(tmp, tmp, 0, 32);
code.RLDICL(tmp, value, 0, 32);
code.STD(tmp, PPC64::RJIT, offs);
} else {
ASSERT(false && "unimp");

55
src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_data_processing.cpp

@ -4,6 +4,7 @@
#include <powah_emit.hpp>
#include <fmt/ostream.h>
#include "abi.h"
#include "dynarmic/common/assert.h"
#include "dynarmic/backend/ppc64/a32_core.h"
#include "dynarmic/backend/ppc64/abi.h"
@ -436,17 +437,28 @@ void EmitIR<IR::Opcode::Add32>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.ADD(result, src_a, src_b);
code.ADDC_(result, src_a, src_b);
code.RLDICL(result, result, 0, 32);
ctx.reg_alloc.DefineValue(inst, result);
}
/*
struct jit {
uint32_t nzcv;
};
uint64_t addc(jit *p, uint64_t a, uint64_t b) {
long long unsigned int e;
uint64_t r = __builtin_addcll(a, b, p->nzcv & 0b0010, &e);
p->nzcv = (p->nzcv & 0b1101) | e;
return r;
}
*/
template<>
void EmitIR<IR::Opcode::Add64>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.ADD(result, src_a, src_b);
code.ADDC_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -455,7 +467,7 @@ void EmitIR<IR::Opcode::Sub32>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.SUBF(result, src_b, src_a);
code.SUBFC_(result, src_b, src_a);
code.RLDICL(result, result, 0, 32);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -465,7 +477,7 @@ void EmitIR<IR::Opcode::Sub64>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.SUBF(result, src_b, src_a);
code.SUBFC_(result, src_b, src_a);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -474,7 +486,7 @@ void EmitIR<IR::Opcode::Mul32>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.MULLW(result, src_a, src_b);
code.MULLWO_(result, src_a, src_b);
code.RLDICL(result, result, 0, 32);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -484,7 +496,7 @@ void EmitIR<IR::Opcode::Mul64>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.MULLD(result, src_a, src_b);
code.MULLDO_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -493,7 +505,7 @@ void EmitIR<IR::Opcode::SignedMultiplyHigh64>(powah::Context& code, EmitContext&
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.MULLD(result, src_a, src_b);
code.MULLDO_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -502,7 +514,7 @@ void EmitIR<IR::Opcode::UnsignedMultiplyHigh64>(powah::Context& code, EmitContex
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.MULLD(result, src_a, src_b);
code.MULLDO_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -511,7 +523,7 @@ void EmitIR<IR::Opcode::UnsignedDiv32>(powah::Context& code, EmitContext& ctx, I
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.DIVDU(result, src_a, src_b);
code.DIVWU_(result, src_a, src_b);
code.RLDICL(result, result, 0, 32);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -521,7 +533,7 @@ void EmitIR<IR::Opcode::UnsignedDiv64>(powah::Context& code, EmitContext& ctx, I
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.DIVDU(result, src_a, src_b);
code.DIVDU_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -530,7 +542,7 @@ void EmitIR<IR::Opcode::SignedDiv32>(powah::Context& code, EmitContext& ctx, IR:
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.DIVW(result, src_a, src_b);
code.DIVW_(result, src_a, src_b);
code.EXTSW(result, result);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -540,7 +552,7 @@ void EmitIR<IR::Opcode::SignedDiv64>(powah::Context& code, EmitContext& ctx, IR:
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.DIVD(result, src_a, src_b);
code.DIVD_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -549,7 +561,8 @@ void EmitIR<IR::Opcode::And32>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.AND(result, src_a, src_b);
code.RLDICL(result, src_a, 0, 32); // Truncate
code.AND_(result, result, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -558,7 +571,8 @@ void EmitIR<IR::Opcode::And64>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.AND(result, src_a, src_b);
code.AND_(result, src_a, src_b);
code.ADDI(result, result, 0); //update cr0
ctx.reg_alloc.DefineValue(inst, result);
}
@ -567,7 +581,7 @@ void EmitIR<IR::Opcode::AndNot32>(powah::Context& code, EmitContext& ctx, IR::In
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.NAND(result, src_a, src_b);
code.NAND_(result, src_a, src_b);
code.RLDICL(result, result, 0, 32);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -577,7 +591,7 @@ void EmitIR<IR::Opcode::AndNot64>(powah::Context& code, EmitContext& ctx, IR::In
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.NAND(result, src_a, src_b);
code.NAND_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -586,7 +600,7 @@ void EmitIR<IR::Opcode::Eor32>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.XOR(result, src_a, src_b);
code.XOR_(result, src_a, src_b);
code.RLDICL(result, result, 0, 32);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -596,7 +610,7 @@ void EmitIR<IR::Opcode::Eor64>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.XOR(result, src_a, src_b);
code.XOR_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -605,7 +619,7 @@ void EmitIR<IR::Opcode::Or32>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.OR(result, src_a, src_b);
code.OR_(result, src_a, src_b);
code.RLDICL(result, result, 0, 32);
ctx.reg_alloc.DefineValue(inst, result);
}
@ -615,10 +629,11 @@ void EmitIR<IR::Opcode::Or64>(powah::Context& code, EmitContext& ctx, IR::Inst*
auto const result = ctx.reg_alloc.ScratchGpr();
auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0));
auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1));
code.OR(result, src_a, src_b);
code.OR_(result, src_a, src_b);
ctx.reg_alloc.DefineValue(inst, result);
}
// TODO(lizzie): NZVC support for NOT
template<>
void EmitIR<IR::Opcode::Not32>(powah::Context& code, EmitContext& ctx, IR::Inst* inst) {
auto const result = ctx.reg_alloc.ScratchGpr();

Loading…
Cancel
Save