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

Annotation of /trunk/ppc32_exec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/ppc32_exec.c
File MIME type: text/plain
File size: 96036 byte(s)
dynamips-0.2.7-RC1

1 dpavlin 7 /*
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