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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 96036 byte(s)
dynamips-0.2.7-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26