Removing all uses of the old PPC tables besides disasm.

This commit is contained in:
Ben Vanik
2015-12-28 10:08:38 -08:00
parent 990d973c74
commit cd938be678
17 changed files with 2393 additions and 2411 deletions

View File

@@ -17,121 +17,122 @@ namespace xe {
namespace cpu {
namespace ppc {
void Disasm_0(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s ???", i->type->name);
void Disasm_0(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s ???", i.opcode_info->name);
}
void Disasm__(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s", i->type->name);
void Disasm__(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s", i.opcode_info->name);
}
void Disasm_X_FRT_FRB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, f%d", i->X.Rc ? -7 : -8, i->type->name,
i->X.Rc ? "." : "", i->X.RT, i->X.RB);
void Disasm_X_FRT_FRB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, f%d", i.X.Rc ? -7 : -8, i.opcode_info->name,
i.X.Rc ? "." : "", i.X.RT, i.X.RB);
}
void Disasm_A_FRT_FRB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, f%d", i->A.Rc ? -7 : -8, i->type->name,
i->A.Rc ? "." : "", i->A.FRT, i->A.FRB);
void Disasm_A_FRT_FRB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, f%d", i.A.Rc ? -7 : -8, i.opcode_info->name,
i.A.Rc ? "." : "", i.A.FRT, i.A.FRB);
}
void Disasm_A_FRT_FRA_FRB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, f%d, f%d", i->A.Rc ? -7 : -8, i->type->name,
i->A.Rc ? "." : "", i->A.FRT, i->A.FRA, i->A.FRB);
void Disasm_A_FRT_FRA_FRB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, f%d, f%d", i.A.Rc ? -7 : -8,
i.opcode_info->name, i.A.Rc ? "." : "", i.A.FRT, i.A.FRA,
i.A.FRB);
}
void Disasm_A_FRT_FRA_FRB_FRC(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, f%d, f%d, f%d", i->A.Rc ? -7 : -8,
i->type->name, i->A.Rc ? "." : "", i->A.FRT, i->A.FRA,
i->A.FRB, i->A.FRC);
void Disasm_A_FRT_FRA_FRB_FRC(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, f%d, f%d, f%d", i.A.Rc ? -7 : -8,
i.opcode_info->name, i.A.Rc ? "." : "", i.A.FRT, i.A.FRA,
i.A.FRB, i.A.FRC);
}
void Disasm_X_RT_RA_RB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, r%d, r%d", i->type->name, i->X.RT, i->X.RA,
i->X.RB);
void Disasm_X_RT_RA_RB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, r%d, r%d", i.opcode_info->name, i.X.RT, i.X.RA,
i.X.RB);
}
void Disasm_X_RT_RA0_RB(InstrData* i, StringBuffer* str) {
if (i->X.RA) {
str->AppendFormat("%-8s r%d, r%d, r%d", i->type->name, i->X.RT, i->X.RA,
i->X.RB);
void Disasm_X_RT_RA0_RB(const InstrData& i, StringBuffer* str) {
if (i.X.RA) {
str->AppendFormat("%-8s r%d, r%d, r%d", i.opcode_info->name, i.X.RT, i.X.RA,
i.X.RB);
} else {
str->AppendFormat("%-8s r%d, 0, r%d", i->type->name, i->X.RT, i->X.RB);
str->AppendFormat("%-8s r%d, 0, r%d", i.opcode_info->name, i.X.RT, i.X.RB);
}
}
void Disasm_X_FRT_RA_RB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s f%d, r%d, r%d", i->type->name, i->X.RT, i->X.RA,
i->X.RB);
void Disasm_X_FRT_RA_RB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s f%d, r%d, r%d", i.opcode_info->name, i.X.RT, i.X.RA,
i.X.RB);
}
void Disasm_X_FRT_RA0_RB(InstrData* i, StringBuffer* str) {
if (i->X.RA) {
str->AppendFormat("%-8s f%d, r%d, r%d", i->type->name, i->X.RT, i->X.RA,
i->X.RB);
void Disasm_X_FRT_RA0_RB(const InstrData& i, StringBuffer* str) {
if (i.X.RA) {
str->AppendFormat("%-8s f%d, r%d, r%d", i.opcode_info->name, i.X.RT, i.X.RA,
i.X.RB);
} else {
str->AppendFormat("%-8s f%d, 0, r%d", i->type->name, i->X.RT, i->X.RB);
str->AppendFormat("%-8s f%d, 0, r%d", i.opcode_info->name, i.X.RT, i.X.RB);
}
}
void Disasm_D_RT_RA_I(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, r%d, %d", i->type->name, i->D.RT, i->D.RA,
(int32_t)(int16_t)XEEXTS16(i->D.DS));
void Disasm_D_RT_RA_I(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, r%d, %d", i.opcode_info->name, i.D.RT, i.D.RA,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
}
void Disasm_D_RT_RA0_I(InstrData* i, StringBuffer* str) {
if (i->D.RA) {
str->AppendFormat("%-8s r%d, r%d, %d", i->type->name, i->D.RT, i->D.RA,
(int32_t)(int16_t)XEEXTS16(i->D.DS));
void Disasm_D_RT_RA0_I(const InstrData& i, StringBuffer* str) {
if (i.D.RA) {
str->AppendFormat("%-8s r%d, r%d, %d", i.opcode_info->name, i.D.RT, i.D.RA,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
} else {
str->AppendFormat("%-8s r%d, 0, %d", i->type->name, i->D.RT,
(int32_t)(int16_t)XEEXTS16(i->D.DS));
str->AppendFormat("%-8s r%d, 0, %d", i.opcode_info->name, i.D.RT,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
}
}
void Disasm_D_FRT_RA_I(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s f%d, r%d, %d", i->type->name, i->D.RT, i->D.RA,
(int32_t)(int16_t)XEEXTS16(i->D.DS));
void Disasm_D_FRT_RA_I(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s f%d, r%d, %d", i.opcode_info->name, i.D.RT, i.D.RA,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
}
void Disasm_D_FRT_RA0_I(InstrData* i, StringBuffer* str) {
if (i->D.RA) {
str->AppendFormat("%-8s f%d, r%d, %d", i->type->name, i->D.RT, i->D.RA,
(int32_t)(int16_t)XEEXTS16(i->D.DS));
void Disasm_D_FRT_RA0_I(const InstrData& i, StringBuffer* str) {
if (i.D.RA) {
str->AppendFormat("%-8s f%d, r%d, %d", i.opcode_info->name, i.D.RT, i.D.RA,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
} else {
str->AppendFormat("%-8s f%d, 0, %d", i->type->name, i->D.RT,
(int32_t)(int16_t)XEEXTS16(i->D.DS));
str->AppendFormat("%-8s f%d, 0, %d", i.opcode_info->name, i.D.RT,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
}
}
void Disasm_DS_RT_RA_I(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, r%d, %d", i->type->name, i->DS.RT, i->DS.RA,
(int32_t)(int16_t)XEEXTS16(i->DS.DS << 2));
void Disasm_DS_RT_RA_I(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, r%d, %d", i.opcode_info->name, i.DS.RT, i.DS.RA,
(int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
}
void Disasm_DS_RT_RA0_I(InstrData* i, StringBuffer* str) {
if (i->DS.RA) {
str->AppendFormat("%-8s r%d, r%d, %d", i->type->name, i->DS.RT, i->DS.RA,
(int32_t)(int16_t)XEEXTS16(i->DS.DS << 2));
void Disasm_DS_RT_RA0_I(const InstrData& i, StringBuffer* str) {
if (i.DS.RA) {
str->AppendFormat("%-8s r%d, r%d, %d", i.opcode_info->name, i.DS.RT,
i.DS.RA, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
} else {
str->AppendFormat("%-8s r%d, 0, %d", i->type->name, i->DS.RT,
(int32_t)(int16_t)XEEXTS16(i->DS.DS << 2));
str->AppendFormat("%-8s r%d, 0, %d", i.opcode_info->name, i.DS.RT,
(int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
}
}
void Disasm_D_RA(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d", i->type->name, i->D.RA);
void Disasm_D_RA(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d", i.opcode_info->name, i.D.RA);
}
void Disasm_X_RA_RB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, r%d", i->type->name, i->X.RA, i->X.RB);
void Disasm_X_RA_RB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, r%d", i.opcode_info->name, i.X.RA, i.X.RB);
}
void Disasm_XO_RT_RA_RB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s%s r%d, r%d, r%d", i->XO.Rc ? -7 : -8, i->type->name,
i->XO.OE ? "o" : "", i->XO.Rc ? "." : "", i->XO.RT,
i->XO.RA, i->XO.RB);
void Disasm_XO_RT_RA_RB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s%s r%d, r%d, r%d", i.XO.Rc ? -7 : -8,
i.opcode_info->name, i.XO.OE ? "o" : "", i.XO.Rc ? "." : "",
i.XO.RT, i.XO.RA, i.XO.RB);
}
void Disasm_XO_RT_RA(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s%s r%d, r%d", i->XO.Rc ? -7 : -8, i->type->name,
i->XO.OE ? "o" : "", i->XO.Rc ? "." : "", i->XO.RT,
i->XO.RA);
void Disasm_XO_RT_RA(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s%s r%d, r%d", i.XO.Rc ? -7 : -8, i.opcode_info->name,
i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA);
}
void Disasm_X_RA_RT_RB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, r%d", i->X.Rc ? -7 : -8, i->type->name,
i->X.Rc ? "." : "", i->X.RA, i->X.RT, i->X.RB);
void Disasm_X_RA_RT_RB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, r%d", i.X.Rc ? -7 : -8,
i.opcode_info->name, i.X.Rc ? "." : "", i.X.RA, i.X.RT,
i.X.RB);
}
void Disasm_D_RA_RT_I(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-7s. r%d, r%d, %.4Xh", i->type->name, i->D.RA, i->D.RT,
i->D.DS);
void Disasm_D_RA_RT_I(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-7s. r%d, r%d, %.4Xh", i.opcode_info->name, i.D.RA,
i.D.RT, i.D.DS);
}
void Disasm_X_RA_RT(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d", i->X.Rc ? -7 : -8, i->type->name,
i->X.Rc ? "." : "", i->X.RA, i->X.RT);
void Disasm_X_RA_RT(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d", i.X.Rc ? -7 : -8, i.opcode_info->name,
i.X.Rc ? "." : "", i.X.RA, i.X.RT);
}
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
@@ -143,90 +144,93 @@ void Disasm_X_RA_RT(InstrData* i, StringBuffer* str) {
#define VX128_5(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x10))
#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630))
#define VX128_VD128 (i->VX128.VD128l | (i->VX128.VD128h << 5))
#define VX128_VD128 (i.VX128.VD128l | (i.VX128.VD128h << 5))
#define VX128_VA128 \
(i->VX128.VA128l | (i->VX128.VA128h << 5) | (i->VX128.VA128H << 6))
#define VX128_VB128 (i->VX128.VB128l | (i->VX128.VB128h << 5))
#define VX128_1_VD128 (i->VX128_1.VD128l | (i->VX128_1.VD128h << 5))
#define VX128_2_VD128 (i->VX128_2.VD128l | (i->VX128_2.VD128h << 5))
(i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6))
#define VX128_VB128 (i.VX128.VB128l | (i.VX128.VB128h << 5))
#define VX128_1_VD128 (i.VX128_1.VD128l | (i.VX128_1.VD128h << 5))
#define VX128_2_VD128 (i.VX128_2.VD128l | (i.VX128_2.VD128h << 5))
#define VX128_2_VA128 \
(i->VX128_2.VA128l | (i->VX128_2.VA128h << 5) | (i->VX128_2.VA128H << 6))
#define VX128_2_VB128 (i->VX128_2.VB128l | (i->VX128_2.VB128h << 5))
#define VX128_2_VC (i->VX128_2.VC)
#define VX128_3_VD128 (i->VX128_3.VD128l | (i->VX128_3.VD128h << 5))
#define VX128_3_VB128 (i->VX128_3.VB128l | (i->VX128_3.VB128h << 5))
#define VX128_3_IMM (i->VX128_3.IMM)
#define VX128_4_VD128 (i->VX128_4.VD128l | (i->VX128_4.VD128h << 5))
#define VX128_4_VB128 (i->VX128_4.VB128l | (i->VX128_4.VB128h << 5))
#define VX128_5_VD128 (i->VX128_5.VD128l | (i->VX128_5.VD128h << 5))
(i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6))
#define VX128_2_VB128 (i.VX128_2.VB128l | (i.VX128_2.VB128h << 5))
#define VX128_2_VC (i.VX128_2.VC)
#define VX128_3_VD128 (i.VX128_3.VD128l | (i.VX128_3.VD128h << 5))
#define VX128_3_VB128 (i.VX128_3.VB128l | (i.VX128_3.VB128h << 5))
#define VX128_3_IMM (i.VX128_3.IMM)
#define VX128_4_VD128 (i.VX128_4.VD128l | (i.VX128_4.VD128h << 5))
#define VX128_4_VB128 (i.VX128_4.VB128l | (i.VX128_4.VB128h << 5))
#define VX128_5_VD128 (i.VX128_5.VD128l | (i.VX128_5.VD128h << 5))
#define VX128_5_VA128 \
(i->VX128_5.VA128l | (i->VX128_5.VA128h << 5)) | (i->VX128_5.VA128H << 6)
#define VX128_5_VB128 (i->VX128_5.VB128l | (i->VX128_5.VB128h << 5))
#define VX128_5_SH (i->VX128_5.SH)
#define VX128_R_VD128 (i->VX128_R.VD128l | (i->VX128_R.VD128h << 5))
(i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6)
#define VX128_5_VB128 (i.VX128_5.VB128l | (i.VX128_5.VB128h << 5))
#define VX128_5_SH (i.VX128_5.SH)
#define VX128_R_VD128 (i.VX128_R.VD128l | (i.VX128_R.VD128h << 5))
#define VX128_R_VA128 \
(i->VX128_R.VA128l | (i->VX128_R.VA128h << 5) | (i->VX128_R.VA128H << 6))
#define VX128_R_VB128 (i->VX128_R.VB128l | (i->VX128_R.VB128h << 5))
(i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6))
#define VX128_R_VB128 (i.VX128_R.VB128l | (i.VX128_R.VB128h << 5))
void Disasm_X_VX_RA0_RB(InstrData* i, StringBuffer* str) {
if (i->X.RA) {
str->AppendFormat("%-8s v%d, r%d, r%d", i->type->name, i->X.RT, i->X.RA,
i->X.RB);
void Disasm_X_VX_RA0_RB(const InstrData& i, StringBuffer* str) {
if (i.X.RA) {
str->AppendFormat("%-8s v%d, r%d, r%d", i.opcode_info->name, i.X.RT, i.X.RA,
i.X.RB);
} else {
str->AppendFormat("%-8s v%d, 0, r%d", i->type->name, i->X.RT, i->X.RB);
str->AppendFormat("%-8s v%d, 0, r%d", i.opcode_info->name, i.X.RT, i.X.RB);
}
}
void Disasm_VX1281_VD_RA0_RB(InstrData* i, StringBuffer* str) {
void Disasm_VX1281_VD_RA0_RB(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_1_VD128;
if (i->VX128_1.RA) {
str->AppendFormat("%-8s v%d, r%d, r%d", i->type->name, vd, i->VX128_1.RA,
i->VX128_1.RB);
if (i.VX128_1.RA) {
str->AppendFormat("%-8s v%d, r%d, r%d", i.opcode_info->name, vd,
i.VX128_1.RA, i.VX128_1.RB);
} else {
str->AppendFormat("%-8s v%d, 0, r%d", i->type->name, vd, i->VX128_1.RB);
str->AppendFormat("%-8s v%d, 0, r%d", i.opcode_info->name, vd,
i.VX128_1.RB);
}
}
void Disasm_VX1283_VD_VB(InstrData* i, StringBuffer* str) {
void Disasm_VX1283_VD_VB(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_3_VD128;
const uint32_t vb = VX128_3_VB128;
str->AppendFormat("%-8s v%d, v%d", i->type->name, vd, vb);
str->AppendFormat("%-8s v%d, v%d", i.opcode_info->name, vd, vb);
}
void Disasm_VX1283_VD_VB_I(InstrData* i, StringBuffer* str) {
void Disasm_VX1283_VD_VB_I(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_VD128;
const uint32_t va = VX128_VA128;
const uint32_t uimm = i->VX128_3.IMM;
str->AppendFormat("%-8s v%d, v%d, %.2Xh", i->type->name, vd, va, uimm);
const uint32_t uimm = i.VX128_3.IMM;
str->AppendFormat("%-8s v%d, v%d, %.2Xh", i.opcode_info->name, vd, va, uimm);
}
void Disasm_VX_VD_VA_VB(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, v%d", i->type->name, i->VX.VD, i->VX.VA,
i->VX.VB);
void Disasm_VX_VD_VA_VB(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, v%d", i.opcode_info->name, i.VX.VD, i.VX.VA,
i.VX.VB);
}
void Disasm_VX128_VD_VA_VB(InstrData* i, StringBuffer* str) {
void Disasm_VX128_VD_VA_VB(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_VD128;
const uint32_t va = VX128_VA128;
const uint32_t vb = VX128_VB128;
str->AppendFormat("%-8s v%d, v%d, v%d", i->type->name, vd, va, vb);
str->AppendFormat("%-8s v%d, v%d, v%d", i.opcode_info->name, vd, va, vb);
}
void Disasm_VX128_VD_VA_VD_VB(InstrData* i, StringBuffer* str) {
void Disasm_VX128_VD_VA_VD_VB(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_VD128;
const uint32_t va = VX128_VA128;
const uint32_t vb = VX128_VB128;
str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i->type->name, vd, va, vd, vb);
str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i.opcode_info->name, vd, va, vd,
vb);
}
void Disasm_VX1282_VD_VA_VB_VC(InstrData* i, StringBuffer* str) {
void Disasm_VX1282_VD_VA_VB_VC(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_2_VD128;
const uint32_t va = VX128_2_VA128;
const uint32_t vb = VX128_2_VB128;
const uint32_t vc = i->VX128_2.VC;
str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i->type->name, vd, va, vb, vc);
const uint32_t vc = i.VX128_2.VC;
str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i.opcode_info->name, vd, va, vb,
vc);
}
void Disasm_VXA_VD_VA_VB_VC(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i->type->name, i->VXA.VD,
i->VXA.VA, i->VXA.VB, i->VXA.VC);
void Disasm_VXA_VD_VA_VB_VC(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, v%d, v%d", i.opcode_info->name, i.VXA.VD,
i.VXA.VA, i.VXA.VB, i.VXA.VC);
}
void Disasm_sync(InstrData* i, StringBuffer* str) {
void Disasm_sync(const InstrData& i, StringBuffer* str) {
const char* name;
int L = i->X.RT & 3;
int L = i.X.RT & 3;
switch (L) {
case 0:
name = "hwsync";
@@ -243,9 +247,9 @@ void Disasm_sync(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s %.2X", name, L);
}
void Disasm_dcbf(InstrData* i, StringBuffer* str) {
void Disasm_dcbf(const InstrData& i, StringBuffer* str) {
const char* name;
switch (i->X.RT & 3) {
switch (i.X.RT & 3) {
case 0:
name = "dcbf";
break;
@@ -262,90 +266,90 @@ void Disasm_dcbf(InstrData* i, StringBuffer* str) {
name = "dcbf.??";
break;
}
str->AppendFormat("%-8s r%d, r%d", name, i->X.RA, i->X.RB);
str->AppendFormat("%-8s r%d, r%d", name, i.X.RA, i.X.RB);
}
void Disasm_dcbz(InstrData* i, StringBuffer* str) {
void Disasm_dcbz(const InstrData& i, StringBuffer* str) {
// or dcbz128 0x7C2007EC
if (i->X.RA) {
str->AppendFormat("%-8s r%d, r%d", i->type->name, i->X.RA, i->X.RB);
if (i.X.RA) {
str->AppendFormat("%-8s r%d, r%d", i.opcode_info->name, i.X.RA, i.X.RB);
} else {
str->AppendFormat("%-8s 0, r%d", i->type->name, i->X.RB);
str->AppendFormat("%-8s 0, r%d", i.opcode_info->name, i.X.RB);
}
}
void Disasm_fcmp(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s cr%d, f%d, f%d", i->type->name, i->X.RT >> 2, i->X.RA,
i->X.RB);
void Disasm_fcmp(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s cr%d, f%d, f%d", i.opcode_info->name, i.X.RT >> 2,
i.X.RA, i.X.RB);
}
void Disasm_mffsx(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, FPSCR", i->X.Rc ? -7 : -8, i->type->name,
i->X.Rc ? "." : "", i->X.RT);
void Disasm_mffsx(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s f%d, FPSCR", i.X.Rc ? -7 : -8, i.opcode_info->name,
i.X.Rc ? "." : "", i.X.RT);
}
void Disasm_bx(InstrData* i, StringBuffer* str) {
const char* name = i->I.LK ? "bl" : "b";
void Disasm_bx(const InstrData& i, StringBuffer* str) {
const char* name = i.I.LK ? "bl" : "b";
uint32_t nia;
if (i->I.AA) {
nia = (uint32_t)XEEXTS26(i->I.LI << 2);
if (i.I.AA) {
nia = (uint32_t)XEEXTS26(i.I.LI << 2);
} else {
nia = (uint32_t)(i->address + XEEXTS26(i->I.LI << 2));
nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2));
}
str->AppendFormat("%-8s %.8X", name, nia);
// TODO(benvanik): resolve target name?
}
void Disasm_bcx(InstrData* i, StringBuffer* str) {
const char* s0 = i->B.LK ? "lr, " : "";
void Disasm_bcx(const InstrData& i, StringBuffer* str) {
const char* s0 = i.B.LK ? "lr, " : "";
const char* s1;
if (!select_bits(i->B.BO, 2, 2)) {
if (!select_bits(i.B.BO, 2, 2)) {
s1 = "ctr, ";
} else {
s1 = "";
}
char s2[8] = {0};
if (!select_bits(i->B.BO, 4, 4)) {
snprintf(s2, xe::countof(s2), "cr%d, ", i->B.BI >> 2);
if (!select_bits(i.B.BO, 4, 4)) {
snprintf(s2, xe::countof(s2), "cr%d, ", i.B.BI >> 2);
}
uint32_t nia;
if (i->B.AA) {
nia = (uint32_t)XEEXTS16(i->B.BD << 2);
if (i.B.AA) {
nia = (uint32_t)XEEXTS16(i.B.BD << 2);
} else {
nia = (uint32_t)(i->address + XEEXTS16(i->B.BD << 2));
nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2));
}
str->AppendFormat("%-8s %s%s%s%.8X", i->type->name, s0, s1, s2, nia);
str->AppendFormat("%-8s %s%s%s%.8X", i.opcode_info->name, s0, s1, s2, nia);
// TODO(benvanik): resolve target name?
}
void Disasm_bcctrx(InstrData* i, StringBuffer* str) {
void Disasm_bcctrx(const InstrData& i, StringBuffer* str) {
// TODO(benvanik): mnemonics
const char* s0 = i->XL.LK ? "lr, " : "";
const char* s0 = i.XL.LK ? "lr, " : "";
char s2[8] = {0};
if (!select_bits(i->XL.BO, 4, 4)) {
snprintf(s2, xe::countof(s2), "cr%d, ", i->XL.BI >> 2);
if (!select_bits(i.XL.BO, 4, 4)) {
snprintf(s2, xe::countof(s2), "cr%d, ", i.XL.BI >> 2);
}
str->AppendFormat("%-8s %s%sctr", i->type->name, s0, s2);
str->AppendFormat("%-8s %s%sctr", i.opcode_info->name, s0, s2);
// TODO(benvanik): resolve target name?
}
void Disasm_bclrx(InstrData* i, StringBuffer* str) {
void Disasm_bclrx(const InstrData& i, StringBuffer* str) {
const char* name = "bclr";
if (i->code == 0x4E800020) {
if (i.code == 0x4E800020) {
name = "blr";
}
const char* s1;
if (!select_bits(i->XL.BO, 2, 2)) {
if (!select_bits(i.XL.BO, 2, 2)) {
s1 = "ctr, ";
} else {
s1 = "";
}
char s2[8] = {0};
if (!select_bits(i->XL.BO, 4, 4)) {
snprintf(s2, xe::countof(s2), "cr%d, ", i->XL.BI >> 2);
if (!select_bits(i.XL.BO, 4, 4)) {
snprintf(s2, xe::countof(s2), "cr%d, ", i.XL.BI >> 2);
}
str->AppendFormat("%-8s %s%s", name, s1, s2);
}
void Disasm_mfcr(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, cr", i->type->name, i->X.RT);
void Disasm_mfcr(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, cr", i.opcode_info->name, i.X.RT);
}
const char* Disasm_spr_name(uint32_t n) {
const char* reg = "???";
@@ -362,158 +366,160 @@ const char* Disasm_spr_name(uint32_t n) {
}
return reg;
}
void Disasm_mfspr(InstrData* i, StringBuffer* str) {
const uint32_t n = ((i->XFX.spr & 0x1F) << 5) | ((i->XFX.spr >> 5) & 0x1F);
void Disasm_mfspr(const InstrData& i, StringBuffer* str) {
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
const char* reg = Disasm_spr_name(n);
str->AppendFormat("%-8s r%d, %s", i->type->name, i->XFX.RT, reg);
str->AppendFormat("%-8s r%d, %s", i.opcode_info->name, i.XFX.RT, reg);
}
void Disasm_mtspr(InstrData* i, StringBuffer* str) {
const uint32_t n = ((i->XFX.spr & 0x1F) << 5) | ((i->XFX.spr >> 5) & 0x1F);
void Disasm_mtspr(const InstrData& i, StringBuffer* str) {
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
const char* reg = Disasm_spr_name(n);
str->AppendFormat("%-8s %s, r%d", i->type->name, reg, i->XFX.RT);
str->AppendFormat("%-8s %s, r%d", i.opcode_info->name, reg, i.XFX.RT);
}
void Disasm_mftb(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, tb", i->type->name, i->XFX.RT);
void Disasm_mftb(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, tb", i.opcode_info->name, i.XFX.RT);
}
void Disasm_mfmsr(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d", i->type->name, i->X.RT);
void Disasm_mfmsr(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d", i.opcode_info->name, i.X.RT);
}
void Disasm_mtmsr(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, %d", i->type->name, i->X.RT,
(i->X.RA & 16) ? 1 : 0);
void Disasm_mtmsr(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s r%d, %d", i.opcode_info->name, i.X.RT,
(i.X.RA & 16) ? 1 : 0);
}
void Disasm_cmp(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s cr%d, %.2X, r%d, r%d", i->type->name, i->X.RT >> 2,
i->X.RT & 1, i->X.RA, i->X.RB);
void Disasm_cmp(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s cr%d, %.2X, r%d, r%d", i.opcode_info->name,
i.X.RT >> 2, i.X.RT & 1, i.X.RA, i.X.RB);
}
void Disasm_cmpi(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s cr%d, %.2X, r%d, %d", i->type->name, i->D.RT >> 2,
i->D.RT & 1, i->D.RA, XEEXTS16(i->D.DS));
void Disasm_cmpi(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s cr%d, %.2X, r%d, %d", i.opcode_info->name,
i.D.RT >> 2, i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS));
}
void Disasm_cmpli(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s cr%d, %.2X, r%d, %.2X", i->type->name, i->D.RT >> 2,
i->D.RT & 1, i->D.RA, XEEXTS16(i->D.DS));
void Disasm_cmpli(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s cr%d, %.2X, r%d, %.2X", i.opcode_info->name,
i.D.RT >> 2, i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS));
}
void Disasm_rld(InstrData* i, StringBuffer* str) {
if (i->MD.idx == 0) {
void Disasm_rld(const InstrData& i, StringBuffer* str) {
if (i.MD.idx == 0) {
// XEDISASMR(rldiclx, 0x78000000, MD )
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i->MD.Rc ? -7 : -8, "rldicl",
i->MD.Rc ? "." : "", i->MD.RA, i->MD.RT,
(i->MD.SH5 << 5) | i->MD.SH, (i->MD.MB5 << 5) | i->MD.MB);
} else if (i->MD.idx == 1) {
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicl",
i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT,
(i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB);
} else if (i.MD.idx == 1) {
// XEDISASMR(rldicrx, 0x78000004, MD )
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i->MD.Rc ? -7 : -8, "rldicr",
i->MD.Rc ? "." : "", i->MD.RA, i->MD.RT,
(i->MD.SH5 << 5) | i->MD.SH, (i->MD.MB5 << 5) | i->MD.MB);
} else if (i->MD.idx == 2) {
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicr",
i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT,
(i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB);
} else if (i.MD.idx == 2) {
// XEDISASMR(rldicx, 0x78000008, MD )
uint32_t sh = (i->MD.SH5 << 5) | i->MD.SH;
uint32_t mb = (i->MD.MB5 << 5) | i->MD.MB;
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
const char* name = (mb == 0x3E) ? "sldi" : "rldic";
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i->MD.Rc ? -7 : -8, name,
i->MD.Rc ? "." : "", i->MD.RA, i->MD.RT, sh, mb);
} else if (i->MDS.idx == 8) {
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, name,
i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, sh, mb);
} else if (i.MDS.idx == 8) {
// XEDISASMR(rldclx, 0x78000010, MDS)
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i->MDS.Rc ? -7 : -8, "rldcl",
i->MDS.Rc ? "." : "", i->MDS.RA, i->MDS.RT, i->MDS.RB,
(i->MDS.MB5 << 5) | i->MDS.MB);
} else if (i->MDS.idx == 9) {
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcl",
i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB,
(i.MDS.MB5 << 5) | i.MDS.MB);
} else if (i.MDS.idx == 9) {
// XEDISASMR(rldcrx, 0x78000012, MDS)
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i->MDS.Rc ? -7 : -8, "rldcr",
i->MDS.Rc ? "." : "", i->MDS.RA, i->MDS.RT, i->MDS.RB,
(i->MDS.MB5 << 5) | i->MDS.MB);
} else if (i->MD.idx == 3) {
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcr",
i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB,
(i.MDS.MB5 << 5) | i.MDS.MB);
} else if (i.MD.idx == 3) {
// XEDISASMR(rldimix, 0x7800000C, MD )
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i->MD.Rc ? -7 : -8, "rldimi",
i->MD.Rc ? "." : "", i->MD.RA, i->MD.RT,
(i->MD.SH5 << 5) | i->MD.SH, (i->MD.MB5 << 5) | i->MD.MB);
str->AppendFormat("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldimi",
i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT,
(i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB);
} else {
assert_always();
}
}
void Disasm_rlwim(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, %d, %d, %d", i->M.Rc ? -7 : -8,
i->type->name, i->M.Rc ? "." : "", i->M.RA, i->M.RT,
i->M.SH, i->M.MB, i->M.ME);
void Disasm_rlwim(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, %d, %d, %d", i.M.Rc ? -7 : -8,
i.opcode_info->name, i.M.Rc ? "." : "", i.M.RA, i.M.RT,
i.M.SH, i.M.MB, i.M.ME);
}
void Disasm_rlwnmx(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, r%d, %d, %d", i->M.Rc ? -7 : -8,
i->type->name, i->M.Rc ? "." : "", i->M.RA, i->M.RT,
i->M.SH, i->M.MB, i->M.ME);
void Disasm_rlwnmx(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, r%d, %d, %d", i.M.Rc ? -7 : -8,
i.opcode_info->name, i.M.Rc ? "." : "", i.M.RA, i.M.RT,
i.M.SH, i.M.MB, i.M.ME);
}
void Disasm_srawix(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, %d", i->X.Rc ? -7 : -8, i->type->name,
i->X.Rc ? "." : "", i->X.RA, i->X.RT, i->X.RB);
void Disasm_srawix(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, %d", i.X.Rc ? -7 : -8, i.opcode_info->name,
i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB);
}
void Disasm_sradix(InstrData* i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, %d", i->XS.Rc ? -7 : -8, i->type->name,
i->XS.Rc ? "." : "", i->XS.RA, i->XS.RT,
(i->XS.SH5 << 5) | i->XS.SH);
void Disasm_sradix(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%*s%s r%d, r%d, %d", i.XS.Rc ? -7 : -8,
i.opcode_info->name, i.XS.Rc ? "." : "", i.XS.RA, i.XS.RT,
(i.XS.SH5 << 5) | i.XS.SH);
}
void Disasm_vpermwi128(InstrData* i, StringBuffer* str) {
const uint32_t vd = i->VX128_P.VD128l | (i->VX128_P.VD128h << 5);
const uint32_t vb = i->VX128_P.VB128l | (i->VX128_P.VB128h << 5);
str->AppendFormat("%-8s v%d, v%d, %.2X", i->type->name, vd, vb,
i->VX128_P.PERMl | (i->VX128_P.PERMh << 5));
void Disasm_vpermwi128(const InstrData& i, StringBuffer* str) {
const uint32_t vd = i.VX128_P.VD128l | (i.VX128_P.VD128h << 5);
const uint32_t vb = i.VX128_P.VB128l | (i.VX128_P.VB128h << 5);
str->AppendFormat("%-8s v%d, v%d, %.2X", i.opcode_info->name, vd, vb,
i.VX128_P.PERMl | (i.VX128_P.PERMh << 5));
}
void Disasm_vrfin128(InstrData* i, StringBuffer* str) {
void Disasm_vrfin128(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_3_VD128;
const uint32_t vb = VX128_3_VB128;
str->AppendFormat("%-8s v%d, v%d", i->type->name, vd, vb);
str->AppendFormat("%-8s v%d, v%d", i.opcode_info->name, vd, vb);
}
void Disasm_vrlimi128(InstrData* i, StringBuffer* str) {
void Disasm_vrlimi128(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_4_VD128;
const uint32_t vb = VX128_4_VB128;
str->AppendFormat("%-8s v%d, v%d, %.2X, %.2X", i->type->name, vd, vb,
i->VX128_4.IMM, i->VX128_4.z);
str->AppendFormat("%-8s v%d, v%d, %.2X, %.2X", i.opcode_info->name, vd, vb,
i.VX128_4.IMM, i.VX128_4.z);
}
void Disasm_vsldoi128(InstrData* i, StringBuffer* str) {
void Disasm_vsldoi128(const InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_5_VD128;
const uint32_t va = VX128_5_VA128;
const uint32_t vb = VX128_5_VB128;
const uint32_t sh = i->VX128_5.SH;
str->AppendFormat("%-8s v%d, v%d, v%d, %.2X", i->type->name, vd, va, vb, sh);
const uint32_t sh = i.VX128_5.SH;
str->AppendFormat("%-8s v%d, v%d, v%d, %.2X", i.opcode_info->name, vd, va, vb,
sh);
}
void Disasm_vspltb(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, %.2X", i->type->name, i->VX.VD, i->VX.VB,
i->VX.VA & 0xF);
void Disasm_vspltb(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, %.2X", i.opcode_info->name, i.VX.VD,
i.VX.VB, i.VX.VA & 0xF);
}
void Disasm_vsplth(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, %.2X", i->type->name, i->VX.VD, i->VX.VB,
i->VX.VA & 0x7);
void Disasm_vsplth(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, %.2X", i.opcode_info->name, i.VX.VD,
i.VX.VB, i.VX.VA & 0x7);
}
void Disasm_vspltw(InstrData* i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, %.2X", i->type->name, i->VX.VD, i->VX.VB,
i->VX.VA);
void Disasm_vspltw(const InstrData& i, StringBuffer* str) {
str->AppendFormat("%-8s v%d, v%d, %.2X", i.opcode_info->name, i.VX.VD,
i.VX.VB, i.VX.VA);
}
void Disasm_vspltisb(InstrData* i, StringBuffer* str) {
void Disasm_vspltisb(const InstrData& i, StringBuffer* str) {
// 5bit -> 8bit sign extend
int8_t simm = (i->VX.VA & 0x10) ? (i->VX.VA | 0xF0) : i->VX.VA;
str->AppendFormat("%-8s v%d, %.2X", i->type->name, i->VX.VD, simm);
int8_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xF0) : i.VX.VA;
str->AppendFormat("%-8s v%d, %.2X", i.opcode_info->name, i.VX.VD, simm);
}
void Disasm_vspltish(InstrData* i, StringBuffer* str) {
void Disasm_vspltish(const InstrData& i, StringBuffer* str) {
// 5bit -> 16bit sign extend
int16_t simm = (i->VX.VA & 0x10) ? (i->VX.VA | 0xFFF0) : i->VX.VA;
str->AppendFormat("%-8s v%d, %.4X", i->type->name, i->VX.VD, simm);
int16_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFF0) : i.VX.VA;
str->AppendFormat("%-8s v%d, %.4X", i.opcode_info->name, i.VX.VD, simm);
}
void Disasm_vspltisw(InstrData* i, StringBuffer* str) {
void Disasm_vspltisw(const InstrData& i, StringBuffer* str) {
// 5bit -> 32bit sign extend
int32_t simm = (i->VX.VA & 0x10) ? (i->VX.VA | 0xFFFFFFF0) : i->VX.VA;
str->AppendFormat("%-8s v%d, %.8X", i->type->name, i->VX.VD, simm);
int32_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFF0) : i.VX.VA;
str->AppendFormat("%-8s v%d, %.8X", i.opcode_info->name, i.VX.VD, simm);
}
int DisasmPPC(uint32_t address, uint32_t code, StringBuffer* str) {
InstrData i;
i.address = address;
i.code = code;
i.type = GetInstrType(i.code);
if (!i.type) {
i.opcode = LookupOpcode(code);
if (i.opcode == PPCOpcode::kInvalid) {
str->Append("???");
} else {
i.type->disasm(&i, str);
i.opcode_info = &GetOpcodeInfo(i.opcode);
GetInstrType(code)->disasm(i, str);
}
return 0;
}

View File

@@ -13,15 +13,14 @@
#include "xenia/base/logging.h"
#include "xenia/cpu/ppc/ppc_emit.h"
#include "xenia/cpu/ppc/ppc_instr.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
namespace xe {
namespace cpu {
namespace ppc {
#define XEEMITTER(name, opcode, format) int InstrEmit_##name
#define XEREGISTERINSTR(name, opcode) \
RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name);
#define XEREGISTERINSTR(name) \
RegisterOpcodeEmitter(PPCOpcode::name, InstrEmit_##name);
#define XEINSTRNOTIMPLEMENTED() \
XELOGE("Unimplemented instruction: %s", __FUNCTION__); \

View File

@@ -10,8 +10,6 @@
#ifndef XENIA_CPU_PPC_PPC_EMIT_H_
#define XENIA_CPU_PPC_PPC_EMIT_H_
#include "xenia/cpu/ppc/ppc_instr.h"
namespace xe {
namespace cpu {
namespace ppc {

File diff suppressed because it is too large Load Diff

View File

@@ -45,7 +45,7 @@ Value* AddWithCarryDidCarry(PPCHIRBuilder& f, Value* v1, Value* v2, Value* v3) {
f.CompareULT(f.Add(v1, v2), v1));
}
XEEMITTER(addx, 0x7C000214, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addx(PPCHIRBuilder& f, const InstrData& i) {
// RD <- (RA) + (RB)
Value* v = f.Add(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB));
f.StoreGPR(i.XO.RT, v);
@@ -59,7 +59,7 @@ XEEMITTER(addx, 0x7C000214, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(addcx, 0x7C000014, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addcx(PPCHIRBuilder& f, const InstrData& i) {
// RD <- (RA) + (RB)
// CA <- carry bit
Value* ra = f.LoadGPR(i.XO.RA);
@@ -78,7 +78,7 @@ XEEMITTER(addcx, 0x7C000014, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(addex, 0x7C000114, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addex(PPCHIRBuilder& f, const InstrData& i) {
// RD <- (RA) + (RB) + XER[CA]
// CA <- carry bit
Value* ra = f.LoadGPR(i.XO.RA);
@@ -97,7 +97,7 @@ XEEMITTER(addex, 0x7C000114, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(addi, 0x38000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addi(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// RT <- EXTS(SI)
// else
@@ -111,7 +111,7 @@ XEEMITTER(addi, 0x38000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(addic, 0x30000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addic(PPCHIRBuilder& f, const InstrData& i) {
// RT <- (RA) + EXTS(SI)
// CA <- carry bit
Value* ra = f.LoadGPR(i.D.RA);
@@ -121,7 +121,7 @@ XEEMITTER(addic, 0x30000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(addicx, 0x34000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addicx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- (RA) + EXTS(SI)
// CA <- carry bit
Value* ra = f.LoadGPR(i.D.RA);
@@ -132,7 +132,7 @@ XEEMITTER(addicx, 0x34000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(addis, 0x3C000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addis(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// RT <- EXTS(SI) || i16.0
// else
@@ -146,7 +146,7 @@ XEEMITTER(addis, 0x3C000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(addmex, 0x7C0001D4, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addmex(PPCHIRBuilder& f, const InstrData& i) {
// RT <- (RA) + CA - 1
// CA <- carry bit
Value* ra = f.LoadGPR(i.XO.RA);
@@ -166,7 +166,7 @@ XEEMITTER(addmex, 0x7C0001D4, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(addzex, 0x7C000194, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_addzex(PPCHIRBuilder& f, const InstrData& i) {
// RT <- (RA) + CA
// CA <- carry bit
Value* ra = f.LoadGPR(i.XO.RA);
@@ -187,7 +187,7 @@ XEEMITTER(addzex, 0x7C000194, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(divdx, 0x7C0003D2, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_divdx(PPCHIRBuilder& f, const InstrData& i) {
// dividend <- (RA)
// divisor <- (RB)
// if divisor = 0 then
@@ -213,7 +213,7 @@ XEEMITTER(divdx, 0x7C0003D2, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(divdux, 0x7C000392, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_divdux(PPCHIRBuilder& f, const InstrData& i) {
// dividend <- (RA)
// divisor <- (RB)
// if divisor = 0 then
@@ -239,7 +239,7 @@ XEEMITTER(divdux, 0x7C000392, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(divwx, 0x7C0003D6, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_divwx(PPCHIRBuilder& f, const InstrData& i) {
// dividend[0:31] <- (RA)[32:63]
// divisor[0:31] <- (RB)[32:63]
// if divisor = 0 then
@@ -267,7 +267,7 @@ XEEMITTER(divwx, 0x7C0003D6, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(divwux, 0x7C000396, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_divwux(PPCHIRBuilder& f, const InstrData& i) {
// dividend[0:31] <- (RA)[32:63]
// divisor[0:31] <- (RB)[32:63]
// if divisor = 0 then
@@ -296,7 +296,7 @@ XEEMITTER(divwux, 0x7C000396, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mulhdx, 0x7C000092, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mulhdx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ((RA) × (RB) as 128)[0:63]
if (i.XO.OE) {
// With XER update.
@@ -311,7 +311,7 @@ XEEMITTER(mulhdx, 0x7C000092, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mulhdux, 0x7C000012, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mulhdux(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ((RA) × (RB) as 128)[0:63]
if (i.XO.OE) {
// With XER update.
@@ -327,7 +327,7 @@ XEEMITTER(mulhdux, 0x7C000012, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mulhwx, 0x7C000096, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mulhwx(PPCHIRBuilder& f, const InstrData& i) {
// RT[32:64] <- ((RA)[32:63] × (RB)[32:63])[0:31]
if (i.XO.OE) {
// With XER update.
@@ -344,7 +344,7 @@ XEEMITTER(mulhwx, 0x7C000096, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mulhwux, 0x7C000016, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mulhwux(PPCHIRBuilder& f, const InstrData& i) {
// RT[32:64] <- ((RA)[32:63] × (RB)[32:63])[0:31]
if (i.XO.OE) {
// With XER update.
@@ -362,7 +362,7 @@ XEEMITTER(mulhwux, 0x7C000016, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mulldx, 0x7C0001D2, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mulldx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ((RA) × (RB))[64:127]
if (i.XO.OE) {
// With XER update.
@@ -377,7 +377,7 @@ XEEMITTER(mulldx, 0x7C0001D2, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mulli, 0x1C000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mulli(PPCHIRBuilder& f, const InstrData& i) {
// prod[0:127] <- (RA) × EXTS(SI)
// RT <- prod[64:127]
Value* v = f.Mul(f.LoadGPR(i.D.RA), f.LoadConstantInt64(XEEXTS16(i.D.DS)));
@@ -385,7 +385,7 @@ XEEMITTER(mulli, 0x1C000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mullwx, 0x7C0001D6, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mullwx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- (RA)[32:63] × (RB)[32:63]
if (i.XO.OE) {
// With XER update.
@@ -402,7 +402,7 @@ XEEMITTER(mullwx, 0x7C0001D6, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(negx, 0x7C0000D0, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_negx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ¬(RA) + 1
if (i.XO.OE) {
// With XER update.
@@ -435,7 +435,7 @@ XEEMITTER(negx, 0x7C0000D0, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(subfx, 0x7C000050, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_subfx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ¬(RA) + (RB) + 1
Value* v = f.Sub(f.LoadGPR(i.XO.RB), f.LoadGPR(i.XO.RA));
f.StoreGPR(i.XO.RT, v);
@@ -449,7 +449,7 @@ XEEMITTER(subfx, 0x7C000050, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(subfcx, 0x7C000010, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_subfcx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ¬(RA) + (RB) + 1
Value* ra = f.LoadGPR(i.XO.RA);
Value* rb = f.LoadGPR(i.XO.RB);
@@ -467,7 +467,7 @@ XEEMITTER(subfcx, 0x7C000010, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(subficx, 0x20000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_subficx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ¬(RA) + EXTS(SI) + 1
Value* ra = f.LoadGPR(i.D.RA);
Value* v = f.Sub(f.LoadConstantInt64(XEEXTS16(i.D.DS)), ra);
@@ -476,7 +476,7 @@ XEEMITTER(subficx, 0x20000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(subfex, 0x7C000110, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_subfex(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ¬(RA) + (RB) + CA
Value* not_ra = f.Not(f.LoadGPR(i.XO.RA));
Value* rb = f.LoadGPR(i.XO.RB);
@@ -494,7 +494,7 @@ XEEMITTER(subfex, 0x7C000110, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(subfmex, 0x7C0001D0, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_subfmex(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ¬(RA) + CA - 1
Value* not_ra = f.Not(f.LoadGPR(i.XO.RA));
Value* v = f.AddWithCarry(not_ra, f.LoadConstantInt64(-1), f.LoadCA());
@@ -512,7 +512,7 @@ XEEMITTER(subfmex, 0x7C0001D0, XO)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(subfzex, 0x7C000190, XO)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_subfzex(PPCHIRBuilder& f, const InstrData& i) {
// RT <- ¬(RA) + CA
Value* not_ra = f.Not(f.LoadGPR(i.XO.RA));
Value* v = f.AddWithCarry(not_ra, f.LoadZeroInt64(), f.LoadCA());
@@ -531,7 +531,7 @@ XEEMITTER(subfzex, 0x7C000190, XO)(PPCHIRBuilder& f, InstrData& i) {
// Integer compare (A-4)
XEEMITTER(cmp, 0x7C000000, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_cmp(PPCHIRBuilder& f, const InstrData& i) {
// if L = 0 then
// a <- EXTS((RA)[32:63])
// b <- EXTS((RB)[32:63])
@@ -560,7 +560,7 @@ XEEMITTER(cmp, 0x7C000000, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(cmpi, 0x2C000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_cmpi(PPCHIRBuilder& f, const InstrData& i) {
// if L = 0 then
// a <- EXTS((RA)[32:63])
// else
@@ -587,7 +587,7 @@ XEEMITTER(cmpi, 0x2C000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(cmpl, 0x7C000040, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_cmpl(PPCHIRBuilder& f, const InstrData& i) {
// if L = 0 then
// a <- i32.0 || (RA)[32:63]
// b <- i32.0 || (RB)[32:63]
@@ -616,7 +616,7 @@ XEEMITTER(cmpl, 0x7C000040, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(cmpli, 0x28000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_cmpli(PPCHIRBuilder& f, const InstrData& i) {
// if L = 0 then
// a <- i32.0 || (RA)[32:63]
// else
@@ -645,7 +645,7 @@ XEEMITTER(cmpli, 0x28000000, D)(PPCHIRBuilder& f, InstrData& i) {
// Integer logical (A-5)
XEEMITTER(andx, 0x7C000038, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_andx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) & (RB)
Value* ra = f.And(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB));
f.StoreGPR(i.X.RA, ra);
@@ -655,7 +655,7 @@ XEEMITTER(andx, 0x7C000038, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(andcx, 0x7C000078, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_andcx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) & ¬(RB)
Value* ra = f.And(f.LoadGPR(i.X.RT), f.Not(f.LoadGPR(i.X.RB)));
f.StoreGPR(i.X.RA, ra);
@@ -665,7 +665,7 @@ XEEMITTER(andcx, 0x7C000078, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(andix, 0x70000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_andix(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) & (i48.0 || UI)
Value* ra = f.And(f.LoadGPR(i.D.RT), f.LoadConstantUint64(XEEXTZ16(i.D.DS)));
f.StoreGPR(i.D.RA, ra);
@@ -673,7 +673,7 @@ XEEMITTER(andix, 0x70000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(andisx, 0x74000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_andisx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) & (i32.0 || UI || i16.0)
Value* ra =
f.And(f.LoadGPR(i.D.RT), f.LoadConstantUint64(XEEXTZ16(i.D.DS) << 16));
@@ -682,7 +682,7 @@ XEEMITTER(andisx, 0x74000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(cntlzdx, 0x7C000074, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_cntlzdx(PPCHIRBuilder& f, const InstrData& i) {
// n <- 0
// do while n < 64
// if (RS)[n] = 1 then leave n
@@ -697,7 +697,7 @@ XEEMITTER(cntlzdx, 0x7C000074, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(cntlzwx, 0x7C000034, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_cntlzwx(PPCHIRBuilder& f, const InstrData& i) {
// n <- 32
// do while n < 64
// if (RS)[n] = 1 then leave n
@@ -712,7 +712,7 @@ XEEMITTER(cntlzwx, 0x7C000034, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(eqvx, 0x7C000238, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_eqvx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) == (RB)
Value* ra = f.Not(f.Xor(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)));
f.StoreGPR(i.X.RA, ra);
@@ -722,7 +722,7 @@ XEEMITTER(eqvx, 0x7C000238, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(extsbx, 0x7C000774, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_extsbx(PPCHIRBuilder& f, const InstrData& i) {
// s <- (RS)[56]
// RA[56:63] <- (RS)[56:63]
// RA[0:55] <- i56.s
@@ -735,7 +735,7 @@ XEEMITTER(extsbx, 0x7C000774, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(extshx, 0x7C000734, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_extshx(PPCHIRBuilder& f, const InstrData& i) {
// s <- (RS)[48]
// RA[48:63] <- (RS)[48:63]
// RA[0:47] <- 48.s
@@ -748,7 +748,7 @@ XEEMITTER(extshx, 0x7C000734, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(extswx, 0x7C0007B4, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_extswx(PPCHIRBuilder& f, const InstrData& i) {
// s <- (RS)[32]
// RA[32:63] <- (RS)[32:63]
// RA[0:31] <- i32.s
@@ -761,7 +761,7 @@ XEEMITTER(extswx, 0x7C0007B4, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(nandx, 0x7C0003B8, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_nandx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- ¬((RS) & (RB))
Value* ra = f.Not(f.And(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)));
f.StoreGPR(i.X.RA, ra);
@@ -771,7 +771,7 @@ XEEMITTER(nandx, 0x7C0003B8, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(norx, 0x7C0000F8, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_norx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- ¬((RS) | (RB))
Value* ra = f.Not(f.Or(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)));
f.StoreGPR(i.X.RA, ra);
@@ -781,7 +781,7 @@ XEEMITTER(norx, 0x7C0000F8, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(orx, 0x7C000378, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_orx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) | (RB)
if (i.X.RT == i.X.RB && i.X.RT == i.X.RA && !i.X.Rc) {
// Sometimes used as no-op.
@@ -801,7 +801,7 @@ XEEMITTER(orx, 0x7C000378, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(orcx, 0x7C000338, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_orcx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) | ¬(RB)
Value* ra = f.Or(f.LoadGPR(i.X.RT), f.Not(f.LoadGPR(i.X.RB)));
f.StoreGPR(i.X.RA, ra);
@@ -811,7 +811,7 @@ XEEMITTER(orcx, 0x7C000338, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ori, 0x60000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_ori(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) | (i48.0 || UI)
if (!i.D.RA && !i.D.RT && !i.D.DS) {
f.Nop();
@@ -822,7 +822,7 @@ XEEMITTER(ori, 0x60000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(oris, 0x64000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_oris(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) | (i32.0 || UI || i16.0)
Value* ra =
f.Or(f.LoadGPR(i.D.RT), f.LoadConstantUint64(XEEXTZ16(i.D.DS) << 16));
@@ -830,7 +830,7 @@ XEEMITTER(oris, 0x64000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(xorx, 0x7C000278, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_xorx(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) XOR (RB)
Value* ra = f.Xor(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB));
f.StoreGPR(i.X.RA, ra);
@@ -840,14 +840,14 @@ XEEMITTER(xorx, 0x7C000278, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(xori, 0x68000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_xori(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) XOR (i48.0 || UI)
Value* ra = f.Xor(f.LoadGPR(i.D.RT), f.LoadConstantUint64(XEEXTZ16(i.D.DS)));
f.StoreGPR(i.D.RA, ra);
return 0;
}
XEEMITTER(xoris, 0x6C000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_xoris(PPCHIRBuilder& f, const InstrData& i) {
// RA <- (RS) XOR (i32.0 || UI || i16.0)
Value* ra =
f.Xor(f.LoadGPR(i.D.RT), f.LoadConstantUint64(XEEXTZ16(i.D.DS) << 16));
@@ -857,104 +857,103 @@ XEEMITTER(xoris, 0x6C000000, D)(PPCHIRBuilder& f, InstrData& i) {
// Integer rotate (A-6)
XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) {
if (i.MD.idx == 0) {
// XEEMITTER(rldiclx, 0x78000000, MD )
// n <- sh[5] || sh[0:4]
// r <- ROTL64((RS), n)
// b <- mb[5] || mb[0:4]
// m <- MASK(b, 63)
// RA <- r & m
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
uint64_t m = XEMASK(mb, 63);
Value* v = f.LoadGPR(i.MD.RT);
if (sh == 64 - mb) {
// srdi == rldicl ra,rs,64-n,n
v = f.Shr(v, int8_t(mb));
} else {
if (sh) {
v = f.RotateLeft(v, f.LoadConstantInt8(sh));
}
if (m != 0xFFFFFFFFFFFFFFFF) {
v = f.And(v, f.LoadConstantUint64(m));
}
}
f.StoreGPR(i.MD.RA, v);
if (i.MD.Rc) {
f.UpdateCR(0, v);
}
return 0;
} else if (i.MD.idx == 1) {
// XEEMITTER(rldicrx, 0x78000004, MD )
// n <- sh[5] || sh[0:4]
// r <- ROTL64((RS), n)
// e <- me[5] || me[0:4]
// m <- MASK(0, e)
// RA <- r & m
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
uint64_t m = XEMASK(0, mb);
Value* v = f.LoadGPR(i.MD.RT);
if (mb == 63 - sh) {
// sldi == rldicr ra,rs,n,63-n
v = f.Shl(v, int8_t(sh));
} else {
if (sh) {
v = f.RotateLeft(v, f.LoadConstantInt8(sh));
}
if (m != 0xFFFFFFFFFFFFFFFF) {
v = f.And(v, f.LoadConstantUint64(m));
}
}
f.StoreGPR(i.MD.RA, v);
if (i.MD.Rc) {
f.UpdateCR(0, v);
}
return 0;
} else if (i.MD.idx == 2) {
// XEEMITTER(rldicx, 0x78000008, MD )
XEINSTRNOTIMPLEMENTED();
return 1;
} else if (i.MDS.idx == 8) {
// XEEMITTER(rldclx, 0x78000010, MDS)
XEINSTRNOTIMPLEMENTED();
return 1;
} else if (i.MDS.idx == 9) {
// XEEMITTER(rldcrx, 0x78000012, MDS)
XEINSTRNOTIMPLEMENTED();
return 1;
} else if (i.MD.idx == 3) {
// XEEMITTER(rldimix, 0x7800000C, MD )
// n <- sh[5] || sh[0:4]
// r <- ROTL64((RS), n)
// b <- me[5] || me[0:4]
// m <- MASK(b, ¬n)
// RA <- (r & m) | ((RA)&¬m)
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
uint64_t m = XEMASK(mb, ~sh);
Value* v = f.LoadGPR(i.MD.RT);
int InstrEmit_rldclx(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
int InstrEmit_rldcrx(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
int InstrEmit_rldicx(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
int InstrEmit_rldiclx(PPCHIRBuilder& f, const InstrData& i) {
// n <- sh[5] || sh[0:4]
// r <- ROTL64((RS), n)
// b <- mb[5] || mb[0:4]
// m <- MASK(b, 63)
// RA <- r & m
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
uint64_t m = XEMASK(mb, 63);
Value* v = f.LoadGPR(i.MD.RT);
if (sh == 64 - mb) {
// srdi == rldicl ra,rs,64-n,n
v = f.Shr(v, int8_t(mb));
} else {
if (sh) {
v = f.RotateLeft(v, f.LoadConstantInt8(sh));
}
if (m != 0xFFFFFFFFFFFFFFFF) {
Value* ra = f.LoadGPR(i.MD.RA);
v = f.Or(f.And(v, f.LoadConstantUint64(m)),
f.And(ra, f.LoadConstantUint64(~m)));
v = f.And(v, f.LoadConstantUint64(m));
}
f.StoreGPR(i.MD.RA, v);
if (i.MD.Rc) {
f.UpdateCR(0, v);
}
return 0;
} else {
XEINSTRNOTIMPLEMENTED();
return 1;
}
f.StoreGPR(i.MD.RA, v);
if (i.MD.Rc) {
f.UpdateCR(0, v);
}
return 0;
}
XEEMITTER(rlwimix, 0x50000000, M)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_rldicrx(PPCHIRBuilder& f, const InstrData& i) {
// n <- sh[5] || sh[0:4]
// r <- ROTL64((RS), n)
// e <- me[5] || me[0:4]
// m <- MASK(0, e)
// RA <- r & m
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
uint64_t m = XEMASK(0, mb);
Value* v = f.LoadGPR(i.MD.RT);
if (mb == 63 - sh) {
// sldi == rldicr ra,rs,n,63-n
v = f.Shl(v, int8_t(sh));
} else {
if (sh) {
v = f.RotateLeft(v, f.LoadConstantInt8(sh));
}
if (m != 0xFFFFFFFFFFFFFFFF) {
v = f.And(v, f.LoadConstantUint64(m));
}
}
f.StoreGPR(i.MD.RA, v);
if (i.MD.Rc) {
f.UpdateCR(0, v);
}
return 0;
}
int InstrEmit_rldimix(PPCHIRBuilder& f, const InstrData& i) {
// n <- sh[5] || sh[0:4]
// r <- ROTL64((RS), n)
// b <- me[5] || me[0:4]
// m <- MASK(b, ¬n)
// RA <- (r & m) | ((RA)&¬m)
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
uint64_t m = XEMASK(mb, ~sh);
Value* v = f.LoadGPR(i.MD.RT);
if (sh) {
v = f.RotateLeft(v, f.LoadConstantInt8(sh));
}
if (m != 0xFFFFFFFFFFFFFFFF) {
Value* ra = f.LoadGPR(i.MD.RA);
v = f.Or(f.And(v, f.LoadConstantUint64(m)),
f.And(ra, f.LoadConstantUint64(~m)));
}
f.StoreGPR(i.MD.RA, v);
if (i.MD.Rc) {
f.UpdateCR(0, v);
}
return 0;
}
int InstrEmit_rlwimix(PPCHIRBuilder& f, const InstrData& i) {
// n <- SH
// r <- ROTL32((RS)[32:63], n)
// m <- MASK(MB+32, ME+32)
@@ -978,7 +977,7 @@ XEEMITTER(rlwimix, 0x50000000, M)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(rlwinmx, 0x54000000, M)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_rlwinmx(PPCHIRBuilder& f, const InstrData& i) {
// n <- SH
// r <- ROTL32((RS)[32:63], n)
// m <- MASK(MB+32, ME+32)
@@ -1006,7 +1005,7 @@ XEEMITTER(rlwinmx, 0x54000000, M)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(rlwnmx, 0x5C000000, M)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_rlwnmx(PPCHIRBuilder& f, const InstrData& i) {
// n <- (RB)[59:63]
// r <- ROTL32((RS)[32:63], n)
// m <- MASK(MB+32, ME+32)
@@ -1031,7 +1030,7 @@ XEEMITTER(rlwnmx, 0x5C000000, M)(PPCHIRBuilder& f, InstrData& i) {
// Integer shift (A-7)
XEEMITTER(sldx, 0x7C000036, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sldx(PPCHIRBuilder& f, const InstrData& i) {
// n <- (RB)[58:63]
// r <- ROTL64((RS), n)
// if (RB)[57] = 0 then
@@ -1050,7 +1049,7 @@ XEEMITTER(sldx, 0x7C000036, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(slwx, 0x7C000030, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_slwx(PPCHIRBuilder& f, const InstrData& i) {
// n <- (RB)[59:63]
// r <- ROTL32((RS)[32:63], n)
// if (RB)[58] = 0 then
@@ -1070,7 +1069,7 @@ XEEMITTER(slwx, 0x7C000030, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(srdx, 0x7C000436, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_srdx(PPCHIRBuilder& f, const InstrData& i) {
// n <- (RB)[58:63]
// r <- ROTL64((RS), 64-n)
// if (RB)[57] = 0 then
@@ -1089,7 +1088,7 @@ XEEMITTER(srdx, 0x7C000436, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(srwx, 0x7C000430, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_srwx(PPCHIRBuilder& f, const InstrData& i) {
// n <- (RB)[59:63]
// r <- ROTL32((RS)[32:63], 64-n)
// if (RB)[58] = 0 then
@@ -1110,7 +1109,7 @@ XEEMITTER(srwx, 0x7C000430, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sradx, 0x7C000634, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sradx(PPCHIRBuilder& f, const InstrData& i) {
// n <- rB[58-63]
// r <- ROTL[64](rS, 64 - n)
// if rB[57] = 0 then m ← MASK(n, 63)
@@ -1139,7 +1138,7 @@ XEEMITTER(sradx, 0x7C000634, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sradix, 0x7C000674, XS)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sradix(PPCHIRBuilder& f, const InstrData& i) {
// n <- sh[5] || sh[0-4]
// r <- ROTL[64](rS, 64 - n)
// m ← MASK(n, 63)
@@ -1171,7 +1170,7 @@ XEEMITTER(sradix, 0x7C000674, XS)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(srawx, 0x7C000630, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_srawx(PPCHIRBuilder& f, const InstrData& i) {
// n <- rB[59-63]
// r <- ROTL32((RS)[32:63], 64-n)
// m <- MASK(n+32, 63)
@@ -1200,7 +1199,7 @@ XEEMITTER(srawx, 0x7C000630, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(srawix, 0x7C000670, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_srawix(PPCHIRBuilder& f, const InstrData& i) {
// n <- SH
// r <- ROTL32((RS)[32:63], 64-n)
// m <- MASK(n+32, 63)
@@ -1233,75 +1232,73 @@ XEEMITTER(srawix, 0x7C000670, X)(PPCHIRBuilder& f, InstrData& i) {
}
void RegisterEmitCategoryALU() {
XEREGISTERINSTR(addx, 0x7C000214);
XEREGISTERINSTR(addcx, 0X7C000014);
XEREGISTERINSTR(addex, 0x7C000114);
XEREGISTERINSTR(addi, 0x38000000);
XEREGISTERINSTR(addic, 0x30000000);
XEREGISTERINSTR(addicx, 0x34000000);
XEREGISTERINSTR(addis, 0x3C000000);
XEREGISTERINSTR(addmex, 0x7C0001D4);
XEREGISTERINSTR(addzex, 0x7C000194);
XEREGISTERINSTR(divdx, 0x7C0003D2);
XEREGISTERINSTR(divdux, 0x7C000392);
XEREGISTERINSTR(divwx, 0x7C0003D6);
XEREGISTERINSTR(divwux, 0x7C000396);
XEREGISTERINSTR(mulhdx, 0x7C000092);
XEREGISTERINSTR(mulhdux, 0x7C000012);
XEREGISTERINSTR(mulhwx, 0x7C000096);
XEREGISTERINSTR(mulhwux, 0x7C000016);
XEREGISTERINSTR(mulldx, 0x7C0001D2);
XEREGISTERINSTR(mulli, 0x1C000000);
XEREGISTERINSTR(mullwx, 0x7C0001D6);
XEREGISTERINSTR(negx, 0x7C0000D0);
XEREGISTERINSTR(subfx, 0x7C000050);
XEREGISTERINSTR(subfcx, 0x7C000010);
XEREGISTERINSTR(subficx, 0x20000000);
XEREGISTERINSTR(subfex, 0x7C000110);
XEREGISTERINSTR(subfmex, 0x7C0001D0);
XEREGISTERINSTR(subfzex, 0x7C000190);
XEREGISTERINSTR(cmp, 0x7C000000);
XEREGISTERINSTR(cmpi, 0x2C000000);
XEREGISTERINSTR(cmpl, 0x7C000040);
XEREGISTERINSTR(cmpli, 0x28000000);
XEREGISTERINSTR(andx, 0x7C000038);
XEREGISTERINSTR(andcx, 0x7C000078);
XEREGISTERINSTR(andix, 0x70000000);
XEREGISTERINSTR(andisx, 0x74000000);
XEREGISTERINSTR(cntlzdx, 0x7C000074);
XEREGISTERINSTR(cntlzwx, 0x7C000034);
XEREGISTERINSTR(eqvx, 0x7C000238);
XEREGISTERINSTR(extsbx, 0x7C000774);
XEREGISTERINSTR(extshx, 0x7C000734);
XEREGISTERINSTR(extswx, 0x7C0007B4);
XEREGISTERINSTR(nandx, 0x7C0003B8);
XEREGISTERINSTR(norx, 0x7C0000F8);
XEREGISTERINSTR(orx, 0x7C000378);
XEREGISTERINSTR(orcx, 0x7C000338);
XEREGISTERINSTR(ori, 0x60000000);
XEREGISTERINSTR(oris, 0x64000000);
XEREGISTERINSTR(xorx, 0x7C000278);
XEREGISTERINSTR(xori, 0x68000000);
XEREGISTERINSTR(xoris, 0x6C000000);
XEREGISTERINSTR(rld, 0x78000000);
// -- // XEREGISTERINSTR(rldclx, 0x78000010);
// -- // XEREGISTERINSTR(rldcrx, 0x78000012);
// -- // XEREGISTERINSTR(rldicx, 0x78000008);
// -- // XEREGISTERINSTR(rldiclx, 0x78000000);
// -- // XEREGISTERINSTR(rldicrx, 0x78000004);
// -- // XEREGISTERINSTR(rldimix, 0x7800000C);
XEREGISTERINSTR(rlwimix, 0x50000000);
XEREGISTERINSTR(rlwinmx, 0x54000000);
XEREGISTERINSTR(rlwnmx, 0x5C000000);
XEREGISTERINSTR(sldx, 0x7C000036);
XEREGISTERINSTR(slwx, 0x7C000030);
XEREGISTERINSTR(srdx, 0x7C000436);
XEREGISTERINSTR(srwx, 0x7C000430);
XEREGISTERINSTR(sradx, 0x7C000634);
XEREGISTERINSTR(sradix, 0x7C000674);
XEREGISTERINSTR(sradix, 0x7C000676); // HACK
XEREGISTERINSTR(srawx, 0x7C000630);
XEREGISTERINSTR(srawix, 0x7C000670);
XEREGISTERINSTR(addx);
XEREGISTERINSTR(addcx);
XEREGISTERINSTR(addex);
XEREGISTERINSTR(addi);
XEREGISTERINSTR(addic);
XEREGISTERINSTR(addicx);
XEREGISTERINSTR(addis);
XEREGISTERINSTR(addmex);
XEREGISTERINSTR(addzex);
XEREGISTERINSTR(divdx);
XEREGISTERINSTR(divdux);
XEREGISTERINSTR(divwx);
XEREGISTERINSTR(divwux);
XEREGISTERINSTR(mulhdx);
XEREGISTERINSTR(mulhdux);
XEREGISTERINSTR(mulhwx);
XEREGISTERINSTR(mulhwux);
XEREGISTERINSTR(mulldx);
XEREGISTERINSTR(mulli);
XEREGISTERINSTR(mullwx);
XEREGISTERINSTR(negx);
XEREGISTERINSTR(subfx);
XEREGISTERINSTR(subfcx);
XEREGISTERINSTR(subficx);
XEREGISTERINSTR(subfex);
XEREGISTERINSTR(subfmex);
XEREGISTERINSTR(subfzex);
XEREGISTERINSTR(cmp);
XEREGISTERINSTR(cmpi);
XEREGISTERINSTR(cmpl);
XEREGISTERINSTR(cmpli);
XEREGISTERINSTR(andx);
XEREGISTERINSTR(andcx);
XEREGISTERINSTR(andix);
XEREGISTERINSTR(andisx);
XEREGISTERINSTR(cntlzdx);
XEREGISTERINSTR(cntlzwx);
XEREGISTERINSTR(eqvx);
XEREGISTERINSTR(extsbx);
XEREGISTERINSTR(extshx);
XEREGISTERINSTR(extswx);
XEREGISTERINSTR(nandx);
XEREGISTERINSTR(norx);
XEREGISTERINSTR(orx);
XEREGISTERINSTR(orcx);
XEREGISTERINSTR(ori);
XEREGISTERINSTR(oris);
XEREGISTERINSTR(xorx);
XEREGISTERINSTR(xori);
XEREGISTERINSTR(xoris);
XEREGISTERINSTR(rldclx);
XEREGISTERINSTR(rldcrx);
XEREGISTERINSTR(rldicx);
XEREGISTERINSTR(rldiclx);
XEREGISTERINSTR(rldicrx);
XEREGISTERINSTR(rldimix);
XEREGISTERINSTR(rlwimix);
XEREGISTERINSTR(rlwinmx);
XEREGISTERINSTR(rlwnmx);
XEREGISTERINSTR(sldx);
XEREGISTERINSTR(slwx);
XEREGISTERINSTR(srdx);
XEREGISTERINSTR(srwx);
XEREGISTERINSTR(sradx);
XEREGISTERINSTR(sradix);
XEREGISTERINSTR(srawx);
XEREGISTERINSTR(srawix);
}
} // namespace ppc

View File

@@ -142,7 +142,7 @@ int InstrEmit_branch(PPCHIRBuilder& f, const char* src, uint64_t cia,
return 0;
}
XEEMITTER(bx, 0x48000000, I)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_bx(PPCHIRBuilder& f, const InstrData& i) {
// if AA then
// NIA <- EXTS(LI || 0b00)
// else
@@ -161,7 +161,7 @@ XEEMITTER(bx, 0x48000000, I)(PPCHIRBuilder& f, InstrData& i) {
i.I.LK);
}
XEEMITTER(bcx, 0x40000000, B)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_bcx(PPCHIRBuilder& f, const InstrData& i) {
// if ¬BO[2] then
// CTR <- CTR - 1
// ctr_ok <- BO[2] | ((CTR[0:63] != 0) XOR BO[3])
@@ -238,7 +238,7 @@ XEEMITTER(bcx, 0x40000000, B)(PPCHIRBuilder& f, InstrData& i) {
i.B.LK, ok, expect_true);
}
XEEMITTER(bcctrx, 0x4C000420, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_bcctrx(PPCHIRBuilder& f, const InstrData& i) {
// cond_ok <- BO[0] | (CR[BI+32] ≡ BO[1])
// if cond_ok then
// NIA <- CTR[0:61] || 0b00
@@ -270,7 +270,7 @@ XEEMITTER(bcctrx, 0x4C000420, XL)(PPCHIRBuilder& f, InstrData& i) {
expect_true);
}
XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_bclrx(PPCHIRBuilder& f, const InstrData& i) {
// if ¬BO[2] then
// CTR <- CTR - 1
// ctr_ok <- BO[2] | ((CTR[0:63] != 0) XOR BO[3]
@@ -340,7 +340,7 @@ XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) {
// Condition register logical (A-23)
XEEMITTER(crand, 0x4C000202, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_crand(PPCHIRBuilder& f, const InstrData& i) {
// CR[bt] <- CR[ba] & CR[bb] bt=bo, ba=bi, bb=bb
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
@@ -349,7 +349,7 @@ XEEMITTER(crand, 0x4C000202, XL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(crandc, 0x4C000102, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_crandc(PPCHIRBuilder& f, const InstrData& i) {
// CR[bt] <- CR[ba] & ¬CR[bb] bt=bo, ba=bi, bb=bb
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
@@ -358,7 +358,7 @@ XEEMITTER(crandc, 0x4C000102, XL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(creqv, 0x4C000242, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_creqv(PPCHIRBuilder& f, const InstrData& i) {
// CR[bt] <- CR[ba] == CR[bb] bt=bo, ba=bi, bb=bb
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
@@ -367,7 +367,7 @@ XEEMITTER(creqv, 0x4C000242, XL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(crnand, 0x4C0001C2, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_crnand(PPCHIRBuilder& f, const InstrData& i) {
// CR[bt] <- ¬(CR[ba] & CR[bb]) bt=bo, ba=bi, bb=bb
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
@@ -376,7 +376,7 @@ XEEMITTER(crnand, 0x4C0001C2, XL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(crnor, 0x4C000042, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_crnor(PPCHIRBuilder& f, const InstrData& i) {
// CR[bt] <- ¬(CR[ba] | CR[bb]) bt=bo, ba=bi, bb=bb
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
@@ -385,7 +385,7 @@ XEEMITTER(crnor, 0x4C000042, XL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(cror, 0x4C000382, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_cror(PPCHIRBuilder& f, const InstrData& i) {
// CR[bt] <- CR[ba] | CR[bb] bt=bo, ba=bi, bb=bb
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
@@ -394,7 +394,7 @@ XEEMITTER(cror, 0x4C000382, XL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(crorc, 0x4C000342, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_crorc(PPCHIRBuilder& f, const InstrData& i) {
// CR[bt] <- CR[ba] | ¬CR[bb] bt=bo, ba=bi, bb=bb
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
@@ -403,7 +403,7 @@ XEEMITTER(crorc, 0x4C000342, XL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(crxor, 0x4C000182, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_crxor(PPCHIRBuilder& f, const InstrData& i) {
// CR[bt] <- CR[ba] xor CR[bb] bt=bo, ba=bi, bb=bb
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
@@ -412,21 +412,21 @@ XEEMITTER(crxor, 0x4C000182, XL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mcrf, 0x4C000000, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mcrf(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// System linkage (A-24)
XEEMITTER(sc, 0x44000002, SC)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sc(PPCHIRBuilder& f, const InstrData& i) {
f.CallExtern(f.function());
return 0;
}
// Trap (A-25)
int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, Value* va, Value* vb,
int InstrEmit_trap(PPCHIRBuilder& f, const InstrData& i, Value* va, Value* vb,
uint32_t TO) {
// if (a < b) & TO[0] then TRAP
// if (a > b) & TO[1] then TRAP
@@ -471,7 +471,7 @@ int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, Value* va, Value* vb,
return 0;
}
XEEMITTER(td, 0x7C000088, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_td(PPCHIRBuilder& f, const InstrData& i) {
// a <- (RA)
// b <- (RB)
// if (a < b) & TO[0] then TRAP
@@ -484,7 +484,7 @@ XEEMITTER(td, 0x7C000088, X)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_trap(f, i, ra, rb, i.X.RT);
}
XEEMITTER(tdi, 0x08000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_tdi(PPCHIRBuilder& f, const InstrData& i) {
// a <- (RA)
// if (a < EXTS(SI)) & TO[0] then TRAP
// if (a > EXTS(SI)) & TO[1] then TRAP
@@ -496,7 +496,7 @@ XEEMITTER(tdi, 0x08000000, D)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_trap(f, i, ra, rb, i.D.RT);
}
XEEMITTER(tw, 0x7C000008, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_tw(PPCHIRBuilder& f, const InstrData& i) {
// a <- EXTS((RA)[32:63])
// b <- EXTS((RB)[32:63])
// if (a < b) & TO[0] then TRAP
@@ -511,7 +511,7 @@ XEEMITTER(tw, 0x7C000008, X)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_trap(f, i, ra, rb, i.X.RT);
}
XEEMITTER(twi, 0x0C000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_twi(PPCHIRBuilder& f, const InstrData& i) {
// a <- EXTS((RA)[32:63])
// if (a < EXTS(SI)) & TO[0] then TRAP
// if (a > EXTS(SI)) & TO[1] then TRAP
@@ -532,7 +532,7 @@ XEEMITTER(twi, 0x0C000000, D)(PPCHIRBuilder& f, InstrData& i) {
// Processor control (A-26)
XEEMITTER(mfcr, 0x7C000026, XFX)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mfcr(PPCHIRBuilder& f, const InstrData& i) {
// mfocrf RT,FXM
// RT <- undefined
// count <- 0
@@ -573,7 +573,7 @@ XEEMITTER(mfcr, 0x7C000026, XFX)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mfspr(PPCHIRBuilder& f, const InstrData& i) {
// n <- spr[5:9] || spr[0:4]
// if length(SPR(n)) = 64 then
// RT <- SPR(n)
@@ -614,7 +614,7 @@ XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mftb(PPCHIRBuilder& f, const InstrData& i) {
Value* time = f.LoadClock();
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
if (n == 268) {
@@ -627,7 +627,7 @@ XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mtcrf, 0x7C000120, XFX)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mtcrf(PPCHIRBuilder& f, const InstrData& i) {
// mtocrf FXM,RS
// count <- 0
// do i = 0 to 7
@@ -666,7 +666,7 @@ XEEMITTER(mtcrf, 0x7C000120, XFX)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mtspr(PPCHIRBuilder& f, const InstrData& i) {
// n <- spr[5:9] || spr[0:4]
// if length(SPR(n)) = 64 then
// SPR(n) <- (RS)
@@ -705,7 +705,7 @@ XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
// code requires it. Sequences of mtmsr/lwar/stcw/mtmsr come up a lot, and
// without the lock here threads can livelock.
XEEMITTER(mfmsr, 0x7C0000A6, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mfmsr(PPCHIRBuilder& f, const InstrData& i) {
// bit 48 = EE; interrupt enabled
// bit 62 = RI; recoverable interrupt
// return 8000h if unlocked (interrupts enabled), else 0
@@ -715,7 +715,7 @@ XEEMITTER(mfmsr, 0x7C0000A6, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mtmsr, 0x7C000124, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mtmsr(PPCHIRBuilder& f, const InstrData& i) {
if (i.X.RA & 0x01) {
// L = 1
// iff storing from r13
@@ -738,7 +738,7 @@ XEEMITTER(mtmsr, 0x7C000124, X)(PPCHIRBuilder& f, InstrData& i) {
}
}
XEEMITTER(mtmsrd, 0x7C000164, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mtmsrd(PPCHIRBuilder& f, const InstrData& i) {
if (i.X.RA & 0x01) {
// L = 1
f.MemoryBarrier();
@@ -760,32 +760,32 @@ XEEMITTER(mtmsrd, 0x7C000164, X)(PPCHIRBuilder& f, InstrData& i) {
}
void RegisterEmitCategoryControl() {
XEREGISTERINSTR(bx, 0x48000000);
XEREGISTERINSTR(bcx, 0x40000000);
XEREGISTERINSTR(bcctrx, 0x4C000420);
XEREGISTERINSTR(bclrx, 0x4C000020);
XEREGISTERINSTR(crand, 0x4C000202);
XEREGISTERINSTR(crandc, 0x4C000102);
XEREGISTERINSTR(creqv, 0x4C000242);
XEREGISTERINSTR(crnand, 0x4C0001C2);
XEREGISTERINSTR(crnor, 0x4C000042);
XEREGISTERINSTR(cror, 0x4C000382);
XEREGISTERINSTR(crorc, 0x4C000342);
XEREGISTERINSTR(crxor, 0x4C000182);
XEREGISTERINSTR(mcrf, 0x4C000000);
XEREGISTERINSTR(sc, 0x44000002);
XEREGISTERINSTR(td, 0x7C000088);
XEREGISTERINSTR(tdi, 0x08000000);
XEREGISTERINSTR(tw, 0x7C000008);
XEREGISTERINSTR(twi, 0x0C000000);
XEREGISTERINSTR(mfcr, 0x7C000026);
XEREGISTERINSTR(mfspr, 0x7C0002A6);
XEREGISTERINSTR(mftb, 0x7C0002E6);
XEREGISTERINSTR(mtcrf, 0x7C000120);
XEREGISTERINSTR(mtspr, 0x7C0003A6);
XEREGISTERINSTR(mfmsr, 0x7C0000A6);
XEREGISTERINSTR(mtmsr, 0x7C000124);
XEREGISTERINSTR(mtmsrd, 0x7C000164);
XEREGISTERINSTR(bx);
XEREGISTERINSTR(bcx);
XEREGISTERINSTR(bcctrx);
XEREGISTERINSTR(bclrx);
XEREGISTERINSTR(crand);
XEREGISTERINSTR(crandc);
XEREGISTERINSTR(creqv);
XEREGISTERINSTR(crnand);
XEREGISTERINSTR(crnor);
XEREGISTERINSTR(cror);
XEREGISTERINSTR(crorc);
XEREGISTERINSTR(crxor);
XEREGISTERINSTR(mcrf);
XEREGISTERINSTR(sc);
XEREGISTERINSTR(td);
XEREGISTERINSTR(tdi);
XEREGISTERINSTR(tw);
XEREGISTERINSTR(twi);
XEREGISTERINSTR(mfcr);
XEREGISTERINSTR(mfspr);
XEREGISTERINSTR(mftb);
XEREGISTERINSTR(mtcrf);
XEREGISTERINSTR(mtspr);
XEREGISTERINSTR(mfmsr);
XEREGISTERINSTR(mtmsr);
XEREGISTERINSTR(mtmsrd);
}
} // namespace ppc

View File

@@ -33,7 +33,7 @@ using xe::cpu::hir::Value;
// Floating-point arithmetic (A-8)
XEEMITTER(faddx, 0xFC00002A, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_faddx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA) + (frB)
Value* v = f.Add(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
@@ -46,7 +46,7 @@ XEEMITTER(faddx, 0xFC00002A, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(faddsx, 0xEC00002A, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_faddsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA) + (frB)
Value* v = f.Add(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
@@ -60,7 +60,7 @@ XEEMITTER(faddsx, 0xEC00002A, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fdivx, 0xFC000024, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fdivx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- frA / frB
Value* v = f.Div(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
@@ -73,7 +73,7 @@ XEEMITTER(fdivx, 0xFC000024, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fdivsx, 0xEC000024, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fdivsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- frA / frB
Value* v = f.Div(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
@@ -87,7 +87,7 @@ XEEMITTER(fdivsx, 0xEC000024, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fmulx, 0xFC000032, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fmulx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA) x (frC)
Value* v = f.Mul(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC));
f.StoreFPR(i.A.FRT, v);
@@ -100,7 +100,7 @@ XEEMITTER(fmulx, 0xFC000032, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fmulsx, 0xEC000032, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fmulsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA) x (frC)
Value* v = f.Mul(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
@@ -114,7 +114,7 @@ XEEMITTER(fmulsx, 0xEC000032, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fresx, 0xEC000030, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fresx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- 1.0 / (frB)
Value* v = f.Convert(f.Div(f.LoadConstantFloat32(1.0f),
f.Convert(f.LoadFPR(i.A.FRB), FLOAT32_TYPE)),
@@ -129,7 +129,7 @@ XEEMITTER(fresx, 0xEC000030, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(frsqrtex, 0xFC000034, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_frsqrtex(PPCHIRBuilder& f, const InstrData& i) {
// Double precision:
// frD <- 1/sqrt(frB)
Value* v = f.RSqrt(f.LoadFPR(i.A.FRB));
@@ -143,7 +143,7 @@ XEEMITTER(frsqrtex, 0xFC000034, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fsubx, 0xFC000028, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fsubx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA) - (frB)
Value* v = f.Sub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
@@ -156,7 +156,7 @@ XEEMITTER(fsubx, 0xFC000028, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fsubsx, 0xEC000028, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fsubsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA) - (frB)
Value* v = f.Sub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
@@ -170,7 +170,7 @@ XEEMITTER(fsubsx, 0xEC000028, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fselx, 0xFC00002E, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fselx(PPCHIRBuilder& f, const InstrData& i) {
// if (frA) >= 0.0
// then frD <- (frC)
// else frD <- (frB)
@@ -185,7 +185,7 @@ XEEMITTER(fselx, 0xFC00002E, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fsqrtx, 0xFC00002C, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fsqrtx(PPCHIRBuilder& f, const InstrData& i) {
// Double precision:
// frD <- sqrt(frB)
Value* v = f.Sqrt(f.LoadFPR(i.A.FRB));
@@ -199,7 +199,7 @@ XEEMITTER(fsqrtx, 0xFC00002C, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fsqrtsx, 0xEC00002C, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fsqrtsx(PPCHIRBuilder& f, const InstrData& i) {
// Single precision:
// frD <- sqrt(frB)
Value* v = f.Sqrt(f.LoadFPR(i.A.FRB));
@@ -216,7 +216,7 @@ XEEMITTER(fsqrtsx, 0xEC00002C, A)(PPCHIRBuilder& f, InstrData& i) {
// Floating-point multiply-add (A-9)
XEEMITTER(fmaddx, 0xFC00003A, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fmaddx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA x frC) + frB
Value* v =
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
@@ -230,7 +230,7 @@ XEEMITTER(fmaddx, 0xFC00003A, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fmaddsx, 0xEC00003A, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fmaddsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA x frC) + frB
Value* v =
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
@@ -245,7 +245,7 @@ XEEMITTER(fmaddsx, 0xEC00003A, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fmsubx, 0xFC000038, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fmsubx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA x frC) - frB
Value* v =
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
@@ -259,7 +259,7 @@ XEEMITTER(fmsubx, 0xFC000038, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fmsubsx, 0xEC000038, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fmsubsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frA x frC) - frB
Value* v =
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
@@ -274,7 +274,7 @@ XEEMITTER(fmsubsx, 0xEC000038, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fnmaddx, 0xFC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fnmaddx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- -([frA x frC] + frB)
Value* v = f.Neg(
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
@@ -288,7 +288,7 @@ XEEMITTER(fnmaddx, 0xFC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fnmaddsx, 0xEC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fnmaddsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- -([frA x frC] + frB)
Value* v = f.Neg(
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
@@ -303,7 +303,7 @@ XEEMITTER(fnmaddsx, 0xEC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fnmsubx, 0xFC00003C, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fnmsubx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- -([frA x frC] - frB)
Value* v = f.Neg(
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
@@ -317,7 +317,7 @@ XEEMITTER(fnmsubx, 0xFC00003C, A)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fnmsubsx, 0xEC00003C, A)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fnmsubsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- -([frA x frC] - frB)
Value* v = f.Neg(
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
@@ -334,7 +334,7 @@ XEEMITTER(fnmsubsx, 0xEC00003C, A)(PPCHIRBuilder& f, InstrData& i) {
// Floating-point rounding and conversion (A-10)
XEEMITTER(fcfidx, 0xFC00069C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fcfidx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- signed_int64_to_double( frB )
Value* v = f.Convert(f.Cast(f.LoadFPR(i.X.RB), INT64_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.X.RT, v);
@@ -347,7 +347,7 @@ XEEMITTER(fcfidx, 0xFC00069C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fctidx, 0xFC00065C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fctidx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- double_to_signed_int64( frB )
// TODO(benvanik): pull from FPSCR[RN]
RoundMode round_mode = ROUND_TO_ZERO;
@@ -363,12 +363,12 @@ XEEMITTER(fctidx, 0xFC00065C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fctidzx, 0xFC00065E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fctidzx(PPCHIRBuilder& f, const InstrData& i) {
// TODO(benvanik): assuming round to zero is always set, is that ok?
return InstrEmit_fctidx(f, i);
}
XEEMITTER(fctiwx, 0xFC00001C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fctiwx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- double_to_signed_int32( frB )
// TODO(benvanik): pull from FPSCR[RN]
RoundMode round_mode = ROUND_TO_ZERO;
@@ -384,12 +384,12 @@ XEEMITTER(fctiwx, 0xFC00001C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fctiwzx, 0xFC00001E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fctiwzx(PPCHIRBuilder& f, const InstrData& i) {
// TODO(benvanik): assuming round to zero is always set, is that ok?
return InstrEmit_fctiwx(f, i);
}
XEEMITTER(frspx, 0xFC000018, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_frspx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- Round_single(frB)
// TODO(benvanik): pull from FPSCR[RN]
RoundMode round_mode = ROUND_TO_ZERO;
@@ -407,7 +407,7 @@ XEEMITTER(frspx, 0xFC000018, X)(PPCHIRBuilder& f, InstrData& i) {
// Floating-point compare (A-11)
int InstrEmit_fcmpx_(PPCHIRBuilder& f, InstrData& i, bool ordered) {
int InstrEmit_fcmpx_(PPCHIRBuilder& f, const InstrData& i, bool ordered) {
// if (FRA) is a NaN or (FRB) is a NaN then
// c <- 0b0001
// else if (FRA) < (FRB) then
@@ -429,21 +429,21 @@ int InstrEmit_fcmpx_(PPCHIRBuilder& f, InstrData& i, bool ordered) {
f.UpdateCR(crf, f.LoadFPR(i.X.RA), f.LoadFPR(i.X.RB), false);
return 0;
}
XEEMITTER(fcmpo, 0xFC000040, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fcmpo(PPCHIRBuilder& f, const InstrData& i) {
return InstrEmit_fcmpx_(f, i, true);
}
XEEMITTER(fcmpu, 0xFC000000, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fcmpu(PPCHIRBuilder& f, const InstrData& i) {
return InstrEmit_fcmpx_(f, i, false);
}
// Floating-point status and control register (A
XEEMITTER(mcrfs, 0xFC000080, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mcrfs(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mffsx, 0xFC00048E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mffsx(PPCHIRBuilder& f, const InstrData& i) {
if (i.X.Rc) {
XEINSTRNOTIMPLEMENTED();
return 1;
@@ -453,17 +453,17 @@ XEEMITTER(mffsx, 0xFC00048E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mtfsb0x, 0xFC00008C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mtfsb0x(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mtfsb1x, 0xFC00004C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mtfsb1x(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mtfsfx(PPCHIRBuilder& f, const InstrData& i) {
if (i.XFL.Rc) {
XEINSTRNOTIMPLEMENTED();
return 1;
@@ -482,14 +482,14 @@ XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mtfsfix, 0xFC00010C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_mtfsfix(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Floating-point move (A-21)
XEEMITTER(fabsx, 0xFC000210, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fabsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- abs(frB)
Value* v = f.Abs(f.LoadFPR(i.X.RB));
f.StoreFPR(i.X.RT, v);
@@ -501,7 +501,7 @@ XEEMITTER(fabsx, 0xFC000210, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fmrx, 0xFC000090, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fmrx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- (frB)
Value* v = f.LoadFPR(i.X.RB);
f.StoreFPR(i.X.RT, v);
@@ -513,7 +513,7 @@ XEEMITTER(fmrx, 0xFC000090, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fnabsx, 0xFC000110, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fnabsx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- !abs(frB)
Value* v = f.Neg(f.Abs(f.LoadFPR(i.X.RB)));
f.StoreFPR(i.X.RT, v);
@@ -525,7 +525,7 @@ XEEMITTER(fnabsx, 0xFC000110, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(fnegx, 0xFC000050, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_fnegx(PPCHIRBuilder& f, const InstrData& i) {
// frD <- ¬ frB[0] || frB[1-63]
Value* v = f.Neg(f.LoadFPR(i.X.RB));
f.StoreFPR(i.X.RT, v);
@@ -538,45 +538,45 @@ XEEMITTER(fnegx, 0xFC000050, X)(PPCHIRBuilder& f, InstrData& i) {
}
void RegisterEmitCategoryFPU() {
XEREGISTERINSTR(faddx, 0xFC00002A);
XEREGISTERINSTR(faddsx, 0xEC00002A);
XEREGISTERINSTR(fdivx, 0xFC000024);
XEREGISTERINSTR(fdivsx, 0xEC000024);
XEREGISTERINSTR(fmulx, 0xFC000032);
XEREGISTERINSTR(fmulsx, 0xEC000032);
XEREGISTERINSTR(fresx, 0xEC000030);
XEREGISTERINSTR(frsqrtex, 0xFC000034);
XEREGISTERINSTR(fsubx, 0xFC000028);
XEREGISTERINSTR(fsubsx, 0xEC000028);
XEREGISTERINSTR(fselx, 0xFC00002E);
XEREGISTERINSTR(fsqrtx, 0xFC00002C);
XEREGISTERINSTR(fsqrtsx, 0xEC00002C);
XEREGISTERINSTR(fmaddx, 0xFC00003A);
XEREGISTERINSTR(fmaddsx, 0xEC00003A);
XEREGISTERINSTR(fmsubx, 0xFC000038);
XEREGISTERINSTR(fmsubsx, 0xEC000038);
XEREGISTERINSTR(fnmaddx, 0xFC00003E);
XEREGISTERINSTR(fnmaddsx, 0xEC00003E);
XEREGISTERINSTR(fnmsubx, 0xFC00003C);
XEREGISTERINSTR(fnmsubsx, 0xEC00003C);
XEREGISTERINSTR(fcfidx, 0xFC00069C);
XEREGISTERINSTR(fctidx, 0xFC00065C);
XEREGISTERINSTR(fctidzx, 0xFC00065E);
XEREGISTERINSTR(fctiwx, 0xFC00001C);
XEREGISTERINSTR(fctiwzx, 0xFC00001E);
XEREGISTERINSTR(frspx, 0xFC000018);
XEREGISTERINSTR(fcmpo, 0xFC000040);
XEREGISTERINSTR(fcmpu, 0xFC000000);
XEREGISTERINSTR(mcrfs, 0xFC000080);
XEREGISTERINSTR(mffsx, 0xFC00048E);
XEREGISTERINSTR(mtfsb0x, 0xFC00008C);
XEREGISTERINSTR(mtfsb1x, 0xFC00004C);
XEREGISTERINSTR(mtfsfx, 0xFC00058E);
XEREGISTERINSTR(mtfsfix, 0xFC00010C);
XEREGISTERINSTR(fabsx, 0xFC000210);
XEREGISTERINSTR(fmrx, 0xFC000090);
XEREGISTERINSTR(fnabsx, 0xFC000110);
XEREGISTERINSTR(fnegx, 0xFC000050);
XEREGISTERINSTR(faddx);
XEREGISTERINSTR(faddsx);
XEREGISTERINSTR(fdivx);
XEREGISTERINSTR(fdivsx);
XEREGISTERINSTR(fmulx);
XEREGISTERINSTR(fmulsx);
XEREGISTERINSTR(fresx);
XEREGISTERINSTR(frsqrtex);
XEREGISTERINSTR(fsubx);
XEREGISTERINSTR(fsubsx);
XEREGISTERINSTR(fselx);
XEREGISTERINSTR(fsqrtx);
XEREGISTERINSTR(fsqrtsx);
XEREGISTERINSTR(fmaddx);
XEREGISTERINSTR(fmaddsx);
XEREGISTERINSTR(fmsubx);
XEREGISTERINSTR(fmsubsx);
XEREGISTERINSTR(fnmaddx);
XEREGISTERINSTR(fnmaddsx);
XEREGISTERINSTR(fnmsubx);
XEREGISTERINSTR(fnmsubsx);
XEREGISTERINSTR(fcfidx);
XEREGISTERINSTR(fctidx);
XEREGISTERINSTR(fctidzx);
XEREGISTERINSTR(fctiwx);
XEREGISTERINSTR(fctiwzx);
XEREGISTERINSTR(frspx);
XEREGISTERINSTR(fcmpo);
XEREGISTERINSTR(fcmpu);
XEREGISTERINSTR(mcrfs);
XEREGISTERINSTR(mffsx);
XEREGISTERINSTR(mtfsb0x);
XEREGISTERINSTR(mtfsb1x);
XEREGISTERINSTR(mtfsfx);
XEREGISTERINSTR(mtfsfix);
XEREGISTERINSTR(fabsx);
XEREGISTERINSTR(fmrx);
XEREGISTERINSTR(fnabsx);
XEREGISTERINSTR(fnegx);
}
} // namespace ppc

View File

@@ -54,7 +54,7 @@ void StoreEA(PPCHIRBuilder& f, uint32_t rt, Value* ea) {
// Integer load (A-13)
XEEMITTER(lbz, 0x88000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lbz(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -67,7 +67,7 @@ XEEMITTER(lbz, 0x88000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lbzu, 0x8C000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lbzu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- i56.0 || MEM(EA, 1)
// RA <- EA
@@ -78,7 +78,7 @@ XEEMITTER(lbzu, 0x8C000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lbzux, 0x7C0000EE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lbzux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// RT <- i56.0 || MEM(EA, 1)
// RA <- EA
@@ -89,7 +89,7 @@ XEEMITTER(lbzux, 0x7C0000EE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lbzx, 0x7C0000AE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lbzx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -102,7 +102,7 @@ XEEMITTER(lbzx, 0x7C0000AE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lha, 0xA8000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lha(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -115,7 +115,7 @@ XEEMITTER(lha, 0xA8000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhau, 0xAC000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lhau(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- EXTS(MEM(EA, 2))
// RA <- EA
@@ -126,7 +126,7 @@ XEEMITTER(lhau, 0xAC000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhaux, 0x7C0002EE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lhaux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// RT <- EXTS(MEM(EA, 2))
// RA <- EA
@@ -137,7 +137,7 @@ XEEMITTER(lhaux, 0x7C0002EE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhax, 0x7C0002AE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lhax(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -150,7 +150,7 @@ XEEMITTER(lhax, 0x7C0002AE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhz, 0xA0000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lhz(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -163,7 +163,7 @@ XEEMITTER(lhz, 0xA0000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhzu, 0xA4000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lhzu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- i48.0 || MEM(EA, 2)
// RA <- EA
@@ -174,7 +174,7 @@ XEEMITTER(lhzu, 0xA4000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhzux, 0x7C00026E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lhzux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// RT <- i48.0 || MEM(EA, 2)
// RA <- EA
@@ -185,7 +185,7 @@ XEEMITTER(lhzux, 0x7C00026E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhzx, 0x7C00022E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lhzx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -198,7 +198,7 @@ XEEMITTER(lhzx, 0x7C00022E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwa, 0xE8000002, DS)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwa(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -211,7 +211,7 @@ XEEMITTER(lwa, 0xE8000002, DS)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwaux, 0x7C0002EA, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwaux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// RT <- EXTS(MEM(EA, 4))
// RA <- EA
@@ -222,7 +222,7 @@ XEEMITTER(lwaux, 0x7C0002EA, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwax, 0x7C0002AA, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwax(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -235,7 +235,7 @@ XEEMITTER(lwax, 0x7C0002AA, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwz, 0x80000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwz(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -248,7 +248,7 @@ XEEMITTER(lwz, 0x80000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwzu, 0x84000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwzu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- i32.0 || MEM(EA, 4)
// RA <- EA
@@ -259,7 +259,7 @@ XEEMITTER(lwzu, 0x84000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwzux, 0x7C00006E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwzux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// RT <- i32.0 || MEM(EA, 4)
// RA <- EA
@@ -270,7 +270,7 @@ XEEMITTER(lwzux, 0x7C00006E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwzx, 0x7C00002E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwzx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -283,7 +283,7 @@ XEEMITTER(lwzx, 0x7C00002E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ld, 0xE8000000, DS)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_ld(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -296,7 +296,7 @@ XEEMITTER(ld, 0xE8000000, DS)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ldu, 0xE8000001, DS)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_ldu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(DS || 0b00)
// RT <- MEM(EA, 8)
// RA <- EA
@@ -307,7 +307,7 @@ XEEMITTER(ldu, 0xE8000001, DS)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ldux, 0x7C00006A, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_ldux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// RT <- MEM(EA, 8)
// RA <- EA
@@ -318,7 +318,7 @@ XEEMITTER(ldux, 0x7C00006A, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ldx, 0x7C00002A, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_ldx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -333,7 +333,7 @@ XEEMITTER(ldx, 0x7C00002A, X)(PPCHIRBuilder& f, InstrData& i) {
// Integer store (A-14)
XEEMITTER(stb, 0x98000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stb(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -345,7 +345,7 @@ XEEMITTER(stb, 0x98000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stbu, 0x9C000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stbu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 1) <- (RS)[56:63]
// RA <- EA
@@ -355,7 +355,7 @@ XEEMITTER(stbu, 0x9C000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stbux, 0x7C0001EE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stbux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 1) <- (RS)[56:63]
// RA <- EA
@@ -365,7 +365,7 @@ XEEMITTER(stbux, 0x7C0001EE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stbx, 0x7C0001AE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stbx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -377,7 +377,7 @@ XEEMITTER(stbx, 0x7C0001AE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sth, 0xB0000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sth(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -389,7 +389,7 @@ XEEMITTER(sth, 0xB0000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sthu, 0xB4000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sthu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 2) <- (RS)[48:63]
// RA <- EA
@@ -399,7 +399,7 @@ XEEMITTER(sthu, 0xB4000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sthux, 0x7C00036E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sthux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 2) <- (RS)[48:63]
// RA <- EA
@@ -409,7 +409,7 @@ XEEMITTER(sthux, 0x7C00036E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sthx, 0x7C00032E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sthx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -421,7 +421,7 @@ XEEMITTER(sthx, 0x7C00032E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stw, 0x90000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stw(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -433,7 +433,7 @@ XEEMITTER(stw, 0x90000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwu, 0x94000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stwu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 4) <- (RS)[32:63]
// RA <- EA
@@ -443,7 +443,7 @@ XEEMITTER(stwu, 0x94000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwux, 0x7C00016E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stwux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 4) <- (RS)[32:63]
// RA <- EA
@@ -453,7 +453,7 @@ XEEMITTER(stwux, 0x7C00016E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwx, 0x7C00012E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stwx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -465,7 +465,7 @@ XEEMITTER(stwx, 0x7C00012E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(std, 0xF8000000, DS)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_std(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -477,7 +477,7 @@ XEEMITTER(std, 0xF8000000, DS)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stdu, 0xF8000001, DS)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stdu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(DS || 0b00)
// MEM(EA, 8) <- (RS)
// RA <- EA
@@ -487,7 +487,7 @@ XEEMITTER(stdu, 0xF8000001, DS)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stdux, 0x7C00016A, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stdux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 8) <- (RS)
// RA <- EA
@@ -497,7 +497,7 @@ XEEMITTER(stdux, 0x7C00016A, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stdx, 0x7C00012A, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stdx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -511,7 +511,7 @@ XEEMITTER(stdx, 0x7C00012A, X)(PPCHIRBuilder& f, InstrData& i) {
// Integer load and store with byte reverse (A-1
XEEMITTER(lhbrx, 0x7C00062C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lhbrx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -524,7 +524,7 @@ XEEMITTER(lhbrx, 0x7C00062C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwbrx, 0x7C00042C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwbrx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -537,7 +537,7 @@ XEEMITTER(lwbrx, 0x7C00042C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ldbrx, 0x7C000428, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_ldbrx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -550,7 +550,7 @@ XEEMITTER(ldbrx, 0x7C000428, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sthbrx, 0x7C00072C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sthbrx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -562,7 +562,7 @@ XEEMITTER(sthbrx, 0x7C00072C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwbrx, 0x7C00052C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stwbrx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -574,7 +574,7 @@ XEEMITTER(stwbrx, 0x7C00052C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stdbrx, 0x7C000528, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stdbrx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -588,57 +588,57 @@ XEEMITTER(stdbrx, 0x7C000528, X)(PPCHIRBuilder& f, InstrData& i) {
// Integer load and store multiple (A-16)
XEEMITTER(lmw, 0xB8000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lmw(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(stmw, 0xBC000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stmw(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Integer load and store string (A-17)
XEEMITTER(lswi, 0x7C0004AA, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lswi(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(lswx, 0x7C00042A, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lswx(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(stswi, 0x7C0005AA, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stswi(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(stswx, 0x7C00052A, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stswx(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Memory synchronization (A-18)
XEEMITTER(eieio, 0x7C0006AC, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_eieio(PPCHIRBuilder& f, const InstrData& i) {
f.MemoryBarrier();
return 0;
}
XEEMITTER(sync, 0x7C0004AC, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_sync(PPCHIRBuilder& f, const InstrData& i) {
f.MemoryBarrier();
return 0;
}
XEEMITTER(isync, 0x4C00012C, XL)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_isync(PPCHIRBuilder& f, const InstrData& i) {
// XEINSTRNOTIMPLEMENTED();
f.Nop();
return 0;
}
XEEMITTER(ldarx, 0x7C0000A8, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_ldarx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -662,7 +662,7 @@ XEEMITTER(ldarx, 0x7C0000A8, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwarx, 0x7C000028, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lwarx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -686,7 +686,7 @@ XEEMITTER(lwarx, 0x7C000028, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stdcx, 0x7C0001AD, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stdcx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -715,7 +715,7 @@ XEEMITTER(stdcx, 0x7C0001AD, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwcx, 0x7C00012D, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stwcx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -746,7 +746,7 @@ XEEMITTER(stwcx, 0x7C00012D, X)(PPCHIRBuilder& f, InstrData& i) {
// Floating-point load (A-19)
XEEMITTER(lfd, 0xC8000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lfd(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -759,7 +759,7 @@ XEEMITTER(lfd, 0xC8000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfdu, 0xCC000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lfdu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// FRT <- MEM(EA, 8)
// RA <- EA
@@ -770,7 +770,7 @@ XEEMITTER(lfdu, 0xCC000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfdux, 0x7C0004EE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lfdux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// FRT <- MEM(EA, 8)
// RA <- EA
@@ -781,7 +781,7 @@ XEEMITTER(lfdux, 0x7C0004EE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfdx, 0x7C0004AE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lfdx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -794,7 +794,7 @@ XEEMITTER(lfdx, 0x7C0004AE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfs, 0xC0000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lfs(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -808,7 +808,7 @@ XEEMITTER(lfs, 0xC0000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfsu, 0xC4000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lfsu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// FRT <- DOUBLE(MEM(EA, 4))
// RA <- EA
@@ -820,7 +820,7 @@ XEEMITTER(lfsu, 0xC4000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfsux, 0x7C00046E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lfsux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// FRT <- DOUBLE(MEM(EA, 4))
// RA <- EA
@@ -832,7 +832,7 @@ XEEMITTER(lfsux, 0x7C00046E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfsx, 0x7C00042E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_lfsx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -848,7 +848,7 @@ XEEMITTER(lfsx, 0x7C00042E, X)(PPCHIRBuilder& f, InstrData& i) {
// Floating-point store (A-20)
XEEMITTER(stfd, 0xD8000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfd(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -860,7 +860,7 @@ XEEMITTER(stfd, 0xD8000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfdu, 0xDC000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfdu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 8) <- (FRS)
// RA <- EA
@@ -870,7 +870,7 @@ XEEMITTER(stfdu, 0xDC000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfdux, 0x7C0005EE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfdux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 8) <- (FRS)
// RA <- EA
@@ -880,7 +880,7 @@ XEEMITTER(stfdux, 0x7C0005EE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfdx, 0x7C0005AE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfdx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -892,7 +892,7 @@ XEEMITTER(stfdx, 0x7C0005AE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfiwx, 0x7C0007AE, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfiwx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -905,7 +905,7 @@ XEEMITTER(stfiwx, 0x7C0007AE, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfs, 0xD0000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfs(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -918,7 +918,7 @@ XEEMITTER(stfs, 0xD0000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfsu, 0xD4000000, D)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfsu(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 4) <- SINGLE(FRS)
// RA <- EA
@@ -929,7 +929,7 @@ XEEMITTER(stfsu, 0xD4000000, D)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfsux, 0x7C00056E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfsux(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 4) <- SINGLE(FRS)
// RA <- EA
@@ -940,7 +940,7 @@ XEEMITTER(stfsux, 0x7C00056E, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfsx, 0x7C00052E, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_stfsx(PPCHIRBuilder& f, const InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -955,7 +955,7 @@ XEEMITTER(stfsx, 0x7C00052E, X)(PPCHIRBuilder& f, InstrData& i) {
// Cache management (A-27)
XEEMITTER(dcbf, 0x7C0000AC, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_dcbf(PPCHIRBuilder& f, const InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// XEINSTRNOTIMPLEMENTED();
@@ -963,7 +963,7 @@ XEEMITTER(dcbf, 0x7C0000AC, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(dcbst, 0x7C00006C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_dcbst(PPCHIRBuilder& f, const InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// XEINSTRNOTIMPLEMENTED();
@@ -971,7 +971,7 @@ XEEMITTER(dcbst, 0x7C00006C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(dcbt, 0x7C00022C, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_dcbt(PPCHIRBuilder& f, const InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// XEINSTRNOTIMPLEMENTED();
@@ -979,7 +979,7 @@ XEEMITTER(dcbt, 0x7C00022C, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(dcbtst, 0x7C0001EC, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_dcbtst(PPCHIRBuilder& f, const InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// XEINSTRNOTIMPLEMENTED();
@@ -987,115 +987,119 @@ XEEMITTER(dcbtst, 0x7C0001EC, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(dcbz, 0x7C0007EC, X)(PPCHIRBuilder& f, InstrData& i) {
// or dcbz128 0x7C2007EC
int InstrEmit_dcbz(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// memset(EA & ~31, 0, 32)
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
int block_size;
int address_mask;
if (i.X.RT == 1) {
// dcbz128 - 128 byte set
block_size = 128;
address_mask = ~127;
} else {
// dcbz - 32 byte set
block_size = 32;
address_mask = ~31;
}
// dcbz - 32 byte set
int block_size = 32;
int address_mask = ~31;
f.Memset(f.And(ea, f.LoadConstantInt64(address_mask)), f.LoadZeroInt8(),
f.LoadConstantInt64(block_size));
return 0;
}
XEEMITTER(icbi, 0x7C0007AC, X)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_dcbz128(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// memset(EA & ~31, 0, 32)
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
// dcbz128 - 128 byte set
int block_size = 128;
int address_mask = ~127;
f.Memset(f.And(ea, f.LoadConstantInt64(address_mask)), f.LoadZeroInt8(),
f.LoadConstantInt64(block_size));
return 0;
}
int InstrEmit_icbi(PPCHIRBuilder& f, const InstrData& i) {
// XEINSTRNOTIMPLEMENTED();
f.Nop();
return 0;
}
void RegisterEmitCategoryMemory() {
XEREGISTERINSTR(lbz, 0x88000000);
XEREGISTERINSTR(lbzu, 0x8C000000);
XEREGISTERINSTR(lbzux, 0x7C0000EE);
XEREGISTERINSTR(lbzx, 0x7C0000AE);
XEREGISTERINSTR(lha, 0xA8000000);
XEREGISTERINSTR(lhau, 0xAC000000);
XEREGISTERINSTR(lhaux, 0x7C0002EE);
XEREGISTERINSTR(lhax, 0x7C0002AE);
XEREGISTERINSTR(lhz, 0xA0000000);
XEREGISTERINSTR(lhzu, 0xA4000000);
XEREGISTERINSTR(lhzux, 0x7C00026E);
XEREGISTERINSTR(lhzx, 0x7C00022E);
XEREGISTERINSTR(lwa, 0xE8000002);
XEREGISTERINSTR(lwaux, 0x7C0002EA);
XEREGISTERINSTR(lwax, 0x7C0002AA);
XEREGISTERINSTR(lwz, 0x80000000);
XEREGISTERINSTR(lwzu, 0x84000000);
XEREGISTERINSTR(lwzux, 0x7C00006E);
XEREGISTERINSTR(lwzx, 0x7C00002E);
XEREGISTERINSTR(ld, 0xE8000000);
XEREGISTERINSTR(ldu, 0xE8000001);
XEREGISTERINSTR(ldux, 0x7C00006A);
XEREGISTERINSTR(ldx, 0x7C00002A);
XEREGISTERINSTR(stb, 0x98000000);
XEREGISTERINSTR(stbu, 0x9C000000);
XEREGISTERINSTR(stbux, 0x7C0001EE);
XEREGISTERINSTR(stbx, 0x7C0001AE);
XEREGISTERINSTR(sth, 0xB0000000);
XEREGISTERINSTR(sthu, 0xB4000000);
XEREGISTERINSTR(sthux, 0x7C00036E);
XEREGISTERINSTR(sthx, 0x7C00032E);
XEREGISTERINSTR(stw, 0x90000000);
XEREGISTERINSTR(stwu, 0x94000000);
XEREGISTERINSTR(stwux, 0x7C00016E);
XEREGISTERINSTR(stwx, 0x7C00012E);
XEREGISTERINSTR(std, 0xF8000000);
XEREGISTERINSTR(stdu, 0xF8000001);
XEREGISTERINSTR(stdux, 0x7C00016A);
XEREGISTERINSTR(stdx, 0x7C00012A);
XEREGISTERINSTR(lhbrx, 0x7C00062C);
XEREGISTERINSTR(lwbrx, 0x7C00042C);
XEREGISTERINSTR(ldbrx, 0x7C000428);
XEREGISTERINSTR(sthbrx, 0x7C00072C);
XEREGISTERINSTR(stwbrx, 0x7C00052C);
XEREGISTERINSTR(stdbrx, 0x7C000528);
XEREGISTERINSTR(lmw, 0xB8000000);
XEREGISTERINSTR(stmw, 0xBC000000);
XEREGISTERINSTR(lswi, 0x7C0004AA);
XEREGISTERINSTR(lswx, 0x7C00042A);
XEREGISTERINSTR(stswi, 0x7C0005AA);
XEREGISTERINSTR(stswx, 0x7C00052A);
XEREGISTERINSTR(eieio, 0x7C0006AC);
XEREGISTERINSTR(sync, 0x7C0004AC);
XEREGISTERINSTR(isync, 0x4C00012C);
XEREGISTERINSTR(ldarx, 0x7C0000A8);
XEREGISTERINSTR(lwarx, 0x7C000028);
XEREGISTERINSTR(stdcx, 0x7C0001AD);
XEREGISTERINSTR(stwcx, 0x7C00012D);
XEREGISTERINSTR(lfd, 0xC8000000);
XEREGISTERINSTR(lfdu, 0xCC000000);
XEREGISTERINSTR(lfdux, 0x7C0004EE);
XEREGISTERINSTR(lfdx, 0x7C0004AE);
XEREGISTERINSTR(lfs, 0xC0000000);
XEREGISTERINSTR(lfsu, 0xC4000000);
XEREGISTERINSTR(lfsux, 0x7C00046E);
XEREGISTERINSTR(lfsx, 0x7C00042E);
XEREGISTERINSTR(stfd, 0xD8000000);
XEREGISTERINSTR(stfdu, 0xDC000000);
XEREGISTERINSTR(stfdux, 0x7C0005EE);
XEREGISTERINSTR(stfdx, 0x7C0005AE);
XEREGISTERINSTR(stfiwx, 0x7C0007AE);
XEREGISTERINSTR(stfs, 0xD0000000);
XEREGISTERINSTR(stfsu, 0xD4000000);
XEREGISTERINSTR(stfsux, 0x7C00056E);
XEREGISTERINSTR(stfsx, 0x7C00052E);
XEREGISTERINSTR(dcbf, 0x7C0000AC);
XEREGISTERINSTR(dcbst, 0x7C00006C);
XEREGISTERINSTR(dcbt, 0x7C00022C);
XEREGISTERINSTR(dcbtst, 0x7C0001EC);
XEREGISTERINSTR(dcbz, 0x7C0007EC);
XEREGISTERINSTR(icbi, 0x7C0007AC);
XEREGISTERINSTR(lbz);
XEREGISTERINSTR(lbzu);
XEREGISTERINSTR(lbzux);
XEREGISTERINSTR(lbzx);
XEREGISTERINSTR(lha);
XEREGISTERINSTR(lhau);
XEREGISTERINSTR(lhaux);
XEREGISTERINSTR(lhax);
XEREGISTERINSTR(lhz);
XEREGISTERINSTR(lhzu);
XEREGISTERINSTR(lhzux);
XEREGISTERINSTR(lhzx);
XEREGISTERINSTR(lwa);
XEREGISTERINSTR(lwaux);
XEREGISTERINSTR(lwax);
XEREGISTERINSTR(lwz);
XEREGISTERINSTR(lwzu);
XEREGISTERINSTR(lwzux);
XEREGISTERINSTR(lwzx);
XEREGISTERINSTR(ld);
XEREGISTERINSTR(ldu);
XEREGISTERINSTR(ldux);
XEREGISTERINSTR(ldx);
XEREGISTERINSTR(stb);
XEREGISTERINSTR(stbu);
XEREGISTERINSTR(stbux);
XEREGISTERINSTR(stbx);
XEREGISTERINSTR(sth);
XEREGISTERINSTR(sthu);
XEREGISTERINSTR(sthux);
XEREGISTERINSTR(sthx);
XEREGISTERINSTR(stw);
XEREGISTERINSTR(stwu);
XEREGISTERINSTR(stwux);
XEREGISTERINSTR(stwx);
XEREGISTERINSTR(std);
XEREGISTERINSTR(stdu);
XEREGISTERINSTR(stdux);
XEREGISTERINSTR(stdx);
XEREGISTERINSTR(lhbrx);
XEREGISTERINSTR(lwbrx);
XEREGISTERINSTR(ldbrx);
XEREGISTERINSTR(sthbrx);
XEREGISTERINSTR(stwbrx);
XEREGISTERINSTR(stdbrx);
XEREGISTERINSTR(lmw);
XEREGISTERINSTR(stmw);
XEREGISTERINSTR(lswi);
XEREGISTERINSTR(lswx);
XEREGISTERINSTR(stswi);
XEREGISTERINSTR(stswx);
XEREGISTERINSTR(eieio);
XEREGISTERINSTR(sync);
XEREGISTERINSTR(isync);
XEREGISTERINSTR(ldarx);
XEREGISTERINSTR(lwarx);
XEREGISTERINSTR(stdcx);
XEREGISTERINSTR(stwcx);
XEREGISTERINSTR(lfd);
XEREGISTERINSTR(lfdu);
XEREGISTERINSTR(lfdux);
XEREGISTERINSTR(lfdx);
XEREGISTERINSTR(lfs);
XEREGISTERINSTR(lfsu);
XEREGISTERINSTR(lfsux);
XEREGISTERINSTR(lfsx);
XEREGISTERINSTR(stfd);
XEREGISTERINSTR(stfdu);
XEREGISTERINSTR(stfdux);
XEREGISTERINSTR(stfdx);
XEREGISTERINSTR(stfiwx);
XEREGISTERINSTR(stfs);
XEREGISTERINSTR(stfsu);
XEREGISTERINSTR(stfsux);
XEREGISTERINSTR(stfsx);
XEREGISTERINSTR(dcbf);
XEREGISTERINSTR(dcbst);
XEREGISTERINSTR(dcbt);
XEREGISTERINSTR(dcbtst);
XEREGISTERINSTR(dcbz);
XEREGISTERINSTR(dcbz128);
XEREGISTERINSTR(icbi);
}
} // namespace ppc

View File

@@ -35,6 +35,25 @@ using xe::cpu::hir::Label;
using xe::cpu::hir::TypeName;
using xe::cpu::hir::Value;
// The number of times each opcode has been translated.
// Accumulated across the entire run.
uint32_t opcode_translation_counts[static_cast<int>(PPCOpcode::kInvalid)] = {0};
void DumpAllOpcodeCounts() {
StringBuffer sb;
sb.Append("Instruction translation counts:\n");
for (size_t i = 0; i < xe::countof(opcode_translation_counts); ++i) {
auto opcode = static_cast<PPCOpcode>(i);
auto& opcode_info = GetOpcodeInfo(opcode);
auto translation_count = opcode_translation_counts[i];
if (translation_count) {
sb.AppendFormat("%8d : %s\n", translation_count, opcode_info.name);
}
}
fprintf(stdout, "%s", sb.GetString());
fflush(stdout);
}
PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend)
: HIRBuilder(), frontend_(frontend), comment_buffer_(4096) {}
@@ -123,29 +142,21 @@ bool PPCHIRBuilder::Emit(GuestFunction* function, uint32_t flags) {
// Stash instruction offset. It's either the SOURCE_OFFSET or the COMMENT.
instr_offset_list_[offset] = first_instr;
InstrData i;
i.address = address;
i.code = code;
i.type = GetInstrType(code);
if (!i.type) {
if (opcode == PPCOpcode::kInvalid) {
XELOGE("Invalid instruction %.8llX %.8X", address, code);
Comment("INVALID!");
// TraceInvalidInstruction(i);
continue;
}
++i.type->translation_count;
++opcode_translation_counts[static_cast<int>(opcode)];
// Synchronize the PPC context as required.
// This will ensure all registers are saved to the PPC context before this
// instruction executes.
if (i.type->type & kXEPPCInstrTypeSynchronizeContext) {
if (opcode_info.type == PPCOpcodeType::kSync) {
ContextBarrier();
}
typedef int (*InstrEmitter)(PPCHIRBuilder& f, InstrData& i);
InstrEmitter emit = (InstrEmitter)i.type->emit;
if (address == FLAGS_break_on_instruction) {
Comment("--break-on-instruction target");
@@ -162,15 +173,23 @@ bool PPCHIRBuilder::Emit(GuestFunction* function, uint32_t flags) {
}
}
if (!i.type->emit || emit(*this, i)) {
InstrData i;
i.address = address;
i.code = code;
i.opcode = opcode;
i.opcode_info = &opcode_info;
if (!opcode_info.emit || opcode_info.emit(*this, i)) {
XELOGE("Unimplemented instr %.8llX %.8X %s", address, code,
opcode_info.name);
Comment("UNIMPLEMENTED!");
// DebugBreak();
// TraceInvalidInstruction(i);
DebugBreak();
}
}
if (false) {
DumpAllOpcodeCounts();
}
return Finalize();
}

View File

@@ -22,21 +22,6 @@ namespace xe {
namespace cpu {
namespace ppc {
std::vector<InstrType*> all_instrs_;
void DumpAllInstrCounts() {
StringBuffer sb;
sb.Append("Instruction translation counts:\n");
for (auto instr_type : all_instrs_) {
if (instr_type->translation_count) {
sb.AppendFormat("%8d : %s\n", instr_type->translation_count,
instr_type->name);
}
}
fprintf(stdout, "%s", sb.GetString());
fflush(stdout);
}
void InstrOperand::Dump(std::string& out_str) {
if (display) {
out_str += display;
@@ -393,18 +378,6 @@ InstrType* GetInstrType(uint32_t code) {
return NULL;
}
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
InstrType* instr_type = GetInstrType(code);
assert_not_null(instr_type);
if (!instr_type) {
return 1;
}
all_instrs_.push_back(instr_type);
assert_null(instr_type->emit);
instr_type->emit = emit;
return 0;
}
} // namespace ppc
} // namespace cpu
} // namespace xe

View File

@@ -15,16 +15,17 @@
#include <vector>
#include "xenia/base/string_buffer.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
namespace xe {
namespace cpu {
namespace ppc {
inline uint32_t make_bitmask(uint32_t a, uint32_t b) {
constexpr uint32_t make_bitmask(uint32_t a, uint32_t b) {
return (static_cast<uint32_t>(-1) >> (31 - b)) & ~((1u << a) - 1);
}
inline uint32_t select_bits(uint32_t value, uint32_t a, uint32_t b) {
constexpr uint32_t select_bits(uint32_t value, uint32_t a, uint32_t b) {
return (value & make_bitmask(a, b)) >> a;
}
@@ -72,26 +73,13 @@ enum xe_ppc_instr_mask_e : uint32_t {
kXEPPCInstrMaskVX128_R = 0xFC000390,
};
typedef enum {
kXEPPCInstrTypeGeneral = (1 << 0),
kXEPPCInstrTypeSynchronizeContext = (1 << 1),
kXEPPCInstrTypeBranch = kXEPPCInstrTypeSynchronizeContext | (1 << 2),
kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 3),
kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 4),
kXEPPCInstrTypeSyscall = kXEPPCInstrTypeSynchronizeContext | (1 << 5),
} xe_ppc_instr_type_e;
typedef enum {
kXEPPCInstrFlagReserved = 0,
} xe_ppc_instr_flag_e;
class InstrType;
static inline int64_t XEEXTS16(uint32_t v) { return (int64_t)((int16_t)v); }
static inline int64_t XEEXTS26(uint32_t v) {
constexpr int64_t XEEXTS16(uint32_t v) { return (int64_t)((int16_t)v); }
constexpr int64_t XEEXTS26(uint32_t v) {
return (int64_t)(v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v));
}
static inline uint64_t XEEXTZ16(uint32_t v) { return (uint64_t)((uint16_t)v); }
constexpr uint64_t XEEXTZ16(uint32_t v) { return (uint64_t)((uint16_t)v); }
static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
// if mstart ≤ mstop then
// mask[mstart:mstop] = ones
@@ -107,8 +95,9 @@ static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
return mstart <= mstop ? value : ~value;
}
typedef struct {
InstrType* type;
struct InstrData {
PPCOpcode opcode;
const PPCOpcodeInfo* opcode_info;
uint32_t address;
union {
@@ -394,7 +383,7 @@ typedef struct {
struct {
} XDSS;
};
} InstrData;
};
typedef struct {
enum RegisterSet {
@@ -498,26 +487,17 @@ class InstrDisasm {
void Dump(std::string& out_str, size_t pad = 13);
};
typedef void (*InstrDisasmFn)(InstrData* i, StringBuffer* str);
typedef void* InstrEmitFn;
typedef void (*InstrDisasmFn)(const InstrData& i, StringBuffer* str);
class InstrType {
public:
uint32_t opcode;
uint32_t opcode_mask; // Only used for certain opcodes (altivec, etc).
uint32_t format; // xe_ppc_instr_format_e
uint32_t type; // xe_ppc_instr_type_e
uint32_t flags; // xe_ppc_instr_flag_e
InstrDisasmFn disasm;
char name[16];
uint32_t translation_count;
InstrEmitFn emit;
};
void DumpAllInstrCounts();
InstrType* GetInstrType(uint32_t code);
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);
} // namespace ppc
} // namespace cpu

View File

@@ -20,76 +20,76 @@ namespace xe {
namespace cpu {
namespace ppc {
void Disasm_0(InstrData* i, StringBuffer* str);
void Disasm__(InstrData* i, StringBuffer* str);
void Disasm_X_FRT_FRB(InstrData* i, StringBuffer* str);
void Disasm_A_FRT_FRB(InstrData* i, StringBuffer* str);
void Disasm_A_FRT_FRA_FRB(InstrData* i, StringBuffer* str);
void Disasm_A_FRT_FRA_FRB_FRC(InstrData* i, StringBuffer* str);
void Disasm_X_RT_RA_RB(InstrData* i, StringBuffer* str);
void Disasm_X_RT_RA0_RB(InstrData* i, StringBuffer* str);
void Disasm_X_FRT_RA_RB(InstrData* i, StringBuffer* str);
void Disasm_X_FRT_RA0_RB(InstrData* i, StringBuffer* str);
void Disasm_D_RT_RA_I(InstrData* i, StringBuffer* str);
void Disasm_D_RT_RA0_I(InstrData* i, StringBuffer* str);
void Disasm_D_FRT_RA_I(InstrData* i, StringBuffer* str);
void Disasm_D_FRT_RA0_I(InstrData* i, StringBuffer* str);
void Disasm_DS_RT_RA_I(InstrData* i, StringBuffer* str);
void Disasm_DS_RT_RA0_I(InstrData* i, StringBuffer* str);
void Disasm_D_RA(InstrData* i, StringBuffer* str);
void Disasm_X_RA_RB(InstrData* i, StringBuffer* str);
void Disasm_XO_RT_RA_RB(InstrData* i, StringBuffer* str);
void Disasm_XO_RT_RA(InstrData* i, StringBuffer* str);
void Disasm_X_RA_RT_RB(InstrData* i, StringBuffer* str);
void Disasm_D_RA_RT_I(InstrData* i, StringBuffer* str);
void Disasm_X_RA_RT(InstrData* i, StringBuffer* str);
void Disasm_X_VX_RA0_RB(InstrData* i, StringBuffer* str);
void Disasm_VX1281_VD_RA0_RB(InstrData* i, StringBuffer* str);
void Disasm_VX1283_VD_VB(InstrData* i, StringBuffer* str);
void Disasm_VX1283_VD_VB_I(InstrData* i, StringBuffer* str);
void Disasm_VX_VD_VA_VB(InstrData* i, StringBuffer* str);
void Disasm_VX128_VD_VA_VB(InstrData* i, StringBuffer* str);
void Disasm_VX128_VD_VA_VD_VB(InstrData* i, StringBuffer* str);
void Disasm_VX1282_VD_VA_VB_VC(InstrData* i, StringBuffer* str);
void Disasm_VXA_VD_VA_VB_VC(InstrData* i, StringBuffer* str);
void Disasm_0(const InstrData& i, StringBuffer* str);
void Disasm__(const InstrData& i, StringBuffer* str);
void Disasm_X_FRT_FRB(const InstrData& i, StringBuffer* str);
void Disasm_A_FRT_FRB(const InstrData& i, StringBuffer* str);
void Disasm_A_FRT_FRA_FRB(const InstrData& i, StringBuffer* str);
void Disasm_A_FRT_FRA_FRB_FRC(const InstrData& i, StringBuffer* str);
void Disasm_X_RT_RA_RB(const InstrData& i, StringBuffer* str);
void Disasm_X_RT_RA0_RB(const InstrData& i, StringBuffer* str);
void Disasm_X_FRT_RA_RB(const InstrData& i, StringBuffer* str);
void Disasm_X_FRT_RA0_RB(const InstrData& i, StringBuffer* str);
void Disasm_D_RT_RA_I(const InstrData& i, StringBuffer* str);
void Disasm_D_RT_RA0_I(const InstrData& i, StringBuffer* str);
void Disasm_D_FRT_RA_I(const InstrData& i, StringBuffer* str);
void Disasm_D_FRT_RA0_I(const InstrData& i, StringBuffer* str);
void Disasm_DS_RT_RA_I(const InstrData& i, StringBuffer* str);
void Disasm_DS_RT_RA0_I(const InstrData& i, StringBuffer* str);
void Disasm_D_RA(const InstrData& i, StringBuffer* str);
void Disasm_X_RA_RB(const InstrData& i, StringBuffer* str);
void Disasm_XO_RT_RA_RB(const InstrData& i, StringBuffer* str);
void Disasm_XO_RT_RA(const InstrData& i, StringBuffer* str);
void Disasm_X_RA_RT_RB(const InstrData& i, StringBuffer* str);
void Disasm_D_RA_RT_I(const InstrData& i, StringBuffer* str);
void Disasm_X_RA_RT(const InstrData& i, StringBuffer* str);
void Disasm_X_VX_RA0_RB(const InstrData& i, StringBuffer* str);
void Disasm_VX1281_VD_RA0_RB(const InstrData& i, StringBuffer* str);
void Disasm_VX1283_VD_VB(const InstrData& i, StringBuffer* str);
void Disasm_VX1283_VD_VB_I(const InstrData& i, StringBuffer* str);
void Disasm_VX_VD_VA_VB(const InstrData& i, StringBuffer* str);
void Disasm_VX128_VD_VA_VB(const InstrData& i, StringBuffer* str);
void Disasm_VX128_VD_VA_VD_VB(const InstrData& i, StringBuffer* str);
void Disasm_VX1282_VD_VA_VB_VC(const InstrData& i, StringBuffer* str);
void Disasm_VXA_VD_VA_VB_VC(const InstrData& i, StringBuffer* str);
void Disasm_sync(InstrData* i, StringBuffer* str);
void Disasm_dcbf(InstrData* i, StringBuffer* str);
void Disasm_dcbz(InstrData* i, StringBuffer* str);
void Disasm_fcmp(InstrData* i, StringBuffer* str);
void Disasm_sync(const InstrData& i, StringBuffer* str);
void Disasm_dcbf(const InstrData& i, StringBuffer* str);
void Disasm_dcbz(const InstrData& i, StringBuffer* str);
void Disasm_fcmp(const InstrData& i, StringBuffer* str);
void Disasm_bx(InstrData* i, StringBuffer* str);
void Disasm_bcx(InstrData* i, StringBuffer* str);
void Disasm_bcctrx(InstrData* i, StringBuffer* str);
void Disasm_bclrx(InstrData* i, StringBuffer* str);
void Disasm_bx(const InstrData& i, StringBuffer* str);
void Disasm_bcx(const InstrData& i, StringBuffer* str);
void Disasm_bcctrx(const InstrData& i, StringBuffer* str);
void Disasm_bclrx(const InstrData& i, StringBuffer* str);
void Disasm_mfcr(InstrData* i, StringBuffer* str);
void Disasm_mfspr(InstrData* i, StringBuffer* str);
void Disasm_mtspr(InstrData* i, StringBuffer* str);
void Disasm_mftb(InstrData* i, StringBuffer* str);
void Disasm_mfmsr(InstrData* i, StringBuffer* str);
void Disasm_mtmsr(InstrData* i, StringBuffer* str);
void Disasm_mfcr(const InstrData& i, StringBuffer* str);
void Disasm_mfspr(const InstrData& i, StringBuffer* str);
void Disasm_mtspr(const InstrData& i, StringBuffer* str);
void Disasm_mftb(const InstrData& i, StringBuffer* str);
void Disasm_mfmsr(const InstrData& i, StringBuffer* str);
void Disasm_mtmsr(const InstrData& i, StringBuffer* str);
void Disasm_cmp(InstrData* i, StringBuffer* str);
void Disasm_cmpi(InstrData* i, StringBuffer* str);
void Disasm_cmpli(InstrData* i, StringBuffer* str);
void Disasm_cmp(const InstrData& i, StringBuffer* str);
void Disasm_cmpi(const InstrData& i, StringBuffer* str);
void Disasm_cmpli(const InstrData& i, StringBuffer* str);
void Disasm_rld(InstrData* i, StringBuffer* str);
void Disasm_rlwim(InstrData* i, StringBuffer* str);
void Disasm_rlwnmx(InstrData* i, StringBuffer* str);
void Disasm_srawix(InstrData* i, StringBuffer* str);
void Disasm_sradix(InstrData* i, StringBuffer* str);
void Disasm_rld(const InstrData& i, StringBuffer* str);
void Disasm_rlwim(const InstrData& i, StringBuffer* str);
void Disasm_rlwnmx(const InstrData& i, StringBuffer* str);
void Disasm_srawix(const InstrData& i, StringBuffer* str);
void Disasm_sradix(const InstrData& i, StringBuffer* str);
void Disasm_vpermwi128(InstrData* i, StringBuffer* str);
void Disasm_vrfin128(InstrData* i, StringBuffer* str);
void Disasm_vrlimi128(InstrData* i, StringBuffer* str);
void Disasm_vsldoi128(InstrData* i, StringBuffer* str);
void Disasm_vspltb(InstrData* i, StringBuffer* str);
void Disasm_vsplth(InstrData* i, StringBuffer* str);
void Disasm_vspltw(InstrData* i, StringBuffer* str);
void Disasm_vspltisb(InstrData* i, StringBuffer* str);
void Disasm_vspltish(InstrData* i, StringBuffer* str);
void Disasm_vspltisw(InstrData* i, StringBuffer* str);
void Disasm_vpermwi128(const InstrData& i, StringBuffer* str);
void Disasm_vrfin128(const InstrData& i, StringBuffer* str);
void Disasm_vrlimi128(const InstrData& i, StringBuffer* str);
void Disasm_vsldoi128(const InstrData& i, StringBuffer* str);
void Disasm_vspltb(const InstrData& i, StringBuffer* str);
void Disasm_vsplth(const InstrData& i, StringBuffer* str);
void Disasm_vspltw(const InstrData& i, StringBuffer* str);
void Disasm_vspltisb(const InstrData& i, StringBuffer* str);
void Disasm_vspltish(const InstrData& i, StringBuffer* str);
void Disasm_vspltisw(const InstrData& i, StringBuffer* str);
namespace tables {
@@ -125,11 +125,8 @@ static InstrType** instr_table_prep_63(InstrType* unprep, size_t unprep_count,
#define EMPTY(slot) \
{ 0 }
#define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
{ \
opcode, 0, kXEPPCInstrFormat##format, kXEPPCInstrType##type, 0, \
Disasm_##disasm_fn, #name, 0, \
}
#define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
{ opcode, 0, kXEPPCInstrFormat##format, Disasm_##disasm_fn, }
#define FLAG(t) kXEPPCInstrFlag##t
// This table set is constructed from:
@@ -845,7 +842,7 @@ static InstrType** instr_table = instr_table_prep(
#define SCAN_INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
{ \
opcode, kXEPPCInstrMask##format, kXEPPCInstrFormat##format, \
kXEPPCInstrType##type, 0, Disasm_##disasm_fn, #name, 0, \
Disasm_##disasm_fn, \
}
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))

View File

@@ -12,12 +12,16 @@
#include <cstdint>
#include "xenia/base/string_buffer.h"
#include "xenia/cpu/ppc/ppc_opcode.h"
namespace xe {
namespace cpu {
namespace ppc {
struct InstrData;
class PPCHIRBuilder;
enum class PPCOpcodeFormat {
kSC,
kD,
@@ -51,23 +55,38 @@ enum class PPCOpcodeFormat {
};
enum class PPCOpcodeGroup {
kInt,
kFp,
kVmx,
kI,
kF,
kV,
};
enum class PPCOpcodeType {
kGeneral,
kSync,
};
typedef void (*InstrDisasmFn1)(const InstrData* i, StringBuffer* str);
typedef int (*InstrEmitFn)(PPCHIRBuilder& f, const InstrData& i);
struct PPCOpcodeInfo {
uint32_t opcode;
const char* name;
PPCOpcodeFormat format;
PPCOpcodeGroup group;
PPCOpcodeType type;
const char* description;
InstrDisasmFn1 disasm;
InstrEmitFn emit;
};
PPCOpcode LookupOpcode(uint32_t code);
const PPCOpcodeInfo& GetOpcodeInfo(PPCOpcode opcode);
void RegisterOpcodeDisasm(PPCOpcode opcode, InstrDisasmFn1 fn);
void RegisterOpcodeEmitter(PPCOpcode opcode, InstrEmitFn fn);
inline const PPCOpcodeInfo& LookupOpcodeInfo(uint32_t code) {
return GetOpcodeInfo(LookupOpcode(code));
}

View File

@@ -2,6 +2,7 @@
// clang-format off
#include <cstdint>
#include "xenia/base/assert.h"
#include "xenia/cpu/ppc/ppc_opcode.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
@@ -9,473 +10,481 @@ namespace xe {
namespace cpu {
namespace ppc {
#define INSTRUCTION(opcode, mnem, form, subform, group, desc) \
{opcode, mnem, PPCOpcodeFormat::form, PPCOpcodeGroup::group, desc}
#define INSTRUCTION(opcode, mnem, form, subform, group, type, desc) \
{opcode, mnem, PPCOpcodeFormat::form, PPCOpcodeGroup::group, PPCOpcodeType::type, desc, nullptr, nullptr}
PPCOpcodeInfo ppc_opcode_table[] = {
INSTRUCTION(0x7c000014, "addcx" , kXO , D_A_B_OE_Rc , kInt, "Add Carrying" ),
INSTRUCTION(0x7c000114, "addex" , kXO , D_A_B_OE_Rc , kInt, "Add Extended" ),
INSTRUCTION(0x38000000, "addi" , kD , D_A_SIMM , kInt, "Add Immediate" ),
INSTRUCTION(0x30000000, "addic" , kD , D_A_SIMM , kInt, "Add Immediate Carrying" ),
INSTRUCTION(0x34000000, "addicx" , kD , D_A_SIMM , kInt, "Add Immediate Carrying and Record" ),
INSTRUCTION(0x3c000000, "addis" , kD , D_A_SIMM , kInt, "Add Immediate Shifted" ),
INSTRUCTION(0x7c0001d4, "addmex" , kXO , D_A_0_OE_Rc , kInt, "Add to Minus One Extended" ),
INSTRUCTION(0x7c000214, "addx" , kXO , D_A_B_OE_Rc , kInt, "Add" ),
INSTRUCTION(0x7c000194, "addzex" , kXO , D_A_0_OE_Rc , kInt, "Add to Zero Extended" ),
INSTRUCTION(0x7c000078, "andcx" , kX , S_A_B_Rc , kInt, "AND with Complement" ),
INSTRUCTION(0x74000000, "andisx" , kD , S_A_UIMM , kInt, "AND Immediate Shifted" ),
INSTRUCTION(0x70000000, "andix" , kD , S_A_UIMM , kInt, "AND Immediate" ),
INSTRUCTION(0x7c000038, "andx" , kX , S_A_B_Rc , kInt, "AND" ),
INSTRUCTION(0x4c000420, "bcctrx" , kXL , BO_BI_0_LK , kInt, "Branch Conditional to Count Register" ),
INSTRUCTION(0x4c000020, "bclrx" , kXL , BO_BI_0_LK , kInt, "Branch Conditional to Link Register" ),
INSTRUCTION(0x40000000, "bcx" , kB , BO_BI_BD_AA_LK , kInt, "Branch Conditional" ),
INSTRUCTION(0x48000000, "bx" , kI , LI_AA_LK , kInt, "Branch" ),
INSTRUCTION(0x7c000000, "cmp" , kX , crfD_L_A_B , kInt, "Compare" ),
INSTRUCTION(0x2c000000, "cmpi" , kD , crfD_L_A_SIMM , kInt, "Compare Immediate" ),
INSTRUCTION(0x7c000040, "cmpl" , kX , crfD_L_A_B , kInt, "Compare Logical" ),
INSTRUCTION(0x28000000, "cmpli" , kD , crfD_L_A_UIMM , kInt, "Compare Logical Immediate" ),
INSTRUCTION(0x7c000074, "cntlzdx" , kX , S_A_0_Rc , kInt, "Count Leading Zeros Doubleword" ),
INSTRUCTION(0x7c000034, "cntlzwx" , kX , S_A_0_Rc , kInt, "Count Leading Zeros Word" ),
INSTRUCTION(0x4c000202, "crand" , kXL , crbD_crbA_crbB , kInt, "Condition Register AND" ),
INSTRUCTION(0x4c000102, "crandc" , kXL , crbD_crbA_crbB , kInt, "Condition Register AND with Complement" ),
INSTRUCTION(0x4c000242, "creqv" , kXL , crbD_crbA_crbB , kInt, "Condition Register Equivalent" ),
INSTRUCTION(0x4c0001c2, "crnand" , kXL , crbD_crbA_crbB , kInt, "Condition Register NAND" ),
INSTRUCTION(0x4c000042, "crnor" , kXL , crbD_crbA_crbB , kInt, "Condition Register NOR" ),
INSTRUCTION(0x4c000382, "cror" , kXL , crbD_crbA_crbB , kInt, "Condition Register OR" ),
INSTRUCTION(0x4c000342, "crorc" , kXL , crbD_crbA_crbB , kInt, "Condition Register OR with Complement" ),
INSTRUCTION(0x4c000182, "crxor" , kXL , crbD_crbA_crbB , kInt, "Condition Register XOR" ),
INSTRUCTION(0x7c0005ec, "dcba" , kX , _0_A_B , kInt, "Data Cache Block Allocate" ),
INSTRUCTION(0x7c0000ac, "dcbf" , kX , _0_A_B , kInt, "Data Cache Block Flush" ),
INSTRUCTION(0x7c0003ac, "dcbi" , kX , _0_A_B , kInt, "Data Cache Block Invalidate" ),
INSTRUCTION(0x7c00006c, "dcbst" , kX , _0_A_B , kInt, "Data Cache Block Store" ),
INSTRUCTION(0x7c00022c, "dcbt" , kX , _0_A_B , kInt, "Data Cache Block Touch" ),
INSTRUCTION(0x7c0001ec, "dcbtst" , kX , _0_A_B , kInt, "Data Cache Block Touch for Store" ),
INSTRUCTION(0x7c0007ec, "dcbz" , kDCBZ , _0_A_B , kInt, "Data Cache Block Clear to Zero" ),
INSTRUCTION(0x7c2007ec, "dcbz128" , kDCBZ , _0_A_B , kInt, "Data Cache Block Clear to Zero 128" ),
INSTRUCTION(0x7c000392, "divdux" , kXO , D_A_B_OE_Rc , kInt, "Divide Doubleword Unsigned" ),
INSTRUCTION(0x7c0003d2, "divdx" , kXO , D_A_B_OE_Rc , kInt, "Divide Doubleword" ),
INSTRUCTION(0x7c000396, "divwux" , kXO , D_A_B_OE_Rc , kInt, "Divide Word Unsigned" ),
INSTRUCTION(0x7c0003d6, "divwx" , kXO , D_A_B_OE_Rc , kInt, "Divide Word" ),
INSTRUCTION(0x7c00026c, "eciwx" , kX , D_A_B , kInt, "External Control In Word Indexed" ),
INSTRUCTION(0x7c00036c, "ecowx" , kX , S_A_B , kInt, "External Control Out Word Indexed" ),
INSTRUCTION(0x7c0006ac, "eieio" , kX , _0_0_0 , kInt, "Enforce In-Order Execution of I/O" ),
INSTRUCTION(0x7c000238, "eqvx" , kX , S_A_B_Rc , kInt, "Equivalent" ),
INSTRUCTION(0x7c000774, "extsbx" , kX , S_A_0_Rc , kInt, "Extend Sign Byte" ),
INSTRUCTION(0x7c000734, "extshx" , kX , S_A_0_Rc , kInt, "Extend Sign Half Word" ),
INSTRUCTION(0x7c0007b4, "extswx" , kX , S_A_0_Rc , kInt, "Extend Sign Word" ),
INSTRUCTION(0xfc000210, "fabsx" , kX , D_0_B_Rc , kFp , "Floating Absolute Value" ),
INSTRUCTION(0xec00002a, "faddsx" , kA , D_A_B_0_Rc , kFp , "Floating Add Single" ),
INSTRUCTION(0xfc00002a, "faddx" , kA , D_A_B_0_Rc , kFp , "Floating Add" ),
INSTRUCTION(0xfc00069c, "fcfidx" , kX , D_A_B_Rc , kFp , "Floating Convert From Integer Doubleword" ),
INSTRUCTION(0xfc000040, "fcmpo" , kX , crfD_A_B , kFp , "Floating Compare Ordered" ),
INSTRUCTION(0xfc000000, "fcmpu" , kX , crfD_A_B , kFp , "Floating Compare Unordered" ),
INSTRUCTION(0xfc00065c, "fctidx" , kX , D_0_B_Rc , kFp , "Floating Convert to Integer Doubleword" ),
INSTRUCTION(0xfc00065e, "fctidzx" , kX , D_0_B_Rc , kFp , "Floating Convert to Integer Doubleword with Round Toward Zero" ),
INSTRUCTION(0xfc00001c, "fctiwx" , kX , D_0_B_Rc , kFp , "Floating Convert to Integer Word" ),
INSTRUCTION(0xfc00001e, "fctiwzx" , kX , D_0_B_Rc , kFp , "Floating Convert to Integer Word with Round Toward Zero" ),
INSTRUCTION(0xec000024, "fdivsx" , kA , D_A_B_0_Rc , kFp , "Floating Divide Single" ),
INSTRUCTION(0xfc000024, "fdivx" , kA , D_A_B_0_Rc , kFp , "Floating Divide" ),
INSTRUCTION(0xec00003a, "fmaddsx" , kA , D_A_B_C_Rc , kFp , "Floating Multiply-Add Single" ),
INSTRUCTION(0xfc00003a, "fmaddx" , kA , D_A_B_C_Rc , kFp , "Floating Multiply-Add" ),
INSTRUCTION(0xfc000090, "fmrx" , kX , D_0_B_Rc , kFp , "Floating Move Register" ),
INSTRUCTION(0xec000038, "fmsubsx" , kA , D_A_B_C_Rc , kFp , "Floating Multiply-Subtract Single" ),
INSTRUCTION(0xfc000038, "fmsubx" , kA , D_A_B_C_Rc , kFp , "Floating Multiply-Subtract" ),
INSTRUCTION(0xec000032, "fmulsx" , kA , D_A_0_C_Rc , kFp , "Floating Multiply Single" ),
INSTRUCTION(0xfc000032, "fmulx" , kA , D_A_0_C_Rc , kFp , "Floating Multiply" ),
INSTRUCTION(0xfc000110, "fnabsx" , kX , D_0_B_Rc , kFp , "Floating Negative Absolute Value" ),
INSTRUCTION(0xfc000050, "fnegx" , kX , D_0_B_Rc , kFp , "Floating Negate" ),
INSTRUCTION(0xec00003e, "fnmaddsx" , kA , D_A_B_C_Rc , kFp , "Floating Negative Multiply-Add Single" ),
INSTRUCTION(0xfc00003e, "fnmaddx" , kA , D_A_B_C_Rc , kFp , "Floating Negative Multiply-Add" ),
INSTRUCTION(0xec00003c, "fnmsubsx" , kA , D_A_B_C_Rc , kFp , "Floating Negative Multiply-Subtract Single" ),
INSTRUCTION(0xfc00003c, "fnmsubx" , kA , D_A_B_C_Rc , kFp , "Floating Negative Multiply-Subtract" ),
INSTRUCTION(0xec000030, "fresx" , kA , D_0_B_0_Rc , kFp , "Floating Reciprocal Estimate Single" ),
INSTRUCTION(0xfc000018, "frspx" , kX , D_0_B_Rc , kFp , "Floating Round to Single" ),
INSTRUCTION(0xfc000034, "frsqrtex" , kA , D_0_B_0_Rc , kFp , "Floating Reciprocal Square Root Estimate" ),
INSTRUCTION(0xfc00002e, "fselx" , kA , D_A_B_C_Rc , kFp , "Floating Select" ),
INSTRUCTION(0xec00002c, "fsqrtsx" , kA , D_0_B_0_Rc , kFp , "Floating Square Root Single" ),
INSTRUCTION(0xfc00002c, "fsqrtx" , kA , D_0_B_0_Rc , kFp , "Floating Square Root" ),
INSTRUCTION(0xec000028, "fsubsx" , kA , D_A_B_0_Rc , kFp , "Floating Subtract Single" ),
INSTRUCTION(0xfc000028, "fsubx" , kA , D_A_B_0_Rc , kFp , "Floating Subtract" ),
INSTRUCTION(0x7c0007ac, "icbi" , kX , _0_A_B , kInt, "Instruction Cache Block Invalidate" ),
INSTRUCTION(0x4c00012c, "isync" , kXL , _0_0_0 , kInt, "Instruction Synchronize" ),
INSTRUCTION(0x88000000, "lbz" , kD , D_A_d , kInt, "Load Byte and Zero" ),
INSTRUCTION(0x8c000000, "lbzu" , kD , D_A_d , kInt, "Load Byte and Zero with Update" ),
INSTRUCTION(0x7c0000ee, "lbzux" , kX , D_A_B , kInt, "Load Byte and Zero with Update Indexed" ),
INSTRUCTION(0x7c0000ae, "lbzx" , kX , D_A_B , kInt, "Load Byte and Zero Indexed" ),
INSTRUCTION(0xe8000000, "ld" , kDS , D_A_d , kInt, "Load Doubleword" ),
INSTRUCTION(0x7c0000a8, "ldarx" , kX , D_A_B , kInt, "Load Doubleword and Reserve Indexed" ),
INSTRUCTION(0x7c000428, "ldbrx" , kX , D_A_B , kInt, "Load Doubleword Byte-Reverse Indexed" ),
INSTRUCTION(0xe8000001, "ldu" , kDS , D_A_d , kInt, "Load Doubleword with Update" ),
INSTRUCTION(0x7c00006a, "ldux" , kX , D_A_B , kInt, "Load Doubleword with Update Indexed" ),
INSTRUCTION(0x7c00002a, "ldx" , kX , D_A_B , kInt, "Load Doubleword Indexed" ),
INSTRUCTION(0xc8000000, "lfd" , kD , D_A_d , kFp , "Load Floating-Point Double" ),
INSTRUCTION(0xcc000000, "lfdu" , kD , D_A_d , kFp , "Load Floating-Point Double with Update" ),
INSTRUCTION(0x7c0004ee, "lfdux" , kX , D_A_B , kFp , "Load Floating-Point Double with Update Indexed" ),
INSTRUCTION(0x7c0004ae, "lfdx" , kX , D_A_B , kFp , "Load Floating-Point Double Indexed" ),
INSTRUCTION(0xc0000000, "lfs" , kD , D_A_d , kFp , "Load Floating-Point Single" ),
INSTRUCTION(0xc4000000, "lfsu" , kD , D_A_d , kFp , "Load Floating-Point Single with Update" ),
INSTRUCTION(0x7c00046e, "lfsux" , kX , D_A_B , kFp , "Load Floating-Point Single with Update Indexed" ),
INSTRUCTION(0x7c00042e, "lfsx" , kX , D_A_B , kFp , "Load Floating-Point Single Indexed" ),
INSTRUCTION(0xa8000000, "lha" , kD , D_A_d , kInt, "Load Half Word Algebraic" ),
INSTRUCTION(0xac000000, "lhau" , kD , D_A_d , kInt, "Load Half Word Algebraic with Update" ),
INSTRUCTION(0x7c0002ee, "lhaux" , kX , D_A_B , kInt, "Load Half Word Algebraic with Update Indexed" ),
INSTRUCTION(0x7c0002ae, "lhax" , kX , D_A_B , kInt, "Load Half Word Algebraic Indexed" ),
INSTRUCTION(0x7c00062c, "lhbrx" , kX , D_A_B , kInt, "Load Half Word Byte-Reverse Indexed" ),
INSTRUCTION(0xa0000000, "lhz" , kD , D_A_d , kInt, "Load Half Word and Zero" ),
INSTRUCTION(0xa4000000, "lhzu" , kD , D_A_d , kInt, "Load Half Word and Zero with Update" ),
INSTRUCTION(0x7c00026e, "lhzux" , kX , D_A_B , kInt, "Load Half Word and Zero with Update Indexed" ),
INSTRUCTION(0x7c00022e, "lhzx" , kX , D_A_B , kInt, "Load Half Word and Zero Indexed" ),
INSTRUCTION(0xb8000000, "lmw" , kD , D_A_d , kInt, "Load Multiple Word" ),
INSTRUCTION(0x7c0004aa, "lswi" , kX , D_A_NB , kInt, "Load String Word Immediate" ),
INSTRUCTION(0x7c00042a, "lswx" , kX , D_A_B , kInt, "Load String Word Indexed" ),
INSTRUCTION(0x7c00000e, "lvebx" , kX , D_A_B , kVmx, "Load Vector Element Byte Indexed" ),
INSTRUCTION(0x7c00004e, "lvehx" , kX , D_A_B , kVmx, "Load Vector Element Half Word Indexed" ),
INSTRUCTION(0x7c00008e, "lvewx" , kX , D_A_B , kVmx, "Load Vector Element Word Indexed" ),
INSTRUCTION(0x10000083, "lvewx128" , kVX128_1, D_A_B , kVmx, "Load Vector Element Word Indexed 128" ),
INSTRUCTION(0x7c00040e, "lvlx" , kX , D_A_B , kVmx, "Load Vector Left Indexed" ),
INSTRUCTION(0x10000403, "lvlx128" , kVX128_1, D_A_B , kVmx, "Load Vector Left Indexed 128" ),
INSTRUCTION(0x7c00060e, "lvlxl" , kX , D_A_B , kVmx, "Load Vector Left Indexed LRU" ),
INSTRUCTION(0x10000603, "lvlxl128" , kVX128_1, D_A_B , kVmx, "Load Vector Left Indexed LRU 128" ),
INSTRUCTION(0x7c00044e, "lvrx" , kX , D_A_B , kVmx, "Load Vector Right Indexed" ),
INSTRUCTION(0x10000443, "lvrx128" , kVX128_1, D_A_B , kVmx, "Load Vector Right Indexed 128" ),
INSTRUCTION(0x7c00064e, "lvrxl" , kX , D_A_B , kVmx, "Load Vector Right Indexed LRU" ),
INSTRUCTION(0x10000643, "lvrxl128" , kVX128_1, D_A_B , kVmx, "Load Vector Right Indexed LRU 128" ),
INSTRUCTION(0x7c00000c, "lvsl" , kX , D_A_B , kVmx, "Load Vector for Shift Left Indexed" ),
INSTRUCTION(0x10000003, "lvsl128" , kVX128_1, D_A_B , kVmx, "Load Vector for Shift Left Indexed 128" ),
INSTRUCTION(0x7c00004c, "lvsr" , kX , D_A_B , kVmx, "Load Vector for Shift Right Indexed" ),
INSTRUCTION(0x10000043, "lvsr128" , kVX128_1, D_A_B , kVmx, "Load Vector for Shift Right Indexed 128" ),
INSTRUCTION(0x7c0000ce, "lvx" , kX , D_A_B , kVmx, "Load Vector Indexed" ),
INSTRUCTION(0x100000c3, "lvx128" , kVX128_1, D_A_B , kVmx, "Load Vector Indexed 128" ),
INSTRUCTION(0x7c0002ce, "lvxl" , kX , D_A_B , kVmx, "Load Vector Indexed LRU" ),
INSTRUCTION(0x100002c3, "lvxl128" , kVX128_1, D_A_B , kVmx, "Load Vector Indexed LRU 128" ),
INSTRUCTION(0xe8000002, "lwa" , kDS , D_A_d , kInt, "Load Word Algebraic" ),
INSTRUCTION(0x7c000028, "lwarx" , kX , D_A_B , kInt, "Load Word and Reserve Indexed" ),
INSTRUCTION(0x7c0002ea, "lwaux" , kX , D_A_B , kInt, "Load Word Algebraic with Update Indexed" ),
INSTRUCTION(0x7c0002aa, "lwax" , kX , D_A_B , kInt, "Load Word Algebraic Indexed" ),
INSTRUCTION(0x7c00042c, "lwbrx" , kX , D_A_B , kInt, "Load Word Byte-Reverse Indexed" ),
INSTRUCTION(0x80000000, "lwz" , kD , D_A_d , kInt, "Load Word and Zero" ),
INSTRUCTION(0x84000000, "lwzu" , kD , D_A_d , kInt, "Load Word and Zero with Update" ),
INSTRUCTION(0x7c00006e, "lwzux" , kX , D_A_B , kInt, "Load Word and Zero with Update Indexed" ),
INSTRUCTION(0x7c00002e, "lwzx" , kX , D_A_B , kInt, "Load Word and Zero Indexed" ),
INSTRUCTION(0x4c000000, "mcrf" , kXL , crfD_crfS_0 , kInt, "Move Condition Register Field" ),
INSTRUCTION(0xfc000080, "mcrfs" , kX , crfD_crfS_0 , kFp , "Move to Condition Register from FPSCR" ),
INSTRUCTION(0x7c000400, "mcrxr" , kX , crfD_0_0 , kInt, "Move to Condition Register from XER" ),
INSTRUCTION(0x7c000026, "mfcr" , kX , D_0_0 , kInt, "Move from Condition Register" ),
INSTRUCTION(0xfc00048e, "mffsx" , kX , D_0_0_Rc , kFp , "Move from FPSCR" ),
INSTRUCTION(0x7c0000a6, "mfmsr" , kX , D_0_0 , kInt, "Move from Machine State Register" ),
INSTRUCTION(0x7c0002a6, "mfspr" , kXFX , D_spr , kInt, "Move from Special-Purpose Register" ),
INSTRUCTION(0x7c0002e6, "mftb" , kXFX , D_tbr , kInt, "Move from Time Base" ),
INSTRUCTION(0x10000604, "mfvscr" , kVX , D_0_0 , kInt, "Move from VSCR" ),
INSTRUCTION(0x7c000120, "mtcrf" , kXFX , S_CRM , kInt, "Move to Condition Register Fields" ),
INSTRUCTION(0xfc00008c, "mtfsb0x" , kX , crbD_0_0_Rc , kFp , "Move to FPSCR Bit 0" ),
INSTRUCTION(0xfc00004c, "mtfsb1x" , kX , crbD_0_0_Rc , kFp , "Move to FPSCR Bit 1" ),
INSTRUCTION(0xfc00010c, "mtfsfix" , kX , crfD_0_IMM_Rc , kFp , "Move to FPSCR Field Immediate" ),
INSTRUCTION(0xfc00058e, "mtfsfx" , kXFL , FM_B_Rc , kFp , "Move to FPSCR Fields" ),
INSTRUCTION(0x7c000124, "mtmsr" , kX , S_0_0 , kInt, "Move to Machine State Register" ),
INSTRUCTION(0x7c000164, "mtmsrd" , kX , S_0_0 , kInt, "Move to Machine State Register Doubleword" ),
INSTRUCTION(0x7c0003a6, "mtspr" , kXFX , S_spr , kInt, "Move to Special-Purpose Register" ),
INSTRUCTION(0x10000644, "mtvscr" , kVX , S_0_0 , kInt, "Move to VSCR" ),
INSTRUCTION(0x7c000012, "mulhdux" , kXO , D_A_B_Rc , kInt, "Multiply High Doubleword Unsigned" ),
INSTRUCTION(0x7c000092, "mulhdx" , kXO , D_A_B_Rc , kInt, "Multiply High Doubleword" ),
INSTRUCTION(0x7c000016, "mulhwux" , kXO , D_A_B_Rc , kInt, "Multiply High Word Unsigned" ),
INSTRUCTION(0x7c000096, "mulhwx" , kXO , D_A_B_Rc , kInt, "Multiply High Word" ),
INSTRUCTION(0x7c0001d2, "mulldx" , kXO , D_A_B_OE_Rc , kInt, "Multiply Low Doubleword" ),
INSTRUCTION(0x1c000000, "mulli" , kD , D_A_SIMM , kInt, "Multiply Low Immediate" ),
INSTRUCTION(0x7c0001d6, "mullwx" , kXO , D_A_B_OE_Rc , kInt, "Multiply Low Word" ),
INSTRUCTION(0x7c0003b8, "nandx" , kX , S_A_B_Rc , kInt, "NAND" ),
INSTRUCTION(0x7c0000d0, "negx" , kXO , D_A_0_OE_Rc , kInt, "Negate" ),
INSTRUCTION(0x7c0000f8, "norx" , kX , S_A_B_Rc , kInt, "NOR" ),
INSTRUCTION(0x7c000338, "orcx" , kX , S_A_B_Rc , kInt, "OR with Complement" ),
INSTRUCTION(0x60000000, "ori" , kD , S_A_UIMM , kInt, "OR Immediate" ),
INSTRUCTION(0x64000000, "oris" , kD , S_A_UIMM , kInt, "OR Immediate Shifted" ),
INSTRUCTION(0x7c000378, "orx" , kX , S_A_B_Rc , kInt, "OR" ),
INSTRUCTION(0x78000010, "rldclx" , kMDS , S_A_B_MB_ME_Rc , kInt, "Rotate Left Doubleword then Clear Left" ),
INSTRUCTION(0x78000012, "rldcrx" , kMDS , S_A_B_MB_ME_Rc , kInt, "Rotate Left Doubleword then Clear Right" ),
INSTRUCTION(0x78000000, "rldiclx" , kMDSH , S_A_SH_MB_ME_Rc, kInt, "Rotate Left Doubleword Immediate then Clear Left" ),
INSTRUCTION(0x78000004, "rldicrx" , kMDSH , S_A_SH_MB_ME_Rc, kInt, "Rotate Left Doubleword Immediate then Clear Right" ),
INSTRUCTION(0x78000008, "rldicx" , kMDSH , S_A_SH_MB_ME_Rc, kInt, "Rotate Left Doubleword Immediate then Clear" ),
INSTRUCTION(0x7800000c, "rldimix" , kMDSH , S_A_SH_MB_ME_Rc, kInt, "Rotate Left Doubleword Immediate then Mask Insert" ),
INSTRUCTION(0x50000000, "rlwimix" , kM , S_A_SH_MB_ME_Rc, kInt, "Rotate Left Word Immediate then Mask Insert" ),
INSTRUCTION(0x54000000, "rlwinmx" , kM , S_A_SH_MB_ME_Rc, kInt, "Rotate Left Word Immediate then AND with Mask" ),
INSTRUCTION(0x5c000000, "rlwnmx" , kM , S_A_SH_MB_ME_Rc, kInt, "Rotate Left Word then AND with Mask" ),
INSTRUCTION(0x44000002, "sc" , kSC , sc , kInt, "System Call" ),
INSTRUCTION(0x7c000036, "sldx" , kX , S_A_B_Rc , kInt, "Shift Left Doubleword" ),
INSTRUCTION(0x7c000030, "slwx" , kX , S_A_B_Rc , kInt, "Shift Left Word" ),
INSTRUCTION(0x7c000674, "sradix" , kXS , S_A_SH_Rc , kInt, "Shift Right Algebraic Doubleword Immediate" ),
INSTRUCTION(0x7c000634, "sradx" , kX , S_A_B_Rc , kInt, "Shift Right Algebraic Doubleword" ),
INSTRUCTION(0x7c000670, "srawix" , kX , S_A_SH_Rc , kInt, "Shift Right Algebraic Word Immediate" ),
INSTRUCTION(0x7c000630, "srawx" , kX , S_A_B_Rc , kInt, "Shift Right Algebraic Word" ),
INSTRUCTION(0x7c000436, "srdx" , kX , S_A_B_Rc , kInt, "Shift Right Doubleword" ),
INSTRUCTION(0x7c000430, "srwx" , kX , S_A_B_Rc , kInt, "Shift Right Word" ),
INSTRUCTION(0x98000000, "stb" , kD , S_A_d , kInt, "Store Byte" ),
INSTRUCTION(0x9c000000, "stbu" , kD , S_A_d , kInt, "Store Byte with Update" ),
INSTRUCTION(0x7c0001ee, "stbux" , kX , S_A_B , kInt, "Store Byte with Update Indexed" ),
INSTRUCTION(0x7c0001ae, "stbx" , kX , S_A_B , kInt, "Store Byte Indexed" ),
INSTRUCTION(0xf8000000, "std" , kDS , S_A_d , kInt, "Store Doubleword" ),
INSTRUCTION(0x7c000528, "stdbrx" , kX , S_A_B , kInt, "Store Doubleword Byte-Reverse Indexed" ),
INSTRUCTION(0x7c0001ad, "stdcx" , kX , S_A_B_1 , kInt, "Store Doubleword Conditional Indexed" ),
INSTRUCTION(0xf8000001, "stdu" , kDS , S_A_d , kInt, "Store Doubleword with Update" ),
INSTRUCTION(0x7c00016a, "stdux" , kX , S_A_B , kInt, "Store Doubleword with Update Indexed" ),
INSTRUCTION(0x7c00012a, "stdx" , kX , S_A_B , kInt, "Store Doubleword Indexed" ),
INSTRUCTION(0xd8000000, "stfd" , kD , S_A_d , kFp , "Store Floating-Point Double" ),
INSTRUCTION(0xdc000000, "stfdu" , kD , S_A_d , kFp , "Store Floating-Point Double with Update" ),
INSTRUCTION(0x7c0005ee, "stfdux" , kX , S_A_B , kFp , "Store Floating-Point Double with Update Indexed" ),
INSTRUCTION(0x7c0005ae, "stfdx" , kX , S_A_B , kFp , "Store Floating-Point Double Indexed" ),
INSTRUCTION(0x7c0007ae, "stfiwx" , kX , S_A_B , kFp , "Store Floating-Point as Integer Word Indexed" ),
INSTRUCTION(0xd0000000, "stfs" , kD , S_A_d , kFp , "Store Floating-Point Single" ),
INSTRUCTION(0xd4000000, "stfsu" , kD , S_A_d , kFp , "Store Floating-Point Single with Update" ),
INSTRUCTION(0x7c00056e, "stfsux" , kX , S_A_B , kFp , "Store Floating-Point Single with Update Indexed" ),
INSTRUCTION(0x7c00052e, "stfsx" , kX , S_A_B , kFp , "Store Floating-Point Single Indexed" ),
INSTRUCTION(0xb0000000, "sth" , kD , S_A_d , kInt, "Store Half Word" ),
INSTRUCTION(0x7c00072c, "sthbrx" , kX , S_A_B , kInt, "Store Half Word Byte-Reverse Indexed" ),
INSTRUCTION(0xb4000000, "sthu" , kD , S_A_d , kInt, "Store Half Word with Update" ),
INSTRUCTION(0x7c00036e, "sthux" , kX , S_A_B , kInt, "Store Half Word with Update Indexed" ),
INSTRUCTION(0x7c00032e, "sthx" , kX , S_A_B , kInt, "Store Half Word Indexed" ),
INSTRUCTION(0xbc000000, "stmw" , kD , S_A_d , kInt, "Store Multiple Word" ),
INSTRUCTION(0x7c0005aa, "stswi" , kX , S_A_NB , kInt, "Store String Word Immediate" ),
INSTRUCTION(0x7c00052a, "stswx" , kX , S_A_B , kInt, "Store String Word Indexed" ),
INSTRUCTION(0x7c00010e, "stvebx" , kX , S_A_B , kVmx, "Store Vector Element Byte Indexed" ),
INSTRUCTION(0x7c00014e, "stvehx" , kX , S_A_B , kVmx, "Store Vector Element Half Word Indexed" ),
INSTRUCTION(0x7c00018e, "stvewx" , kX , S_A_B , kVmx, "Store Vector Element Word Indexed" ),
INSTRUCTION(0x10000183, "stvewx128" , kVX128_1, S_A_B , kVmx, "Store Vector Element Word Indexed 128" ),
INSTRUCTION(0x7c00050e, "stvlx" , kX , S_A_B , kVmx, "Store Vector Left Indexed" ),
INSTRUCTION(0x10000503, "stvlx128" , kVX128_1, S_A_B , kVmx, "Store Vector Left Indexed 128" ),
INSTRUCTION(0x7c00070e, "stvlxl" , kX , S_A_B , kVmx, "Store Vector Left Indexed LRU" ),
INSTRUCTION(0x10000703, "stvlxl128" , kVX128_1, S_A_B , kVmx, "Store Vector Left Indexed LRU 128" ),
INSTRUCTION(0x7c00054e, "stvrx" , kX , S_A_B , kVmx, "Store Vector Right Indexed" ),
INSTRUCTION(0x10000543, "stvrx128" , kVX128_1, S_A_B , kVmx, "Store Vector Right Indexed 128" ),
INSTRUCTION(0x7c00074e, "stvrxl" , kX , S_A_B , kVmx, "Store Vector Right Indexed LRU" ),
INSTRUCTION(0x10000743, "stvrxl128" , kVX128_1, S_A_B , kVmx, "Store Vector Right Indexed LRU 128" ),
INSTRUCTION(0x7c0001ce, "stvx" , kX , S_A_B , kVmx, "Store Vector Indexed" ),
INSTRUCTION(0x100001c3, "stvx128" , kVX128_1, S_A_B , kVmx, "Store Vector Indexed 128" ),
INSTRUCTION(0x7c0003ce, "stvxl" , kX , S_A_B , kVmx, "Store Vector Indexed LRU" ),
INSTRUCTION(0x100003c3, "stvxl128" , kVX128_1, S_A_B , kVmx, "Store Vector Indexed LRU 128" ),
INSTRUCTION(0x90000000, "stw" , kD , S_A_d , kInt, "Store Word" ),
INSTRUCTION(0x7c00052c, "stwbrx" , kX , S_A_B , kInt, "Store Word Byte-Reverse Indexed" ),
INSTRUCTION(0x7c00012d, "stwcx" , kX , S_A_B_1 , kInt, "Store Word Conditional Indexed" ),
INSTRUCTION(0x94000000, "stwu" , kD , S_A_d , kInt, "Store Word with Update" ),
INSTRUCTION(0x7c00016e, "stwux" , kX , S_A_B , kInt, "Store Word with Update Indexed" ),
INSTRUCTION(0x7c00012e, "stwx" , kX , S_A_B , kInt, "Store Word Indexed" ),
INSTRUCTION(0x7c000010, "subfcx" , kXO , D_A_B_OE_Rc , kInt, "Subtract From Carrying" ),
INSTRUCTION(0x7c000110, "subfex" , kXO , D_A_B_OE_Rc , kInt, "Subtract From Extended" ),
INSTRUCTION(0x20000000, "subficx" , kD , D_A_SIMM , kInt, "Subtract From Immediate Carrying" ),
INSTRUCTION(0x7c0001d0, "subfmex" , kXO , D_A_0_OE_Rc , kInt, "Subtract From Minus One Extended" ),
INSTRUCTION(0x7c000050, "subfx" , kXO , D_A_B_OE_Rc , kInt, "Subtract From" ),
INSTRUCTION(0x7c000190, "subfzex" , kXO , D_A_0_OE_Rc , kInt, "Subtract From Zero Extended" ),
INSTRUCTION(0x7c0004ac, "sync" , kX , _0_0_0 , kInt, "Synchronize" ),
INSTRUCTION(0x7c000088, "td" , kX , TO_A_B , kInt, "Trap Doubleword" ),
INSTRUCTION(0x08000000, "tdi" , kD , TO_A_SIMM , kInt, "Trap Doubleword Immediate" ),
INSTRUCTION(0x7c000008, "tw" , kX , TO_A_B , kInt, "Trap Word" ),
INSTRUCTION(0x0c000000, "twi" , kD , TO_A_SIMM , kInt, "Trap Word Immediate" ),
INSTRUCTION(0x10000180, "vaddcuw" , kVX , D_A_B , kVmx, "Vector Add Carryout Unsigned Word" ),
INSTRUCTION(0x1000000a, "vaddfp" , kVX , D_A_B , kVmx, "Vector Add Floating Point" ),
INSTRUCTION(0x14000010, "vaddfp128" , kVX128 , D_A_B , kVmx, "Vector128 Add Floating Point" ),
INSTRUCTION(0x10000300, "vaddsbs" , kVX , D_A_B , kVmx, "Vector Add Signed Byte Saturate" ),
INSTRUCTION(0x10000340, "vaddshs" , kVX , D_A_B , kVmx, "Vector Add Signed Half Word Saturate" ),
INSTRUCTION(0x10000380, "vaddsws" , kVX , D_A_B , kVmx, "Vector Add Signed Word Saturate" ),
INSTRUCTION(0x10000000, "vaddubm" , kVX , D_A_B , kVmx, "Vector Add Unsigned Byte Modulo" ),
INSTRUCTION(0x10000200, "vaddubs" , kVX , D_A_B , kVmx, "Vector Add Unsigned Byte Saturate" ),
INSTRUCTION(0x10000040, "vadduhm" , kVX , D_A_B , kVmx, "Vector Add Unsigned Half Word Modulo" ),
INSTRUCTION(0x10000240, "vadduhs" , kVX , D_A_B , kVmx, "Vector Add Unsigned Half Word Saturate" ),
INSTRUCTION(0x10000080, "vadduwm" , kVX , D_A_B , kVmx, "Vector Add Unsigned Word Modulo" ),
INSTRUCTION(0x10000280, "vadduws" , kVX , D_A_B , kVmx, "Vector Add Unsigned Word Saturate" ),
INSTRUCTION(0x10000404, "vand" , kVX , D_A_B , kVmx, "Vector Logical AND" ),
INSTRUCTION(0x14000210, "vand128" , kVX128 , D_A_B , kVmx, "Vector128 Logical AND" ),
INSTRUCTION(0x10000444, "vandc" , kVX , D_A_B , kVmx, "Vector Logical AND with Complement" ),
INSTRUCTION(0x14000250, "vandc128" , kVX128 , D_A_B , kVmx, "Vector128 Logical AND with Complement" ),
INSTRUCTION(0x10000502, "vavgsb" , kVX , D_A_B , kVmx, "Vector Average Signed Byte" ),
INSTRUCTION(0x10000542, "vavgsh" , kVX , D_A_B , kVmx, "Vector Average Signed Half Word" ),
INSTRUCTION(0x10000582, "vavgsw" , kVX , D_A_B , kVmx, "Vector Average Signed Word" ),
INSTRUCTION(0x10000402, "vavgub" , kVX , D_A_B , kVmx, "Vector Average Unsigned Byte" ),
INSTRUCTION(0x10000442, "vavguh" , kVX , D_A_B , kVmx, "Vector Average Unsigned Half Word" ),
INSTRUCTION(0x10000482, "vavguw" , kVX , D_A_B , kVmx, "Vector Average Unsigned Word" ),
INSTRUCTION(0x18000230, "vcfpsxws128" , kVX128_3, D_B_SIMM , kVmx, "Vector128 Convert From Floating-Point to Signed Fixed-Point Word Saturate" ),
INSTRUCTION(0x18000270, "vcfpuxws128" , kVX128_3, D_B_UIMM , kVmx, "Vector128 Convert From Floating-Point to Unsigned Fixed-Point Word Saturate"),
INSTRUCTION(0x1000034a, "vcfsx" , kVX , D_A_B , kVmx, "Vector Convert from Signed Fixed-Point Word" ),
INSTRUCTION(0x1000030a, "vcfux" , kVX , D_A_B , kVmx, "Vector Convert from Unsigned Fixed-Point Word" ),
INSTRUCTION(0x100003c6, "vcmpbfp" , kVC , D_A_B , kVmx, "Vector Compare Bounds Floating Point" ),
INSTRUCTION(0x18000180, "vcmpbfp128" , kVX128_R, D_A_B , kVmx, "Vector128 Compare Bounds Floating Point" ),
INSTRUCTION(0x100000c6, "vcmpeqfp" , kVC , D_A_B , kVmx, "Vector Compare Equal-to Floating Point" ),
INSTRUCTION(0x18000000, "vcmpeqfp128" , kVX128_R, D_A_B , kVmx, "Vector128 Compare Equal-to Floating Point" ),
INSTRUCTION(0x10000006, "vcmpequb" , kVC , D_A_B , kVmx, "Vector Compare Equal-to Unsigned Byte" ),
INSTRUCTION(0x10000046, "vcmpequh" , kVC , D_A_B , kVmx, "Vector Compare Equal-to Unsigned Half Word" ),
INSTRUCTION(0x10000086, "vcmpequw" , kVC , D_A_B , kVmx, "Vector Compare Equal-to Unsigned Word" ),
INSTRUCTION(0x18000200, "vcmpequw128" , kVX128_R, D_A_B , kVmx, "Vector128 Compare Equal-to Unsigned Word" ),
INSTRUCTION(0x100001c6, "vcmpgefp" , kVC , D_A_B , kVmx, "Vector Compare Greater-Than-or-Equal-to Floating Point" ),
INSTRUCTION(0x18000080, "vcmpgefp128" , kVX128_R, D_A_B , kVmx, "Vector128 Compare Greater-Than-or-Equal-to Floating Point" ),
INSTRUCTION(0x100002c6, "vcmpgtfp" , kVC , D_A_B , kVmx, "Vector Compare Greater-Than Floating Point" ),
INSTRUCTION(0x18000100, "vcmpgtfp128" , kVX128_R, D_A_B , kVmx, "Vector128 Compare Greater-Than Floating-Point" ),
INSTRUCTION(0x10000306, "vcmpgtsb" , kVC , D_A_B , kVmx, "Vector Compare Greater-Than Signed Byte" ),
INSTRUCTION(0x10000346, "vcmpgtsh" , kVC , D_A_B , kVmx, "Vector Compare Greater-Than Signed Half Word" ),
INSTRUCTION(0x10000386, "vcmpgtsw" , kVC , D_A_B , kVmx, "Vector Compare Greater-Than Signed Word" ),
INSTRUCTION(0x10000206, "vcmpgtub" , kVC , D_A_B , kVmx, "Vector Compare Greater-Than Unsigned Byte" ),
INSTRUCTION(0x10000246, "vcmpgtuh" , kVC , D_A_B , kVmx, "Vector Compare Greater-Than Unsigned Half Word" ),
INSTRUCTION(0x10000286, "vcmpgtuw" , kVC , D_A_B , kVmx, "Vector Compare Greater-Than Unsigned Word" ),
INSTRUCTION(0x180002b0, "vcsxwfp128" , kVX128_3, D_B_SIMM , kVmx, "Vector128 Convert From Signed Fixed-Point Word to Floating-Point" ),
INSTRUCTION(0x100003ca, "vctsxs" , kVX , D_A_B , kVmx, "Vector Convert to Signed Fixed-Point Word Saturate" ),
INSTRUCTION(0x1000038a, "vctuxs" , kVX , D_A_B , kVmx, "Vector Convert to Unsigned Fixed-Point Word Saturate" ),
INSTRUCTION(0x180002f0, "vcuxwfp128" , kVX128_3, D_B_SIMM , kVmx, "Vector128 Convert From Unsigned Fixed-Point Word to Floating-Point" ),
INSTRUCTION(0x1000018a, "vexptefp" , kVX , D_A_B , kVmx, "Vector 2 Raised to the Exponent Estimate Floating Point" ),
INSTRUCTION(0x180006b0, "vexptefp128" , kVX128_3, D_B , kVmx, "Vector128 Log2 Estimate Floating Point" ),
INSTRUCTION(0x100001ca, "vlogefp" , kVX , D_A_B , kVmx, "Vector Log2 Estimate Floating Point" ),
INSTRUCTION(0x180006f0, "vlogefp128" , kVX128_3, D_B , kVmx, "Vector128 Log2 Estimate Floating Point" ),
INSTRUCTION(0x14000110, "vmaddcfp128" , kVX128 , D_A_D_B , kVmx, "Vector128 Multiply Add Floating Point" ),
INSTRUCTION(0x1000002e, "vmaddfp" , kVA , D_A_B_C , kVmx, "Vector Multiply-Add Floating Point" ),
INSTRUCTION(0x140000d0, "vmaddfp128" , kVX128 , D_A_D_B , kVmx, "Vector128 Multiply Add Floating Point" ),
INSTRUCTION(0x1000040a, "vmaxfp" , kVX , D_A_B , kVmx, "Vector Maximum Floating Point" ),
INSTRUCTION(0x18000280, "vmaxfp128" , kVX128 , D_A_B , kVmx, "Vector128 Maximum Floating Point" ),
INSTRUCTION(0x10000102, "vmaxsb" , kVX , D_A_B , kVmx, "Vector Maximum Signed Byte" ),
INSTRUCTION(0x10000142, "vmaxsh" , kVX , D_A_B , kVmx, "Vector Maximum Signed Half Word" ),
INSTRUCTION(0x10000182, "vmaxsw" , kVX , D_A_B , kVmx, "Vector Maximum Signed Word" ),
INSTRUCTION(0x10000002, "vmaxub" , kVX , D_A_B , kVmx, "Vector Maximum Unsigned Byte" ),
INSTRUCTION(0x10000042, "vmaxuh" , kVX , D_A_B , kVmx, "Vector Maximum Unsigned Half Word" ),
INSTRUCTION(0x10000082, "vmaxuw" , kVX , D_A_B , kVmx, "Vector Maximum Unsigned Word" ),
INSTRUCTION(0x10000020, "vmhaddshs" , kVA , D_A_B_C , kVmx, "Vector Multiply-High and Add Signed Signed Half Word Saturate" ),
INSTRUCTION(0x10000021, "vmhraddshs" , kVA , D_A_B_C , kVmx, "Vector Multiply-High Round and Add Signed Signed Half Word Saturate" ),
INSTRUCTION(0x1000044a, "vminfp" , kVX , D_A_B , kVmx, "Vector Minimum Floating Point" ),
INSTRUCTION(0x180002c0, "vminfp128" , kVX128 , D_A_B , kVmx, "Vector128 Minimum Floating Point" ),
INSTRUCTION(0x10000302, "vminsb" , kVX , D_A_B , kVmx, "Vector Minimum Signed Byte" ),
INSTRUCTION(0x10000342, "vminsh" , kVX , D_A_B , kVmx, "Vector Minimum Signed Half Word" ),
INSTRUCTION(0x10000382, "vminsw" , kVX , D_A_B , kVmx, "Vector Minimum Signed Word" ),
INSTRUCTION(0x10000202, "vminub" , kVX , D_A_B , kVmx, "Vector Minimum Unsigned Byte" ),
INSTRUCTION(0x10000242, "vminuh" , kVX , D_A_B , kVmx, "Vector Minimum Unsigned Half Word" ),
INSTRUCTION(0x10000282, "vminuw" , kVX , D_A_B , kVmx, "Vector Minimum Unsigned Word" ),
INSTRUCTION(0x10000022, "vmladduhm" , kVA , D_A_B_C , kVmx, "Vector Multiply-Low and Add Unsigned Half Word Modulo" ),
INSTRUCTION(0x1000000c, "vmrghb" , kVX , D_A_B , kVmx, "Vector Merge High Byte" ),
INSTRUCTION(0x1000004c, "vmrghh" , kVX , D_A_B , kVmx, "Vector Merge High Half Word" ),
INSTRUCTION(0x1000008c, "vmrghw" , kVX , D_A_B , kVmx, "Vector Merge High Word" ),
INSTRUCTION(0x18000300, "vmrghw128" , kVX128 , D_A_B , kVmx, "Vector128 Merge High Word" ),
INSTRUCTION(0x1000010c, "vmrglb" , kVX , D_A_B , kVmx, "Vector Merge Low Byte" ),
INSTRUCTION(0x1000014c, "vmrglh" , kVX , D_A_B , kVmx, "Vector Merge Low Half Word" ),
INSTRUCTION(0x1000018c, "vmrglw" , kVX , D_A_B , kVmx, "Vector Merge Low Word" ),
INSTRUCTION(0x18000340, "vmrglw128" , kVX128 , D_A_B , kVmx, "Vector128 Merge Low Word" ),
INSTRUCTION(0x14000190, "vmsum3fp128" , kVX128 , D_A_B , kVmx, "Vector128 Multiply Sum 3-way Floating Point" ),
INSTRUCTION(0x140001d0, "vmsum4fp128" , kVX128 , D_A_B , kVmx, "Vector128 Multiply Sum 4-way Floating-Point" ),
INSTRUCTION(0x10000025, "vmsummbm" , kVA , D_A_B_C , kVmx, "Vector Multiply-Sum Mixed-Sign Byte Modulo" ),
INSTRUCTION(0x10000028, "vmsumshm" , kVA , D_A_B_C , kVmx, "Vector Multiply-Sum Signed Half Word Modulo" ),
INSTRUCTION(0x10000029, "vmsumshs" , kVA , D_A_B_C , kVmx, "Vector Multiply-Sum Signed Half Word Saturate" ),
INSTRUCTION(0x10000024, "vmsumubm" , kVA , D_A_B_C , kVmx, "Vector Multiply-Sum Unsigned Byte Modulo" ),
INSTRUCTION(0x10000026, "vmsumuhm" , kVA , D_A_B_C , kVmx, "Vector Multiply-Sum Unsigned Half Word Modulo" ),
INSTRUCTION(0x10000027, "vmsumuhs" , kVA , D_A_B_C , kVmx, "Vector Multiply-Sum Unsigned Half Word Saturate" ),
INSTRUCTION(0x10000308, "vmulesb" , kVX , D_A_B , kVmx, "Vector Multiply Even Signed Byte" ),
INSTRUCTION(0x10000348, "vmulesh" , kVX , D_A_B , kVmx, "Vector Multiply Even Signed Half Word" ),
INSTRUCTION(0x10000208, "vmuleub" , kVX , D_A_B , kVmx, "Vector Multiply Even Unsigned Byte" ),
INSTRUCTION(0x10000248, "vmuleuh" , kVX , D_A_B , kVmx, "Vector Multiply Even Unsigned Half Word" ),
INSTRUCTION(0x14000090, "vmulfp128" , kVX128 , D_A_B , kVmx, "Vector128 Multiply Floating-Point" ),
INSTRUCTION(0x10000108, "vmulosb" , kVX , D_A_B , kVmx, "Vector Multiply Odd Signed Byte" ),
INSTRUCTION(0x10000148, "vmulosh" , kVX , D_A_B , kVmx, "Vector Multiply Odd Signed Half Word" ),
INSTRUCTION(0x10000008, "vmuloub" , kVX , D_A_B , kVmx, "Vector Multiply Odd Unsigned Byte" ),
INSTRUCTION(0x10000048, "vmulouh" , kVX , D_A_B , kVmx, "Vector Multiply Odd Unsigned Half Word" ),
INSTRUCTION(0x1000002f, "vnmsubfp" , kVA , D_A_B_C , kVmx, "Vector Negative Multiply-Subtract Floating Point" ),
INSTRUCTION(0x14000150, "vnmsubfp128" , kVX128 , D_A_B , kVmx, "Vector128 Negative Multiply-Subtract Floating Point" ),
INSTRUCTION(0x10000504, "vnor" , kVX , D_A_B , kVmx, "Vector Logical NOR" ),
INSTRUCTION(0x14000290, "vnor128" , kVX128 , D_A_B , kVmx, "Vector128 Logical NOR" ),
INSTRUCTION(0x10000484, "vor" , kVX , D_A_B , kVmx, "Vector Logical OR" ),
INSTRUCTION(0x140002d0, "vor128" , kVX128 , D_A_B , kVmx, "Vector128 Logical OR" ),
INSTRUCTION(0x1000002b, "vperm" , kVA , D_A_B_C , kVmx, "Vector Permute" ),
INSTRUCTION(0x14000000, "vperm128" , kVX128_2, D_A_B_C , kVmx, "Vector128 Permute" ),
INSTRUCTION(0x18000210, "vpermwi128" , kVX128_P, D_A_B_C , kVmx, "Vector128 Permutate Word Immediate" ),
INSTRUCTION(0x18000610, "vpkd3d128" , kVX128_4, D_B , kVmx, "Vector128 Pack D3Dtype, Rotate Left Immediate and Mask Insert" ),
INSTRUCTION(0x1000030e, "vpkpx" , kVX , D_A_B , kVmx, "Vector Pack Pixel" ),
INSTRUCTION(0x1000018e, "vpkshss" , kVX , D_A_B , kVmx, "Vector Pack Signed Half Word Signed Saturate" ),
INSTRUCTION(0x14000200, "vpkshss128" , kVX128 , D_A_B , kVmx, "Vector128 Pack Signed Half Word Signed Saturate" ),
INSTRUCTION(0x1000010e, "vpkshus" , kVX , D_A_B , kVmx, "Vector Pack Signed Half Word Unsigned Saturate" ),
INSTRUCTION(0x14000240, "vpkshus128" , kVX128 , D_A_B , kVmx, "Vector128 Pack Signed Half Word Unsigned Saturate" ),
INSTRUCTION(0x100001ce, "vpkswss" , kVX , D_A_B , kVmx, "Vector Pack Signed Word Signed Saturate" ),
INSTRUCTION(0x14000280, "vpkswss128" , kVX128 , D_A_B , kVmx, "Vector128 Pack Signed Word Signed Saturate" ),
INSTRUCTION(0x1000014e, "vpkswus" , kVX , D_A_B , kVmx, "Vector Pack Signed Word Unsigned Saturate" ),
INSTRUCTION(0x140002c0, "vpkswus128" , kVX128 , D_A_B , kVmx, "Vector128 Pack Signed Word Unsigned Saturate" ),
INSTRUCTION(0x1000000e, "vpkuhum" , kVX , D_A_B , kVmx, "Vector Pack Unsigned Half Word Unsigned Modulo" ),
INSTRUCTION(0x14000300, "vpkuhum128" , kVX128 , D_A_B , kVmx, "Vector128 Pack Unsigned Half Word Unsigned Modulo" ),
INSTRUCTION(0x1000008e, "vpkuhus" , kVX , D_A_B , kVmx, "Vector Pack Unsigned Half Word Unsigned Saturate" ),
INSTRUCTION(0x14000340, "vpkuhus128" , kVX128 , D_A_B , kVmx, "Vector128 Pack Unsigned Half Word Unsigned Saturate" ),
INSTRUCTION(0x1000004e, "vpkuwum" , kVX , D_A_B , kVmx, "Vector Pack Unsigned Word Unsigned Modulo" ),
INSTRUCTION(0x14000380, "vpkuwum128" , kVX128 , D_A_B , kVmx, "Vector128 Pack Unsigned Word Unsigned Modulo" ),
INSTRUCTION(0x100000ce, "vpkuwus" , kVX , D_A_B , kVmx, "Vector Pack Unsigned Word Unsigned Saturate" ),
INSTRUCTION(0x140003c0, "vpkuwus128" , kVX128 , D_A_B , kVmx, "Vector128 Pack Unsigned Word Unsigned Saturate" ),
INSTRUCTION(0x1000010a, "vrefp" , kVX , D_A_B , kVmx, "Vector Reciprocal Estimate Floating Point" ),
INSTRUCTION(0x18000630, "vrefp128" , kVX128_3, D_B , kVmx, "Vector128 Reciprocal Estimate Floating Point" ),
INSTRUCTION(0x100002ca, "vrfim" , kVX , D_A_B , kVmx, "Vector Round to Floating-Point Integer toward -Infinity" ),
INSTRUCTION(0x18000330, "vrfim128" , kVX128_3, D_B , kVmx, "Vector128 Round to Floating-Point Integer toward -Infinity" ),
INSTRUCTION(0x1000020a, "vrfin" , kVX , D_A_B , kVmx, "Vector Round to Floating-Point Integer Nearest" ),
INSTRUCTION(0x18000370, "vrfin128" , kVX128_3, D_B , kVmx, "Vector128 Round to Floating-Point Integer Nearest" ),
INSTRUCTION(0x1000028a, "vrfip" , kVX , D_A_B , kVmx, "Vector Round to Floating-Point Integer toward +Infinity" ),
INSTRUCTION(0x180003b0, "vrfip128" , kVX128_3, D_B , kVmx, "Vector128 Round to Floating-Point Integer toward +Infinity" ),
INSTRUCTION(0x1000024a, "vrfiz" , kVX , D_A_B , kVmx, "Vector Round to Floating-Point Integer toward Zero" ),
INSTRUCTION(0x180003f0, "vrfiz128" , kVX128_3, D_B , kVmx, "Vector128 Round to Floating-Point Integer toward Zero" ),
INSTRUCTION(0x10000004, "vrlb" , kVX , D_A_B , kVmx, "Vector Rotate Left Integer Byte" ),
INSTRUCTION(0x10000044, "vrlh" , kVX , D_A_B , kVmx, "Vector Rotate Left Integer Half Word" ),
INSTRUCTION(0x18000710, "vrlimi128" , kVX128_4, D_B_UIMM , kVmx, "Vector128 Rotate Left Immediate and Mask Insert" ),
INSTRUCTION(0x10000084, "vrlw" , kVX , D_A_B , kVmx, "Vector Rotate Left Integer Word" ),
INSTRUCTION(0x18000050, "vrlw128" , kVX128 , D_A_B , kVmx, "Vector128 Rotate Left Word" ),
INSTRUCTION(0x1000014a, "vrsqrtefp" , kVX , D_A_B , kVmx, "Vector Reciprocal Square Root Estimate Floating Point" ),
INSTRUCTION(0x18000670, "vrsqrtefp128", kVX128_3, D_B , kVmx, "Vector128 Reciprocal Square Root Estimate Floating Point" ),
INSTRUCTION(0x1000002a, "vsel" , kVA , D_A_B_C , kVmx, "Vector Conditional Select" ),
INSTRUCTION(0x14000350, "vsel128" , kVX128 , D_A_B_D , kVmx, "Vector128 Conditional Select" ),
INSTRUCTION(0x100001c4, "vsl" , kVX , D_A_B , kVmx, "Vector Shift Left" ),
INSTRUCTION(0x10000104, "vslb" , kVX , D_A_B , kVmx, "Vector Shift Left Integer Byte" ),
INSTRUCTION(0x1000002c, "vsldoi" , kVA , D_A_B_C , kVmx, "Vector Shift Left Double by Octet Immediate" ),
INSTRUCTION(0x10000010, "vsldoi128" , kVX128_5, D_A_B_I , kVmx, "Vector128 Shift Left Double by Octet Immediate" ),
INSTRUCTION(0x10000144, "vslh" , kVX , D_A_B , kVmx, "Vector Shift Left Integer Half Word" ),
INSTRUCTION(0x1000040c, "vslo" , kVX , D_A_B , kVmx, "Vector Shift Left by Octet" ),
INSTRUCTION(0x14000390, "vslo128" , kVX128 , D_A_B , kVmx, "Vector128 Shift Left Octet" ),
INSTRUCTION(0x10000184, "vslw" , kVX , D_A_B , kVmx, "Vector Shift Left Integer Word" ),
INSTRUCTION(0x180000d0, "vslw128" , kVX128 , D_A_B , kVmx, "Vector128 Shift Left Integer Word" ),
INSTRUCTION(0x1000020c, "vspltb" , kVX , D_A_B , kVmx, "Vector Splat Byte" ),
INSTRUCTION(0x1000024c, "vsplth" , kVX , D_A_B , kVmx, "Vector Splat Half Word" ),
INSTRUCTION(0x1000030c, "vspltisb" , kVX , D_A_B , kVmx, "Vector Splat Immediate Signed Byte" ),
INSTRUCTION(0x1000034c, "vspltish" , kVX , D_A_B , kVmx, "Vector Splat Immediate Signed Half Word" ),
INSTRUCTION(0x1000038c, "vspltisw" , kVX , D_A_B , kVmx, "Vector Splat Immediate Signed Word" ),
INSTRUCTION(0x18000770, "vspltisw128" , kVX128_3, D_B_SIMM , kVmx, "Vector128 Splat Immediate Signed Word" ),
INSTRUCTION(0x1000028c, "vspltw" , kVX , D_A_B , kVmx, "Vector Splat Word" ),
INSTRUCTION(0x18000730, "vspltw128" , kVX128_3, D_B_SIMM , kVmx, "Vector128 Splat Word" ),
INSTRUCTION(0x100002c4, "vsr" , kVX , D_A_B , kVmx, "Vector Shift Right" ),
INSTRUCTION(0x10000304, "vsrab" , kVX , D_A_B , kVmx, "Vector Shift Right Algebraic Byte" ),
INSTRUCTION(0x10000344, "vsrah" , kVX , D_A_B , kVmx, "Vector Shift Right Algebraic Half Word" ),
INSTRUCTION(0x10000384, "vsraw" , kVX , D_A_B , kVmx, "Vector Shift Right Algebraic Word" ),
INSTRUCTION(0x18000150, "vsraw128" , kVX128 , D_A_B , kVmx, "Vector128 Shift Right Arithmetic Word" ),
INSTRUCTION(0x10000204, "vsrb" , kVX , D_A_B , kVmx, "Vector Shift Right Byte" ),
INSTRUCTION(0x10000244, "vsrh" , kVX , D_A_B , kVmx, "Vector Shift Right Half Word" ),
INSTRUCTION(0x1000044c, "vsro" , kVX , D_A_B , kVmx, "Vector Shift Right Octet" ),
INSTRUCTION(0x140003d0, "vsro128" , kVX128 , D_A_B , kVmx, "Vector128 Shift Right Octet" ),
INSTRUCTION(0x10000284, "vsrw" , kVX , D_A_B , kVmx, "Vector Shift Right Word" ),
INSTRUCTION(0x180001d0, "vsrw128" , kVX128 , D_A_B , kVmx, "Vector128 Shift Right Word" ),
INSTRUCTION(0x10000580, "vsubcuw" , kVX , D_A_B , kVmx, "Vector Subtract Carryout Unsigned Word" ),
INSTRUCTION(0x1000004a, "vsubfp" , kVX , D_A_B , kVmx, "Vector Subtract Floating Point" ),
INSTRUCTION(0x14000050, "vsubfp128" , kVX128 , D_A_B , kVmx, "Vector128 Subtract Floating Point" ),
INSTRUCTION(0x10000700, "vsubsbs" , kVX , D_A_B , kVmx, "Vector Subtract Signed Byte Saturate" ),
INSTRUCTION(0x10000740, "vsubshs" , kVX , D_A_B , kVmx, "Vector Subtract Signed Half Word Saturate" ),
INSTRUCTION(0x10000780, "vsubsws" , kVX , D_A_B , kVmx, "Vector Subtract Signed Word Saturate" ),
INSTRUCTION(0x10000400, "vsububm" , kVX , D_A_B , kVmx, "Vector Subtract Unsigned Byte Modulo" ),
INSTRUCTION(0x10000600, "vsububs" , kVX , D_A_B , kVmx, "Vector Subtract Unsigned Byte Saturate" ),
INSTRUCTION(0x10000440, "vsubuhm" , kVX , D_A_B , kVmx, "Vector Subtract Unsigned Half Word Modulo" ),
INSTRUCTION(0x10000640, "vsubuhs" , kVX , D_A_B , kVmx, "Vector Subtract Unsigned Half Word Saturate" ),
INSTRUCTION(0x10000480, "vsubuwm" , kVX , D_A_B , kVmx, "Vector Subtract Unsigned Word Modulo" ),
INSTRUCTION(0x10000680, "vsubuws" , kVX , D_A_B , kVmx, "Vector Subtract Unsigned Word Saturate" ),
INSTRUCTION(0x10000688, "vsum2sws" , kVX , D_A_B , kVmx, "Vector Sum Across Partial (1/2) Signed Word Saturate" ),
INSTRUCTION(0x10000708, "vsum4sbs" , kVX , D_A_B , kVmx, "Vector Sum Across Partial (1/4) Signed Byte Saturate" ),
INSTRUCTION(0x10000648, "vsum4shs" , kVX , D_A_B , kVmx, "Vector Sum Across Partial (1/4) Signed Half Word Saturate" ),
INSTRUCTION(0x10000608, "vsum4ubs" , kVX , D_A_B , kVmx, "Vector Sum Across Partial (1/4) Unsigned Byte Saturate" ),
INSTRUCTION(0x10000788, "vsumsws" , kVX , D_A_B , kVmx, "Vector Sum Across Signed Word Saturate" ),
INSTRUCTION(0x180007f0, "vupkd3d128" , kVX128_3, D_B_SIMM , kVmx, "Vector128 Unpack D3Dtype" ),
INSTRUCTION(0x1000034e, "vupkhpx" , kVX , D_A_B , kVmx, "Vector Unpack High Pixel" ),
INSTRUCTION(0x1000020e, "vupkhsb" , kVX , D_A_B , kVmx, "Vector Unpack High Signed Byte" ),
INSTRUCTION(0x18000380, "vupkhsb128" , kVX128 , D_B , kVmx, "Vector128 Unpack High Signed Byte" ),
INSTRUCTION(0x1000024e, "vupkhsh" , kVX , D_A_B , kVmx, "Vector Unpack High Signed Half Word" ),
INSTRUCTION(0x100003ce, "vupklpx" , kVX , D_A_B , kVmx, "Vector Unpack Low Pixel" ),
INSTRUCTION(0x1000028e, "vupklsb" , kVX , D_A_B , kVmx, "Vector Unpack Low Signed Byte" ),
INSTRUCTION(0x180003c0, "vupklsb128" , kVX128 , D_B , kVmx, "Vector128 Unpack Low Signed Byte" ),
INSTRUCTION(0x100002ce, "vupklsh" , kVX , D_A_B , kVmx, "Vector Unpack Low Signed Half Word" ),
INSTRUCTION(0x100004c4, "vxor" , kVX , D_A_B , kVmx, "Vector Logical XOR" ),
INSTRUCTION(0x14000310, "vxor128" , kVX128 , D_A_B , kVmx, "Vector128 Logical XOR" ),
INSTRUCTION(0x68000000, "xori" , kD , S_A_UIMM , kInt, "XOR Immediate" ),
INSTRUCTION(0x6c000000, "xoris" , kD , S_A_UIMM , kInt, "XOR Immediate Shifted" ),
INSTRUCTION(0x7c000278, "xorx" , kX , S_A_B_Rc , kInt, "XOR" ),
INSTRUCTION(0x7c000014, "addcx" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Add Carrying" ),
INSTRUCTION(0x7c000114, "addex" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Add Extended" ),
INSTRUCTION(0x38000000, "addi" , kD , D_A_SIMM , kI, kGeneral, "Add Immediate" ),
INSTRUCTION(0x30000000, "addic" , kD , D_A_SIMM , kI, kGeneral, "Add Immediate Carrying" ),
INSTRUCTION(0x34000000, "addicx" , kD , D_A_SIMM , kI, kGeneral, "Add Immediate Carrying and Record" ),
INSTRUCTION(0x3c000000, "addis" , kD , D_A_SIMM , kI, kGeneral, "Add Immediate Shifted" ),
INSTRUCTION(0x7c0001d4, "addmex" , kXO , D_A_0_OE_Rc , kI, kGeneral, "Add to Minus One Extended" ),
INSTRUCTION(0x7c000214, "addx" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Add" ),
INSTRUCTION(0x7c000194, "addzex" , kXO , D_A_0_OE_Rc , kI, kGeneral, "Add to Zero Extended" ),
INSTRUCTION(0x7c000078, "andcx" , kX , S_A_B_Rc , kI, kGeneral, "AND with Complement" ),
INSTRUCTION(0x74000000, "andisx" , kD , S_A_UIMM , kI, kGeneral, "AND Immediate Shifted" ),
INSTRUCTION(0x70000000, "andix" , kD , S_A_UIMM , kI, kGeneral, "AND Immediate" ),
INSTRUCTION(0x7c000038, "andx" , kX , S_A_B_Rc , kI, kGeneral, "AND" ),
INSTRUCTION(0x4c000420, "bcctrx" , kXL , BO_BI_0_LK , kI, kSync , "Branch Conditional to Count Register" ),
INSTRUCTION(0x4c000020, "bclrx" , kXL , BO_BI_0_LK , kI, kSync , "Branch Conditional to Link Register" ),
INSTRUCTION(0x40000000, "bcx" , kB , BO_BI_BD_AA_LK , kI, kSync , "Branch Conditional" ),
INSTRUCTION(0x48000000, "bx" , kI , LI_AA_LK , kI, kSync , "Branch" ),
INSTRUCTION(0x7c000000, "cmp" , kX , crfD_L_A_B , kI, kGeneral, "Compare" ),
INSTRUCTION(0x2c000000, "cmpi" , kD , crfD_L_A_SIMM , kI, kGeneral, "Compare Immediate" ),
INSTRUCTION(0x7c000040, "cmpl" , kX , crfD_L_A_B , kI, kGeneral, "Compare Logical" ),
INSTRUCTION(0x28000000, "cmpli" , kD , crfD_L_A_UIMM , kI, kGeneral, "Compare Logical Immediate" ),
INSTRUCTION(0x7c000074, "cntlzdx" , kX , S_A_0_Rc , kI, kGeneral, "Count Leading Zeros Doubleword" ),
INSTRUCTION(0x7c000034, "cntlzwx" , kX , S_A_0_Rc , kI, kGeneral, "Count Leading Zeros Word" ),
INSTRUCTION(0x4c000202, "crand" , kXL , crbD_crbA_crbB , kI, kGeneral, "Condition Register AND" ),
INSTRUCTION(0x4c000102, "crandc" , kXL , crbD_crbA_crbB , kI, kGeneral, "Condition Register AND with Complement" ),
INSTRUCTION(0x4c000242, "creqv" , kXL , crbD_crbA_crbB , kI, kGeneral, "Condition Register Equivalent" ),
INSTRUCTION(0x4c0001c2, "crnand" , kXL , crbD_crbA_crbB , kI, kGeneral, "Condition Register NAND" ),
INSTRUCTION(0x4c000042, "crnor" , kXL , crbD_crbA_crbB , kI, kGeneral, "Condition Register NOR" ),
INSTRUCTION(0x4c000382, "cror" , kXL , crbD_crbA_crbB , kI, kGeneral, "Condition Register OR" ),
INSTRUCTION(0x4c000342, "crorc" , kXL , crbD_crbA_crbB , kI, kGeneral, "Condition Register OR with Complement" ),
INSTRUCTION(0x4c000182, "crxor" , kXL , crbD_crbA_crbB , kI, kGeneral, "Condition Register XOR" ),
INSTRUCTION(0x7c0005ec, "dcba" , kX , _0_A_B , kI, kGeneral, "Data Cache Block Allocate" ),
INSTRUCTION(0x7c0000ac, "dcbf" , kX , _0_A_B , kI, kGeneral, "Data Cache Block Flush" ),
INSTRUCTION(0x7c0003ac, "dcbi" , kX , _0_A_B , kI, kGeneral, "Data Cache Block Invalidate" ),
INSTRUCTION(0x7c00006c, "dcbst" , kX , _0_A_B , kI, kGeneral, "Data Cache Block Store" ),
INSTRUCTION(0x7c00022c, "dcbt" , kX , _0_A_B , kI, kGeneral, "Data Cache Block Touch" ),
INSTRUCTION(0x7c0001ec, "dcbtst" , kX , _0_A_B , kI, kGeneral, "Data Cache Block Touch for Store" ),
INSTRUCTION(0x7c0007ec, "dcbz" , kDCBZ , _0_A_B , kI, kGeneral, "Data Cache Block Clear to Zero" ),
INSTRUCTION(0x7c2007ec, "dcbz128" , kDCBZ , _0_A_B , kI, kGeneral, "Data Cache Block Clear to Zero 128" ),
INSTRUCTION(0x7c000392, "divdux" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Divide Doubleword Unsigned" ),
INSTRUCTION(0x7c0003d2, "divdx" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Divide Doubleword" ),
INSTRUCTION(0x7c000396, "divwux" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Divide Word Unsigned" ),
INSTRUCTION(0x7c0003d6, "divwx" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Divide Word" ),
INSTRUCTION(0x7c00026c, "eciwx" , kX , D_A_B , kI, kGeneral, "External Control In Word Indexed" ),
INSTRUCTION(0x7c00036c, "ecowx" , kX , S_A_B , kI, kGeneral, "External Control Out Word Indexed" ),
INSTRUCTION(0x7c0006ac, "eieio" , kX , _0_0_0 , kI, kGeneral, "Enforce In-Order Execution of I/O" ),
INSTRUCTION(0x7c000238, "eqvx" , kX , S_A_B_Rc , kI, kGeneral, "Equivalent" ),
INSTRUCTION(0x7c000774, "extsbx" , kX , S_A_0_Rc , kI, kGeneral, "Extend Sign Byte" ),
INSTRUCTION(0x7c000734, "extshx" , kX , S_A_0_Rc , kI, kGeneral, "Extend Sign Half Word" ),
INSTRUCTION(0x7c0007b4, "extswx" , kX , S_A_0_Rc , kI, kGeneral, "Extend Sign Word" ),
INSTRUCTION(0xfc000210, "fabsx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Absolute Value" ),
INSTRUCTION(0xec00002a, "faddsx" , kA , D_A_B_0_Rc , kF, kGeneral, "Floating Add Single" ),
INSTRUCTION(0xfc00002a, "faddx" , kA , D_A_B_0_Rc , kF, kGeneral, "Floating Add" ),
INSTRUCTION(0xfc00069c, "fcfidx" , kX , D_A_B_Rc , kF, kGeneral, "Floating Convert From Integer Doubleword" ),
INSTRUCTION(0xfc000040, "fcmpo" , kX , crfD_A_B , kF, kGeneral, "Floating Compare Ordered" ),
INSTRUCTION(0xfc000000, "fcmpu" , kX , crfD_A_B , kF, kGeneral, "Floating Compare Unordered" ),
INSTRUCTION(0xfc00065c, "fctidx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Convert to Integer Doubleword" ),
INSTRUCTION(0xfc00065e, "fctidzx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Convert to Integer Doubleword with Round Toward Zero" ),
INSTRUCTION(0xfc00001c, "fctiwx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Convert to Integer Word" ),
INSTRUCTION(0xfc00001e, "fctiwzx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Convert to Integer Word with Round Toward Zero" ),
INSTRUCTION(0xec000024, "fdivsx" , kA , D_A_B_0_Rc , kF, kGeneral, "Floating Divide Single" ),
INSTRUCTION(0xfc000024, "fdivx" , kA , D_A_B_0_Rc , kF, kGeneral, "Floating Divide" ),
INSTRUCTION(0xec00003a, "fmaddsx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Multiply-Add Single" ),
INSTRUCTION(0xfc00003a, "fmaddx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Multiply-Add" ),
INSTRUCTION(0xfc000090, "fmrx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Move Register" ),
INSTRUCTION(0xec000038, "fmsubsx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Multiply-Subtract Single" ),
INSTRUCTION(0xfc000038, "fmsubx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Multiply-Subtract" ),
INSTRUCTION(0xec000032, "fmulsx" , kA , D_A_0_C_Rc , kF, kGeneral, "Floating Multiply Single" ),
INSTRUCTION(0xfc000032, "fmulx" , kA , D_A_0_C_Rc , kF, kGeneral, "Floating Multiply" ),
INSTRUCTION(0xfc000110, "fnabsx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Negative Absolute Value" ),
INSTRUCTION(0xfc000050, "fnegx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Negate" ),
INSTRUCTION(0xec00003e, "fnmaddsx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Negative Multiply-Add Single" ),
INSTRUCTION(0xfc00003e, "fnmaddx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Negative Multiply-Add" ),
INSTRUCTION(0xec00003c, "fnmsubsx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Negative Multiply-Subtract Single" ),
INSTRUCTION(0xfc00003c, "fnmsubx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Negative Multiply-Subtract" ),
INSTRUCTION(0xec000030, "fresx" , kA , D_0_B_0_Rc , kF, kGeneral, "Floating Reciprocal Estimate Single" ),
INSTRUCTION(0xfc000018, "frspx" , kX , D_0_B_Rc , kF, kGeneral, "Floating Round to Single" ),
INSTRUCTION(0xfc000034, "frsqrtex" , kA , D_0_B_0_Rc , kF, kGeneral, "Floating Reciprocal Square Root Estimate" ),
INSTRUCTION(0xfc00002e, "fselx" , kA , D_A_B_C_Rc , kF, kGeneral, "Floating Select" ),
INSTRUCTION(0xec00002c, "fsqrtsx" , kA , D_0_B_0_Rc , kF, kGeneral, "Floating Square Root Single" ),
INSTRUCTION(0xfc00002c, "fsqrtx" , kA , D_0_B_0_Rc , kF, kGeneral, "Floating Square Root" ),
INSTRUCTION(0xec000028, "fsubsx" , kA , D_A_B_0_Rc , kF, kGeneral, "Floating Subtract Single" ),
INSTRUCTION(0xfc000028, "fsubx" , kA , D_A_B_0_Rc , kF, kGeneral, "Floating Subtract" ),
INSTRUCTION(0x7c0007ac, "icbi" , kX , _0_A_B , kI, kGeneral, "Instruction Cache Block Invalidate" ),
INSTRUCTION(0x4c00012c, "isync" , kXL , _0_0_0 , kI, kGeneral, "Instruction Synchronize" ),
INSTRUCTION(0x88000000, "lbz" , kD , D_A_d , kI, kGeneral, "Load Byte and Zero" ),
INSTRUCTION(0x8c000000, "lbzu" , kD , D_A_d , kI, kGeneral, "Load Byte and Zero with Update" ),
INSTRUCTION(0x7c0000ee, "lbzux" , kX , D_A_B , kI, kGeneral, "Load Byte and Zero with Update Indexed" ),
INSTRUCTION(0x7c0000ae, "lbzx" , kX , D_A_B , kI, kGeneral, "Load Byte and Zero Indexed" ),
INSTRUCTION(0xe8000000, "ld" , kDS , D_A_d , kI, kGeneral, "Load Doubleword" ),
INSTRUCTION(0x7c0000a8, "ldarx" , kX , D_A_B , kI, kGeneral, "Load Doubleword and Reserve Indexed" ),
INSTRUCTION(0x7c000428, "ldbrx" , kX , D_A_B , kI, kGeneral, "Load Doubleword Byte-Reverse Indexed" ),
INSTRUCTION(0xe8000001, "ldu" , kDS , D_A_d , kI, kGeneral, "Load Doubleword with Update" ),
INSTRUCTION(0x7c00006a, "ldux" , kX , D_A_B , kI, kGeneral, "Load Doubleword with Update Indexed" ),
INSTRUCTION(0x7c00002a, "ldx" , kX , D_A_B , kI, kGeneral, "Load Doubleword Indexed" ),
INSTRUCTION(0xc8000000, "lfd" , kD , D_A_d , kF, kGeneral, "Load Floating-Point Double" ),
INSTRUCTION(0xcc000000, "lfdu" , kD , D_A_d , kF, kGeneral, "Load Floating-Point Double with Update" ),
INSTRUCTION(0x7c0004ee, "lfdux" , kX , D_A_B , kF, kGeneral, "Load Floating-Point Double with Update Indexed" ),
INSTRUCTION(0x7c0004ae, "lfdx" , kX , D_A_B , kF, kGeneral, "Load Floating-Point Double Indexed" ),
INSTRUCTION(0xc0000000, "lfs" , kD , D_A_d , kF, kGeneral, "Load Floating-Point Single" ),
INSTRUCTION(0xc4000000, "lfsu" , kD , D_A_d , kF, kGeneral, "Load Floating-Point Single with Update" ),
INSTRUCTION(0x7c00046e, "lfsux" , kX , D_A_B , kF, kGeneral, "Load Floating-Point Single with Update Indexed" ),
INSTRUCTION(0x7c00042e, "lfsx" , kX , D_A_B , kF, kGeneral, "Load Floating-Point Single Indexed" ),
INSTRUCTION(0xa8000000, "lha" , kD , D_A_d , kI, kGeneral, "Load Half Word Algebraic" ),
INSTRUCTION(0xac000000, "lhau" , kD , D_A_d , kI, kGeneral, "Load Half Word Algebraic with Update" ),
INSTRUCTION(0x7c0002ee, "lhaux" , kX , D_A_B , kI, kGeneral, "Load Half Word Algebraic with Update Indexed" ),
INSTRUCTION(0x7c0002ae, "lhax" , kX , D_A_B , kI, kGeneral, "Load Half Word Algebraic Indexed" ),
INSTRUCTION(0x7c00062c, "lhbrx" , kX , D_A_B , kI, kGeneral, "Load Half Word Byte-Reverse Indexed" ),
INSTRUCTION(0xa0000000, "lhz" , kD , D_A_d , kI, kGeneral, "Load Half Word and Zero" ),
INSTRUCTION(0xa4000000, "lhzu" , kD , D_A_d , kI, kGeneral, "Load Half Word and Zero with Update" ),
INSTRUCTION(0x7c00026e, "lhzux" , kX , D_A_B , kI, kGeneral, "Load Half Word and Zero with Update Indexed" ),
INSTRUCTION(0x7c00022e, "lhzx" , kX , D_A_B , kI, kGeneral, "Load Half Word and Zero Indexed" ),
INSTRUCTION(0xb8000000, "lmw" , kD , D_A_d , kI, kGeneral, "Load Multiple Word" ),
INSTRUCTION(0x7c0004aa, "lswi" , kX , D_A_NB , kI, kGeneral, "Load String Word Immediate" ),
INSTRUCTION(0x7c00042a, "lswx" , kX , D_A_B , kI, kGeneral, "Load String Word Indexed" ),
INSTRUCTION(0x7c00000e, "lvebx" , kX , D_A_B , kV, kGeneral, "Load Vector Element Byte Indexed" ),
INSTRUCTION(0x7c00004e, "lvehx" , kX , D_A_B , kV, kGeneral, "Load Vector Element Half Word Indexed" ),
INSTRUCTION(0x7c00008e, "lvewx" , kX , D_A_B , kV, kGeneral, "Load Vector Element Word Indexed" ),
INSTRUCTION(0x10000083, "lvewx128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector Element Word Indexed 128" ),
INSTRUCTION(0x7c00040e, "lvlx" , kX , D_A_B , kV, kGeneral, "Load Vector Left Indexed" ),
INSTRUCTION(0x10000403, "lvlx128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector Left Indexed 128" ),
INSTRUCTION(0x7c00060e, "lvlxl" , kX , D_A_B , kV, kGeneral, "Load Vector Left Indexed LRU" ),
INSTRUCTION(0x10000603, "lvlxl128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector Left Indexed LRU 128" ),
INSTRUCTION(0x7c00044e, "lvrx" , kX , D_A_B , kV, kGeneral, "Load Vector Right Indexed" ),
INSTRUCTION(0x10000443, "lvrx128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector Right Indexed 128" ),
INSTRUCTION(0x7c00064e, "lvrxl" , kX , D_A_B , kV, kGeneral, "Load Vector Right Indexed LRU" ),
INSTRUCTION(0x10000643, "lvrxl128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector Right Indexed LRU 128" ),
INSTRUCTION(0x7c00000c, "lvsl" , kX , D_A_B , kV, kGeneral, "Load Vector for Shift Left Indexed" ),
INSTRUCTION(0x10000003, "lvsl128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector for Shift Left Indexed 128" ),
INSTRUCTION(0x7c00004c, "lvsr" , kX , D_A_B , kV, kGeneral, "Load Vector for Shift Right Indexed" ),
INSTRUCTION(0x10000043, "lvsr128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector for Shift Right Indexed 128" ),
INSTRUCTION(0x7c0000ce, "lvx" , kX , D_A_B , kV, kGeneral, "Load Vector Indexed" ),
INSTRUCTION(0x100000c3, "lvx128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector Indexed 128" ),
INSTRUCTION(0x7c0002ce, "lvxl" , kX , D_A_B , kV, kGeneral, "Load Vector Indexed LRU" ),
INSTRUCTION(0x100002c3, "lvxl128" , kVX128_1, D_A_B , kV, kGeneral, "Load Vector Indexed LRU 128" ),
INSTRUCTION(0xe8000002, "lwa" , kDS , D_A_d , kI, kGeneral, "Load Word Algebraic" ),
INSTRUCTION(0x7c000028, "lwarx" , kX , D_A_B , kI, kGeneral, "Load Word and Reserve Indexed" ),
INSTRUCTION(0x7c0002ea, "lwaux" , kX , D_A_B , kI, kGeneral, "Load Word Algebraic with Update Indexed" ),
INSTRUCTION(0x7c0002aa, "lwax" , kX , D_A_B , kI, kGeneral, "Load Word Algebraic Indexed" ),
INSTRUCTION(0x7c00042c, "lwbrx" , kX , D_A_B , kI, kGeneral, "Load Word Byte-Reverse Indexed" ),
INSTRUCTION(0x80000000, "lwz" , kD , D_A_d , kI, kGeneral, "Load Word and Zero" ),
INSTRUCTION(0x84000000, "lwzu" , kD , D_A_d , kI, kGeneral, "Load Word and Zero with Update" ),
INSTRUCTION(0x7c00006e, "lwzux" , kX , D_A_B , kI, kGeneral, "Load Word and Zero with Update Indexed" ),
INSTRUCTION(0x7c00002e, "lwzx" , kX , D_A_B , kI, kGeneral, "Load Word and Zero Indexed" ),
INSTRUCTION(0x4c000000, "mcrf" , kXL , crfD_crfS_0 , kI, kGeneral, "Move Condition Register Field" ),
INSTRUCTION(0xfc000080, "mcrfs" , kX , crfD_crfS_0 , kF, kGeneral, "Move to Condition Register from FPSCR" ),
INSTRUCTION(0x7c000400, "mcrxr" , kX , crfD_0_0 , kI, kGeneral, "Move to Condition Register from XER" ),
INSTRUCTION(0x7c000026, "mfcr" , kX , D_0_0 , kI, kGeneral, "Move from Condition Register" ),
INSTRUCTION(0xfc00048e, "mffsx" , kX , D_0_0_Rc , kF, kGeneral, "Move from FPSCR" ),
INSTRUCTION(0x7c0000a6, "mfmsr" , kX , D_0_0 , kI, kGeneral, "Move from Machine State Register" ),
INSTRUCTION(0x7c0002a6, "mfspr" , kXFX , D_spr , kI, kGeneral, "Move from Special-Purpose Register" ),
INSTRUCTION(0x7c0002e6, "mftb" , kXFX , D_tbr , kI, kGeneral, "Move from Time Base" ),
INSTRUCTION(0x10000604, "mfvscr" , kVX , D_0_0 , kI, kGeneral, "Move from VSCR" ),
INSTRUCTION(0x7c000120, "mtcrf" , kXFX , S_CRM , kI, kGeneral, "Move to Condition Register Fields" ),
INSTRUCTION(0xfc00008c, "mtfsb0x" , kX , crbD_0_0_Rc , kF, kGeneral, "Move to FPSCR Bit 0" ),
INSTRUCTION(0xfc00004c, "mtfsb1x" , kX , crbD_0_0_Rc , kF, kGeneral, "Move to FPSCR Bit 1" ),
INSTRUCTION(0xfc00010c, "mtfsfix" , kX , crfD_0_IMM_Rc , kF, kGeneral, "Move to FPSCR Field Immediate" ),
INSTRUCTION(0xfc00058e, "mtfsfx" , kXFL , FM_B_Rc , kF, kGeneral, "Move to FPSCR Fields" ),
INSTRUCTION(0x7c000124, "mtmsr" , kX , S_0_0 , kI, kGeneral, "Move to Machine State Register" ),
INSTRUCTION(0x7c000164, "mtmsrd" , kX , S_0_0 , kI, kGeneral, "Move to Machine State Register Doubleword" ),
INSTRUCTION(0x7c0003a6, "mtspr" , kXFX , S_spr , kI, kGeneral, "Move to Special-Purpose Register" ),
INSTRUCTION(0x10000644, "mtvscr" , kVX , S_0_0 , kI, kGeneral, "Move to VSCR" ),
INSTRUCTION(0x7c000012, "mulhdux" , kXO , D_A_B_Rc , kI, kGeneral, "Multiply High Doubleword Unsigned" ),
INSTRUCTION(0x7c000092, "mulhdx" , kXO , D_A_B_Rc , kI, kGeneral, "Multiply High Doubleword" ),
INSTRUCTION(0x7c000016, "mulhwux" , kXO , D_A_B_Rc , kI, kGeneral, "Multiply High Word Unsigned" ),
INSTRUCTION(0x7c000096, "mulhwx" , kXO , D_A_B_Rc , kI, kGeneral, "Multiply High Word" ),
INSTRUCTION(0x7c0001d2, "mulldx" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Multiply Low Doubleword" ),
INSTRUCTION(0x1c000000, "mulli" , kD , D_A_SIMM , kI, kGeneral, "Multiply Low Immediate" ),
INSTRUCTION(0x7c0001d6, "mullwx" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Multiply Low Word" ),
INSTRUCTION(0x7c0003b8, "nandx" , kX , S_A_B_Rc , kI, kGeneral, "NAND" ),
INSTRUCTION(0x7c0000d0, "negx" , kXO , D_A_0_OE_Rc , kI, kGeneral, "Negate" ),
INSTRUCTION(0x7c0000f8, "norx" , kX , S_A_B_Rc , kI, kGeneral, "NOR" ),
INSTRUCTION(0x7c000338, "orcx" , kX , S_A_B_Rc , kI, kGeneral, "OR with Complement" ),
INSTRUCTION(0x60000000, "ori" , kD , S_A_UIMM , kI, kGeneral, "OR Immediate" ),
INSTRUCTION(0x64000000, "oris" , kD , S_A_UIMM , kI, kGeneral, "OR Immediate Shifted" ),
INSTRUCTION(0x7c000378, "orx" , kX , S_A_B_Rc , kI, kGeneral, "OR" ),
INSTRUCTION(0x78000010, "rldclx" , kMDS , S_A_B_MB_ME_Rc , kI, kGeneral, "Rotate Left Doubleword then Clear Left" ),
INSTRUCTION(0x78000012, "rldcrx" , kMDS , S_A_B_MB_ME_Rc , kI, kGeneral, "Rotate Left Doubleword then Clear Right" ),
INSTRUCTION(0x78000000, "rldiclx" , kMDSH , S_A_SH_MB_ME_Rc, kI, kGeneral, "Rotate Left Doubleword Immediate then Clear Left" ),
INSTRUCTION(0x78000004, "rldicrx" , kMDSH , S_A_SH_MB_ME_Rc, kI, kGeneral, "Rotate Left Doubleword Immediate then Clear Right" ),
INSTRUCTION(0x78000008, "rldicx" , kMDSH , S_A_SH_MB_ME_Rc, kI, kGeneral, "Rotate Left Doubleword Immediate then Clear" ),
INSTRUCTION(0x7800000c, "rldimix" , kMDSH , S_A_SH_MB_ME_Rc, kI, kGeneral, "Rotate Left Doubleword Immediate then Mask Insert" ),
INSTRUCTION(0x50000000, "rlwimix" , kM , S_A_SH_MB_ME_Rc, kI, kGeneral, "Rotate Left Word Immediate then Mask Insert" ),
INSTRUCTION(0x54000000, "rlwinmx" , kM , S_A_SH_MB_ME_Rc, kI, kGeneral, "Rotate Left Word Immediate then AND with Mask" ),
INSTRUCTION(0x5c000000, "rlwnmx" , kM , S_A_SH_MB_ME_Rc, kI, kGeneral, "Rotate Left Word then AND with Mask" ),
INSTRUCTION(0x44000002, "sc" , kSC , sc , kI, kSync , "System Call" ),
INSTRUCTION(0x7c000036, "sldx" , kX , S_A_B_Rc , kI, kGeneral, "Shift Left Doubleword" ),
INSTRUCTION(0x7c000030, "slwx" , kX , S_A_B_Rc , kI, kGeneral, "Shift Left Word" ),
INSTRUCTION(0x7c000674, "sradix" , kXS , S_A_SH_Rc , kI, kGeneral, "Shift Right Algebraic Doubleword Immediate" ),
INSTRUCTION(0x7c000634, "sradx" , kX , S_A_B_Rc , kI, kGeneral, "Shift Right Algebraic Doubleword" ),
INSTRUCTION(0x7c000670, "srawix" , kX , S_A_SH_Rc , kI, kGeneral, "Shift Right Algebraic Word Immediate" ),
INSTRUCTION(0x7c000630, "srawx" , kX , S_A_B_Rc , kI, kGeneral, "Shift Right Algebraic Word" ),
INSTRUCTION(0x7c000436, "srdx" , kX , S_A_B_Rc , kI, kGeneral, "Shift Right Doubleword" ),
INSTRUCTION(0x7c000430, "srwx" , kX , S_A_B_Rc , kI, kGeneral, "Shift Right Word" ),
INSTRUCTION(0x98000000, "stb" , kD , S_A_d , kI, kGeneral, "Store Byte" ),
INSTRUCTION(0x9c000000, "stbu" , kD , S_A_d , kI, kGeneral, "Store Byte with Update" ),
INSTRUCTION(0x7c0001ee, "stbux" , kX , S_A_B , kI, kGeneral, "Store Byte with Update Indexed" ),
INSTRUCTION(0x7c0001ae, "stbx" , kX , S_A_B , kI, kGeneral, "Store Byte Indexed" ),
INSTRUCTION(0xf8000000, "std" , kDS , S_A_d , kI, kGeneral, "Store Doubleword" ),
INSTRUCTION(0x7c000528, "stdbrx" , kX , S_A_B , kI, kGeneral, "Store Doubleword Byte-Reverse Indexed" ),
INSTRUCTION(0x7c0001ad, "stdcx" , kX , S_A_B_1 , kI, kGeneral, "Store Doubleword Conditional Indexed" ),
INSTRUCTION(0xf8000001, "stdu" , kDS , S_A_d , kI, kGeneral, "Store Doubleword with Update" ),
INSTRUCTION(0x7c00016a, "stdux" , kX , S_A_B , kI, kGeneral, "Store Doubleword with Update Indexed" ),
INSTRUCTION(0x7c00012a, "stdx" , kX , S_A_B , kI, kGeneral, "Store Doubleword Indexed" ),
INSTRUCTION(0xd8000000, "stfd" , kD , S_A_d , kF, kGeneral, "Store Floating-Point Double" ),
INSTRUCTION(0xdc000000, "stfdu" , kD , S_A_d , kF, kGeneral, "Store Floating-Point Double with Update" ),
INSTRUCTION(0x7c0005ee, "stfdux" , kX , S_A_B , kF, kGeneral, "Store Floating-Point Double with Update Indexed" ),
INSTRUCTION(0x7c0005ae, "stfdx" , kX , S_A_B , kF, kGeneral, "Store Floating-Point Double Indexed" ),
INSTRUCTION(0x7c0007ae, "stfiwx" , kX , S_A_B , kF, kGeneral, "Store Floating-Point as Integer Word Indexed" ),
INSTRUCTION(0xd0000000, "stfs" , kD , S_A_d , kF, kGeneral, "Store Floating-Point Single" ),
INSTRUCTION(0xd4000000, "stfsu" , kD , S_A_d , kF, kGeneral, "Store Floating-Point Single with Update" ),
INSTRUCTION(0x7c00056e, "stfsux" , kX , S_A_B , kF, kGeneral, "Store Floating-Point Single with Update Indexed" ),
INSTRUCTION(0x7c00052e, "stfsx" , kX , S_A_B , kF, kGeneral, "Store Floating-Point Single Indexed" ),
INSTRUCTION(0xb0000000, "sth" , kD , S_A_d , kI, kGeneral, "Store Half Word" ),
INSTRUCTION(0x7c00072c, "sthbrx" , kX , S_A_B , kI, kGeneral, "Store Half Word Byte-Reverse Indexed" ),
INSTRUCTION(0xb4000000, "sthu" , kD , S_A_d , kI, kGeneral, "Store Half Word with Update" ),
INSTRUCTION(0x7c00036e, "sthux" , kX , S_A_B , kI, kGeneral, "Store Half Word with Update Indexed" ),
INSTRUCTION(0x7c00032e, "sthx" , kX , S_A_B , kI, kGeneral, "Store Half Word Indexed" ),
INSTRUCTION(0xbc000000, "stmw" , kD , S_A_d , kI, kGeneral, "Store Multiple Word" ),
INSTRUCTION(0x7c0005aa, "stswi" , kX , S_A_NB , kI, kGeneral, "Store String Word Immediate" ),
INSTRUCTION(0x7c00052a, "stswx" , kX , S_A_B , kI, kGeneral, "Store String Word Indexed" ),
INSTRUCTION(0x7c00010e, "stvebx" , kX , S_A_B , kV, kGeneral, "Store Vector Element Byte Indexed" ),
INSTRUCTION(0x7c00014e, "stvehx" , kX , S_A_B , kV, kGeneral, "Store Vector Element Half Word Indexed" ),
INSTRUCTION(0x7c00018e, "stvewx" , kX , S_A_B , kV, kGeneral, "Store Vector Element Word Indexed" ),
INSTRUCTION(0x10000183, "stvewx128" , kVX128_1, S_A_B , kV, kGeneral, "Store Vector Element Word Indexed 128" ),
INSTRUCTION(0x7c00050e, "stvlx" , kX , S_A_B , kV, kGeneral, "Store Vector Left Indexed" ),
INSTRUCTION(0x10000503, "stvlx128" , kVX128_1, S_A_B , kV, kGeneral, "Store Vector Left Indexed 128" ),
INSTRUCTION(0x7c00070e, "stvlxl" , kX , S_A_B , kV, kGeneral, "Store Vector Left Indexed LRU" ),
INSTRUCTION(0x10000703, "stvlxl128" , kVX128_1, S_A_B , kV, kGeneral, "Store Vector Left Indexed LRU 128" ),
INSTRUCTION(0x7c00054e, "stvrx" , kX , S_A_B , kV, kGeneral, "Store Vector Right Indexed" ),
INSTRUCTION(0x10000543, "stvrx128" , kVX128_1, S_A_B , kV, kGeneral, "Store Vector Right Indexed 128" ),
INSTRUCTION(0x7c00074e, "stvrxl" , kX , S_A_B , kV, kGeneral, "Store Vector Right Indexed LRU" ),
INSTRUCTION(0x10000743, "stvrxl128" , kVX128_1, S_A_B , kV, kGeneral, "Store Vector Right Indexed LRU 128" ),
INSTRUCTION(0x7c0001ce, "stvx" , kX , S_A_B , kV, kGeneral, "Store Vector Indexed" ),
INSTRUCTION(0x100001c3, "stvx128" , kVX128_1, S_A_B , kV, kGeneral, "Store Vector Indexed 128" ),
INSTRUCTION(0x7c0003ce, "stvxl" , kX , S_A_B , kV, kGeneral, "Store Vector Indexed LRU" ),
INSTRUCTION(0x100003c3, "stvxl128" , kVX128_1, S_A_B , kV, kGeneral, "Store Vector Indexed LRU 128" ),
INSTRUCTION(0x90000000, "stw" , kD , S_A_d , kI, kGeneral, "Store Word" ),
INSTRUCTION(0x7c00052c, "stwbrx" , kX , S_A_B , kI, kGeneral, "Store Word Byte-Reverse Indexed" ),
INSTRUCTION(0x7c00012d, "stwcx" , kX , S_A_B_1 , kI, kGeneral, "Store Word Conditional Indexed" ),
INSTRUCTION(0x94000000, "stwu" , kD , S_A_d , kI, kGeneral, "Store Word with Update" ),
INSTRUCTION(0x7c00016e, "stwux" , kX , S_A_B , kI, kGeneral, "Store Word with Update Indexed" ),
INSTRUCTION(0x7c00012e, "stwx" , kX , S_A_B , kI, kGeneral, "Store Word Indexed" ),
INSTRUCTION(0x7c000010, "subfcx" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Subtract From Carrying" ),
INSTRUCTION(0x7c000110, "subfex" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Subtract From Extended" ),
INSTRUCTION(0x20000000, "subficx" , kD , D_A_SIMM , kI, kGeneral, "Subtract From Immediate Carrying" ),
INSTRUCTION(0x7c0001d0, "subfmex" , kXO , D_A_0_OE_Rc , kI, kGeneral, "Subtract From Minus One Extended" ),
INSTRUCTION(0x7c000050, "subfx" , kXO , D_A_B_OE_Rc , kI, kGeneral, "Subtract From" ),
INSTRUCTION(0x7c000190, "subfzex" , kXO , D_A_0_OE_Rc , kI, kGeneral, "Subtract From Zero Extended" ),
INSTRUCTION(0x7c0004ac, "sync" , kX , _0_0_0 , kI, kGeneral, "Synchronize" ),
INSTRUCTION(0x7c000088, "td" , kX , TO_A_B , kI, kGeneral, "Trap Doubleword" ),
INSTRUCTION(0x08000000, "tdi" , kD , TO_A_SIMM , kI, kGeneral, "Trap Doubleword Immediate" ),
INSTRUCTION(0x7c000008, "tw" , kX , TO_A_B , kI, kGeneral, "Trap Word" ),
INSTRUCTION(0x0c000000, "twi" , kD , TO_A_SIMM , kI, kGeneral, "Trap Word Immediate" ),
INSTRUCTION(0x10000180, "vaddcuw" , kVX , D_A_B , kV, kGeneral, "Vector Add Carryout Unsigned Word" ),
INSTRUCTION(0x1000000a, "vaddfp" , kVX , D_A_B , kV, kGeneral, "Vector Add Floating Point" ),
INSTRUCTION(0x14000010, "vaddfp128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Add Floating Point" ),
INSTRUCTION(0x10000300, "vaddsbs" , kVX , D_A_B , kV, kGeneral, "Vector Add Signed Byte Saturate" ),
INSTRUCTION(0x10000340, "vaddshs" , kVX , D_A_B , kV, kGeneral, "Vector Add Signed Half Word Saturate" ),
INSTRUCTION(0x10000380, "vaddsws" , kVX , D_A_B , kV, kGeneral, "Vector Add Signed Word Saturate" ),
INSTRUCTION(0x10000000, "vaddubm" , kVX , D_A_B , kV, kGeneral, "Vector Add Unsigned Byte Modulo" ),
INSTRUCTION(0x10000200, "vaddubs" , kVX , D_A_B , kV, kGeneral, "Vector Add Unsigned Byte Saturate" ),
INSTRUCTION(0x10000040, "vadduhm" , kVX , D_A_B , kV, kGeneral, "Vector Add Unsigned Half Word Modulo" ),
INSTRUCTION(0x10000240, "vadduhs" , kVX , D_A_B , kV, kGeneral, "Vector Add Unsigned Half Word Saturate" ),
INSTRUCTION(0x10000080, "vadduwm" , kVX , D_A_B , kV, kGeneral, "Vector Add Unsigned Word Modulo" ),
INSTRUCTION(0x10000280, "vadduws" , kVX , D_A_B , kV, kGeneral, "Vector Add Unsigned Word Saturate" ),
INSTRUCTION(0x10000404, "vand" , kVX , D_A_B , kV, kGeneral, "Vector Logical AND" ),
INSTRUCTION(0x14000210, "vand128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Logical AND" ),
INSTRUCTION(0x10000444, "vandc" , kVX , D_A_B , kV, kGeneral, "Vector Logical AND with Complement" ),
INSTRUCTION(0x14000250, "vandc128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Logical AND with Complement" ),
INSTRUCTION(0x10000502, "vavgsb" , kVX , D_A_B , kV, kGeneral, "Vector Average Signed Byte" ),
INSTRUCTION(0x10000542, "vavgsh" , kVX , D_A_B , kV, kGeneral, "Vector Average Signed Half Word" ),
INSTRUCTION(0x10000582, "vavgsw" , kVX , D_A_B , kV, kGeneral, "Vector Average Signed Word" ),
INSTRUCTION(0x10000402, "vavgub" , kVX , D_A_B , kV, kGeneral, "Vector Average Unsigned Byte" ),
INSTRUCTION(0x10000442, "vavguh" , kVX , D_A_B , kV, kGeneral, "Vector Average Unsigned Half Word" ),
INSTRUCTION(0x10000482, "vavguw" , kVX , D_A_B , kV, kGeneral, "Vector Average Unsigned Word" ),
INSTRUCTION(0x18000230, "vcfpsxws128" , kVX128_3, D_B_SIMM , kV, kGeneral, "Vector128 Convert From Floating-Point to Signed Fixed-Point Word Saturate" ),
INSTRUCTION(0x18000270, "vcfpuxws128" , kVX128_3, D_B_UIMM , kV, kGeneral, "Vector128 Convert From Floating-Point to Unsigned Fixed-Point Word Saturate"),
INSTRUCTION(0x1000034a, "vcfsx" , kVX , D_A_B , kV, kGeneral, "Vector Convert from Signed Fixed-Point Word" ),
INSTRUCTION(0x1000030a, "vcfux" , kVX , D_A_B , kV, kGeneral, "Vector Convert from Unsigned Fixed-Point Word" ),
INSTRUCTION(0x100003c6, "vcmpbfp" , kVC , D_A_B , kV, kGeneral, "Vector Compare Bounds Floating Point" ),
INSTRUCTION(0x18000180, "vcmpbfp128" , kVX128_R, D_A_B , kV, kGeneral, "Vector128 Compare Bounds Floating Point" ),
INSTRUCTION(0x100000c6, "vcmpeqfp" , kVC , D_A_B , kV, kGeneral, "Vector Compare Equal-to Floating Point" ),
INSTRUCTION(0x18000000, "vcmpeqfp128" , kVX128_R, D_A_B , kV, kGeneral, "Vector128 Compare Equal-to Floating Point" ),
INSTRUCTION(0x10000006, "vcmpequb" , kVC , D_A_B , kV, kGeneral, "Vector Compare Equal-to Unsigned Byte" ),
INSTRUCTION(0x10000046, "vcmpequh" , kVC , D_A_B , kV, kGeneral, "Vector Compare Equal-to Unsigned Half Word" ),
INSTRUCTION(0x10000086, "vcmpequw" , kVC , D_A_B , kV, kGeneral, "Vector Compare Equal-to Unsigned Word" ),
INSTRUCTION(0x18000200, "vcmpequw128" , kVX128_R, D_A_B , kV, kGeneral, "Vector128 Compare Equal-to Unsigned Word" ),
INSTRUCTION(0x100001c6, "vcmpgefp" , kVC , D_A_B , kV, kGeneral, "Vector Compare Greater-Than-or-Equal-to Floating Point" ),
INSTRUCTION(0x18000080, "vcmpgefp128" , kVX128_R, D_A_B , kV, kGeneral, "Vector128 Compare Greater-Than-or-Equal-to Floating Point" ),
INSTRUCTION(0x100002c6, "vcmpgtfp" , kVC , D_A_B , kV, kGeneral, "Vector Compare Greater-Than Floating Point" ),
INSTRUCTION(0x18000100, "vcmpgtfp128" , kVX128_R, D_A_B , kV, kGeneral, "Vector128 Compare Greater-Than Floating-Point" ),
INSTRUCTION(0x10000306, "vcmpgtsb" , kVC , D_A_B , kV, kGeneral, "Vector Compare Greater-Than Signed Byte" ),
INSTRUCTION(0x10000346, "vcmpgtsh" , kVC , D_A_B , kV, kGeneral, "Vector Compare Greater-Than Signed Half Word" ),
INSTRUCTION(0x10000386, "vcmpgtsw" , kVC , D_A_B , kV, kGeneral, "Vector Compare Greater-Than Signed Word" ),
INSTRUCTION(0x10000206, "vcmpgtub" , kVC , D_A_B , kV, kGeneral, "Vector Compare Greater-Than Unsigned Byte" ),
INSTRUCTION(0x10000246, "vcmpgtuh" , kVC , D_A_B , kV, kGeneral, "Vector Compare Greater-Than Unsigned Half Word" ),
INSTRUCTION(0x10000286, "vcmpgtuw" , kVC , D_A_B , kV, kGeneral, "Vector Compare Greater-Than Unsigned Word" ),
INSTRUCTION(0x180002b0, "vcsxwfp128" , kVX128_3, D_B_SIMM , kV, kGeneral, "Vector128 Convert From Signed Fixed-Point Word to Floating-Point" ),
INSTRUCTION(0x100003ca, "vctsxs" , kVX , D_A_B , kV, kGeneral, "Vector Convert to Signed Fixed-Point Word Saturate" ),
INSTRUCTION(0x1000038a, "vctuxs" , kVX , D_A_B , kV, kGeneral, "Vector Convert to Unsigned Fixed-Point Word Saturate" ),
INSTRUCTION(0x180002f0, "vcuxwfp128" , kVX128_3, D_B_SIMM , kV, kGeneral, "Vector128 Convert From Unsigned Fixed-Point Word to Floating-Point" ),
INSTRUCTION(0x1000018a, "vexptefp" , kVX , D_A_B , kV, kGeneral, "Vector 2 Raised to the Exponent Estimate Floating Point" ),
INSTRUCTION(0x180006b0, "vexptefp128" , kVX128_3, D_B , kV, kGeneral, "Vector128 Log2 Estimate Floating Point" ),
INSTRUCTION(0x100001ca, "vlogefp" , kVX , D_A_B , kV, kGeneral, "Vector Log2 Estimate Floating Point" ),
INSTRUCTION(0x180006f0, "vlogefp128" , kVX128_3, D_B , kV, kGeneral, "Vector128 Log2 Estimate Floating Point" ),
INSTRUCTION(0x14000110, "vmaddcfp128" , kVX128 , D_A_D_B , kV, kGeneral, "Vector128 Multiply Add Floating Point" ),
INSTRUCTION(0x1000002e, "vmaddfp" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-Add Floating Point" ),
INSTRUCTION(0x140000d0, "vmaddfp128" , kVX128 , D_A_D_B , kV, kGeneral, "Vector128 Multiply Add Floating Point" ),
INSTRUCTION(0x1000040a, "vmaxfp" , kVX , D_A_B , kV, kGeneral, "Vector Maximum Floating Point" ),
INSTRUCTION(0x18000280, "vmaxfp128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Maximum Floating Point" ),
INSTRUCTION(0x10000102, "vmaxsb" , kVX , D_A_B , kV, kGeneral, "Vector Maximum Signed Byte" ),
INSTRUCTION(0x10000142, "vmaxsh" , kVX , D_A_B , kV, kGeneral, "Vector Maximum Signed Half Word" ),
INSTRUCTION(0x10000182, "vmaxsw" , kVX , D_A_B , kV, kGeneral, "Vector Maximum Signed Word" ),
INSTRUCTION(0x10000002, "vmaxub" , kVX , D_A_B , kV, kGeneral, "Vector Maximum Unsigned Byte" ),
INSTRUCTION(0x10000042, "vmaxuh" , kVX , D_A_B , kV, kGeneral, "Vector Maximum Unsigned Half Word" ),
INSTRUCTION(0x10000082, "vmaxuw" , kVX , D_A_B , kV, kGeneral, "Vector Maximum Unsigned Word" ),
INSTRUCTION(0x10000020, "vmhaddshs" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-High and Add Signed Signed Half Word Saturate" ),
INSTRUCTION(0x10000021, "vmhraddshs" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-High Round and Add Signed Signed Half Word Saturate" ),
INSTRUCTION(0x1000044a, "vminfp" , kVX , D_A_B , kV, kGeneral, "Vector Minimum Floating Point" ),
INSTRUCTION(0x180002c0, "vminfp128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Minimum Floating Point" ),
INSTRUCTION(0x10000302, "vminsb" , kVX , D_A_B , kV, kGeneral, "Vector Minimum Signed Byte" ),
INSTRUCTION(0x10000342, "vminsh" , kVX , D_A_B , kV, kGeneral, "Vector Minimum Signed Half Word" ),
INSTRUCTION(0x10000382, "vminsw" , kVX , D_A_B , kV, kGeneral, "Vector Minimum Signed Word" ),
INSTRUCTION(0x10000202, "vminub" , kVX , D_A_B , kV, kGeneral, "Vector Minimum Unsigned Byte" ),
INSTRUCTION(0x10000242, "vminuh" , kVX , D_A_B , kV, kGeneral, "Vector Minimum Unsigned Half Word" ),
INSTRUCTION(0x10000282, "vminuw" , kVX , D_A_B , kV, kGeneral, "Vector Minimum Unsigned Word" ),
INSTRUCTION(0x10000022, "vmladduhm" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-Low and Add Unsigned Half Word Modulo" ),
INSTRUCTION(0x1000000c, "vmrghb" , kVX , D_A_B , kV, kGeneral, "Vector Merge High Byte" ),
INSTRUCTION(0x1000004c, "vmrghh" , kVX , D_A_B , kV, kGeneral, "Vector Merge High Half Word" ),
INSTRUCTION(0x1000008c, "vmrghw" , kVX , D_A_B , kV, kGeneral, "Vector Merge High Word" ),
INSTRUCTION(0x18000300, "vmrghw128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Merge High Word" ),
INSTRUCTION(0x1000010c, "vmrglb" , kVX , D_A_B , kV, kGeneral, "Vector Merge Low Byte" ),
INSTRUCTION(0x1000014c, "vmrglh" , kVX , D_A_B , kV, kGeneral, "Vector Merge Low Half Word" ),
INSTRUCTION(0x1000018c, "vmrglw" , kVX , D_A_B , kV, kGeneral, "Vector Merge Low Word" ),
INSTRUCTION(0x18000340, "vmrglw128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Merge Low Word" ),
INSTRUCTION(0x14000190, "vmsum3fp128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Multiply Sum 3-way Floating Point" ),
INSTRUCTION(0x140001d0, "vmsum4fp128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Multiply Sum 4-way Floating-Point" ),
INSTRUCTION(0x10000025, "vmsummbm" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-Sum Mixed-Sign Byte Modulo" ),
INSTRUCTION(0x10000028, "vmsumshm" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-Sum Signed Half Word Modulo" ),
INSTRUCTION(0x10000029, "vmsumshs" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-Sum Signed Half Word Saturate" ),
INSTRUCTION(0x10000024, "vmsumubm" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-Sum Unsigned Byte Modulo" ),
INSTRUCTION(0x10000026, "vmsumuhm" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-Sum Unsigned Half Word Modulo" ),
INSTRUCTION(0x10000027, "vmsumuhs" , kVA , D_A_B_C , kV, kGeneral, "Vector Multiply-Sum Unsigned Half Word Saturate" ),
INSTRUCTION(0x10000308, "vmulesb" , kVX , D_A_B , kV, kGeneral, "Vector Multiply Even Signed Byte" ),
INSTRUCTION(0x10000348, "vmulesh" , kVX , D_A_B , kV, kGeneral, "Vector Multiply Even Signed Half Word" ),
INSTRUCTION(0x10000208, "vmuleub" , kVX , D_A_B , kV, kGeneral, "Vector Multiply Even Unsigned Byte" ),
INSTRUCTION(0x10000248, "vmuleuh" , kVX , D_A_B , kV, kGeneral, "Vector Multiply Even Unsigned Half Word" ),
INSTRUCTION(0x14000090, "vmulfp128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Multiply Floating-Point" ),
INSTRUCTION(0x10000108, "vmulosb" , kVX , D_A_B , kV, kGeneral, "Vector Multiply Odd Signed Byte" ),
INSTRUCTION(0x10000148, "vmulosh" , kVX , D_A_B , kV, kGeneral, "Vector Multiply Odd Signed Half Word" ),
INSTRUCTION(0x10000008, "vmuloub" , kVX , D_A_B , kV, kGeneral, "Vector Multiply Odd Unsigned Byte" ),
INSTRUCTION(0x10000048, "vmulouh" , kVX , D_A_B , kV, kGeneral, "Vector Multiply Odd Unsigned Half Word" ),
INSTRUCTION(0x1000002f, "vnmsubfp" , kVA , D_A_B_C , kV, kGeneral, "Vector Negative Multiply-Subtract Floating Point" ),
INSTRUCTION(0x14000150, "vnmsubfp128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Negative Multiply-Subtract Floating Point" ),
INSTRUCTION(0x10000504, "vnor" , kVX , D_A_B , kV, kGeneral, "Vector Logical NOR" ),
INSTRUCTION(0x14000290, "vnor128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Logical NOR" ),
INSTRUCTION(0x10000484, "vor" , kVX , D_A_B , kV, kGeneral, "Vector Logical OR" ),
INSTRUCTION(0x140002d0, "vor128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Logical OR" ),
INSTRUCTION(0x1000002b, "vperm" , kVA , D_A_B_C , kV, kGeneral, "Vector Permute" ),
INSTRUCTION(0x14000000, "vperm128" , kVX128_2, D_A_B_C , kV, kGeneral, "Vector128 Permute" ),
INSTRUCTION(0x18000210, "vpermwi128" , kVX128_P, D_A_B_C , kV, kGeneral, "Vector128 Permutate Word Immediate" ),
INSTRUCTION(0x18000610, "vpkd3d128" , kVX128_4, D_B , kV, kGeneral, "Vector128 Pack D3Dtype, Rotate Left Immediate and Mask Insert" ),
INSTRUCTION(0x1000030e, "vpkpx" , kVX , D_A_B , kV, kGeneral, "Vector Pack Pixel" ),
INSTRUCTION(0x1000018e, "vpkshss" , kVX , D_A_B , kV, kGeneral, "Vector Pack Signed Half Word Signed Saturate" ),
INSTRUCTION(0x14000200, "vpkshss128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Pack Signed Half Word Signed Saturate" ),
INSTRUCTION(0x1000010e, "vpkshus" , kVX , D_A_B , kV, kGeneral, "Vector Pack Signed Half Word Unsigned Saturate" ),
INSTRUCTION(0x14000240, "vpkshus128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Pack Signed Half Word Unsigned Saturate" ),
INSTRUCTION(0x100001ce, "vpkswss" , kVX , D_A_B , kV, kGeneral, "Vector Pack Signed Word Signed Saturate" ),
INSTRUCTION(0x14000280, "vpkswss128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Pack Signed Word Signed Saturate" ),
INSTRUCTION(0x1000014e, "vpkswus" , kVX , D_A_B , kV, kGeneral, "Vector Pack Signed Word Unsigned Saturate" ),
INSTRUCTION(0x140002c0, "vpkswus128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Pack Signed Word Unsigned Saturate" ),
INSTRUCTION(0x1000000e, "vpkuhum" , kVX , D_A_B , kV, kGeneral, "Vector Pack Unsigned Half Word Unsigned Modulo" ),
INSTRUCTION(0x14000300, "vpkuhum128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Pack Unsigned Half Word Unsigned Modulo" ),
INSTRUCTION(0x1000008e, "vpkuhus" , kVX , D_A_B , kV, kGeneral, "Vector Pack Unsigned Half Word Unsigned Saturate" ),
INSTRUCTION(0x14000340, "vpkuhus128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Pack Unsigned Half Word Unsigned Saturate" ),
INSTRUCTION(0x1000004e, "vpkuwum" , kVX , D_A_B , kV, kGeneral, "Vector Pack Unsigned Word Unsigned Modulo" ),
INSTRUCTION(0x14000380, "vpkuwum128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Pack Unsigned Word Unsigned Modulo" ),
INSTRUCTION(0x100000ce, "vpkuwus" , kVX , D_A_B , kV, kGeneral, "Vector Pack Unsigned Word Unsigned Saturate" ),
INSTRUCTION(0x140003c0, "vpkuwus128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Pack Unsigned Word Unsigned Saturate" ),
INSTRUCTION(0x1000010a, "vrefp" , kVX , D_A_B , kV, kGeneral, "Vector Reciprocal Estimate Floating Point" ),
INSTRUCTION(0x18000630, "vrefp128" , kVX128_3, D_B , kV, kGeneral, "Vector128 Reciprocal Estimate Floating Point" ),
INSTRUCTION(0x100002ca, "vrfim" , kVX , D_A_B , kV, kGeneral, "Vector Round to Floating-Point Integer toward -Infinity" ),
INSTRUCTION(0x18000330, "vrfim128" , kVX128_3, D_B , kV, kGeneral, "Vector128 Round to Floating-Point Integer toward -Infinity" ),
INSTRUCTION(0x1000020a, "vrfin" , kVX , D_A_B , kV, kGeneral, "Vector Round to Floating-Point Integer Nearest" ),
INSTRUCTION(0x18000370, "vrfin128" , kVX128_3, D_B , kV, kGeneral, "Vector128 Round to Floating-Point Integer Nearest" ),
INSTRUCTION(0x1000028a, "vrfip" , kVX , D_A_B , kV, kGeneral, "Vector Round to Floating-Point Integer toward +Infinity" ),
INSTRUCTION(0x180003b0, "vrfip128" , kVX128_3, D_B , kV, kGeneral, "Vector128 Round to Floating-Point Integer toward +Infinity" ),
INSTRUCTION(0x1000024a, "vrfiz" , kVX , D_A_B , kV, kGeneral, "Vector Round to Floating-Point Integer toward Zero" ),
INSTRUCTION(0x180003f0, "vrfiz128" , kVX128_3, D_B , kV, kGeneral, "Vector128 Round to Floating-Point Integer toward Zero" ),
INSTRUCTION(0x10000004, "vrlb" , kVX , D_A_B , kV, kGeneral, "Vector Rotate Left Integer Byte" ),
INSTRUCTION(0x10000044, "vrlh" , kVX , D_A_B , kV, kGeneral, "Vector Rotate Left Integer Half Word" ),
INSTRUCTION(0x18000710, "vrlimi128" , kVX128_4, D_B_UIMM , kV, kGeneral, "Vector128 Rotate Left Immediate and Mask Insert" ),
INSTRUCTION(0x10000084, "vrlw" , kVX , D_A_B , kV, kGeneral, "Vector Rotate Left Integer Word" ),
INSTRUCTION(0x18000050, "vrlw128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Rotate Left Word" ),
INSTRUCTION(0x1000014a, "vrsqrtefp" , kVX , D_A_B , kV, kGeneral, "Vector Reciprocal Square Root Estimate Floating Point" ),
INSTRUCTION(0x18000670, "vrsqrtefp128", kVX128_3, D_B , kV, kGeneral, "Vector128 Reciprocal Square Root Estimate Floating Point" ),
INSTRUCTION(0x1000002a, "vsel" , kVA , D_A_B_C , kV, kGeneral, "Vector Conditional Select" ),
INSTRUCTION(0x14000350, "vsel128" , kVX128 , D_A_B_D , kV, kGeneral, "Vector128 Conditional Select" ),
INSTRUCTION(0x100001c4, "vsl" , kVX , D_A_B , kV, kGeneral, "Vector Shift Left" ),
INSTRUCTION(0x10000104, "vslb" , kVX , D_A_B , kV, kGeneral, "Vector Shift Left Integer Byte" ),
INSTRUCTION(0x1000002c, "vsldoi" , kVA , D_A_B_C , kV, kGeneral, "Vector Shift Left Double by Octet Immediate" ),
INSTRUCTION(0x10000010, "vsldoi128" , kVX128_5, D_A_B_I , kV, kGeneral, "Vector128 Shift Left Double by Octet Immediate" ),
INSTRUCTION(0x10000144, "vslh" , kVX , D_A_B , kV, kGeneral, "Vector Shift Left Integer Half Word" ),
INSTRUCTION(0x1000040c, "vslo" , kVX , D_A_B , kV, kGeneral, "Vector Shift Left by Octet" ),
INSTRUCTION(0x14000390, "vslo128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Shift Left Octet" ),
INSTRUCTION(0x10000184, "vslw" , kVX , D_A_B , kV, kGeneral, "Vector Shift Left Integer Word" ),
INSTRUCTION(0x180000d0, "vslw128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Shift Left Integer Word" ),
INSTRUCTION(0x1000020c, "vspltb" , kVX , D_A_B , kV, kGeneral, "Vector Splat Byte" ),
INSTRUCTION(0x1000024c, "vsplth" , kVX , D_A_B , kV, kGeneral, "Vector Splat Half Word" ),
INSTRUCTION(0x1000030c, "vspltisb" , kVX , D_A_B , kV, kGeneral, "Vector Splat Immediate Signed Byte" ),
INSTRUCTION(0x1000034c, "vspltish" , kVX , D_A_B , kV, kGeneral, "Vector Splat Immediate Signed Half Word" ),
INSTRUCTION(0x1000038c, "vspltisw" , kVX , D_A_B , kV, kGeneral, "Vector Splat Immediate Signed Word" ),
INSTRUCTION(0x18000770, "vspltisw128" , kVX128_3, D_B_SIMM , kV, kGeneral, "Vector128 Splat Immediate Signed Word" ),
INSTRUCTION(0x1000028c, "vspltw" , kVX , D_A_B , kV, kGeneral, "Vector Splat Word" ),
INSTRUCTION(0x18000730, "vspltw128" , kVX128_3, D_B_SIMM , kV, kGeneral, "Vector128 Splat Word" ),
INSTRUCTION(0x100002c4, "vsr" , kVX , D_A_B , kV, kGeneral, "Vector Shift Right" ),
INSTRUCTION(0x10000304, "vsrab" , kVX , D_A_B , kV, kGeneral, "Vector Shift Right Algebraic Byte" ),
INSTRUCTION(0x10000344, "vsrah" , kVX , D_A_B , kV, kGeneral, "Vector Shift Right Algebraic Half Word" ),
INSTRUCTION(0x10000384, "vsraw" , kVX , D_A_B , kV, kGeneral, "Vector Shift Right Algebraic Word" ),
INSTRUCTION(0x18000150, "vsraw128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Shift Right Arithmetic Word" ),
INSTRUCTION(0x10000204, "vsrb" , kVX , D_A_B , kV, kGeneral, "Vector Shift Right Byte" ),
INSTRUCTION(0x10000244, "vsrh" , kVX , D_A_B , kV, kGeneral, "Vector Shift Right Half Word" ),
INSTRUCTION(0x1000044c, "vsro" , kVX , D_A_B , kV, kGeneral, "Vector Shift Right Octet" ),
INSTRUCTION(0x140003d0, "vsro128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Shift Right Octet" ),
INSTRUCTION(0x10000284, "vsrw" , kVX , D_A_B , kV, kGeneral, "Vector Shift Right Word" ),
INSTRUCTION(0x180001d0, "vsrw128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Shift Right Word" ),
INSTRUCTION(0x10000580, "vsubcuw" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Carryout Unsigned Word" ),
INSTRUCTION(0x1000004a, "vsubfp" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Floating Point" ),
INSTRUCTION(0x14000050, "vsubfp128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Subtract Floating Point" ),
INSTRUCTION(0x10000700, "vsubsbs" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Signed Byte Saturate" ),
INSTRUCTION(0x10000740, "vsubshs" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Signed Half Word Saturate" ),
INSTRUCTION(0x10000780, "vsubsws" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Signed Word Saturate" ),
INSTRUCTION(0x10000400, "vsububm" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Unsigned Byte Modulo" ),
INSTRUCTION(0x10000600, "vsububs" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Unsigned Byte Saturate" ),
INSTRUCTION(0x10000440, "vsubuhm" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Unsigned Half Word Modulo" ),
INSTRUCTION(0x10000640, "vsubuhs" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Unsigned Half Word Saturate" ),
INSTRUCTION(0x10000480, "vsubuwm" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Unsigned Word Modulo" ),
INSTRUCTION(0x10000680, "vsubuws" , kVX , D_A_B , kV, kGeneral, "Vector Subtract Unsigned Word Saturate" ),
INSTRUCTION(0x10000688, "vsum2sws" , kVX , D_A_B , kV, kGeneral, "Vector Sum Across Partial (1/2) Signed Word Saturate" ),
INSTRUCTION(0x10000708, "vsum4sbs" , kVX , D_A_B , kV, kGeneral, "Vector Sum Across Partial (1/4) Signed Byte Saturate" ),
INSTRUCTION(0x10000648, "vsum4shs" , kVX , D_A_B , kV, kGeneral, "Vector Sum Across Partial (1/4) Signed Half Word Saturate" ),
INSTRUCTION(0x10000608, "vsum4ubs" , kVX , D_A_B , kV, kGeneral, "Vector Sum Across Partial (1/4) Unsigned Byte Saturate" ),
INSTRUCTION(0x10000788, "vsumsws" , kVX , D_A_B , kV, kGeneral, "Vector Sum Across Signed Word Saturate" ),
INSTRUCTION(0x180007f0, "vupkd3d128" , kVX128_3, D_B_SIMM , kV, kGeneral, "Vector128 Unpack D3Dtype" ),
INSTRUCTION(0x1000034e, "vupkhpx" , kVX , D_A_B , kV, kGeneral, "Vector Unpack High Pixel" ),
INSTRUCTION(0x1000020e, "vupkhsb" , kVX , D_A_B , kV, kGeneral, "Vector Unpack High Signed Byte" ),
INSTRUCTION(0x18000380, "vupkhsb128" , kVX128 , D_B , kV, kGeneral, "Vector128 Unpack High Signed Byte" ),
INSTRUCTION(0x1000024e, "vupkhsh" , kVX , D_A_B , kV, kGeneral, "Vector Unpack High Signed Half Word" ),
INSTRUCTION(0x100003ce, "vupklpx" , kVX , D_A_B , kV, kGeneral, "Vector Unpack Low Pixel" ),
INSTRUCTION(0x1000028e, "vupklsb" , kVX , D_A_B , kV, kGeneral, "Vector Unpack Low Signed Byte" ),
INSTRUCTION(0x180003c0, "vupklsb128" , kVX128 , D_B , kV, kGeneral, "Vector128 Unpack Low Signed Byte" ),
INSTRUCTION(0x100002ce, "vupklsh" , kVX , D_A_B , kV, kGeneral, "Vector Unpack Low Signed Half Word" ),
INSTRUCTION(0x100004c4, "vxor" , kVX , D_A_B , kV, kGeneral, "Vector Logical XOR" ),
INSTRUCTION(0x14000310, "vxor128" , kVX128 , D_A_B , kV, kGeneral, "Vector128 Logical XOR" ),
INSTRUCTION(0x68000000, "xori" , kD , S_A_UIMM , kI, kGeneral, "XOR Immediate" ),
INSTRUCTION(0x6c000000, "xoris" , kD , S_A_UIMM , kI, kGeneral, "XOR Immediate Shifted" ),
INSTRUCTION(0x7c000278, "xorx" , kX , S_A_B_Rc , kI, kGeneral, "XOR" ),
};
static_assert(sizeof(ppc_opcode_table) / sizeof(PPCOpcodeInfo) == static_cast<int>(PPCOpcode::kInvalid), "PPC table mismatch - rerun ppc-table-gen");
const PPCOpcodeInfo& GetOpcodeInfo(PPCOpcode opcode) {
return ppc_opcode_table[static_cast<int>(opcode)];
}
void RegisterOpcodeDisasm(PPCOpcode opcode, InstrDisasmFn1 fn) {
assert_null(ppc_opcode_table[static_cast<int>(opcode)].disasm);
ppc_opcode_table[static_cast<int>(opcode)].disasm = fn;
}
void RegisterOpcodeEmitter(PPCOpcode opcode, InstrEmitFn fn) {
assert_null(ppc_opcode_table[static_cast<int>(opcode)].emit);
ppc_opcode_table[static_cast<int>(opcode)].emit = fn;
}
} // namespace ppc
} // namespace cpu

View File

@@ -21,7 +21,6 @@
#include "xenia/cpu/ppc/ppc_disasm.h"
#include "xenia/cpu/ppc/ppc_frontend.h"
#include "xenia/cpu/ppc/ppc_hir_builder.h"
#include "xenia/cpu/ppc/ppc_instr.h"
#include "xenia/cpu/ppc/ppc_scanner.h"
#include "xenia/cpu/processor.h"
#include "xenia/debug/debugger.h"
@@ -166,10 +165,6 @@ bool PPCTranslator::Translate(GuestFunction* function,
string_buffer_.Reset();
}
if (false) {
DumpAllInstrCounts();
}
// Emit function.
uint32_t emit_flags = 0;
// if (debug_info) {