Moving disasm to new tables.
Also adding useful CPU docs.
This commit is contained in:
parent
cd938be678
commit
cc72de0f64
Binary file not shown.
Binary file not shown.
|
@ -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)
|
|
@ -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
|
||||
|
|
|
@ -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_
|
|
@ -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
|
|
@ -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_
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
@ -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
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS;
|
||||
//}
|
||||
if (debug_info) {
|
||||
emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS;
|
||||
}
|
||||
if (!builder_->Emit(function, emit_flags)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue