/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (12 years, 2 months ago) by dpavlin
File size: 19730 byte(s)
import upstream CVS
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