/[pearpc]/src/cpu/cpu_generic/ppc_dec.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /src/cpu/cpu_generic/ppc_dec.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 19730 byte(s)
import upstream CVS
1 dpavlin 1 /*
2     * PearPC
3     * ppc_dec.cc
4     *
5     * Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net)
6     * Portions Copyright (C) 2004 Daniel Foesch (dfoesch@cs.nmsu.edu)
7     * Portions Copyright (C) 2004 Apple Computer, Inc.
8     *
9     * This program is free software; you can redistribute it and/or modify
10     * it under the terms of the GNU General Public License version 2 as
11     * published by the Free Software Foundation.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21     */
22    
23     #include "cstring"
24    
25     #include "system/types.h"
26     #include "cpu/debug.h"
27     #include "cpu/cpu.h"
28     #include "ppc_alu.h"
29     #include "ppc_cpu.h"
30     #include "ppc_dec.h"
31     #include "ppc_exc.h"
32     #include "ppc_fpu.h"
33     #include "ppc_vec.h"
34     #include "ppc_mmu.h"
35     #include "ppc_opc.h"
36    
37     #include "io/prom/promosi.h"
38    
39     static void ppc_opc_invalid()
40     {
41     if (gCPU.pc == gPromOSIEntry && gCPU.current_opc == PROM_MAGIC_OPCODE) {
42     call_prom_osi();
43     return;
44     }
45     if (gCPU.current_opc == 0x00333301) {
46     // memset(r3, r4, r5)
47     uint32 dest = gCPU.gpr[3];
48     uint32 c = gCPU.gpr[4];
49     uint32 size = gCPU.gpr[5];
50     if (dest & 0xfff) {
51     byte *dst;
52     ppc_direct_effective_memory_handle(dest, dst);
53     uint32 a = 4096 - (dest & 0xfff);
54     memset(dst, c, a);
55     size -= a;
56     dest += a;
57     }
58     while (size >= 4096) {
59     byte *dst;
60     ppc_direct_effective_memory_handle(dest, dst);
61     memset(dst, c, 4096);
62     dest += 4096;
63     size -= 4096;
64     }
65     if (size) {
66     byte *dst;
67     ppc_direct_effective_memory_handle(dest, dst);
68     memset(dst, c, size);
69     }
70     gCPU.pc = gCPU.npc;
71     return;
72     }
73     if (gCPU.current_opc == 0x00333302) {
74     // memcpy
75     uint32 dest = gCPU.gpr[3];
76     uint32 src = gCPU.gpr[4];
77     uint32 size = gCPU.gpr[5];
78     byte *d, *s;
79     ppc_direct_effective_memory_handle(dest, d);
80     ppc_direct_effective_memory_handle(src, s);
81     while (size--) {
82     if (!(dest & 0xfff)) ppc_direct_effective_memory_handle(dest, d);
83     if (!(src & 0xfff)) ppc_direct_effective_memory_handle(src, s);
84     *d = *s;
85     src++; dest++; d++; s++;
86     }
87     gCPU.pc = gCPU.npc;
88     return;
89     }
90     fprintf(stderr, "[PPC/DEC] Bad opcode: %08x (%u:%u)\n",
91     gCPU.current_opc, PPC_OPC_MAIN(gCPU.current_opc),
92     PPC_OPC_EXT(gCPU.current_opc));
93    
94     SINGLESTEP("unknown instruction\n");
95     }
96    
97     // main opcode 19
98     static void ppc_opc_group_1()
99     {
100     uint32 ext = PPC_OPC_EXT(gCPU.current_opc);
101     if (ext & 1) {
102     // crxxx
103     if (ext <= 225) {
104     switch (ext) {
105     case 33: ppc_opc_crnor(); return;
106     case 129: ppc_opc_crandc(); return;
107     case 193: ppc_opc_crxor(); return;
108     case 225: ppc_opc_crnand(); return;
109     }
110     } else {
111     switch (ext) {
112     case 257: ppc_opc_crand(); return;
113     case 289: ppc_opc_creqv(); return;
114     case 417: ppc_opc_crorc(); return;
115     case 449: ppc_opc_cror(); return;
116     }
117     }
118     } else if (ext & (1<<9)) {
119     // bcctrx
120     if (ext == 528) {
121     ppc_opc_bcctrx();
122     return;
123     }
124     } else {
125     switch (ext) {
126     case 16: ppc_opc_bclrx(); return;
127     case 0: ppc_opc_mcrf(); return;
128     case 50: ppc_opc_rfi(); return;
129     case 150: ppc_opc_isync(); return;
130     }
131     }
132     ppc_opc_invalid();
133     }
134    
135     ppc_opc_function ppc_opc_table_group2[1015];
136    
137     // main opcode 31
138     static void ppc_opc_init_group2()
139     {
140     for (uint i=0; i<(sizeof ppc_opc_table_group2 / sizeof ppc_opc_table_group2[0]); i++) {
141     ppc_opc_table_group2[i] = ppc_opc_invalid;
142     }
143     ppc_opc_table_group2[0] = ppc_opc_cmp;
144     ppc_opc_table_group2[4] = ppc_opc_tw;
145     ppc_opc_table_group2[8] = ppc_opc_subfcx;//+
146     ppc_opc_table_group2[10] = ppc_opc_addcx;//+
147     ppc_opc_table_group2[11] = ppc_opc_mulhwux;
148     ppc_opc_table_group2[19] = ppc_opc_mfcr;
149     ppc_opc_table_group2[20] = ppc_opc_lwarx;
150     ppc_opc_table_group2[23] = ppc_opc_lwzx;
151     ppc_opc_table_group2[24] = ppc_opc_slwx;
152     ppc_opc_table_group2[26] = ppc_opc_cntlzwx;
153     ppc_opc_table_group2[28] = ppc_opc_andx;
154     ppc_opc_table_group2[32] = ppc_opc_cmpl;
155     ppc_opc_table_group2[40] = ppc_opc_subfx;
156     ppc_opc_table_group2[54] = ppc_opc_dcbst;
157     ppc_opc_table_group2[55] = ppc_opc_lwzux;
158     ppc_opc_table_group2[60] = ppc_opc_andcx;
159     ppc_opc_table_group2[75] = ppc_opc_mulhwx;
160     ppc_opc_table_group2[83] = ppc_opc_mfmsr;
161     ppc_opc_table_group2[86] = ppc_opc_dcbf;
162     ppc_opc_table_group2[87] = ppc_opc_lbzx;
163     ppc_opc_table_group2[104] = ppc_opc_negx;
164     ppc_opc_table_group2[119] = ppc_opc_lbzux;
165     ppc_opc_table_group2[124] = ppc_opc_norx;
166     ppc_opc_table_group2[136] = ppc_opc_subfex;//+
167     ppc_opc_table_group2[138] = ppc_opc_addex;//+
168     ppc_opc_table_group2[144] = ppc_opc_mtcrf;
169     ppc_opc_table_group2[146] = ppc_opc_mtmsr;
170     ppc_opc_table_group2[150] = ppc_opc_stwcx_;
171     ppc_opc_table_group2[151] = ppc_opc_stwx;
172     ppc_opc_table_group2[183] = ppc_opc_stwux;
173     ppc_opc_table_group2[200] = ppc_opc_subfzex;//+
174     ppc_opc_table_group2[202] = ppc_opc_addzex;//+
175     ppc_opc_table_group2[210] = ppc_opc_mtsr;
176     ppc_opc_table_group2[215] = ppc_opc_stbx;
177     ppc_opc_table_group2[232] = ppc_opc_subfmex;//+
178     ppc_opc_table_group2[234] = ppc_opc_addmex;
179     ppc_opc_table_group2[235] = ppc_opc_mullwx;//+
180     ppc_opc_table_group2[242] = ppc_opc_mtsrin;
181     ppc_opc_table_group2[246] = ppc_opc_dcbtst;
182     ppc_opc_table_group2[247] = ppc_opc_stbux;
183     ppc_opc_table_group2[266] = ppc_opc_addx;//+
184     ppc_opc_table_group2[278] = ppc_opc_dcbt;
185     ppc_opc_table_group2[279] = ppc_opc_lhzx;
186     ppc_opc_table_group2[284] = ppc_opc_eqvx;
187     ppc_opc_table_group2[306] = ppc_opc_tlbie;
188     ppc_opc_table_group2[310] = ppc_opc_eciwx;
189     ppc_opc_table_group2[311] = ppc_opc_lhzux;
190     ppc_opc_table_group2[316] = ppc_opc_xorx;
191     ppc_opc_table_group2[339] = ppc_opc_mfspr;
192     ppc_opc_table_group2[343] = ppc_opc_lhax;
193     ppc_opc_table_group2[370] = ppc_opc_tlbia;
194     ppc_opc_table_group2[371] = ppc_opc_mftb;
195     ppc_opc_table_group2[375] = ppc_opc_lhaux;
196     ppc_opc_table_group2[407] = ppc_opc_sthx;
197     ppc_opc_table_group2[412] = ppc_opc_orcx;
198     ppc_opc_table_group2[438] = ppc_opc_ecowx;
199     ppc_opc_table_group2[439] = ppc_opc_sthux;
200     ppc_opc_table_group2[444] = ppc_opc_orx;
201     ppc_opc_table_group2[459] = ppc_opc_divwux;//+
202     ppc_opc_table_group2[467] = ppc_opc_mtspr;
203     ppc_opc_table_group2[470] = ppc_opc_dcbi;
204     ppc_opc_table_group2[476] = ppc_opc_nandx;
205     ppc_opc_table_group2[491] = ppc_opc_divwx;//+
206     ppc_opc_table_group2[512] = ppc_opc_mcrxr;
207     ppc_opc_table_group2[533] = ppc_opc_lswx;
208     ppc_opc_table_group2[534] = ppc_opc_lwbrx;
209     ppc_opc_table_group2[535] = ppc_opc_lfsx;
210     ppc_opc_table_group2[536] = ppc_opc_srwx;
211     ppc_opc_table_group2[566] = ppc_opc_tlbsync;
212     ppc_opc_table_group2[567] = ppc_opc_lfsux;
213     ppc_opc_table_group2[595] = ppc_opc_mfsr;
214     ppc_opc_table_group2[597] = ppc_opc_lswi;
215     ppc_opc_table_group2[598] = ppc_opc_sync;
216     ppc_opc_table_group2[599] = ppc_opc_lfdx;
217     ppc_opc_table_group2[631] = ppc_opc_lfdux;
218     ppc_opc_table_group2[659] = ppc_opc_mfsrin;
219     ppc_opc_table_group2[661] = ppc_opc_stswx;
220     ppc_opc_table_group2[662] = ppc_opc_stwbrx;
221     ppc_opc_table_group2[663] = ppc_opc_stfsx;
222     ppc_opc_table_group2[695] = ppc_opc_stfsux;
223     ppc_opc_table_group2[725] = ppc_opc_stswi;
224     ppc_opc_table_group2[727] = ppc_opc_stfdx;
225     ppc_opc_table_group2[758] = ppc_opc_dcba;
226     ppc_opc_table_group2[759] = ppc_opc_stfdux;
227     ppc_opc_table_group2[790] = ppc_opc_lhbrx;
228     ppc_opc_table_group2[792] = ppc_opc_srawx;
229     ppc_opc_table_group2[824] = ppc_opc_srawix;
230     ppc_opc_table_group2[854] = ppc_opc_eieio;
231     ppc_opc_table_group2[918] = ppc_opc_sthbrx;
232     ppc_opc_table_group2[922] = ppc_opc_extshx;
233     ppc_opc_table_group2[954] = ppc_opc_extsbx;
234     ppc_opc_table_group2[982] = ppc_opc_icbi;
235     ppc_opc_table_group2[983] = ppc_opc_stfiwx;
236     ppc_opc_table_group2[1014] = ppc_opc_dcbz;
237    
238     if ((ppc_cpu_get_pvr(0) & 0xffff0000) == 0x000c0000) {
239     /* Added for Altivec support */
240     ppc_opc_table_group2[6] = ppc_opc_lvsl;
241     ppc_opc_table_group2[7] = ppc_opc_lvebx;
242     ppc_opc_table_group2[38] = ppc_opc_lvsr;
243     ppc_opc_table_group2[39] = ppc_opc_lvehx;
244     ppc_opc_table_group2[71] = ppc_opc_lvewx;
245     ppc_opc_table_group2[103] = ppc_opc_lvx;
246     ppc_opc_table_group2[135] = ppc_opc_stvebx;
247     ppc_opc_table_group2[167] = ppc_opc_stvehx;
248     ppc_opc_table_group2[199] = ppc_opc_stvewx;
249     ppc_opc_table_group2[231] = ppc_opc_stvx;
250     ppc_opc_table_group2[342] = ppc_opc_dst;
251     ppc_opc_table_group2[359] = ppc_opc_lvxl;
252     ppc_opc_table_group2[374] = ppc_opc_dstst;
253     ppc_opc_table_group2[487] = ppc_opc_stvxl;
254     ppc_opc_table_group2[822] = ppc_opc_dss;
255     }
256     }
257    
258     // main opcode 31
259     inline static void ppc_opc_group_2()
260     {
261     uint32 ext = PPC_OPC_EXT(gCPU.current_opc);
262     if (ext >= (sizeof ppc_opc_table_group2 / sizeof ppc_opc_table_group2[0])) {
263     ppc_opc_invalid();
264     }
265     ppc_opc_table_group2[ext]();
266     }
267    
268     // main opcode 59
269     static void ppc_opc_group_f1()
270     {
271     if ((gCPU.msr & MSR_FP) == 0) {
272     ppc_exception(PPC_EXC_NO_FPU);
273     return;
274     }
275     uint32 ext = PPC_OPC_EXT(gCPU.current_opc);
276     switch (ext & 0x1f) {
277     case 18: ppc_opc_fdivsx(); return;
278     case 20: ppc_opc_fsubsx(); return;
279     case 21: ppc_opc_faddsx(); return;
280     case 22: ppc_opc_fsqrtsx(); return;
281     case 24: ppc_opc_fresx(); return;
282     case 25: ppc_opc_fmulsx(); return;
283     case 28: ppc_opc_fmsubsx(); return;
284     case 29: ppc_opc_fmaddsx(); return;
285     case 30: ppc_opc_fnmsubsx(); return;
286     case 31: ppc_opc_fnmaddsx(); return;
287     }
288     ppc_opc_invalid();
289     }
290    
291     // main opcode 63
292     static void ppc_opc_group_f2()
293     {
294     if ((gCPU.msr & MSR_FP) == 0) {
295     ppc_exception(PPC_EXC_NO_FPU);
296     return;
297     }
298     uint32 ext = PPC_OPC_EXT(gCPU.current_opc);
299     if (ext & 16) {
300     switch (ext & 0x1f) {
301     case 18: ppc_opc_fdivx(); return;
302     case 20: ppc_opc_fsubx(); return;
303     case 21: ppc_opc_faddx(); return;
304     case 22: ppc_opc_fsqrtx(); return;
305     case 23: ppc_opc_fselx(); return;
306     case 25: ppc_opc_fmulx(); return;
307     case 26: ppc_opc_frsqrtex(); return;
308     case 28: ppc_opc_fmsubx(); return;
309     case 29: ppc_opc_fmaddx(); return;
310     case 30: ppc_opc_fnmsubx(); return;
311     case 31: ppc_opc_fnmaddx(); return;
312     }
313     } else {
314     switch (ext) {
315     case 0: ppc_opc_fcmpu(); return;
316     case 12: ppc_opc_frspx(); return;
317     case 14: ppc_opc_fctiwx(); return;
318     case 15: ppc_opc_fctiwzx(); return;
319     //--
320     case 32: ppc_opc_fcmpo(); return;
321     case 38: ppc_opc_mtfsb1x(); return;
322     case 40: ppc_opc_fnegx(); return;
323     case 64: ppc_opc_mcrfs(); return;
324     case 70: ppc_opc_mtfsb0x(); return;
325     case 72: ppc_opc_fmrx(); return;
326     case 134: ppc_opc_mtfsfix(); return;
327     case 136: ppc_opc_fnabsx(); return;
328     case 264: ppc_opc_fabsx(); return;
329     case 583: ppc_opc_mffsx(); return;
330     case 711: ppc_opc_mtfsfx(); return;
331     }
332     }
333     ppc_opc_invalid();
334     }
335    
336     ppc_opc_function ppc_opc_table_groupv[965];
337    
338     static void ppc_opc_init_groupv()
339     {
340     for (uint i=0; i<(sizeof ppc_opc_table_groupv / sizeof ppc_opc_table_groupv[0]);i++) {
341     ppc_opc_table_groupv[i] = ppc_opc_invalid;
342     }
343     ppc_opc_table_groupv[0] = ppc_opc_vaddubm;
344     ppc_opc_table_groupv[1] = ppc_opc_vmaxub;
345     ppc_opc_table_groupv[2] = ppc_opc_vrlb;
346     ppc_opc_table_groupv[4] = ppc_opc_vmuloub;
347     ppc_opc_table_groupv[5] = ppc_opc_vaddfp;
348     ppc_opc_table_groupv[6] = ppc_opc_vmrghb;
349     ppc_opc_table_groupv[7] = ppc_opc_vpkuhum;
350     ppc_opc_table_groupv[32] = ppc_opc_vadduhm;
351     ppc_opc_table_groupv[33] = ppc_opc_vmaxuh;
352     ppc_opc_table_groupv[34] = ppc_opc_vrlh;
353     ppc_opc_table_groupv[36] = ppc_opc_vmulouh;
354     ppc_opc_table_groupv[37] = ppc_opc_vsubfp;
355     ppc_opc_table_groupv[38] = ppc_opc_vmrghh;
356     ppc_opc_table_groupv[39] = ppc_opc_vpkuwum;
357     ppc_opc_table_groupv[64] = ppc_opc_vadduwm;
358     ppc_opc_table_groupv[65] = ppc_opc_vmaxuw;
359     ppc_opc_table_groupv[66] = ppc_opc_vrlw;
360     ppc_opc_table_groupv[70] = ppc_opc_vmrghw;
361     ppc_opc_table_groupv[71] = ppc_opc_vpkuhus;
362     ppc_opc_table_groupv[103] = ppc_opc_vpkuwus;
363     ppc_opc_table_groupv[129] = ppc_opc_vmaxsb;
364     ppc_opc_table_groupv[130] = ppc_opc_vslb;
365     ppc_opc_table_groupv[132] = ppc_opc_vmulosb;
366     ppc_opc_table_groupv[133] = ppc_opc_vrefp;
367     ppc_opc_table_groupv[134] = ppc_opc_vmrglb;
368     ppc_opc_table_groupv[135] = ppc_opc_vpkshus;
369     ppc_opc_table_groupv[161] = ppc_opc_vmaxsh;
370     ppc_opc_table_groupv[162] = ppc_opc_vslh;
371     ppc_opc_table_groupv[164] = ppc_opc_vmulosh;
372     ppc_opc_table_groupv[165] = ppc_opc_vrsqrtefp;
373     ppc_opc_table_groupv[166] = ppc_opc_vmrglh;
374     ppc_opc_table_groupv[167] = ppc_opc_vpkswus;
375     ppc_opc_table_groupv[192] = ppc_opc_vaddcuw;
376     ppc_opc_table_groupv[193] = ppc_opc_vmaxsw;
377     ppc_opc_table_groupv[194] = ppc_opc_vslw;
378     ppc_opc_table_groupv[197] = ppc_opc_vexptefp;
379     ppc_opc_table_groupv[198] = ppc_opc_vmrglw;
380     ppc_opc_table_groupv[199] = ppc_opc_vpkshss;
381     ppc_opc_table_groupv[226] = ppc_opc_vsl;
382     ppc_opc_table_groupv[229] = ppc_opc_vlogefp;
383     ppc_opc_table_groupv[231] = ppc_opc_vpkswss;
384     ppc_opc_table_groupv[256] = ppc_opc_vaddubs;
385     ppc_opc_table_groupv[257] = ppc_opc_vminub;
386     ppc_opc_table_groupv[258] = ppc_opc_vsrb;
387     ppc_opc_table_groupv[260] = ppc_opc_vmuleub;
388     ppc_opc_table_groupv[261] = ppc_opc_vrfin;
389     ppc_opc_table_groupv[262] = ppc_opc_vspltb;
390     ppc_opc_table_groupv[263] = ppc_opc_vupkhsb;
391     ppc_opc_table_groupv[288] = ppc_opc_vadduhs;
392     ppc_opc_table_groupv[289] = ppc_opc_vminuh;
393     ppc_opc_table_groupv[290] = ppc_opc_vsrh;
394     ppc_opc_table_groupv[292] = ppc_opc_vmuleuh;
395     ppc_opc_table_groupv[293] = ppc_opc_vrfiz;
396     ppc_opc_table_groupv[294] = ppc_opc_vsplth;
397     ppc_opc_table_groupv[295] = ppc_opc_vupkhsh;
398     ppc_opc_table_groupv[320] = ppc_opc_vadduws;
399     ppc_opc_table_groupv[321] = ppc_opc_vminuw;
400     ppc_opc_table_groupv[322] = ppc_opc_vsrw;
401     ppc_opc_table_groupv[325] = ppc_opc_vrfip;
402     ppc_opc_table_groupv[326] = ppc_opc_vspltw;
403     ppc_opc_table_groupv[327] = ppc_opc_vupklsb;
404     ppc_opc_table_groupv[354] = ppc_opc_vsr;
405     ppc_opc_table_groupv[357] = ppc_opc_vrfim;
406     ppc_opc_table_groupv[359] = ppc_opc_vupklsh;
407     ppc_opc_table_groupv[384] = ppc_opc_vaddsbs;
408     ppc_opc_table_groupv[385] = ppc_opc_vminsb;
409     ppc_opc_table_groupv[386] = ppc_opc_vsrab;
410     ppc_opc_table_groupv[388] = ppc_opc_vmulesb;
411     ppc_opc_table_groupv[389] = ppc_opc_vcfux;
412     ppc_opc_table_groupv[390] = ppc_opc_vspltisb;
413     ppc_opc_table_groupv[391] = ppc_opc_vpkpx;
414     ppc_opc_table_groupv[416] = ppc_opc_vaddshs;
415     ppc_opc_table_groupv[417] = ppc_opc_vminsh;
416     ppc_opc_table_groupv[418] = ppc_opc_vsrah;
417     ppc_opc_table_groupv[420] = ppc_opc_vmulesh;
418     ppc_opc_table_groupv[421] = ppc_opc_vcfsx;
419     ppc_opc_table_groupv[422] = ppc_opc_vspltish;
420     ppc_opc_table_groupv[423] = ppc_opc_vupkhpx;
421     ppc_opc_table_groupv[448] = ppc_opc_vaddsws;
422     ppc_opc_table_groupv[449] = ppc_opc_vminsw;
423     ppc_opc_table_groupv[450] = ppc_opc_vsraw;
424     ppc_opc_table_groupv[453] = ppc_opc_vctuxs;
425     ppc_opc_table_groupv[454] = ppc_opc_vspltisw;
426     ppc_opc_table_groupv[485] = ppc_opc_vctsxs;
427     ppc_opc_table_groupv[487] = ppc_opc_vupklpx;
428     ppc_opc_table_groupv[512] = ppc_opc_vsububm;
429     ppc_opc_table_groupv[513] = ppc_opc_vavgub;
430     ppc_opc_table_groupv[514] = ppc_opc_vand;
431     ppc_opc_table_groupv[517] = ppc_opc_vmaxfp;
432     ppc_opc_table_groupv[518] = ppc_opc_vslo;
433     ppc_opc_table_groupv[544] = ppc_opc_vsubuhm;
434     ppc_opc_table_groupv[545] = ppc_opc_vavguh;
435     ppc_opc_table_groupv[546] = ppc_opc_vandc;
436     ppc_opc_table_groupv[549] = ppc_opc_vminfp;
437     ppc_opc_table_groupv[550] = ppc_opc_vsro;
438     ppc_opc_table_groupv[576] = ppc_opc_vsubuwm;
439     ppc_opc_table_groupv[577] = ppc_opc_vavguw;
440     ppc_opc_table_groupv[578] = ppc_opc_vor;
441     ppc_opc_table_groupv[610] = ppc_opc_vxor;
442     ppc_opc_table_groupv[641] = ppc_opc_vavgsb;
443     ppc_opc_table_groupv[642] = ppc_opc_vnor;
444     ppc_opc_table_groupv[673] = ppc_opc_vavgsh;
445     ppc_opc_table_groupv[704] = ppc_opc_vsubcuw;
446     ppc_opc_table_groupv[705] = ppc_opc_vavgsw;
447     ppc_opc_table_groupv[768] = ppc_opc_vsububs;
448     ppc_opc_table_groupv[770] = ppc_opc_mfvscr;
449     ppc_opc_table_groupv[772] = ppc_opc_vsum4ubs;
450     ppc_opc_table_groupv[800] = ppc_opc_vsubuhs;
451     ppc_opc_table_groupv[802] = ppc_opc_mtvscr;
452     ppc_opc_table_groupv[804] = ppc_opc_vsum4shs;
453     ppc_opc_table_groupv[832] = ppc_opc_vsubuws;
454     ppc_opc_table_groupv[836] = ppc_opc_vsum2sws;
455     ppc_opc_table_groupv[896] = ppc_opc_vsubsbs;
456     ppc_opc_table_groupv[900] = ppc_opc_vsum4sbs;
457     ppc_opc_table_groupv[928] = ppc_opc_vsubshs;
458     ppc_opc_table_groupv[960] = ppc_opc_vsubsws;
459     ppc_opc_table_groupv[964] = ppc_opc_vsumsws;
460     }
461    
462     // main opcode 04
463     static void ppc_opc_group_v()
464     {
465     uint32 ext = PPC_OPC_EXT(gCPU.current_opc);
466     #ifndef __VEC_EXC_OFF__
467     if ((gCPU.msr & MSR_VEC) == 0) {
468     ppc_exception(PPC_EXC_NO_VEC);
469     return;
470     }
471     #endif
472     switch(ext & 0x1f) {
473     case 16:
474     if (gCPU.current_opc & PPC_OPC_Rc)
475     return ppc_opc_vmhraddshs();
476     else
477     return ppc_opc_vmhaddshs();
478     case 17: return ppc_opc_vmladduhm();
479     case 18:
480     if (gCPU.current_opc & PPC_OPC_Rc)
481     return ppc_opc_vmsummbm();
482     else
483     return ppc_opc_vmsumubm();
484     case 19:
485     if (gCPU.current_opc & PPC_OPC_Rc)
486     return ppc_opc_vmsumuhs();
487     else
488     return ppc_opc_vmsumuhm();
489     case 20:
490     if (gCPU.current_opc & PPC_OPC_Rc)
491     return ppc_opc_vmsumshs();
492     else
493     return ppc_opc_vmsumshm();
494     case 21:
495     if (gCPU.current_opc & PPC_OPC_Rc)
496     return ppc_opc_vperm();
497     else
498     return ppc_opc_vsel();
499     case 22: return ppc_opc_vsldoi();
500     case 23:
501     if (gCPU.current_opc & PPC_OPC_Rc)
502     return ppc_opc_vnmsubfp();
503     else
504     return ppc_opc_vmaddfp();
505     }
506     switch(ext & 0x1ff)
507     {
508     case 3: return ppc_opc_vcmpequbx();
509     case 35: return ppc_opc_vcmpequhx();
510     case 67: return ppc_opc_vcmpequwx();
511     case 99: return ppc_opc_vcmpeqfpx();
512     case 227: return ppc_opc_vcmpgefpx();
513     case 259: return ppc_opc_vcmpgtubx();
514     case 291: return ppc_opc_vcmpgtuhx();
515     case 323: return ppc_opc_vcmpgtuwx();
516     case 355: return ppc_opc_vcmpgtfpx();
517     case 387: return ppc_opc_vcmpgtsbx();
518     case 419: return ppc_opc_vcmpgtshx();
519     case 451: return ppc_opc_vcmpgtswx();
520     case 483: return ppc_opc_vcmpbfpx();
521     }
522    
523     if (ext >= (sizeof ppc_opc_table_groupv / sizeof ppc_opc_table_groupv[0])) {
524     return ppc_opc_invalid();
525     }
526     return ppc_opc_table_groupv[ext]();
527     }
528    
529     static ppc_opc_function ppc_opc_table_main[64] = {
530     &ppc_opc_invalid, // 0
531     &ppc_opc_invalid, // 1
532     &ppc_opc_invalid, // 2 (tdi on 64 bit platforms)
533     &ppc_opc_twi, // 3
534     &ppc_opc_invalid, // 4 (altivec group 1)
535     &ppc_opc_invalid, // 5
536     &ppc_opc_invalid, // 6
537     &ppc_opc_mulli, // 7
538     &ppc_opc_subfic, // 8
539     &ppc_opc_invalid, // 9
540     &ppc_opc_cmpli, // 10
541     &ppc_opc_cmpi, // 11
542     &ppc_opc_addic, // 12
543     &ppc_opc_addic_, // 13
544     &ppc_opc_addi, // 14
545     &ppc_opc_addis, // 15
546     &ppc_opc_bcx, // 16
547     &ppc_opc_sc, // 17
548     &ppc_opc_bx, // 18
549     &ppc_opc_group_1, // 19
550     &ppc_opc_rlwimix, // 20
551     &ppc_opc_rlwinmx, // 21
552     &ppc_opc_invalid, // 22
553     &ppc_opc_rlwnmx, // 23
554     &ppc_opc_ori, // 24
555     &ppc_opc_oris, // 25
556     &ppc_opc_xori, // 26
557     &ppc_opc_xoris, // 27
558     &ppc_opc_andi_, // 28
559     &ppc_opc_andis_, // 29
560     &ppc_opc_invalid, // 30 (group_rld on 64 bit platforms)
561     &ppc_opc_group_2, // 31
562     &ppc_opc_lwz, // 32
563     &ppc_opc_lwzu, // 33
564     &ppc_opc_lbz, // 34
565     &ppc_opc_lbzu, // 35
566     &ppc_opc_stw, // 36
567     &ppc_opc_stwu, // 37
568     &ppc_opc_stb, // 38
569     &ppc_opc_stbu, // 39
570     &ppc_opc_lhz, // 40
571     &ppc_opc_lhzu, // 41
572     &ppc_opc_lha, // 42
573     &ppc_opc_lhau, // 43
574     &ppc_opc_sth, // 44
575     &ppc_opc_sthu, // 45
576     &ppc_opc_lmw, // 46
577     &ppc_opc_stmw, // 47
578     &ppc_opc_lfs, // 48
579     &ppc_opc_lfsu, // 49
580     &ppc_opc_lfd, // 50
581     &ppc_opc_lfdu, // 51
582     &ppc_opc_stfs, // 52
583     &ppc_opc_stfsu, // 53
584     &ppc_opc_stfd, // 54
585     &ppc_opc_stfdu, // 55
586     &ppc_opc_invalid, // 56
587     &ppc_opc_invalid, // 57
588     &ppc_opc_invalid, // 58 (ld on 64 bit platforms)
589     &ppc_opc_group_f1, // 59
590     &ppc_opc_invalid, // 60
591     &ppc_opc_invalid, // 61
592     &ppc_opc_invalid, // 62
593     &ppc_opc_group_f2, // 63
594     };
595    
596     void FASTCALL ppc_exec_opc()
597     {
598     uint32 mainopc = PPC_OPC_MAIN(gCPU.current_opc);
599     ppc_opc_table_main[mainopc]();
600     }
601    
602     void ppc_dec_init()
603     {
604     ppc_opc_init_group2();
605     if ((ppc_cpu_get_pvr(0) & 0xffff0000) == 0x000c0000) {
606     ppc_opc_table_main[4] = ppc_opc_group_v;
607     ppc_opc_init_groupv();
608     }
609     }

  ViewVC Help
Powered by ViewVC 1.1.26