/[dynamips]/trunk/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 /trunk/ppc32_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 95841 byte(s)
make working copy

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

  ViewVC Help
Powered by ViewVC 1.1.26