Simplifying disassembler. Much faster than before.

This commit is contained in:
Ben Vanik 2014-01-23 20:31:04 -08:00
parent f36e6cd820
commit 53b9ed5214
17 changed files with 1053 additions and 4864 deletions

View File

@ -25,6 +25,7 @@ which are only documented in a few places (like the gcc source code, etc).
* [PowerPC Vector PEM](https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/C40E4C6133B31EE8872570B500791108/$file/vector_simd_pem_v_2.07c_26Oct2006_cell.pdf)
* [AltiVec PEM](http://cache.freescale.com/files/32bit/doc/ref_manual/ALTIVECPEM.pdf)
* [VMX128 Opcodes](http://biallas.net/doc/vmx128/vmx128.txt)
* [AltiVec Decoding](https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp)
### x64

View File

@ -1,36 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_DISASM_PRIVATE_H_
#define ALLOY_FRONTEND_PPC_PPC_DISASM_PRIVATE_H_
#include <alloy/frontend/ppc/ppc_disasm.h>
#include <alloy/frontend/ppc/ppc_instr.h>
namespace alloy {
namespace frontend {
namespace ppc {
#define XEDISASMR(name, opcode, format) int InstrDisasm_##name
#define XEREGISTERINSTR(name, opcode) \
RegisterInstrDisassemble(opcode, (InstrDisassembleFn)InstrDisasm_##name);
#define XEINSTRNOTIMPLEMENTED()
//#define XEINSTRNOTIMPLEMENTED XEASSERTALWAYS
} // namespace ppc
} // namespace frontend
} // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_DISASM_PRIVATE_H_

View File

@ -0,0 +1,533 @@
/*
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/frontend/ppc/ppc_disasm.h>
using namespace alloy::frontend::ppc;
namespace alloy {
namespace frontend {
namespace ppc {
void Disasm_0(InstrData& i, StringBuffer* str) {
str->Append("%-8s ???", i.type->name);
}
void Disasm__(InstrData& i, StringBuffer* str) {
str->Append("%-8s", i.type->name);
}
void Disasm_X_FRT_FRB(InstrData& i, StringBuffer* str) {
str->Append("%*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_A_FRT_FRB(InstrData& i, StringBuffer* str) {
str->Append("%*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_FRA_FRB(InstrData& i, StringBuffer* str) {
str->Append("%*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_FRC(InstrData& i, StringBuffer* str) {
str->Append("%*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_X_RT_RA_RB(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, r%d, %d", i.type->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->Append("%-8s r%d, r%d, %d", i.type->name,
i.X.RT, i.X.RA, i.X.RB);
} else {
str->Append("%-8s r%d, 0, %d", i.type->name,
i.X.RT, i.X.RB);
}
}
void Disasm_X_FRT_RA_RB(InstrData& i, StringBuffer* str) {
str->Append("%-8s f%d, r%d, %d", i.type->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->Append("%-8s f%d, r%d, %d", i.type->name,
i.X.RT, i.X.RA, i.X.RB);
} else {
str->Append("%-8s f%d, 0, %d", i.type->name,
i.X.RT, i.X.RB);
}
}
void Disasm_D_RT_RA_I(InstrData& i, StringBuffer* str) {
str->Append("%-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(InstrData& i, StringBuffer* str) {
if (i.D.RA) {
str->Append("%-8s r%d, r%d, %d", i.type->name,
i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS));
} else {
str->Append("%-8s r%d, 0, %d", i.type->name,
i.D.RT, (int32_t)(int16_t)XEEXTS16(i.D.DS));
}
}
void Disasm_D_FRT_RA_I(InstrData& i, StringBuffer* str) {
str->Append("%-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(InstrData& i, StringBuffer* str) {
if (i.D.RA) {
str->Append("%-8s f%d, r%d, %d", i.type->name,
i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS));
} else {
str->Append("%-8s f%d, 0, %d", i.type->name,
i.D.RT, (int32_t)(int16_t)XEEXTS16(i.D.DS));
}
}
void Disasm_DS_RT_RA_I(InstrData& i, StringBuffer* str) {
str->Append("%-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(InstrData& i, StringBuffer* str) {
if (i.DS.RA) {
str->Append("%-8s r%d, r%d, %d", i.type->name,
i.DS.RT, i.DS.RA, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
} else {
str->Append("%-8s r%d, 0, %d", i.type->name,
i.DS.RT, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
}
}
void Disasm_D_RA(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d", i.type->name,
i.D.RA);
}
void Disasm_X_RA_RB(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, r%d", i.type->name,
i.X.RA, i.X.RB);
}
void Disasm_XO_RT_RA_RB(InstrData& i, StringBuffer* str) {
str->Append("%*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, i.XO.RB);
}
void Disasm_XO_RT_RA(InstrData& i, StringBuffer* str) {
str->Append("%*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_X_RA_RT_RB(InstrData& i, StringBuffer* str) {
str->Append("%*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_D_RA_RT_I(InstrData& i, StringBuffer* str) {
str->Append("%-7s. r%d, r%d, %.4Xh", i.type->name,
i.D.RA, i.D.RT, i.D.DS);
}
void Disasm_X_RA_RT(InstrData& i, StringBuffer* str) {
str->Append("%*s%s r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "",
i.X.RA, i.X.RT);
}
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))
#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3))
#define VX128_2(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x210))
#define VX128_3(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f0))
#define VX128_4(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x730))
#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_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))
#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.VD128h << 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))
#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))
void Disasm_X_VX_RA0_RB(InstrData& i, StringBuffer* str) {
if (i.X.RA) {
str->Append("%-8s v%d, r%d, r%d", i.type->name,
i.X.RT, i.X.RA, i.X.RB);
} else {
str->Append("%-8s v%d, 0, r%d", i.type->name,
i.X.RT, i.X.RB);
}
}
void Disasm_VX1281_VD_RA0_RB(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_1_VD128;
if (i.VX128_1.RA) {
str->Append("%-8s v%d, r%d, r%d", i.type->name,
vd, i.VX128_1.RA, i.VX128_1.RB);
} else {
str->Append("%-8s v%d, 0, r%d", i.type->name,
vd, i.VX128_1.RB);
}
}
void Disasm_VX1283_VD_VB(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_3_VD128;
const uint32_t vb = VX128_3_VB128;
str->Append("%-8s v%d, v%d", i.type->name,
vd, vb);
}
void Disasm_VX1283_VD_VB_I(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->Append("%-8s v%d, v%d, %.2Xh", i.type->name,
vd, va, uimm);
}
void Disasm_VX_VD_VA_VB(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, v%d", i.type->name,
i.VX.VD, i.VX.VA, i.VX.VB);
}
void Disasm_VX128_VD_VA_VB(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_VD128;
const uint32_t va = VX128_VA128;
const uint32_t vb = VX128_VB128;
str->Append("%-8s v%d, v%d, v%d", i.type->name,
vd, va, vb);
}
void Disasm_VX128_VD_VA_VD_VB(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_VD128;
const uint32_t va = VX128_VA128;
const uint32_t vb = VX128_VB128;
str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name,
vd, va, vd, vb);
}
void Disasm_VX1282_VD_VA_VB_VC(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->Append("%-8s v%d, v%d, v%d, v%d", i.type->name,
vd, va, vb, vc);
}
void Disasm_VXA_VD_VA_VB_VC(InstrData& i, StringBuffer* str) {
str->Append("%-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_sync(InstrData& i, StringBuffer* str) {
const char* name;
int L = i.X.RT & 3;
switch (L) {
case 0: name = "hwsync"; break;
case 1: name = "lwsync"; break;
default:
case 2:
case 3:
name = "sync";
break;
}
str->Append("%-8s %.2X", name, L);
}
void Disasm_dcbf(InstrData& i, StringBuffer* str) {
const char* name;
switch (i.X.RT & 3) {
case 0: name = "dcbf"; break;
case 1: name = "dcbfl"; break;
case 2: name = "dcbf.RESERVED"; break;
case 3: name = "dcbflp"; break;
}
str->Append("%-8s r%d, r%d", name, i.X.RA, i.X.RB);
}
void Disasm_dcbz(InstrData& i, StringBuffer* str) {
// or dcbz128 0x7C2007EC
if (i.X.RA) {
str->Append("%-8s r%d, r%d", i.type->name, i.X.RA, i.X.RB);
} else {
str->Append("%-8s 0, r%d", i.type->name, i.X.RB);
}
}
void Disasm_fcmp(InstrData& i, StringBuffer* str) {
str->Append("%-8s cr%d, r%d, r%d", i.type->name,
i.X.RT >> 2, i.X.RA, i.X.RB);
}
void Disasm_mffsx(InstrData& i, StringBuffer* str) {
str->Append("%*s%s f%d, FPSCR", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "",
i.X.RT);
}
void Disasm_bx(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);
} else {
nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2));
}
str->Append("%-8s %.8X", name,
nia);
// TODO(benvanik): resolve target name?
}
void Disasm_bcx(InstrData& i, StringBuffer* str) {
const char* s0 = i.B.LK ? "lr, " : "";
const char* s1;
if (!XESELECTBITS(i.B.BO, 2, 2)) {
s1 = "ctr, ";
} else {
s1 = "";
}
char s2[8] = { 'c', 'r', 0, };
if (!XESELECTBITS(i.B.BO, 4, 4)) {
char* s2a = _itoa(i.B.BI >> 2, s2 + 2, 10);
s2a += xestrlena(s2a);
s2a[0] = ',';
s2a[1] = ' ';
} else {
s2[0] = 0;
}
uint32_t nia;
if (i.B.AA) {
nia = (uint32_t)XEEXTS16(i.B.BD << 2);
} else {
nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2));
}
str->Append("%-8s %s%s%s%.8X", i.type->name,
s0, s1, s2, nia);
// TODO(benvanik): resolve target name?
}
void Disasm_bcctrx(InstrData& i, StringBuffer* str) {
// TODO(benvanik): mnemonics
const char* s0 = i.XL.LK ? "lr, " : "";
char s2[8] = { 'c', 'r', 0, };
if (!XESELECTBITS(i.XL.BO, 4, 4)) {
char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10);
s2a += xestrlena(s2a);
s2a[0] = ',';
s2a[1] = ' ';
} else {
s2[0] = 0;
}
str->Append("%-8s %s%sctr", i.type->name,
s0, s2);
// TODO(benvanik): resolve target name?
}
void Disasm_bclrx(InstrData& i, StringBuffer* str) {
const char* name = "bclr";
if (i.code == 0x4E800020) {
name = "blr";
}
const char* s1;
if (!XESELECTBITS(i.XL.BO, 2, 2)) {
s1 = "ctr, ";
} else {
s1 = "";
}
char s2[8] = { 'c', 'r', 0, };
if (!XESELECTBITS(i.XL.BO, 4, 4)) {
char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10);
s2a += xestrlena(s2a);
s2a[0] = ',';
s2a[1] = ' ';
} else {
s2[0] = 0;
}
str->Append("%-8s %s%s", name,
s1, s2);
}
void Disasm_mfcr(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, cr", i.type->name,
i.X.RT);
}
const char* Disasm_spr_name(uint32_t n) {
const char* reg = "???";
switch (n) {
case 1:
reg = "xer";
break;
case 8:
reg = "lr";
break;
case 9:
reg = "ctr";
break;
}
return reg;
}
void Disasm_mfspr(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->Append("%-8s r%d, %s", i.type->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);
const char* reg = Disasm_spr_name(n);
str->Append("%-8s %s, r%d", i.type->name,
reg, i.XFX.RT);
}
void Disasm_mftb(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, tb", i.type->name,
i.XFX.RT);
}
void Disasm_mfmsr(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d", i.type->name,
i.X.RT);
}
void Disasm_mtmsr(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, %d", i.type->name,
i.X.RT, (i.X.RA & 16) ? 1 : 0);
}
void Disasm_cmp(InstrData& i, StringBuffer* str) {
str->Append("%-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_cmpi(InstrData& i, StringBuffer* str) {
str->Append("%-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_cmpli(InstrData& i, StringBuffer* str) {
str->Append("%-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_rld(InstrData& i, StringBuffer* str) {
if (i.MD.idx == 0) {
// XEDISASMR(rldiclx, 0x78000000, MD )
str->Append("%*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->Append("%*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;
const char* name = (mb == 0x3E) ? "sldi" : "rldic";
str->Append("%*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->Append("%*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->Append("%*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->Append("%*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 {
XEASSERTALWAYS();
}
}
void Disasm_rlwim(InstrData& i, StringBuffer* str) {
str->Append("%*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_rlwnmx(InstrData& i, StringBuffer* str) {
str->Append("%*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_srawix(InstrData& i, StringBuffer* str) {
str->Append("%*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_sradix(InstrData& i, StringBuffer* str) {
str->Append("%*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_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->Append("%-8s v%d, v%d, %.2X", i.type->name,
vd, vb, i.VX128_P.PERMl | (i.VX128_P.PERMh << 5));
}
void Disasm_vrfin128(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_3_VD128;
const uint32_t vb = VX128_3_VB128;
str->Append("%-8s v%d, v%d", i.type->name,
vd, vb);
}
void Disasm_vrlimi128(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_4_VD128;
const uint32_t vb = VX128_4_VB128;
str->Append("%-8s v%d, v%d, %.2X, %.2X", i.type->name,
vd, vb, i.VX128_4.IMM, i.VX128_4.z);
}
void Disasm_vsldoi128(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->Append("%-8s v%d, v%d, v%d, %.2X", i.type->name,
vd, va, vb, sh);
}
void Disasm_vspltb(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, %.2X", i.type->name,
i.VX.VD, i.VX.VB, i.VX.VA & 0xF);
}
void Disasm_vsplth(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, %.2X", i.type->name,
i.VX.VD, i.VX.VB, i.VX.VA & 0x7);
}
void Disasm_vspltw(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, %.2X", i.type->name,
i.VX.VD, i.VX.VB, i.VX.VA);
}
void Disasm_vspltisb(InstrData& i, StringBuffer* str) {
// 5bit -> 8bit sign extend
int8_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xF0) : i.VX.VA;
str->Append("%-8s v%d, %.2X", i.type->name,
i.VX.VD, simm);
}
void Disasm_vspltish(InstrData& i, StringBuffer* str) {
// 5bit -> 16bit sign extend
int16_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFF0) : i.VX.VA;
str->Append("%-8s v%d, %.4X", i.type->name,
i.VX.VD, simm);
}
void Disasm_vspltisw(InstrData& i, StringBuffer* str) {
// 5bit -> 32bit sign extend
int32_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFF0) : i.VX.VA;
str->Append("%-8s v%d, %.8X", i.type->name,
i.VX.VD, simm);
}
} // namespace ppc
} // namespace frontend
} // namespace alloy
int alloy::frontend::ppc::DisasmPPC(InstrData& i, StringBuffer* str) {
if (!i.type) {
str->Append("???");
} else {
i.type->disasm(i, str);
}
return 0;
}

View File

@ -18,11 +18,7 @@ namespace frontend {
namespace ppc {
void RegisterDisasmCategoryAltivec();
void RegisterDisasmCategoryALU();
void RegisterDisasmCategoryControl();
void RegisterDisasmCategoryFPU();
void RegisterDisasmCategoryMemory();
int DisasmPPC(InstrData& i, StringBuffer* str);
} // namespace ppc

File diff suppressed because it is too large Load Diff

View File

@ -1,729 +0,0 @@
/*
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/frontend/ppc/ppc_disasm-private.h>
using namespace alloy::frontend::ppc;
namespace alloy {
namespace frontend {
namespace ppc {
// Integer arithmetic (A-3)
XEDISASMR(addx, 0x7C000214, XO )(InstrData& i, InstrDisasm& d) {
d.Init("add", "Add",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(addcx, 0x7C000014, XO )(InstrData& i, InstrDisasm& d) {
d.Init("addc", "Add Carrying",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0) |
InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(addex, 0x7C000114, XO )(InstrData& i, InstrDisasm& d) {
d.Init("adde", "Add Extended",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(addi, 0x38000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("addi", "Add Immediate", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddSImmOperand(0, 4);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(addic, 0x30000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("addic", "Add Immediate Carrying", InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(addicx, 0x34000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("addic", "Add Immediate Carrying and Record",
InstrDisasm::kRc | InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(addis, 0x3C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("addis", "Add Immediate Shifted", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddSImmOperand(0, 4);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(addmex, 0x7C0001D4, XO )(InstrData& i, InstrDisasm& d) {
d.Init("addme", "Add to Minus One Extended",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0) |
InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(addzex, 0x7C000194, XO )(InstrData& i, InstrDisasm& d) {
d.Init("addze", "Add to Zero Extended",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0) |
InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(divdx, 0x7C0003D2, XO )(InstrData& i, InstrDisasm& d) {
d.Init("divd", "Divide Doubleword",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(divdux, 0x7C000392, XO )(InstrData& i, InstrDisasm& d) {
d.Init("divdu", "Divide Doubleword Unsigned",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(divwx, 0x7C0003D6, XO )(InstrData& i, InstrDisasm& d) {
d.Init("divw", "Divide Word",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(divwux, 0x7C000396, XO )(InstrData& i, InstrDisasm& d) {
d.Init("divwu", "Divide Word Unsigned",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(mulhdx, 0x7C000092, XO )(InstrData& i, InstrDisasm& d) {
d.Init("mulhd", "Multiply High Doubleword", i.XO.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(mulhdux, 0x7C000012, XO )(InstrData& i, InstrDisasm& d) {
d.Init("mulhdu", "Multiply High Doubleword Unsigned",
i.XO.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(mulhwx, 0x7C000096, XO )(InstrData& i, InstrDisasm& d) {
d.Init("mulhw", "Multiply High Word", i.XO.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(mulhwux, 0x7C000016, XO )(InstrData& i, InstrDisasm& d) {
d.Init("mulhwu", "Multiply High Word Unsigned",
i.XO.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(mulldx, 0x7C0001D2, XO )(InstrData& i, InstrDisasm& d) {
d.Init("mulld", "Multiply Low Doubleword",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(mulli, 0x1C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("mulli", "Multiply Low Immediate", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(mullwx, 0x7C0001D6, XO )(InstrData& i, InstrDisasm& d) {
d.Init("mullw", "Multiply Low Word",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(negx, 0x7C0000D0, XO )(InstrData& i, InstrDisasm& d) {
d.Init("neg", "Negate",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(subfx, 0x7C000050, XO )(InstrData& i, InstrDisasm& d) {
d.Init("subf", "Subtract From",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(subfcx, 0x7C000010, XO )(InstrData& i, InstrDisasm& d) {
d.Init("subfc", "Subtract From Carrying",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0) |
InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(subficx, 0x20000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("subfic", "Subtract From Immediate Carrying", InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(subfex, 0x7C000110, XO )(InstrData& i, InstrDisasm& d) {
d.Init("subfe", "Subtract From Extended",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0) |
InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(subfmex, 0x7C0001D0, XO )(InstrData& i, InstrDisasm& d) {
d.Init("subfme", "Subtract From Minus One Extended",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0) |
InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(subfzex, 0x7C000190, XO )(InstrData& i, InstrDisasm& d) {
d.Init("subfze", "Subtract From Zero Extended",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0) |
InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
return d.Finish();
}
// Integer compare (A-4)
XEDISASMR(cmp, 0x7C000000, X )(InstrData& i, InstrDisasm& d) {
d.Init("cmp", "Compare", 0);
d.AddCR(i.X.RT >> 2, InstrRegister::kWrite);
d.AddUImmOperand(i.X.RT >> 2, 1);
d.AddUImmOperand(i.X.RT & 1, 1);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(cmpi, 0x2C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("cmpi", "Compare Immediate", 0);
d.AddCR(i.D.RT >> 2, InstrRegister::kWrite);
d.AddUImmOperand(i.D.RT >> 2, 1);
d.AddUImmOperand(i.D.RT & 1, 1);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(cmpl, 0x7C000040, X )(InstrData& i, InstrDisasm& d) {
d.Init("cmpl", "Compare Logical", 0);
d.AddCR(i.X.RT >> 2, InstrRegister::kWrite);
d.AddUImmOperand(i.X.RT >> 2, 1);
d.AddUImmOperand(i.X.RT & 1, 1);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(cmpli, 0x28000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("cmpli", "Compare Logical Immediate", 0);
d.AddCR(i.D.RT >> 2, InstrRegister::kWrite);
d.AddUImmOperand(i.D.RT >> 2, 1);
d.AddUImmOperand(i.D.RT & 1, 1);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
d.AddSImmOperand(i.D.DS, 2);
return d.Finish();
}
// Integer logical (A-5)
XEDISASMR(andx, 0x7C000038, X )(InstrData& i, InstrDisasm& d) {
d.Init("and", "AND", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(andcx, 0x7C000078, X )(InstrData& i, InstrDisasm& d) {
d.Init("andc", "AND with Complement", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(andix, 0x70000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("andi", "AND Immediate", 0);
d.AddCR(0, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddUImmOperand(i.D.DS, 2);
return d.Finish();
}
XEDISASMR(andisx, 0x74000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("andi", "AND Immediate Shifted", 0);
d.AddCR(0, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddUImmOperand(i.D.DS, 2);
return d.Finish();
}
XEDISASMR(cntlzdx, 0x7C000074, X )(InstrData& i, InstrDisasm& d) {
d.Init("cntlzd", "Count Leading Zeros Doubleword",
i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(cntlzwx, 0x7C000034, X )(InstrData& i, InstrDisasm& d) {
d.Init("cntlzw", "Count Leading Zeros Word",
i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(eqvx, 0x7C000238, X )(InstrData& i, InstrDisasm& d) {
d.Init("eqv", "Equivalent", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(extsbx, 0x7C000774, X )(InstrData& i, InstrDisasm& d) {
d.Init("extsb", "Extend Sign Byte", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(extshx, 0x7C000734, X )(InstrData& i, InstrDisasm& d) {
d.Init("extsh", "Extend Sign Halfword", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(extswx, 0x7C0007B4, X )(InstrData& i, InstrDisasm& d) {
d.Init("extsw", "Extend Sign Word", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(nandx, 0x7C0003B8, X )(InstrData& i, InstrDisasm& d) {
d.Init("nand", "NAND", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(norx, 0x7C0000F8, X )(InstrData& i, InstrDisasm& d) {
d.Init("nor", "NOR", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(orx, 0x7C000378, X )(InstrData& i, InstrDisasm& d) {
d.Init("or", "OR", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(orcx, 0x7C000338, X )(InstrData& i, InstrDisasm& d) {
d.Init("orc", "OR with Complement", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(ori, 0x60000000, D )(InstrData& i, InstrDisasm& d) {
if (!i.D.RA && !i.D.RT && !i.D.DS) {
d.Init("nop", "OR Immediate", 0);
return d.Finish();
} else {
d.Init("ori", "OR Immediate", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddUImmOperand(i.D.DS, 2);
return d.Finish();
}
}
XEDISASMR(oris, 0x64000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("oris", "OR Immediate Shifted", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddUImmOperand(i.D.DS, 2);
return d.Finish();
}
XEDISASMR(xorx, 0x7C000278, X )(InstrData& i, InstrDisasm& d) {
d.Init("xor", "XOR", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(xori, 0x68000000, D )(InstrData& i, InstrDisasm& d) {
if (!i.D.RA && !i.D.RT && !i.D.DS) {
d.Init("xnop", "XOR Immediate", 0);
} else {
d.Init("xori", "XOR Immediate", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddUImmOperand(i.D.DS, 2);
}
return d.Finish();
}
XEDISASMR(xoris, 0x6C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("xoris", "XOR Immediate Shifted", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddUImmOperand(i.D.DS, 2);
return d.Finish();
}
// Integer rotate (A-6)
XEDISASMR(rld, 0x78000000, MDS)(InstrData& i, InstrDisasm& d) {
if (i.MD.idx == 0) {
// XEDISASMR(rldiclx, 0x78000000, MD )
d.Init("rldicl", "Rotate Left Doubleword Immediate then Clear Left",
i.MD.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1);
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
return d.Finish();
} else if (i.MD.idx == 1) {
// XEDISASMR(rldicrx, 0x78000004, MD )
d.Init("rldicr", "Rotate Left Doubleword Immediate then Clear Right",
i.MD.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1);
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
return d.Finish();
} else if (i.MD.idx == 2) {
// XEDISASMR(rldicx, 0x78000008, MD )
const char* name;
const char* desc;
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
if (mb == 0x3E) {
name = "sldi";
desc = "Shift Left Immediate";
} else {
name = "rldic";
desc = "Rotate Left Doubleword Immediate then Clear";
}
d.Init(name, desc,
i.MD.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
d.AddUImmOperand(sh, 1);
d.AddUImmOperand(mb, 1);
return d.Finish();
} else if (i.MDS.idx == 8) {
// XEDISASMR(rldclx, 0x78000010, MDS)
d.Init("rldcl", "Rotate Left Doubleword then Clear Left",
i.MDS.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead);
d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1);
return d.Finish();
} else if (i.MDS.idx == 9) {
// XEDISASMR(rldcrx, 0x78000012, MDS)
d.Init("rldcr", "Rotate Left Doubleword then Clear Right",
i.MDS.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.MDS.RB, InstrRegister::kRead);
d.AddUImmOperand((i.MDS.MB5 << 5) | i.MDS.MB, 1);
return d.Finish();
} else if (i.MD.idx == 3) {
// XEDISASMR(rldimix, 0x7800000C, MD )
d.Init("rldimi", "Rotate Left Doubleword Immediate then Mask Insert",
i.MD.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.MD.RT, InstrRegister::kRead);
d.AddUImmOperand((i.MD.SH5 << 5) | i.MD.SH, 1);
d.AddUImmOperand((i.MD.MB5 << 5) | i.MD.MB, 1);
return d.Finish();
} else {
XEASSERTALWAYS();
return 1;
}
}
XEDISASMR(rlwimix, 0x50000000, M )(InstrData& i, InstrDisasm& d) {
d.Init("rlwimi", "Rotate Left Word Immediate then Mask Insert",
i.M.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.M.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.M.RT, InstrRegister::kRead);
d.AddUImmOperand(i.M.SH, 1);
d.AddUImmOperand(i.M.MB, 1);
d.AddUImmOperand(i.M.ME, 1);
return d.Finish();
}
XEDISASMR(rlwinmx, 0x54000000, M )(InstrData& i, InstrDisasm& d) {
d.Init("rlwinm", "Rotate Left Word Immediate then AND with Mask",
i.M.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.M.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.M.RT, InstrRegister::kRead);
d.AddUImmOperand(i.M.SH, 1);
d.AddUImmOperand(i.M.MB, 1);
d.AddUImmOperand(i.M.ME, 1);
return d.Finish();
}
XEDISASMR(rlwnmx, 0x5C000000, M )(InstrData& i, InstrDisasm& d) {
d.Init("rlwnm", "Rotate Left Word then AND with Mask",
i.M.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.M.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.M.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.M.SH, InstrRegister::kRead);
d.AddUImmOperand(i.M.MB, 1);
d.AddUImmOperand(i.M.ME, 1);
return d.Finish();
}
// Integer shift (A-7)
XEDISASMR(sldx, 0x7C000036, X )(InstrData& i, InstrDisasm& d) {
d.Init("sld", "Shift Left Doubleword", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(slwx, 0x7C000030, X )(InstrData& i, InstrDisasm& d) {
d.Init("slw", "Shift Left Word", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(sradx, 0x7C000634, X )(InstrData& i, InstrDisasm& d) {
d.Init("srad", "Shift Right Algebraic Doubleword",
i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(sradix, 0x7C000674, XS )(InstrData& i, InstrDisasm& d) {
d.Init("sradi", "Shift Right Algebraic Doubleword Immediate",
(i.XS.Rc ? InstrDisasm::kRc : 0) | InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.XS.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XS.RT, InstrRegister::kRead);
d.AddUImmOperand((i.XS.SH5 << 5) | i.XS.SH, 1);
return d.Finish();
}
XEDISASMR(srawx, 0x7C000630, X )(InstrData& i, InstrDisasm& d) {
d.Init("sraw", "Shift Right Algebraic Word",
(i.X.Rc ? InstrDisasm::kRc : 0) | InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(srawix, 0x7C000670, X )(InstrData& i, InstrDisasm& d) {
d.Init("srawi", "Shift Right Algebraic Word Immediate",
(i.X.Rc ? InstrDisasm::kRc : 0) | InstrDisasm::kCA);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddUImmOperand(i.X.RB, 1);
return d.Finish();
}
XEDISASMR(srdx, 0x7C000436, X )(InstrData& i, InstrDisasm& d) {
d.Init("srd", "Shift Right Doubleword", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(srwx, 0x7C000430, X )(InstrData& i, InstrDisasm& d) {
d.Init("srw", "Shift Right Word", i.X.Rc ? InstrDisasm::kRc : 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
void RegisterDisasmCategoryALU() {
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(sradx, 0x7C000634);
XEREGISTERINSTR(sradix, 0x7C000674);
XEREGISTERINSTR(srawx, 0x7C000630);
XEREGISTERINSTR(srawix, 0x7C000670);
XEREGISTERINSTR(srdx, 0x7C000436);
XEREGISTERINSTR(srwx, 0x7C000430);
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -1,283 +0,0 @@
/*
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/frontend/ppc/ppc_disasm-private.h>
using namespace alloy::frontend::ppc;
namespace alloy {
namespace frontend {
namespace ppc {
XEDISASMR(bx, 0x48000000, I )(InstrData& i, InstrDisasm& d) {
d.Init("b", "Branch", i.I.LK ? InstrDisasm::kLR : 0);
uint32_t nia;
if (i.I.AA) {
nia = (uint32_t)XEEXTS26(i.I.LI << 2);
} else {
nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2));
}
d.AddUImmOperand(nia, 4);
return d.Finish();
}
XEDISASMR(bcx, 0x40000000, B )(InstrData& i, InstrDisasm& d) {
// TODO(benvanik): mnemonics
d.Init("bc", "Branch Conditional", i.B.LK ? InstrDisasm::kLR : 0);
if (!XESELECTBITS(i.B.BO, 2, 2)) {
d.AddCTR(InstrRegister::kReadWrite);
}
if (!XESELECTBITS(i.B.BO, 4, 4)) {
d.AddCR(i.B.BI >> 2, InstrRegister::kRead);
}
d.AddUImmOperand(i.B.BO, 1);
d.AddUImmOperand(i.B.BI, 1);
uint32_t nia;
if (i.B.AA) {
nia = (uint32_t)XEEXTS16(i.B.BD << 2);
} else {
nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2));
}
d.AddUImmOperand(nia, 4);
return d.Finish();
}
XEDISASMR(bcctrx, 0x4C000420, XL )(InstrData& i, InstrDisasm& d) {
// TODO(benvanik): mnemonics
d.Init("bcctr", "Branch Conditional to Count Register",
i.XL.LK ? InstrDisasm::kLR : 0);
if (!XESELECTBITS(i.XL.BO, 4, 4)) {
d.AddCR(i.XL.BI >> 2, InstrRegister::kRead);
}
d.AddUImmOperand(i.XL.BO, 1);
d.AddUImmOperand(i.XL.BI, 1);
d.AddCTR(InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(bclrx, 0x4C000020, XL )(InstrData& i, InstrDisasm& d) {
const char* name = "bclr";
if (i.code == 0x4E800020) {
name = "blr";
}
d.Init(name, "Branch Conditional to Link Register",
i.XL.LK ? InstrDisasm::kLR : 0);
if (!XESELECTBITS(i.B.BO, 2, 2)) {
d.AddCTR(InstrRegister::kReadWrite);
}
if (!XESELECTBITS(i.B.BO, 4, 4)) {
d.AddCR(i.B.BI >> 2, InstrRegister::kRead);
}
d.AddUImmOperand(i.XL.BO, 1);
d.AddUImmOperand(i.XL.BI, 1);
d.AddLR(InstrRegister::kRead);
return d.Finish();
}
// Condition register logical (A-23)
XEDISASMR(crand, 0x4C000202, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(crandc, 0x4C000102, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(creqv, 0x4C000242, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(crnand, 0x4C0001C2, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(crnor, 0x4C000042, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(cror, 0x4C000382, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(crorc, 0x4C000342, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(crxor, 0x4C000182, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(mcrf, 0x4C000000, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// System linkage (A-24)
XEDISASMR(sc, 0x44000002, SC )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Trap (A-25)
XEDISASMR(td, 0x7C000088, X )(InstrData& i, InstrDisasm& d) {
d.Init("td", "Trap Doubleword", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(tdi, 0x08000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("tdi", "Trap Doubleword Immediate", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(tw, 0x7C000008, X )(InstrData& i, InstrDisasm& d) {
d.Init("tw", "Trap Word", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(twi, 0x0C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("twi", "Trap Word Immediate", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
return d.Finish();
}
// Processor control (A-26)
XEDISASMR(mfcr, 0x7C000026, X )(InstrData& i, InstrDisasm& d) {
d.Init("mfcr", "Move From Condition Register", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
for (int n = 0; n < 8; n++) {
d.AddCR(0, InstrRegister::kRead);
}
return d.Finish();
}
XEDISASMR(mfspr, 0x7C0002A6, XFX)(InstrData& i, InstrDisasm& d) {
d.Init("mfspr", "Move From Special Purpose Register", 0);
d.AddRegOperand(InstrRegister::kGPR, i.XFX.RT, InstrRegister::kWrite);
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
switch (n) {
case 1:
d.AddRegOperand(InstrRegister::kXER, 0, InstrRegister::kRead);
break;
case 8:
d.AddRegOperand(InstrRegister::kLR, 0, InstrRegister::kRead);
break;
case 9:
d.AddRegOperand(InstrRegister::kCTR, 0, InstrRegister::kRead);
break;
}
return d.Finish();
}
XEDISASMR(mftb, 0x7C0002E6, XFX)(InstrData& i, InstrDisasm& d) {
d.Init("mftb", "Move From Time Base", 0);
d.AddRegOperand(InstrRegister::kGPR, i.XFX.RT, InstrRegister::kWrite);
return d.Finish();
}
XEDISASMR(mtcrf, 0x7C000120, XFX)(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(mtspr, 0x7C0003A6, XFX)(InstrData& i, InstrDisasm& d) {
d.Init("mtspr", "Move To Special Purpose Register", 0);
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
switch (n) {
case 1:
d.AddRegOperand(InstrRegister::kXER, 0, InstrRegister::kWrite);
break;
case 8:
d.AddRegOperand(InstrRegister::kLR, 0, InstrRegister::kWrite);
break;
case 9:
d.AddRegOperand(InstrRegister::kCTR, 0, InstrRegister::kWrite);
break;
}
d.AddRegOperand(InstrRegister::kGPR, i.XFX.RT, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(mfmsr, 0x7C0000A6, X)(InstrData& i, InstrDisasm& d) {
d.Init("mfmsr", "Move From Machine State Register", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
return d.Finish();
}
XEDISASMR(mtmsr, 0x7C000124, X)(InstrData& i, InstrDisasm& d) {
d.Init("mtmsr", "Move To Machine State Register", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddSImmOperand((i.X.RA & 16) ? 1 : 0, 1);
return d.Finish();
}
XEDISASMR(mtmsrd, 0x7C000164, X)(InstrData& i, InstrDisasm& d) {
d.Init("mtmsrd", "Move To Machine State Register Doubleword", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddSImmOperand((i.X.RA & 16) ? 1 : 0, 1);
return d.Finish();
}
void RegisterDisasmCategoryControl() {
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);
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -1,413 +0,0 @@
/*
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/frontend/ppc/ppc_disasm-private.h>
using namespace alloy::frontend::ppc;
namespace alloy {
namespace frontend {
namespace ppc {
// Floating-point arithmetic (A-8)
XEDISASMR(faddx, 0xFC00002A, A )(InstrData& i, InstrDisasm& d) {
d.Init("fadd", "Floating Add [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(faddsx, 0xEC00002A, A )(InstrData& i, InstrDisasm& d) {
d.Init("fadds", "Floating Add [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fdivx, 0xFC000024, A )(InstrData& i, InstrDisasm& d) {
d.Init("fdiv", "Floating Divide [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fdivsx, 0xEC000024, A )(InstrData& i, InstrDisasm& d) {
d.Init("fdivs", "Floating Divide [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fmulx, 0xFC000032, A )(InstrData& i, InstrDisasm& d) {
d.Init("fmul", "Floating Multiply [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fmulsx, 0xEC000032, A )(InstrData& i, InstrDisasm& d) {
d.Init("fmuls", "Floating Multiply [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fresx, 0xEC000030, A )(InstrData& i, InstrDisasm& d) {
d.Init("fres", "Floating Reciprocal Estimate [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(frsqrtex, 0xFC000034, A )(InstrData& i, InstrDisasm& d) {
d.Init("frsqrte", "Floating Reciprocal Square Root Estimate [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fsubx, 0xFC000028, A )(InstrData& i, InstrDisasm& d) {
d.Init("fsub", "Floating Subtract [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fsubsx, 0xEC000028, A )(InstrData& i, InstrDisasm& d) {
d.Init("fsubs", "Floating Subtract [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fselx, 0xFC00002E, A )(InstrData& i, InstrDisasm& d) {
d.Init("fsel", "Floating Select",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fsqrtx, 0xFC00002C, A )(InstrData& i, InstrDisasm& d) {
d.Init("fsqrt", "Floating Square Root [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fsqrtsx, 0xEC00002C, A )(InstrData& i, InstrDisasm& d) {
d.Init("fsqrts", "Floating Square Root [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
return d.Finish();
}
// Floating-point multiply-add (A-9)
XEDISASMR(fmaddx, 0xFC00003A, A )(InstrData& i, InstrDisasm& d) {
d.Init("fmadd", "Floating Multiply-Add [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fmaddsx, 0xEC00003A, A )(InstrData& i, InstrDisasm& d) {
d.Init("fmadds", "Floating Multiply-Add [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fmsubx, 0xFC000038, A )(InstrData& i, InstrDisasm& d) {
d.Init("fmsub", "Floating Multiply-Subtract[Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fmsubsx, 0xEC000038, A )(InstrData& i, InstrDisasm& d) {
d.Init("fmsubs", "Floating Multiply-Subtract [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fnmaddx, 0xFC00003E, A )(InstrData& i, InstrDisasm& d) {
d.Init("fnmadd", "Floating Negative Multiply-Add [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fnmaddsx, 0xEC00003E, A )(InstrData& i, InstrDisasm& d) {
d.Init("fnmadds", "Floating Negative Multiply-Add [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fnmsubx, 0xFC00003C, A )(InstrData& i, InstrDisasm& d) {
d.Init("fnmsub", "Floating Negative Multiply-Subtract [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fnmsubsx, 0xEC00003C, A )(InstrData& i, InstrDisasm& d) {
d.Init("fnmsubs", "Floating Negative Multiply-Add [Single]",
InstrDisasm::kFP | (i.A.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.A.FRT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRB, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.A.FRC, InstrRegister::kRead);
return d.Finish();
}
// Floating-point rounding and conversion (A-10)
XEDISASMR(fcfidx, 0xFC00069C, X )(InstrData& i, InstrDisasm& d) {
d.Init("fcfid", "Floating Convert From Integer Doubleword",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fctidx, 0xFC00065C, X )(InstrData& i, InstrDisasm& d) {
d.Init("fctid", "Floating Convert To Integer Doubleword",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fctidzx, 0xFC00065E, X )(InstrData& i, InstrDisasm& d) {
d.Init("fctidz",
"Floating Convert To Integer Doubleword with round toward Zero",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fctiwx, 0xFC00001C, X )(InstrData& i, InstrDisasm& d) {
d.Init("fctiw", "Floating Convert To Integer Word",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fctiwzx, 0xFC00001E, X )(InstrData& i, InstrDisasm& d) {
d.Init("fctiwz", "Floating Convert To Integer Word with round toward Zero",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(frspx, 0xFC000018, X )(InstrData& i, InstrDisasm& d) {
d.Init("frsp", "Floating Round to Single-Precision",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
// Floating-point compare (A-11)
XEDISASMR(fcmpo, 0xFC000040, X )(InstrData& i, InstrDisasm& d) {
d.Init("fcmpo", "Floating Compare Ordered", 0);
d.AddCR(i.X.RT >> 2, InstrRegister::kWrite);
d.AddUImmOperand(i.X.RT >> 2, 1);
d.AddRegOperand(InstrRegister::kFPR, i.X.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fcmpu, 0xFC000000, X )(InstrData& i, InstrDisasm& d) {
d.Init("fcmpu", "Floating Compare Unordered", 0);
d.AddCR(i.X.RT >> 2, InstrRegister::kWrite);
d.AddUImmOperand(i.X.RT >> 2, 1);
d.AddRegOperand(InstrRegister::kFPR, i.X.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
// Floating-point status and control register (A
XEDISASMR(mcrfs, 0xFC000080, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(mffsx, 0xFC00048E, X )(InstrData& i, InstrDisasm& d) {
d.Init("mffs", "Move from FPSCR",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddFPSCR(InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
return d.Finish();
}
XEDISASMR(mtfsb0x, 0xFC00008C, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(mtfsb1x, 0xFC00004C, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(mtfsfx, 0xFC00058E, XFL)(InstrData& i, InstrDisasm& d) {
d.Init("mtfsf", "Move to FPSCR Fields",
InstrDisasm::kFP | (i.XFL.Rc ? InstrDisasm::kRc : 0));
d.AddFPSCR(InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.XFL.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(mtfsfix, 0xFC00010C, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Floating-point move (A-21)
XEDISASMR(fabsx, 0xFC000210, X )(InstrData& i, InstrDisasm& d) {
d.Init("fabs", "Floating Absolute Value",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fmrx, 0xFC000090, X )(InstrData& i, InstrDisasm& d) {
d.Init("fmr", "Floating Move Register",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fnabsx, 0xFC000110, X )(InstrData& i, InstrDisasm& d) {
d.Init("fnabs", "Floating Negative Absolute Value",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(fnegx, 0xFC000050, X )(InstrData& i, InstrDisasm& d) {
d.Init("fneg", "Floating Negate",
InstrDisasm::kFP | (i.X.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kFPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
void RegisterDisasmCategoryFPU() {
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);
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -1,930 +0,0 @@
/*
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <alloy/frontend/ppc/ppc_disasm-private.h>
using namespace alloy::frontend::ppc;
namespace alloy {
namespace frontend {
namespace ppc {
// Integer load (A-13)
XEDISASMR(lbz, 0x88000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lbz", "Load Byte and Zero", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lbzu, 0x8C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lbzu", "Load Byte and Zero with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lbzux, 0x7C0000EE, X )(InstrData& i, InstrDisasm& d) {
d.Init("lbzux", "Load Byte and Zero with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lbzx, 0x7C0000AE, X )(InstrData& i, InstrDisasm& d) {
d.Init("lbzx", "Load Byte and Zero Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(ld, 0xE8000000, DS )(InstrData& i, InstrDisasm& d) {
d.Init("ld", "Load Doubleword", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kWrite);
if (i.DS.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEDISASMR(ldu, 0xE8000001, DS )(InstrData& i, InstrDisasm& d) {
d.Init("ldu", "Load Doubleword with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEDISASMR(ldux, 0x7C00006A, X )(InstrData& i, InstrDisasm& d) {
d.Init("ldux", "Load Doubleword with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(ldx, 0x7C00002A, X )(InstrData& i, InstrDisasm& d) {
d.Init("ldx", "Load Doubleword Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lha, 0xA8000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lha", "Load Halfword Algebraic", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lhau, 0xAC000000, D )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(lhaux, 0x7C0002EE, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(lhax, 0x7C0002AE, X )(InstrData& i, InstrDisasm& d) {
d.Init("lhax", "Load Halfword Algebraic Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lhz, 0xA0000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lhz", "Load Halfword and Zero", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lhzu, 0xA4000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lhzu", "Load Halfword and Zero with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lhzux, 0x7C00026E, X )(InstrData& i, InstrDisasm& d) {
d.Init("lhzux", "Load Halfword and Zero with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lhzx, 0x7C00022E, X )(InstrData& i, InstrDisasm& d) {
d.Init("lhzx", "Load Halfword and Zero Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lwa, 0xE8000002, DS )(InstrData& i, InstrDisasm& d) {
d.Init("lwa", "Load Word Algebraic", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEDISASMR(lwaux, 0x7C0002EA, X )(InstrData& i, InstrDisasm& d) {
d.Init("lwaux", "Load Word Algebraic with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lwax, 0x7C0002AA, X )(InstrData& i, InstrDisasm& d) {
d.Init("lwax", "Load Word Algebraic Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lwz, 0x80000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lwz", "Load Word and Zero", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lwzu, 0x84000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lwzu", "Load Word and Zero with Udpate", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lwzux, 0x7C00006E, X )(InstrData& i, InstrDisasm& d) {
d.Init("lwzux", "Load Word and Zero with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lwzx, 0x7C00002E, X )(InstrData& i, InstrDisasm& d) {
d.Init("lwzx", "Load Word and Zero Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
// Integer store (A-14)
XEDISASMR(stb, 0x98000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stb", "Store Byte", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(stbu, 0x9C000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stbu", "Store Byte with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(stbux, 0x7C0001EE, X )(InstrData& i, InstrDisasm& d) {
d.Init("stbux", "Store Byte with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stbx, 0x7C0001AE, X )(InstrData& i, InstrDisasm& d) {
d.Init("stbx", "Store Byte Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.DS.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(std, 0xF8000000, DS )(InstrData& i, InstrDisasm& d) {
d.Init("std", "Store Doubleword", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kRead);
if (i.DS.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEDISASMR(stdu, 0xF8000001, DS )(InstrData& i, InstrDisasm& d) {
d.Init("stdu", "Store Doubleword with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.DS.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.DS.DS << 2), 2);
return d.Finish();
}
XEDISASMR(stdux, 0x7C00016A, X )(InstrData& i, InstrDisasm& d) {
d.Init("stdux", "Store Doubleword with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stdx, 0x7C00012A, X )(InstrData& i, InstrDisasm& d) {
d.Init("stdx", "Store Doubleword Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(sth, 0xB0000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("sth", "Store Halfword", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(sthu, 0xB4000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("sthu", "Store Halfword with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(sthux, 0x7C00036E, X )(InstrData& i, InstrDisasm& d) {
d.Init("sthux", "Store Halfword with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(sthx, 0x7C00032E, X )(InstrData& i, InstrDisasm& d) {
d.Init("sth", "Store Halfword Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stw, 0x90000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stw", "Store Word", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(stwu, 0x94000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stwu", "Store Word with Update", 0);
d.AddRegOperand(InstrRegister::kGPR, i.D.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(stwux, 0x7C00016E, X )(InstrData& i, InstrDisasm& d) {
d.Init("stwux", "Store Word with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stwx, 0x7C00012E, X )(InstrData& i, InstrDisasm& d) {
d.Init("stwx", "Store Word Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
// Integer load and store with byte reverse (A-1
XEDISASMR(lhbrx, 0x7C00062C, X )(InstrData& i, InstrDisasm& d) {
d.Init("lhbrx", "Load Halfword Byte-Reverse Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lwbrx, 0x7C00042C, X )(InstrData& i, InstrDisasm& d) {
d.Init("lwbrx", "Load Word Byte-Reverse Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(ldbrx, 0x7C000428, X )(InstrData& i, InstrDisasm& d) {
d.Init("ldbrx", "Load Doubleword Byte-Reverse Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(sthbrx, 0x7C00072C, X )(InstrData& i, InstrDisasm& d) {
d.Init("sthbrx", "Store Halfword Byte-Reverse Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stwbrx, 0x7C00052C, X )(InstrData& i, InstrDisasm& d) {
d.Init("stwbrx", "Store Word Byte-Reverse Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stdbrx, 0x7C000528, X )(InstrData& i, InstrDisasm& d) {
d.Init("stdbrx", "Store Doubleword Byte-Reverse Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
// Integer load and store multiple (A-16)
XEDISASMR(lmw, 0xB8000000, D )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(stmw, 0xBC000000, D )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Integer load and store string (A-17)
XEDISASMR(lswi, 0x7C0004AA, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(lswx, 0x7C00042A, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(stswi, 0x7C0005AA, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(stswx, 0x7C00052A, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Memory synchronization (A-18)
XEDISASMR(eieio, 0x7C0006AC, X )(InstrData& i, InstrDisasm& d) {
d.Init("eieio", "Enforce In-Order Execution of I/O Instruction", 0);
return d.Finish();
}
XEDISASMR(isync, 0x4C00012C, XL )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(ldarx, 0x7C0000A8, X )(InstrData& i, InstrDisasm& d) {
d.Init("ldarx", "Load Doubleword And Reserve Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lwarx, 0x7C000028, X )(InstrData& i, InstrDisasm& d) {
d.Init("lwarx", "Load Word And Reserve Indexed", 0);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stdcx, 0x7C0001AD, X )(InstrData& i, InstrDisasm& d) {
d.Init("stdcx", "Store Doubleword Conditional Indexed",
InstrDisasm::kRc);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stwcx, 0x7C00012D, X )(InstrData& i, InstrDisasm& d) {
d.Init("stwcx", "Store Word Conditional Indexed",
InstrDisasm::kRc);
d.AddRegOperand(InstrRegister::kGPR, i.X.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(sync, 0x7C0004AC, X )(InstrData& i, InstrDisasm& d) {
const char* name;
const char* desc;
int L = i.X.RT & 3;
switch (L) {
case 0:
name = "hwsync";
desc = "Synchronize (heavyweight)";
break;
case 1:
name = "lwsync";
desc = "Synchronize (lightweight)";
break;
default:
case 2:
case 3:
name = "sync";
desc = "Synchronize";
break;
}
d.Init(name, desc, 0);
d.AddUImmOperand(L, 1);
return d.Finish();
}
// Floating-point load (A-19)
XEDISASMR(lfd, 0xC8000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lfd", "Load Floating-Point Double", 0);
d.AddRegOperand(InstrRegister::kFPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lfdu, 0xCC000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lfdu", "Load Floating-Point Double with Update", 0);
d.AddRegOperand(InstrRegister::kFPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lfdux, 0x7C0004EE, X )(InstrData& i, InstrDisasm& d) {
d.Init("lfdux", "Load Floating-Point Double with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lfdx, 0x7C0004AE, X )(InstrData& i, InstrDisasm& d) {
d.Init("lfdx", "Load Floating-Point Double Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lfs, 0xC0000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lfs", "Load Floating-Point Single", 0);
d.AddRegOperand(InstrRegister::kFPR, i.D.RT, InstrRegister::kWrite);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lfsu, 0xC4000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("lfsu", "Load Floating-Point Single with Update", 0);
d.AddRegOperand(InstrRegister::kFPR, i.D.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(lfsux, 0x7C00046E, X )(InstrData& i, InstrDisasm& d) {
d.Init("lfsux", "Load Floating-Point Single with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(lfsx, 0x7C00042E, X )(InstrData& i, InstrDisasm& d) {
d.Init("lfsx", "Load Floating-Point Single Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kWrite);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
// Floating-point store (A-20)
XEDISASMR(stfd, 0xD8000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stfd", "Store Floating-Point Double", 0);
d.AddRegOperand(InstrRegister::kFPR, i.D.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(stfdu, 0xDC000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stfdu", "Store Floating-Point Double with Update", 0);
d.AddRegOperand(InstrRegister::kFPR, i.D.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(stfdux, 0x7C0005EE, X )(InstrData& i, InstrDisasm& d) {
d.Init("stfdux", "Store Floating-Point Double with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stfdx, 0x7C0005AE, X )(InstrData& i, InstrDisasm& d) {
d.Init("stfdx", "Store Floating-Point Double Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stfiwx, 0x7C0007AE, X )(InstrData& i, InstrDisasm& d) {
d.Init("stfiwx", "Store Floating-Point as Integer Word Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stfs, 0xD0000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stfs", "Store Floating-Point Single", 0);
d.AddRegOperand(InstrRegister::kFPR, i.D.RT, InstrRegister::kRead);
if (i.D.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(stfsu, 0xD4000000, D )(InstrData& i, InstrDisasm& d) {
d.Init("stfsu", "Store Floating-Point Single with Update", 0);
d.AddRegOperand(InstrRegister::kFPR, i.D.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.D.RA, InstrRegister::kReadWrite);
d.AddSImmOperand(XEEXTS16(i.D.DS), 2);
return d.Finish();
}
XEDISASMR(stfsux, 0x7C00056E, X )(InstrData& i, InstrDisasm& d) {
d.Init("stfsux", "Store Floating-Point Single with Update Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kReadWrite);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(stfsx, 0x7C00052E, X )(InstrData& i, InstrDisasm& d) {
d.Init("stfsx", "Store Floating-Point Single Indexed", 0);
d.AddRegOperand(InstrRegister::kFPR, i.X.RT, InstrRegister::kRead);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
// Cache management (A-27)
XEDISASMR(dcbf, 0x7C0000AC, X )(InstrData& i, InstrDisasm& d) {
d.Init("dcbf", "Data Cache Block Flush", 0);
/*
switch (i.X.RT & 3)
{
case 0: "dcbf";
case 1: "dcbfl"
case 2: RESERVED
case 3: "dcbflp"
}
*/
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(dcbst, 0x7C00006C, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEDISASMR(dcbt, 0x7C00022C, X )(InstrData& i, InstrDisasm& d) {
d.Init("dcbt", "Data Cache Block Touch", 0);
// TODO
return d.Finish();
}
XEDISASMR(dcbtst, 0x7C0001EC, X )(InstrData& i, InstrDisasm& d) {
d.Init("dcbtst", "Data Cache Block Touch for Store", 0);
// TODO
return d.Finish();
}
XEDISASMR(dcbz, 0x7C0007EC, X )(InstrData& i, InstrDisasm& d) {
// or dcbz128 0x7C2007EC
d.Init("dcbz", "Data Cache Block set to Zero", 0);
if (i.X.RA) {
d.AddRegOperand(InstrRegister::kGPR, i.X.RA, InstrRegister::kRead);
} else {
d.AddUImmOperand(0, 1);
}
d.AddRegOperand(InstrRegister::kGPR, i.X.RB, InstrRegister::kRead);
return d.Finish();
}
XEDISASMR(icbi, 0x7C0007AC, X )(InstrData& i, InstrDisasm& d) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
void RegisterDisasmCategoryMemory() {
XEREGISTERINSTR(lbz, 0x88000000);
XEREGISTERINSTR(lbzu, 0x8C000000);
XEREGISTERINSTR(lbzux, 0x7C0000EE);
XEREGISTERINSTR(lbzx, 0x7C0000AE);
XEREGISTERINSTR(ld, 0xE8000000);
XEREGISTERINSTR(ldu, 0xE8000001);
XEREGISTERINSTR(ldux, 0x7C00006A);
XEREGISTERINSTR(ldx, 0x7C00002A);
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(stb, 0x98000000);
XEREGISTERINSTR(stbu, 0x9C000000);
XEREGISTERINSTR(stbux, 0x7C0001EE);
XEREGISTERINSTR(stbx, 0x7C0001AE);
XEREGISTERINSTR(std, 0xF8000000);
XEREGISTERINSTR(stdu, 0xF8000001);
XEREGISTERINSTR(stdux, 0x7C00016A);
XEREGISTERINSTR(stdx, 0x7C00012A);
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(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(isync, 0x4C00012C);
XEREGISTERINSTR(ldarx, 0x7C0000A8);
XEREGISTERINSTR(lwarx, 0x7C000028);
XEREGISTERINSTR(stdcx, 0x7C0001AD);
XEREGISTERINSTR(stwcx, 0x7C00012D);
XEREGISTERINSTR(sync, 0x7C0004AC);
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);
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -32,12 +32,6 @@ namespace {
}
has_initialized = true;
RegisterDisasmCategoryAltivec();
RegisterDisasmCategoryALU();
RegisterDisasmCategoryControl();
RegisterDisasmCategoryFPU();
RegisterDisasmCategoryMemory();
RegisterEmitCategoryAltivec();
RegisterEmitCategoryALU();
RegisterEmitCategoryControl();

View File

@ -11,6 +11,7 @@
#include <alloy/frontend/tracing.h>
#include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_disasm.h>
#include <alloy/frontend/ppc/ppc_frontend.h>
#include <alloy/frontend/ppc/ppc_instr.h>
#include <alloy/hir/label.h>
@ -26,9 +27,11 @@ using namespace alloy::runtime;
PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend) :
frontend_(frontend),
HIRBuilder() {
comment_buffer_ = new StringBuffer(4096);
}
PPCHIRBuilder::~PPCHIRBuilder() {
delete comment_buffer_;
}
void PPCHIRBuilder::Reset() {
@ -96,17 +99,9 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) {
if (label) {
AnnotateLabel(address, label);
}
if (!i.type) {
Comment("%.8X %.8X ???", address, i.code);
} else if (i.type->disassemble) {
ppc::InstrDisasm d;
i.type->disassemble(i, d);
std::string disasm;
d.Dump(disasm);
Comment("%.8X %.8X %s", address, i.code, disasm.c_str());
} else {
Comment("%.8X %.8X %s ???", address, i.code, i.type->name);
}
comment_buffer_->Reset();
DisasmPPC(i, comment_buffer_);
Comment("%.8X %.8X %s", address, i.code, comment_buffer_->GetString());
first_instr = last_instr();
}

View File

@ -74,6 +74,9 @@ private:
private:
PPCFrontend* frontend_;
// Reset whenever needed:
StringBuffer* comment_buffer_;
// Reset each Emit:
bool with_debug_info_;
runtime::FunctionInfo* symbol_info_;

View File

@ -283,114 +283,37 @@ void InstrAccessBits::Dump(std::string& out_str) {
void InstrDisasm::Init(const char* name, const char* info, uint32_t flags) {
operands.clear();
special_registers.clear();
access_bits.Clear();
this->name = name;
this->info = info;
this->flags = flags;
if (flags & InstrDisasm::kOE) {
InstrRegister i = {
InstrRegister::kXER, 0, InstrRegister::kReadWrite
};
special_registers.push_back(i);
}
if (flags & InstrDisasm::kRc) {
InstrRegister i = {
InstrRegister::kCR, 0, InstrRegister::kWrite
};
special_registers.push_back(i);
}
if (flags & InstrDisasm::kCA) {
InstrRegister i = {
InstrRegister::kXER, 0, InstrRegister::kReadWrite
};
special_registers.push_back(i);
}
if (flags & InstrDisasm::kLR) {
InstrRegister i = {
InstrRegister::kLR, 0, InstrRegister::kWrite
};
special_registers.push_back(i);
}
}
void InstrDisasm::AddLR(InstrRegister::Access access) {
InstrRegister i = {
InstrRegister::kLR, 0, access
};
special_registers.push_back(i);
}
void InstrDisasm::AddCTR(InstrRegister::Access access) {
InstrRegister i = {
InstrRegister::kCTR, 0, access
};
special_registers.push_back(i);
}
void InstrDisasm::AddCR(uint32_t bf, InstrRegister::Access access) {
InstrRegister i = {
InstrRegister::kCR, bf, access
};
special_registers.push_back(i);
}
void InstrDisasm::AddFPSCR(InstrRegister::Access access) {
InstrRegister i = {
InstrRegister::kFPSCR, 0, access
};
special_registers.push_back(i);
}
void InstrDisasm::AddRegOperand(
InstrRegister::RegisterSet set, uint32_t ordinal,
InstrRegister::Access access, const char* display) {
InstrRegister i = {
set, ordinal, access
};
InstrOperand o;
o.type = InstrOperand::kRegister;
o.reg = i;
o.display = display;
operands.push_back(o);
}
void InstrDisasm::AddSImmOperand(uint64_t value, size_t width,
const char* display) {
InstrOperand o;
o.type = InstrOperand::kImmediate;
o.imm.is_signed = true;
o.imm.value = value;
o.imm.width = width;
o.display = display;
operands.push_back(o);
}
void InstrDisasm::AddUImmOperand(uint64_t value, size_t width,
const char* display) {
InstrOperand o;
o.type = InstrOperand::kImmediate;
o.imm.is_signed = false;
o.imm.value = value;
o.imm.width = width;
o.display = display;
operands.push_back(o);
}
int InstrDisasm::Finish() {
for (std::vector<InstrOperand>::iterator it = operands.begin();
it != operands.end(); ++it) {
if (it->type == InstrOperand::kRegister) {
access_bits.MarkAccess(it->reg);
}
}
for (std::vector<InstrRegister>::iterator it = special_registers.begin();
it != special_registers.end(); ++it) {
access_bits.MarkAccess(*it);
}
return 0;
}
@ -405,19 +328,6 @@ void InstrDisasm::Dump(std::string& out_str, size_t pad) {
if (flags & InstrDisasm::kLR) {
out_str += "l";
}
if (operands.size()) {
if (pad && out_str.size() < pad) {
out_str += std::string(pad - out_str.size(), ' ');
}
for (std::vector<InstrOperand>::iterator it = operands.begin();
it != operands.end(); ++it) {
it->Dump(out_str);
if (it + 1 != operands.end()) {
out_str += ", ";
}
}
}
}
@ -480,18 +390,6 @@ InstrType* alloy::frontend::ppc::GetInstrType(uint32_t code) {
return NULL;
}
int alloy::frontend::ppc::RegisterInstrDisassemble(
uint32_t code, InstrDisassembleFn disassemble) {
InstrType* instr_type = GetInstrType(code);
XEASSERTNOTNULL(instr_type);
if (!instr_type) {
return 1;
}
XEASSERTNULL(instr_type->disassemble);
instr_type->disassemble = disassemble;
return 0;
}
int alloy::frontend::ppc::RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
InstrType* instr_type = GetInstrType(code);
XEASSERTNOTNULL(instr_type);

View File

@ -481,9 +481,6 @@ public:
const char* name;
const char* info;
uint32_t flags;
std::vector<InstrOperand> operands;
std::vector<InstrRegister> special_registers;
InstrAccessBits access_bits;
void Init(const char* name, const char* info, uint32_t flags);
void AddLR(InstrRegister::Access access);
@ -500,7 +497,7 @@ public:
};
typedef int (*InstrDisassembleFn)(InstrData& i, InstrDisasm& d);
typedef void (*InstrDisasmFn)(InstrData& i, StringBuffer* str);
typedef void* InstrEmitFn;
@ -511,14 +508,13 @@ public:
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];
InstrDisassembleFn disassemble;
InstrEmitFn emit;
};
InstrType* GetInstrType(uint32_t code);
int RegisterInstrDisassemble(uint32_t code, InstrDisassembleFn disassemble);
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);

View File

@ -16,6 +16,78 @@
namespace alloy {
namespace frontend {
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_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_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_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_cmp(InstrData& i, StringBuffer* str);
void Disasm_cmpi(InstrData& i, StringBuffer* str);
void Disasm_cmpli(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_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);
namespace tables {
@ -51,12 +123,13 @@ static InstrType** instr_table_prep_63(
#define EMPTY(slot) {0}
#define INSTRUCTION(name, opcode, format, type, custom_disasm, descr) { \
#define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) { \
opcode, \
0, \
kXEPPCInstrFormat##format, \
kXEPPCInstrType##type, \
custom_disasm, \
0, \
Disasm_##disasm_fn, \
#name, \
}
#define FLAG(t) kXEPPCInstrFlag##t
@ -72,7 +145,7 @@ static InstrType instr_table_4_unprep[] = {
INSTRUCTION(mfvscr, 0x10000604, VX , General , 0 , "Move from Vector Status and Control Register"),
INSTRUCTION(mtvscr, 0x10000644, VX , General , 0 , "Move to Vector Status and Control Register"),
INSTRUCTION(vaddcuw, 0x10000180, VX , General , 0 , "Vector Add Carryout Unsigned Word"),
INSTRUCTION(vaddfp, 0x1000000A, VX , General , 0 , "Vector Add Floating Point"),
INSTRUCTION(vaddfp, 0x1000000A, VX , General , VX_VD_VA_VB , "Vector Add Floating Point"),
INSTRUCTION(vaddsbs, 0x10000300, VX , General , 0 , "Vector Add Signed Byte Saturate"),
INSTRUCTION(vaddshs, 0x10000340, VX , General , 0 , "Vector Add Signed Half Word Saturate"),
INSTRUCTION(vaddsws, 0x10000380, VX , General , 0 , "Vector Add Signed Word Saturate"),
@ -82,8 +155,8 @@ static InstrType instr_table_4_unprep[] = {
INSTRUCTION(vadduhs, 0x10000240, VX , General , 0 , "Vector Add Unsigned Half Word Saturate"),
INSTRUCTION(vadduwm, 0x10000080, VX , General , 0 , "Vector Add Unsigned Word Modulo"),
INSTRUCTION(vadduws, 0x10000280, VX , General , 0 , "Vector Add Unsigned Word Saturate"),
INSTRUCTION(vand, 0x10000404, VX , General , 0 , "Vector Logical AND"),
INSTRUCTION(vandc, 0x10000444, VX , General , 0 , "Vector Logical AND with Complement"),
INSTRUCTION(vand, 0x10000404, VX , General , VX_VD_VA_VB , "Vector Logical AND"),
INSTRUCTION(vandc, 0x10000444, VX , General , VX_VD_VA_VB , "Vector Logical AND with Complement"),
INSTRUCTION(vavgsb, 0x10000502, VX , General , 0 , "Vector Average Signed Byte"),
INSTRUCTION(vavgsh, 0x10000542, VX , General , 0 , "Vector Average Signed Half Word"),
INSTRUCTION(vavgsw, 0x10000582, VX , General , 0 , "Vector Average Signed Word"),
@ -124,8 +197,8 @@ static InstrType instr_table_4_unprep[] = {
INSTRUCTION(vmulosh, 0x10000148, VX , General , 0 , "Vector Multiply Odd Signed Half Word"),
INSTRUCTION(vmuloub, 0x10000008, VX , General , 0 , "Vector Multiply Odd Unsigned Byte"),
INSTRUCTION(vmulouh, 0x10000048, VX , General , 0 , "Vector Multiply Odd Unsigned Half Word"),
INSTRUCTION(vnor, 0x10000504, VX , General , 0 , "Vector Logical NOR"),
INSTRUCTION(vor, 0x10000484, VX , General , 0 , "Vector Logical OR"),
INSTRUCTION(vnor, 0x10000504, VX , General , VX_VD_VA_VB , "Vector Logical NOR"),
INSTRUCTION(vor, 0x10000484, VX , General , VX_VD_VA_VB , "Vector Logical OR"),
INSTRUCTION(vpkpx, 0x1000030E, VX , General , 0 , "Vector Pack Pixel"),
INSTRUCTION(vpkshss, 0x1000018E, VX , General , 0 , "Vector Pack Signed Half Word Signed Saturate"),
INSTRUCTION(vpkshus, 0x1000010E, VX , General , 0 , "Vector Pack Signed Half Word Unsigned Saturate"),
@ -145,24 +218,24 @@ static InstrType instr_table_4_unprep[] = {
INSTRUCTION(vrlw, 0x10000084, VX , General , 0 , "Vector Rotate Left Integer Word"),
INSTRUCTION(vrsqrtefp, 0x1000014A, VX , General , 0 , "Vector Reciprocal Square Root Estimate Floating Point"),
INSTRUCTION(vsl, 0x100001C4, VX , General , 0 , "Vector Shift Left"),
INSTRUCTION(vslb, 0x10000104, VX , General , 0 , "Vector Shift Left Integer Byte"),
INSTRUCTION(vslb, 0x10000104, VX , General , VX_VD_VA_VB , "Vector Shift Left Integer Byte"),
INSTRUCTION(vslh, 0x10000144, VX , General , 0 , "Vector Shift Left Integer Half Word"),
INSTRUCTION(vslo, 0x1000040C, VX , General , 0 , "Vector Shift Left by Octet"),
INSTRUCTION(vslw, 0x10000184, VX , General , 0 , "Vector Shift Left Integer Word"),
INSTRUCTION(vspltb, 0x1000020C, VX , General , 0 , "Vector Splat Byte"),
INSTRUCTION(vsplth, 0x1000024C, VX , General , 0 , "Vector Splat Half Word"),
INSTRUCTION(vspltisb, 0x1000030C, VX , General , 0 , "Vector Splat Immediate Signed Byte"),
INSTRUCTION(vspltish, 0x1000034C, VX , General , 0 , "Vector Splat Immediate Signed Half Word"),
INSTRUCTION(vspltisw, 0x1000038C, VX , General , 0 , "Vector Splat Immediate Signed Word"),
INSTRUCTION(vspltw, 0x1000028C, VX , General , 0 , "Vector Splat Word"),
INSTRUCTION(vsr, 0x100002C4, VX , General , 0 , "Vector Shift Right"),
INSTRUCTION(vsrab, 0x10000304, VX , General , 0 , "Vector Shift Right Algebraic Byte"),
INSTRUCTION(vsrah, 0x10000344, VX , General , 0 , "Vector Shift Right Algebraic Half Word"),
INSTRUCTION(vsraw, 0x10000384, VX , General , 0 , "Vector Shift Right Algebraic Word"),
INSTRUCTION(vsrb, 0x10000204, VX , General , 0 , "Vector Shift Right Byte"),
INSTRUCTION(vsrh, 0x10000244, VX , General , 0 , "Vector Shift Right Half Word"),
INSTRUCTION(vsro, 0x1000044C, VX , General , 0 , "Vector Shift Right Octet"),
INSTRUCTION(vsrw, 0x10000284, VX , General , 0 , "Vector Shift Right Word"),
INSTRUCTION(vspltb, 0x1000020C, VX , General , vspltb , "Vector Splat Byte"),
INSTRUCTION(vsplth, 0x1000024C, VX , General , vsplth , "Vector Splat Half Word"),
INSTRUCTION(vspltisb, 0x1000030C, VX , General , vspltisb , "Vector Splat Immediate Signed Byte"),
INSTRUCTION(vspltish, 0x1000034C, VX , General , vspltish , "Vector Splat Immediate Signed Half Word"),
INSTRUCTION(vspltisw, 0x1000038C, VX , General , vspltisw , "Vector Splat Immediate Signed Word"),
INSTRUCTION(vspltw, 0x1000028C, VX , General , vspltw , "Vector Splat Word"),
INSTRUCTION(vsr, 0x100002C4, VX , General , VX_VD_VA_VB , "Vector Shift Right"),
INSTRUCTION(vsrab, 0x10000304, VX , General , VX_VD_VA_VB , "Vector Shift Right Algebraic Byte"),
INSTRUCTION(vsrah, 0x10000344, VX , General , VX_VD_VA_VB , "Vector Shift Right Algebraic Half Word"),
INSTRUCTION(vsraw, 0x10000384, VX , General , VX_VD_VA_VB , "Vector Shift Right Algebraic Word"),
INSTRUCTION(vsrb, 0x10000204, VX , General , VX_VD_VA_VB , "Vector Shift Right Byte"),
INSTRUCTION(vsrh, 0x10000244, VX , General , VX_VD_VA_VB , "Vector Shift Right Half Word"),
INSTRUCTION(vsro, 0x1000044C, VX , General , VX_VD_VA_VB , "Vector Shift Right Octet"),
INSTRUCTION(vsrw, 0x10000284, VX , General , VX_VD_VA_VB , "Vector Shift Right Word"),
INSTRUCTION(vsubcuw, 0x10000580, VX , General , 0 , "Vector Subtract Carryout Unsigned Word"),
INSTRUCTION(vsubfp, 0x1000004A, VX , General , 0 , "Vector Subtract Floating Point"),
INSTRUCTION(vsubsbs, 0x10000700, VX , General , 0 , "Vector Subtract Signed Byte Saturate"),
@ -185,7 +258,7 @@ static InstrType instr_table_4_unprep[] = {
INSTRUCTION(vupklpx, 0x100003CE, VX , General , 0 , "Vector Unpack Low Pixel"),
INSTRUCTION(vupklsb, 0x1000028E, VX , General , 0 , "Vector Unpack Low Signed Byte"),
INSTRUCTION(vupklsh, 0x100002CE, VX , General , 0 , "Vector Unpack Low Signed Half Word"),
INSTRUCTION(vxor, 0x100004C4, VX , General , 0 , "Vector Logical XOR"),
INSTRUCTION(vxor, 0x100004C4, VX , General , VX_VD_VA_VB , "Vector Logical XOR"),
};
static InstrType** instr_table_4 = instr_table_prep(
instr_table_4_unprep, XECOUNT(instr_table_4_unprep), 0, 11);
@ -193,7 +266,7 @@ static InstrType** instr_table_4 = instr_table_prep(
// Opcode = 19, index = bits 10-1 (10)
static InstrType instr_table_19_unprep[] = {
INSTRUCTION(mcrf, 0x4C000000, XL , General , 0 , NULL),
INSTRUCTION(bclrx, 0x4C000020, XL , BranchCond , 0 , "Branch Conditional to Link Register"),
INSTRUCTION(bclrx, 0x4C000020, XL , BranchCond , bclrx , "Branch Conditional to Link Register"),
INSTRUCTION(crnor, 0x4C000042, XL , General , 0 , NULL),
INSTRUCTION(crandc, 0x4C000102, XL , General , 0 , NULL),
INSTRUCTION(isync, 0x4C00012C, XL , General , 0 , NULL),
@ -203,7 +276,7 @@ static InstrType instr_table_19_unprep[] = {
INSTRUCTION(creqv, 0x4C000242, XL , General , 0 , NULL),
INSTRUCTION(crorc, 0x4C000342, XL , General , 0 , NULL),
INSTRUCTION(cror, 0x4C000382, XL , General , 0 , NULL),
INSTRUCTION(bcctrx, 0x4C000420, XL , BranchCond , 0 , "Branch Conditional to Count Register"),
INSTRUCTION(bcctrx, 0x4C000420, XL , BranchCond , bcctrx , "Branch Conditional to Count Register"),
};
static InstrType** instr_table_19 = instr_table_prep(
instr_table_19_unprep, XECOUNT(instr_table_19_unprep), 1, 10);
@ -213,7 +286,7 @@ static InstrType instr_table_30_unprep[] = {
// Decoding these instrunctions in this table is difficult because the
// index bits are kind of random. This is special cased by an uber
// instruction handler.
INSTRUCTION(rld, 0x78000000, MD , General , 0 , NULL),
INSTRUCTION(rld, 0x78000000, MD , General , rld , NULL),
// INSTRUCTION(rldiclx, 0x78000000, MD , General , 0),
// INSTRUCTION(rldicrx, 0x78000004, MD , General , 0),
// INSTRUCTION(rldicx, 0x78000008, MD , General , 0),
@ -226,126 +299,126 @@ static InstrType** instr_table_30 = instr_table_prep(
// Opcode = 31, index = bits 10-1 (10)
static InstrType instr_table_31_unprep[] = {
INSTRUCTION(cmp, 0x7C000000, X , General , 0 , "Compare"),
INSTRUCTION(tw, 0x7C000008, X , General , 0 , "Trap Word"),
INSTRUCTION(lvsl, 0x7C00000C, X , General , 0 , "Load Vector for Shift Left"),
INSTRUCTION(cmp, 0x7C000000, X , General , cmp , "Compare"),
INSTRUCTION(tw, 0x7C000008, X , General , X_RA_RB , "Trap Word"),
INSTRUCTION(lvsl, 0x7C00000C, X , General , X_VX_RA0_RB , "Load Vector for Shift Left"),
INSTRUCTION(lvebx, 0x7C00000E, X , General , 0 , "Load Vector Element Byte Indexed"),
INSTRUCTION(subfcx, 0x7C000010, XO , General , 0 , "Subtract From Carrying"),
INSTRUCTION(mulhdux, 0x7C000012, XO , General , 0 , "Multiply High Doubleword Unsigned"),
INSTRUCTION(addcx, 0x7C000014, XO , General , 0 , "Add Carrying"),
INSTRUCTION(mulhwux, 0x7C000016, XO , General , 0 , "Multiply High Word Unsigned"),
INSTRUCTION(mfcr, 0x7C000026, X , General , 0 , "Move From Condition Register"),
INSTRUCTION(lwarx, 0x7C000028, X , General , 0 , "Load Word And Reserve Indexed"),
INSTRUCTION(ldx, 0x7C00002A, X , General , 0 , "Load Doubleword Indexed"),
INSTRUCTION(lwzx, 0x7C00002E, X , General , 0 , "Load Word and Zero Indexed"),
INSTRUCTION(slwx, 0x7C000030, X , General , 0 , "Shift Left Word"),
INSTRUCTION(cntlzwx, 0x7C000034, X , General , 0 , "Count Leading Zeros Word"),
INSTRUCTION(sldx, 0x7C000036, X , General , 0 , "Shift Left Doubleword"),
INSTRUCTION(andx, 0x7C000038, X , General , 0 , "AND"),
INSTRUCTION(cmpl, 0x7C000040, X , General , 0 , "Compare Logical"),
INSTRUCTION(lvsr, 0x7C00004C, X , General , 0 , "Load Vector for Shift Right"),
INSTRUCTION(subfcx, 0x7C000010, XO , General , XO_RT_RA_RB , "Subtract From Carrying"),
INSTRUCTION(mulhdux, 0x7C000012, XO , General , XO_RT_RA_RB , "Multiply High Doubleword Unsigned"),
INSTRUCTION(addcx, 0x7C000014, XO , General , XO_RT_RA_RB , "Add Carrying"),
INSTRUCTION(mulhwux, 0x7C000016, XO , General , XO_RT_RA_RB , "Multiply High Word Unsigned"),
INSTRUCTION(mfcr, 0x7C000026, X , General , mfcr , "Move From Condition Register"),
INSTRUCTION(lwarx, 0x7C000028, X , General , X_RT_RA0_RB , "Load Word And Reserve Indexed"),
INSTRUCTION(ldx, 0x7C00002A, X , General , X_RT_RA0_RB , "Load Doubleword Indexed"),
INSTRUCTION(lwzx, 0x7C00002E, X , General , X_RT_RA0_RB , "Load Word and Zero Indexed"),
INSTRUCTION(slwx, 0x7C000030, X , General , X_RA_RT_RB , "Shift Left Word"),
INSTRUCTION(cntlzwx, 0x7C000034, X , General , X_RA_RT , "Count Leading Zeros Word"),
INSTRUCTION(sldx, 0x7C000036, X , General , X_RA_RT_RB , "Shift Left Doubleword"),
INSTRUCTION(andx, 0x7C000038, X , General , X_RA_RT_RB , "AND"),
INSTRUCTION(cmpl, 0x7C000040, X , General , cmp , "Compare Logical"),
INSTRUCTION(lvsr, 0x7C00004C, X , General , X_VX_RA0_RB , "Load Vector for Shift Right"),
INSTRUCTION(lvehx, 0x7C00004E, X , General , 0 , "Load Vector Element Half Word Indexed"),
INSTRUCTION(subfx, 0x7C000050, XO , General , 0 , "Subtract From"),
INSTRUCTION(ldux, 0x7C00006A, X , General , 0 , "Load Doubleword with Update Indexed"),
INSTRUCTION(subfx, 0x7C000050, XO , General , XO_RT_RA_RB , "Subtract From"),
INSTRUCTION(ldux, 0x7C00006A, X , General , X_RT_RA_RB , "Load Doubleword with Update Indexed"),
INSTRUCTION(dcbst, 0x7C00006C, X , General , 0 , NULL),
INSTRUCTION(lwzux, 0x7C00006E, X , General , 0 , "Load Word and Zero with Update Indexed"),
INSTRUCTION(cntlzdx, 0x7C000074, X , General , 0 , "Count Leading Zeros Doubleword"),
INSTRUCTION(andcx, 0x7C000078, X , General , 0 , "AND with Complement"),
INSTRUCTION(td, 0x7C000088, X , General , 0 , "Trap Doubleword"),
INSTRUCTION(lwzux, 0x7C00006E, X , General , X_RT_RA_RB , "Load Word and Zero with Update Indexed"),
INSTRUCTION(cntlzdx, 0x7C000074, X , General , X_RA_RT , "Count Leading Zeros Doubleword"),
INSTRUCTION(andcx, 0x7C000078, X , General , X_RA_RT_RB , "AND with Complement"),
INSTRUCTION(td, 0x7C000088, X , General , X_RA_RB , "Trap Doubleword"),
INSTRUCTION(lvewx, 0x7C00008E, X , General , 0 , "Load Vector Element Word Indexed"),
INSTRUCTION(mulhdx, 0x7C000092, XO , General , 0 , "Multiply High Doubleword"),
INSTRUCTION(mulhwx, 0x7C000096, XO , General , 0 , "Multiply High Word"),
INSTRUCTION(mfmsr, 0x7C0000A6, X , General , 0 , "Move From Machine State Register"),
INSTRUCTION(ldarx, 0x7C0000A8, X , General , 0 , "Load Doubleword And Reserve Indexed"),
INSTRUCTION(dcbf, 0x7C0000AC, X , General , 0 , "Data Cache Block Flush"),
INSTRUCTION(lbzx, 0x7C0000AE, X , General , 0 , "Load Byte and Zero Indexed"),
INSTRUCTION(lvx, 0x7C0000CE, X , General , 0 , "Load Vector Indexed"),
INSTRUCTION(negx, 0x7C0000D0, XO , General , 0 , "Negate"),
INSTRUCTION(lbzux, 0x7C0000EE, X , General , 0 , "Load Byte and Zero with Update Indexed"),
INSTRUCTION(norx, 0x7C0000F8, X , General , 0 , "NOR"),
INSTRUCTION(mulhdx, 0x7C000092, XO , General , XO_RT_RA_RB , "Multiply High Doubleword"),
INSTRUCTION(mulhwx, 0x7C000096, XO , General , XO_RT_RA_RB , "Multiply High Word"),
INSTRUCTION(mfmsr, 0x7C0000A6, X , General , mfmsr , "Move From Machine State Register"),
INSTRUCTION(ldarx, 0x7C0000A8, X , General , X_RT_RA0_RB , "Load Doubleword And Reserve Indexed"),
INSTRUCTION(dcbf, 0x7C0000AC, X , General , dcbf , "Data Cache Block Flush"),
INSTRUCTION(lbzx, 0x7C0000AE, X , General , X_RT_RA0_RB , "Load Byte and Zero Indexed"),
INSTRUCTION(lvx, 0x7C0000CE, X , General , X_VX_RA0_RB , "Load Vector Indexed"),
INSTRUCTION(negx, 0x7C0000D0, XO , General , XO_RT_RA , "Negate"),
INSTRUCTION(lbzux, 0x7C0000EE, X , General , X_RT_RA_RB , "Load Byte and Zero with Update Indexed"),
INSTRUCTION(norx, 0x7C0000F8, X , General , X_RA_RT_RB , "NOR"),
INSTRUCTION(stvebx, 0x7C00010E, X , General , 0 , "Store Vector Element Byte Indexed"),
INSTRUCTION(subfex, 0x7C000110, XO , General , 0 , "Subtract From Extended"),
INSTRUCTION(addex, 0x7C000114, XO , General , 0 , "Add Extended"),
INSTRUCTION(subfex, 0x7C000110, XO , General , XO_RT_RA_RB , "Subtract From Extended"),
INSTRUCTION(addex, 0x7C000114, XO , General , XO_RT_RA_RB , "Add Extended"),
INSTRUCTION(mtcrf, 0x7C000120, XFX, General , 0 , NULL),
INSTRUCTION(mtmsr, 0x7C000124, X , General , 0 , "Move To Machine State Register"),
INSTRUCTION(stdx, 0x7C00012A, X , General , 0 , "Store Doubleword Indexed"),
INSTRUCTION(stwcx, 0x7C00012D, X , General , 0 , "Store Word Conditional Indexed"),
INSTRUCTION(stwx, 0x7C00012E, X , General , 0 , "Store Word Indexed"),
INSTRUCTION(mtmsr, 0x7C000124, X , General , mtmsr , "Move To Machine State Register"),
INSTRUCTION(stdx, 0x7C00012A, X , General , X_RT_RA0_RB , "Store Doubleword Indexed"),
INSTRUCTION(stwcx, 0x7C00012D, X , General , X_RT_RA0_RB , "Store Word Conditional Indexed"),
INSTRUCTION(stwx, 0x7C00012E, X , General , X_RT_RA0_RB , "Store Word Indexed"),
INSTRUCTION(stvehx, 0x7C00014E, X , General , 0 , "Store Vector Element Half Word Indexed"),
INSTRUCTION(mtmsrd, 0x7C000164, X , General , 0 , "Move To Machine State Register Doubleword"),
INSTRUCTION(stdux, 0x7C00016A, X , General , 0 , "Store Doubleword with Update Indexed"),
INSTRUCTION(stwux, 0x7C00016E, X , General , 0 , "Store Word with Update Indexed"),
INSTRUCTION(mtmsrd, 0x7C000164, X , General , mtmsr , "Move To Machine State Register Doubleword"),
INSTRUCTION(stdux, 0x7C00016A, X , General , X_RT_RA_RB , "Store Doubleword with Update Indexed"),
INSTRUCTION(stwux, 0x7C00016E, X , General , X_RT_RA_RB , "Store Word with Update Indexed"),
INSTRUCTION(stvewx, 0x7C00018E, X , General , 0 , "Store Vector Element Word Indexed"),
INSTRUCTION(subfzex, 0x7C000190, XO , General , 0 , "Subtract From Zero Extended"),
INSTRUCTION(addzex, 0x7C000194, XO , General , 0 , "Add to Zero Extended"),
INSTRUCTION(stdcx, 0x7C0001AD, X , General , 0 , "Store Doubleword Conditional Indexed"),
INSTRUCTION(stbx, 0x7C0001AE, X , General , 0 , "Store Byte Indexed"),
INSTRUCTION(subfzex, 0x7C000190, XO , General , XO_RT_RA , "Subtract From Zero Extended"),
INSTRUCTION(addzex, 0x7C000194, XO , General , XO_RT_RA , "Add to Zero Extended"),
INSTRUCTION(stdcx, 0x7C0001AD, X , General , X_RT_RA0_RB , "Store Doubleword Conditional Indexed"),
INSTRUCTION(stbx, 0x7C0001AE, X , General , X_RT_RA0_RB , "Store Byte Indexed"),
INSTRUCTION(stvx, 0x7C0001CE, X , General , 0 , "Store Vector Indexed"),
INSTRUCTION(subfmex, 0x7C0001D0, XO , General , 0 , "Subtract From Minus One Extended"),
INSTRUCTION(mulldx, 0x7C0001D2, XO , General , 0 , "Multiply Low Doubleword"),
INSTRUCTION(addmex, 0x7C0001D4, XO , General , 0 , "Add to Minus One Extended"),
INSTRUCTION(mullwx, 0x7C0001D6, XO , General , 0 , "Multiply Low Word"),
INSTRUCTION(subfmex, 0x7C0001D0, XO , General , XO_RT_RA , "Subtract From Minus One Extended"),
INSTRUCTION(mulldx, 0x7C0001D2, XO , General , XO_RT_RA_RB , "Multiply Low Doubleword"),
INSTRUCTION(addmex, 0x7C0001D4, XO , General , XO_RT_RA , "Add to Minus One Extended"),
INSTRUCTION(mullwx, 0x7C0001D6, XO , General , XO_RT_RA_RB , "Multiply Low Word"),
INSTRUCTION(dcbtst, 0x7C0001EC, X , General , 0 , "Data Cache Block Touch for Store"),
INSTRUCTION(stbux, 0x7C0001EE, X , General , 0 , "Store Byte with Update Indexed"),
INSTRUCTION(addx, 0x7C000214, XO , General , 0 , "Add"),
INSTRUCTION(stbux, 0x7C0001EE, X , General , X_RT_RA_RB , "Store Byte with Update Indexed"),
INSTRUCTION(addx, 0x7C000214, XO , General , XO_RT_RA_RB , "Add"),
INSTRUCTION(dcbt, 0x7C00022C, X , General , 0 , "Data Cache Block Touch"),
INSTRUCTION(lhzx, 0x7C00022E, X , General , 0 , "Load Halfword and Zero Indexed"),
INSTRUCTION(eqvx, 0x7C000238, X , General , 0 , "Equivalent"),
INSTRUCTION(lhzx, 0x7C00022E, X , General , X_RT_RA0_RB , "Load Halfword and Zero Indexed"),
INSTRUCTION(eqvx, 0x7C000238, X , General , X_RA_RT_RB , "Equivalent"),
INSTRUCTION(eciwx, 0x7C00026C, X , General , 0 , NULL),
INSTRUCTION(lhzux, 0x7C00026E, X , General , 0 , "Load Halfword and Zero with Update Indexed"),
INSTRUCTION(xorx, 0x7C000278, X , General , 0 , "XOR"),
INSTRUCTION(mfspr, 0x7C0002A6, XFX, General , 0 , "Move From Special Purpose Register"),
INSTRUCTION(lwax, 0x7C0002AA, X , General , 0 , "Load Word Algebraic Indexed"),
INSTRUCTION(lhax, 0x7C0002AE, X , General , 0 , "Load Halfword Algebraic Indexed"),
INSTRUCTION(lvxl, 0x7C0002CE, X , General , 0 , "Load Vector Indexed LRU"),
INSTRUCTION(mftb, 0x7C0002E6, XFX, General , 0 , "Move From Time Base"),
INSTRUCTION(lwaux, 0x7C0002EA, X , General , 0 , "Load Word Algebraic with Update Indexed"),
INSTRUCTION(lhzux, 0x7C00026E, X , General , X_RT_RA_RB , "Load Halfword and Zero with Update Indexed"),
INSTRUCTION(xorx, 0x7C000278, X , General , X_RA_RT_RB , "XOR"),
INSTRUCTION(mfspr, 0x7C0002A6, XFX, General , mfspr , "Move From Special Purpose Register"),
INSTRUCTION(lwax, 0x7C0002AA, X , General , X_RT_RA0_RB , "Load Word Algebraic Indexed"),
INSTRUCTION(lhax, 0x7C0002AE, X , General , X_RT_RA0_RB , "Load Halfword Algebraic Indexed"),
INSTRUCTION(lvxl, 0x7C0002CE, X , General , X_VX_RA0_RB , "Load Vector Indexed LRU"),
INSTRUCTION(mftb, 0x7C0002E6, XFX, General , mftb , "Move From Time Base"),
INSTRUCTION(lwaux, 0x7C0002EA, X , General , X_RT_RA_RB , "Load Word Algebraic with Update Indexed"),
INSTRUCTION(lhaux, 0x7C0002EE, X , General , 0 , NULL),
INSTRUCTION(sthx, 0x7C00032E, X , General , 0 , "Store Halfword Indexed"),
INSTRUCTION(orcx, 0x7C000338, X , General , 0 , "OR with Complement"),
INSTRUCTION(sthx, 0x7C00032E, X , General , X_RT_RA0_RB , "Store Halfword Indexed"),
INSTRUCTION(orcx, 0x7C000338, X , General , X_RA_RT_RB , "OR with Complement"),
INSTRUCTION(ecowx, 0x7C00036C, X , General , 0 , NULL),
INSTRUCTION(sthux, 0x7C00036E, X , General , 0 , "Store Halfword with Update Indexed"),
INSTRUCTION(orx, 0x7C000378, X , General , 0 , "OR"),
INSTRUCTION(divdux, 0x7C000392, XO , General , 0 , "Divide Doubleword Unsigned"),
INSTRUCTION(divwux, 0x7C000396, XO , General , 0 , "Divide Word Unsigned"),
INSTRUCTION(mtspr, 0x7C0003A6, XFX, General , 0 , "Move To Special Purpose Register"),
INSTRUCTION(nandx, 0x7C0003B8, X , General , 0 , "NAND"),
INSTRUCTION(sthux, 0x7C00036E, X , General , X_RT_RA_RB , "Store Halfword with Update Indexed"),
INSTRUCTION(orx, 0x7C000378, X , General , X_RA_RT_RB , "OR"),
INSTRUCTION(divdux, 0x7C000392, XO , General , XO_RT_RA_RB , "Divide Doubleword Unsigned"),
INSTRUCTION(divwux, 0x7C000396, XO , General , XO_RT_RA_RB , "Divide Word Unsigned"),
INSTRUCTION(mtspr, 0x7C0003A6, XFX, General , mtspr , "Move To Special Purpose Register"),
INSTRUCTION(nandx, 0x7C0003B8, X , General , X_RA_RT_RB , "NAND"),
INSTRUCTION(stvxl, 0x7C0003CE, X , General , 0 , "Store Vector Indexed LRU"),
INSTRUCTION(divdx, 0x7C0003D2, XO , General , 0 , "Divide Doubleword"),
INSTRUCTION(divwx, 0x7C0003D6, XO , General , 0 , "Divide Word"),
INSTRUCTION(divdx, 0x7C0003D2, XO , General , XO_RT_RA_RB , "Divide Doubleword"),
INSTRUCTION(divwx, 0x7C0003D6, XO , General , XO_RT_RA_RB , "Divide Word"),
INSTRUCTION(lvlx, 0x7C00040E, X , General , 0 , "Load Vector Indexed"),
INSTRUCTION(ldbrx, 0x7C000428, X , General , 0 , "Load Doubleword Byte-Reverse Indexed"),
INSTRUCTION(ldbrx, 0x7C000428, X , General , X_RT_RA0_RB , "Load Doubleword Byte-Reverse Indexed"),
INSTRUCTION(lswx, 0x7C00042A, X , General , 0 , NULL),
INSTRUCTION(lwbrx, 0x7C00042C, X , General , 0 , "Load Word Byte-Reverse Indexed"),
INSTRUCTION(lfsx, 0x7C00042E, X , General , 0 , "Load Floating-Point Single Indexed"),
INSTRUCTION(srwx, 0x7C000430, X , General , 0 , "Shift Right Word"),
INSTRUCTION(srdx, 0x7C000436, X , General , 0 , "Shift Right Doubleword"),
INSTRUCTION(lfsux, 0x7C00046E, X , General , 0 , "Load Floating-Point Single with Update Indexed"),
INSTRUCTION(lwbrx, 0x7C00042C, X , General , X_RT_RA0_RB , "Load Word Byte-Reverse Indexed"),
INSTRUCTION(lfsx, 0x7C00042E, X , General , X_FRT_RA0_RB , "Load Floating-Point Single Indexed"),
INSTRUCTION(srwx, 0x7C000430, X , General , X_RA_RT_RB , "Shift Right Word"),
INSTRUCTION(srdx, 0x7C000436, X , General , X_RA_RT_RB , "Shift Right Doubleword"),
INSTRUCTION(lfsux, 0x7C00046E, X , General , X_FRT_RA_RB , "Load Floating-Point Single with Update Indexed"),
INSTRUCTION(lswi, 0x7C0004AA, X , General , 0 , NULL),
INSTRUCTION(sync, 0x7C0004AC, X , General , 0 , "Synchronize"),
INSTRUCTION(lfdx, 0x7C0004AE, X , General , 0 , "Load Floating-Point Double Indexed"),
INSTRUCTION(lfdux, 0x7C0004EE, X , General , 0 , "Load Floating-Point Double with Update Indexed"),
INSTRUCTION(stdbrx, 0x7C000528, X , General , 0 , "Store Doubleword Byte-Reverse Indexed"),
INSTRUCTION(sync, 0x7C0004AC, X , General , sync , "Synchronize"),
INSTRUCTION(lfdx, 0x7C0004AE, X , General , X_FRT_RA0_RB , "Load Floating-Point Double Indexed"),
INSTRUCTION(lfdux, 0x7C0004EE, X , General , X_FRT_RA_RB , "Load Floating-Point Double with Update Indexed"),
INSTRUCTION(stdbrx, 0x7C000528, X , General , X_RT_RA0_RB , "Store Doubleword Byte-Reverse Indexed"),
INSTRUCTION(stswx, 0x7C00052A, X , General , 0 , NULL),
INSTRUCTION(stwbrx, 0x7C00052C, X , General , 0 , "Store Word Byte-Reverse Indexed"),
INSTRUCTION(stfsx, 0x7C00052E, X , General , 0 , "Store Floating-Point Single Indexed"),
INSTRUCTION(stfsux, 0x7C00056E, X , General , 0 , "Store Floating-Point Single with Update Indexed"),
INSTRUCTION(stwbrx, 0x7C00052C, X , General , X_RT_RA0_RB , "Store Word Byte-Reverse Indexed"),
INSTRUCTION(stfsx, 0x7C00052E, X , General , X_FRT_RA0_RB , "Store Floating-Point Single Indexed"),
INSTRUCTION(stfsux, 0x7C00056E, X , General , X_FRT_RA_RB , "Store Floating-Point Single with Update Indexed"),
INSTRUCTION(stswi, 0x7C0005AA, X , General , 0 , NULL),
INSTRUCTION(stfdx, 0x7C0005AE, X , General , 0 , "Store Floating-Point Double Indexed"),
INSTRUCTION(stfdux, 0x7C0005EE, X , General , 0 , "Store Floating-Point Double with Update Indexed"),
INSTRUCTION(lhbrx, 0x7C00062C, X , General , 0 , "Load Halfword Byte-Reverse Indexed"),
INSTRUCTION(srawx, 0x7C000630, X , General , 0 , "Shift Right Algebraic Word"),
INSTRUCTION(sradx, 0x7C000634, X , General , 0 , "Shift Right Algebraic Doubleword"),
INSTRUCTION(srawix, 0x7C000670, X , General , 0 , "Shift Right Algebraic Word Immediate"),
INSTRUCTION(sradix, 0x7C000674, XS , General , 0 , "Shift Right Algebraic Doubleword Immediate"), // TODO
INSTRUCTION(eieio, 0x7C0006AC, X , General , 0 , "Enforce In-Order Execution of I/O Instruction"),
INSTRUCTION(sthbrx, 0x7C00072C, X , General , 0 , "Store Halfword Byte-Reverse Indexed"),
INSTRUCTION(extshx, 0x7C000734, X , General , 0 , "Extend Sign Halfword"),
INSTRUCTION(extsbx, 0x7C000774, X , General , 0 , "Extend Sign Byte"),
INSTRUCTION(stfdx, 0x7C0005AE, X , General , X_FRT_RA0_RB , "Store Floating-Point Double Indexed"),
INSTRUCTION(stfdux, 0x7C0005EE, X , General , X_FRT_RA_RB , "Store Floating-Point Double with Update Indexed"),
INSTRUCTION(lhbrx, 0x7C00062C, X , General , X_RT_RA0_RB , "Load Halfword Byte-Reverse Indexed"),
INSTRUCTION(srawx, 0x7C000630, X , General , X_RA_RT_RB , "Shift Right Algebraic Word"),
INSTRUCTION(sradx, 0x7C000634, X , General , X_RA_RT_RB , "Shift Right Algebraic Doubleword"),
INSTRUCTION(srawix, 0x7C000670, X , General , srawix , "Shift Right Algebraic Word Immediate"),
INSTRUCTION(sradix, 0x7C000674, XS , General , sradix , "Shift Right Algebraic Doubleword Immediate"), // TODO
INSTRUCTION(eieio, 0x7C0006AC, X , General , _ , "Enforce In-Order Execution of I/O Instruction"),
INSTRUCTION(sthbrx, 0x7C00072C, X , General , X_RT_RA0_RB , "Store Halfword Byte-Reverse Indexed"),
INSTRUCTION(extshx, 0x7C000734, X , General , X_RA_RT , "Extend Sign Halfword"),
INSTRUCTION(extsbx, 0x7C000774, X , General , X_RA_RT , "Extend Sign Byte"),
INSTRUCTION(icbi, 0x7C0007AC, X , General , 0 , NULL),
INSTRUCTION(stfiwx, 0x7C0007AE, X , General , 0 , "Store Floating-Point as Integer Word Indexed"),
INSTRUCTION(extswx, 0x7C0007B4, X , General , 0 , "Extend Sign Word"),
INSTRUCTION(dcbz, 0x7C0007EC, X , General , 0 , "Data Cache Block set to Zero"), // 0x7C2007EC = DCBZ128
INSTRUCTION(stfiwx, 0x7C0007AE, X , General , X_FRT_RA0_RB , "Store Floating-Point as Integer Word Indexed"),
INSTRUCTION(extswx, 0x7C0007B4, X , General , X_RA_RT , "Extend Sign Word"),
INSTRUCTION(dcbz, 0x7C0007EC, X , General , dcbz , "Data Cache Block set to Zero"), // 0x7C2007EC = DCBZ128
INSTRUCTION(dst, 0x7C0002AC, XDSS, General , 0 , NULL),
INSTRUCTION(dstst, 0x7C0002EC, XDSS, General , 0 , NULL),
INSTRUCTION(dss, 0x7C00066C, XDSS, General , 0 , NULL),
@ -359,49 +432,49 @@ static InstrType instr_table_31_unprep[] = {
INSTRUCTION(stvebx, 0x7C00010E, X , General , 0 , "Store Vector Element Byte Indexed"),
INSTRUCTION(stvehx, 0x7C00014E, X , General , 0 , "Store Vector Element Half Word Indexed"),
INSTRUCTION(stvewx, 0x7C00018E, X , General , 0 , "Store Vector Element Word Indexed"),
INSTRUCTION(stvx, 0x7C0001CE, X , General , 0 , "Store Vector Indexed"),
INSTRUCTION(stvxl, 0x7C0003CE, X , General , 0 , "Store Vector Indexed LRU"),
INSTRUCTION(lvlx, 0x7C00040E, X , General , 0 , "Load Vector Left Indexed"),
INSTRUCTION(lvlxl, 0x7C00060E, X , General , 0 , "Load Vector Left Indexed LRU"),
INSTRUCTION(lvrx, 0x7C00044E, X , General , 0 , "Load Vector Right Indexed"),
INSTRUCTION(lvrxl, 0x7C00064E, X , General , 0 , "Load Vector Right Indexed LRU"),
INSTRUCTION(stvlx, 0x7C00050E, X , General , 0 , "Store Vector Left Indexed"),
INSTRUCTION(stvlxl, 0x7C00070E, X , General , 0 , "Store Vector Left Indexed LRU"),
INSTRUCTION(stvrx, 0x7C00054E, X , General , 0 , "Store Vector Right Indexed"),
INSTRUCTION(stvrxl, 0x7C00074E, X , General , 0 , "Store Vector Right Indexed LRU"),
INSTRUCTION(stvx, 0x7C0001CE, X , General , X_VX_RA0_RB , "Store Vector Indexed"),
INSTRUCTION(stvxl, 0x7C0003CE, X , General , X_VX_RA0_RB , "Store Vector Indexed LRU"),
INSTRUCTION(lvlx, 0x7C00040E, X , General , X_VX_RA0_RB , "Load Vector Left Indexed"),
INSTRUCTION(lvlxl, 0x7C00060E, X , General , X_VX_RA0_RB , "Load Vector Left Indexed LRU"),
INSTRUCTION(lvrx, 0x7C00044E, X , General , X_VX_RA0_RB , "Load Vector Right Indexed"),
INSTRUCTION(lvrxl, 0x7C00064E, X , General , X_VX_RA0_RB , "Load Vector Right Indexed LRU"),
INSTRUCTION(stvlx, 0x7C00050E, X , General , X_VX_RA0_RB , "Store Vector Left Indexed"),
INSTRUCTION(stvlxl, 0x7C00070E, X , General , X_VX_RA0_RB , "Store Vector Left Indexed LRU"),
INSTRUCTION(stvrx, 0x7C00054E, X , General , X_VX_RA0_RB , "Store Vector Right Indexed"),
INSTRUCTION(stvrxl, 0x7C00074E, X , General , X_VX_RA0_RB , "Store Vector Right Indexed LRU"),
};
static InstrType** instr_table_31 = instr_table_prep(
instr_table_31_unprep, XECOUNT(instr_table_31_unprep), 1, 10);
// Opcode = 58, index = bits 1-0 (2)
static InstrType instr_table_58_unprep[] = {
INSTRUCTION(ld, 0xE8000000, DS , General , 0 , "Load Doubleword"),
INSTRUCTION(ldu, 0xE8000001, DS , General , 0 , "Load Doubleword with Update"),
INSTRUCTION(lwa, 0xE8000002, DS , General , 0 , "Load Word Algebraic"),
INSTRUCTION(ld, 0xE8000000, DS , General , DS_RT_RA0_I , "Load Doubleword"),
INSTRUCTION(ldu, 0xE8000001, DS , General , DS_RT_RA_I , "Load Doubleword with Update"),
INSTRUCTION(lwa, 0xE8000002, DS , General , DS_RT_RA0_I , "Load Word Algebraic"),
};
static InstrType** instr_table_58 = instr_table_prep(
instr_table_58_unprep, XECOUNT(instr_table_58_unprep), 0, 1);
// Opcode = 59, index = bits 5-1 (5)
static InstrType instr_table_59_unprep[] = {
INSTRUCTION(fdivsx, 0xEC000024, A , General , 0 , "Floating Divide [Single]"),
INSTRUCTION(fsubsx, 0xEC000028, A , General , 0 , "Floating Subtract [Single]"),
INSTRUCTION(faddsx, 0xEC00002A, A , General , 0 , "Floating Add [Single]"),
INSTRUCTION(fsqrtsx, 0xEC00002C, A , General , 0 , "Floating Square Root [Single]"),
INSTRUCTION(fresx, 0xEC000030, A , General , 0 , "Floating Reciprocal Estimate [Single]"),
INSTRUCTION(fmulsx, 0xEC000032, A , General , 0 , "Floating Multiply [Single]"),
INSTRUCTION(fmsubsx, 0xEC000038, A , General , 0 , "Floating Multiply-Subtract [Single]"),
INSTRUCTION(fmaddsx, 0xEC00003A, A , General , 0 , "Floating Multiply-Add [Single]"),
INSTRUCTION(fnmsubsx, 0xEC00003C, A , General , 0 , "Floating Negative Multiply-Subtract [Single]"),
INSTRUCTION(fnmaddsx, 0xEC00003E, A , General , 0 , "Floating Negative Multiply-Add [Single]"),
INSTRUCTION(fdivsx, 0xEC000024, A , General , A_FRT_FRA_FRB , "Floating Divide [Single]"),
INSTRUCTION(fsubsx, 0xEC000028, A , General , A_FRT_FRA_FRB , "Floating Subtract [Single]"),
INSTRUCTION(faddsx, 0xEC00002A, A , General , A_FRT_FRA_FRB , "Floating Add [Single]"),
INSTRUCTION(fsqrtsx, 0xEC00002C, A , General , A_FRT_FRB , "Floating Square Root [Single]"),
INSTRUCTION(fresx, 0xEC000030, A , General , A_FRT_FRB , "Floating Reciprocal Estimate [Single]"),
INSTRUCTION(fmulsx, 0xEC000032, A , General , A_FRT_FRA_FRB , "Floating Multiply [Single]"),
INSTRUCTION(fmsubsx, 0xEC000038, A , General , A_FRT_FRA_FRB_FRC , "Floating Multiply-Subtract [Single]"),
INSTRUCTION(fmaddsx, 0xEC00003A, A , General , A_FRT_FRA_FRB_FRC , "Floating Multiply-Add [Single]"),
INSTRUCTION(fnmsubsx, 0xEC00003C, A , General , A_FRT_FRA_FRB_FRC , "Floating Negative Multiply-Subtract [Single]"),
INSTRUCTION(fnmaddsx, 0xEC00003E, A , General , A_FRT_FRA_FRB_FRC , "Floating Negative Multiply-Add [Single]"),
};
static InstrType** instr_table_59 = instr_table_prep(
instr_table_59_unprep, XECOUNT(instr_table_59_unprep), 1, 5);
// Opcode = 62, index = bits 1-0 (2)
static InstrType instr_table_62_unprep[] = {
INSTRUCTION(std, 0xF8000000, DS , General , 0 , "Store Doubleword"),
INSTRUCTION(stdu, 0xF8000001, DS , General , 0 , "Store Doubleword with Update"),
INSTRUCTION(std, 0xF8000000, DS , General , DS_RT_RA0_I , "Store Doubleword"),
INSTRUCTION(stdu, 0xF8000001, DS , General , DS_RT_RA_I , "Store Doubleword with Update"),
};
static InstrType** instr_table_62 = instr_table_prep(
instr_table_62_unprep, XECOUNT(instr_table_62_unprep), 0, 1);
@ -410,87 +483,87 @@ static InstrType** instr_table_62 = instr_table_prep(
// NOTE: the A format instructions need some special handling because
// they only use 6bits to identify their index.
static InstrType instr_table_63_unprep[] = {
INSTRUCTION(fcmpu, 0xFC000000, X , General , 0 , "Floating Compare Unordered"),
INSTRUCTION(frspx, 0xFC000018, X , General , 0 , "Floating Round to Single-Precision"),
INSTRUCTION(fctiwx, 0xFC00001C, X , General , 0 , "Floating Convert To Integer Word"),
INSTRUCTION(fctiwzx, 0xFC00001E, X , General , 0 , "Floating Convert To Integer Word with round toward Zero"),
INSTRUCTION(fdivx, 0xFC000024, A , General , 0 , "Floating Divide [Single]"),
INSTRUCTION(fsubx, 0xFC000028, A , General , 0 , "Floating Subtract [Single]"),
INSTRUCTION(faddx, 0xFC00002A, A , General , 0 , "Floating Add [Single]"),
INSTRUCTION(fsqrtx, 0xFC00002C, A , General , 0 , "Floating Square Root [Single]"),
INSTRUCTION(fselx, 0xFC00002E, A , General , 0 , "Floating Select"),
INSTRUCTION(fmulx, 0xFC000032, A , General , 0 , "Floating Multiply [Single]"),
INSTRUCTION(frsqrtex, 0xFC000034, A , General , 0 , "Floating Reciprocal Square Root Estimate [Single]"),
INSTRUCTION(fcmpu, 0xFC000000, X , General , fcmp , "Floating Compare Unordered"),
INSTRUCTION(frspx, 0xFC000018, X , General , X_FRT_FRB , "Floating Round to Single-Precision"),
INSTRUCTION(fctiwx, 0xFC00001C, X , General , X_FRT_FRB , "Floating Convert To Integer Word"),
INSTRUCTION(fctiwzx, 0xFC00001E, X , General , X_FRT_FRB , "Floating Convert To Integer Word with round toward Zero"),
INSTRUCTION(fdivx, 0xFC000024, A , General , A_FRT_FRA_FRB , "Floating Divide [Single]"),
INSTRUCTION(fsubx, 0xFC000028, A , General , A_FRT_FRA_FRB , "Floating Subtract [Single]"),
INSTRUCTION(faddx, 0xFC00002A, A , General , A_FRT_FRA_FRB , "Floating Add [Single]"),
INSTRUCTION(fsqrtx, 0xFC00002C, A , General , A_FRT_FRB , "Floating Square Root [Single]"),
INSTRUCTION(fselx, 0xFC00002E, A , General , A_FRT_FRA_FRB_FRC , "Floating Select"),
INSTRUCTION(fmulx, 0xFC000032, A , General , A_FRT_FRA_FRB , "Floating Multiply [Single]"),
INSTRUCTION(frsqrtex, 0xFC000034, A , General , A_FRT_FRB , "Floating Reciprocal Square Root Estimate [Single]"),
INSTRUCTION(fmsubx, 0xFC000038, A , General , 0 , "Floating Multiply-Subtract [Single]"),
INSTRUCTION(fmaddx, 0xFC00003A, A , General , 0 , "Floating Multiply-Add [Single]"),
INSTRUCTION(fnmsubx, 0xFC00003C, A , General , 0 , "Floating Negative Multiply-Subtract [Single]"),
INSTRUCTION(fnmaddx, 0xFC00003E, A , General , 0 , "Floating Negative Multiply-Add [Single]"),
INSTRUCTION(fcmpo, 0xFC000040, X , General , 0 , "Floating Compare Ordered"),
INSTRUCTION(fmaddx, 0xFC00003A, A , General , A_FRT_FRA_FRB_FRC , "Floating Multiply-Add [Single]"),
INSTRUCTION(fnmsubx, 0xFC00003C, A , General , A_FRT_FRA_FRB_FRC , "Floating Negative Multiply-Subtract [Single]"),
INSTRUCTION(fnmaddx, 0xFC00003E, A , General , A_FRT_FRA_FRB_FRC , "Floating Negative Multiply-Add [Single]"),
INSTRUCTION(fcmpo, 0xFC000040, X , General , fcmp , "Floating Compare Ordered"),
INSTRUCTION(mtfsb1x, 0xFC00004C, X , General , 0 , NULL),
INSTRUCTION(fnegx, 0xFC000050, X , General , 0 , "Floating Negate"),
INSTRUCTION(fnegx, 0xFC000050, X , General , X_FRT_FRB , "Floating Negate"),
INSTRUCTION(mcrfs, 0xFC000080, X , General , 0 , NULL),
INSTRUCTION(mtfsb0x, 0xFC00008C, X , General , 0 , NULL),
INSTRUCTION(fmrx, 0xFC000090, X , General , 0 , "Floating Move Register"),
INSTRUCTION(fmrx, 0xFC000090, X , General , X_FRT_FRB , "Floating Move Register"),
INSTRUCTION(mtfsfix, 0xFC00010C, X , General , 0 , NULL),
INSTRUCTION(fnabsx, 0xFC000110, X , General , 0 , "Floating Negative Absolute Value"),
INSTRUCTION(fabsx, 0xFC000210, X , General , 0 , "Floating Absolute Value"),
INSTRUCTION(fnabsx, 0xFC000110, X , General , X_FRT_FRB , "Floating Negative Absolute Value"),
INSTRUCTION(fabsx, 0xFC000210, X , General , X_FRT_FRB , "Floating Absolute Value"),
INSTRUCTION(mffsx, 0xFC00048E, X , General , 0 , "Move from FPSCR"),
INSTRUCTION(mtfsfx, 0xFC00058E, XFL, General , 0 , "Move to FPSCR Fields"),
INSTRUCTION(fctidx, 0xFC00065C, X , General , 0 , "Floating Convert To Integer Doubleword"),
INSTRUCTION(fctidzx, 0xFC00065E, X , General , 0 , "Floating Convert To Integer Doubleword with round toward Zero"),
INSTRUCTION(fcfidx, 0xFC00069C, X , General , 0 , "Floating Convert From Integer Doubleword"),
INSTRUCTION(fctidx, 0xFC00065C, X , General , X_FRT_FRB , "Floating Convert To Integer Doubleword"),
INSTRUCTION(fctidzx, 0xFC00065E, X , General , X_FRT_FRB , "Floating Convert To Integer Doubleword with round toward Zero"),
INSTRUCTION(fcfidx, 0xFC00069C, X , General , X_FRT_FRB , "Floating Convert From Integer Doubleword"),
};
static InstrType** instr_table_63 = instr_table_prep_63(
instr_table_63_unprep, XECOUNT(instr_table_63_unprep), 1, 10);
// Main table, index = bits 31-26 (6) : (code >> 26)
static InstrType instr_table_unprep[64] = {
INSTRUCTION(tdi, 0x08000000, D , General , 0 , "Trap Doubleword Immediate"),
INSTRUCTION(twi, 0x0C000000, D , General , 0 , "Trap Word Immediate"),
INSTRUCTION(mulli, 0x1C000000, D , General , 0 , "Multiply Low Immediate"),
INSTRUCTION(subficx, 0x20000000, D , General , 0 , "Subtract From Immediate Carrying"),
INSTRUCTION(cmpli, 0x28000000, D , General , 0 , "Compare Logical Immediate"),
INSTRUCTION(cmpi, 0x2C000000, D , General , 0 , "Compare Immediate"),
INSTRUCTION(addic, 0x30000000, D , General , 0 , "Add Immediate Carrying"),
INSTRUCTION(addicx, 0x34000000, D , General , 0 , "Add Immediate Carrying and Record"),
INSTRUCTION(addi, 0x38000000, D , General , 0 , "Add Immediate"),
INSTRUCTION(addis, 0x3C000000, D , General , 0 , "Add Immediate Shifted"),
INSTRUCTION(bcx, 0x40000000, B , BranchCond , 0 , "Branch Conditional"),
INSTRUCTION(tdi, 0x08000000, D , General , D_RA , "Trap Doubleword Immediate"),
INSTRUCTION(twi, 0x0C000000, D , General , D_RA , "Trap Word Immediate"),
INSTRUCTION(mulli, 0x1C000000, D , General , D_RT_RA_I , "Multiply Low Immediate"),
INSTRUCTION(subficx, 0x20000000, D , General , D_RT_RA_I , "Subtract From Immediate Carrying"),
INSTRUCTION(cmpli, 0x28000000, D , General , cmpli , "Compare Logical Immediate"),
INSTRUCTION(cmpi, 0x2C000000, D , General , cmpi , "Compare Immediate"),
INSTRUCTION(addic, 0x30000000, D , General , D_RT_RA_I , "Add Immediate Carrying"),
INSTRUCTION(addicx, 0x34000000, D , General , D_RT_RA_I , "Add Immediate Carrying and Record"),
INSTRUCTION(addi, 0x38000000, D , General , D_RT_RA0_I , "Add Immediate"),
INSTRUCTION(addis, 0x3C000000, D , General , D_RT_RA0_I , "Add Immediate Shifted"),
INSTRUCTION(bcx, 0x40000000, B , BranchCond , bcx , "Branch Conditional"),
INSTRUCTION(sc, 0x44000002, SC , Syscall , 0 , NULL),
INSTRUCTION(bx, 0x48000000, I , BranchAlways , 0 , "Branch"),
INSTRUCTION(rlwimix, 0x50000000, M , General , 0 , "Rotate Left Word Immediate then Mask Insert"),
INSTRUCTION(rlwinmx, 0x54000000, M , General , 0 , "Rotate Left Word Immediate then AND with Mask"),
INSTRUCTION(rlwnmx, 0x5C000000, M , General , 0 , "Rotate Left Word then AND with Mask"),
INSTRUCTION(ori, 0x60000000, D , General , 0 , "OR Immediate"),
INSTRUCTION(oris, 0x64000000, D , General , 0 , "OR Immediate Shifted"),
INSTRUCTION(xori, 0x68000000, D , General , 0 , "XOR Immediate"),
INSTRUCTION(xoris, 0x6C000000, D , General , 0 , "XOR Immediate Shifted"),
INSTRUCTION(andix, 0x70000000, D , General , 0 , "AND Immediate"),
INSTRUCTION(andisx, 0x74000000, D , General , 0 , "AND Immediate Shifted"),
INSTRUCTION(lwz, 0x80000000, D , General , 0 , "Load Word and Zero"),
INSTRUCTION(lwzu, 0x84000000, D , General , 0 , "Load Word and Zero with Udpate"),
INSTRUCTION(lbz, 0x88000000, D , General , 0 , "Load Byte and Zero"),
INSTRUCTION(lbzu, 0x8C000000, D , General , 0 , "Load Byte and Zero with Update"),
INSTRUCTION(stw, 0x90000000, D , General , 0 , "Store Word"),
INSTRUCTION(stwu, 0x94000000, D , General , 0 , "Store Word with Update"),
INSTRUCTION(stb, 0x98000000, D , General , 0 , "Store Byte"),
INSTRUCTION(stbu, 0x9C000000, D , General , 0 , "Store Byte with Update"),
INSTRUCTION(lhz, 0xA0000000, D , General , 0 , "Load Halfword and Zero"),
INSTRUCTION(lhzu, 0xA4000000, D , General , 0 , "Load Halfword and Zero with Update"),
INSTRUCTION(lha, 0xA8000000, D , General , 0 , "Load Halfword Algebraic"),
INSTRUCTION(lhau, 0xAC000000, D , General , 0 , NULL),
INSTRUCTION(sth, 0xB0000000, D , General , 0 , "Store Halfword"),
INSTRUCTION(sthu, 0xB4000000, D , General , 0 , "Store Halfword with Update"),
INSTRUCTION(bx, 0x48000000, I , BranchAlways , bx , "Branch"),
INSTRUCTION(rlwimix, 0x50000000, M , General , rlwim , "Rotate Left Word Immediate then Mask Insert"),
INSTRUCTION(rlwinmx, 0x54000000, M , General , rlwim , "Rotate Left Word Immediate then AND with Mask"),
INSTRUCTION(rlwnmx, 0x5C000000, M , General , rlwnmx , "Rotate Left Word then AND with Mask"),
INSTRUCTION(ori, 0x60000000, D , General , D_RA_RT_I , "OR Immediate"),
INSTRUCTION(oris, 0x64000000, D , General , D_RA_RT_I , "OR Immediate Shifted"),
INSTRUCTION(xori, 0x68000000, D , General , D_RA_RT_I , "XOR Immediate"),
INSTRUCTION(xoris, 0x6C000000, D , General , D_RA_RT_I , "XOR Immediate Shifted"),
INSTRUCTION(andix, 0x70000000, D , General , D_RA_RT_I , "AND Immediate"),
INSTRUCTION(andisx, 0x74000000, D , General , D_RA_RT_I , "AND Immediate Shifted"),
INSTRUCTION(lwz, 0x80000000, D , General , D_RT_RA0_I , "Load Word and Zero"),
INSTRUCTION(lwzu, 0x84000000, D , General , D_RT_RA_I , "Load Word and Zero with Udpate"),
INSTRUCTION(lbz, 0x88000000, D , General , D_RT_RA0_I , "Load Byte and Zero"),
INSTRUCTION(lbzu, 0x8C000000, D , General , D_RT_RA_I , "Load Byte and Zero with Update"),
INSTRUCTION(stw, 0x90000000, D , General , D_RT_RA0_I , "Store Word"),
INSTRUCTION(stwu, 0x94000000, D , General , D_RT_RA_I , "Store Word with Update"),
INSTRUCTION(stb, 0x98000000, D , General , D_RT_RA0_I , "Store Byte"),
INSTRUCTION(stbu, 0x9C000000, D , General , D_RT_RA_I , "Store Byte with Update"),
INSTRUCTION(lhz, 0xA0000000, D , General , D_RT_RA0_I , "Load Halfword and Zero"),
INSTRUCTION(lhzu, 0xA4000000, D , General , D_RT_RA_I , "Load Halfword and Zero with Update"),
INSTRUCTION(lha, 0xA8000000, D , General , D_RT_RA0_I , "Load Halfword Algebraic"),
INSTRUCTION(lhau, 0xAC000000, D , General , D_RT_RA_I , NULL),
INSTRUCTION(sth, 0xB0000000, D , General , D_RT_RA0_I , "Store Halfword"),
INSTRUCTION(sthu, 0xB4000000, D , General , D_RT_RA_I , "Store Halfword with Update"),
INSTRUCTION(lmw, 0xB8000000, D , General , 0 , NULL),
INSTRUCTION(stmw, 0xBC000000, D , General , 0 , NULL),
INSTRUCTION(lfs, 0xC0000000, D , General , 0 , "Load Floating-Point Single"),
INSTRUCTION(lfsu, 0xC4000000, D , General , 0 , "Load Floating-Point Single with Update"),
INSTRUCTION(lfd, 0xC8000000, D , General , 0 , "Load Floating-Point Double"),
INSTRUCTION(lfdu, 0xCC000000, D , General , 0 , "Load Floating-Point Double with Update"),
INSTRUCTION(stfs, 0xD0000000, D , General , 0 , "Store Floating-Point Single"),
INSTRUCTION(stfsu, 0xD4000000, D , General , 0 , "Store Floating-Point Single with Update"),
INSTRUCTION(stfd, 0xD8000000, D , General , 0 , "Store Floating-Point Double"),
INSTRUCTION(stfdu, 0xDC000000, D , General , 0 , "Store Floating-Point Double with Update"),
INSTRUCTION(lfs, 0xC0000000, D , General , D_FRT_RA0_I , "Load Floating-Point Single"),
INSTRUCTION(lfsu, 0xC4000000, D , General , D_FRT_RA_I , "Load Floating-Point Single with Update"),
INSTRUCTION(lfd, 0xC8000000, D , General , D_FRT_RA0_I , "Load Floating-Point Double"),
INSTRUCTION(lfdu, 0xCC000000, D , General , D_FRT_RA_I , "Load Floating-Point Double with Update"),
INSTRUCTION(stfs, 0xD0000000, D , General , D_FRT_RA0_I , "Store Floating-Point Single"),
INSTRUCTION(stfsu, 0xD4000000, D , General , D_FRT_RA_I , "Store Floating-Point Single with Update"),
INSTRUCTION(stfd, 0xD8000000, D , General , D_FRT_RA0_I , "Store Floating-Point Double"),
INSTRUCTION(stfdu, 0xDC000000, D , General , D_FRT_RA_I , "Store Floating-Point Double with Update"),
};
static InstrType** instr_table = instr_table_prep(
instr_table_unprep, XECOUNT(instr_table_unprep), 26, 31);
@ -498,12 +571,13 @@ static InstrType** instr_table = instr_table_prep(
// Altivec instructions.
// TODO(benvanik): build a table like the other instructions.
// This table is looked up via linear scan of opcodes.
#define SCAN_INSTRUCTION(name, opcode, format, type, custom_disasm, descr) { \
#define SCAN_INSTRUCTION(name, opcode, format, type, disasm_fn, descr) { \
opcode, \
kXEPPCInstrMask##format, \
kXEPPCInstrFormat##format, \
kXEPPCInstrType##type, \
custom_disasm, \
0, \
Disasm_##disasm_fn, \
#name, \
}
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
@ -529,93 +603,93 @@ static InstrType instr_table_scan[] = {
SCAN_INSTRUCTION(vcmpgtub, 0x10000206, VXR , General , 0 , "Vector Compare Greater-Than Unsigned Byte"),
SCAN_INSTRUCTION(vcmpgtuh, 0x10000246, VXR , General , 0 , "Vector Compare Greater-Than Unsigned Half Word"),
SCAN_INSTRUCTION(vcmpgtuw, 0x10000286, VXR , General , 0 , "Vector Compare Greater-Than Unsigned Word"),
SCAN_INSTRUCTION(vmaddfp, 0x1000002E, VXA , General , 0 , "Vector Multiply-Add Floating Point"),
SCAN_INSTRUCTION(vmhaddshs, 0x10000020, VXA , General , 0 , "Vector Multiply-High and Add Signed Signed Half Word Saturate"),
SCAN_INSTRUCTION(vmhraddshs, 0x10000021, VXA , General , 0 , "Vector Multiply-High Round and Add Signed Signed Half Word Saturate"),
SCAN_INSTRUCTION(vmladduhm, 0x10000022, VXA , General , 0 , "Vector Multiply-Low and Add Unsigned Half Word Modulo"),
SCAN_INSTRUCTION(vmsummbm, 0x10000025, VXA , General , 0 , "Vector Multiply-Sum Mixed-Sign Byte Modulo"),
SCAN_INSTRUCTION(vmsumshm, 0x10000028, VXA , General , 0 , "Vector Multiply-Sum Signed Half Word Modulo"),
SCAN_INSTRUCTION(vmsumshs, 0x10000029, VXA , General , 0 , "Vector Multiply-Sum Signed Half Word Saturate"),
SCAN_INSTRUCTION(vmsumubm, 0x10000024, VXA , General , 0 , "Vector Multiply-Sum Unsigned Byte Modulo"),
SCAN_INSTRUCTION(vmsumuhm, 0x10000026, VXA , General , 0 , "Vector Multiply-Sum Unsigned Half Word Modulo"),
SCAN_INSTRUCTION(vmsumuhs, 0x10000027, VXA , General , 0 , "Vector Multiply-Sum Unsigned Half Word Saturate"),
SCAN_INSTRUCTION(vnmsubfp, 0x1000002F, VXA , General , 0 , "Vector Negative Multiply-Subtract Floating Point"),
SCAN_INSTRUCTION(vperm, 0x1000002B, VXA , General , 0 , "Vector Permute"),
SCAN_INSTRUCTION(vsel, 0x1000002A, VXA , General , 0 , "Vector Conditional Select"),
SCAN_INSTRUCTION(vsldoi, 0x1000002C, VXA , General , 0 , "Vector Shift Left Double by Octet Immediate"),
SCAN_INSTRUCTION(lvsl128, VX128_1(4, 3), VX128_1 , General , 0 , "Load Vector128 for Shift Left"),
SCAN_INSTRUCTION(lvsr128, VX128_1(4, 67), VX128_1 , General , 0 , "Load Vector128 for Shift Right"),
SCAN_INSTRUCTION(lvewx128, VX128_1(4, 131), VX128_1 , General , 0 , "Load Vector128 Element Word Indexed"),
SCAN_INSTRUCTION(lvx128, VX128_1(4, 195), VX128_1 , General , 0 , "Load Vector128 Indexed"),
SCAN_INSTRUCTION(stvewx128, VX128_1(4, 387), VX128_1 , General , 0 , "Store Vector128 Element Word Indexed"),
SCAN_INSTRUCTION(stvx128, VX128_1(4, 451), VX128_1 , General , 0 , "Store Vector128 Indexed"),
SCAN_INSTRUCTION(lvxl128, VX128_1(4, 707), VX128_1 , General , 0 , "Load Vector128 Left Indexed"),
SCAN_INSTRUCTION(stvxl128, VX128_1(4, 963), VX128_1 , General , 0 , "Store Vector128 Indexed LRU"),
SCAN_INSTRUCTION(lvlx128, VX128_1(4, 1027), VX128_1 , General , 0 , "Load Vector128 Left Indexed LRU"),
SCAN_INSTRUCTION(lvrx128, VX128_1(4, 1091), VX128_1 , General , 0 , "Load Vector128 Right Indexed"),
SCAN_INSTRUCTION(stvlx128, VX128_1(4, 1283), VX128_1 , General , 0 , "Store Vector128 Left Indexed"),
SCAN_INSTRUCTION(stvrx128, VX128_1(4, 1347), VX128_1 , General , 0 , "Store Vector128 Right Indexed"),
SCAN_INSTRUCTION(lvlxl128, VX128_1(4, 1539), VX128_1 , General , 0 , "Load Vector128 Indexed LRU"),
SCAN_INSTRUCTION(lvrxl128, VX128_1(4, 1603), VX128_1 , General , 0 , "Load Vector128 Right Indexed LRU"),
SCAN_INSTRUCTION(stvlxl128, VX128_1(4, 1795), VX128_1 , General , 0 , "Store Vector128 Left Indexed LRU"),
SCAN_INSTRUCTION(stvrxl128, VX128_1(4, 1859), VX128_1 , General , 0 , "Store Vector128 Right Indexed LRU"),
SCAN_INSTRUCTION(vsldoi128, VX128_5(4, 16), VX128_5 , General , 0 , "Vector128 Shift Left Double by Octet Immediate"),
SCAN_INSTRUCTION(vperm128, VX128_2(5, 0), VX128_2 , General , 0 , "Vector128 Permute"),
SCAN_INSTRUCTION(vaddfp128, VX128(5, 16), VX128 , General , 0 , "Vector128 Add Floating Point"),
SCAN_INSTRUCTION(vsubfp128, VX128(5, 80), VX128 , General , 0 , "Vector128 Subtract Floating Point"),
SCAN_INSTRUCTION(vmulfp128, VX128(5, 144), VX128 , General , 0 , "Vector128 Multiply Floating-Point"),
SCAN_INSTRUCTION(vmaddfp128, VX128(5, 208), VX128 , General , 0 , "Vector128 Multiply Add Floating Point"),
SCAN_INSTRUCTION(vmaddcfp128, VX128(5, 272), VX128 , General , 0 , "Vector128 Multiply Add Floating Point"),
SCAN_INSTRUCTION(vnmsubfp128, VX128(5, 336), VX128 , General , 0 , "Vector128 Negative Multiply-Subtract Floating Point"),
SCAN_INSTRUCTION(vmsum3fp128, VX128(5, 400), VX128 , General , 0 , "Vector128 Multiply Sum 3-way Floating Point"),
SCAN_INSTRUCTION(vmsum4fp128, VX128(5, 464), VX128 , General , 0 , "Vector128 Multiply Sum 4-way Floating-Point"),
SCAN_INSTRUCTION(vmaddfp, 0x1000002E, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Add Floating Point"),
SCAN_INSTRUCTION(vmhaddshs, 0x10000020, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-High and Add Signed Signed Half Word Saturate"),
SCAN_INSTRUCTION(vmhraddshs, 0x10000021, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-High Round and Add Signed Signed Half Word Saturate"),
SCAN_INSTRUCTION(vmladduhm, 0x10000022, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Low and Add Unsigned Half Word Modulo"),
SCAN_INSTRUCTION(vmsummbm, 0x10000025, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Mixed-Sign Byte Modulo"),
SCAN_INSTRUCTION(vmsumshm, 0x10000028, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Signed Half Word Modulo"),
SCAN_INSTRUCTION(vmsumshs, 0x10000029, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Signed Half Word Saturate"),
SCAN_INSTRUCTION(vmsumubm, 0x10000024, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Unsigned Byte Modulo"),
SCAN_INSTRUCTION(vmsumuhm, 0x10000026, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Unsigned Half Word Modulo"),
SCAN_INSTRUCTION(vmsumuhs, 0x10000027, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Unsigned Half Word Saturate"),
SCAN_INSTRUCTION(vnmsubfp, 0x1000002F, VXA , General , VXA_VD_VA_VB_VC , "Vector Negative Multiply-Subtract Floating Point"),
SCAN_INSTRUCTION(vperm, 0x1000002B, VXA , General , VXA_VD_VA_VB_VC , "Vector Permute"),
SCAN_INSTRUCTION(vsel, 0x1000002A, VXA , General , VXA_VD_VA_VB_VC , "Vector Conditional Select"),
SCAN_INSTRUCTION(vsldoi, 0x1000002C, VXA , General , VXA_VD_VA_VB_VC , "Vector Shift Left Double by Octet Immediate"),
SCAN_INSTRUCTION(lvsl128, VX128_1(4, 3), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 for Shift Left"),
SCAN_INSTRUCTION(lvsr128, VX128_1(4, 67), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 for Shift Right"),
SCAN_INSTRUCTION(lvewx128, VX128_1(4, 131), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Element Word Indexed"),
SCAN_INSTRUCTION(lvx128, VX128_1(4, 195), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Indexed"),
SCAN_INSTRUCTION(stvewx128, VX128_1(4, 387), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Element Word Indexed"),
SCAN_INSTRUCTION(stvx128, VX128_1(4, 451), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Indexed"),
SCAN_INSTRUCTION(lvxl128, VX128_1(4, 707), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Left Indexed"),
SCAN_INSTRUCTION(stvxl128, VX128_1(4, 963), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Indexed LRU"),
SCAN_INSTRUCTION(lvlx128, VX128_1(4, 1027), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Left Indexed LRU"),
SCAN_INSTRUCTION(lvrx128, VX128_1(4, 1091), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Right Indexed"),
SCAN_INSTRUCTION(stvlx128, VX128_1(4, 1283), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Left Indexed"),
SCAN_INSTRUCTION(stvrx128, VX128_1(4, 1347), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Right Indexed"),
SCAN_INSTRUCTION(lvlxl128, VX128_1(4, 1539), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Indexed LRU"),
SCAN_INSTRUCTION(lvrxl128, VX128_1(4, 1603), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Right Indexed LRU"),
SCAN_INSTRUCTION(stvlxl128, VX128_1(4, 1795), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Left Indexed LRU"),
SCAN_INSTRUCTION(stvrxl128, VX128_1(4, 1859), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Right Indexed LRU"),
SCAN_INSTRUCTION(vsldoi128, VX128_5(4, 16), VX128_5 , General , vsldoi128 , "Vector128 Shift Left Double by Octet Immediate"),
SCAN_INSTRUCTION(vperm128, VX128_2(5, 0), VX128_2 , General , VX1282_VD_VA_VB_VC, "Vector128 Permute"),
SCAN_INSTRUCTION(vaddfp128, VX128(5, 16), VX128 , General , VX128_VD_VA_VB , "Vector128 Add Floating Point"),
SCAN_INSTRUCTION(vsubfp128, VX128(5, 80), VX128 , General , VX128_VD_VA_VB , "Vector128 Subtract Floating Point"),
SCAN_INSTRUCTION(vmulfp128, VX128(5, 144), VX128 , General , VX128_VD_VA_VB , "Vector128 Multiply Floating-Point"),
SCAN_INSTRUCTION(vmaddfp128, VX128(5, 208), VX128 , General , VX128_VD_VA_VD_VB, "Vector128 Multiply Add Floating Point"),
SCAN_INSTRUCTION(vmaddcfp128, VX128(5, 272), VX128 , General , VX128_VD_VA_VD_VB, "Vector128 Multiply Add Floating Point"),
SCAN_INSTRUCTION(vnmsubfp128, VX128(5, 336), VX128 , General , VX128_VD_VA_VB , "Vector128 Negative Multiply-Subtract Floating Point"),
SCAN_INSTRUCTION(vmsum3fp128, VX128(5, 400), VX128 , General , VX128_VD_VA_VB , "Vector128 Multiply Sum 3-way Floating Point"),
SCAN_INSTRUCTION(vmsum4fp128, VX128(5, 464), VX128 , General , VX128_VD_VA_VB , "Vector128 Multiply Sum 4-way Floating-Point"),
SCAN_INSTRUCTION(vpkshss128, VX128(5, 512), VX128 , General , 0 , "Vector128 Pack Signed Half Word Signed Saturate"),
SCAN_INSTRUCTION(vand128, VX128(5, 528), VX128 , General , 0 , "Vector128 Logical AND"),
SCAN_INSTRUCTION(vand128, VX128(5, 528), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical AND"),
SCAN_INSTRUCTION(vpkshus128, VX128(5, 576), VX128 , General , 0 , "Vector128 Pack Signed Half Word Unsigned Saturate"),
SCAN_INSTRUCTION(vandc128, VX128(5, 592), VX128 , General , 0 , "Vector128 Logical AND with Complement"),
SCAN_INSTRUCTION(vandc128, VX128(5, 592), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical AND with Complement"),
SCAN_INSTRUCTION(vpkswss128, VX128(5, 640), VX128 , General , 0 , "Vector128 Pack Signed Word Signed Saturate"),
SCAN_INSTRUCTION(vnor128, VX128(5, 656), VX128 , General , 0 , "Vector128 Logical NOR"),
SCAN_INSTRUCTION(vnor128, VX128(5, 656), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical NOR"),
SCAN_INSTRUCTION(vpkswus128, VX128(5, 704), VX128 , General , 0 , "Vector128 Pack Signed Word Unsigned Saturate"),
SCAN_INSTRUCTION(vor128, VX128(5, 720), VX128 , General , 0 , "Vector128 Logical OR"),
SCAN_INSTRUCTION(vor128, VX128(5, 720), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical OR"),
SCAN_INSTRUCTION(vpkuhum128, VX128(5, 768), VX128 , General , 0 , "Vector128 Pack Unsigned Half Word Unsigned Modulo"),
SCAN_INSTRUCTION(vxor128, VX128(5, 784), VX128 , General , 0 , "Vector128 Logical XOR"),
SCAN_INSTRUCTION(vxor128, VX128(5, 784), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical XOR"),
SCAN_INSTRUCTION(vpkuhus128, VX128(5, 832), VX128 , General , 0 , "Vector128 Pack Unsigned Half Word Unsigned Saturate"),
SCAN_INSTRUCTION(vsel128, VX128(5, 848), VX128 , General , 0 , "Vector128 Conditional Select"),
SCAN_INSTRUCTION(vpkuwum128, VX128(5, 896), VX128 , General , 0 , "Vector128 Pack Unsigned Word Unsigned Modulo"),
SCAN_INSTRUCTION(vslo128, VX128(5, 912), VX128 , General , 0 , "Vector128 Shift Left Octet"),
SCAN_INSTRUCTION(vpkuwus128, VX128(5, 960), VX128 , General , 0 , "Vector128 Pack Unsigned Word Unsigned Saturate"),
SCAN_INSTRUCTION(vsro128, VX128(5, 976), VX128 , General , 0 , "Vector128 Shift Right Octet"),
SCAN_INSTRUCTION(vpermwi128, VX128_P(6, 528), VX128_P , General , 0 , "Vector128 Permutate Word Immediate"),
SCAN_INSTRUCTION(vcfpsxws128, VX128_3(6, 560), VX128_3 , General , 0 , "Vector128 Convert From Floating-Point to Signed Fixed-Point Word Saturate"),
SCAN_INSTRUCTION(vsro128, VX128(5, 976), VX128 , General , VX128_VD_VA_VB , "Vector128 Shift Right Octet"),
SCAN_INSTRUCTION(vpermwi128, VX128_P(6, 528), VX128_P , General , vpermwi128 , "Vector128 Permutate Word Immediate"),
SCAN_INSTRUCTION(vcfpsxws128, VX128_3(6, 560), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Convert From Floating-Point to Signed Fixed-Point Word Saturate"),
SCAN_INSTRUCTION(vcfpuxws128, VX128_3(6, 624), VX128_3 , General , 0 , "Vector128 Convert From Floating-Point to Unsigned Fixed-Point Word Saturate"),
SCAN_INSTRUCTION(vcsxwfp128, VX128_3(6, 688), VX128_3 , General , 0 , "Vector128 Convert From Signed Fixed-Point Word to Floating-Point"),
SCAN_INSTRUCTION(vcsxwfp128, VX128_3(6, 688), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Convert From Signed Fixed-Point Word to Floating-Point"),
SCAN_INSTRUCTION(vcuxwfp128, VX128_3(6, 752), VX128_3 , General , 0 , "Vector128 Convert From Unsigned Fixed-Point Word to Floating-Point"),
SCAN_INSTRUCTION(vrfim128, VX128_3(6, 816), VX128_3 , General , 0 , "Vector128 Round to Floating-Point Integer toward -Infinity"),
SCAN_INSTRUCTION(vrfin128, VX128_3(6, 880), VX128_3 , General , 0 , "Vector128 Round to Floating-Point Integer Nearest"),
SCAN_INSTRUCTION(vrfin128, VX128_3(6, 880), VX128_3 , General , vrfin128 , "Vector128 Round to Floating-Point Integer Nearest"),
SCAN_INSTRUCTION(vrfip128, VX128_3(6, 944), VX128_3 , General , 0 , "Vector128 Round to Floating-Point Integer toward +Infinity"),
SCAN_INSTRUCTION(vrfiz128, VX128_3(6, 1008), VX128_3 , General , 0 , "Vector128 Round to Floating-Point Integer toward Zero"),
SCAN_INSTRUCTION(vpkd3d128, VX128_4(6, 1552), VX128_4 , General , 0 , "Vector128 Pack D3Dtype, Rotate Left Immediate and Mask Insert"),
SCAN_INSTRUCTION(vrefp128, VX128_3(6, 1584), VX128_3 , General , 0 , "Vector128 Reciprocal Estimate Floating Point"),
SCAN_INSTRUCTION(vrsqrtefp128, VX128_3(6, 1648), VX128_3 , General , 0 , "Vector128 Reciprocal Square Root Estimate Floating Point"),
SCAN_INSTRUCTION(vrsqrtefp128, VX128_3(6, 1648), VX128_3 , General , VX1283_VD_VB , "Vector128 Reciprocal Square Root Estimate Floating Point"),
SCAN_INSTRUCTION(vexptefp128, VX128_3(6, 1712), VX128_3 , General , 0 , "Vector128 Log2 Estimate Floating Point"),
SCAN_INSTRUCTION(vlogefp128, VX128_3(6, 1776), VX128_3 , General , 0 , "Vector128 Log2 Estimate Floating Point"),
SCAN_INSTRUCTION(vrlimi128, VX128_4(6, 1808), VX128_4 , General , 0 , "Vector128 Rotate Left Immediate and Mask Insert"),
SCAN_INSTRUCTION(vspltw128, VX128_3(6, 1840), VX128_3 , General , 0 , "Vector128 Splat Word"),
SCAN_INSTRUCTION(vspltisw128, VX128_3(6, 1904), VX128_3 , General , 0 , "Vector128 Splat Immediate Signed Word"),
SCAN_INSTRUCTION(vupkd3d128, VX128_3(6, 2032), VX128_3 , General , 0 , "Vector128 Unpack D3Dtype"),
SCAN_INSTRUCTION(vcmpeqfp128, VX128_R(6, 0), VX128_R , General , 0 , "Vector128 Compare Equal-to Floating Point"),
SCAN_INSTRUCTION(vrlimi128, VX128_4(6, 1808), VX128_4 , General , vrlimi128 , "Vector128 Rotate Left Immediate and Mask Insert"),
SCAN_INSTRUCTION(vspltw128, VX128_3(6, 1840), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Splat Word"),
SCAN_INSTRUCTION(vspltisw128, VX128_3(6, 1904), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Splat Immediate Signed Word"),
SCAN_INSTRUCTION(vupkd3d128, VX128_3(6, 2032), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Unpack D3Dtype"),
SCAN_INSTRUCTION(vcmpeqfp128, VX128_R(6, 0), VX128_R , General , VX128_VD_VA_VB , "Vector128 Compare Equal-to Floating Point"),
SCAN_INSTRUCTION(vrlw128, VX128(6, 80), VX128 , General , 0 , "Vector128 Rotate Left Word"),
SCAN_INSTRUCTION(vcmpgefp128, VX128_R(6, 128), VX128_R , General , 0 , "Vector128 Compare Greater-Than-or-Equal-to Floating Point"),
SCAN_INSTRUCTION(vslw128, VX128(6, 208), VX128 , General , 0 , "Vector128 Shift Left Integer Word"),
SCAN_INSTRUCTION(vslw128, VX128(6, 208), VX128 , General , VX128_VD_VA_VB , "Vector128 Shift Left Integer Word"),
SCAN_INSTRUCTION(vcmpgtfp128, VX128_R(6, 256), VX128_R , General , 0 , "Vector128 Compare Greater-Than Floating-Point"),
SCAN_INSTRUCTION(vsraw128, VX128(6, 336), VX128 , General , 0 , "Vector128 Shift Right Arithmetic Word"),
SCAN_INSTRUCTION(vsraw128, VX128(6, 336), VX128 , General , VX128_VD_VA_VB , "Vector128 Shift Right Arithmetic Word"),
SCAN_INSTRUCTION(vcmpbfp128, VX128_R(6, 384), VX128_R , General , 0 , "Vector128 Compare Bounds Floating Point"),
SCAN_INSTRUCTION(vsrw128, VX128(6, 464), VX128 , General , 0 , "Vector128 Shift Right Word"),
SCAN_INSTRUCTION(vcmpequw128, VX128_R(6, 512), VX128_R , General , 0 , "Vector128 Compare Equal-to Unsigned Word"),
SCAN_INSTRUCTION(vsrw128, VX128(6, 464), VX128 , General , VX128_VD_VA_VB , "Vector128 Shift Right Word"),
SCAN_INSTRUCTION(vcmpequw128, VX128_R(6, 512), VX128_R , General , VX128_VD_VA_VB , "Vector128 Compare Equal-to Unsigned Word"),
SCAN_INSTRUCTION(vmaxfp128, VX128(6, 640), VX128 , General , 0 , "Vector128 Maximum Floating Point"),
SCAN_INSTRUCTION(vminfp128, VX128(6, 704), VX128 , General , 0 , "Vector128 Minimum Floating Point"),
SCAN_INSTRUCTION(vmrghw128, VX128(6, 768), VX128 , General , 0 , "Vector128 Merge High Word"),
SCAN_INSTRUCTION(vmrglw128, VX128(6, 832), VX128 , General , 0 , "Vector128 Merge Low Word"),
SCAN_INSTRUCTION(vmrghw128, VX128(6, 768), VX128 , General , VX128_VD_VA_VB , "Vector128 Merge High Word"),
SCAN_INSTRUCTION(vmrglw128, VX128(6, 832), VX128 , General , VX128_VD_VA_VB , "Vector128 Merge Low Word"),
SCAN_INSTRUCTION(vupkhsb128, VX128(6, 896), VX128 , General , 0 , "Vector128 Unpack High Signed Byte"),
SCAN_INSTRUCTION(vupklsb128, VX128(6, 960), VX128 , General , 0 , "Vector128 Unpack Low Signed Byte"),
};

View File

@ -12,6 +12,7 @@
#include <alloy/alloy-private.h>
#include <alloy/compiler/compiler_passes.h>
#include <alloy/frontend/tracing.h>
#include <alloy/frontend/ppc/ppc_disasm.h>
#include <alloy/frontend/ppc/ppc_frontend.h>
#include <alloy/frontend/ppc/ppc_hir_builder.h>
#include <alloy/frontend/ppc/ppc_instr.h>
@ -161,17 +162,8 @@ void PPCTranslator::DumpSource(
++block_it;
}
if (!i.type) {
string_buffer->Append("%.8X %.8X ???", address, i.code);
} else if (i.type->disassemble) {
ppc::InstrDisasm d;
i.type->disassemble(i, d);
std::string disasm;
d.Dump(disasm);
string_buffer->Append("%.8X %.8X %s", address, i.code, disasm.c_str());
} else {
string_buffer->Append("%.8X %.8X %s ???", address, i.code, i.type->name);
}
string_buffer->Append("%.8X %.8X ", address, i.code);
DisasmPPC(i, string_buffer);
string_buffer->Append("\n");
}
}

View File

@ -3,13 +3,8 @@
'sources': [
'ppc_context.cc',
'ppc_context.h',
'ppc_disasm-private.h',
'ppc_disasm.cc',
'ppc_disasm.h',
'ppc_disasm_altivec.cc',
'ppc_disasm_alu.cc',
'ppc_disasm_control.cc',
'ppc_disasm_fpu.cc',
'ppc_disasm_memory.cc',
'ppc_emit-private.h',
'ppc_emit.h',
'ppc_emit_altivec.cc',