/[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 10 - (hide annotations)
Sat Oct 6 16:29:14 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7/ppc32_exec.c
File MIME type: text/plain
File size: 96387 byte(s)
dynamips-0.2.7

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

  ViewVC Help
Powered by ViewVC 1.1.26