/[pearpc]/src/cpu/cpu_generic/ppc_alu.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_alu.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (12 years, 3 months ago) by dpavlin
File size: 26802 byte(s)
import upstream CVS
1 dpavlin 1 /*
2     * PearPC
3     * ppc_alu.cc
4     *
5     * Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net)
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License version 2 as
9     * published by the Free Software Foundation.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include "debug/tracers.h"
22     #include "cpu/debug.h"
23     #include "ppc_alu.h"
24     #include "ppc_dec.h"
25     #include "ppc_exc.h"
26     #include "ppc_cpu.h"
27     #include "ppc_opc.h"
28     #include "ppc_tools.h"
29    
30     static inline uint32 ppc_mask(int MB, int ME)
31     {
32     uint32 mask;
33     if (MB <= ME) {
34     if (ME-MB == 31) {
35     mask = 0xffffffff;
36     } else {
37     mask = ((1<<(ME-MB+1))-1)<<(31-ME);
38     }
39     } else {
40     mask = ppc_word_rotl((1<<(32-MB+ME+1))-1, 31-ME);
41     }
42     return mask;
43     }
44    
45     /*
46     * addx Add
47     * .422
48     */
49     void ppc_opc_addx()
50     {
51     int rD, rA, rB;
52     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
53     gCPU.gpr[rD] = gCPU.gpr[rA] + gCPU.gpr[rB];
54     if (gCPU.current_opc & PPC_OPC_Rc) {
55     // update cr0 flags
56     ppc_update_cr0(gCPU.gpr[rD]);
57     }
58     }
59     /*
60     * addox Add with Overflow
61     * .422
62     */
63     void ppc_opc_addox()
64     {
65     int rD, rA, rB;
66     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
67     gCPU.gpr[rD] = gCPU.gpr[rA] + gCPU.gpr[rB];
68     if (gCPU.current_opc & PPC_OPC_Rc) {
69     // update cr0 flags
70     ppc_update_cr0(gCPU.gpr[rD]);
71     }
72     // update XER flags
73     PPC_ALU_ERR("addox unimplemented\n");
74     }
75     /*
76     * addcx Add Carrying
77     * .423
78     */
79     void ppc_opc_addcx()
80     {
81     int rD, rA, rB;
82     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
83     uint32 a = gCPU.gpr[rA];
84     gCPU.gpr[rD] = a + gCPU.gpr[rB];
85     // update xer
86     if (gCPU.gpr[rD] < a) {
87     gCPU.xer |= XER_CA;
88     } else {
89     gCPU.xer &= ~XER_CA;
90     }
91     if (gCPU.current_opc & PPC_OPC_Rc) {
92     // update cr0 flags
93     ppc_update_cr0(gCPU.gpr[rD]);
94     }
95     }
96     /*
97     * addcox Add Carrying with Overflow
98     * .423
99     */
100     void ppc_opc_addcox()
101     {
102     int rD, rA, rB;
103     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
104     uint32 a = gCPU.gpr[rA];
105     gCPU.gpr[rD] = a + gCPU.gpr[rB];
106     // update xer
107     if (gCPU.gpr[rD] < a) {
108     gCPU.xer |= XER_CA;
109     } else {
110     gCPU.xer &= ~XER_CA;
111     }
112     if (gCPU.current_opc & PPC_OPC_Rc) {
113     // update cr0 flags
114     ppc_update_cr0(gCPU.gpr[rD]);
115     }
116     // update XER flags
117     PPC_ALU_ERR("addcox unimplemented\n");
118     }
119     /*
120     * addex Add Extended
121     * .424
122     */
123     void ppc_opc_addex()
124     {
125     int rD, rA, rB;
126     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
127     uint32 a = gCPU.gpr[rA];
128     uint32 b = gCPU.gpr[rB];
129     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
130     gCPU.gpr[rD] = a + b + ca;
131     // update xer
132     if (ppc_carry_3(a, b, ca)) {
133     gCPU.xer |= XER_CA;
134     } else {
135     gCPU.xer &= ~XER_CA;
136     }
137     if (gCPU.current_opc & PPC_OPC_Rc) {
138     // update cr0 flags
139     ppc_update_cr0(gCPU.gpr[rD]);
140     }
141     }
142     /*
143     * addeox Add Extended with Overflow
144     * .424
145     */
146     void ppc_opc_addeox()
147     {
148     int rD, rA, rB;
149     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
150     uint32 a = gCPU.gpr[rA];
151     uint32 b = gCPU.gpr[rB];
152     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
153     gCPU.gpr[rD] = a + b + ca;
154     // update xer
155     if (ppc_carry_3(a, b, ca)) {
156     gCPU.xer |= XER_CA;
157     } else {
158     gCPU.xer &= ~XER_CA;
159     }
160     if (gCPU.current_opc & PPC_OPC_Rc) {
161     // update cr0 flags
162     ppc_update_cr0(gCPU.gpr[rD]);
163     }
164     // update XER flags
165     PPC_ALU_ERR("addeox unimplemented\n");
166     }
167     /*
168     * addi Add Immediate
169     * .425
170     */
171     void ppc_opc_addi()
172     {
173     int rD, rA;
174     uint32 imm;
175     PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rD, rA, imm);
176     gCPU.gpr[rD] = (rA ? gCPU.gpr[rA] : 0) + imm;
177     }
178     /*
179     * addic Add Immediate Carrying
180     * .426
181     */
182     void ppc_opc_addic()
183     {
184     int rD, rA;
185     uint32 imm;
186     PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rD, rA, imm);
187     uint32 a = gCPU.gpr[rA];
188     gCPU.gpr[rD] = a + imm;
189     // update XER
190     if (gCPU.gpr[rD] < a) {
191     gCPU.xer |= XER_CA;
192     } else {
193     gCPU.xer &= ~XER_CA;
194     }
195     }
196     /*
197     * addic. Add Immediate Carrying and Record
198     * .427
199     */
200     void ppc_opc_addic_()
201     {
202     int rD, rA;
203     uint32 imm;
204     PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rD, rA, imm);
205     uint32 a = gCPU.gpr[rA];
206     gCPU.gpr[rD] = a + imm;
207     // update XER
208     if (gCPU.gpr[rD] < a) {
209     gCPU.xer |= XER_CA;
210     } else {
211     gCPU.xer &= ~XER_CA;
212     }
213     // update cr0 flags
214     ppc_update_cr0(gCPU.gpr[rD]);
215     }
216     /*
217     * addis Add Immediate Shifted
218     * .428
219     */
220     void ppc_opc_addis()
221     {
222     int rD, rA;
223     uint32 imm;
224     PPC_OPC_TEMPL_D_Shift16(gCPU.current_opc, rD, rA, imm);
225     gCPU.gpr[rD] = (rA ? gCPU.gpr[rA] : 0) + imm;
226     }
227     /*
228     * addmex Add to Minus One Extended
229     * .429
230     */
231     void ppc_opc_addmex()
232     {
233     int rD, rA, rB;
234     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
235     PPC_OPC_ASSERT(rB == 0);
236     uint32 a = gCPU.gpr[rA];
237     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
238     gCPU.gpr[rD] = a + ca + 0xffffffff;
239     if (a || ca) {
240     gCPU.xer |= XER_CA;
241     } else {
242     gCPU.xer &= ~XER_CA;
243     }
244     if (gCPU.current_opc & PPC_OPC_Rc) {
245     // update cr0 flags
246     ppc_update_cr0(gCPU.gpr[rD]);
247     }
248     }
249     /*
250     * addmeox Add to Minus One Extended with Overflow
251     * .429
252     */
253     void ppc_opc_addmeox()
254     {
255     int rD, rA, rB;
256     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
257     PPC_OPC_ASSERT(rB == 0);
258     uint32 a = gCPU.gpr[rA];
259     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
260     gCPU.gpr[rD] = a + ca + 0xffffffff;
261     if (a || ca) {
262     gCPU.xer |= XER_CA;
263     } else {
264     gCPU.xer &= ~XER_CA;
265     }
266     if (gCPU.current_opc & PPC_OPC_Rc) {
267     // update cr0 flags
268     ppc_update_cr0(gCPU.gpr[rD]);
269     }
270     // update XER flags
271     PPC_ALU_ERR("addmeox unimplemented\n");
272     }
273     /*
274     * addzex Add to Zero Extended
275     * .430
276     */
277     void ppc_opc_addzex()
278     {
279     int rD, rA, rB;
280     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
281     PPC_OPC_ASSERT(rB == 0);
282     uint32 a = gCPU.gpr[rA];
283     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
284     gCPU.gpr[rD] = a + ca;
285     if ((a == 0xffffffff) && ca) {
286     gCPU.xer |= XER_CA;
287     } else {
288     gCPU.xer &= ~XER_CA;
289     }
290     // update xer
291     if (gCPU.current_opc & PPC_OPC_Rc) {
292     // update cr0 flags
293     ppc_update_cr0(gCPU.gpr[rD]);
294     }
295     }
296     /*
297     * addzeox Add to Zero Extended with Overflow
298     * .430
299     */
300     void ppc_opc_addzeox()
301     {
302     int rD, rA, rB;
303     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
304     PPC_OPC_ASSERT(rB == 0);
305     uint32 a = gCPU.gpr[rA];
306     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
307     gCPU.gpr[rD] = a + ca;
308     if ((a == 0xffffffff) && ca) {
309     gCPU.xer |= XER_CA;
310     } else {
311     gCPU.xer &= ~XER_CA;
312     }
313     // update xer
314     if (gCPU.current_opc & PPC_OPC_Rc) {
315     // update cr0 flags
316     ppc_update_cr0(gCPU.gpr[rD]);
317     }
318     // update XER flags
319     PPC_ALU_ERR("addzeox unimplemented\n");
320     }
321    
322     /*
323     * andx AND
324     * .431
325     */
326     void ppc_opc_andx()
327     {
328     int rS, rA, rB;
329     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
330     gCPU.gpr[rA] = gCPU.gpr[rS] & gCPU.gpr[rB];
331     if (gCPU.current_opc & PPC_OPC_Rc) {
332     // update cr0 flags
333     ppc_update_cr0(gCPU.gpr[rA]);
334     }
335     }
336     /*
337     * andcx AND with Complement
338     * .432
339     */
340     void ppc_opc_andcx()
341     {
342     int rS, rA, rB;
343     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
344     gCPU.gpr[rA] = gCPU.gpr[rS] & ~gCPU.gpr[rB];
345     if (gCPU.current_opc & PPC_OPC_Rc) {
346     // update cr0 flags
347     ppc_update_cr0(gCPU.gpr[rA]);
348     }
349     }
350     /*
351     * andi. AND Immediate
352     * .433
353     */
354     void ppc_opc_andi_()
355     {
356     int rS, rA;
357     uint32 imm;
358     PPC_OPC_TEMPL_D_UImm(gCPU.current_opc, rS, rA, imm);
359     gCPU.gpr[rA] = gCPU.gpr[rS] & imm;
360     // update cr0 flags
361     ppc_update_cr0(gCPU.gpr[rA]);
362     }
363     /*
364     * andis. AND Immediate Shifted
365     * .434
366     */
367     void ppc_opc_andis_()
368     {
369     int rS, rA;
370     uint32 imm;
371     PPC_OPC_TEMPL_D_Shift16(gCPU.current_opc, rS, rA, imm);
372     gCPU.gpr[rA] = gCPU.gpr[rS] & imm;
373     // update cr0 flags
374     ppc_update_cr0(gCPU.gpr[rA]);
375     }
376    
377     /*
378     * cmp Compare
379     * .442
380     */
381     static uint32 ppc_cmp_and_mask[8] = {
382     0xfffffff0,
383     0xffffff0f,
384     0xfffff0ff,
385     0xffff0fff,
386     0xfff0ffff,
387     0xff0fffff,
388     0xf0ffffff,
389     0x0fffffff,
390     };
391    
392     void ppc_opc_cmp()
393     {
394     uint32 cr;
395     int rA, rB;
396     PPC_OPC_TEMPL_X(gCPU.current_opc, cr, rA, rB);
397     cr >>= 2;
398     sint32 a = gCPU.gpr[rA];
399     sint32 b = gCPU.gpr[rB];
400     uint32 c;
401     if (a < b) {
402     c = 8;
403     } else if (a > b) {
404     c = 4;
405     } else {
406     c = 2;
407     }
408     if (gCPU.xer & XER_SO) c |= 1;
409     cr = 7-cr;
410     gCPU.cr &= ppc_cmp_and_mask[cr];
411     gCPU.cr |= c<<(cr*4);
412     }
413     /*
414     * cmpi Compare Immediate
415     * .443
416     */
417     void ppc_opc_cmpi()
418     {
419     uint32 cr;
420     int rA;
421     uint32 imm;
422     PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, cr, rA, imm);
423     cr >>= 2;
424     sint32 a = gCPU.gpr[rA];
425     sint32 b = imm;
426     uint32 c;
427     /* if (!VALGRIND_CHECK_READABLE(a, sizeof a)) {
428     ht_printf("%08x <--i\n", gCPU.pc);
429     // SINGLESTEP("");
430     }*/
431     if (a < b) {
432     c = 8;
433     } else if (a > b) {
434     c = 4;
435     } else {
436     c = 2;
437     }
438     if (gCPU.xer & XER_SO) c |= 1;
439     cr = 7-cr;
440     gCPU.cr &= ppc_cmp_and_mask[cr];
441     gCPU.cr |= c<<(cr*4);
442     }
443     /*
444     * cmpl Compare Logical
445     * .444
446     */
447     void ppc_opc_cmpl()
448     {
449     uint32 cr;
450     int rA, rB;
451     PPC_OPC_TEMPL_X(gCPU.current_opc, cr, rA, rB);
452     cr >>= 2;
453     uint32 a = gCPU.gpr[rA];
454     uint32 b = gCPU.gpr[rB];
455     uint32 c;
456     if (a < b) {
457     c = 8;
458     } else if (a > b) {
459     c = 4;
460     } else {
461     c = 2;
462     }
463     if (gCPU.xer & XER_SO) c |= 1;
464     cr = 7-cr;
465     gCPU.cr &= ppc_cmp_and_mask[cr];
466     gCPU.cr |= c<<(cr*4);
467     }
468     /*
469     * cmpli Compare Logical Immediate
470     * .445
471     */
472     void ppc_opc_cmpli()
473     {
474     uint32 cr;
475     int rA;
476     uint32 imm;
477     PPC_OPC_TEMPL_D_UImm(gCPU.current_opc, cr, rA, imm);
478     cr >>= 2;
479     uint32 a = gCPU.gpr[rA];
480     uint32 b = imm;
481     uint32 c;
482     if (a < b) {
483     c = 8;
484     } else if (a > b) {
485     c = 4;
486     } else {
487     c = 2;
488     }
489     if (gCPU.xer & XER_SO) c |= 1;
490     cr = 7-cr;
491     gCPU.cr &= ppc_cmp_and_mask[cr];
492     gCPU.cr |= c<<(cr*4);
493     }
494    
495     /*
496     * cntlzwx Count Leading Zeros Word
497     * .447
498     */
499     void ppc_opc_cntlzwx()
500     {
501     int rS, rA, rB;
502     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
503     PPC_OPC_ASSERT(rB==0);
504     uint32 n=0;
505     uint32 x=0x80000000;
506     uint32 v=gCPU.gpr[rS];
507     while (!(v & x)) {
508     n++;
509     if (n==32) break;
510     x>>=1;
511     }
512     gCPU.gpr[rA] = n;
513     if (gCPU.current_opc & PPC_OPC_Rc) {
514     // update cr0 flags
515     ppc_update_cr0(gCPU.gpr[rA]);
516     }
517     }
518    
519     /*
520     * crand Condition Register AND
521     * .448
522     */
523     void ppc_opc_crand()
524     {
525     int crD, crA, crB;
526     PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crA, crB);
527     if ((gCPU.cr & (1<<(31-crA))) && (gCPU.cr & (1<<(31-crB)))) {
528     gCPU.cr |= (1<<(31-crD));
529     } else {
530     gCPU.cr &= ~(1<<(31-crD));
531     }
532     }
533     /*
534     * crandc Condition Register AND with Complement
535     * .449
536     */
537     void ppc_opc_crandc()
538     {
539     int crD, crA, crB;
540     PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crA, crB);
541     if ((gCPU.cr & (1<<(31-crA))) && !(gCPU.cr & (1<<(31-crB)))) {
542     gCPU.cr |= (1<<(31-crD));
543     } else {
544     gCPU.cr &= ~(1<<(31-crD));
545     }
546     }
547     /*
548     * creqv Condition Register Equivalent
549     * .450
550     */
551     void ppc_opc_creqv()
552     {
553     int crD, crA, crB;
554     PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crA, crB);
555     if (((gCPU.cr & (1<<(31-crA))) && (gCPU.cr & (1<<(31-crB))))
556     || (!(gCPU.cr & (1<<(31-crA))) && !(gCPU.cr & (1<<(31-crB))))) {
557     gCPU.cr |= (1<<(31-crD));
558     } else {
559     gCPU.cr &= ~(1<<(31-crD));
560     }
561     }
562     /*
563     * crnand Condition Register NAND
564     * .451
565     */
566     void ppc_opc_crnand()
567     {
568     int crD, crA, crB;
569     PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crA, crB);
570     if (!((gCPU.cr & (1<<(31-crA))) && (gCPU.cr & (1<<(31-crB))))) {
571     gCPU.cr |= (1<<(31-crD));
572     } else {
573     gCPU.cr &= ~(1<<(31-crD));
574     }
575     }
576     /*
577     * crnor Condition Register NOR
578     * .452
579     */
580     void ppc_opc_crnor()
581     {
582     int crD, crA, crB;
583     PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crA, crB);
584     uint32 t = (1<<(31-crA)) | (1<<(31-crB));
585     if (!(gCPU.cr & t)) {
586     gCPU.cr |= (1<<(31-crD));
587     } else {
588     gCPU.cr &= ~(1<<(31-crD));
589     }
590     }
591     /*
592     * cror Condition Register OR
593     * .453
594     */
595     void ppc_opc_cror()
596     {
597     int crD, crA, crB;
598     PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crA, crB);
599     uint32 t = (1<<(31-crA)) | (1<<(31-crB));
600     if (gCPU.cr & t) {
601     gCPU.cr |= (1<<(31-crD));
602     } else {
603     gCPU.cr &= ~(1<<(31-crD));
604     }
605     }
606     /*
607     * crorc Condition Register OR with Complement
608     * .454
609     */
610     void ppc_opc_crorc()
611     {
612     int crD, crA, crB;
613     PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crA, crB);
614     if ((gCPU.cr & (1<<(31-crA))) || !(gCPU.cr & (1<<(31-crB)))) {
615     gCPU.cr |= (1<<(31-crD));
616     } else {
617     gCPU.cr &= ~(1<<(31-crD));
618     }
619     }
620     /*
621     * crxor Condition Register XOR
622     * .448
623     */
624     void ppc_opc_crxor()
625     {
626     int crD, crA, crB;
627     PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crA, crB);
628     if ((!(gCPU.cr & (1<<(31-crA))) && (gCPU.cr & (1<<(31-crB))))
629     || ((gCPU.cr & (1<<(31-crA))) && !(gCPU.cr & (1<<(31-crB))))) {
630     gCPU.cr |= (1<<(31-crD));
631     } else {
632     gCPU.cr &= ~(1<<(31-crD));
633     }
634     }
635    
636     /*
637     * divwx Divide Word
638     * .470
639     */
640     void ppc_opc_divwx()
641     {
642     int rD, rA, rB;
643     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
644     if (!gCPU.gpr[rB]) {
645     PPC_ALU_WARN("division by zero @%08x\n", gCPU.pc);
646     SINGLESTEP("");
647     }
648     sint32 a = gCPU.gpr[rA];
649     sint32 b = gCPU.gpr[rB];
650     gCPU.gpr[rD] = a / b;
651     if (gCPU.current_opc & PPC_OPC_Rc) {
652     // update cr0 flags
653     ppc_update_cr0(gCPU.gpr[rD]);
654     }
655     }
656     /*
657     * divwox Divide Word with Overflow
658     * .470
659     */
660     void ppc_opc_divwox()
661     {
662     int rD, rA, rB;
663     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
664     if (!gCPU.gpr[rB]) {
665     PPC_ALU_ERR("division by zero\n");
666     }
667     sint32 a = gCPU.gpr[rA];
668     sint32 b = gCPU.gpr[rB];
669     gCPU.gpr[rD] = a / b;
670     if (gCPU.current_opc & PPC_OPC_Rc) {
671     // update cr0 flags
672     ppc_update_cr0(gCPU.gpr[rD]);
673     }
674     // update XER flags
675     PPC_ALU_ERR("divwox unimplemented\n");
676     }
677     /*
678     * divwux Divide Word Unsigned
679     * .472
680     */
681     void ppc_opc_divwux()
682     {
683     int rD, rA, rB;
684     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
685     if (!gCPU.gpr[rB]) {
686     PPC_ALU_WARN("division by zero @%08x\n", gCPU.pc);
687     SINGLESTEP("");
688     }
689     gCPU.gpr[rD] = gCPU.gpr[rA] / gCPU.gpr[rB];
690     if (gCPU.current_opc & PPC_OPC_Rc) {
691     // update cr0 flags
692     ppc_update_cr0(gCPU.gpr[rD]);
693     }
694     }
695     /*
696     * divwuox Divide Word Unsigned with Overflow
697     * .472
698     */
699     void ppc_opc_divwuox()
700     {
701     int rD, rA, rB;
702     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
703     if (!gCPU.gpr[rB]) {
704     // PPC_ALU_ERR("division by zero\n");
705     }
706     gCPU.gpr[rD] = gCPU.gpr[rA] / gCPU.gpr[rB];
707     if (gCPU.current_opc & PPC_OPC_Rc) {
708     // update cr0 flags
709     ppc_update_cr0(gCPU.gpr[rD]);
710     }
711     // update XER flags
712     PPC_ALU_ERR("divwuox unimplemented\n");
713     }
714    
715     /*
716     * eqvx Equivalent
717     * .480
718     */
719     void ppc_opc_eqvx()
720     {
721     int rS, rA, rB;
722     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
723     gCPU.gpr[rA] = ~(gCPU.gpr[rS] ^ gCPU.gpr[rB]);
724     if (gCPU.current_opc & PPC_OPC_Rc) {
725     // update cr0 flags
726     ppc_update_cr0(gCPU.gpr[rA]);
727     }
728     }
729    
730     /*
731     * extsbx Extend Sign Byte
732     * .481
733     */
734     void ppc_opc_extsbx()
735     {
736     int rS, rA, rB;
737     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
738     PPC_OPC_ASSERT(rB==0);
739     gCPU.gpr[rA] = gCPU.gpr[rS];
740     if (gCPU.gpr[rA] & 0x80) {
741     gCPU.gpr[rA] |= 0xffffff00;
742     } else {
743     gCPU.gpr[rA] &= ~0xffffff00;
744     }
745     if (gCPU.current_opc & PPC_OPC_Rc) {
746     // update cr0 flags
747     ppc_update_cr0(gCPU.gpr[rA]);
748     }
749     }
750     /*
751     * extshx Extend Sign Half Word
752     * .482
753     */
754     void ppc_opc_extshx()
755     {
756     int rS, rA, rB;
757     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
758     PPC_OPC_ASSERT(rB==0);
759     gCPU.gpr[rA] = gCPU.gpr[rS];
760     if (gCPU.gpr[rA] & 0x8000) {
761     gCPU.gpr[rA] |= 0xffff0000;
762     } else {
763     gCPU.gpr[rA] &= ~0xffff0000;
764     }
765     if (gCPU.current_opc & PPC_OPC_Rc) {
766     // update cr0 flags
767     ppc_update_cr0(gCPU.gpr[rA]);
768     }
769     }
770    
771     /*
772     * mulhwx Multiply High Word
773     * .595
774     */
775     void ppc_opc_mulhwx()
776     {
777     int rD, rA, rB;
778     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
779     sint64 a = (sint32)gCPU.gpr[rA];
780     sint64 b = (sint32)gCPU.gpr[rB];
781     sint64 c = a*b;
782     gCPU.gpr[rD] = ((uint64)c)>>32;
783     if (gCPU.current_opc & PPC_OPC_Rc) {
784     // update cr0 flags
785     ppc_update_cr0(gCPU.gpr[rD]);
786     // PPC_ALU_WARN("mulhw. correct?\n");
787     }
788     }
789     /*
790     * mulhwux Multiply High Word Unsigned
791     * .596
792     */
793     void ppc_opc_mulhwux()
794     {
795     int rD, rA, rB;
796     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
797     uint64 a = gCPU.gpr[rA];
798     uint64 b = gCPU.gpr[rB];
799     uint64 c = a*b;
800     gCPU.gpr[rD] = c>>32;
801     if (gCPU.current_opc & PPC_OPC_Rc) {
802     // update cr0 flags
803     ppc_update_cr0(gCPU.gpr[rD]);
804     }
805     }
806     /*
807     * mulli Multiply Low Immediate
808     * .598
809     */
810     void ppc_opc_mulli()
811     {
812     int rD, rA;
813     uint32 imm;
814     PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rD, rA, imm);
815     // FIXME: signed / unsigned correct?
816     gCPU.gpr[rD] = gCPU.gpr[rA] * imm;
817     }
818     /*
819     * mullwx Multiply Low Word
820     * .599
821     */
822     void ppc_opc_mullwx()
823     {
824     int rD, rA, rB;
825     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
826     gCPU.gpr[rD] = gCPU.gpr[rA] * gCPU.gpr[rB];
827     if (gCPU.current_opc & PPC_OPC_Rc) {
828     // update cr0 flags
829     ppc_update_cr0(gCPU.gpr[rD]);
830     }
831     if (gCPU.current_opc & PPC_OPC_OE) {
832     // update XER flags
833     PPC_ALU_ERR("mullwx unimplemented\n");
834     }
835     }
836    
837     /*
838     * nandx NAND
839     * .600
840     */
841     void ppc_opc_nandx()
842     {
843     int rS, rA, rB;
844     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
845     gCPU.gpr[rA] = ~(gCPU.gpr[rS] & gCPU.gpr[rB]);
846     if (gCPU.current_opc & PPC_OPC_Rc) {
847     // update cr0 flags
848     ppc_update_cr0(gCPU.gpr[rA]);
849     }
850     }
851    
852     /*
853     * negx Negate
854     * .601
855     */
856     void ppc_opc_negx()
857     {
858     int rD, rA, rB;
859     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
860     PPC_OPC_ASSERT(rB == 0);
861     gCPU.gpr[rD] = -gCPU.gpr[rA];
862     if (gCPU.current_opc & PPC_OPC_Rc) {
863     // update cr0 flags
864     ppc_update_cr0(gCPU.gpr[rD]);
865     }
866     }
867     /*
868     * negox Negate with Overflow
869     * .601
870     */
871     void ppc_opc_negox()
872     {
873     int rD, rA, rB;
874     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
875     PPC_OPC_ASSERT(rB == 0);
876     gCPU.gpr[rD] = -gCPU.gpr[rA];
877     if (gCPU.current_opc & PPC_OPC_Rc) {
878     // update cr0 flags
879     ppc_update_cr0(gCPU.gpr[rD]);
880     }
881     // update XER flags
882     PPC_ALU_ERR("negox unimplemented\n");
883     }
884     /*
885     * norx NOR
886     * .602
887     */
888     void ppc_opc_norx()
889     {
890     int rS, rA, rB;
891     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
892     gCPU.gpr[rA] = ~(gCPU.gpr[rS] | gCPU.gpr[rB]);
893     if (gCPU.current_opc & PPC_OPC_Rc) {
894     // update cr0 flags
895     ppc_update_cr0(gCPU.gpr[rA]);
896     }
897     }
898    
899     /*
900     * orx OR
901     * .603
902     */
903     void ppc_opc_orx()
904     {
905     int rS, rA, rB;
906     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
907     gCPU.gpr[rA] = gCPU.gpr[rS] | gCPU.gpr[rB];
908     if (gCPU.current_opc & PPC_OPC_Rc) {
909     // update cr0 flags
910     ppc_update_cr0(gCPU.gpr[rA]);
911     }
912     }
913     /*
914     * orcx OR with Complement
915     * .604
916     */
917     void ppc_opc_orcx()
918     {
919     int rS, rA, rB;
920     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
921     gCPU.gpr[rA] = gCPU.gpr[rS] | ~gCPU.gpr[rB];
922     if (gCPU.current_opc & PPC_OPC_Rc) {
923     // update cr0 flags
924     ppc_update_cr0(gCPU.gpr[rA]);
925     }
926     }
927     /*
928     * ori OR Immediate
929     * .605
930     */
931     void ppc_opc_ori()
932     {
933     int rS, rA;
934     uint32 imm;
935     PPC_OPC_TEMPL_D_UImm(gCPU.current_opc, rS, rA, imm);
936     gCPU.gpr[rA] = gCPU.gpr[rS] | imm;
937     }
938     /*
939     * oris OR Immediate Shifted
940     * .606
941     */
942     void ppc_opc_oris()
943     {
944     int rS, rA;
945     uint32 imm;
946     PPC_OPC_TEMPL_D_Shift16(gCPU.current_opc, rS, rA, imm);
947     gCPU.gpr[rA] = gCPU.gpr[rS] | imm;
948     }
949    
950     /*
951     * rlwimix Rotate Left Word Immediate then Mask Insert
952     * .617
953     */
954     void ppc_opc_rlwimix()
955     {
956     int rS, rA, SH, MB, ME;
957     PPC_OPC_TEMPL_M(gCPU.current_opc, rS, rA, SH, MB, ME);
958     uint32 v = ppc_word_rotl(gCPU.gpr[rS], SH);
959     uint32 mask = ppc_mask(MB, ME);
960     gCPU.gpr[rA] = (v & mask) | (gCPU.gpr[rA] & ~mask);
961     if (gCPU.current_opc & PPC_OPC_Rc) {
962     // update cr0 flags
963     ppc_update_cr0(gCPU.gpr[rA]);
964     }
965     }
966    
967     /*
968     * rlwinmx Rotate Left Word Immediate then AND with Mask
969     * .618
970     */
971     void ppc_opc_rlwinmx()
972     {
973     int rS, rA, SH, MB, ME;
974     PPC_OPC_TEMPL_M(gCPU.current_opc, rS, rA, SH, MB, ME);
975     uint32 v = ppc_word_rotl(gCPU.gpr[rS], SH);
976     uint32 mask = ppc_mask(MB, ME);
977     gCPU.gpr[rA] = v & mask;
978     if (gCPU.current_opc & PPC_OPC_Rc) {
979     // update cr0 flags
980     ppc_update_cr0(gCPU.gpr[rA]);
981     }
982     }
983     /*
984     * rlwnmx Rotate Left Word then AND with Mask
985     * .620
986     */
987     void ppc_opc_rlwnmx()
988     {
989     int rS, rA, rB, MB, ME;
990     PPC_OPC_TEMPL_M(gCPU.current_opc, rS, rA, rB, MB, ME);
991     uint32 v = ppc_word_rotl(gCPU.gpr[rS], gCPU.gpr[rB]);
992     uint32 mask = ppc_mask(MB, ME);
993     gCPU.gpr[rA] = v & mask;
994     if (gCPU.current_opc & PPC_OPC_Rc) {
995     // update cr0 flags
996     ppc_update_cr0(gCPU.gpr[rA]);
997     }
998     }
999    
1000     /*
1001     * slwx Shift Left Word
1002     * .625
1003     */
1004     void ppc_opc_slwx()
1005     {
1006     int rS, rA, rB;
1007     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
1008     uint32 s = gCPU.gpr[rB] & 0x3f;
1009     if (s > 31) {
1010     gCPU.gpr[rA] = 0;
1011     } else {
1012     gCPU.gpr[rA] = gCPU.gpr[rS] << s;
1013     }
1014     if (gCPU.current_opc & PPC_OPC_Rc) {
1015     // update cr0 flags
1016     ppc_update_cr0(gCPU.gpr[rA]);
1017     }
1018     }
1019     /*
1020     * srawx Shift Right Algebraic Word
1021     * .628
1022     */
1023     void ppc_opc_srawx()
1024     {
1025     int rS, rA, rB;
1026     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
1027     uint32 SH = gCPU.gpr[rB] & 0x3f;
1028     gCPU.gpr[rA] = gCPU.gpr[rS];
1029     gCPU.xer &= ~XER_CA;
1030     if (gCPU.gpr[rA] & 0x80000000) {
1031     uint32 ca = 0;
1032     for (uint i=0; i < SH; i++) {
1033     if (gCPU.gpr[rA] & 1) ca = 1;
1034     gCPU.gpr[rA] >>= 1;
1035     gCPU.gpr[rA] |= 0x80000000;
1036     }
1037     if (ca) gCPU.xer |= XER_CA;
1038     } else {
1039     if (SH > 31) {
1040     gCPU.gpr[rA] = 0;
1041     } else {
1042     gCPU.gpr[rA] >>= SH;
1043     }
1044     }
1045     if (gCPU.current_opc & PPC_OPC_Rc) {
1046     // update cr0 flags
1047     ppc_update_cr0(gCPU.gpr[rA]);
1048     }
1049     }
1050     /*
1051     * srawix Shift Right Algebraic Word Immediate
1052     * .629
1053     */
1054     void ppc_opc_srawix()
1055     {
1056     int rS, rA;
1057     uint32 SH;
1058     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, SH);
1059     gCPU.gpr[rA] = gCPU.gpr[rS];
1060     gCPU.xer &= ~XER_CA;
1061     if (gCPU.gpr[rA] & 0x80000000) {
1062     uint32 ca = 0;
1063     for (uint i=0; i < SH; i++) {
1064     if (gCPU.gpr[rA] & 1) ca = 1;
1065     gCPU.gpr[rA] >>= 1;
1066     gCPU.gpr[rA] |= 0x80000000;
1067     }
1068     if (ca) gCPU.xer |= XER_CA;
1069     } else {
1070     if (SH > 31) {
1071     gCPU.gpr[rA] = 0;
1072     } else {
1073     gCPU.gpr[rA] >>= SH;
1074     }
1075     }
1076     if (gCPU.current_opc & PPC_OPC_Rc) {
1077     // update cr0 flags
1078     ppc_update_cr0(gCPU.gpr[rA]);
1079     }
1080     }
1081     /*
1082     * srwx Shift Right Word
1083     * .631
1084     */
1085     void ppc_opc_srwx()
1086     {
1087     int rS, rA, rB;
1088     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
1089     uint32 v = gCPU.gpr[rB] & 0x3f;
1090     if (v > 31) {
1091     gCPU.gpr[rA] = 0;
1092     } else {
1093     gCPU.gpr[rA] = gCPU.gpr[rS] >> v;
1094     }
1095     if (gCPU.current_opc & PPC_OPC_Rc) {
1096     // update cr0 flags
1097     ppc_update_cr0(gCPU.gpr[rA]);
1098     }
1099     }
1100    
1101     /*
1102     * subfx Subtract From
1103     * .666
1104     */
1105     void ppc_opc_subfx()
1106     {
1107     int rD, rA, rB;
1108     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1109     gCPU.gpr[rD] = ~gCPU.gpr[rA] + gCPU.gpr[rB] + 1;
1110     if (gCPU.current_opc & PPC_OPC_Rc) {
1111     // update cr0 flags
1112     ppc_update_cr0(gCPU.gpr[rD]);
1113     }
1114     }
1115     /*
1116     * subfox Subtract From with Overflow
1117     * .666
1118     */
1119     void ppc_opc_subfox()
1120     {
1121     int rD, rA, rB;
1122     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1123     gCPU.gpr[rD] = ~gCPU.gpr[rA] + gCPU.gpr[rB] + 1;
1124     if (gCPU.current_opc & PPC_OPC_Rc) {
1125     // update cr0 flags
1126     ppc_update_cr0(gCPU.gpr[rD]);
1127     }
1128     // update XER flags
1129     PPC_ALU_ERR("subfox unimplemented\n");
1130     }
1131     /*
1132     * subfcx Subtract From Carrying
1133     * .667
1134     */
1135     void ppc_opc_subfcx()
1136     {
1137     int rD, rA, rB;
1138     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1139     uint32 a = gCPU.gpr[rA];
1140     uint32 b = gCPU.gpr[rB];
1141     gCPU.gpr[rD] = ~a + b + 1;
1142     // update xer
1143     if (ppc_carry_3(~a, b, 1)) {
1144     gCPU.xer |= XER_CA;
1145     } else {
1146     gCPU.xer &= ~XER_CA;
1147     }
1148     if (gCPU.current_opc & PPC_OPC_Rc) {
1149     // update cr0 flags
1150     ppc_update_cr0(gCPU.gpr[rD]);
1151     }
1152     }
1153     /*
1154     * subfcox Subtract From Carrying with Overflow
1155     * .667
1156     */
1157     void ppc_opc_subfcox()
1158     {
1159     int rD, rA, rB;
1160     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1161     uint32 a = gCPU.gpr[rA];
1162     uint32 b = gCPU.gpr[rB];
1163     gCPU.gpr[rD] = ~a + b + 1;
1164     // update xer
1165     if (ppc_carry_3(~a, b, 1)) {
1166     gCPU.xer |= XER_CA;
1167     } else {
1168     gCPU.xer &= ~XER_CA;
1169     }
1170     if (gCPU.current_opc & PPC_OPC_Rc) {
1171     // update cr0 flags
1172     ppc_update_cr0(gCPU.gpr[rD]);
1173     }
1174     // update XER flags
1175     PPC_ALU_ERR("subfcox unimplemented\n");
1176     }
1177     /*
1178     * subfex Subtract From Extended
1179     * .668
1180     */
1181     void ppc_opc_subfex()
1182     {
1183     int rD, rA, rB;
1184     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1185     uint32 a = gCPU.gpr[rA];
1186     uint32 b = gCPU.gpr[rB];
1187     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
1188     gCPU.gpr[rD] = ~a + b + ca;
1189     // update xer
1190     if (ppc_carry_3(~a, b, ca)) {
1191     gCPU.xer |= XER_CA;
1192     } else {
1193     gCPU.xer &= ~XER_CA;
1194     }
1195     if (gCPU.current_opc & PPC_OPC_Rc) {
1196     // update cr0 flags
1197     ppc_update_cr0(gCPU.gpr[rD]);
1198     }
1199     }
1200     /*
1201     * subfeox Subtract From Extended with Overflow
1202     * .668
1203     */
1204     void ppc_opc_subfeox()
1205     {
1206     int rD, rA, rB;
1207     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1208     uint32 a = gCPU.gpr[rA];
1209     uint32 b = gCPU.gpr[rB];
1210     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
1211     gCPU.gpr[rD] = ~a + b + ca;
1212     // update xer
1213     if (ppc_carry_3(~a, b, ca)) {
1214     gCPU.xer |= XER_CA;
1215     } else {
1216     gCPU.xer &= ~XER_CA;
1217     }
1218     if (gCPU.current_opc & PPC_OPC_Rc) {
1219     // update cr0 flags
1220     ppc_update_cr0(gCPU.gpr[rD]);
1221     }
1222     // update XER flags
1223     PPC_ALU_ERR("subfeox unimplemented\n");
1224     }
1225     /*
1226     * subfic Subtract From Immediate Carrying
1227     * .669
1228     */
1229     void ppc_opc_subfic()
1230     {
1231     int rD, rA;
1232     uint32 imm;
1233     PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rD, rA, imm);
1234     uint32 a = gCPU.gpr[rA];
1235     gCPU.gpr[rD] = ~a + imm + 1;
1236     // update XER
1237     if (ppc_carry_3(~a, imm, 1)) {
1238     gCPU.xer |= XER_CA;
1239     } else {
1240     gCPU.xer &= ~XER_CA;
1241     }
1242     }
1243     /*
1244     * subfmex Subtract From Minus One Extended
1245     * .670
1246     */
1247     void ppc_opc_subfmex()
1248     {
1249     int rD, rA, rB;
1250     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1251     PPC_OPC_ASSERT(rB == 0);
1252     uint32 a = gCPU.gpr[rA];
1253     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
1254     gCPU.gpr[rD] = ~a + ca + 0xffffffff;
1255     // update XER
1256     if ((a!=0xffffffff) || ca) {
1257     gCPU.xer |= XER_CA;
1258     } else {
1259     gCPU.xer &= ~XER_CA;
1260     }
1261     if (gCPU.current_opc & PPC_OPC_Rc) {
1262     // update cr0 flags
1263     ppc_update_cr0(gCPU.gpr[rD]);
1264     }
1265     }
1266     /*
1267     * subfmeox Subtract From Minus One Extended with Overflow
1268     * .670
1269     */
1270     void ppc_opc_subfmeox()
1271     {
1272     int rD, rA, rB;
1273     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1274     PPC_OPC_ASSERT(rB == 0);
1275     uint32 a = gCPU.gpr[rA];
1276     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
1277     gCPU.gpr[rD] = ~a + ca + 0xffffffff;
1278     // update XER
1279     if ((a!=0xffffffff) || ca) {
1280     gCPU.xer |= XER_CA;
1281     } else {
1282     gCPU.xer &= ~XER_CA;
1283     }
1284     if (gCPU.current_opc & PPC_OPC_Rc) {
1285     // update cr0 flags
1286     ppc_update_cr0(gCPU.gpr[rD]);
1287     }
1288     // update XER flags
1289     PPC_ALU_ERR("subfmeox unimplemented\n");
1290     }
1291     /*
1292     * subfzex Subtract From Zero Extended
1293     * .671
1294     */
1295     void ppc_opc_subfzex()
1296     {
1297     int rD, rA, rB;
1298     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1299     PPC_OPC_ASSERT(rB == 0);
1300     uint32 a = gCPU.gpr[rA];
1301     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
1302     gCPU.gpr[rD] = ~a + ca;
1303     if (!a && ca) {
1304     gCPU.xer |= XER_CA;
1305     } else {
1306     gCPU.xer &= ~XER_CA;
1307     }
1308     if (gCPU.current_opc & PPC_OPC_Rc) {
1309     // update cr0 flags
1310     ppc_update_cr0(gCPU.gpr[rD]);
1311     }
1312     }
1313     /*
1314     * subfzeox Subtract From Zero Extended with Overflow
1315     * .671
1316     */
1317     void ppc_opc_subfzeox()
1318     {
1319     int rD, rA, rB;
1320     PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB);
1321     PPC_OPC_ASSERT(rB == 0);
1322     uint32 a = gCPU.gpr[rA];
1323     uint32 ca = ((gCPU.xer&XER_CA)?1:0);
1324     gCPU.gpr[rD] = ~a + ca;
1325     if (!a && ca) {
1326     gCPU.xer |= XER_CA;
1327     } else {
1328     gCPU.xer &= ~XER_CA;
1329     }
1330     if (gCPU.current_opc & PPC_OPC_Rc) {
1331     // update cr0 flags
1332     ppc_update_cr0(gCPU.gpr[rD]);
1333     }
1334     // update XER flags
1335     PPC_ALU_ERR("subfzeox unimplemented\n");
1336     }
1337    
1338     /*
1339     * xorx XOR
1340     * .680
1341     */
1342     void ppc_opc_xorx()
1343     {
1344     int rS, rA, rB;
1345     PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
1346     gCPU.gpr[rA] = gCPU.gpr[rS] ^ gCPU.gpr[rB];
1347     if (gCPU.current_opc & PPC_OPC_Rc) {
1348     // update cr0 flags
1349     ppc_update_cr0(gCPU.gpr[rA]);
1350     }
1351     }
1352     /*
1353     * xori XOR Immediate
1354     * .681
1355     */
1356     void ppc_opc_xori()
1357     {
1358     int rS, rA;
1359     uint32 imm;
1360     PPC_OPC_TEMPL_D_UImm(gCPU.current_opc, rS, rA, imm);
1361     gCPU.gpr[rA] = gCPU.gpr[rS] ^ imm;
1362     }
1363     /*
1364     * xoris XOR Immediate Shifted
1365     * .682
1366     */
1367     void ppc_opc_xoris()
1368     {
1369     int rS, rA;
1370     uint32 imm;
1371     PPC_OPC_TEMPL_D_Shift16(gCPU.current_opc, rS, rA, imm);
1372     gCPU.gpr[rA] = gCPU.gpr[rS] ^ imm;
1373     }
1374    

  ViewVC Help
Powered by ViewVC 1.1.26