/[dynamips]/upstream/dynamips-0.2.7/ppc32_exec.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.7/ppc32_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (show annotations)
Sat Oct 6 16:29:14 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 96387 byte(s)
dynamips-0.2.7

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

  ViewVC Help
Powered by ViewVC 1.1.26