/[dynamips]/upstream/dynamips-0.2.7-RC2/ppc32_exec.c
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 /upstream/dynamips-0.2.7-RC2/ppc32_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 95797 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4 *
5 * PowerPC (32-bit) step-by-step execution.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <sys/mman.h>
15 #include <fcntl.h>
16 #include <assert.h>
17
18 #include "cpu.h"
19 #include "vm.h"
20 #include "ppc32_exec.h"
21 #include "ppc32_mem.h"
22 #include "memory.h"
23 #include "insn_lookup.h"
24 #include "dynamips.h"
25
26 /* Forward declaration of instruction array */
27 static struct ppc32_insn_exec_tag ppc32_exec_tags[];
28 static insn_lookup_t *ilt = NULL;
29
30 /* ILT */
31 static forced_inline void *ppc32_exec_get_insn(int index)
32 {
33 return(&ppc32_exec_tags[index]);
34 }
35
36 static int ppc32_exec_chk_lo(struct ppc32_insn_exec_tag *tag,int value)
37 {
38 return((value & tag->mask) == (tag->value & 0xFFFF));
39 }
40
41 static int ppc32_exec_chk_hi(struct ppc32_insn_exec_tag *tag,int value)
42 {
43 return((value & (tag->mask >> 16)) == (tag->value >> 16));
44 }
45
46 /* Initialize instruction lookup table */
47 void ppc32_exec_create_ilt(void)
48 {
49 int i,count;
50
51 for(i=0,count=0;ppc32_exec_tags[i].exec;i++)
52 count++;
53
54 ilt = ilt_create("ppc32e",count,
55 (ilt_get_insn_cbk_t)ppc32_exec_get_insn,
56 (ilt_check_cbk_t)ppc32_exec_chk_lo,
57 (ilt_check_cbk_t)ppc32_exec_chk_hi);
58 }
59
60 /* Dump statistics */
61 void ppc32_dump_stats(cpu_ppc_t *cpu)
62 {
63 int i;
64
65 #if NJM_STATS_ENABLE
66 printf("\n");
67
68 for(i=0;ppc32_exec_tags[i].exec;i++)
69 printf(" * %-10s : %10llu\n",
70 ppc32_exec_tags[i].name,ppc32_exec_tags[i].count);
71
72 printf("%llu instructions executed since startup.\n",cpu->insn_exec_count);
73 #else
74 printf("Statistics support is not compiled in.\n");
75 #endif
76 }
77
78 /* Execute a memory operation */
79 static forced_inline int ppc32_exec_memop(cpu_ppc_t *cpu,int memop,
80 m_uint32_t vaddr,u_int dst_reg)
81 {
82 fastcall ppc_memop_fn fn;
83
84 fn = cpu->mem_op_fn[memop];
85 return(fn(cpu,vaddr,dst_reg));
86 }
87
88 /* Fetch an instruction */
89 static forced_inline int ppc32_exec_fetch(cpu_ppc_t *cpu,m_uint32_t ia,
90 ppc_insn_t *insn)
91 {
92 m_uint32_t exec_page,offset;
93
94 exec_page = ia & ~PPC32_MIN_PAGE_IMASK;
95
96 if (unlikely(exec_page != cpu->njm_exec_page)) {
97 cpu->njm_exec_page = exec_page;
98 cpu->njm_exec_ptr = cpu->mem_op_lookup(cpu,exec_page,PPC32_MTS_ICACHE);
99 }
100
101 offset = (ia & PPC32_MIN_PAGE_IMASK) >> 2;
102 *insn = vmtoh32(cpu->njm_exec_ptr[offset]);
103 return(0);
104 }
105
106 /* Unknown opcode */
107 static fastcall int ppc32_exec_unknown(cpu_ppc_t *cpu,ppc_insn_t insn)
108 {
109 printf("PPC32: unknown opcode 0x%8.8x at ia = 0x%x\n",insn,cpu->ia);
110 ppc32_dump_regs(cpu->gen);
111 return(0);
112 }
113
114 /* Execute a single instruction */
115 static forced_inline int
116 ppc32_exec_single_instruction(cpu_ppc_t *cpu,ppc_insn_t instruction)
117 {
118 register fastcall int (*exec)(cpu_ppc_t *,ppc_insn_t) = NULL;
119 struct ppc32_insn_exec_tag *tag;
120 int index;
121
122 #if DEBUG_INSN_PERF_CNT
123 cpu->perf_counter++;
124 #endif
125
126 /* Lookup for instruction */
127 index = ilt_lookup(ilt,instruction);
128 tag = ppc32_exec_get_insn(index);
129 exec = tag->exec;
130
131 #if NJM_STATS_ENABLE
132 cpu->insn_exec_count++;
133 ppc32_exec_tags[index].count++;
134 #endif
135 return(exec(cpu,instruction));
136 }
137
138 /* Execute a single instruction (external) */
139 fastcall int ppc32_exec_single_insn_ext(cpu_ppc_t *cpu,ppc_insn_t insn)
140 {
141 int res;
142
143 res = ppc32_exec_single_instruction(cpu,insn);
144 if (likely(!res)) cpu->ia += sizeof(ppc_insn_t);
145 return(res);
146 }
147
148 /* Run PowerPC code in step-by-step mode */
149 void *ppc32_exec_run_cpu(cpu_gen_t *gen)
150 {
151 cpu_ppc_t *cpu = CPU_PPC32(gen);
152 pthread_t timer_irq_thread;
153 int timer_irq_check = 0;
154 ppc_insn_t insn;
155 int res;
156
157 if (pthread_create(&timer_irq_thread,NULL,
158 (void *)ppc32_timer_irq_run,cpu))
159 {
160 fprintf(stderr,"VM '%s': unable to create Timer IRQ thread for CPU%u.\n",
161 cpu->vm->name,gen->id);
162 cpu_stop(gen);
163 return NULL;
164 }
165
166 gen->cpu_thread_running = TRUE;
167
168 start_cpu:
169 for(;;) {
170 if (unlikely(gen->state != CPU_STATE_RUNNING))
171 break;
172
173 /* Check IRQ */
174 if (unlikely(cpu->irq_check))
175 ppc32_trigger_irq(cpu);
176
177 /* Handle virtual idle loop */
178 if (unlikely(cpu->ia == cpu->idle_pc)) {
179 if (++gen->idle_count == gen->idle_max) {
180 cpu_idle_loop(gen);
181 gen->idle_count = 0;
182 }
183 }
184
185 /* Handle the virtual CPU clock */
186 if (++timer_irq_check == cpu->timer_irq_check_itv) {
187 timer_irq_check = 0;
188
189 if (cpu->timer_irq_pending && !cpu->irq_disable &&
190 (cpu->msr & PPC32_MSR_EE))
191 {
192 cpu->timer_irq_armed = 0;
193 cpu->timer_irq_pending--;
194
195 vm_set_irq(cpu->vm,0);
196 //ppc32_trigger_timer_irq(cpu);
197 }
198 }
199
200 /* Increment the time base */
201 cpu->tb += 100;
202
203 /* Fetch and execute the instruction */
204 ppc32_exec_fetch(cpu,cpu->ia,&insn);
205 res = ppc32_exec_single_instruction(cpu,insn);
206
207 /* Normal flow ? */
208 if (likely(!res)) cpu->ia += sizeof(ppc_insn_t);
209 }
210
211 /* Check regularly if the CPU has been restarted */
212 while(gen->cpu_thread_running) {
213 gen->seq_state++;
214
215 switch(gen->state) {
216 case CPU_STATE_RUNNING:
217 gen->state = CPU_STATE_RUNNING;
218 goto start_cpu;
219
220 case CPU_STATE_HALTED:
221 gen->cpu_thread_running = FALSE;
222 pthread_join(timer_irq_thread,NULL);
223 break;
224 }
225
226 /* CPU is paused */
227 usleep(200000);
228 }
229
230 return NULL;
231 }
232
233 /* ========================================================================= */
234
235 /* Update CR0 */
236 static forced_inline void ppc32_exec_update_cr0(cpu_ppc_t *cpu,m_uint32_t val)
237 {
238 m_uint32_t res;
239
240 if (val & 0x80000000)
241 res = 1 << PPC32_CR_LT_BIT;
242 else {
243 if (val > 0)
244 res = 1 << PPC32_CR_GT_BIT;
245 else
246 res = 1 << PPC32_CR_EQ_BIT;
247 }
248
249 if (cpu->xer & PPC32_XER_SO)
250 res |= 1 << PPC32_CR_SO_BIT;
251
252 cpu->cr_fields[0] = res;
253 }
254
255 /*
256 * Update Overflow bit from a sum result (r = a + b)
257 *
258 * (a > 0) && (b > 0) => r > 0, otherwise overflow
259 * (a < 0) && (a < 0) => r < 0, otherwise overflow.
260 */
261 static forced_inline void ppc32_exec_ov_sum(cpu_ppc_t *cpu,m_uint32_t r,
262 m_uint32_t a,m_uint32_t b)
263 {
264 register m_uint32_t sc;
265
266 sc = (~(a ^ b) & (a ^ r) & 0x80000000);
267 if (unlikely(sc))
268 cpu->xer |= PPC32_XER_SO | PPC32_XER_OV;
269 else
270 cpu->xer &= ~PPC32_XER_OV;
271 }
272
273 /*
274 * Update Overflow bit from a substraction result (r = a - b)
275 *
276 * (a > 0) && (b < 0) => r > 0, otherwise overflow
277 * (a < 0) && (a > 0) => r < 0, otherwise overflow.
278 */
279 static forced_inline void ppc32_exec_ov_sub(cpu_ppc_t *cpu,m_uint32_t r,
280 m_uint32_t a,m_uint32_t b)
281 {
282 register m_uint32_t sc;
283
284 sc = ((a ^ b) & (a ^ r) & 0x80000000);
285 if (unlikely(sc))
286 cpu->xer |= PPC32_XER_SO | PPC32_XER_OV;
287 else
288 cpu->xer &= ~PPC32_XER_OV;
289 }
290
291 /*
292 * Update CA bit from a sum result (r = a + b)
293 */
294 static forced_inline void ppc32_exec_ca_sum(cpu_ppc_t *cpu,m_uint32_t r,
295 m_uint32_t a,m_uint32_t b)
296 {
297 cpu->xer_ca = (r < a) ? 1 : 0;
298 }
299
300 /*
301 * Update CA bit from a substraction result (r = a - b)
302 */
303 static forced_inline void ppc32_exec_ca_sub(cpu_ppc_t *cpu,m_uint32_t r,
304 m_uint32_t a,m_uint32_t b)
305 {
306 cpu->xer_ca = (b > a) ? 1 : 0;
307 }
308
309 /* Check condition code */
310 static forced_inline int ppc32_check_cond(cpu_ppc_t *cpu,m_uint32_t bo,
311 m_uint32_t bi)
312 {
313 u_int ctr_ok = TRUE;
314 u_int cond_ok;
315 u_int cr_bit;
316
317 if (!(bo & 0x04)) {
318 cpu->ctr--;
319 ctr_ok = (cpu->ctr != 0) ^ ((bo >> 1) & 0x1);
320 }
321
322 cr_bit = ppc32_read_cr_bit(cpu,bi);
323 cond_ok = (bo >> 4) | ((cr_bit ^ (~bo >> 3)) & 0x1);
324
325 return(ctr_ok & cond_ok);
326 }
327
328 /* MFLR - Move From Link Register */
329 static fastcall int ppc32_exec_MFLR(cpu_ppc_t *cpu,ppc_insn_t insn)
330 {
331 int rd = bits(insn,21,25);
332
333 cpu->gpr[rd] = cpu->lr;
334 return(0);
335 }
336
337 /* MTLR - Move To Link Register */
338 static fastcall int ppc32_exec_MTLR(cpu_ppc_t *cpu,ppc_insn_t insn)
339 {
340 int rs = bits(insn,21,25);
341
342 cpu->lr = cpu->gpr[rs];
343 return(0);
344 }
345
346 /* MFCTR - Move From Counter Register */
347 static fastcall int ppc32_exec_MFCTR(cpu_ppc_t *cpu,ppc_insn_t insn)
348 {
349 int rd = bits(insn,21,25);
350
351 cpu->gpr[rd] = cpu->ctr;
352 return(0);
353 }
354
355 /* MTCTR - Move To Counter Register */
356 static fastcall int ppc32_exec_MTCTR(cpu_ppc_t *cpu,ppc_insn_t insn)
357 {
358 int rs = bits(insn,21,25);
359
360 cpu->ctr = cpu->gpr[rs];
361 return(0);
362 }
363
364 /* ADD */
365 static fastcall int ppc32_exec_ADD(cpu_ppc_t *cpu,ppc_insn_t insn)
366 {
367 int rd = bits(insn,21,25);
368 int ra = bits(insn,16,20);
369 int rb = bits(insn,11,15);
370
371 cpu->gpr[rd] = cpu->gpr[ra] + cpu->gpr[rb];
372 return(0);
373 }
374
375 /* ADD. */
376 static fastcall int ppc32_exec_ADD_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
377 {
378 int rd = bits(insn,21,25);
379 int ra = bits(insn,16,20);
380 int rb = bits(insn,11,15);
381 register m_uint32_t tmp;
382
383 tmp = cpu->gpr[ra] + cpu->gpr[rb];
384 ppc32_exec_update_cr0(cpu,tmp);
385 cpu->gpr[rd] = tmp;
386 return(0);
387 }
388
389 /* ADDO - Add with Overflow */
390 static fastcall int ppc32_exec_ADDO(cpu_ppc_t *cpu,ppc_insn_t insn)
391 {
392 int rd = bits(insn,21,25);
393 int ra = bits(insn,16,20);
394 int rb = bits(insn,11,15);
395 register m_uint32_t a,b,d;
396
397 a = cpu->gpr[ra];
398 b = cpu->gpr[rb];
399 d = a + b;
400
401 ppc32_exec_ov_sum(cpu,d,a,b);
402 cpu->gpr[rd] = d;
403 return(0);
404 }
405
406 /* ADDO. */
407 static fastcall int ppc32_exec_ADDO_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
408 {
409 int rd = bits(insn,21,25);
410 int ra = bits(insn,16,20);
411 int rb = bits(insn,11,15);
412 register m_uint32_t a,b,d;
413
414 a = cpu->gpr[ra];
415 b = cpu->gpr[rb];
416 d = a + b;
417
418 ppc32_exec_ov_sum(cpu,d,a,b);
419 ppc32_exec_update_cr0(cpu,d);
420 cpu->gpr[rd] = d;
421 return(0);
422 }
423
424 /* ADDC - Add Carrying */
425 static fastcall int ppc32_exec_ADDC(cpu_ppc_t *cpu,ppc_insn_t insn)
426 {
427 int rd = bits(insn,21,25);
428 int ra = bits(insn,16,20);
429 int rb = bits(insn,11,15);
430 register m_uint32_t a,b,d;
431
432 a = cpu->gpr[ra];
433 b = cpu->gpr[rb];
434 d = a + b;
435
436 ppc32_exec_ca_sum(cpu,d,a,b);
437 cpu->gpr[rd] = d;
438 return(0);
439 }
440
441 /* ADDC. */
442 static fastcall int ppc32_exec_ADDC_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
443 {
444 int rd = bits(insn,21,25);
445 int ra = bits(insn,16,20);
446 int rb = bits(insn,11,15);
447 register m_uint32_t a,b,d;
448
449 a = cpu->gpr[ra];
450 b = cpu->gpr[rb];
451 d = a + b;
452
453 ppc32_exec_ca_sum(cpu,d,a,b);
454 ppc32_exec_update_cr0(cpu,d);
455 cpu->gpr[rd] = d;
456 return(0);
457 }
458
459 /* ADDCO - Add Carrying with Overflow */
460 static fastcall int ppc32_exec_ADDCO(cpu_ppc_t *cpu,ppc_insn_t insn)
461 {
462 int rd = bits(insn,21,25);
463 int ra = bits(insn,16,20);
464 int rb = bits(insn,11,15);
465 register m_uint32_t a,b,d;
466
467 a = cpu->gpr[ra];
468 b = cpu->gpr[rb];
469 d = a + b;
470
471 ppc32_exec_ca_sum(cpu,d,a,b);
472 ppc32_exec_ov_sum(cpu,d,a,b);
473 cpu->gpr[rd] = d;
474 return(0);
475 }
476
477 /* ADDCO. */
478 static fastcall int ppc32_exec_ADDCO_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
479 {
480 int rd = bits(insn,21,25);
481 int ra = bits(insn,16,20);
482 int rb = bits(insn,11,15);
483 register m_uint32_t a,b,d;
484
485 a = cpu->gpr[ra];
486 b = cpu->gpr[rb];
487 d = a + b;
488
489 ppc32_exec_ca_sum(cpu,d,a,b);
490 ppc32_exec_ov_sum(cpu,d,a,b);
491 ppc32_exec_update_cr0(cpu,d);
492 cpu->gpr[rd] = d;
493 return(0);
494 }
495
496 /* ADDE - Add Extended */
497 static fastcall int ppc32_exec_ADDE(cpu_ppc_t *cpu,ppc_insn_t insn)
498 {
499 int rd = bits(insn,21,25);
500 int ra = bits(insn,16,20);
501 int rb = bits(insn,11,15);
502 register m_uint32_t a,b,d;
503 m_uint32_t carry;
504
505 carry = cpu->xer_ca;
506 cpu->xer_ca = 0;
507
508 a = cpu->gpr[ra];
509 b = cpu->gpr[rb];
510 d = a + b + carry;
511
512 if (((b + carry) < b) || (d < a))
513 cpu->xer_ca = 1;
514
515 cpu->gpr[rd] = d;
516 return(0);
517 }
518
519 /* ADDE. */
520 static fastcall int ppc32_exec_ADDE_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
521 {
522 int rd = bits(insn,21,25);
523 int ra = bits(insn,16,20);
524 int rb = bits(insn,11,15);
525 register m_uint32_t a,b,d;
526 m_uint32_t carry;
527
528 carry = cpu->xer_ca;
529 cpu->xer_ca = 0;
530
531 a = cpu->gpr[ra];
532 b = cpu->gpr[rb];
533 d = a + b + carry;
534
535 if (((b + carry) < b) || (d < a))
536 cpu->xer_ca = 1;
537
538 ppc32_exec_update_cr0(cpu,d);
539 cpu->gpr[rd] = d;
540 return(0);
541 }
542
543 /* ADDEO - Add Extended with Overflow */
544 static fastcall int ppc32_exec_ADDEO(cpu_ppc_t *cpu,ppc_insn_t insn)
545 {
546 int rd = bits(insn,21,25);
547 int ra = bits(insn,16,20);
548 int rb = bits(insn,11,15);
549 register m_uint32_t a,b,d;
550 m_uint32_t carry;
551
552 carry = cpu->xer_ca;
553 cpu->xer_ca = 0;
554
555 a = cpu->gpr[ra];
556 b = cpu->gpr[rb];
557 d = a + b + carry;
558
559 if (((b + carry) < b) || (d < a))
560 cpu->xer_ca = 1;
561
562 ppc32_exec_ov_sum(cpu,d,a,b);
563 cpu->gpr[rd] = d;
564 return(0);
565 }
566
567 /* ADDEO. */
568 static fastcall int ppc32_exec_ADDEO_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
569 {
570 int rd = bits(insn,21,25);
571 int ra = bits(insn,16,20);
572 int rb = bits(insn,11,15);
573 register m_uint32_t a,b,d;
574 m_uint32_t carry;
575
576 carry = cpu->xer_ca;
577 cpu->xer_ca = 0;
578
579 a = cpu->gpr[ra];
580 b = cpu->gpr[rb];
581 d = a + b + carry;
582
583 if (((b + carry) < b) || (d < a))
584 cpu->xer_ca = 1;
585
586 ppc32_exec_ov_sum(cpu,d,a,b);
587 ppc32_exec_update_cr0(cpu,d);
588 cpu->gpr[rd] = d;
589 return(0);
590 }
591
592 /* ADDI - ADD Immediate */
593 static fastcall int ppc32_exec_ADDI(cpu_ppc_t *cpu,ppc_insn_t insn)
594 {
595 int rd = bits(insn,21,25);
596 int ra = bits(insn,16,20);
597 int imm = bits(insn,0,15);
598 register m_uint32_t tmp;
599
600 tmp = sign_extend_32(imm,16);
601
602 if (ra != 0)
603 tmp += cpu->gpr[ra];
604
605 cpu->gpr[rd] = tmp;
606 return(0);
607 }
608
609 /* ADDIC - ADD Immediate with Carry */
610 static fastcall int ppc32_exec_ADDIC(cpu_ppc_t *cpu,ppc_insn_t insn)
611 {
612 int rd = bits(insn,21,25);
613 int ra = bits(insn,16,20);
614 int imm = bits(insn,0,15);
615 register m_uint32_t a,d;
616
617 a = cpu->gpr[ra];
618 d = a + sign_extend_32(imm,16);
619 ppc32_exec_ca_sum(cpu,d,a,0);
620 cpu->gpr[rd] = d;
621 return(0);
622 }
623
624 /* ADDIC. */
625 static fastcall int ppc32_exec_ADDIC_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
626 {
627 int rd = bits(insn,21,25);
628 int ra = bits(insn,16,20);
629 int imm = bits(insn,0,15);
630 register m_uint32_t a,d;
631
632 a = cpu->gpr[ra];
633 d = a + sign_extend_32(imm,16);
634 ppc32_exec_ca_sum(cpu,d,a,0);
635 ppc32_exec_update_cr0(cpu,d);
636 cpu->gpr[rd] = d;
637 return(0);
638 }
639
640 /* ADDIS - ADD Immediate Shifted */
641 static fastcall int ppc32_exec_ADDIS(cpu_ppc_t *cpu,ppc_insn_t insn)
642 {
643 int rd = bits(insn,21,25);
644 int ra = bits(insn,16,20);
645 m_uint32_t imm = bits(insn,0,15);
646 register m_uint32_t tmp;
647
648 tmp = imm << 16;
649
650 if (ra != 0)
651 tmp += cpu->gpr[ra];
652
653 cpu->gpr[rd] = tmp;
654 return(0);
655 }
656
657 /* ADDME - Add to Minus One Extended */
658 static fastcall int ppc32_exec_ADDME(cpu_ppc_t *cpu,ppc_insn_t insn)
659 {
660 int rd = bits(insn,21,25);
661 int ra = bits(insn,16,20);
662 register m_uint32_t a,b,d;
663 m_uint32_t carry;
664
665 carry = cpu->xer_ca;
666 cpu->xer_ca = 0;
667
668 a = cpu->gpr[ra];
669 b = 0xFFFFFFFF;
670 d = a + b + carry;
671
672 if (((b + carry) < b) || (d < a))
673 cpu->xer_ca = 1;
674
675 cpu->gpr[rd] = d;
676 return(0);
677 }
678
679 /* ADDME. */
680 static fastcall int ppc32_exec_ADDME_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
681 {
682 int rd = bits(insn,21,25);
683 int ra = bits(insn,16,20);
684 register m_uint32_t a,b,d;
685 m_uint32_t carry;
686
687 carry = cpu->xer_ca;
688 cpu->xer_ca = 0;
689
690 a = cpu->gpr[ra];
691 b = 0xFFFFFFFF;
692 d = a + b + carry;
693
694 if (((b + carry) < b) || (d < a))
695 cpu->xer_ca = 1;
696
697 ppc32_exec_update_cr0(cpu,d);
698 cpu->gpr[rd] = d;
699 return(0);
700 }
701
702 /* ADDZE - Add to Zero Extended */
703 static fastcall int ppc32_exec_ADDZE(cpu_ppc_t *cpu,ppc_insn_t insn)
704 {
705 int rd = bits(insn,21,25);
706 int ra = bits(insn,16,20);
707 register m_uint32_t a,d;
708 m_uint32_t carry;
709
710 carry = cpu->xer_ca;
711 cpu->xer_ca = 0;
712
713 a = cpu->gpr[ra];
714 d = a + carry;
715
716 if (d < a)
717 cpu->xer_ca = 1;
718
719 cpu->gpr[rd] = d;
720 return(0);
721 }
722
723 /* ADDZE. */
724 static fastcall int ppc32_exec_ADDZE_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
725 {
726 int rd = bits(insn,21,25);
727 int ra = bits(insn,16,20);
728 register m_uint32_t a,d;
729 m_uint32_t carry;
730
731 carry = cpu->xer_ca;
732 cpu->xer_ca = 0;
733
734 a = cpu->gpr[ra];
735 d = a + carry;
736
737 if (d < a)
738 cpu->xer_ca = 1;
739
740 ppc32_exec_update_cr0(cpu,d);
741 cpu->gpr[rd] = d;
742 return(0);
743 }
744
745 /* AND */
746 static fastcall int ppc32_exec_AND(cpu_ppc_t *cpu,ppc_insn_t insn)
747 {
748 int rs = bits(insn,21,25);
749 int ra = bits(insn,16,20);
750 int rb = bits(insn,11,15);
751
752 cpu->gpr[ra] = cpu->gpr[rs] & cpu->gpr[rb];
753 return(0);
754 }
755
756 /* AND. */
757 static fastcall int ppc32_exec_AND_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
758 {
759 int rs = bits(insn,21,25);
760 int ra = bits(insn,16,20);
761 int rb = bits(insn,11,15);
762 m_uint32_t tmp;
763
764 tmp = cpu->gpr[rs] & cpu->gpr[rb];
765 ppc32_exec_update_cr0(cpu,tmp);
766 cpu->gpr[ra] = tmp;
767 return(0);
768 }
769
770 /* ANDC - AND with Complement */
771 static fastcall int ppc32_exec_ANDC(cpu_ppc_t *cpu,ppc_insn_t insn)
772 {
773 int rs = bits(insn,21,25);
774 int ra = bits(insn,16,20);
775 int rb = bits(insn,11,15);
776
777 cpu->gpr[ra] = cpu->gpr[rs] & (~cpu->gpr[rb]);
778 return(0);
779 }
780
781 /* ANDC. - AND with Complement */
782 static fastcall int ppc32_exec_ANDC_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
783 {
784 int rs = bits(insn,21,25);
785 int ra = bits(insn,16,20);
786 int rb = bits(insn,11,15);
787 m_uint32_t tmp;
788
789 tmp = cpu->gpr[rs] & (~cpu->gpr[rb]);
790 ppc32_exec_update_cr0(cpu,tmp);
791 cpu->gpr[ra] = tmp;
792 return(0);
793 }
794
795 /* ANDI. - AND Immediate */
796 static fastcall int ppc32_exec_ANDI_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
797 {
798 int rs = bits(insn,21,25);
799 int ra = bits(insn,16,20);
800 m_uint16_t imm = bits(insn,0,15);
801 register m_uint32_t tmp;
802
803 tmp = cpu->gpr[rs] & imm;
804 ppc32_exec_update_cr0(cpu,tmp);
805 cpu->gpr[ra] = tmp;
806 return(0);
807 }
808
809 /* ANDIS. - AND Immediate Shifted */
810 static fastcall int ppc32_exec_ANDIS_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
811 {
812 int rs = bits(insn,21,25);
813 int ra = bits(insn,16,20);
814 m_uint32_t imm = bits(insn,0,15);
815 register m_uint32_t tmp;
816
817 tmp = cpu->gpr[rs] & (imm << 16);
818 ppc32_exec_update_cr0(cpu,tmp);
819 cpu->gpr[ra] = tmp;
820 return(0);
821 }
822
823 /* B - Branch */
824 static fastcall int ppc32_exec_B(cpu_ppc_t *cpu,ppc_insn_t insn)
825 {
826 m_uint32_t offset = bits(insn,2,25);
827
828 cpu->ia += sign_extend_32(offset << 2,26);
829 return(1);
830 }
831
832 /* BA - Branch Absolute */
833 static fastcall int ppc32_exec_BA(cpu_ppc_t *cpu,ppc_insn_t insn)
834 {
835 m_uint32_t offset = bits(insn,2,25);
836
837 cpu->ia = sign_extend_32(offset << 2,26);
838 return(1);
839 }
840
841 /* BL - Branch and Link */
842 static fastcall int ppc32_exec_BL(cpu_ppc_t *cpu,ppc_insn_t insn)
843 {
844 m_uint32_t offset = bits(insn,2,25);
845
846 cpu->lr = cpu->ia + 4;
847 cpu->ia += sign_extend_32(offset << 2,26);
848 return(1);
849 }
850
851 /* BLA - Branch and Link Absolute */
852 static fastcall int ppc32_exec_BLA(cpu_ppc_t *cpu,ppc_insn_t insn)
853 {
854 m_uint32_t offset = bits(insn,2,25);
855
856 cpu->lr = cpu->ia + 4;
857 cpu->ia = sign_extend_32(offset << 2,26);
858 return(1);
859 }
860
861 /* BC - Branch Conditional */
862 static fastcall int ppc32_exec_BC(cpu_ppc_t *cpu,ppc_insn_t insn)
863 {
864 int bo = bits(insn,21,25);
865 int bi = bits(insn,16,20);
866 int bd = bits(insn,2,15);
867
868 if (ppc32_check_cond(cpu,bo,bi)) {
869 cpu->ia += sign_extend_32(bd << 2,16);
870 return(1);
871 }
872
873 return(0);
874 }
875
876 /* BCA - Branch Conditional (absolute) */
877 static fastcall int ppc32_exec_BCA(cpu_ppc_t *cpu,ppc_insn_t insn)
878 {
879 int bo = bits(insn,21,25);
880 int bi = bits(insn,16,20);
881 int bd = bits(insn,2,15);
882
883 if (ppc32_check_cond(cpu,bo,bi)) {
884 cpu->ia = sign_extend_32(bd << 2,16);
885 return(1);
886 }
887
888 return(0);
889 }
890
891 /* BCL - Branch Conditional and Link */
892 static fastcall int ppc32_exec_BCL(cpu_ppc_t *cpu,ppc_insn_t insn)
893 {
894 int bo = bits(insn,21,25);
895 int bi = bits(insn,16,20);
896 int bd = bits(insn,2,15);
897
898 cpu->lr = cpu->ia + 4;
899
900 if (ppc32_check_cond(cpu,bo,bi)) {
901 cpu->ia += sign_extend_32(bd << 2,16);
902 return(1);
903 }
904
905 return(0);
906 }
907
908 /* BCLA - Branch Conditional and Link (absolute) */
909 static fastcall int ppc32_exec_BCLA(cpu_ppc_t *cpu,ppc_insn_t insn)
910 {
911 int bo = bits(insn,21,25);
912 int bi = bits(insn,16,20);
913 int bd = bits(insn,2,15);
914
915 cpu->lr = cpu->ia + 4;
916
917 if (ppc32_check_cond(cpu,bo,bi)) {
918 cpu->ia = sign_extend_32(bd << 2,16);
919 return(1);
920 }
921
922 return(0);
923 }
924
925 /* BCLR - Branch Conditional to Link register */
926 static fastcall int ppc32_exec_BCLR(cpu_ppc_t *cpu,ppc_insn_t insn)
927 {
928 int bo = bits(insn,21,25);
929 int bi = bits(insn,16,20);
930
931 if (ppc32_check_cond(cpu,bo,bi)) {
932 cpu->ia = cpu->lr & ~0x3;
933 return(1);
934 }
935
936 return(0);
937 }
938
939 /* BCLRL - Branch Conditional to Link register */
940 static fastcall int ppc32_exec_BCLRL(cpu_ppc_t *cpu,ppc_insn_t insn)
941 {
942 int bo = bits(insn,21,25);
943 int bi = bits(insn,16,20);
944 m_uint32_t new_ia;
945
946 new_ia = cpu->lr & ~0x03;
947 cpu->lr = cpu->ia + 4;
948
949 if (ppc32_check_cond(cpu,bo,bi)) {
950 cpu->ia = new_ia;
951 return(1);
952 }
953
954 return(0);
955 }
956
957 /* BCCTR - Branch Conditional to Count register */
958 static fastcall int ppc32_exec_BCCTR(cpu_ppc_t *cpu,ppc_insn_t insn)
959 {
960 int bo = bits(insn,21,25);
961 int bi = bits(insn,16,20);
962
963 if (ppc32_check_cond(cpu,bo,bi)) {
964 cpu->ia = cpu->ctr & ~0x3;
965 return(1);
966 }
967
968 return(0);
969 }
970
971 /* BCCTRL - Branch Conditional to Count register and Link */
972 static fastcall int ppc32_exec_BCCTRL(cpu_ppc_t *cpu,ppc_insn_t insn)
973 {
974 int bo = bits(insn,21,25);
975 int bi = bits(insn,16,20);
976
977 cpu->lr = cpu->ia + 4;
978
979 if (ppc32_check_cond(cpu,bo,bi)) {
980 cpu->ia = cpu->ctr & ~0x3;
981 return(1);
982 }
983
984 return(0);
985 }
986
987 /* CMP - Compare */
988 static fastcall int ppc32_exec_CMP(cpu_ppc_t *cpu,ppc_insn_t insn)
989 {
990 int rd = bits(insn,23,25);
991 int ra = bits(insn,16,20);
992 int rb = bits(insn,11,15);
993 m_uint32_t res;
994 m_int32_t a,b;
995
996 a = (m_int32_t)cpu->gpr[ra];
997 b = (m_int32_t)cpu->gpr[rb];
998
999 if (a < b)
1000 res = 0x08;
1001 else {
1002 if (a > b)
1003 res = 0x04;
1004 else
1005 res = 0x02;
1006 }
1007
1008 if (cpu->xer & PPC32_XER_SO)
1009 res |= 0x01;
1010
1011 cpu->cr_fields[rd] = res;
1012 return(0);
1013 }
1014
1015 /* CMPI - Compare Immediate */
1016 static fastcall int ppc32_exec_CMPI(cpu_ppc_t *cpu,ppc_insn_t insn)
1017 {
1018 int rd = bits(insn,23,25);
1019 int ra = bits(insn,16,20);
1020 m_uint16_t imm = bits(insn,0,15);
1021 m_uint32_t res;
1022 m_int32_t a,b;
1023
1024 a = (m_int32_t)cpu->gpr[ra];
1025 b = sign_extend_32(imm,16);
1026
1027 if (a < b)
1028 res = 0x08;
1029 else {
1030 if (a > b)
1031 res = 0x04;
1032 else
1033 res = 0x02;
1034 }
1035
1036 if (cpu->xer & PPC32_XER_SO)
1037 res |= 0x01;
1038
1039 cpu->cr_fields[rd] = res;
1040 return(0);
1041 }
1042
1043 /* CMPL - Compare Logical */
1044 static fastcall int ppc32_exec_CMPL(cpu_ppc_t *cpu,ppc_insn_t insn)
1045 {
1046 int rd = bits(insn,23,25);
1047 int ra = bits(insn,16,20);
1048 int rb = bits(insn,11,15);
1049 m_uint32_t res,a,b;
1050
1051 a = cpu->gpr[ra];
1052 b = cpu->gpr[rb];
1053
1054 if (a < b)
1055 res = 0x08;
1056 else {
1057 if (a > b)
1058 res = 0x04;
1059 else
1060 res = 0x02;
1061 }
1062
1063 if (cpu->xer & PPC32_XER_SO)
1064 res |= 0x01;
1065
1066 cpu->cr_fields[rd] = res;
1067 return(0);
1068 }
1069
1070 /* CMPLI - Compare Logical Immediate */
1071 static fastcall int ppc32_exec_CMPLI(cpu_ppc_t *cpu,ppc_insn_t insn)
1072 {
1073 int rd = bits(insn,23,25);
1074 int ra = bits(insn,16,20);
1075 m_uint32_t imm = bits(insn,0,15);
1076 m_uint32_t res,a;
1077
1078 a = cpu->gpr[ra];
1079
1080 if (a < imm)
1081 res = 0x08;
1082 else {
1083 if (a > imm)
1084 res = 0x04;
1085 else
1086 res = 0x02;
1087 }
1088
1089 if (cpu->xer & PPC32_XER_SO)
1090 res |= 0x01;
1091
1092 cpu->cr_fields[rd] = res;
1093 return(0);
1094 }
1095
1096 /* CNTLZW - Count Leading Zeros Word */
1097 static fastcall int ppc32_exec_CNTLZW(cpu_ppc_t *cpu,ppc_insn_t insn)
1098 {
1099 int rs = bits(insn,21,25);
1100 int ra = bits(insn,16,20);
1101 m_uint32_t val,mask;
1102 int i;
1103
1104 val = cpu->gpr[rs];
1105 mask = 0x80000000;
1106
1107 for(i=0;i<32;i++) {
1108 if (val & mask)
1109 break;
1110
1111 mask >>= 1;
1112 }
1113
1114 cpu->gpr[ra] = i;
1115 return(0);
1116 }
1117
1118 /* CRAND - Condition Register AND */
1119 static fastcall int ppc32_exec_CRAND(cpu_ppc_t *cpu,ppc_insn_t insn)
1120 {
1121 int bd = bits(insn,21,25);
1122 int bb = bits(insn,16,20);
1123 int ba = bits(insn,11,15);
1124 m_uint32_t tmp;
1125
1126 tmp = ppc32_read_cr_bit(cpu,ba);
1127 tmp &= ppc32_read_cr_bit(cpu,bb);
1128
1129 if (tmp & 0x1)
1130 ppc32_set_cr_bit(cpu,bd);
1131 else
1132 ppc32_clear_cr_bit(cpu,bd);
1133
1134 return(0);
1135 }
1136
1137 /* CREQV - Condition Register Equivalent */
1138 static fastcall int ppc32_exec_CREQV(cpu_ppc_t *cpu,ppc_insn_t insn)
1139 {
1140 int bd = bits(insn,21,25);
1141 int bb = bits(insn,16,20);
1142 int ba = bits(insn,11,15);
1143 m_uint32_t tmp;
1144
1145 tmp = ppc32_read_cr_bit(cpu,ba);
1146 tmp ^= ppc32_read_cr_bit(cpu,bb);
1147
1148 if (!(tmp & 0x1))
1149 ppc32_set_cr_bit(cpu,bd);
1150 else
1151 ppc32_clear_cr_bit(cpu,bd);
1152
1153 return(0);
1154 }
1155
1156 /* CRANDC - Condition Register AND with Complement */
1157 static fastcall int ppc32_exec_CRANDC(cpu_ppc_t *cpu,ppc_insn_t insn)
1158 {
1159 int bd = bits(insn,21,25);
1160 int bb = bits(insn,16,20);
1161 int ba = bits(insn,11,15);
1162 m_uint32_t tmp;
1163
1164 tmp = ppc32_read_cr_bit(cpu,ba);
1165 tmp &= ~ppc32_read_cr_bit(cpu,bb);
1166
1167 if (tmp & 0x1)
1168 ppc32_set_cr_bit(cpu,bd);
1169 else
1170 ppc32_clear_cr_bit(cpu,bd);
1171
1172 return(0);
1173 }
1174
1175 /* CRNAND - Condition Register NAND */
1176 static fastcall int ppc32_exec_CRNAND(cpu_ppc_t *cpu,ppc_insn_t insn)
1177 {
1178 int bd = bits(insn,21,25);
1179 int bb = bits(insn,16,20);
1180 int ba = bits(insn,11,15);
1181 m_uint32_t tmp;
1182
1183 tmp = ppc32_read_cr_bit(cpu,ba);
1184 tmp &= ppc32_read_cr_bit(cpu,bb);
1185
1186 if (!(tmp & 0x1))
1187 ppc32_set_cr_bit(cpu,bd);
1188 else
1189 ppc32_clear_cr_bit(cpu,bd);
1190
1191 return(0);
1192 }
1193
1194 /* CRNOR - Condition Register NOR */
1195 static fastcall int ppc32_exec_CRNOR(cpu_ppc_t *cpu,ppc_insn_t insn)
1196 {
1197 int bd = bits(insn,21,25);
1198 int bb = bits(insn,16,20);
1199 int ba = bits(insn,11,15);
1200 m_uint32_t tmp;
1201
1202 tmp = ppc32_read_cr_bit(cpu,ba);
1203 tmp |= ppc32_read_cr_bit(cpu,bb);
1204
1205 if (!(tmp & 0x1))
1206 ppc32_set_cr_bit(cpu,bd);
1207 else
1208 ppc32_clear_cr_bit(cpu,bd);
1209
1210 return(0);
1211 }
1212
1213 /* CROR - Condition Register OR */
1214 static fastcall int ppc32_exec_CROR(cpu_ppc_t *cpu,ppc_insn_t insn)
1215 {
1216 int bd = bits(insn,21,25);
1217 int bb = bits(insn,16,20);
1218 int ba = bits(insn,11,15);
1219 m_uint32_t tmp;
1220
1221 tmp = ppc32_read_cr_bit(cpu,ba);
1222 tmp |= ppc32_read_cr_bit(cpu,bb);
1223
1224 if (tmp & 0x1)
1225 ppc32_set_cr_bit(cpu,bd);
1226 else
1227 ppc32_clear_cr_bit(cpu,bd);
1228
1229 return(0);
1230 }
1231
1232 /* CRORC - Condition Register OR with complement */
1233 static fastcall int ppc32_exec_CRORC(cpu_ppc_t *cpu,ppc_insn_t insn)
1234 {
1235 int bd = bits(insn,21,25);
1236 int bb = bits(insn,16,20);
1237 int ba = bits(insn,11,15);
1238 m_uint32_t tmp;
1239
1240 tmp = ppc32_read_cr_bit(cpu,ba);
1241 tmp |= ~ppc32_read_cr_bit(cpu,bb);
1242
1243 if (tmp & 0x1)
1244 ppc32_set_cr_bit(cpu,bd);
1245 else
1246 ppc32_clear_cr_bit(cpu,bd);
1247
1248 return(0);
1249 }
1250
1251 /* CRXOR - Condition Register XOR */
1252 static fastcall int ppc32_exec_CRXOR(cpu_ppc_t *cpu,ppc_insn_t insn)
1253 {
1254 int bd = bits(insn,21,25);
1255 int bb = bits(insn,16,20);
1256 int ba = bits(insn,11,15);
1257 m_uint32_t tmp;
1258
1259 tmp = ppc32_read_cr_bit(cpu,ba);
1260 tmp ^= ppc32_read_cr_bit(cpu,bb);
1261
1262 if (tmp & 0x1)
1263 ppc32_set_cr_bit(cpu,bd);
1264 else
1265 ppc32_clear_cr_bit(cpu,bd);
1266
1267 return(0);
1268 }
1269
1270 /* DCBF - Data Cache Block Flush */
1271 static fastcall int ppc32_exec_DCBF(cpu_ppc_t *cpu,ppc_insn_t insn)
1272 {
1273 int ra = bits(insn,16,20);
1274 int rb = bits(insn,11,15);
1275 m_uint32_t vaddr;
1276
1277 vaddr = cpu->gpr[rb];
1278
1279 if (ra != 0)
1280 vaddr += cpu->gpr[ra];
1281
1282 //printf("PPC32: DBCF: vaddr=0x%8.8x\n",vaddr);
1283 return(0);
1284 }
1285
1286 /* DCBI - Data Cache Block Invalidate */
1287 static fastcall int ppc32_exec_DCBI(cpu_ppc_t *cpu,ppc_insn_t insn)
1288 {
1289 int ra = bits(insn,16,20);
1290 int rb = bits(insn,11,15);
1291 m_uint32_t vaddr;
1292
1293 vaddr = cpu->gpr[rb];
1294
1295 if (ra != 0)
1296 vaddr += cpu->gpr[ra];
1297
1298 //printf("PPC32: DBCI: vaddr=0x%8.8x\n",vaddr);
1299 return(0);
1300 }
1301
1302 /* DCBT - Data Cache Block Touch */
1303 static fastcall int ppc32_exec_DCBT(cpu_ppc_t *cpu,ppc_insn_t insn)
1304 {
1305 int ra = bits(insn,16,20);
1306 int rb = bits(insn,11,15);
1307 m_uint32_t vaddr;
1308
1309 vaddr = cpu->gpr[rb];
1310
1311 if (ra != 0)
1312 vaddr += cpu->gpr[ra];
1313
1314 //printf("PPC32: DBCT: vaddr=0x%8.8x\n",vaddr);
1315 return(0);
1316 }
1317
1318 /* DCBST - Data Cache Block Store */
1319 static fastcall int ppc32_exec_DCBST(cpu_ppc_t *cpu,ppc_insn_t insn)
1320 {
1321 int ra = bits(insn,16,20);
1322 int rb = bits(insn,11,15);
1323 m_uint32_t vaddr;
1324
1325 vaddr = cpu->gpr[rb];
1326
1327 if (ra != 0)
1328 vaddr += cpu->gpr[ra];
1329
1330 //printf("PPC32: DBCST: vaddr=0x%8.8x\n",vaddr);
1331 return(0);
1332 }
1333
1334 /* DIVW - Divide Word */
1335 static fastcall int ppc32_exec_DIVW(cpu_ppc_t *cpu,ppc_insn_t insn)
1336 {
1337 int rd = bits(insn,21,25);
1338 int ra = bits(insn,16,20);
1339 int rb = bits(insn,11,15);
1340 register m_uint32_t a,b;
1341
1342 a = (m_int32_t)cpu->gpr[ra];
1343 b = (m_int32_t)cpu->gpr[rb];
1344
1345 if (!((b == 0) || ((cpu->gpr[ra] == 0x80000000) && (b == -1))))
1346 cpu->gpr[rd] = a / b;
1347 return(0);
1348 }
1349
1350 /* DIVW. - Divide Word */
1351 static fastcall int ppc32_exec_DIVW_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
1352 {
1353 int rd = bits(insn,21,25);
1354 int ra = bits(insn,16,20);
1355 int rb = bits(insn,11,15);
1356 register m_int32_t a,b,d;
1357
1358 a = (m_int32_t)cpu->gpr[ra];
1359 b = (m_int32_t)cpu->gpr[rb];
1360 d = 0;
1361
1362 if (!((b == 0) || ((cpu->gpr[ra] == 0x80000000) && (b == -1))))
1363 d = a / b;
1364
1365 ppc32_exec_update_cr0(cpu,d);
1366 cpu->gpr[rd] = d;
1367 return(0);
1368 }
1369
1370 /* DIVWU - Divide Word Unsigned */
1371 static fastcall int ppc32_exec_DIVWU(cpu_ppc_t *cpu,ppc_insn_t insn)
1372 {
1373 int rd = bits(insn,21,25);
1374 int ra = bits(insn,16,20);
1375 int rb = bits(insn,11,15);
1376 register m_uint32_t a,b;
1377
1378 a = cpu->gpr[ra];
1379 b = cpu->gpr[rb];
1380
1381 if (b != 0)
1382 cpu->gpr[rd] = a / b;
1383 return(0);
1384 }
1385
1386 /* DIVWU. - Divide Word Unsigned */
1387 static fastcall int ppc32_exec_DIVWU_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
1388 {
1389 int rd = bits(insn,21,25);
1390 int ra = bits(insn,16,20);
1391 int rb = bits(insn,11,15);
1392 register m_uint32_t a,b,d;
1393
1394 a = cpu->gpr[ra];
1395 b = cpu->gpr[rb];
1396 d = 0;
1397
1398 if (b != 0)
1399 d = a / b;
1400
1401 ppc32_exec_update_cr0(cpu,d);
1402 cpu->gpr[rd] = d;
1403 return(0);
1404 }
1405
1406 /* EIEIO - Enforce In-order Execution of I/O */
1407 static fastcall int ppc32_exec_EIEIO(cpu_ppc_t *cpu,ppc_insn_t insn)
1408 {
1409 return(0);
1410 }
1411
1412 /* EQV */
1413 static fastcall int ppc32_exec_EQV(cpu_ppc_t *cpu,ppc_insn_t insn)
1414 {
1415 int rs = bits(insn,21,25);
1416 int ra = bits(insn,16,20);
1417 int rb = bits(insn,11,15);
1418
1419 cpu->gpr[ra] = ~(cpu->gpr[rs] ^ cpu->gpr[rb]);
1420 return(0);
1421 }
1422
1423 /* EXTSB - Extend Sign Byte */
1424 static fastcall int ppc32_exec_EXTSB(cpu_ppc_t *cpu,ppc_insn_t insn)
1425 {
1426 int rs = bits(insn,21,25);
1427 int ra = bits(insn,16,20);
1428
1429 cpu->gpr[ra] = sign_extend_32(cpu->gpr[rs],8);
1430 return(0);
1431 }
1432
1433 /* EXTSB. */
1434 static fastcall int ppc32_exec_EXTSB_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
1435 {
1436 int rs = bits(insn,21,25);
1437 int ra = bits(insn,16,20);
1438 m_uint32_t tmp;
1439
1440 tmp = sign_extend_32(cpu->gpr[rs],8);
1441 ppc32_exec_update_cr0(cpu,tmp);
1442 cpu->gpr[ra] = tmp;
1443 return(0);
1444 }
1445
1446 /* EXTSH - Extend Sign Word */
1447 static fastcall int ppc32_exec_EXTSH(cpu_ppc_t *cpu,ppc_insn_t insn)
1448 {
1449 int rs = bits(insn,21,25);
1450 int ra = bits(insn,16,20);
1451
1452 cpu->gpr[ra] = sign_extend_32(cpu->gpr[rs],16);
1453 return(0);
1454 }
1455
1456 /* EXTSH. */
1457 static fastcall int ppc32_exec_EXTSH_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
1458 {
1459 int rs = bits(insn,21,25);
1460 int ra = bits(insn,16,20);
1461 m_uint32_t tmp;
1462
1463 tmp = sign_extend_32(cpu->gpr[rs],16);
1464 ppc32_exec_update_cr0(cpu,tmp);
1465 cpu->gpr[ra] = tmp;
1466 return(0);
1467 }
1468
1469 /* ICBI - Instruction Cache Block Invalidate */
1470 static fastcall int ppc32_exec_ICBI(cpu_ppc_t *cpu,ppc_insn_t insn)
1471 {
1472 int ra = bits(insn,16,20);
1473 int rb = bits(insn,11,15);
1474 m_uint32_t vaddr;
1475
1476 vaddr = cpu->gpr[rb];
1477
1478 if (ra != 0)
1479 vaddr += cpu->gpr[ra];
1480
1481 return(ppc32_exec_memop(cpu,PPC_MEMOP_ICBI,vaddr,0));
1482 }
1483
1484 /* ISYNC - Instruction Synchronize */
1485 static fastcall int ppc32_exec_ISYNC(cpu_ppc_t *cpu,ppc_insn_t insn)
1486 {
1487 return(0);
1488 }
1489
1490 /* LBZ - Load Byte and Zero */
1491 static fastcall int ppc32_exec_LBZ(cpu_ppc_t *cpu,ppc_insn_t insn)
1492 {
1493 int rd = bits(insn,21,25);
1494 int ra = bits(insn,16,20);
1495 m_uint16_t imm = bits(insn,0,15);
1496 m_uint32_t vaddr;
1497
1498 vaddr = sign_extend_32(imm,16);
1499
1500 if (ra != 0)
1501 vaddr += cpu->gpr[ra];
1502
1503 return(ppc32_exec_memop(cpu,PPC_MEMOP_LBZ,vaddr,rd));
1504 }
1505
1506 /* LBZU - Load Byte and Zero with Update */
1507 static fastcall int ppc32_exec_LBZU(cpu_ppc_t *cpu,ppc_insn_t insn)
1508 {
1509 int rd = bits(insn,21,25);
1510 int ra = bits(insn,16,20);
1511 m_uint16_t imm = bits(insn,0,15);
1512 m_uint32_t vaddr;
1513 int res;
1514
1515 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
1516 res = ppc32_exec_memop(cpu,PPC_MEMOP_LBZ,vaddr,rd);
1517 cpu->gpr[ra] = vaddr;
1518 return(res);
1519 }
1520
1521 /* LBZUX - Load Byte and Zero with Update Indexed */
1522 static fastcall int ppc32_exec_LBZUX(cpu_ppc_t *cpu,ppc_insn_t insn)
1523 {
1524 int rd = bits(insn,21,25);
1525 int ra = bits(insn,16,20);
1526 int rb = bits(insn,11,15);
1527 m_uint32_t vaddr;
1528 int res;
1529
1530 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
1531 res = ppc32_exec_memop(cpu,PPC_MEMOP_LBZ,vaddr,rd);
1532 cpu->gpr[ra] = vaddr;
1533 return(res);
1534 }
1535
1536 /* LBZX - Load Byte and Zero Indexed */
1537 static fastcall int ppc32_exec_LBZX(cpu_ppc_t *cpu,ppc_insn_t insn)
1538 {
1539 int rd = bits(insn,21,25);
1540 int ra = bits(insn,16,20);
1541 int rb = bits(insn,11,15);
1542 m_uint32_t vaddr;
1543
1544 vaddr = cpu->gpr[rb];
1545
1546 if (ra != 0)
1547 vaddr += cpu->gpr[ra];
1548
1549 return(ppc32_exec_memop(cpu,PPC_MEMOP_LBZ,vaddr,rd));
1550 }
1551
1552 /* LHA - Load Half-Word Algebraic */
1553 static fastcall int ppc32_exec_LHA(cpu_ppc_t *cpu,ppc_insn_t insn)
1554 {
1555 int rd = bits(insn,21,25);
1556 int ra = bits(insn,16,20);
1557 m_uint16_t imm = bits(insn,0,15);
1558 m_uint32_t vaddr;
1559
1560 vaddr = sign_extend_32(imm,16);
1561
1562 if (ra != 0)
1563 vaddr += cpu->gpr[ra];
1564
1565 return(ppc32_exec_memop(cpu,PPC_MEMOP_LHA,vaddr,rd));
1566 }
1567
1568 /* LHAU - Load Half-Word Algebraic with Update */
1569 static fastcall int ppc32_exec_LHAU(cpu_ppc_t *cpu,ppc_insn_t insn)
1570 {
1571 int rd = bits(insn,21,25);
1572 int ra = bits(insn,16,20);
1573 m_uint16_t imm = bits(insn,0,15);
1574 m_uint32_t vaddr;
1575 int res;
1576
1577 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
1578 res = ppc32_exec_memop(cpu,PPC_MEMOP_LHA,vaddr,rd);
1579 cpu->gpr[ra] = vaddr;
1580 return(res);
1581 }
1582
1583 /* LHAUX - Load Half-Word Algebraic with Update Indexed */
1584 static fastcall int ppc32_exec_LHAUX(cpu_ppc_t *cpu,ppc_insn_t insn)
1585 {
1586 int rd = bits(insn,21,25);
1587 int ra = bits(insn,16,20);
1588 int rb = bits(insn,11,15);
1589 m_uint32_t vaddr;
1590 int res;
1591
1592 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
1593 res = ppc32_exec_memop(cpu,PPC_MEMOP_LHA,vaddr,rd);
1594 cpu->gpr[ra] = vaddr;
1595 return(res);
1596 }
1597
1598 /* LHAX - Load Half-Word Algebraic ndexed */
1599 static fastcall int ppc32_exec_LHAX(cpu_ppc_t *cpu,ppc_insn_t insn)
1600 {
1601 int rd = bits(insn,21,25);
1602 int ra = bits(insn,16,20);
1603 int rb = bits(insn,11,15);
1604 m_uint32_t vaddr;
1605
1606 vaddr = cpu->gpr[rb];
1607
1608 if (ra != 0)
1609 vaddr += cpu->gpr[ra];
1610
1611 return(ppc32_exec_memop(cpu,PPC_MEMOP_LHA,vaddr,rd));
1612 }
1613
1614 /* LHZ - Load Half-Word and Zero */
1615 static fastcall int ppc32_exec_LHZ(cpu_ppc_t *cpu,ppc_insn_t insn)
1616 {
1617 int rd = bits(insn,21,25);
1618 int ra = bits(insn,16,20);
1619 m_uint16_t imm = bits(insn,0,15);
1620 m_uint32_t vaddr;
1621
1622 vaddr = sign_extend_32(imm,16);
1623
1624 if (ra != 0)
1625 vaddr += cpu->gpr[ra];
1626
1627 return(ppc32_exec_memop(cpu,PPC_MEMOP_LHZ,vaddr,rd));
1628 }
1629
1630 /* LHZU - Load Half-Word and Zero with Update */
1631 static fastcall int ppc32_exec_LHZU(cpu_ppc_t *cpu,ppc_insn_t insn)
1632 {
1633 int rd = bits(insn,21,25);
1634 int ra = bits(insn,16,20);
1635 m_uint16_t imm = bits(insn,0,15);
1636 m_uint32_t vaddr;
1637 int res;
1638
1639 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
1640 res = ppc32_exec_memop(cpu,PPC_MEMOP_LHZ,vaddr,rd);
1641 cpu->gpr[ra] = vaddr;
1642 return(res);
1643 }
1644
1645 /* LHZUX - Load Half-Word and Zero with Update Indexed */
1646 static fastcall int ppc32_exec_LHZUX(cpu_ppc_t *cpu,ppc_insn_t insn)
1647 {
1648 int rd = bits(insn,21,25);
1649 int ra = bits(insn,16,20);
1650 int rb = bits(insn,11,15);
1651 m_uint32_t vaddr;
1652 int res;
1653
1654 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
1655 res = ppc32_exec_memop(cpu,PPC_MEMOP_LHZ,vaddr,rd);
1656 cpu->gpr[ra] = vaddr;
1657 return(res);
1658 }
1659
1660 /* LHZX - Load Half-Word and Zero Indexed */
1661 static fastcall int ppc32_exec_LHZX(cpu_ppc_t *cpu,ppc_insn_t insn)
1662 {
1663 int rd = bits(insn,21,25);
1664 int ra = bits(insn,16,20);
1665 int rb = bits(insn,11,15);
1666 m_uint32_t vaddr;
1667
1668 vaddr = cpu->gpr[rb];
1669
1670 if (ra != 0)
1671 vaddr += cpu->gpr[ra];
1672
1673 return(ppc32_exec_memop(cpu,PPC_MEMOP_LHZ,vaddr,rd));
1674 }
1675
1676 /* LMW - Load Multiple Word */
1677 static fastcall int ppc32_exec_LMW(cpu_ppc_t *cpu,ppc_insn_t insn)
1678 {
1679 int rd = bits(insn,21,25);
1680 int ra = bits(insn,16,20);
1681 m_uint16_t imm = bits(insn,0,15);
1682 m_uint32_t vaddr;
1683 int r,res;
1684
1685 vaddr = sign_extend_32(imm,16);
1686
1687 if (ra != 0)
1688 vaddr += cpu->gpr[ra];
1689
1690 for(r=rd;r<=31;r++) {
1691 res = ppc32_exec_memop(cpu,PPC_MEMOP_LWZ,vaddr,r);
1692 if (res != 0) return(res);
1693
1694 vaddr += sizeof(m_uint32_t);
1695 }
1696
1697 return(0);
1698 }
1699
1700 /* LWBRX - Load Word Byte-Reverse Indexed */
1701 static fastcall int ppc32_exec_LWBRX(cpu_ppc_t *cpu,ppc_insn_t insn)
1702 {
1703 int rd = bits(insn,21,25);
1704 int ra = bits(insn,16,20);
1705 int rb = bits(insn,11,15);
1706 m_uint32_t vaddr;
1707
1708 vaddr = cpu->gpr[rb];
1709
1710 if (ra != 0)
1711 vaddr += cpu->gpr[ra];
1712
1713 return(ppc32_exec_memop(cpu,PPC_MEMOP_LWBR,vaddr,rd));
1714 }
1715
1716 /* LWZ - Load Word and Zero */
1717 static fastcall int ppc32_exec_LWZ(cpu_ppc_t *cpu,ppc_insn_t insn)
1718 {
1719 int rd = bits(insn,21,25);
1720 int ra = bits(insn,16,20);
1721 m_uint16_t imm = bits(insn,0,15);
1722 m_uint32_t vaddr;
1723
1724 vaddr = sign_extend_32(imm,16);
1725
1726 if (ra != 0)
1727 vaddr += cpu->gpr[ra];
1728
1729 return(ppc32_exec_memop(cpu,PPC_MEMOP_LWZ,vaddr,rd));
1730 }
1731
1732 /* LWZU - Load Word and Zero with Update */
1733 static fastcall int ppc32_exec_LWZU(cpu_ppc_t *cpu,ppc_insn_t insn)
1734 {
1735 int rd = bits(insn,21,25);
1736 int ra = bits(insn,16,20);
1737 m_uint16_t imm = bits(insn,0,15);
1738 m_uint32_t vaddr;
1739 int res;
1740
1741 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
1742 res = ppc32_exec_memop(cpu,PPC_MEMOP_LWZ,vaddr,rd);
1743 cpu->gpr[ra] = vaddr;
1744 return(res);
1745 }
1746
1747 /* LWZUX - Load Word and Zero with Update Indexed */
1748 static fastcall int ppc32_exec_LWZUX(cpu_ppc_t *cpu,ppc_insn_t insn)
1749 {
1750 int rd = bits(insn,21,25);
1751 int ra = bits(insn,16,20);
1752 int rb = bits(insn,11,15);
1753 m_uint32_t vaddr;
1754 int res;
1755
1756 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
1757 res = ppc32_exec_memop(cpu,PPC_MEMOP_LWZ,vaddr,rd);
1758 cpu->gpr[ra] = vaddr;
1759 return(res);
1760 }
1761
1762 /* LWZX - Load Word and Zero Indexed */
1763 static fastcall int ppc32_exec_LWZX(cpu_ppc_t *cpu,ppc_insn_t insn)
1764 {
1765 int rd = bits(insn,21,25);
1766 int ra = bits(insn,16,20);
1767 int rb = bits(insn,11,15);
1768 m_uint32_t vaddr;
1769
1770 vaddr = cpu->gpr[rb];
1771
1772 if (ra != 0)
1773 vaddr += cpu->gpr[ra];
1774
1775 return(ppc32_exec_memop(cpu,PPC_MEMOP_LWZ,vaddr,rd));
1776 }
1777
1778 /* LWARX - Load Word and Reserve Indexed */
1779 static fastcall int ppc32_exec_LWARX(cpu_ppc_t *cpu,ppc_insn_t insn)
1780 {
1781 int rd = bits(insn,21,25);
1782 int ra = bits(insn,16,20);
1783 int rb = bits(insn,11,15);
1784 m_uint32_t vaddr;
1785
1786 vaddr = cpu->gpr[rb];
1787
1788 if (ra != 0)
1789 vaddr += cpu->gpr[ra];
1790
1791 cpu->reserve = 1;
1792
1793 return(ppc32_exec_memop(cpu,PPC_MEMOP_LWZ,vaddr,rd));
1794 }
1795
1796 /* LFD - Load Floating-Point Double */
1797 static fastcall int ppc32_exec_LFD(cpu_ppc_t *cpu,ppc_insn_t insn)
1798 {
1799 int rd = bits(insn,21,25);
1800 int ra = bits(insn,16,20);
1801 m_uint16_t imm = bits(insn,0,15);
1802 m_uint32_t vaddr;
1803
1804 vaddr = sign_extend_32(imm,16);
1805
1806 if (ra != 0)
1807 vaddr += cpu->gpr[ra];
1808
1809 return(ppc32_exec_memop(cpu,PPC_MEMOP_LFD,vaddr,rd));
1810 }
1811
1812 /* LFDU - Load Floating-Point Double with Update */
1813 static fastcall int ppc32_exec_LFDU(cpu_ppc_t *cpu,ppc_insn_t insn)
1814 {
1815 int rd = bits(insn,21,25);
1816 int ra = bits(insn,16,20);
1817 m_uint16_t imm = bits(insn,0,15);
1818 m_uint32_t vaddr;
1819 int res;
1820
1821 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
1822 res = ppc32_exec_memop(cpu,PPC_MEMOP_LFD,vaddr,rd);
1823 cpu->gpr[ra] = vaddr;
1824 return(res);
1825 }
1826
1827 /* LFDUX - Load Floating-Point Double with Update Indexed */
1828 static fastcall int ppc32_exec_LFDUX(cpu_ppc_t *cpu,ppc_insn_t insn)
1829 {
1830 int rd = bits(insn,21,25);
1831 int ra = bits(insn,16,20);
1832 int rb = bits(insn,11,15);
1833 m_uint32_t vaddr;
1834 int res;
1835
1836 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
1837 res = ppc32_exec_memop(cpu,PPC_MEMOP_LFD,vaddr,rd);
1838 cpu->gpr[ra] = vaddr;
1839 return(res);
1840 }
1841
1842 /* LFDX - Load Floating-Point Double Indexed */
1843 static fastcall int ppc32_exec_LFDX(cpu_ppc_t *cpu,ppc_insn_t insn)
1844 {
1845 int rd = bits(insn,21,25);
1846 int ra = bits(insn,16,20);
1847 int rb = bits(insn,11,15);
1848 m_uint32_t vaddr;
1849
1850 vaddr = cpu->gpr[rb];
1851
1852 if (ra != 0)
1853 vaddr += cpu->gpr[ra];
1854
1855 return(ppc32_exec_memop(cpu,PPC_MEMOP_LFD,vaddr,rd));
1856 }
1857
1858 /* LSWI - Load String Word Immediate */
1859 static fastcall int ppc32_exec_LSWI(cpu_ppc_t *cpu,ppc_insn_t insn)
1860 {
1861 int rd = bits(insn,21,25);
1862 int ra = bits(insn,16,20);
1863 int nb = bits(insn,11,15);
1864 m_uint32_t vaddr = 0;
1865 int res,r;
1866
1867 if (ra != 0)
1868 vaddr += cpu->gpr[ra];
1869
1870 if (nb == 0)
1871 nb = 32;
1872
1873 r = rd - 1;
1874 cpu->sw_pos = 0;
1875
1876 while(nb > 0) {
1877 if (cpu->sw_pos == 0) {
1878 r = (r + 1) & 0x1F;
1879 cpu->gpr[r] = 0;
1880 }
1881
1882 if (unlikely(res = ppc32_exec_memop(cpu,PPC_MEMOP_LSW,vaddr,r)) != 0)
1883 return(res);
1884
1885 cpu->sw_pos += 8;
1886
1887 if (cpu->sw_pos == 32)
1888 cpu->sw_pos = 0;
1889
1890 vaddr++;
1891 nb--;
1892 }
1893
1894 return(0);
1895 }
1896
1897 /* LSWX - Load String Word Indexed */
1898 static fastcall int ppc32_exec_LSWX(cpu_ppc_t *cpu,ppc_insn_t insn)
1899 {
1900 int rd = bits(insn,21,25);
1901 int ra = bits(insn,16,20);
1902 int rb = bits(insn,11,15);
1903 m_uint32_t vaddr;
1904 int res,r,nb;
1905
1906 vaddr = cpu->gpr[rb];
1907
1908 if (ra != 0)
1909 vaddr += cpu->gpr[ra];
1910
1911 nb = cpu->xer & PPC32_XER_BC_MASK;
1912 r = rd - 1;
1913 cpu->sw_pos = 0;
1914
1915 while(nb > 0) {
1916 if (cpu->sw_pos == 0) {
1917 r = (r + 1) & 0x1F;
1918 cpu->gpr[r] = 0;
1919 }
1920
1921 if (unlikely(res = ppc32_exec_memop(cpu,PPC_MEMOP_LSW,vaddr,r)) != 0)
1922 return(res);
1923
1924 cpu->sw_pos += 8;
1925
1926 if (cpu->sw_pos == 32)
1927 cpu->sw_pos = 0;
1928
1929 vaddr++;
1930 nb--;
1931 }
1932
1933 return(0);
1934 }
1935
1936 /* MCRF - Move Condition Register Field */
1937 static fastcall int ppc32_exec_MCRF(cpu_ppc_t *cpu,ppc_insn_t insn)
1938 {
1939 int rd = bits(insn,23,25);
1940 int rs = bits(insn,18,20);
1941
1942 cpu->cr_fields[rd] = cpu->cr_fields[rs];
1943 return(0);
1944 }
1945
1946 /* MFCR - Move from Condition Register */
1947 static fastcall int ppc32_exec_MFCR(cpu_ppc_t *cpu,ppc_insn_t insn)
1948 {
1949 int rd = bits(insn,21,25);
1950
1951 cpu->gpr[rd] = ppc32_get_cr(cpu);
1952 return(0);
1953 }
1954
1955 /* MFMSR - Move from Machine State Register */
1956 static fastcall int ppc32_exec_MFMSR(cpu_ppc_t *cpu,ppc_insn_t insn)
1957 {
1958 int rd = bits(insn,21,25);
1959
1960 cpu->gpr[rd] = cpu->msr;
1961 return(0);
1962 }
1963
1964 /* MFTBU - Move from Time Base (Up) */
1965 static fastcall int ppc32_exec_MFTBU(cpu_ppc_t *cpu,ppc_insn_t insn)
1966 {
1967 int rd = bits(insn,21,25);
1968
1969 cpu->gpr[rd] = cpu->tb >> 32;
1970 return(0);
1971 }
1972
1973 /* MFTBL - Move from Time Base (Lo) */
1974 static fastcall int ppc32_exec_MFTBL(cpu_ppc_t *cpu,ppc_insn_t insn)
1975 {
1976 int rd = bits(insn,21,25);
1977
1978 cpu->tb += 50;
1979
1980 cpu->gpr[rd] = cpu->tb & 0xFFFFFFFF;
1981 return(0);
1982 }
1983
1984 /* MFSPR - Move from Special-Purpose Register */
1985 static fastcall int ppc32_exec_MFSPR(cpu_ppc_t *cpu,ppc_insn_t insn)
1986 {
1987 int rd = bits(insn,21,25);
1988 int spr0 = bits(insn,16,20);
1989 int spr1 = bits(insn,11,15);
1990 u_int spr;
1991
1992 spr = (spr1 << 5) | spr0;
1993 cpu->gpr[rd] = 0;
1994
1995 //cpu_log(cpu->gen,"SPR","reading SPR=%d at cpu->ia=0x%8.8x\n",spr,cpu->ia);
1996
1997 if ((spr1 == 0x10) || (spr1 == 0x11)) {
1998 cpu->gpr[rd] = ppc32_get_bat_spr(cpu,spr);
1999 return(0);
2000 }
2001
2002 switch(spr) {
2003 case PPC32_SPR_XER:
2004 cpu->gpr[rd] = cpu->xer | (cpu->xer_ca << PPC32_XER_CA_BIT);
2005 break;
2006 case PPC32_SPR_DSISR:
2007 cpu->gpr[rd] = cpu->dsisr;
2008 break;
2009 case PPC32_SPR_DAR:
2010 cpu->gpr[rd] = cpu->dar;
2011 break;
2012 case PPC32_SPR_DEC:
2013 cpu->gpr[rd] = cpu->dec;
2014 break;
2015 case PPC32_SPR_SDR1:
2016 cpu->gpr[rd] = cpu->sdr1;
2017 break;
2018 case PPC32_SPR_SRR0:
2019 cpu->gpr[rd] = cpu->srr0;
2020 break;
2021 case PPC32_SPR_SRR1:
2022 cpu->gpr[rd] = cpu->srr1;
2023 break;
2024 case PPC32_SPR_TBL_READ:
2025 cpu->gpr[rd] = cpu->tb & 0xFFFFFFFF;
2026 break;
2027 case PPC32_SPR_TBU_READ:
2028 cpu->gpr[rd] = cpu->tb >> 32;
2029 break;
2030 case PPC32_SPR_SPRG0:
2031 cpu->gpr[rd] = cpu->sprg[0];
2032 break;
2033 case PPC32_SPR_SPRG1:
2034 cpu->gpr[rd] = cpu->sprg[1];
2035 break;
2036 case PPC32_SPR_SPRG2:
2037 cpu->gpr[rd] = cpu->sprg[2];
2038 break;
2039 case PPC32_SPR_SPRG3:
2040 cpu->gpr[rd] = cpu->sprg[3];
2041 break;
2042 case PPC32_SPR_PVR:
2043 cpu->gpr[rd] = cpu->pvr;
2044 break;
2045 case PPC32_SPR_HID0:
2046 cpu->gpr[rd] = cpu->hid0;
2047 break;
2048 case PPC32_SPR_HID1:
2049 cpu->gpr[rd] = cpu->hid1;
2050 break;
2051 case PPC405_SPR_PID:
2052 cpu->gpr[rd] = cpu->ppc405_pid;
2053 break;
2054
2055 /* MPC860 IMMR */
2056 case 638:
2057 cpu->gpr[rd] = 0x68010000;
2058 break;
2059
2060 default:
2061 cpu->gpr[rd] = 0x0;
2062 //printf("READING SPR = %d\n",spr);
2063 }
2064
2065 return(0);
2066 }
2067
2068 /* MFSR - Move From Segment Register */
2069 static fastcall int ppc32_exec_MFSR(cpu_ppc_t *cpu,ppc_insn_t insn)
2070 {
2071 int rd = bits(insn,21,25);
2072 int sr = bits(insn,16,19);
2073
2074 cpu->gpr[rd] = cpu->sr[sr];
2075 return(0);
2076 }
2077
2078 /* MFSRIN - Move From Segment Register Indirect */
2079 static fastcall int ppc32_exec_MFSRIN(cpu_ppc_t *cpu,ppc_insn_t insn)
2080 {
2081 int rd = bits(insn,21,25);
2082 int rb = bits(insn,11,15);
2083
2084 cpu->gpr[rd] = cpu->sr[cpu->gpr[rb] >> 28];
2085 return(0);
2086 }
2087
2088 /* MTCRF - Move to Condition Register Fields */
2089 static fastcall int ppc32_exec_MTCRF(cpu_ppc_t *cpu,ppc_insn_t insn)
2090 {
2091 int rs = bits(insn,21,25);
2092 int crm = bits(insn,12,19);
2093 int i;
2094
2095 for(i=0;i<8;i++)
2096 if (crm & (1 << (7 - i)))
2097 cpu->cr_fields[i] = (cpu->gpr[rs] >> (28 - (i << 2))) & 0x0F;
2098
2099 return(0);
2100 }
2101
2102 /* MTMSR - Move to Machine State Register */
2103 static fastcall int ppc32_exec_MTMSR(cpu_ppc_t *cpu,ppc_insn_t insn)
2104 {
2105 int rs = bits(insn,21,25);
2106
2107 cpu->msr = cpu->gpr[rs];
2108 cpu->irq_check = (cpu->msr & PPC32_MSR_EE) && cpu->irq_pending;
2109
2110 //printf("New MSR = 0x%8.8x at cpu->ia=0x%8.8x\n",cpu->msr,cpu->ia);
2111 return(0);
2112 }
2113
2114 /* MTSPR - Move to Special-Purpose Register */
2115 static fastcall int ppc32_exec_MTSPR(cpu_ppc_t *cpu,ppc_insn_t insn)
2116 {
2117 int rd = bits(insn,21,25);
2118 int spr0 = bits(insn,16,20);
2119 int spr1 = bits(insn,11,15);
2120 u_int spr;
2121
2122 spr = (spr1 << 5) | spr0;
2123
2124 //cpu_log(cpu->gen,"SPR","writing SPR=%d, val=0x%8.8x at cpu->ia=0x%8.8x\n",
2125 // spr,cpu->ia,cpu->gpr[rd]);
2126
2127 if ((spr1 == 0x10) || (spr1 == 0x11)) {
2128 ppc32_set_bat_spr(cpu,spr,cpu->gpr[rd]);
2129 return(0);
2130 }
2131
2132 switch(spr) {
2133 case PPC32_SPR_XER:
2134 cpu->xer = cpu->gpr[rd] & ~PPC32_XER_CA;
2135 cpu->xer_ca = (cpu->gpr[rd] >> PPC32_XER_CA_BIT) & 0x1;
2136 break;
2137 case PPC32_SPR_DEC:
2138 //printf("WRITING DECR 0x%8.8x AT IA=0x%8.8x\n",cpu->gpr[rd],cpu->ia);
2139 cpu->dec = cpu->gpr[rd];
2140 cpu->timer_irq_armed = TRUE;
2141 break;
2142 case PPC32_SPR_SDR1:
2143 cpu->sdr1 = cpu->gpr[rd];
2144 ppc32_mem_invalidate_cache(cpu);
2145 break;
2146 case PPC32_SPR_SRR0:
2147 cpu->srr0 = cpu->gpr[rd];
2148 break;
2149 case PPC32_SPR_SRR1:
2150 cpu->srr1 = cpu->gpr[rd];
2151 break;
2152 case PPC32_SPR_SPRG0:
2153 cpu->sprg[0] = cpu->gpr[rd];
2154 break;
2155 case PPC32_SPR_SPRG1:
2156 cpu->sprg[1] = cpu->gpr[rd];
2157 break;
2158 case PPC32_SPR_SPRG2:
2159 cpu->sprg[2] = cpu->gpr[rd];
2160 break;
2161 case PPC32_SPR_SPRG3:
2162 cpu->sprg[3] = cpu->gpr[rd];
2163 break;
2164 case PPC32_SPR_HID0:
2165 cpu->hid0 = cpu->gpr[rd];
2166 break;
2167 case PPC32_SPR_HID1:
2168 cpu->hid1 = cpu->gpr[rd];
2169 break;
2170 case PPC405_SPR_PID:
2171 cpu->ppc405_pid = cpu->gpr[rd];
2172 break;
2173 #if 0
2174 default:
2175 printf("WRITING SPR=%d, data=0x%8.8x\n",spr,cpu->gpr[rd]);
2176 #endif
2177 }
2178
2179 return(0);
2180 }
2181
2182 /* MTSR - Move To Segment Register */
2183 static fastcall int ppc32_exec_MTSR(cpu_ppc_t *cpu,ppc_insn_t insn)
2184 {
2185 int rs = bits(insn,21,25);
2186 int sr = bits(insn,16,19);
2187
2188 cpu->sr[sr] = cpu->gpr[rs];
2189 ppc32_mem_invalidate_cache(cpu);
2190 return(0);
2191 }
2192
2193 /* MULHW - Multiply High Word */
2194 static fastcall int ppc32_exec_MULHW(cpu_ppc_t *cpu,ppc_insn_t insn)
2195 {
2196 int rd = bits(insn,21,25);
2197 int ra = bits(insn,16,20);
2198 int rb = bits(insn,11,15);
2199 m_int64_t tmp;
2200 m_uint32_t res;
2201
2202 tmp = (m_int64_t)(m_int32_t)cpu->gpr[ra];
2203 tmp *= (m_int64_t)(m_int32_t)cpu->gpr[rb];
2204 res = tmp >> 32;
2205
2206 cpu->gpr[rd] = res;
2207 return(0);
2208 }
2209
2210 /* MULHW. */
2211 static fastcall int ppc32_exec_MULHW_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2212 {
2213 int rd = bits(insn,21,25);
2214 int ra = bits(insn,16,20);
2215 int rb = bits(insn,11,15);
2216 m_int64_t tmp;
2217 m_uint32_t res;
2218
2219 tmp = (m_int64_t)(m_int32_t)cpu->gpr[ra];
2220 tmp *= (m_int64_t)(m_int32_t)cpu->gpr[rb];
2221 res = tmp >> 32;
2222 ppc32_exec_update_cr0(cpu,res);
2223 cpu->gpr[rd] = res;
2224 return(0);
2225 }
2226
2227 /* MULHWU - Multiply High Word Unsigned */
2228 static fastcall int ppc32_exec_MULHWU(cpu_ppc_t *cpu,ppc_insn_t insn)
2229 {
2230 int rd = bits(insn,21,25);
2231 int ra = bits(insn,16,20);
2232 int rb = bits(insn,11,15);
2233 m_uint64_t tmp;
2234 m_uint32_t res;
2235
2236 tmp = (m_uint64_t)cpu->gpr[ra];
2237 tmp *= (m_uint64_t)cpu->gpr[rb];
2238 res = tmp >> 32;
2239
2240 cpu->gpr[rd] = res;
2241 return(0);
2242 }
2243
2244 /* MULHWU. */
2245 static fastcall int ppc32_exec_MULHWU_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2246 {
2247 int rd = bits(insn,21,25);
2248 int ra = bits(insn,16,20);
2249 int rb = bits(insn,11,15);
2250 m_uint64_t tmp;
2251 m_uint32_t res;
2252
2253 tmp = (m_uint64_t)cpu->gpr[ra];
2254 tmp *= (m_uint64_t)cpu->gpr[rb];
2255 res = tmp >> 32;
2256 ppc32_exec_update_cr0(cpu,res);
2257 cpu->gpr[rd] = res;
2258 return(0);
2259 }
2260
2261 /* MULLI - Multiply Low Immediate */
2262 static fastcall int ppc32_exec_MULLI(cpu_ppc_t *cpu,ppc_insn_t insn)
2263 {
2264 int rd = bits(insn,21,25);
2265 int ra = bits(insn,16,20);
2266 m_uint32_t imm = bits(insn,0,15);
2267
2268 cpu->gpr[rd] = (m_int32_t)cpu->gpr[ra] * sign_extend_32(imm,16);
2269 return(0);
2270 }
2271
2272 /* MULLW - Multiply Low Word */
2273 static fastcall int ppc32_exec_MULLW(cpu_ppc_t *cpu,ppc_insn_t insn)
2274 {
2275 int rd = bits(insn,21,25);
2276 int ra = bits(insn,16,20);
2277 int rb = bits(insn,11,15);
2278 m_int64_t tmp;
2279
2280 tmp = (m_int64_t)(m_int32_t)cpu->gpr[ra];
2281 tmp *= (m_int64_t)(m_int32_t)cpu->gpr[rb];
2282 cpu->gpr[rd] = (m_uint32_t)tmp;
2283 return(0);
2284 }
2285
2286 /* MULLW. */
2287 static fastcall int ppc32_exec_MULLW_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2288 {
2289 int rd = bits(insn,21,25);
2290 int ra = bits(insn,16,20);
2291 int rb = bits(insn,11,15);
2292 register m_uint32_t res;
2293 m_int64_t tmp;
2294
2295 tmp = (m_int64_t)(m_int32_t)cpu->gpr[ra];
2296 tmp *= (m_int64_t)(m_int32_t)cpu->gpr[rb];
2297
2298 res = (m_uint32_t)tmp;
2299 ppc32_exec_update_cr0(cpu,res);
2300 cpu->gpr[rd] = res;
2301 return(0);
2302 }
2303
2304 /* MULLWO - Multiply Low Word with Overflow */
2305 static fastcall int ppc32_exec_MULLWO(cpu_ppc_t *cpu,ppc_insn_t insn)
2306 {
2307 int rd = bits(insn,21,25);
2308 int ra = bits(insn,16,20);
2309 int rb = bits(insn,11,15);
2310 m_int64_t tmp;
2311
2312 tmp = (m_int64_t)(m_int32_t)cpu->gpr[ra];
2313 tmp *= (m_int64_t)(m_int32_t)cpu->gpr[rb];
2314
2315 cpu->xer &= ~PPC32_XER_OV;
2316
2317 if (unlikely(tmp != (m_int64_t)(m_int32_t)tmp))
2318 cpu->xer |= PPC32_XER_OV|PPC32_XER_SO;
2319
2320 cpu->gpr[rd] = (m_uint32_t)tmp;
2321 return(0);
2322 }
2323
2324 /* MULLWO. */
2325 static fastcall int ppc32_exec_MULLWO_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2326 {
2327 int rd = bits(insn,21,25);
2328 int ra = bits(insn,16,20);
2329 int rb = bits(insn,11,15);
2330 register m_uint32_t res;
2331 m_int64_t tmp;
2332
2333 tmp = (m_int64_t)(m_int32_t)cpu->gpr[ra];
2334 tmp *= (m_int64_t)(m_int32_t)cpu->gpr[rb];
2335
2336 cpu->xer &= ~PPC32_XER_OV;
2337
2338 if (unlikely(tmp != (m_int64_t)(m_int32_t)tmp))
2339 cpu->xer |= PPC32_XER_OV|PPC32_XER_SO;
2340
2341 res = (m_uint32_t)tmp;
2342 ppc32_exec_update_cr0(cpu,res);
2343 cpu->gpr[rd] = res;
2344 return(0);
2345 }
2346
2347 /* NAND */
2348 static fastcall int ppc32_exec_NAND(cpu_ppc_t *cpu,ppc_insn_t insn)
2349 {
2350 int rs = bits(insn,21,25);
2351 int ra = bits(insn,16,20);
2352 int rb = bits(insn,11,15);
2353
2354 cpu->gpr[ra] = ~(cpu->gpr[rs] & cpu->gpr[rb]);
2355 return(0);
2356 }
2357
2358 /* NAND. */
2359 static fastcall int ppc32_exec_NAND_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2360 {
2361 int rs = bits(insn,21,25);
2362 int ra = bits(insn,16,20);
2363 int rb = bits(insn,11,15);
2364 register m_uint32_t tmp;
2365
2366 tmp = ~(cpu->gpr[rs] & cpu->gpr[rb]);
2367 ppc32_exec_update_cr0(cpu,tmp);
2368 cpu->gpr[ra] = tmp;
2369 return(0);
2370 }
2371
2372 /* NEG - Negate */
2373 static fastcall int ppc32_exec_NEG(cpu_ppc_t *cpu,ppc_insn_t insn)
2374 {
2375 int rd = bits(insn,21,25);
2376 int ra = bits(insn,16,20);
2377
2378 cpu->gpr[rd] = ~cpu->gpr[ra] + 1;
2379 return(0);
2380 }
2381
2382 /* NEG. */
2383 static fastcall int ppc32_exec_NEG_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2384 {
2385 int rd = bits(insn,21,25);
2386 int ra = bits(insn,16,20);
2387 register m_uint32_t tmp;
2388
2389 tmp = ~cpu->gpr[ra] + 1;
2390 ppc32_exec_update_cr0(cpu,tmp);
2391 cpu->gpr[rd] = tmp;
2392 return(0);
2393 }
2394
2395 /* NEGO */
2396 static fastcall int ppc32_exec_NEGO(cpu_ppc_t *cpu,ppc_insn_t insn)
2397 {
2398 int rd = bits(insn,21,25);
2399 int ra = bits(insn,16,20);
2400 register m_uint32_t tmp;
2401
2402 tmp = ~cpu->gpr[ra] + 1;
2403 cpu->gpr[rd] = tmp;
2404
2405 cpu->xer &= ~PPC32_XER_OV;
2406
2407 if (unlikely(tmp == 0x80000000))
2408 cpu->xer |= PPC32_XER_OV|PPC32_XER_SO;
2409
2410 ppc32_exec_update_cr0(cpu,tmp);
2411 return(0);
2412 }
2413
2414 /* NEGO. */
2415 static fastcall int ppc32_exec_NEGO_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2416 {
2417 int rd = bits(insn,21,25);
2418 int ra = bits(insn,16,20);
2419 register m_uint32_t tmp;
2420
2421 tmp = ~cpu->gpr[ra] + 1;
2422 cpu->gpr[rd] = tmp;
2423
2424 cpu->xer &= ~PPC32_XER_OV;
2425
2426 if (unlikely(tmp == 0x80000000))
2427 cpu->xer |= PPC32_XER_OV|PPC32_XER_SO;
2428
2429 ppc32_exec_update_cr0(cpu,tmp);
2430 return(0);
2431 }
2432
2433 /* NOR */
2434 static fastcall int ppc32_exec_NOR(cpu_ppc_t *cpu,ppc_insn_t insn)
2435 {
2436 int rs = bits(insn,21,25);
2437 int ra = bits(insn,16,20);
2438 int rb = bits(insn,11,15);
2439
2440 cpu->gpr[ra] = ~(cpu->gpr[rs] | cpu->gpr[rb]);
2441 return(0);
2442 }
2443
2444 /* NOR. */
2445 static fastcall int ppc32_exec_NOR_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2446 {
2447 int rs = bits(insn,21,25);
2448 int ra = bits(insn,16,20);
2449 int rb = bits(insn,11,15);
2450 register m_uint32_t tmp;
2451
2452 tmp = ~(cpu->gpr[rs] | cpu->gpr[rb]);
2453 ppc32_exec_update_cr0(cpu,tmp);
2454 cpu->gpr[ra] = tmp;
2455 return(0);
2456 }
2457
2458 /* OR */
2459 static fastcall int ppc32_exec_OR(cpu_ppc_t *cpu,ppc_insn_t insn)
2460 {
2461 int rs = bits(insn,21,25);
2462 int ra = bits(insn,16,20);
2463 int rb = bits(insn,11,15);
2464
2465 cpu->gpr[ra] = cpu->gpr[rs] | cpu->gpr[rb];
2466 return(0);
2467 }
2468
2469 /* OR. */
2470 static fastcall int ppc32_exec_OR_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2471 {
2472 int rs = bits(insn,21,25);
2473 int ra = bits(insn,16,20);
2474 int rb = bits(insn,11,15);
2475 register m_uint32_t tmp;
2476
2477 tmp = cpu->gpr[rs] | cpu->gpr[rb];
2478 ppc32_exec_update_cr0(cpu,tmp);
2479 cpu->gpr[ra] = tmp;
2480 return(0);
2481 }
2482
2483 /* ORC - OR with Complement */
2484 static fastcall int ppc32_exec_ORC(cpu_ppc_t *cpu,ppc_insn_t insn)
2485 {
2486 int rs = bits(insn,21,25);
2487 int ra = bits(insn,16,20);
2488 int rb = bits(insn,11,15);
2489
2490 cpu->gpr[ra] = cpu->gpr[rs] | ~cpu->gpr[rb];
2491 return(0);
2492 }
2493
2494 /* ORC. */
2495 static fastcall int ppc32_exec_ORC_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2496 {
2497 int rs = bits(insn,21,25);
2498 int ra = bits(insn,16,20);
2499 int rb = bits(insn,11,15);
2500 register m_uint32_t tmp;
2501
2502 tmp = cpu->gpr[rs] | ~cpu->gpr[rb];
2503 ppc32_exec_update_cr0(cpu,tmp);
2504 cpu->gpr[ra] = tmp;
2505 return(0);
2506 }
2507
2508 /* ORI - OR Immediate */
2509 static fastcall int ppc32_exec_ORI(cpu_ppc_t *cpu,ppc_insn_t insn)
2510 {
2511 int rs = bits(insn,21,25);
2512 int ra = bits(insn,16,20);
2513 m_uint16_t imm = bits(insn,0,15);
2514
2515 cpu->gpr[ra] = cpu->gpr[rs] | imm;
2516 return(0);
2517 }
2518
2519 /* ORIS - OR Immediate Shifted */
2520 static fastcall int ppc32_exec_ORIS(cpu_ppc_t *cpu,ppc_insn_t insn)
2521 {
2522 int rs = bits(insn,21,25);
2523 int ra = bits(insn,16,20);
2524 m_uint32_t imm = bits(insn,0,15);
2525
2526 cpu->gpr[ra] = cpu->gpr[rs] | (imm << 16);
2527 return(0);
2528 }
2529
2530 /* RFI - Return From Interrupt */
2531 static fastcall int ppc32_exec_RFI(cpu_ppc_t *cpu,ppc_insn_t insn)
2532 {
2533 //printf("RFI: srr0=0x%8.8x, srr1=0x%8.8x\n",cpu->srr0,cpu->srr1);
2534
2535 cpu->msr &= ~PPC32_RFI_MSR_MASK;
2536 cpu->msr |= cpu->srr1 & PPC32_RFI_MSR_MASK;
2537
2538 cpu->msr &= ~(1 << 13);
2539 cpu->ia = cpu->srr0 & ~0x03;
2540
2541 cpu->irq_check = (cpu->msr & PPC32_MSR_EE) && cpu->irq_pending;
2542
2543 //printf("NEW IA=0x%8.8x, NEW MSR=0x%8.8x\n",cpu->ia,cpu->msr);
2544 return(1);
2545 }
2546
2547 /* RLWIMI - Rotate Left Word Immediate then Mask Insert */
2548 static fastcall int ppc32_exec_RLWIMI(cpu_ppc_t *cpu,ppc_insn_t insn)
2549 {
2550 int rs = bits(insn,21,25);
2551 int ra = bits(insn,16,20);
2552 int sh = bits(insn,11,15);
2553 int mb = bits(insn,6,10);
2554 int me = bits(insn,1,5);
2555 register m_uint32_t r,mask;
2556
2557 r = (cpu->gpr[rs] << sh) | (cpu->gpr[rs] >> (32 - sh));
2558 mask = ppc32_rotate_mask(mb,me);
2559 cpu->gpr[ra] = (r & mask) | (cpu->gpr[ra] & ~mask);
2560 return(0);
2561 }
2562
2563 /* RLWIMI. - Rotate Left Word Immediate then Mask Insert */
2564 static fastcall int ppc32_exec_RLWIMI_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2565 {
2566 int rs = bits(insn,21,25);
2567 int ra = bits(insn,16,20);
2568 int sh = bits(insn,11,15);
2569 int mb = bits(insn,6,10);
2570 int me = bits(insn,1,5);
2571 register m_uint32_t r,mask,tmp;
2572
2573 r = (cpu->gpr[rs] << sh) | (cpu->gpr[rs] >> (32 - sh));
2574 mask = ppc32_rotate_mask(mb,me);
2575 tmp = (r & mask) | (cpu->gpr[ra] & ~mask);
2576 ppc32_exec_update_cr0(cpu,tmp);
2577 cpu->gpr[ra] = tmp;
2578 return(0);
2579 }
2580
2581 /* RLWINM - Rotate Left Word Immediate AND with Mask */
2582 static fastcall int ppc32_exec_RLWINM(cpu_ppc_t *cpu,ppc_insn_t insn)
2583 {
2584 int rs = bits(insn,21,25);
2585 int ra = bits(insn,16,20);
2586 int sh = bits(insn,11,15);
2587 int mb = bits(insn,6,10);
2588 int me = bits(insn,1,5);
2589 register m_uint32_t r,mask;
2590
2591 r = (cpu->gpr[rs] << sh) | (cpu->gpr[rs] >> (32 - sh));
2592 mask = ppc32_rotate_mask(mb,me);
2593 cpu->gpr[ra] = r & mask;
2594 return(0);
2595 }
2596
2597 /* RLWINM. - Rotate Left Word Immediate AND with Mask */
2598 static fastcall int ppc32_exec_RLWINM_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2599 {
2600 int rs = bits(insn,21,25);
2601 int ra = bits(insn,16,20);
2602 int sh = bits(insn,11,15);
2603 int mb = bits(insn,6,10);
2604 int me = bits(insn,1,5);
2605 register m_uint32_t r,mask,tmp;
2606
2607 r = (cpu->gpr[rs] << sh) | (cpu->gpr[rs] >> (32 - sh));
2608 mask = ppc32_rotate_mask(mb,me);
2609 tmp = r & mask;
2610 ppc32_exec_update_cr0(cpu,tmp);
2611 cpu->gpr[ra] = tmp;
2612 return(0);
2613 }
2614
2615 /* RLWNM - Rotate Left Word then Mask Insert */
2616 static fastcall int ppc32_exec_RLWNM(cpu_ppc_t *cpu,ppc_insn_t insn)
2617 {
2618 int rs = bits(insn,21,25);
2619 int ra = bits(insn,16,20);
2620 int rb = bits(insn,11,15);
2621 int mb = bits(insn,6,10);
2622 int me = bits(insn,1,5);
2623 register m_uint32_t r,sh,mask;
2624
2625 sh = cpu->gpr[rb] & 0x1f;
2626 r = (cpu->gpr[rs] << sh) | (cpu->gpr[rs] >> (32 - sh));
2627 mask = ppc32_rotate_mask(mb,me);
2628 cpu->gpr[ra] = r & mask;
2629 return(0);
2630 }
2631
2632 /* RLWNM. - Rotate Left Word then Mask Insert */
2633 static fastcall int ppc32_exec_RLWNM_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2634 {
2635 int rs = bits(insn,21,25);
2636 int ra = bits(insn,16,20);
2637 int rb = bits(insn,11,15);
2638 int mb = bits(insn,6,10);
2639 int me = bits(insn,1,5);
2640 register m_uint32_t r,sh,mask,tmp;
2641
2642 sh = cpu->gpr[rb] & 0x1f;
2643 r = (cpu->gpr[rs] << sh) | (cpu->gpr[rs] >> (32 - sh));
2644 mask = ppc32_rotate_mask(mb,me);
2645 tmp = r & mask;
2646 ppc32_exec_update_cr0(cpu,tmp);
2647 cpu->gpr[ra] = tmp;
2648 return(0);
2649 }
2650
2651 /* SC - System Call */
2652 static fastcall int ppc32_exec_SC(cpu_ppc_t *cpu,ppc_insn_t insn)
2653 {
2654 ppc32_trigger_exception(cpu,PPC32_EXC_SYSCALL);
2655 return(1);
2656 }
2657
2658 /* SLW - Shift Left Word */
2659 static fastcall int ppc32_exec_SLW(cpu_ppc_t *cpu,ppc_insn_t insn)
2660 {
2661 int rs = bits(insn,21,25);
2662 int ra = bits(insn,16,20);
2663 int rb = bits(insn,11,15);
2664 register m_uint32_t s;
2665
2666 s = cpu->gpr[rb] & 0x3f;
2667
2668 if (likely(!(s & 0x20)))
2669 cpu->gpr[ra] = cpu->gpr[rs] << s;
2670 else
2671 cpu->gpr[ra] = 0;
2672
2673 return(0);
2674 }
2675
2676 /* SLW. */
2677 static fastcall int ppc32_exec_SLW_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2678 {
2679 int rs = bits(insn,21,25);
2680 int ra = bits(insn,16,20);
2681 int rb = bits(insn,11,15);
2682 register m_uint32_t s,tmp;
2683
2684 s = cpu->gpr[rb] & 0x3f;
2685
2686 if (likely(!(s & 0x20)))
2687 tmp = cpu->gpr[rs] << s;
2688 else
2689 tmp = 0;
2690
2691 ppc32_exec_update_cr0(cpu,tmp);
2692 cpu->gpr[ra] = tmp;
2693 return(0);
2694 }
2695
2696 /* SRAW - Shift Right Algebraic Word */
2697 static fastcall int ppc32_exec_SRAW(cpu_ppc_t *cpu,ppc_insn_t insn)
2698 {
2699 int rs = bits(insn,21,25);
2700 int ra = bits(insn,16,20);
2701 int rb = bits(insn,11,15);
2702 register m_uint32_t s,mask;
2703 int sh;
2704
2705 cpu->xer_ca = 0;
2706
2707 s = cpu->gpr[rs];
2708 sh = cpu->gpr[rb];
2709
2710 if (unlikely(sh & 0x20)) {
2711 cpu->gpr[ra] = (m_int32_t)s >> 31;
2712 cpu->xer_ca = cpu->gpr[ra] & 0x1;
2713 return(0);
2714 }
2715
2716 cpu->gpr[ra] = (m_int32_t)s >> sh;
2717 mask = ~(0xFFFFFFFFU << sh);
2718
2719 if ((s & 0x80000000) && ((s & mask) != 0))
2720 cpu->xer_ca = 1;
2721
2722 return(0);
2723 }
2724
2725 /* SRAWI - Shift Right Algebraic Word Immediate */
2726 static fastcall int ppc32_exec_SRAWI(cpu_ppc_t *cpu,ppc_insn_t insn)
2727 {
2728 int rs = bits(insn,21,25);
2729 int ra = bits(insn,16,20);
2730 int sh = bits(insn,11,15);
2731 register m_uint32_t s,mask;
2732
2733 cpu->xer_ca = 0;
2734
2735 s = cpu->gpr[rs];
2736 cpu->gpr[ra] = (m_int32_t)s >> sh;
2737 mask = ~(0xFFFFFFFFU << sh);
2738
2739 if ((s & 0x80000000) && ((s & mask) != 0))
2740 cpu->xer_ca = 1;
2741
2742 return(0);
2743 }
2744
2745 /* SRAWI. */
2746 static fastcall int ppc32_exec_SRAWI_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2747 {
2748 int rs = bits(insn,21,25);
2749 int ra = bits(insn,16,20);
2750 int sh = bits(insn,11,15);
2751 register m_uint32_t s,r,mask;
2752
2753 cpu->xer_ca = 0;
2754
2755 s = cpu->gpr[rs];
2756 r = (m_int32_t)s >> sh;
2757 mask = ~(0xFFFFFFFFU << sh);
2758
2759 if ((s & 0x80000000) && ((s & mask) != 0))
2760 cpu->xer_ca = 1;
2761
2762 ppc32_exec_update_cr0(cpu,r);
2763 cpu->gpr[ra] = r;
2764 return(0);
2765 }
2766
2767 /* SRW - Shift Right Word */
2768 static fastcall int ppc32_exec_SRW(cpu_ppc_t *cpu,ppc_insn_t insn)
2769 {
2770 int rs = bits(insn,21,25);
2771 int ra = bits(insn,16,20);
2772 int rb = bits(insn,11,15);
2773 register m_uint32_t s;
2774
2775 s = cpu->gpr[rb] & 0x3f;
2776
2777 if (likely(!(s & 0x20)))
2778 cpu->gpr[ra] = cpu->gpr[rs] >> s;
2779 else
2780 cpu->gpr[ra] = 0;
2781
2782 return(0);
2783 }
2784
2785 /* SRW. */
2786 static fastcall int ppc32_exec_SRW_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
2787 {
2788 int rs = bits(insn,21,25);
2789 int ra = bits(insn,16,20);
2790 int rb = bits(insn,11,15);
2791 register m_uint32_t s,tmp;
2792
2793 s = cpu->gpr[rb] & 0x3f;
2794
2795 if (likely(!(s & 0x20)))
2796 tmp = cpu->gpr[rs] >> s;
2797 else
2798 tmp = 0;
2799
2800 ppc32_exec_update_cr0(cpu,tmp);
2801 cpu->gpr[ra] = tmp;
2802 return(0);
2803 }
2804
2805 /* STB - Store Byte */
2806 static fastcall int ppc32_exec_STB(cpu_ppc_t *cpu,ppc_insn_t insn)
2807 {
2808 int rs = bits(insn,21,25);
2809 int ra = bits(insn,16,20);
2810 m_uint16_t imm = bits(insn,0,15);
2811 m_uint32_t vaddr;
2812
2813 vaddr = sign_extend_32(imm,16);
2814
2815 if (ra != 0)
2816 vaddr += cpu->gpr[ra];
2817
2818 return(ppc32_exec_memop(cpu,PPC_MEMOP_STB,vaddr,rs));
2819 }
2820
2821 /* STBU - Store Byte with Update */
2822 static fastcall int ppc32_exec_STBU(cpu_ppc_t *cpu,ppc_insn_t insn)
2823 {
2824 int rs = bits(insn,21,25);
2825 int ra = bits(insn,16,20);
2826 m_uint16_t imm = bits(insn,0,15);
2827 m_uint32_t vaddr;
2828 int res;
2829
2830 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
2831 res = ppc32_exec_memop(cpu,PPC_MEMOP_STB,vaddr,rs);
2832 cpu->gpr[ra] = vaddr;
2833 return(res);
2834 }
2835
2836 /* STBUX - Store Byte with Update Indexed */
2837 static fastcall int ppc32_exec_STBUX(cpu_ppc_t *cpu,ppc_insn_t insn)
2838 {
2839 int rs = bits(insn,21,25);
2840 int ra = bits(insn,16,20);
2841 int rb = bits(insn,11,15);
2842 m_uint32_t vaddr;
2843 int res;
2844
2845 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
2846 res = ppc32_exec_memop(cpu,PPC_MEMOP_STB,vaddr,rs);
2847 cpu->gpr[ra] = vaddr;
2848 return(res);
2849 }
2850
2851 /* STBX - Store Byte Indexed */
2852 static fastcall int ppc32_exec_STBX(cpu_ppc_t *cpu,ppc_insn_t insn)
2853 {
2854 int rs = bits(insn,21,25);
2855 int ra = bits(insn,16,20);
2856 int rb = bits(insn,11,15);
2857 m_uint32_t vaddr;
2858
2859 vaddr = cpu->gpr[rb];
2860
2861 if (ra != 0)
2862 vaddr += cpu->gpr[ra];
2863
2864 return(ppc32_exec_memop(cpu,PPC_MEMOP_STB,vaddr,rs));
2865 }
2866
2867 /* STH - Store Half-Word */
2868 static fastcall int ppc32_exec_STH(cpu_ppc_t *cpu,ppc_insn_t insn)
2869 {
2870 int rs = bits(insn,21,25);
2871 int ra = bits(insn,16,20);
2872 m_uint16_t imm = bits(insn,0,15);
2873 m_uint32_t vaddr;
2874
2875 vaddr = sign_extend_32(imm,16);
2876
2877 if (ra != 0)
2878 vaddr += cpu->gpr[ra];
2879
2880 return(ppc32_exec_memop(cpu,PPC_MEMOP_STH,vaddr,rs));
2881 }
2882
2883 /* STHU - Store Half-Word with Update */
2884 static fastcall int ppc32_exec_STHU(cpu_ppc_t *cpu,ppc_insn_t insn)
2885 {
2886 int rs = bits(insn,21,25);
2887 int ra = bits(insn,16,20);
2888 m_uint16_t imm = bits(insn,0,15);
2889 m_uint32_t vaddr;
2890 int res;
2891
2892 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
2893 res = ppc32_exec_memop(cpu,PPC_MEMOP_STH,vaddr,rs);
2894 cpu->gpr[ra] = vaddr;
2895 return(res);
2896 }
2897
2898 /* STHUX - Store Half-Word with Update Indexed */
2899 static fastcall int ppc32_exec_STHUX(cpu_ppc_t *cpu,ppc_insn_t insn)
2900 {
2901 int rs = bits(insn,21,25);
2902 int ra = bits(insn,16,20);
2903 int rb = bits(insn,11,15);
2904 m_uint32_t vaddr;
2905 int res;
2906
2907 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
2908 res = ppc32_exec_memop(cpu,PPC_MEMOP_STH,vaddr,rs);
2909 cpu->gpr[ra] = vaddr;
2910 return(res);
2911 }
2912
2913 /* STHX - Store Half-Word Indexed */
2914 static fastcall int ppc32_exec_STHX(cpu_ppc_t *cpu,ppc_insn_t insn)
2915 {
2916 int rs = bits(insn,21,25);
2917 int ra = bits(insn,16,20);
2918 int rb = bits(insn,11,15);
2919 m_uint32_t vaddr;
2920
2921 vaddr = cpu->gpr[rb];
2922
2923 if (ra != 0)
2924 vaddr += cpu->gpr[ra];
2925
2926 return(ppc32_exec_memop(cpu,PPC_MEMOP_STH,vaddr,rs));
2927 }
2928
2929 /* STMW - Store Multiple Word */
2930 static fastcall int ppc32_exec_STMW(cpu_ppc_t *cpu,ppc_insn_t insn)
2931 {
2932 int rs = bits(insn,21,25);
2933 int ra = bits(insn,16,20);
2934 m_uint16_t imm = bits(insn,0,15);
2935 m_uint32_t vaddr;
2936 int r,res;
2937
2938 vaddr = sign_extend_32(imm,16);
2939
2940 if (ra != 0)
2941 vaddr += cpu->gpr[ra];
2942
2943 for(r=rs;r<=31;r++) {
2944 res = ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,r);
2945 if (res != 0) return(res);
2946
2947 vaddr += sizeof(m_uint32_t);
2948 }
2949
2950 return(0);
2951 }
2952
2953 /* STW - Store Word */
2954 static fastcall int ppc32_exec_STW(cpu_ppc_t *cpu,ppc_insn_t insn)
2955 {
2956 int rs = bits(insn,21,25);
2957 int ra = bits(insn,16,20);
2958 m_uint16_t imm = bits(insn,0,15);
2959 m_uint32_t vaddr;
2960
2961 vaddr = sign_extend_32(imm,16);
2962
2963 if (ra != 0)
2964 vaddr += cpu->gpr[ra];
2965
2966 return(ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs));
2967 }
2968
2969 /* STWU - Store Word with Update */
2970 static fastcall int ppc32_exec_STWU(cpu_ppc_t *cpu,ppc_insn_t insn)
2971 {
2972 int rs = bits(insn,21,25);
2973 int ra = bits(insn,16,20);
2974 m_uint16_t imm = bits(insn,0,15);
2975 m_uint32_t vaddr;
2976 int res;
2977
2978 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
2979 res = ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs);
2980 cpu->gpr[ra] = vaddr;
2981 return(res);
2982 }
2983
2984 /* STWUX - Store Word with Update Indexed */
2985 static fastcall int ppc32_exec_STWUX(cpu_ppc_t *cpu,ppc_insn_t insn)
2986 {
2987 int rs = bits(insn,21,25);
2988 int ra = bits(insn,16,20);
2989 int rb = bits(insn,11,15);
2990 m_uint32_t vaddr;
2991 int res;
2992
2993 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
2994 res = ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs);
2995 cpu->gpr[ra] = vaddr;
2996 return(res);
2997 }
2998
2999 /* STWX - Store Word Indexed */
3000 static fastcall int ppc32_exec_STWX(cpu_ppc_t *cpu,ppc_insn_t insn)
3001 {
3002 int rs = bits(insn,21,25);
3003 int ra = bits(insn,16,20);
3004 int rb = bits(insn,11,15);
3005 m_uint32_t vaddr;
3006
3007 vaddr = cpu->gpr[rb];
3008
3009 if (ra != 0)
3010 vaddr += cpu->gpr[ra];
3011
3012 return(ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs));
3013 }
3014
3015 /* STWBRX - Store Word Byte-Reverse Indexed */
3016 static fastcall int ppc32_exec_STWBRX(cpu_ppc_t *cpu,ppc_insn_t insn)
3017 {
3018 int rs = bits(insn,21,25);
3019 int ra = bits(insn,16,20);
3020 int rb = bits(insn,11,15);
3021 m_uint32_t vaddr;
3022
3023 vaddr = cpu->gpr[rb];
3024
3025 if (ra != 0)
3026 vaddr += cpu->gpr[ra];
3027
3028 return(ppc32_exec_memop(cpu,PPC_MEMOP_STWBR,vaddr,rs));
3029 }
3030
3031 /* STWCX. - Store Word Conditional Indexed */
3032 static fastcall int ppc32_exec_STWCX_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
3033 {
3034 int rs = bits(insn,21,25);
3035 int ra = bits(insn,16,20);
3036 int rb = bits(insn,11,15);
3037 m_uint32_t vaddr;
3038 int res;
3039
3040 vaddr = cpu->gpr[rb];
3041
3042 if (ra != 0)
3043 vaddr += cpu->gpr[ra];
3044
3045 if (cpu->reserve) {
3046 res = ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs);
3047 if (res != 0) return(res);
3048
3049 cpu->cr_fields[0] = 1 << PPC32_CR_EQ_BIT;
3050
3051 if (cpu->xer & PPC32_XER_SO)
3052 cpu->cr_fields[0] |= 1 << PPC32_CR_SO_BIT;
3053
3054 cpu->reserve = 0;
3055 } else {
3056 cpu->cr_fields[0] = 0;
3057
3058 if (cpu->xer & PPC32_XER_SO)
3059 cpu->cr_fields[0] |= 1 << PPC32_CR_SO_BIT;
3060 }
3061
3062 return(0);
3063 }
3064
3065 /* STFD - Store Floating-Point Double */
3066 static fastcall int ppc32_exec_STFD(cpu_ppc_t *cpu,ppc_insn_t insn)
3067 {
3068 int rs = bits(insn,21,25);
3069 int ra = bits(insn,16,20);
3070 m_uint16_t imm = bits(insn,0,15);
3071 m_uint32_t vaddr;
3072
3073 vaddr = sign_extend_32(imm,16);
3074
3075 if (ra != 0)
3076 vaddr += cpu->gpr[ra];
3077
3078 return(ppc32_exec_memop(cpu,PPC_MEMOP_STFD,vaddr,rs));
3079 }
3080
3081 /* STFDU - Store Floating-Point Double with Update */
3082 static fastcall int ppc32_exec_STFDU(cpu_ppc_t *cpu,ppc_insn_t insn)
3083 {
3084 int rs = bits(insn,21,25);
3085 int ra = bits(insn,16,20);
3086 m_uint16_t imm = bits(insn,0,15);
3087 m_uint32_t vaddr;
3088 int res;
3089
3090 vaddr = cpu->gpr[ra] + sign_extend_32(imm,16);
3091 res = ppc32_exec_memop(cpu,PPC_MEMOP_STFD,vaddr,rs);
3092 cpu->gpr[ra] = vaddr;
3093 return(res);
3094 }
3095
3096 /* STFDUX - Store Floating-Point Double with Update Indexed */
3097 static fastcall int ppc32_exec_STFDUX(cpu_ppc_t *cpu,ppc_insn_t insn)
3098 {
3099 int rs = bits(insn,21,25);
3100 int ra = bits(insn,16,20);
3101 int rb = bits(insn,11,15);
3102 m_uint32_t vaddr;
3103 int res;
3104
3105 vaddr = cpu->gpr[ra] + cpu->gpr[rb];
3106 res = ppc32_exec_memop(cpu,PPC_MEMOP_STFD,vaddr,rs);
3107 cpu->gpr[ra] = vaddr;
3108 return(res);
3109 }
3110
3111 /* STFDX - Store Floating-Point Double Indexed */
3112 static fastcall int ppc32_exec_STFDX(cpu_ppc_t *cpu,ppc_insn_t insn)
3113 {
3114 int rs = bits(insn,21,25);
3115 int ra = bits(insn,16,20);
3116 int rb = bits(insn,11,15);
3117 m_uint32_t vaddr;
3118
3119 vaddr = cpu->gpr[rb];
3120
3121 if (ra != 0)
3122 vaddr += cpu->gpr[ra];
3123
3124 return(ppc32_exec_memop(cpu,PPC_MEMOP_STFD,vaddr,rs));
3125 }
3126
3127 /* STSWI - Store String Word Immediate */
3128 static fastcall int ppc32_exec_STSWI(cpu_ppc_t *cpu,ppc_insn_t insn)
3129 {
3130 int rs = bits(insn,21,25);
3131 int ra = bits(insn,16,20);
3132 int nb = bits(insn,11,15);
3133 m_uint32_t vaddr = 0;
3134 int res,r;
3135
3136 if (ra != 0)
3137 vaddr += cpu->gpr[ra];
3138
3139 if (nb == 0)
3140 nb = 32;
3141
3142 r = rs - 1;
3143 cpu->sw_pos = 0;
3144
3145 while(nb > 0) {
3146 if (cpu->sw_pos == 0)
3147 r = (r + 1) & 0x1F;
3148
3149 if (unlikely(res = ppc32_exec_memop(cpu,PPC_MEMOP_STSW,vaddr,r)) != 0)
3150 return(res);
3151
3152 cpu->sw_pos += 8;
3153
3154 if (cpu->sw_pos == 32)
3155 cpu->sw_pos = 0;
3156
3157 vaddr++;
3158 nb--;
3159 }
3160
3161 return(0);
3162 }
3163
3164 /* STSWX - Store String Word Indexed */
3165 static fastcall int ppc32_exec_STSWX(cpu_ppc_t *cpu,ppc_insn_t insn)
3166 {
3167 int rs = bits(insn,21,25);
3168 int ra = bits(insn,16,20);
3169 int rb = bits(insn,11,15);
3170 m_uint32_t vaddr;
3171 int res,r,nb;
3172
3173 vaddr = cpu->gpr[rb];
3174
3175 if (ra != 0)
3176 vaddr += cpu->gpr[ra];
3177
3178 nb = cpu->xer & PPC32_XER_BC_MASK;
3179 r = rs - 1;
3180 cpu->sw_pos = 0;
3181
3182 while(nb > 0) {
3183 if (cpu->sw_pos == 0)
3184 r = (r + 1) & 0x1F;
3185
3186 if (unlikely(res = ppc32_exec_memop(cpu,PPC_MEMOP_STSW,vaddr,r)) != 0)
3187 return(res);
3188
3189 cpu->sw_pos += 8;
3190
3191 if (cpu->sw_pos == 32)
3192 cpu->sw_pos = 0;
3193
3194 vaddr++;
3195 nb--;
3196 }
3197
3198 return(0);
3199 }
3200
3201 /* SUBF - Subtract From */
3202 static fastcall int ppc32_exec_SUBF(cpu_ppc_t *cpu,ppc_insn_t insn)
3203 {
3204 int rd = bits(insn,21,25);
3205 int ra = bits(insn,16,20);
3206 int rb = bits(insn,11,15);
3207
3208 cpu->gpr[rd] = cpu->gpr[rb] - cpu->gpr[ra];
3209 return(0);
3210 }
3211
3212 /* SUBF. */
3213 static fastcall int ppc32_exec_SUBF_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
3214 {
3215 int rd = bits(insn,21,25);
3216 int ra = bits(insn,16,20);
3217 int rb = bits(insn,11,15);
3218 register m_uint32_t tmp;
3219
3220 tmp = cpu->gpr[rb] - cpu->gpr[ra];
3221 ppc32_exec_update_cr0(cpu,tmp);
3222 cpu->gpr[rd] = tmp;
3223 return(0);
3224 }
3225
3226 /* SUBFO - Subtract From with Overflow */
3227 static fastcall int ppc32_exec_SUBFO(cpu_ppc_t *cpu,ppc_insn_t insn)
3228 {
3229 int rd = bits(insn,21,25);
3230 int ra = bits(insn,16,20);
3231 int rb = bits(insn,11,15);
3232 register m_uint32_t a,b,tmp;
3233
3234 a = cpu->gpr[ra];
3235 b = cpu->gpr[rb];
3236
3237 tmp = b - a;
3238 ppc32_exec_ov_sub(cpu,tmp,b,a);
3239 cpu->gpr[rd] = tmp;
3240 return(0);
3241 }
3242
3243 /* SUBFO. */
3244 static fastcall int ppc32_exec_SUBFO_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
3245 {
3246 int rd = bits(insn,21,25);
3247 int ra = bits(insn,16,20);
3248 int rb = bits(insn,11,15);
3249 register m_uint32_t a,b,tmp;
3250
3251 a = cpu->gpr[ra];
3252 b = cpu->gpr[rb];
3253
3254 tmp = b - a;
3255 ppc32_exec_ov_sub(cpu,tmp,b,a);
3256 ppc32_exec_update_cr0(cpu,tmp);
3257 cpu->gpr[rd] = tmp;
3258 return(0);
3259 }
3260
3261 /* SUBFC - Subtract From Carrying */
3262 static fastcall int ppc32_exec_SUBFC(cpu_ppc_t *cpu,ppc_insn_t insn)
3263 {
3264 int rd = bits(insn,21,25);
3265 int ra = bits(insn,16,20);
3266 int rb = bits(insn,11,15);
3267 register m_uint32_t a,b,r,tmp;
3268
3269 a = ~cpu->gpr[ra];
3270 b = cpu->gpr[rb];
3271
3272 tmp = a + 1;
3273 r = b + tmp;
3274
3275 ppc32_exec_ca_sum(cpu,tmp,a,1);
3276 if (r < tmp)
3277 cpu->xer_ca = 1;
3278
3279 cpu->gpr[rd] = r;
3280 return(0);
3281 }
3282
3283 /* SUBFC. */
3284 static fastcall int ppc32_exec_SUBFC_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
3285 {
3286 int rd = bits(insn,21,25);
3287 int ra = bits(insn,16,20);
3288 int rb = bits(insn,11,15);
3289 register m_uint32_t a,b,r,tmp;
3290
3291 a = ~cpu->gpr[ra];
3292 b = cpu->gpr[rb];
3293
3294 tmp = a + 1;
3295 r = b + tmp;
3296
3297 ppc32_exec_ca_sum(cpu,tmp,a,1);
3298 if (r < tmp)
3299 cpu->xer_ca = 1;
3300
3301 ppc32_exec_update_cr0(cpu,r);
3302 cpu->gpr[rd] = r;
3303 return(0);
3304 }
3305
3306 /* SUBFCO - Subtract From with Overflow */
3307 static fastcall int ppc32_exec_SUBFCO(cpu_ppc_t *cpu,ppc_insn_t insn)
3308 {
3309 int rd = bits(insn,21,25);
3310 int ra = bits(insn,16,20);
3311 int rb = bits(insn,11,15);
3312 register m_uint32_t a,b,tmp;
3313
3314 a = cpu->gpr[ra];
3315 b = cpu->gpr[rb];
3316 tmp = b - a;
3317
3318 ppc32_exec_ca_sub(cpu,tmp,b,a);
3319 ppc32_exec_ov_sub(cpu,tmp,b,a);
3320 cpu->gpr[rd] = tmp;
3321 return(0);
3322 }
3323
3324 /* SUBFCO. */
3325 static fastcall int ppc32_exec_SUBFCO_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
3326 {
3327 int rd = bits(insn,21,25);
3328 int ra = bits(insn,16,20);
3329 int rb = bits(insn,11,15);
3330 register m_uint32_t a,b,tmp;
3331
3332 a = cpu->gpr[ra];
3333 b = cpu->gpr[rb];
3334 tmp = b - a;
3335
3336 ppc32_exec_ca_sub(cpu,tmp,b,a);
3337 ppc32_exec_ov_sub(cpu,tmp,b,a);
3338 ppc32_exec_update_cr0(cpu,tmp);
3339 cpu->gpr[rd] = tmp;
3340 return(0);
3341 }
3342
3343 /* SUBFE - Subtract From Carrying */
3344 static fastcall int ppc32_exec_SUBFE(cpu_ppc_t *cpu,ppc_insn_t insn)
3345 {
3346 int rd = bits(insn,21,25);
3347 int ra = bits(insn,16,20);
3348 int rb = bits(insn,11,15);
3349 register m_uint32_t a,b,r,tmp;
3350 m_uint32_t carry;
3351
3352 carry = cpu->xer_ca;
3353
3354 a = ~cpu->gpr[ra];
3355 b = cpu->gpr[rb];
3356 tmp = a + carry;
3357 r = b + tmp;
3358
3359 ppc32_exec_ca_sum(cpu,tmp,a,carry);
3360 if (r < tmp)
3361 cpu->xer_ca = 1;
3362
3363 cpu->gpr[rd] = r;
3364 return(0);
3365 }
3366
3367 /* SUBFIC - Subtract From Immediate Carrying */
3368 static fastcall int ppc32_exec_SUBFIC(cpu_ppc_t *cpu,ppc_insn_t insn)
3369 {
3370 int rd = bits(insn,21,25);
3371 int ra = bits(insn,16,20);
3372 m_uint16_t imm = bits(insn,0,15);
3373 register m_uint32_t a,b,r,tmp;
3374
3375 a = ~cpu->gpr[ra];
3376 b = sign_extend_32(imm,16);
3377
3378 tmp = a + 1;
3379 r = b + tmp;
3380
3381 ppc32_exec_ca_sum(cpu,tmp,a,1);
3382 if (r < tmp)
3383 cpu->xer_ca = 1;
3384
3385 cpu->gpr[rd] = r;
3386 return(0);
3387 }
3388
3389 /* SUBFZE - Subtract From Zero extended */
3390 static fastcall int ppc32_exec_SUBFZE(cpu_ppc_t *cpu,ppc_insn_t insn)
3391 {
3392 int rd = bits(insn,21,25);
3393 int ra = bits(insn,16,20);
3394 register m_uint32_t a,r;
3395 m_uint32_t carry;
3396
3397 carry = cpu->xer_ca;
3398
3399 a = ~cpu->gpr[ra];
3400 r = a + carry;
3401
3402 if (r < a)
3403 cpu->xer_ca = 1;
3404
3405 cpu->gpr[rd] = r;
3406 return(0);
3407 }
3408
3409 /* SUBFZE. */
3410 static fastcall int ppc32_exec_SUBFZE_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
3411 {
3412 int rd = bits(insn,21,25);
3413 int ra = bits(insn,16,20);
3414 register m_uint32_t a,r;
3415 m_uint32_t carry;
3416
3417 carry = cpu->xer_ca;
3418
3419 a = ~cpu->gpr[ra];
3420 r = a + carry;
3421
3422 if (r < a)
3423 cpu->xer_ca = 1;
3424
3425 ppc32_exec_update_cr0(cpu,r);
3426 cpu->gpr[rd] = r;
3427 return(0);
3428 }
3429
3430 /* SYNC - Synchronize */
3431 static fastcall int ppc32_exec_SYNC(cpu_ppc_t *cpu,ppc_insn_t insn)
3432 {
3433 return(0);
3434 }
3435
3436 /* TLBIA - TLB Invalidate All */
3437 static fastcall int ppc32_exec_TLBIA(cpu_ppc_t *cpu,ppc_insn_t insn)
3438 {
3439 ppc32_mem_invalidate_cache(cpu);
3440 return(0);
3441 }
3442
3443 /* TLBIE - TLB Invalidate Entry */
3444 static fastcall int ppc32_exec_TLBIE(cpu_ppc_t *cpu,ppc_insn_t insn)
3445 {
3446 ppc32_mem_invalidate_cache(cpu);
3447 return(0);
3448 }
3449
3450 /* TLBSYNC - TLB Synchronize */
3451 static fastcall int ppc32_exec_TLBSYNC(cpu_ppc_t *cpu,ppc_insn_t insn)
3452 {
3453 return(0);
3454 }
3455
3456 /* TW - Trap Word */
3457 static fastcall int ppc32_exec_TW(cpu_ppc_t *cpu,ppc_insn_t insn)
3458 {
3459 int to = bits(insn,21,25);
3460 int ra = bits(insn,16,20);
3461 int rb = bits(insn,11,15);
3462 m_int32_t a,b;
3463
3464 a = cpu->gpr[ra];
3465 b = cpu->gpr[rb];
3466
3467 if (((a < b) && (to & 0x10)) ||
3468 ((a > b) && (to & 0x08)) ||
3469 ((a == b) && (to & 0x04)) ||
3470 (((m_uint32_t)a < (m_uint32_t)b) && (to & 0x02)) ||
3471 (((m_uint32_t)a > (m_uint32_t)b) && (to & 0x01)))
3472 {
3473 ppc32_trigger_exception(cpu,PPC32_EXC_PROG);
3474 cpu->srr1 |= 1 << 17;
3475 return(1);
3476 }
3477
3478 return(0);
3479 }
3480
3481 /* TWI - Trap Word Immediate */
3482 static fastcall int ppc32_exec_TWI(cpu_ppc_t *cpu,ppc_insn_t insn)
3483 {
3484 int to = bits(insn,21,25);
3485 int ra = bits(insn,16,20);
3486 m_uint16_t imm = bits(insn,0,15);
3487 m_int32_t a,b;
3488
3489 a = cpu->gpr[ra];
3490 b = sign_extend(imm,16);
3491
3492 if (((a < b) && (to & 0x10)) ||
3493 ((a > b) && (to & 0x08)) ||
3494 ((a == b) && (to & 0x04)) ||
3495 (((m_uint32_t)a < (m_uint32_t)b) && (to & 0x02)) ||
3496 (((m_uint32_t)a > (m_uint32_t)b) && (to & 0x01)))
3497 {
3498 ppc32_trigger_exception(cpu,PPC32_EXC_PROG);
3499 cpu->srr1 |= 1 << 17;
3500 return(1);
3501 }
3502
3503 return(0);
3504 }
3505
3506 /* XOR */
3507 static fastcall int ppc32_exec_XOR(cpu_ppc_t *cpu,ppc_insn_t insn)
3508 {
3509 int rs = bits(insn,21,25);
3510 int ra = bits(insn,16,20);
3511 int rb = bits(insn,11,15);
3512
3513 cpu->gpr[ra] = cpu->gpr[rs] ^ cpu->gpr[rb];
3514 return(0);
3515 }
3516
3517 /* XOR. */
3518 static fastcall int ppc32_exec_XOR_dot(cpu_ppc_t *cpu,ppc_insn_t insn)
3519 {
3520 int rs = bits(insn,21,25);
3521 int ra = bits(insn,16,20);
3522 int rb = bits(insn,11,15);
3523 m_uint32_t tmp;
3524
3525 tmp = cpu->gpr[rs] ^ cpu->gpr[rb];
3526 ppc32_exec_update_cr0(cpu,tmp);
3527 cpu->gpr[ra] = tmp;
3528 return(0);
3529 }
3530
3531 /* XORI - XOR Immediate */
3532 static fastcall int ppc32_exec_XORI(cpu_ppc_t *cpu,ppc_insn_t insn)
3533 {
3534 int rs = bits(insn,21,25);
3535 int ra = bits(insn,16,20);
3536 m_uint16_t imm = bits(insn,0,15);
3537
3538 cpu->gpr[ra] = cpu->gpr[rs] ^ imm;
3539 return(0);
3540 }
3541
3542 /* XORIS - XOR Immediate Shifted */
3543 static fastcall int ppc32_exec_XORIS(cpu_ppc_t *cpu,ppc_insn_t insn)
3544 {
3545 int rs = bits(insn,21,25);
3546 int ra = bits(insn,16,20);
3547 m_uint32_t imm = bits(insn,0,15);
3548
3549 cpu->gpr[ra] = cpu->gpr[rs] ^ (imm << 16);
3550 return(0);
3551 }
3552
3553 /* DCCCI - Data Cache Congruence Class Invalidate (PowerPC 405) */
3554 static fastcall int ppc32_exec_DCCCI(cpu_ppc_t *cpu,ppc_insn_t insn)
3555 {
3556 int ra = bits(insn,16,20);
3557 int rb = bits(insn,11,15);
3558 m_uint32_t vaddr;
3559
3560 vaddr = cpu->gpr[rb];
3561
3562 if (ra != 0)
3563 vaddr += cpu->gpr[ra];
3564
3565 return(0);
3566 }
3567
3568 /* ICCCI - Instruction Cache Congruence Class Invalidate (PowerPC 405) */
3569 static fastcall int ppc32_exec_ICCCI(cpu_ppc_t *cpu,ppc_insn_t insn)
3570 {
3571 int ra = bits(insn,16,20);
3572 int rb = bits(insn,11,15);
3573 m_uint32_t vaddr;
3574
3575 vaddr = cpu->gpr[rb];
3576
3577 if (ra != 0)
3578 vaddr += cpu->gpr[ra];
3579
3580 return(0);
3581 }
3582
3583 /* MFDCR - Move From Device Control Register (PowerPC 405) */
3584 static fastcall int ppc32_exec_MFDCR(cpu_ppc_t *cpu,ppc_insn_t insn)
3585 {
3586 int rt = bits(insn,21,25);
3587 return(0);
3588 }
3589
3590 /* MTDCR - Move To Device Control Register (PowerPC 405) */
3591 static fastcall int ppc32_exec_MTDCR(cpu_ppc_t *cpu,ppc_insn_t insn)
3592 {
3593 int rt = bits(insn,21,25);
3594 return(0);
3595 }
3596
3597 /* TLBRE - TLB Read Entry (PowerPC 405) */
3598 static fastcall int ppc32_exec_TLBRE(cpu_ppc_t *cpu,ppc_insn_t insn)
3599 {
3600 int rt = bits(insn,21,25);
3601 int ra = bits(insn,16,20);
3602 int ws = bits(insn,11,15);
3603 m_uint32_t index;
3604
3605 index = cpu->gpr[ra] & 0x3F;
3606
3607 if (ws == 1) {
3608 cpu->gpr[rt] = cpu->ppc405_tlb[index].tlb_lo;
3609 } else {
3610 cpu->gpr[rt] = cpu->ppc405_tlb[index].tlb_hi;
3611 cpu->ppc405_pid = cpu->ppc405_tlb[index].tid;
3612 }
3613
3614 return(0);
3615 }
3616
3617 /* TLBWE - TLB Write Entry (PowerPC 405) */
3618 static fastcall int ppc32_exec_TLBWE(cpu_ppc_t *cpu,ppc_insn_t insn)
3619 {
3620 int rs = bits(insn,21,25);
3621 int ra = bits(insn,16,20);
3622 int ws = bits(insn,11,15);
3623 m_uint32_t index;
3624
3625 index = cpu->gpr[ra] & 0x3F;
3626
3627 if (ws == 1) {
3628 cpu->ppc405_tlb[index].tlb_lo = cpu->gpr[rs];
3629 } else {
3630 cpu->ppc405_tlb[index].tlb_hi = cpu->gpr[rs];
3631 cpu->ppc405_tlb[index].tid = cpu->ppc405_pid;
3632 }
3633
3634 return(0);
3635 }
3636
3637 /* PowerPC instruction array */
3638 static struct ppc32_insn_exec_tag ppc32_exec_tags[] = {
3639 { "mflr" , ppc32_exec_MFLR , 0xfc1fffff , 0x7c0802a6, 0 },
3640 { "mtlr" , ppc32_exec_MTLR , 0xfc1fffff , 0x7c0803a6, 0 },
3641 { "mfctr" , ppc32_exec_MFCTR , 0xfc1fffff , 0x7c0902a6, 0 },
3642 { "mtctr" , ppc32_exec_MTCTR , 0xfc1fffff , 0x7c0903a6, 0 },
3643 { "add" , ppc32_exec_ADD , 0xfc0007ff , 0x7c000214, 0 },
3644 { "add." , ppc32_exec_ADD_dot , 0xfc0007ff , 0x7c000215, 0 },
3645 { "addo" , ppc32_exec_ADDO , 0xfc0007ff , 0x7c000614, 0 },
3646 { "addo." , ppc32_exec_ADDO_dot , 0xfc0007ff , 0x7c000615, 0 },
3647 { "addc" , ppc32_exec_ADDC , 0xfc0007ff , 0x7c000014, 0 },
3648 { "addc." , ppc32_exec_ADDC_dot , 0xfc0007ff , 0x7c000015, 0 },
3649 { "addco" , ppc32_exec_ADDCO , 0xfc0007ff , 0x7c000414, 0 },
3650 { "addco." , ppc32_exec_ADDCO_dot , 0xfc0007ff , 0x7c000415, 0 },
3651 { "adde" , ppc32_exec_ADDE , 0xfc0007ff , 0x7c000114, 0 },
3652 { "adde." , ppc32_exec_ADDE_dot , 0xfc0007ff , 0x7c000115, 0 },
3653 { "addeo" , ppc32_exec_ADDEO , 0xfc0007ff , 0x7c000514, 0 },
3654 { "addeo." , ppc32_exec_ADDEO_dot , 0xfc0007ff , 0x7c000515, 0 },
3655 { "addi" , ppc32_exec_ADDI , 0xfc000000 , 0x38000000, 0 },
3656 { "addic" , ppc32_exec_ADDIC , 0xfc000000 , 0x30000000, 0 },
3657 { "addic." , ppc32_exec_ADDIC_dot , 0xfc000000 , 0x34000000, 0 },
3658 { "addis" , ppc32_exec_ADDIS , 0xfc000000 , 0x3c000000, 0 },
3659 { "addme" , ppc32_exec_ADDME , 0xfc00ffff , 0x7c0001d4, 0 },
3660 { "addme." , ppc32_exec_ADDME_dot , 0xfc00ffff , 0x7c0001d5, 0 },
3661 { "addze" , ppc32_exec_ADDZE , 0xfc00ffff , 0x7c000194, 0 },
3662 { "addze." , ppc32_exec_ADDZE_dot , 0xfc00ffff , 0x7c000195, 0 },
3663 { "and" , ppc32_exec_AND , 0xfc0007ff , 0x7c000038, 0 },
3664 { "and." , ppc32_exec_AND_dot , 0xfc0007ff , 0x7c000039, 0 },
3665 { "andc" , ppc32_exec_ANDC , 0xfc0007ff , 0x7c000078, 0 },
3666 { "andc." , ppc32_exec_ANDC_dot , 0xfc0007ff , 0x7c000079, 0 },
3667 { "andi." , ppc32_exec_ANDI_dot , 0xfc000000 , 0x70000000, 0 },
3668 { "andis." , ppc32_exec_ANDIS_dot , 0xfc000000 , 0x74000000, 0 },
3669 { "b" , ppc32_exec_B , 0xfc000003 , 0x48000000, 0 },
3670 { "ba" , ppc32_exec_BA , 0xfc000003 , 0x48000002, 0 },
3671 { "bl" , ppc32_exec_BL , 0xfc000003 , 0x48000001, 0 },
3672 { "bla" , ppc32_exec_BLA , 0xfc000003 , 0x48000003, 0 },
3673 { "bc" , ppc32_exec_BC , 0xfc000003 , 0x40000000, 0 },
3674 { "bca" , ppc32_exec_BCA , 0xfc000003 , 0x40000002, 0 },
3675 { "bcl" , ppc32_exec_BCL , 0xfc000003 , 0x40000001, 0 },
3676 { "bcla" , ppc32_exec_BCLA , 0xfc000003 , 0x40000003, 0 },
3677 { "bclr" , ppc32_exec_BCLR , 0xfc00ffff , 0x4c000020, 0 },
3678 { "bclrl" , ppc32_exec_BCLRL , 0xfc00ffff , 0x4c000021, 0 },
3679 { "bcctr" , ppc32_exec_BCCTR , 0xfc00ffff , 0x4c000420, 0 },
3680 { "bcctrl" , ppc32_exec_BCCTRL , 0xfc00ffff , 0x4c000421, 0 },
3681 { "cmp" , ppc32_exec_CMP , 0xfc6007ff , 0x7c000000, 0 },
3682 { "cmpi" , ppc32_exec_CMPI , 0xfc600000 , 0x2c000000, 0 },
3683 { "cmpl" , ppc32_exec_CMPL , 0xfc6007ff , 0x7c000040, 0 },
3684 { "cmpli" , ppc32_exec_CMPLI , 0xfc600000 , 0x28000000, 0 },
3685 { "cntlzw" , ppc32_exec_CNTLZW , 0xfc00ffff , 0x7c000034, 0 },
3686 { "crand" , ppc32_exec_CRAND , 0xfc0007ff , 0x4c000202, 0 },
3687 { "crandc" , ppc32_exec_CRANDC , 0xfc0007ff , 0x4c000102, 0 },
3688 { "creqv" , ppc32_exec_CREQV , 0xfc0007ff , 0x4c000242, 0 },
3689 { "crnand" , ppc32_exec_CRNAND , 0xfc0007ff , 0x4c0001c2, 0 },
3690 { "crnor" , ppc32_exec_CRNOR , 0xfc0007ff , 0x4c000042, 0 },
3691 { "cror" , ppc32_exec_CROR , 0xfc0007ff , 0x4c000382, 0 },
3692 { "crorc" , ppc32_exec_CRORC , 0xfc0007ff , 0x4c000342, 0 },
3693 { "crxor" , ppc32_exec_CRXOR , 0xfc0007ff , 0x4c000182, 0 },
3694 { "dcbf" , ppc32_exec_DCBF , 0xffe007ff , 0x7c0000ac, 0 },
3695 { "dcbi" , ppc32_exec_DCBI , 0xffe007ff , 0x7c0003ac, 0 },
3696 { "dcbt" , ppc32_exec_DCBT , 0xffe007ff , 0x7c00022c, 0 },
3697 { "dcbst" , ppc32_exec_DCBST , 0xffe007ff , 0x7c00006c, 0 },
3698 { "divw" , ppc32_exec_DIVW , 0xfc0007ff , 0x7c0003d6, 0 },
3699 { "divw." , ppc32_exec_DIVW_dot , 0xfc0007ff , 0x7c0003d7, 0 },
3700 { "divwu" , ppc32_exec_DIVWU , 0xfc0007ff , 0x7c000396, 0 },
3701 { "divwu." , ppc32_exec_DIVWU_dot , 0xfc0007ff , 0x7c000397, 0 },
3702 { "eieio" , ppc32_exec_EIEIO , 0xffffffff , 0x7c0006ac, 0 },
3703 { "eqv" , ppc32_exec_EQV , 0xfc0007ff , 0x7c000238, 0 },
3704 { "extsb" , ppc32_exec_EXTSB , 0xfc00ffff , 0x7c000774, 0 },
3705 { "extsb." , ppc32_exec_EXTSB_dot , 0xfc00ffff , 0x7c000775, 0 },
3706 { "extsh" , ppc32_exec_EXTSH , 0xfc00ffff , 0x7c000734, 0 },
3707 { "extsh." , ppc32_exec_EXTSH_dot , 0xfc00ffff , 0x7c000735, 0 },
3708 { "icbi" , ppc32_exec_ICBI , 0xffe007ff , 0x7c0007ac, 0 },
3709 { "isync" , ppc32_exec_ISYNC , 0xffffffff , 0x4c00012c, 0 },
3710 { "lbz" , ppc32_exec_LBZ , 0xfc000000 , 0x88000000, 0 },
3711 { "lbzu" , ppc32_exec_LBZU , 0xfc000000 , 0x8c000000, 0 },
3712 { "lbzux" , ppc32_exec_LBZUX , 0xfc0007ff , 0x7c0000ee, 0 },
3713 { "lbzx" , ppc32_exec_LBZX , 0xfc0007ff , 0x7c0000ae, 0 },
3714 { "lha" , ppc32_exec_LHA , 0xfc000000 , 0xa8000000, 0 },
3715 { "lhau" , ppc32_exec_LHAU , 0xfc000000 , 0xac000000, 0 },
3716 { "lhaux" , ppc32_exec_LHAUX , 0xfc0007ff , 0x7c0002ee, 0 },
3717 { "lhax" , ppc32_exec_LHAX , 0xfc0007ff , 0x7c0002ae, 0 },
3718 { "lhz" , ppc32_exec_LHZ , 0xfc000000 , 0xa0000000, 0 },
3719 { "lhzu" , ppc32_exec_LHZU , 0xfc000000 , 0xa4000000, 0 },
3720 { "lhzux" , ppc32_exec_LHZUX , 0xfc0007ff , 0x7c00026e, 0 },
3721 { "lhzx" , ppc32_exec_LHZX , 0xfc0007ff , 0x7c00022e, 0 },
3722 { "lmw" , ppc32_exec_LMW , 0xfc000000 , 0xb8000000, 0 },
3723 { "lwbrx" , ppc32_exec_LWBRX , 0xfc0007ff , 0x7c00042c, 0 },
3724 { "lwz" , ppc32_exec_LWZ , 0xfc000000 , 0x80000000, 0 },
3725 { "lwzu" , ppc32_exec_LWZU , 0xfc000000 , 0x84000000, 0 },
3726 { "lwzux" , ppc32_exec_LWZUX , 0xfc0007ff , 0x7c00006e, 0 },
3727 { "lwzx" , ppc32_exec_LWZX , 0xfc0007ff , 0x7c00002e, 0 },
3728 { "lwarx" , ppc32_exec_LWARX , 0xfc0007ff , 0x7c000028, 0 },
3729 { "lfd" , ppc32_exec_LFD , 0xfc000000 , 0xc8000000, 0 },
3730 { "lfdu" , ppc32_exec_LFDU , 0xfc000000 , 0xcc000000, 0 },
3731 { "lfdux" , ppc32_exec_LFDUX , 0xfc0007ff , 0x7c0004ee, 0 },
3732 { "lfdx" , ppc32_exec_LFDX , 0xfc0007ff , 0x7c0004ae, 0 },
3733 { "lswi" , ppc32_exec_LSWI , 0xfc0007ff , 0x7c0004aa, 0 },
3734 { "lswx" , ppc32_exec_LSWX , 0xfc0007ff , 0x7c00042a, 0 },
3735 { "mcrf" , ppc32_exec_MCRF , 0xfc63ffff , 0x4c000000, 0 },
3736 { "mfcr" , ppc32_exec_MFCR , 0xfc1fffff , 0x7c000026, 0 },
3737 { "mfmsr" , ppc32_exec_MFMSR , 0xfc1fffff , 0x7c0000a6, 0 },
3738 { "mfspr" , ppc32_exec_MFSPR , 0xfc0007ff , 0x7c0002a6, 0 },
3739 { "mfsr" , ppc32_exec_MFSR , 0xfc10ffff , 0x7c0004a6, 0 },
3740 { "mfsrin" , ppc32_exec_MFSRIN , 0xfc1f07ff , 0x7c000526, 0 },
3741 { "mftbl" , ppc32_exec_MFTBL , 0xfc1ff7ff , 0x7c0c42e6, 0 },
3742 { "mftbu" , ppc32_exec_MFTBU , 0xfc1ff7ff , 0x7c0d42e6, 0 },
3743 { "mtcrf" , ppc32_exec_MTCRF , 0xfc100fff , 0x7c000120, 0 },
3744 { "mtmsr" , ppc32_exec_MTMSR , 0xfc1fffff , 0x7c000124, 0 },
3745 { "mtspr" , ppc32_exec_MTSPR , 0xfc0007ff , 0x7c0003a6, 0 },
3746 { "mtsr" , ppc32_exec_MTSR , 0xfc10ffff , 0x7c0001a4, 0 },
3747 { "mulhw" , ppc32_exec_MULHW , 0xfc0007ff , 0x7c000096, 0 },
3748 { "mulhw." , ppc32_exec_MULHW_dot , 0xfc0007ff , 0x7c000097, 0 },
3749 { "mulhwu" , ppc32_exec_MULHWU , 0xfc0007ff , 0x7c000016, 0 },
3750 { "mulhwu." , ppc32_exec_MULHWU_dot , 0xfc0007ff , 0x7c000017, 0 },
3751 { "mulli" , ppc32_exec_MULLI , 0xfc000000 , 0x1c000000, 0 },
3752 { "mullw" , ppc32_exec_MULLW , 0xfc0007ff , 0x7c0001d6, 0 },
3753 { "mullw." , ppc32_exec_MULLW_dot , 0xfc0007ff , 0x7c0001d7, 0 },
3754 { "mullwo" , ppc32_exec_MULLWO , 0xfc0007ff , 0x7c0005d6, 0 },
3755 { "mullwo." , ppc32_exec_MULLWO_dot , 0xfc0007ff , 0x7c0005d7, 0 },
3756 { "nand" , ppc32_exec_NAND , 0xfc0007ff , 0x7c0003b8, 0 },
3757 { "nand." , ppc32_exec_NAND_dot , 0xfc0007ff , 0x7c0003b9, 0 },
3758 { "neg" , ppc32_exec_NEG , 0xfc00ffff , 0x7c0000d0, 0 },
3759 { "neg." , ppc32_exec_NEG_dot , 0xfc00ffff , 0x7c0000d1, 0 },
3760 { "nego" , ppc32_exec_NEGO , 0xfc00ffff , 0x7c0004d0, 0 },
3761 { "nego." , ppc32_exec_NEGO_dot , 0xfc00ffff , 0x7c0004d1, 0 },
3762 { "nor" , ppc32_exec_NOR , 0xfc0007ff , 0x7c0000f8, 0 },
3763 { "nor." , ppc32_exec_NOR_dot , 0xfc0007ff , 0x7c0000f9, 0 },
3764 { "or" , ppc32_exec_OR , 0xfc0007ff , 0x7c000378, 0 },
3765 { "or." , ppc32_exec_OR_dot , 0xfc0007ff , 0x7c000379, 0 },
3766 { "orc" , ppc32_exec_ORC , 0xfc0007ff , 0x7c000338, 0 },
3767 { "orc." , ppc32_exec_ORC_dot , 0xfc0007ff , 0x7c000339, 0 },
3768 { "ori" , ppc32_exec_ORI , 0xfc000000 , 0x60000000, 0 },
3769 { "oris" , ppc32_exec_ORIS , 0xfc000000 , 0x64000000, 0 },
3770 { "rfi" , ppc32_exec_RFI , 0xffffffff , 0x4c000064, 0 },
3771 { "rlwimi" , ppc32_exec_RLWIMI , 0xfc000001 , 0x50000000, 0 },
3772 { "rlwimi." , ppc32_exec_RLWIMI_dot , 0xfc000001 , 0x50000001, 0 },
3773 { "rlwinm" , ppc32_exec_RLWINM , 0xfc000001 , 0x54000000, 0 },
3774 { "rlwinm." , ppc32_exec_RLWINM_dot , 0xfc000001 , 0x54000001, 0 },
3775 { "rlwnm" , ppc32_exec_RLWNM , 0xfc000001 , 0x5c000000, 0 },
3776 { "rlwnm." , ppc32_exec_RLWNM_dot , 0xfc000001 , 0x5c000001, 0 },
3777 { "sc" , ppc32_exec_SC , 0xffffffff , 0x44000002, 0 },
3778 { "slw" , ppc32_exec_SLW , 0xfc0007ff , 0x7c000030, 0 },
3779 { "slw." , ppc32_exec_SLW_dot , 0xfc0007ff , 0x7c000031, 0 },
3780 { "sraw" , ppc32_exec_SRAW , 0xfc0007ff , 0x7c000630, 0 },
3781 { "srawi" , ppc32_exec_SRAWI , 0xfc0007ff , 0x7c000670, 0 },
3782 { "srawi." , ppc32_exec_SRAWI_dot , 0xfc0007ff , 0x7c000671, 0 },
3783 { "srw" , ppc32_exec_SRW , 0xfc0007ff , 0x7c000430, 0 },
3784 { "srw." , ppc32_exec_SRW_dot , 0xfc0007ff , 0x7c000431, 0 },
3785 { "stb" , ppc32_exec_STB , 0xfc000000 , 0x98000000, 0 },
3786 { "stbu" , ppc32_exec_STBU , 0xfc000000 , 0x9c000000, 0 },
3787 { "stbux" , ppc32_exec_STBUX , 0xfc0007ff , 0x7c0001ee, 0 },
3788 { "stbx" , ppc32_exec_STBX , 0xfc0007ff , 0x7c0001ae, 0 },
3789 { "sth" , ppc32_exec_STH , 0xfc000000 , 0xb0000000, 0 },
3790 { "sthu" , ppc32_exec_STHU , 0xfc000000 , 0xb4000000, 0 },
3791 { "sthux" , ppc32_exec_STHUX , 0xfc0007ff , 0x7c00036e, 0 },
3792 { "sthx" , ppc32_exec_STHX , 0xfc0007ff , 0x7c00032e, 0 },
3793 { "stmw" , ppc32_exec_STMW , 0xfc000000 , 0xbc000000, 0 },
3794 { "stw" , ppc32_exec_STW , 0xfc000000 , 0x90000000, 0 },
3795 { "stwu" , ppc32_exec_STWU , 0xfc000000 , 0x94000000, 0 },
3796 { "stwux" , ppc32_exec_STWUX , 0xfc0007ff , 0x7c00016e, 0 },
3797 { "stwx" , ppc32_exec_STWX , 0xfc0007ff , 0x7c00012e, 0 },
3798 { "stwbrx" , ppc32_exec_STWBRX , 0xfc0007ff , 0x7c00052c, 0 },
3799 { "stwcx." , ppc32_exec_STWCX_dot , 0xfc0007ff , 0x7c00012d, 0 },
3800 { "stfd" , ppc32_exec_STFD , 0xfc000000 , 0xd8000000, 0 },
3801 { "stfdu" , ppc32_exec_STFDU , 0xfc000000 , 0xdc000000, 0 },
3802 { "stfdux" , ppc32_exec_STFDUX , 0xfc0007ff , 0x7c0005ee, 0 },
3803 { "stfdx" , ppc32_exec_STFDX , 0xfc0007ff , 0x7c0005ae, 0 },
3804 { "stswi" , ppc32_exec_STSWI , 0xfc0007ff , 0x7c0005aa, 0 },
3805 { "stswx" , ppc32_exec_STSWX , 0xfc0007ff , 0x7c00052a, 0 },
3806 { "subf" , ppc32_exec_SUBF , 0xfc0007ff , 0x7c000050, 0 },
3807 { "subf." , ppc32_exec_SUBF_dot , 0xfc0007ff , 0x7c000051, 0 },
3808 { "subfo" , ppc32_exec_SUBFO , 0xfc0007ff , 0x7c000450, 0 },
3809 { "subfo." , ppc32_exec_SUBFO_dot , 0xfc0007ff , 0x7c000451, 0 },
3810 { "subfc" , ppc32_exec_SUBFC , 0xfc0007ff , 0x7c000010, 0 },
3811 { "subfc." , ppc32_exec_SUBFC_dot , 0xfc0007ff , 0x7c000011, 0 },
3812 //{ "subfco" , ppc32_exec_SUBFCO , 0xfc0007ff , 0x7c000410, 0 },
3813 //{ "subfco." , ppc32_exec_SUBFCO_dot , 0xfc0007ff , 0x7c000411, 0 },
3814 { "subfe" , ppc32_exec_SUBFE , 0xfc0007ff , 0x7c000110, 0 },
3815 { "subfic" , ppc32_exec_SUBFIC , 0xfc000000 , 0x20000000, 0 },
3816 { "subfze" , ppc32_exec_SUBFZE , 0xfc00ffff , 0x7c000190, 0 },
3817 { "subfze." , ppc32_exec_SUBFZE_dot , 0xfc00ffff , 0x7c000191, 0 },
3818 { "sync" , ppc32_exec_SYNC , 0xffffffff , 0x7c0004ac, 0 },
3819 { "tlbia" , ppc32_exec_TLBIA , 0xffffffff , 0x7c0002e4, 0 },
3820 { "tlbie" , ppc32_exec_TLBIE , 0xffff07ff , 0x7c000264, 0 },
3821 { "tlbsync" , ppc32_exec_TLBSYNC , 0xffffffff , 0x7c00046c, 0 },
3822 { "tw" , ppc32_exec_TW , 0xfc0007ff , 0x7c000008, 0 },
3823 { "twi" , ppc32_exec_TWI , 0xfc000000 , 0x0c000000, 0 },
3824 { "xor" , ppc32_exec_XOR , 0xfc0007ff , 0x7c000278, 0 },
3825 { "xor." , ppc32_exec_XOR_dot , 0xfc0007ff , 0x7c000279, 0 },
3826 { "xori" , ppc32_exec_XORI , 0xfc000000 , 0x68000000, 0 },
3827 { "xoris" , ppc32_exec_XORIS , 0xfc000000 , 0x6c000000, 0 },
3828
3829 /* PowerPC 405 specific instructions */
3830 { "dccci" , ppc32_exec_DCCCI , 0xfc0007ff , 0x7c00038c, 0 },
3831 { "iccci" , ppc32_exec_ICCCI , 0xfc0007ff , 0x7c00078c, 0 },
3832 { "mfdcr" , ppc32_exec_MFDCR , 0xfc0007ff , 0x7c000286, 0 },
3833 { "mtdcr" , ppc32_exec_MTDCR , 0xfc0007ff , 0x7c000386, 0 },
3834 { "tlbre" , ppc32_exec_TLBRE , 0xfc0007ff , 0x7c000764, 0 },
3835 { "tlbwe" , ppc32_exec_TLBWE , 0xfc0007ff , 0x7c0007a4, 0 },
3836
3837 /* Unknown opcode fallback */
3838 { "unknown" , ppc32_exec_unknown , 0x00000000 , 0x00000000, 0 },
3839
3840 { NULL , NULL, 0, 0, 0 },
3841 };

  ViewVC Help
Powered by ViewVC 1.1.26