/[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 12 - (hide annotations)
Sat Oct 6 16:45:40 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 95841 byte(s)
make working copy

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

  ViewVC Help
Powered by ViewVC 1.1.26