Moving disasm to new tables.

Also adding useful CPU docs.
This commit is contained in:
Ben Vanik 2015-12-28 20:49:22 -08:00
parent cd938be678
commit cc72de0f64
25 changed files with 10502 additions and 3252 deletions

Binary file not shown.

Binary file not shown.

610
docs/ppc/vmx128.txt Normal file
View File

@ -0,0 +1,610 @@
2006/09/01 Revision 1.2
-----------------------------------------------------------------
This is a description of the VMX128-type opcodes found on
the xbox360 processor. I figured this out by looking at
various disassmblies, so there might some errors and
missing instructions. Some instructions have unknown
semantics for me.
See comments or corrections to sb#biallas.net
=================================================================
Conventions:
VD128, VS128: 5 lower bits of a VMX128 vector register
number
VDh: upper 2 bits of VD128
(so register number is (VDh << 5 | VD128))
VA128: same as VD128
A: bit 6 of VA128
a: bit 5 of VA128
(so register number is (A<<6 | a<<5 | VA128))
VB128: same as VD128
VBh: same as VDh
VC128: 3 bits of a VMX128 vector register number
(you can only use vr0-vr7 here)
RA, RB: general purpose register number
UIMM: unsigned immediate value
SIMM: signed immediate value
PERMh: upper 3 bits of a permutation
PERMl: lower 5 bits of a permutation
x, y, z: unknown immediate values
=================================================================
lvewx128 Load Vector128 Element Word Indexed
|0 0 0 1 0 0| VD128 | RA | RB |0 0 0 1 0 0 0|VDh|1 1|
lvewx128 vr(VD128), r(RA), r(RB)
=================================================================
lvlx128 Load Vector128 Left Indexed
|0 0 0 1 0 0| VD128 | RA | RB |1 0 0 0 0 0 0|VDh|1 1|
lvlx128 vr(VD128), r(RA), r(RB)
=================================================================
lvrx128 Load Vector128 Right Indexed
|0 0 0 1 0 0| VD128 | RA | RB |1 0 0 0 1 0 0|VDh|1 1|
lvrx128 vr(VD128), r(RA), r(RB)
=================================================================
lvlxl128 Load Vector128 Left Indexed LRU
|0 0 0 1 0 0| VD128 | RA | RB |1 1 0 0 0 0 0|VDh|1 1|
lvlxl128 vr(VD128), r(RA), r(RB)
=================================================================
lvrxl128 Load Vector128 Right Indexed LRU
|0 0 0 1 0 0| VD128 | RA | RB |1 1 0 0 1 0 0|VDh|1 1|
lvrxl128 vr(VD128), r(RA), r(RB)
=================================================================
lvsl128 Load Vector128 for Shift Left
|0 0 0 1 0 0| VD128 | RA | RB |0 0 0 0 0 0 0|VDh|1 1|
lvsl128 vr(VD128), r(RA), r(RB)
=================================================================
lvsr128 Load Vector128 for Shift Right
|0 0 0 1 0 0| VD128 | RA | RB |0 0 0 0 1 0 0|VDh|1 1|
lvsr128 vr(VD128), r(RA), r(RB)
=================================================================
lvx128 Load Vector128 Indexed
|0 0 0 1 0 0| VD128 | RA | RB |0 0 0 1 1 0 0|VDh|1 1|
lvx128 vr(VD128), r(RA), r(RB)
=================================================================
lvxl128 Load Vector128 Indexed LRU
|0 0 0 1 0 0| VD128 | RA | RB |0 1 0 1 1 0 0|VDh|1 1|
lvxl128 vr(VD128), r(RA), r(RB)
=================================================================
stewx128 Store Vector128 Element Word Indexed
|0 0 0 1 0 0| VS128 | RA | RB |0 1 1 0 0 0 0|VDh|1 1|
stvewx128 vr(VS128), r(RA), r(RB)
=================================================================
stvlx128 Store Vector128 Left Indexed
|0 0 0 1 0 0| VS128 | RA | RB |1 0 1 0 0 0 0|VDh|1 1|
stvlx128 vr(VS128), r(RA), r(RB)
=================================================================
stvlxl128 Store Vector128 Left Indexed LRU
|0 0 0 1 0 0| VS128 | RA | RB |1 1 1 0 0 0 0|VDh|1 1|
lvlxl128 vr(VS128), r(RA), r(RB)
=================================================================
stvrx128 Store Vector128 Right Indexed
|0 0 0 1 0 0| VS128 | RA | RB |1 0 1 0 1 0 0|VDh|1 1|
stvrx128 vr(VS128), r(RA), r(RB)
=================================================================
stvrxl128 Store Vector128 Right Indexed LRU
|0 0 0 1 0 0| VS128 | RA | RB |1 1 1 0 1 0 0|VDh|1 1|
stvrxl128 vr(VS128), r(RA), r(RB)
=================================================================
stvx128 Store Vector128 Indexed
|0 0 0 1 0 0| VS128 | RA | RB |0 0 1 1 1 0 0|VDh|1 1|
stvx128 vr(VS128), r(RA), r(RB)
=================================================================
stvxl128 Store Vector128 Indexed LRU
|0 0 0 1 0 0| VS128 | RA | RB |0 1 1 1 1 0 0|VDh|1 1|
stvxl128 vr(VS128), r(RA), r(RB)
=================================================================
vaddfp128 Vector128 Add Floating Point
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 0 0 0|a|1|VDh|VBh|
vaddfp128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vand128 Vector128 Logical AND
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 0 0|a|1|VDh|VBh|
vand128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vandc128 Vector128 Logical AND
with Complement
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 0|a|1|VDh|VBh|
vandc128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vcfpsxws128 Vector128 Convert From Floating-Point to
Signed Fixed-Point Word Saturate
|0 0 0 1 1 0| VD128 | SIMM | VB128 |0 1 0 0 0 1 1|VDh|VBh|
vcfpsxws128 vr(VD128), vr(VB128), SIMM
=================================================================
vcfpuxws128 Vector128 Convert From Floating-Point to
Unsigned Fixed-Point Word Saturate
|0 0 0 1 1 0| VD128 | UIMM | VB128 |0 1 0 0 1 1 1|VDh|VBh|
vcfpuxws128 vr(VD128), vr(VB128), UIMM
=================================================================
vcmpbfp128 Vector128 Compare Bounds
Floating Point
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 1 1|R|a|0|VDh|VBh|
vcmpbfp128 vr(VD128), vr(VA128), vr(VB128) (R == 0)
vcmpbfp128. vr(VD128), vr(VA128), vr(VB128) (R == 1)
=================================================================
vcmpeqfp128 Vector128 Compare Equal-to
Floating Point
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 0 0|R|a|0|VDh|VBh|
vcmpeqfp128 vr(VD128), vr(VA128), vr(VB128) (R == 0)
vcmpeqfp128. vr(VD128), vr(VA128), vr(VB128) (R == 1)
=================================================================
vcmpequw128 Vector128 Compare Equal-to
Unsigned Word
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 0 0|R|a|0|VDh|VBh|
vcmpequw128 vr(VD128), vr(VA128), vr(VB128) (R == 0)
vcmpequw128. vr(VD128), vr(VA128), vr(VB128) (R == 1)
=================================================================
vcmpgefp128 Vector128 Compare Greater-Than-
or-Equal-to Floating Point
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 0 1|R|a|0|VDh|VBh|
vcmpgefp128 vr(VD128), vr(VA128), vr(VB128) (R == 0)
vcmpgefp128. vr(VD128), vr(VA128), vr(VB128) (R == 1)
=================================================================
vcmpgtfp128 Vector128 Compare Greater-Than
Floating-Point
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 1 0|R|a|0|VDh|VBh|
vcmpgtfp128 vr(VD128), vr(VA128), vr(VB128) (R == 0)
vcmpgtfp128. vr(VD128), vr(VA128), vr(VB128) (R == 1)
=================================================================
vcsxwfp128 Vector128 Convert From Signed Fixed-Point
Word to Floating-Point
|0 0 0 1 1 0| VD128 | UIMM | VB128 |0 1 0 1 0 1 1|VDh|VBh|
vcsxwfp128 vr(VD128), vr(VB128), SIMM
=================================================================
vcuxwfp128 Vector128 Convert From Unsigned Fixed-Point
Word to Floating-Point
|0 0 0 1 1 0| VD128 | UIMM | VB128 |0 1 0 1 1 1 1|VDh|VBh|
vcuxwfp128 vr(VD128), vr(VB128), UIMM
=================================================================
vexptefp128 Vector128 2 Raised to the Exponent
Estimate Floating Point
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |1 1 0 1 0 1 1|VDh|VBh|
vexptefp128 vr(VD128), vr(VB128)
=================================================================
vlogefp128 Vector128 Log2 Estimate
Floating Point
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |1 1 0 1 1 1 1|VDh|VBh|
vlogefp128 vr(VD128), vr(VB128)
=================================================================
vmaddcfp128 Vector128 Multiply Add
Floating Point
|0 0 0 1 0 1| VDS128 | VA128 | VB128 |A|0 1 0 0|a|1|VDh|VBh|
vmaddcfp128 vr(VDS128), vr(VA128), vr(VSD128), vr(VB128)
=================================================================
vmaddfp128 Vector128 Multiply Add
Floating Point
|0 0 0 1 0 1| VDS128 | VA128 | VB128 |A|0 0 1 1|a|1|VDh|VBh|
vmaddfp128 vr(VDS128), vr(VA128), vr(VB128), vr(VDS128)
=================================================================
vmaxfp128 Vector128 Maximum
Floating Point
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 0 1 0|a|0|VDh|VBh|
vmaxfp128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vminfp128 Vector128 Minimum
Floating Point
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 0 1 1|a|0|VDh|VBh|
vminfp128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vmrghw128 Vector128 Merge High Word
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 1 0 0|a|0|VDh|VBh|
vmrghw128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vmrglw128 Vector128 Merge Low Word
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 1 0 1|a|0|VDh|VBh|
vmrglw128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vmsum3fp128 Vector128 Multiply Sum 3-way
Floating Point
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 1 1 0|a|1|VDh|VBh|
vmsub3fp128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vmsum4fp128 Vector128 Multiply Sum 4-way
Floating-Point
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 1 1 1|a|1|VDh|VBh|
vmsub4fp128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vmulfp128 Vector128 Multiply
Floating-Point
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 0 1 0|a|1|VDh|VBh|
vmulfp128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vnmsubfp128 Vector128 Negative Multiply-Subtract
Floating Point
|0 0 0 1 0 1| VDS128 | VA128 | VB128 |A|0 1 0 1|a|1|VDh|VBh|
vnmsubfp128 vr(VDS128), vr(VA128), vr(VB128), vr(VDS128)
=================================================================
vnor128 Vector128 Logical NOR
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 0|a|1|VDh|VBh|
vnor128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vor128 Vector128 Logical OR
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 1|a|1|VDh|VBh|
vor128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vperm128 Vector128 Permutation
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0| VC |a|0|VDh|VBh|
vperm128 vr(VD128), vr(VA128), vr(VB128), vr(VC)
=================================================================
vpermwi128 Vector128 Permutate Word Immediate
|0 0 0 1 1 0| VD128 | PERMl | VB128 |0|1|PERMh|0|1|VDh|VBh|
vpermwi128 vr(VD128), vr(VB128), (PERMh << 5 | PERMl)
=================================================================
vpkd3d128 Vector128 Pack D3Dtype, Rotate Left
Immediate and Mask Insert
|0 0 0 1 1 0| VD128 | x | y | VB128 |1 1 0| z |0 1|VDh|VBh|
vpkd3d128 vr(VD128), vr(VB128), x, y, z
=================================================================
vpkshss128 Vector128 Pack Signed Half Word
Signed Saturate
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 0 0|a|0|VDh|VBh|
vpkshss128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vpkshus128 Vector128 Pack Signed Half Word
Unsigned Saturate
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 0 1|a|0|VDh|VBh|
vpkshus128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vpkswss128 Vector128 Pack Signed Word
Signed Saturate
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 0|a|0|VDh|VBh|
vpkswss128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vpkswus128 Vector128 Pack Signed Word
Unsigned Saturate
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 0 1 1|a|0|VDh|VBh|
vpkswus128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vpkuhum128 Vector128 Pack Unsigned Half Word
Unsigned Modulo
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 0 0|a|0|VDh|VBh|
vpkuhum128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vpkuhus128 Vector128 Pack Unsigned Half Word
Unsigned Saturate
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 0 1|a|0|VDh|VBh|
vpkuhus128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vpkuwum128 Vector128 Pack Unsigned Word
Unsigned Modulo
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 1 0|a|0|VDh|VBh|
vpkuwum128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vpkuwus128 Vector128 Pack Unsigned Word
Unsigned Saturate
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 1 1|a|0|VDh|VBh|
vpkuwus128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vrefp128 Vector128 Reciprocal Estimate
Floating Point
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |1 1 0 0 0 1 1|VDh|VBh|
vrefp128 vr(VD128), vr(VB128)
=================================================================
vrfim128 Vector128 Round to Floating-Point
Integer toward -oo
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 0 0 1 1|VDh|VBh|
vrfim128 vr(VD128), vr(VB128)
=================================================================
vrfin128 Vector128 Round to Floating-Point
Integer toward Nearest
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 0 1 1 1|VDh|VBh|
vrfin128 vr(VD128), vr(VB128)
=================================================================
vrfip128 Vector128 Round to Floating-Point
Integer toward +oo
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 1 0 1 1|VDh|VBh|
vrfip128 vr(VD128), vr(VB128)
=================================================================
vrfiz128 Vector128 Round to Floating-Point
Integer toward Zero
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 1 1 1 1|VDh|VBh|
vrfiz128 vr(VD128), vr(VB128)
=================================================================
vrlimi128 Vector128 Rotate Left Immediate
and Mask Insert
|0 0 0 1 1 0| VD128 | UIMM | VB128 |1 1 1| z |0 1|VDh|VBh|
vrlimi128 vr(VD128), vr(VB128), UIMM, z
=================================================================
vrlw128 Vector128 Rotate Left Word
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 0 0 1|a|1|VDh|VBh|
vrlw128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vrsqrtefp128 Vector128 Reciprocal Square Root
Estimate Floating Point
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |1 1 0 0 1 1 1|VDh|VBh|
vrsqrtefp128 vr(VD128), vr(VB128)
=================================================================
vsel128 Vector128 Select
|0 0 0 1 0 1| VDS128 | VA128 | VB128 |A|1 1 0 1|a|1|VDh|VBh|
vsel128 vr(VDS128), vr(VA128), vr(VB128), vr(VDS128)
=================================================================
vsldoi128 Vector128 Shift Left Double
by Octet Immediate
|0 0 0 1 0 0| VD128 | VA128 | VB128 |A| SHB |a|1|VDh|VBh|
vsldoi128 vr(VD128), vr(VA128), vr(VB128), SHB
=================================================================
vslo128 Vector128 Shift Left Octet
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 1 0|a|1|VDh|VBh|
vslo128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vslw128 Vector128 Shift Left Word
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 0 1 1|a|1|VDh|VBh|
vslw128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vspltisw128 Vector128 Splat Immediate
Signed Word
|0 0 0 1 1 0| VD128 | SIMM | VB128 |1 1 1 0 1 1 1|VDh|VBh|
vspltisw128 vr(VD128), vr(VB128), SIMM
=================================================================
vspltw128 Vector128 Splat Word
|0 0 0 1 1 0| VD128 | UIMM | VB128 |1 1 1 0 0 1 1|VDh|VBh|
vspltw128 vr(VD128), vr(VB128), UIMM
=================================================================
vsraw128 Vector128 Shift Right
Arithmetic Word
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 1 0 1|a|1|VDh|VBh|
vsraw128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vsro128 Vector128 Shift Right Octet
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|1 1 1 1|a|1|VDh|VBh|
vsro128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vsrw128 Vector128 Shift Right Word
|0 0 0 1 1 0| VD128 | VA128 | VB128 |A|0 1 1 1|a|1|VDh|VBh|
vsrw128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vsubfp128 Vector128 Subtract Floating Point
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|0 0 0 1|a|1|VDh|VBh|
vsubfp128 vr(VD128), vr(VA128), vr(VB128)
=================================================================
vupkd3d128 Vector128 Unpack D3Dtype
|0 0 0 1 1 0| VD128 | UIMM | VB128 |1 1 1 1 1 1 1|VDh|VBh|
vupkd3d128 vr(VD128), vr(VB128), UIMM
=================================================================
vupkhsb128 Vector128 Unpack
High Signed Byte
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 1 0 0 0|VDh|VBh|
vupkhsb128 vr(VD128), vr(VB128)
=================================================================
vupklsb128 Vector128 Unpack
Low Signed Byte
|0 0 0 1 1 0| VD128 |0 0 0 0 0| VB128 |0 1 1 1 1 0 0|VDh|VBh|
vupkhsb128 vr(VD128), vr(VB128)
=================================================================
vxor128 Vector128 Logical XOR
|0 0 0 1 0 1| VD128 | VA128 | VB128 |A|1 1 0 0|a|1|VDh|VBh|
vxor128 vr(VD128), vr(VA128), vr(VB128)

View File

@ -56,6 +56,14 @@ T next_pow2(T value) {
return value;
}
constexpr uint32_t make_bitmask(uint32_t a, uint32_t b) {
return (static_cast<uint32_t>(-1) >> (31 - b)) & ~((1u << a) - 1);
}
constexpr uint32_t select_bits(uint32_t value, uint32_t a, uint32_t b) {
return (value & make_bitmask(a, b)) >> a;
}
// lzcnt instruction, typed for integers of all sizes.
// The number of leading zero bits in the value parameter. If value is zero, the
// return value is the size of the input operand (8, 16, 32, or 64). If the most

View File

@ -0,0 +1,687 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_CPU_PPC_PPC_DECODE_DATA_H_
#define XENIA_CPU_PPC_PPC_DECODE_DATA_H_
#include <cstdint>
#include "xenia/base/math.h"
#include "xenia/base/string_buffer.h"
#include "xenia/cpu/ppc/ppc_instr.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
namespace xe {
namespace cpu {
namespace ppc {
constexpr int64_t XEEXTS16(uint32_t v) { return (int64_t)((int16_t)v); }
constexpr int64_t XEEXTS26(uint32_t v) {
return (int64_t)(v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v));
}
constexpr uint64_t XEEXTZ16(uint32_t v) { return (uint64_t)((uint16_t)v); }
static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
// if mstart ≤ mstop then
// mask[mstart:mstop] = ones
// mask[all other bits] = zeros
// else
// mask[mstart:63] = ones
// mask[0:mstop] = ones
// mask[all other bits] = zeros
mstart &= 0x3F;
mstop &= 0x3F;
uint64_t value =
(UINT64_MAX >> mstart) ^ ((mstop >= 63) ? 0 : UINT64_MAX >> (mstop + 1));
return mstart <= mstop ? value : ~value;
}
struct PPCDecodeData {
struct FormatSC {};
struct FormatD {
uint32_t RT() const { return bits_.RT; }
uint32_t RD() const { return RT(); }
uint32_t RS() const { return RT(); }
uint32_t FD() const { return RT(); }
uint32_t FS() const { return RT(); }
uint32_t TO() const { return RT(); }
uint32_t RA() const { return bits_.RA; }
uint32_t RA0() const { return RA(); }
uint32_t DS() const { return bits_.DS; }
int32_t d() const { return static_cast<int32_t>(XEEXTS16(DS())); }
int32_t SIMM() const { return d(); }
uint32_t UIMM() const { return static_cast<uint32_t>(XEEXTZ16(DS())); }
uint32_t CRFD() const { return bits_.RT >> 2; }
uint32_t L() const { return bits_.RT & 0x1; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t DS : 16;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatDS {
uint32_t RT() const { return bits_.RT; }
uint32_t RD() const { return RT(); }
uint32_t RS() const { return RT(); }
uint32_t RA() const { return bits_.RA; }
uint32_t RA0() const { return RA(); }
uint32_t DS() const { return bits_.DS; }
int32_t ds() const { return static_cast<int32_t>(XEEXTS16(DS() << 2)); }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t DS : 14;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatB {
uint32_t BO() const { return bits_.BO; }
uint32_t BI() const { return bits_.BI; }
uint32_t BD() const { return bits_.BD; }
uint32_t ADDR() const {
return static_cast<uint32_t>(XEEXTS16(BD() << 2)) + (AA() ? 0 : address_);
}
bool AA() const { return bits_.AA ? true : false; }
bool LK() const { return bits_.LK ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t LK : 1;
uint32_t AA : 1;
uint32_t BD : 14;
uint32_t BI : 5;
uint32_t BO : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatI {
uint32_t LI() const { return bits_.LI; }
uint32_t ADDR() const {
return static_cast<uint32_t>(XEEXTS16(LI() << 2)) + (AA() ? 0 : address_);
}
bool AA() const { return bits_.AA ? true : false; }
bool LK() const { return bits_.LK ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t LK : 1;
uint32_t AA : 1;
uint32_t LI : 24;
uint32_t : 6;
} bits_;
};
};
struct FormatX {
uint32_t RT() const { return bits_.RT; }
uint32_t RD() const { return RT(); }
uint32_t RS() const { return RT(); }
uint32_t FD() const { return RT(); }
uint32_t FS() const { return RT(); }
uint32_t VD() const { return RT(); }
uint32_t VS() const { return RT(); }
uint32_t TO() const { return RT(); }
uint32_t RA() const { return bits_.RA; }
uint32_t RA0() const { return RA(); }
uint32_t FA() const { return RA(); }
uint32_t RB() const { return bits_.RB; }
uint32_t FB() const { return RB(); }
uint32_t SH() const { return RB(); }
uint32_t IMM() const { return RB(); }
bool Rc() const { return bits_.Rc ? true : false; }
uint32_t CRFD() const { return bits_.RT >> 2; }
uint32_t L() const { return bits_.RT & 0x1; }
uint32_t CRFS() const { return bits_.RA >> 2; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t Rc : 1;
uint32_t : 10;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatXL {
uint32_t BO() const { return bits_.BO; }
uint32_t CRBD() const { return BO(); }
uint32_t BI() const { return bits_.BI; }
uint32_t CRBA() const { return BI(); }
uint32_t BB() const { return bits_.BB; }
uint32_t CRBB() const { return BB(); }
bool LK() const { return bits_.LK ? true : false; }
uint32_t CRFD() const { return CRBD() >> 2; }
uint32_t CRFS() const { return CRBA() >> 2; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t LK : 1;
uint32_t : 10;
uint32_t BB : 5;
uint32_t BI : 5;
uint32_t BO : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatXFX {
uint32_t RT() const { return bits_.RT; }
uint32_t RD() const { return RT(); }
uint32_t RS() const { return RT(); }
uint32_t SPR() const { return bits_.SPR; }
uint32_t TBR() const {
return ((bits_.SPR & 0x1F) << 5) | ((bits_.SPR >> 5) & 0x1F);
}
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t : 1;
uint32_t : 10;
uint32_t SPR : 10;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatXFL {
bool L() const { return bits_.L ? true : false; }
uint32_t FM() const { return bits_.FM; }
bool W() const { return bits_.W ? true : false; }
uint32_t RB() const { return bits_.RB; }
uint32_t FB() const { return RB(); }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t Rc : 1;
uint32_t : 10;
uint32_t RB : 5;
uint32_t W : 1;
uint32_t FM : 8;
uint32_t L : 1;
uint32_t : 6;
} bits_;
};
};
struct FormatXS {
uint32_t RT() const { return bits_.RT; }
uint32_t RS() const { return RT(); }
uint32_t RA() const { return bits_.RA; }
uint32_t SH() const { return (bits_.SH5 << 5) | bits_.SH; }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t Rc : 1;
uint32_t SH5 : 1;
uint32_t : 9;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatXO {
uint32_t RT() const { return bits_.RT; }
uint32_t RD() const { return RT(); }
uint32_t RA() const { return bits_.RA; }
uint32_t RB() const { return bits_.RB; }
bool OE() const { return bits_.OE ? true : false; }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t Rc : 1;
uint32_t : 9;
uint32_t OE : 1;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatA {
uint32_t FT() const { return bits_.FT; }
uint32_t FD() const { return FT(); }
uint32_t FS() const { return FT(); }
uint32_t FA() const { return bits_.FA; }
uint32_t FB() const { return bits_.FB; }
uint32_t FC() const { return bits_.FC; }
uint32_t XO() const { return bits_.XO; }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t Rc : 1;
uint32_t XO : 5;
uint32_t FC : 5;
uint32_t FB : 5;
uint32_t FA : 5;
uint32_t FT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatM {
uint32_t RT() const { return bits_.RT; }
uint32_t RS() const { return RT(); }
uint32_t RA() const { return bits_.RA; }
uint32_t SH() const { return bits_.SH; }
uint32_t RB() const { return SH(); }
uint32_t MB() const { return bits_.MB; }
uint32_t ME() const { return bits_.ME; }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t Rc : 1;
uint32_t ME : 5;
uint32_t MB : 5;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatMD {
uint32_t RT() const { return bits_.RT; }
uint32_t RS() const { return RT(); }
uint32_t RA() const { return bits_.RA; }
uint32_t SH() const { return (bits_.SH5 << 5) | bits_.SH; }
uint32_t MB() const { return (bits_.MB5 << 5) | bits_.MB; }
uint32_t ME() const { return MB(); }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t Rc : 1;
uint32_t SH5 : 1;
uint32_t : 3;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatMDS {
uint32_t RT() const { return bits_.RT; }
uint32_t RS() const { return RT(); }
uint32_t RA() const { return bits_.RA; }
uint32_t RB() const { return bits_.RB; }
uint32_t MB() const { return (bits_.MB5 << 5) | bits_.MB; }
uint32_t ME() const { return MB(); }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t Rc : 1;
uint32_t : 4;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX {
uint32_t VD() const { return bits_.VD; }
uint32_t VA() const { return bits_.VA; }
uint32_t VB() const { return bits_.VB; }
uint32_t UIMM() const { return VA(); }
int32_t SIMM() const { return static_cast<int32_t>(XEEXTS16(VA())); }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t : 11;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVC {
uint32_t VD() const { return bits_.VD; }
uint32_t VA() const { return bits_.VA; }
uint32_t VB() const { return bits_.VB; }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t : 10;
uint32_t Rc : 1;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVA {
uint32_t VD() const { return bits_.VD; }
uint32_t VA() const { return bits_.VA; }
uint32_t VB() const { return bits_.VB; }
uint32_t VC() const { return bits_.VC; }
uint32_t SHB() const { return VC() & 0xF; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t : 6;
uint32_t VC : 5;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX128 {
uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); }
uint32_t VA() const {
return bits_.VA128l | (bits_.VA128h << 5) | (bits_.VA128H << 6);
}
uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 1;
uint32_t VA128h : 1;
uint32_t : 4;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX128_1 {
uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); }
uint32_t VS() const { return VD(); }
uint32_t RA() const { return bits_.RA; }
uint32_t RA0() const { return RA(); }
uint32_t RB() const { return bits_.RB; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t : 2;
uint32_t VD128h : 2;
uint32_t : 7;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t VD128l : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX128_2 {
uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); }
uint32_t VA() const {
return bits_.VA128l | (bits_.VA128h << 5) | (bits_.VA128H << 6);
}
uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); }
uint32_t VC() const { return bits_.VC; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 1;
uint32_t VA128h : 1;
uint32_t VC : 3;
uint32_t : 1;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX128_3 {
uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); }
uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); }
uint32_t UIMM() const { return bits_.UIMM; }
int32_t SIMM() const { return static_cast<int32_t>(XEEXTS16(bits_.UIMM)); }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 7;
uint32_t VB128l : 5;
uint32_t UIMM : 5;
uint32_t VD128l : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX128_4 {
uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); }
uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); }
uint32_t IMM() const { return bits_.IMM; }
uint32_t z() const { return bits_.z; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 2;
uint32_t z : 2;
uint32_t : 3;
uint32_t VB128l : 5;
uint32_t IMM : 5;
uint32_t VD128l : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX128_5 {
uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); }
uint32_t VA() const {
return bits_.VA128l | (bits_.VA128h << 5) | (bits_.VA128H << 6);
}
uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); }
uint32_t SH() const { return bits_.SH; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 1;
uint32_t VA128h : 1;
uint32_t SH : 4;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX128_R {
uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); }
uint32_t VA() const {
return bits_.VA128l | (bits_.VA128h << 5) | (bits_.VA128H << 6);
}
uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); }
bool Rc() const { return bits_.Rc ? true : false; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 1;
uint32_t VA128h : 1;
uint32_t Rc : 1;
uint32_t : 3;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t : 6;
} bits_;
};
};
struct FormatVX128_P {
uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); }
uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); }
uint32_t UIMM() const { return bits_.PERMl | (bits_.PERMh << 5); }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 2;
uint32_t PERMh : 3;
uint32_t : 2;
uint32_t VB128l : 5;
uint32_t PERMl : 5;
uint32_t VD128l : 5;
uint32_t : 6;
} bits_;
};
};
union {
struct {
uint32_t address;
uint32_t code;
};
FormatSC SC;
FormatD D;
FormatDS DS;
FormatB B;
FormatI I;
FormatX X;
FormatXL XL;
FormatXFX XFX;
FormatXFL XFL;
FormatXS XS;
FormatXO XO;
FormatA A;
FormatM M;
FormatMD MD;
FormatMDS MDS;
FormatX DCBZ;
FormatVX VX;
FormatVC VC;
FormatVA VA;
FormatVX128 VX128;
FormatVX128_1 VX128_1;
FormatVX128_2 VX128_2;
FormatVX128_3 VX128_3;
FormatVX128_4 VX128_4;
FormatVX128_5 VX128_5;
FormatVX128_R VX128_R;
FormatVX128_P VX128_P;
};
};
} // namespace ppc
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_PPC_PPC_DECODE_DATA_H_

View File

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

View File

@ -1,25 +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 XENIA_CPU_PPC_PPC_DISASM_H_
#define XENIA_CPU_PPC_PPC_DISASM_H_
#include "xenia/base/string_buffer.h"
namespace xe {
namespace cpu {
namespace ppc {
int DisasmPPC(uint32_t address, uint32_t code, StringBuffer* str);
} // namespace ppc
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_PPC_PPC_DISASM_H_

View File

@ -11,8 +11,8 @@
#define XENIA_CPU_PPC_PPC_EMIT_PRIVATE_H_
#include "xenia/base/logging.h"
#include "xenia/cpu/ppc/ppc_decode_data.h"
#include "xenia/cpu/ppc/ppc_emit.h"
#include "xenia/cpu/ppc/ppc_instr.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
namespace xe {

View File

@ -11,8 +11,8 @@
#include "xenia/base/atomic.h"
#include "xenia/cpu/ppc/ppc_context.h"
#include "xenia/cpu/ppc/ppc_disasm.h"
#include "xenia/cpu/ppc/ppc_emit.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/ppc/ppc_translator.h"
#include "xenia/cpu/processor.h"

View File

@ -18,9 +18,8 @@
#include "xenia/cpu/cpu_flags.h"
#include "xenia/cpu/hir/label.h"
#include "xenia/cpu/ppc/ppc_context.h"
#include "xenia/cpu/ppc/ppc_disasm.h"
#include "xenia/cpu/ppc/ppc_decode_data.h"
#include "xenia/cpu/ppc/ppc_frontend.h"
#include "xenia/cpu/ppc/ppc_instr.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/processor.h"
@ -45,9 +44,10 @@ void DumpAllOpcodeCounts() {
for (size_t i = 0; i < xe::countof(opcode_translation_counts); ++i) {
auto opcode = static_cast<PPCOpcode>(i);
auto& opcode_info = GetOpcodeInfo(opcode);
auto& disasm_info = GetOpcodeDisasmInfo(opcode);
auto translation_count = opcode_translation_counts[i];
if (translation_count) {
sb.AppendFormat("%8d : %s\n", translation_count, opcode_info.name);
sb.AppendFormat("%8d : %s\n", translation_count, disasm_info.name);
}
}
fprintf(stdout, "%s", sb.GetString());
@ -179,8 +179,9 @@ bool PPCHIRBuilder::Emit(GuestFunction* function, uint32_t flags) {
i.opcode = opcode;
i.opcode_info = &opcode_info;
if (!opcode_info.emit || opcode_info.emit(*this, i)) {
auto& disasm_info = GetOpcodeDisasmInfo(opcode);
XELOGE("Unimplemented instr %.8llX %.8X %s", address, code,
opcode_info.name);
disasm_info.name);
Comment("UNIMPLEMENTED!");
DebugBreak();
}

View File

@ -1,383 +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 "xenia/cpu/ppc/ppc_instr.h"
#include <cinttypes>
#include <sstream>
#include <vector>
#include "xenia/base/assert.h"
#include "xenia/base/math.h"
#include "xenia/base/string_buffer.h"
#include "xenia/cpu/ppc/ppc_instr_tables.h"
namespace xe {
namespace cpu {
namespace ppc {
void InstrOperand::Dump(std::string& out_str) {
if (display) {
out_str += display;
return;
}
char buffer[32];
const size_t max_count = xe::countof(buffer);
switch (type) {
case InstrOperand::kRegister:
switch (reg.set) {
case InstrRegister::kXER:
snprintf(buffer, max_count, "XER");
break;
case InstrRegister::kLR:
snprintf(buffer, max_count, "LR");
break;
case InstrRegister::kCTR:
snprintf(buffer, max_count, "CTR");
break;
case InstrRegister::kCR:
snprintf(buffer, max_count, "CR%d", reg.ordinal);
break;
case InstrRegister::kFPSCR:
snprintf(buffer, max_count, "FPSCR");
break;
case InstrRegister::kGPR:
snprintf(buffer, max_count, "r%d", reg.ordinal);
break;
case InstrRegister::kFPR:
snprintf(buffer, max_count, "f%d", reg.ordinal);
break;
case InstrRegister::kVMX:
snprintf(buffer, max_count, "vr%d", reg.ordinal);
break;
}
break;
case InstrOperand::kImmediate:
switch (imm.width) {
case 1:
if (imm.is_signed) {
snprintf(buffer, max_count, "%d", (int32_t)(int8_t)imm.value);
} else {
snprintf(buffer, max_count, "0x%.2X", (uint8_t)imm.value);
}
break;
case 2:
if (imm.is_signed) {
snprintf(buffer, max_count, "%d", (int32_t)(int16_t)imm.value);
} else {
snprintf(buffer, max_count, "0x%.4X", (uint16_t)imm.value);
}
break;
case 4:
if (imm.is_signed) {
snprintf(buffer, max_count, "%d", (int32_t)imm.value);
} else {
snprintf(buffer, max_count, "0x%.8X", (uint32_t)imm.value);
}
break;
case 8:
if (imm.is_signed) {
snprintf(buffer, max_count, "%" PRId64, (int64_t)imm.value);
} else {
snprintf(buffer, max_count, "0x%.16" PRIX64, imm.value);
}
break;
}
break;
}
out_str += buffer;
}
void InstrAccessBits::Clear() { spr = cr = gpr = fpr = 0; }
void InstrAccessBits::Extend(InstrAccessBits& other) {
spr |= other.spr;
cr |= other.cr;
gpr |= other.gpr;
fpr |= other.fpr;
vr31_0 |= other.vr31_0;
vr63_32 |= other.vr63_32;
vr95_64 |= other.vr95_64;
vr127_96 |= other.vr127_96;
}
void InstrAccessBits::MarkAccess(InstrRegister& reg) {
uint64_t bits = 0;
if (reg.access & InstrRegister::kRead) {
bits |= 0x1;
}
if (reg.access & InstrRegister::kWrite) {
bits |= 0x2;
}
switch (reg.set) {
case InstrRegister::kXER:
spr |= bits << (2 * 0);
break;
case InstrRegister::kLR:
spr |= bits << (2 * 1);
break;
case InstrRegister::kCTR:
spr |= bits << (2 * 2);
break;
case InstrRegister::kCR:
cr |= bits << (2 * reg.ordinal);
break;
case InstrRegister::kFPSCR:
spr |= bits << (2 * 3);
break;
case InstrRegister::kGPR:
gpr |= bits << (2 * reg.ordinal);
break;
case InstrRegister::kFPR:
fpr |= bits << (2 * reg.ordinal);
break;
case InstrRegister::kVMX:
if (reg.ordinal < 32) {
vr31_0 |= bits << (2 * reg.ordinal);
} else if (reg.ordinal < 64) {
vr63_32 |= bits << (2 * (reg.ordinal - 32));
} else if (reg.ordinal < 96) {
vr95_64 |= bits << (2 * (reg.ordinal - 64));
} else {
vr127_96 |= bits << (2 * (reg.ordinal - 96));
}
break;
default:
assert_unhandled_case(reg.set);
break;
}
}
void InstrAccessBits::Dump(std::string& out_str) {
std::stringstream str;
if (spr) {
uint64_t spr_t = spr;
if (spr_t & 0x3) {
str << "XER [";
str << ((spr_t & 1) ? "R" : " ");
str << ((spr_t & 2) ? "W" : " ");
str << "] ";
}
spr_t >>= 2;
if (spr_t & 0x3) {
str << "LR [";
str << ((spr_t & 1) ? "R" : " ");
str << ((spr_t & 2) ? "W" : " ");
str << "] ";
}
spr_t >>= 2;
if (spr_t & 0x3) {
str << "CTR [";
str << ((spr_t & 1) ? "R" : " ");
str << ((spr_t & 2) ? "W" : " ");
str << "] ";
}
spr_t >>= 2;
if (spr_t & 0x3) {
str << "FPCSR [";
str << ((spr_t & 1) ? "R" : " ");
str << ((spr_t & 2) ? "W" : " ");
str << "] ";
}
spr_t >>= 2;
}
if (cr) {
uint64_t cr_t = cr;
for (size_t n = 0; n < 8; n++) {
if (cr_t & 0x3) {
str << "cr" << n << " [";
str << ((cr_t & 1) ? "R" : " ");
str << ((cr_t & 2) ? "W" : " ");
str << "] ";
}
cr_t >>= 2;
}
}
if (gpr) {
uint64_t gpr_t = gpr;
for (size_t n = 0; n < 32; n++) {
if (gpr_t & 0x3) {
str << "r" << n << " [";
str << ((gpr_t & 1) ? "R" : " ");
str << ((gpr_t & 2) ? "W" : " ");
str << "] ";
}
gpr_t >>= 2;
}
}
if (fpr) {
uint64_t fpr_t = fpr;
for (size_t n = 0; n < 32; n++) {
if (fpr_t & 0x3) {
str << "f" << n << " [";
str << ((fpr_t & 1) ? "R" : " ");
str << ((fpr_t & 2) ? "W" : " ");
str << "] ";
}
fpr_t >>= 2;
}
}
if (vr31_0) {
uint64_t vr31_0_t = vr31_0;
for (size_t n = 0; n < 32; n++) {
if (vr31_0_t & 0x3) {
str << "vr" << n << " [";
str << ((vr31_0_t & 1) ? "R" : " ");
str << ((vr31_0_t & 2) ? "W" : " ");
str << "] ";
}
vr31_0_t >>= 2;
}
}
if (vr63_32) {
uint64_t vr63_32_t = vr63_32;
for (size_t n = 0; n < 32; n++) {
if (vr63_32_t & 0x3) {
str << "vr" << (n + 32) << " [";
str << ((vr63_32_t & 1) ? "R" : " ");
str << ((vr63_32_t & 2) ? "W" : " ");
str << "] ";
}
vr63_32_t >>= 2;
}
}
if (vr95_64) {
uint64_t vr95_64_t = vr95_64;
for (size_t n = 0; n < 32; n++) {
if (vr95_64_t & 0x3) {
str << "vr" << (n + 64) << " [";
str << ((vr95_64_t & 1) ? "R" : " ");
str << ((vr95_64_t & 2) ? "W" : " ");
str << "] ";
}
vr95_64_t >>= 2;
}
}
if (vr127_96) {
uint64_t vr127_96_t = vr127_96;
for (size_t n = 0; n < 32; n++) {
if (vr127_96_t & 0x3) {
str << "vr" << (n + 96) << " [";
str << ((vr127_96_t & 1) ? "R" : " ");
str << ((vr127_96_t & 2) ? "W" : " ");
str << "] ";
}
vr127_96_t >>= 2;
}
}
out_str = str.str();
}
void InstrDisasm::Init(const char* new_name, const char* new_info,
uint32_t new_flags) {
name = new_name;
info = new_info;
flags = new_flags;
}
void InstrDisasm::AddLR(InstrRegister::Access access) {}
void InstrDisasm::AddCTR(InstrRegister::Access access) {}
void InstrDisasm::AddCR(uint32_t bf, InstrRegister::Access access) {}
void InstrDisasm::AddFPSCR(InstrRegister::Access access) {}
void InstrDisasm::AddRegOperand(InstrRegister::RegisterSet set,
uint32_t ordinal, InstrRegister::Access access,
const char* display) {}
void InstrDisasm::AddSImmOperand(uint64_t value, size_t width,
const char* display) {}
void InstrDisasm::AddUImmOperand(uint64_t value, size_t width,
const char* display) {}
int InstrDisasm::Finish() { return 0; }
void InstrDisasm::Dump(std::string& out_str, size_t pad) {
out_str = name;
if (flags & InstrDisasm::kOE) {
out_str += "o";
}
if (flags & InstrDisasm::kRc) {
out_str += ".";
}
if (flags & InstrDisasm::kLR) {
out_str += "l";
}
}
InstrType* GetInstrType(uint32_t code) {
// Fast lookup via tables.
InstrType* slot = NULL;
switch (code >> 26) {
case 4:
// Opcode = 4, index = bits 10-0 (10)
slot = tables::instr_table_4[select_bits(code, 0, 10)];
break;
case 19:
// Opcode = 19, index = bits 10-1 (10)
slot = tables::instr_table_19[select_bits(code, 1, 10)];
break;
case 30:
// Opcode = 30, index = bits 4-1 (4)
// Special cased to an uber instruction.
slot = tables::instr_table_30[select_bits(code, 0, 0)];
break;
case 31:
// Opcode = 31, index = bits 10-1 (10)
slot = tables::instr_table_31[select_bits(code, 1, 10)];
break;
case 58:
// Opcode = 58, index = bits 1-0 (2)
slot = tables::instr_table_58[select_bits(code, 0, 1)];
break;
case 59:
// Opcode = 59, index = bits 5-1 (5)
slot = tables::instr_table_59[select_bits(code, 1, 5)];
break;
case 62:
// Opcode = 62, index = bits 1-0 (2)
slot = tables::instr_table_62[select_bits(code, 0, 1)];
break;
case 63:
// Opcode = 63, index = bits 10-1 (10)
slot = tables::instr_table_63[select_bits(code, 1, 10)];
break;
default:
slot = tables::instr_table[select_bits(code, 26, 31)];
break;
}
if (slot && slot->opcode) {
return slot;
}
// Slow lookup via linear scan.
// This is primarily due to laziness. It could be made fast like the others.
for (size_t n = 0; n < xe::countof(tables::instr_table_scan); n++) {
slot = &(tables::instr_table_scan[n]);
if (slot->opcode == (code & slot->opcode_mask)) {
return slot;
}
}
return NULL;
}
} // namespace ppc
} // namespace cpu
} // namespace xe

View File

@ -21,80 +21,8 @@ namespace xe {
namespace cpu {
namespace ppc {
constexpr uint32_t make_bitmask(uint32_t a, uint32_t b) {
return (static_cast<uint32_t>(-1) >> (31 - b)) & ~((1u << a) - 1);
}
constexpr uint32_t select_bits(uint32_t value, uint32_t a, uint32_t b) {
return (value & make_bitmask(a, b)) >> a;
}
// TODO(benvanik): rename these
typedef enum {
kXEPPCInstrFormatI = 0,
kXEPPCInstrFormatB = 1,
kXEPPCInstrFormatSC = 2,
kXEPPCInstrFormatD = 3,
kXEPPCInstrFormatDS = 4,
kXEPPCInstrFormatX = 5,
kXEPPCInstrFormatXL = 6,
kXEPPCInstrFormatXFX = 7,
kXEPPCInstrFormatXFL = 8,
kXEPPCInstrFormatXS = 9,
kXEPPCInstrFormatXO = 10,
kXEPPCInstrFormatA = 11,
kXEPPCInstrFormatM = 12,
kXEPPCInstrFormatMD = 13,
kXEPPCInstrFormatMDS = 14,
kXEPPCInstrFormatVXA = 15,
kXEPPCInstrFormatVX = 16,
kXEPPCInstrFormatVXR = 17,
kXEPPCInstrFormatVX128 = 18,
kXEPPCInstrFormatVX128_1 = 19,
kXEPPCInstrFormatVX128_2 = 20,
kXEPPCInstrFormatVX128_3 = 21,
kXEPPCInstrFormatVX128_4 = 22,
kXEPPCInstrFormatVX128_5 = 23,
kXEPPCInstrFormatVX128_P = 24,
kXEPPCInstrFormatVX128_R = 25,
kXEPPCInstrFormatXDSS = 26,
} xe_ppc_instr_format_e;
enum xe_ppc_instr_mask_e : uint32_t {
kXEPPCInstrMaskVXR = 0xFC0003FF,
kXEPPCInstrMaskVXA = 0xFC00003F,
kXEPPCInstrMaskVX128 = 0xFC0003D0,
kXEPPCInstrMaskVX128_1 = 0xFC0007F3,
kXEPPCInstrMaskVX128_2 = 0xFC000210,
kXEPPCInstrMaskVX128_3 = 0xFC0007F0,
kXEPPCInstrMaskVX128_4 = 0xFC000730,
kXEPPCInstrMaskVX128_5 = 0xFC000010,
kXEPPCInstrMaskVX128_P = 0xFC000630,
kXEPPCInstrMaskVX128_R = 0xFC000390,
};
class InstrType;
constexpr int64_t XEEXTS16(uint32_t v) { return (int64_t)((int16_t)v); }
constexpr int64_t XEEXTS26(uint32_t v) {
return (int64_t)(v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v));
}
constexpr uint64_t XEEXTZ16(uint32_t v) { return (uint64_t)((uint16_t)v); }
static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
// if mstart ≤ mstop then
// mask[mstart:mstop] = ones
// mask[all other bits] = zeros
// else
// mask[mstart:63] = ones
// mask[0:mstop] = ones
// mask[all other bits] = zeros
mstart &= 0x3F;
mstop &= 0x3F;
uint64_t value =
(UINT64_MAX >> mstart) ^ ((mstop >= 63) ? 0 : UINT64_MAX >> (mstop + 1));
return mstart <= mstop ? value : ~value;
}
// DEPRECATED
// TODO(benvanik): move code to PPCDecodeData.
struct InstrData {
PPCOpcode opcode;
const PPCOpcodeInfo* opcode_info;
@ -235,6 +163,17 @@ struct InstrData {
uint32_t RT : 5;
uint32_t : 6;
} MDS;
// kXEPPCInstrFormatMDSH
struct {
uint32_t Rc : 1;
uint32_t idx : 4;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} MDSH;
// kXEPPCInstrFormatVXA
struct {
uint32_t : 6;
@ -385,120 +324,6 @@ struct InstrData {
};
};
typedef struct {
enum RegisterSet {
kXER,
kLR,
kCTR,
kCR, // 0-7
kFPSCR,
kGPR, // 0-31
kFPR, // 0-31
kVMX, // 0-127
};
enum Access {
kRead = 1 << 0,
kWrite = 1 << 1,
kReadWrite = kRead | kWrite,
};
RegisterSet set;
uint32_t ordinal;
Access access;
} InstrRegister;
typedef struct {
enum OperandType {
kRegister,
kImmediate,
};
OperandType type;
const char* display;
union {
InstrRegister reg;
struct {
bool is_signed;
uint64_t value;
size_t width;
} imm;
};
void Dump(std::string& out_str);
} InstrOperand;
class InstrAccessBits {
public:
InstrAccessBits()
: spr(0),
cr(0),
gpr(0),
fpr(0),
vr31_0(0),
vr63_32(0),
vr95_64(0),
vr127_96(0) {}
// Bitmasks derived from the accesses to registers.
// Format is 2 bits for each register, even bits indicating reads and odds
// indicating writes.
uint64_t spr; // fpcsr/ctr/lr/xer
uint64_t cr; // cr7/6/5/4/3/2/1/0
uint64_t gpr; // r31-0
uint64_t fpr; // f31-0
uint64_t vr31_0;
uint64_t vr63_32;
uint64_t vr95_64;
uint64_t vr127_96;
void Clear();
void Extend(InstrAccessBits& other);
void MarkAccess(InstrRegister& reg);
void Dump(std::string& out_str);
};
class InstrDisasm {
public:
enum Flags {
kOE = 1 << 0,
kRc = 1 << 1,
kCA = 1 << 2,
kLR = 1 << 4,
kFP = 1 << 5,
kVMX = 1 << 6,
};
const char* name;
const char* info;
uint32_t flags;
void Init(const char* new_name, const char* new_info, uint32_t new_flags);
void AddLR(InstrRegister::Access access);
void AddCTR(InstrRegister::Access access);
void AddCR(uint32_t bf, InstrRegister::Access access);
void AddFPSCR(InstrRegister::Access access);
void AddRegOperand(InstrRegister::RegisterSet set, uint32_t ordinal,
InstrRegister::Access access, const char* display = NULL);
void AddSImmOperand(uint64_t value, size_t width, const char* display = NULL);
void AddUImmOperand(uint64_t value, size_t width, const char* display = NULL);
int Finish();
void Dump(std::string& out_str, size_t pad = 13);
};
typedef void (*InstrDisasmFn)(const InstrData& i, StringBuffer* str);
class InstrType {
public:
uint32_t opcode;
uint32_t opcode_mask; // Only used for certain opcodes (altivec, etc).
uint32_t format; // xe_ppc_instr_format_e
InstrDisasmFn disasm;
};
InstrType* GetInstrType(uint32_t code);
} // namespace ppc
} // namespace cpu
} // namespace xe

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ namespace xe {
namespace cpu {
namespace ppc {
// All PPC opcodes in the same order they appear in ppc_instr_table.h:
// All PPC opcodes in the same order they appear in ppc_opcode_table.h:
enum class PPCOpcode : uint32_t {
addcx,
addex,
@ -54,8 +54,6 @@ enum class PPCOpcode : uint32_t {
divdx,
divwux,
divwx,
eciwx,
ecowx,
eieio,
eqvx,
extsbx,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/ppc/ppc_decode_data.h"
namespace xe {
namespace cpu {
namespace ppc {
bool DisasmPPC(uint32_t address, uint32_t code, StringBuffer* str) {
auto opcode = LookupOpcode(code);
if (opcode == PPCOpcode::kInvalid) {
str->Append("DISASM ERROR");
return false;
}
auto& disasm_info = GetOpcodeDisasmInfo(opcode);
if (disasm_info.disasm) {
PPCDecodeData d;
d.address = address;
d.code = code;
disasm_info.disasm(d, str);
} else {
str->AppendFormat("%-8s", disasm_info.name);
}
return true;
}
} // namespace ppc
} // namespace cpu
} // namespace xe

View File

@ -1,4 +1,4 @@
/**
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
@ -25,13 +25,23 @@ class PPCHIRBuilder;
enum class PPCOpcodeFormat {
kSC,
kD,
kDS,
kB,
kI,
kX,
kXL,
kXFX,
kXFL,
kXS,
kXO,
kA,
kM,
kMD,
kMDS,
kDCBZ,
kVX,
kVC,
kVA,
kVX128,
kVX128_1,
kVX128_2,
@ -40,18 +50,6 @@ enum class PPCOpcodeFormat {
kVX128_5,
kVX128_R,
kVX128_P,
kVC,
kVA,
kXO,
kXW,
kA,
kDS,
kM,
kMD,
kMDS,
kMDSH,
kXS,
kDCBZ,
};
enum class PPCOpcodeGroup {
@ -65,32 +63,97 @@ enum class PPCOpcodeType {
kSync,
};
typedef void (*InstrDisasmFn1)(const InstrData* i, StringBuffer* str);
typedef int (*InstrEmitFn)(PPCHIRBuilder& f, const InstrData& i);
struct PPCOpcodeInfo {
PPCOpcodeType type;
InstrEmitFn emit;
};
struct PPCDecodeData;
typedef void (*InstrDisasmFn)(const PPCDecodeData& d, StringBuffer* str);
enum class PPCOpcodeField : uint32_t {
kRA,
kRA0, // 0 if RA==0 else RA
kRB,
kRD,
kRS, // alias for RD
kOE,
kOEcond, // iff OE=1
kCR,
kCRcond, // iff Rc=1
kCA,
kCRM,
kIMM,
kSIMM,
kUIMM,
kd, // displacement
kds,
kLR,
kLRcond,
kADDR,
kBI,
kBO,
kCTR,
kCTRcond,
kL,
kLK,
kAA,
kCRFD,
kCRFS,
kCRBA,
kCRBB,
kCRBD,
kFPSCR,
kFPSCRD,
kMSR,
kSPR,
kVSCR,
kTBR,
kFM,
kFA,
kFB,
kFC,
kFD,
kFS,
kVA,
kVB,
kVC,
kVD,
kVS,
kSH,
kSHB,
kME,
kMB,
kTO,
};
struct PPCOpcodeDisasmInfo {
PPCOpcodeGroup group;
PPCOpcodeFormat format;
uint32_t opcode;
const char* name;
PPCOpcodeFormat format;
PPCOpcodeGroup group;
PPCOpcodeType type;
const char* description;
InstrDisasmFn1 disasm;
InstrEmitFn emit;
std::vector<PPCOpcodeField> reads;
std::vector<PPCOpcodeField> writes;
InstrDisasmFn disasm;
};
PPCOpcode LookupOpcode(uint32_t code);
const PPCOpcodeInfo& GetOpcodeInfo(PPCOpcode opcode);
const PPCOpcodeDisasmInfo& GetOpcodeDisasmInfo(PPCOpcode opcode);
void RegisterOpcodeDisasm(PPCOpcode opcode, InstrDisasmFn1 fn);
void RegisterOpcodeEmitter(PPCOpcode opcode, InstrEmitFn fn);
void RegisterOpcodeDisasm(PPCOpcode opcode, InstrDisasmFn fn);
inline const PPCOpcodeInfo& LookupOpcodeInfo(uint32_t code) {
return GetOpcodeInfo(LookupOpcode(code));
}
bool DisasmPPC(uint32_t address, uint32_t code, StringBuffer* str);
} // namespace ppc
} // namespace cpu
} // namespace xe

View File

@ -371,7 +371,6 @@ PPCOpcode LookupOpcode(uint32_t code) {
case 0b0100010110: PPC_DECODER_HIT(dcbt);
case 0b0100010111: PPC_DECODER_HIT(lhzx);
case 0b0100011100: PPC_DECODER_HIT(eqvx);
case 0b0100110110: PPC_DECODER_HIT(eciwx);
case 0b0100110111: PPC_DECODER_HIT(lhzux);
case 0b0100111100: PPC_DECODER_HIT(xorx);
case 0b0101010011: PPC_DECODER_HIT(mfspr);
@ -383,7 +382,6 @@ PPCOpcode LookupOpcode(uint32_t code) {
case 0b0101110111: PPC_DECODER_HIT(lhaux);
case 0b0110010111: PPC_DECODER_HIT(sthx);
case 0b0110011100: PPC_DECODER_HIT(orcx);
case 0b0110110110: PPC_DECODER_HIT(ecowx);
case 0b0110110111: PPC_DECODER_HIT(sthux);
case 0b0110111100: PPC_DECODER_HIT(orx);
case 0b0111010011: PPC_DECODER_HIT(mtspr);

View File

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

View File

@ -15,8 +15,8 @@
#include "xenia/base/logging.h"
#include "xenia/base/memory.h"
#include "xenia/base/profiling.h"
#include "xenia/cpu/ppc/ppc_decode_data.h"
#include "xenia/cpu/ppc/ppc_frontend.h"
#include "xenia/cpu/ppc/ppc_instr.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/processor.h"
@ -79,9 +79,9 @@ bool PPCScanner::Scan(GuestFunction* function, DebugInfo* debug_info) {
auto opcode = LookupOpcode(code);
InstrData i;
i.address = address;
i.code = code;
PPCDecodeData d;
d.address = address;
d.code = code;
// TODO(benvanik): switch on instruction metadata.
++address_reference_count;
@ -91,7 +91,7 @@ bool PPCScanner::Scan(GuestFunction* function, DebugInfo* debug_info) {
// of whether or not this is a normal function with a prolog/epilog.
// Some valid leaf functions won't have this, but most will.
if (address == start_address && opcode == PPCOpcode::mfspr &&
(((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F)) == 8) {
(((d.XFX.SPR() & 0x1F) << 5) | ((d.XFX.SPR() >> 5) & 0x1F)) == 8) {
starts_with_mfspr_lr = true;
}
@ -135,10 +135,8 @@ bool PPCScanner::Scan(GuestFunction* function, DebugInfo* debug_info) {
ends_block = true;
} else if (opcode == PPCOpcode::bx) {
// b/ba/bl/bla
uint32_t target =
(uint32_t)XEEXTS26(i.I.LI << 2) + (i.I.AA ? 0 : (int32_t)address);
if (i.I.LK) {
uint32_t target = d.I.ADDR();
if (d.I.LK()) {
LOGPPC("bl %.8X -> %.8X", address, target);
// Queue call target if needed.
// GetOrInsertFunction(target);
@ -213,9 +211,8 @@ bool PPCScanner::Scan(GuestFunction* function, DebugInfo* debug_info) {
ends_block = true;
} else if (opcode == PPCOpcode::bcx) {
// bc/bca/bcl/bcla
uint32_t target =
(uint32_t)XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)address);
if (i.B.LK) {
uint32_t target = d.B.ADDR();
if (d.B.LK()) {
LOGPPC("bcl %.8X -> %.8X", address, target);
// Queue call target if needed.
@ -234,7 +231,7 @@ bool PPCScanner::Scan(GuestFunction* function, DebugInfo* debug_info) {
ends_block = true;
} else if (opcode == PPCOpcode::bclrx) {
// bclr/bclrl
if (i.XL.LK) {
if (d.XL.LK()) {
LOGPPC("bclrl %.8X", address);
} else {
LOGPPC("bclr %.8X", address);
@ -242,7 +239,7 @@ bool PPCScanner::Scan(GuestFunction* function, DebugInfo* debug_info) {
ends_block = true;
} else if (opcode == PPCOpcode::bcctrx) {
// bcctr/bcctrl
if (i.XL.LK) {
if (d.XL.LK()) {
LOGPPC("bcctrl %.8X", address);
} else {
LOGPPC("bcctr %.8X", address);

View File

@ -18,16 +18,13 @@
#include "xenia/base/reset_scope.h"
#include "xenia/cpu/compiler/compiler_passes.h"
#include "xenia/cpu/cpu_flags.h"
#include "xenia/cpu/ppc/ppc_disasm.h"
#include "xenia/cpu/ppc/ppc_frontend.h"
#include "xenia/cpu/ppc/ppc_hir_builder.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/ppc/ppc_scanner.h"
#include "xenia/cpu/processor.h"
#include "xenia/debug/debugger.h"
DEFINE_bool(preserve_hir_disasm, true,
"Preserves HIR disassembly for the debugger when it is attached.");
namespace xe {
namespace cpu {
namespace ppc {
@ -106,11 +103,6 @@ bool PPCTranslator::Translate(GuestFunction* function,
xe::make_reset_scope(&string_buffer_);
// NOTE: we only want to do this when required, as it's expensive to build.
if (FLAGS_preserve_hir_disasm && frontend_->processor()->debugger() &&
frontend_->processor()->debugger()->is_attached()) {
debug_info_flags |= DebugInfoFlags::kDebugInfoDisasmRawHir |
DebugInfoFlags::kDebugInfoDisasmHir;
}
if (FLAGS_disassemble_functions) {
debug_info_flags |= DebugInfoFlags::kDebugInfoAllDisasm;
}
@ -167,9 +159,9 @@ bool PPCTranslator::Translate(GuestFunction* function,
// Emit function.
uint32_t emit_flags = 0;
// if (debug_info) {
if (debug_info) {
emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS;
//}
}
if (!builder_->Emit(function, emit_flags)) {
return false;
}

View File

@ -19,11 +19,12 @@
#include "xenia/base/debugging.h"
#include "xenia/base/filesystem.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/string.h"
#include "xenia/base/threading.h"
#include "xenia/cpu/backend/code_cache.h"
#include "xenia/cpu/function.h"
#include "xenia/cpu/ppc/ppc_instr.h"
#include "xenia/cpu/ppc/ppc_decode_data.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/processor.h"
#include "xenia/cpu/stack_walker.h"
@ -691,11 +692,11 @@ bool TestPpcCondition(const xe::cpu::ppc::PPCContext* context, uint32_t bo,
uint32_t bi, bool check_ctr, bool check_cond) {
bool ctr_ok = true;
if (check_ctr) {
if (xe::cpu::ppc::select_bits(bo, 2, 2)) {
if (select_bits(bo, 2, 2)) {
ctr_ok = true;
} else {
uint32_t new_ctr_value = static_cast<uint32_t>(context->ctr - 1);
if (xe::cpu::ppc::select_bits(bo, 1, 1)) {
if (select_bits(bo, 1, 1)) {
ctr_ok = new_ctr_value == 0;
} else {
ctr_ok = new_ctr_value != 0;
@ -704,12 +705,12 @@ bool TestPpcCondition(const xe::cpu::ppc::PPCContext* context, uint32_t bo,
}
bool cond_ok = true;
if (check_cond) {
if (xe::cpu::ppc::select_bits(bo, 4, 4)) {
if (select_bits(bo, 4, 4)) {
cond_ok = true;
} else {
uint8_t cr = *(reinterpret_cast<const uint8_t*>(&context->cr0) +
(4 * (bi >> 2)) + (bi & 3));
if (xe::cpu::ppc::select_bits(bo, 3, 3)) {
if (select_bits(bo, 3, 3)) {
cond_ok = cr != 0;
} else {
cond_ok = cr == 0;
@ -721,44 +722,40 @@ bool TestPpcCondition(const xe::cpu::ppc::PPCContext* context, uint32_t bo,
uint32_t Debugger::CalculateNextGuestInstruction(
ThreadExecutionInfo* thread_info, uint32_t current_pc) {
xe::cpu::ppc::InstrData i;
i.address = current_pc;
i.code = xe::load_and_swap<uint32_t>(
emulator_->memory()->TranslateVirtual(i.address));
auto opcode = xe::cpu::ppc::LookupOpcode(i.code);
if (i.code == 0x4E800020) {
xe::cpu::ppc::PPCDecodeData d;
d.address = current_pc;
d.code = xe::load_and_swap<uint32_t>(
emulator_->memory()->TranslateVirtual(d.address));
auto opcode = xe::cpu::ppc::LookupOpcode(d.code);
if (d.code == 0x4E800020) {
// blr -- unconditional branch to LR.
uint32_t target_pc = static_cast<uint32_t>(thread_info->guest_context.lr);
return target_pc;
} else if (i.code == 0x4E800420) {
} else if (d.code == 0x4E800420) {
// bctr -- unconditional branch to CTR.
uint32_t target_pc = static_cast<uint32_t>(thread_info->guest_context.ctr);
return target_pc;
} else if (opcode == PPCOpcode::bx) {
// b/ba/bl/bla
uint32_t target_pc =
static_cast<uint32_t>(xe::cpu::ppc::XEEXTS26(i.I.LI << 2)) +
(i.I.AA ? 0u : i.address);
uint32_t target_pc = d.I.ADDR();
return target_pc;
} else if (opcode == PPCOpcode::bcx) {
// bc/bca/bcl/bcla
uint32_t target_pc =
static_cast<uint32_t>(xe::cpu::ppc::XEEXTS16(i.B.BD << 2)) +
(i.B.AA ? 0u : i.address);
bool test_passed = TestPpcCondition(&thread_info->guest_context, i.B.BO,
i.B.BI, true, true);
uint32_t target_pc = d.B.ADDR();
bool test_passed = TestPpcCondition(&thread_info->guest_context, d.B.BO(),
d.B.BI(), true, true);
return test_passed ? target_pc : current_pc + 4;
} else if (opcode == PPCOpcode::bclrx) {
// bclr/bclrl
uint32_t target_pc = static_cast<uint32_t>(thread_info->guest_context.lr);
bool test_passed = TestPpcCondition(&thread_info->guest_context, i.XL.BO,
i.XL.BI, true, true);
bool test_passed = TestPpcCondition(&thread_info->guest_context, d.XL.BO(),
d.XL.BI(), true, true);
return test_passed ? target_pc : current_pc + 4;
} else if (opcode == PPCOpcode::bcctrx) {
// bcctr/bcctrl
uint32_t target_pc = static_cast<uint32_t>(thread_info->guest_context.ctr);
bool test_passed = TestPpcCondition(&thread_info->guest_context, i.XL.BO,
i.XL.BI, false, true);
bool test_passed = TestPpcCondition(&thread_info->guest_context, d.XL.BO(),
d.XL.BI(), false, true);
return test_passed ? target_pc : current_pc + 4;
} else {
return current_pc + 4;

View File

@ -25,7 +25,7 @@
#include "xenia/base/platform.h"
#include "xenia/base/string_util.h"
#include "xenia/base/threading.h"
#include "xenia/cpu/ppc/ppc_disasm.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/stack_walker.h"
#include "xenia/gpu/graphics_system.h"
#include "xenia/kernel/xmodule.h"
@ -571,7 +571,7 @@ void DebugWindow::DrawMachineCodeSource(const uint8_t* machine_code_ptr,
ImGui::Text(" %c ", is_current_instr ? '>' : ' ');
ImGui::SameLine();
ImGui::Text(" %.8X %-8s %s", uint32_t(insn.address), insn.mnemonic,
ImGui::Text(" %.8X %-10s %s", uint32_t(insn.address), insn.mnemonic,
insn.op_str);
if (is_current_instr) {

File diff suppressed because it is too large Load Diff

View File

@ -48,9 +48,8 @@ extended_opcode_bits = {
'XW': [(25, 30)],
'A': [(26, 30)],
'DS': [(30, 31)],
'MD': [(27, 30)],
'MD': [(27, 29)],
'MDS': [(27, 30)],
'MDSH': [(27, 29)],
'XS': [(21, 29)],
'DCBZ': [(6, 10), (21, 30)], # like X
}
@ -84,7 +83,6 @@ def parse_insns(filename):
i.opcode = int(e.attrib['opcode'], 16)
i.mnem = e.attrib['mnem']
i.form = e.attrib['form']
i.subform = e.attrib['sub-form']
i.group = e.attrib['group']
i.desc = e.attrib['desc']
i.type = 'General'
@ -92,6 +90,17 @@ def parse_insns(filename):
i.type = 'Sync'
i.op_primary = opcode_primary(i.opcode)
i.op_extended = opcode_extended(i.opcode, i.form)
i.reads = []
i.writes = []
for r in e.findall('.//in'):
is_conditional = 'conditional' in r.attrib and r.attrib['conditional'] == 'true'
i.reads.append((r.attrib['field'], is_conditional))
for w in e.findall('.//out'):
is_conditional = 'conditional' in w.attrib and w.attrib['conditional'] == 'true'
i.writes.append((w.attrib['field'], is_conditional))
i.disasm_str = None
for d in e.findall('.//disasm'):
i.disasm_str = d.text
insns.append(i)
return insns
@ -100,13 +109,6 @@ def c_mnem(x):
return x.replace('.', 'x')
def c_subform(x):
x = x.replace('-', '_')
if x[0] >= '0' and x[0] <= '9':
x = '_' + x
return x
def c_group(x):
return 'k' + x[0].upper() + x[1:]
@ -115,6 +117,12 @@ def c_bool(x):
return 'true' if x else 'false'
def c_field(x):
base_name = 'k' + x[0]
cond_name = 'cond' if x[1] else ''
return base_name + cond_name
def generate_opcodes(insns):
l = []
TAB = ' ' * 2
@ -137,7 +145,6 @@ def generate_opcodes(insns):
for i in insns:
i.mnem = c_mnem(i.mnem)
i.subform = c_subform(i.subform)
insns = sorted(insns, key = lambda i: i.mnem)
w0('// All PPC opcodes in the same order they appear in ppc_opcode_table.h:')
@ -182,44 +189,34 @@ def generate_table(insns):
for i in insns:
i.mnem = '"' + c_mnem(i.mnem) + '"'
i.form = c_group(i.form)
i.subform = c_subform(i.subform)
i.desc = '"' + i.desc + '"'
i.group = c_group(i.group)
i.type = c_group(i.type)
mnem_len = len(max(insns, key = lambda i: len(i.mnem)).mnem)
form_len = len(max(insns, key = lambda i: len(i.form)).form)
subform_len = len(max(insns, key = lambda i: len(i.subform)).subform)
desc_len = len(max(insns, key = lambda i: len(i.desc)).desc)
group_len = len(max(insns, key = lambda i: len(i.group)).group)
type_len = len(max(insns, key = lambda i: len(i.type)).type)
insns = sorted(insns, key = lambda i: i.mnem)
w0('#define INSTRUCTION(opcode, mnem, form, subform, group, type, desc) \\')
w0(' {opcode, mnem, PPCOpcodeFormat::form, PPCOpcodeGroup::group, PPCOpcodeType::type, desc, nullptr, nullptr}')
w0('#define INSTRUCTION(opcode, mnem, form, group, type) \\')
w0(' {PPCOpcodeType::type, nullptr}')
w0('PPCOpcodeInfo ppc_opcode_table[] = {')
fmt = 'INSTRUCTION(' + ', '.join([
'0x%08x',
'%-' + str(mnem_len) + 's',
'%-' + str(form_len) + 's',
'%-' + str(subform_len) + 's',
'%-' + str(group_len) + 's',
'%-' + str(type_len) + 's',
'%-' + str(desc_len) + 's',
]) + '),'
for i in insns:
w1(fmt % (i.opcode, i.mnem, i.form, i.subform, i.group, i.type, i.desc))
w1(fmt % (i.opcode, i.mnem, i.form, i.group, i.type))
w0('};')
w0('static_assert(sizeof(ppc_opcode_table) / sizeof(PPCOpcodeInfo) == static_cast<int>(PPCOpcode::kInvalid), "PPC table mismatch - rerun ppc-table-gen");')
w0('')
w0('const PPCOpcodeInfo& GetOpcodeInfo(PPCOpcode opcode) {')
w1('return ppc_opcode_table[static_cast<int>(opcode)];')
w0('}')
w0('void RegisterOpcodeDisasm(PPCOpcode opcode, InstrDisasmFn fn) {')
w1('assert_null(ppc_opcode_table[static_cast<int>(opcode)].disasm);')
w1('ppc_opcode_table[static_cast<int>(opcode)].disasm = fn;')
w0('}')
w0('void RegisterOpcodeEmitter(PPCOpcode opcode, InstrEmitFn fn) {')
w1('assert_null(ppc_opcode_table[static_cast<int>(opcode)].emit);')
w1('ppc_opcode_table[static_cast<int>(opcode)].emit = fn;')
@ -234,6 +231,171 @@ def generate_table(insns):
return '\n'.join(l)
def literal_mnem(x):
x = x.replace('.', '_')
x = x.replace('"', '')
return x
def generate_token_append(i, token):
# Rc = . iff Rc=1
# OE = o iff OE=1
if token == 'Rc':
return 'if (d.%s.Rc()) str->Append(\'.\');' % (i.o_form)
elif token == 'OE':
return 'if (d.%s.OE()) str->Append(\'o\');' % (i.o_form)
elif token == 'LK':
return 'if (d.%s.LK()) str->Append(\'l\');' % (i.o_form)
elif token == 'AA':
return 'if (d.%s.AA()) str->Append(\'a\');' % (i.o_form)
elif token in ['RA', 'RA0', 'RB', 'RC', 'RT', 'RS', 'RD']:
return 'str->AppendFormat("r%%d", d.%s.%s());' % (i.o_form, token)
elif token in ['FA', 'FB', 'FC', 'FT', 'FS', 'FD']:
return 'str->AppendFormat("fr%%d", d.%s.%s());' % (i.o_form, token)
elif token in ['VA', 'VB', 'VC', 'VT', 'VS', 'VD']:
return 'str->AppendFormat("vr%%d", d.%s.%s());' % (i.o_form, token)
elif token in ['CRFD', 'CRFS']:
return 'str->AppendFormat("crf%%d", d.%s.%s());' % (i.o_form, token)
elif token in ['CRBA', 'CRBB', 'CRBD']:
return 'str->AppendFormat("crb%%d", d.%s.%s());' % (i.o_form, token)
elif token in ['BO', 'BI', 'TO', 'SPR', 'TBR', 'L', 'FM', 'MB', 'ME', 'SH', 'IMM', 'z']:
return 'str->AppendFormat("%%d", d.%s.%s());' % (i.o_form, token)
elif token == 'UIMM':
return 'str->AppendFormat("0x%%X", d.%s.%s());' % (i.o_form, token)
elif token in ['d', 'ds', 'SIMM']:
return 'str->AppendFormat(d.%s.%s() < 0 ? "-0x%%X" : "0x%%X", std::abs(d.%s.%s()));' % (i.o_form, token, i.o_form, token)
elif token == 'ADDR':
return 'str->AppendFormat("0x%%X", d.%s.%s());' % (i.o_form, token)
return 'str->AppendFormat("(UNHANDLED %s)");' % token
def generate_disasm(insns):
l = []
TAB = ' ' * 2
def w0(x): l.append(x)
def w1(x): w0(TAB * 1 + x)
def w2(x): w0(TAB * 2 + x)
def w3(x): w0(TAB * 3 + x)
w0('// This code was autogenerated by %s. Do not modify!' % (sys.argv[0]))
w0('// clang-format off')
w0('#include <cstdint>')
w0('')
w0('#include "xenia/base/assert.h"')
w0('#include "xenia/cpu/ppc/ppc_decode_data.h"')
w0('#include "xenia/cpu/ppc/ppc_opcode.h"')
w0('#include "xenia/cpu/ppc/ppc_opcode_info.h"')
w0('')
w0('namespace xe {')
w0('namespace cpu {')
w0('namespace ppc {')
w0('')
w0('constexpr size_t kNamePad = 11;')
w0('const uint8_t kSpaces[kNamePad] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};')
w0('void PadStringBuffer(StringBuffer* str, size_t base, size_t pad) {')
w1('size_t added_len = str->length() - base;')
w1('if (added_len < pad) str->AppendBytes(kSpaces, kNamePad - added_len);')
w0('}')
w0('')
for i in insns:
i.mnem = '"' + c_mnem(i.mnem) + '"'
i.o_form = i.form
i.form = c_group(i.form)
i.desc = '"' + i.desc + '"'
i.group = c_group(i.group)
i.type = c_group(i.type)
mnem_len = len(max(insns, key = lambda i: len(i.mnem)).mnem)
form_len = len(max(insns, key = lambda i: len(i.form)).form)
desc_len = len(max(insns, key = lambda i: len(i.desc)).desc)
group_len = len(max(insns, key = lambda i: len(i.group)).group)
type_len = len(max(insns, key = lambda i: len(i.type)).type)
insns = sorted(insns, key = lambda i: i.mnem)
# TODO(benvanik): support alts:
# <disasm cond="![RA]">li [RD], [SIMM]</disasm>
for i in insns:
if not i.disasm_str:
continue
w0('void PrintDisasm_%s(const PPCDecodeData& d, StringBuffer* str) {' % (literal_mnem(i.mnem)))
w1('// ' + i.disasm_str)
w1('size_t str_start = str->length();')
current_str = ''
j = 0
first_space = False
while j < len(i.disasm_str):
c = i.disasm_str[j]
if c == '[':
if current_str:
w1('str->Append("%s");' % (current_str))
current_str = ''
token = i.disasm_str[j + 1 : i.disasm_str.index(']', j)]
j += len(token) + 1
w1(generate_token_append(i, token))
else:
if c == ' ' and not first_space:
if current_str:
w1('str->Append("%s");' % (current_str))
current_str = ''
w1('PadStringBuffer(str, str_start, kNamePad);')
first_space = True
else:
current_str += c
j += 1
if current_str:
w1('str->Append("%s");' % (current_str))
if not first_space:
w1('PadStringBuffer(str, str_start, kNamePad);')
w0('}')
w0('#define INIT_LIST(...) {__VA_ARGS__}')
w0('#define INSTRUCTION(opcode, mnem, form, group, type, desc, reads, writes, fn) \\')
w0(' {PPCOpcodeGroup::group, PPCOpcodeFormat::form, opcode, mnem, desc, INIT_LIST reads, INIT_LIST writes, fn}')
w0('PPCOpcodeDisasmInfo ppc_opcode_disasm_table[] = {')
fmt = 'INSTRUCTION(' + ', '.join([
'0x%08x',
'%-' + str(mnem_len) + 's',
'%-' + str(form_len) + 's',
'%-' + str(group_len) + 's',
'%-' + str(type_len) + 's',
'%-' + str(desc_len) + 's',
'(%s)',
'(%s)',
'%s',
]) + '),'
for i in insns:
w1(fmt % (
i.opcode,
i.mnem,
i.form,
i.group,
i.type,
i.desc,
','.join(['PPCOpcodeField::' + c_field(r) for r in i.reads]),
','.join(['PPCOpcodeField::' + c_field(w) for w in i.writes]),
('PrintDisasm_' + literal_mnem(i.mnem)) if i.disasm_str else 'nullptr',
))
w0('};')
w0('static_assert(sizeof(ppc_opcode_disasm_table) / sizeof(PPCOpcodeDisasmInfo) == static_cast<int>(PPCOpcode::kInvalid), "PPC table mismatch - rerun ppc-table-gen");')
w0('')
w0('const PPCOpcodeDisasmInfo& GetOpcodeDisasmInfo(PPCOpcode opcode) {')
w1('return ppc_opcode_disasm_table[static_cast<int>(opcode)];')
w0('}')
w0('void RegisterOpcodeDisasm(PPCOpcode opcode, InstrDisasmFn fn) {')
w1('assert_null(ppc_opcode_disasm_table[static_cast<int>(opcode)].disasm);')
w1('ppc_opcode_disasm_table[static_cast<int>(opcode)].disasm = fn;')
w0('}')
w0('')
w0('} // namespace ppc')
w0('} // namespace cpu')
w0('} // namespace xe')
w0('')
return '\n'.join(l)
def generate_lookup(insns):
l = []
TAB = ' ' * 2
@ -356,5 +518,8 @@ if __name__ == '__main__':
with open(os.path.join(ppc_src_path, 'ppc_opcode_table.cc'), 'w') as f:
f.write(generate_table(insns))
insns = parse_insns(os.path.join(self_path, 'ppc-instructions.xml'))
with open(os.path.join(ppc_src_path, 'ppc_opcode_disasm.cc'), 'w') as f:
f.write(generate_disasm(insns))
insns = parse_insns(os.path.join(self_path, 'ppc-instructions.xml'))
with open(os.path.join(ppc_src_path, 'ppc_opcode_lookup.cc'), 'w') as f:
f.write(generate_lookup(insns))