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

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

  ViewVC Help
Powered by ViewVC 1.1.26