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

Contents of /src/cpu/cpu_generic/ppc_alu.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: 26802 byte(s)
import upstream CVS
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