Simplifying disassembler. Much faster than before.
This commit is contained in:
parent
f36e6cd820
commit
53b9ed5214
|
@ -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
|
||||
|
||||
|
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -32,12 +32,6 @@ namespace {
|
|||
}
|
||||
has_initialized = true;
|
||||
|
||||
RegisterDisasmCategoryAltivec();
|
||||
RegisterDisasmCategoryALU();
|
||||
RegisterDisasmCategoryControl();
|
||||
RegisterDisasmCategoryFPU();
|
||||
RegisterDisasmCategoryMemory();
|
||||
|
||||
RegisterEmitCategoryAltivec();
|
||||
RegisterEmitCategoryALU();
|
||||
RegisterEmitCategoryControl();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue