/[gxemul]/upstream/0.3.3.2/src/cpu_ppc.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 /upstream/0.3.3.2/src/cpu_ppc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Mon Oct 8 16:18:22 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 69460 byte(s)
0.3.3.2
1 dpavlin 2 /*
2     * Copyright (C) 2005 Anders Gavare. All rights reserved.
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 4 * $Id: cpu_ppc.c,v 1.62 2005/04/18 23:00:56 debug Exp $
29 dpavlin 2 *
30     * PowerPC/POWER CPU emulation.
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35     #include <string.h>
36     #include <ctype.h>
37    
38     #include "misc.h"
39    
40    
41     #ifndef ENABLE_PPC
42    
43    
44     #include "cpu_ppc.h"
45    
46    
47     /*
48     * ppc_cpu_family_init():
49     *
50     * Bogus function.
51     */
52     int ppc_cpu_family_init(struct cpu_family *fp)
53     {
54     return 0;
55     }
56    
57    
58     #else /* ENABLE_PPC */
59    
60    
61     #include "cpu.h"
62     #include "cpu_ppc.h"
63     #include "machine.h"
64     #include "memory.h"
65     #include "opcodes_ppc.h"
66     #include "symbol.h"
67    
68    
69     extern volatile int single_step;
70     extern int old_show_trace_tree;
71     extern int old_instruction_trace;
72     extern int old_quiet_mode;
73     extern int quiet_mode;
74    
75    
76     /*
77     * ppc_cpu_new():
78     *
79     * Create a new PPC cpu object.
80     */
81     struct cpu *ppc_cpu_new(struct memory *mem, struct machine *machine,
82     int cpu_id, char *cpu_type_name)
83     {
84     struct cpu *cpu;
85     int any_cache = 0;
86     int i, found;
87     struct ppc_cpu_type_def cpu_type_defs[] = PPC_CPU_TYPE_DEFS;
88    
89     /* Scan the cpu_type_defs list for this cpu type: */
90     i = 0;
91     found = -1;
92     while (i >= 0 && cpu_type_defs[i].name != NULL) {
93     if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
94     found = i;
95     break;
96     }
97     i++;
98     }
99     if (found == -1)
100     return NULL;
101    
102     cpu = malloc(sizeof(struct cpu));
103     if (cpu == NULL) {
104     fprintf(stderr, "out of memory\n");
105     exit(1);
106     }
107    
108     memset(cpu, 0, sizeof(struct cpu));
109     cpu->memory_rw = ppc_memory_rw;
110     cpu->cd.ppc.cpu_type = cpu_type_defs[found];
111     cpu->name = cpu->cd.ppc.cpu_type.name;
112     cpu->mem = mem;
113     cpu->machine = machine;
114     cpu->cpu_id = cpu_id;
115     cpu->byte_order = EMUL_BIG_ENDIAN;
116     cpu->cd.ppc.mode = MODE_PPC; /* TODO */
117     cpu->cd.ppc.of_emul_addr = 0xff000000; /* TODO */
118    
119     /* Current operating mode: */
120     cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;
121     cpu->bootstrap_cpu_flag = 0;
122     cpu->running = 0;
123    
124     /* Only show name and caches etc for CPU nr 0 (in SMP machines): */
125     if (cpu_id == 0) {
126     debug("%s", cpu->cd.ppc.cpu_type.name);
127    
128     if (cpu->cd.ppc.cpu_type.icache_shift != 0)
129     any_cache = 1;
130     if (cpu->cd.ppc.cpu_type.dcache_shift != 0)
131     any_cache = 1;
132     if (cpu->cd.ppc.cpu_type.l2cache_shift != 0)
133     any_cache = 1;
134    
135     if (any_cache) {
136     debug(" (I+D = %i+%i KB",
137     (int)(1 << (cpu->cd.ppc.cpu_type.icache_shift-10)),
138     (int)(1 << (cpu->cd.ppc.cpu_type.dcache_shift-10)));
139     if (cpu->cd.ppc.cpu_type.l2cache_shift != 0) {
140     debug(", L2 = %i KB",
141     (int)(1 << (cpu->cd.ppc.cpu_type.
142     l2cache_shift-10)));
143     }
144     debug(")");
145     }
146     }
147    
148     cpu->cd.ppc.pir = cpu_id;
149    
150     /* Some default stack pointer value. TODO: move this? */
151     cpu->cd.ppc.gpr[1] = machine->physical_ram_in_mb * 1048576 - 4096;
152    
153     return cpu;
154     }
155    
156    
157     /*
158     * ppc_cpu_list_available_types():
159     *
160     * Print a list of available PPC CPU types.
161     */
162     void ppc_cpu_list_available_types(void)
163     {
164     int i, j;
165     struct ppc_cpu_type_def tdefs[] = PPC_CPU_TYPE_DEFS;
166    
167     i = 0;
168     while (tdefs[i].name != NULL) {
169     debug("%s", tdefs[i].name);
170     for (j=10 - strlen(tdefs[i].name); j>0; j--)
171     debug(" ");
172     i++;
173     if ((i % 6) == 0 || tdefs[i].name == NULL)
174     debug("\n");
175     }
176     }
177    
178    
179     /*
180     * ppc_cpu_dumpinfo():
181     */
182     void ppc_cpu_dumpinfo(struct cpu *cpu)
183     {
184     struct ppc_cpu_type_def *ct = &cpu->cd.ppc.cpu_type;
185    
186     debug(" (%i-bit ", cpu->cd.ppc.bits);
187    
188     switch (cpu->cd.ppc.mode) {
189     case MODE_PPC:
190     debug("PPC");
191     break;
192     case MODE_POWER:
193     debug("POWER");
194     break;
195     default:
196     debug("_INTERNAL ERROR_");
197     }
198    
199     debug(", I+D = %i+%i KB",
200     (1 << ct->icache_shift) / 1024,
201     (1 << ct->dcache_shift) / 1024);
202    
203     if (ct->l2cache_shift) {
204     int kb = (1 << ct->l2cache_shift) / 1024;
205     debug(", L2 = %i %cB",
206     kb >= 1024? kb / 1024 : kb,
207     kb >= 1024? 'M' : 'K');
208     }
209    
210     debug(")\n");
211     }
212    
213    
214     /*
215     * reg_access_msr():
216     */
217     static void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag)
218     {
219     if (valuep == NULL) {
220     fatal("reg_access_msr(): NULL\n");
221     return;
222     }
223    
224     if (writeflag)
225     cpu->cd.ppc.msr = *valuep;
226    
227     /* TODO: Is the little-endian bit writable? */
228    
229     cpu->cd.ppc.msr &= ~PPC_MSR_LE;
230     if (cpu->byte_order != EMUL_BIG_ENDIAN)
231     cpu->cd.ppc.msr |= PPC_MSR_LE;
232    
233     if (!writeflag)
234     *valuep = cpu->cd.ppc.msr;
235     }
236    
237    
238     /*
239     * ppc_cpu_register_dump():
240     *
241     * Dump cpu registers in a relatively readable format.
242     *
243     * gprs: set to non-zero to dump GPRs and some special-purpose registers.
244     * coprocs: set bit 0..3 to dump registers in coproc 0..3.
245     */
246     void ppc_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
247     {
248     char *symbol;
249     uint64_t offset, tmp;
250     int i, x = cpu->cpu_id;
251     int bits32 = cpu->cd.ppc.bits == 32;
252    
253     if (gprs) {
254     /* Special registers (pc, ...) first: */
255     symbol = get_symbol_name(&cpu->machine->symbol_context,
256     cpu->pc, &offset);
257    
258     debug("cpu%i: pc = 0x", x);
259     if (bits32)
260     debug("%08x", (int)cpu->pc);
261     else
262     debug("%016llx", (long long)cpu->pc);
263     debug(" <%s>\n", symbol != NULL? symbol : " no symbol ");
264    
265     debug("cpu%i: lr = 0x", x);
266     if (bits32)
267     debug("%08x", (int)cpu->cd.ppc.lr);
268     else
269     debug("%016llx", (long long)cpu->cd.ppc.lr);
270     debug(" cr = 0x%08x\n", (int)cpu->cd.ppc.cr);
271    
272     debug("cpu%i: ctr = 0x", x);
273     if (bits32)
274     debug("%08x", (int)cpu->cd.ppc.ctr);
275     else
276     debug("%016llx", (long long)cpu->cd.ppc.ctr);
277    
278     debug(" xer = 0x", x);
279     if (bits32)
280     debug("%08x\n", (int)cpu->cd.ppc.xer);
281     else
282     debug("%016llx\n", (long long)cpu->cd.ppc.xer);
283    
284     if (bits32) {
285     /* 32-bit: */
286     for (i=0; i<PPC_NGPRS; i++) {
287     if ((i % 4) == 0)
288     debug("cpu%i:", x);
289     debug(" r%02i = 0x%08x ", i,
290     (int)cpu->cd.ppc.gpr[i]);
291     if ((i % 4) == 3)
292     debug("\n");
293     }
294     } else {
295     /* 64-bit: */
296     for (i=0; i<PPC_NGPRS; i++) {
297     if ((i % 2) == 0)
298     debug("cpu%i:", x);
299     debug(" r%02i = 0x%016llx ", i,
300     (long long)cpu->cd.ppc.gpr[i]);
301     if ((i % 2) == 1)
302     debug("\n");
303     }
304     }
305    
306     /* Other special registers: */
307     reg_access_msr(cpu, &tmp, 0);
308     debug("cpu%i: msr = 0x%016llx ", x, (long long)tmp);
309     debug("tb = 0x%08x%08x\n",
310     (int)cpu->cd.ppc.tbu, (int)cpu->cd.ppc.tbl);
311     debug("cpu%i: dec = 0x%08x hdec = 0x%08x\n",
312     x, (int)cpu->cd.ppc.dec, (int)cpu->cd.ppc.hdec);
313     }
314    
315     if (coprocs) {
316     debug("cpu%i: fpscr = 0x%08x\n", x, (int)cpu->cd.ppc.fpscr);
317    
318     /* TODO: show floating-point values :-) */
319    
320     /* TODO: 32-bit fprs on 32-bit PPC cpus? */
321    
322     for (i=0; i<PPC_NFPRS; i++) {
323     if ((i % 2) == 0)
324     debug("cpu%i:", x);
325     debug(" f%02i = 0x%016llx ", i,
326     (long long)cpu->cd.ppc.fpr[i]);
327     if ((i % 2) == 1)
328     debug("\n");
329     }
330     }
331     }
332    
333    
334     /*
335     * ppc_cpu_register_match():
336     */
337     void ppc_cpu_register_match(struct machine *m, char *name,
338     int writeflag, uint64_t *valuep, int *match_register)
339     {
340     int cpunr = 0;
341    
342     /* CPU number: */
343    
344     /* TODO */
345    
346     /* Register name: */
347     if (strcasecmp(name, "pc") == 0) {
348     if (writeflag) {
349     m->cpus[cpunr]->pc = *valuep;
350     } else
351     *valuep = m->cpus[cpunr]->pc;
352     *match_register = 1;
353     } else if (strcasecmp(name, "msr") == 0) {
354     if (writeflag)
355     m->cpus[cpunr]->cd.ppc.msr = *valuep;
356     else
357     *valuep = m->cpus[cpunr]->cd.ppc.msr;
358     *match_register = 1;
359     } else if (strcasecmp(name, "lr") == 0) {
360     if (writeflag)
361     m->cpus[cpunr]->cd.ppc.lr = *valuep;
362     else
363     *valuep = m->cpus[cpunr]->cd.ppc.lr;
364     *match_register = 1;
365     } else if (strcasecmp(name, "cr") == 0) {
366     if (writeflag)
367     m->cpus[cpunr]->cd.ppc.cr = *valuep;
368     else
369     *valuep = m->cpus[cpunr]->cd.ppc.cr;
370     *match_register = 1;
371     } else if (strcasecmp(name, "dec") == 0) {
372     if (writeflag)
373     m->cpus[cpunr]->cd.ppc.dec = *valuep;
374     else
375     *valuep = m->cpus[cpunr]->cd.ppc.dec;
376     *match_register = 1;
377     } else if (strcasecmp(name, "hdec") == 0) {
378     if (writeflag)
379     m->cpus[cpunr]->cd.ppc.hdec = *valuep;
380     else
381     *valuep = m->cpus[cpunr]->cd.ppc.hdec;
382     *match_register = 1;
383     } else if (strcasecmp(name, "ctr") == 0) {
384     if (writeflag)
385     m->cpus[cpunr]->cd.ppc.ctr = *valuep;
386     else
387     *valuep = m->cpus[cpunr]->cd.ppc.ctr;
388     *match_register = 1;
389     } else if (name[0] == 'r' && isdigit((int)name[1])) {
390     int nr = atoi(name + 1);
391     if (nr >= 0 && nr < PPC_NGPRS) {
392     if (writeflag) {
393     m->cpus[cpunr]->cd.ppc.gpr[nr] = *valuep;
394     } else
395     *valuep = m->cpus[cpunr]->cd.ppc.gpr[nr];
396     *match_register = 1;
397     }
398     } else if (strcasecmp(name, "xer") == 0) {
399     if (writeflag)
400     m->cpus[cpunr]->cd.ppc.xer = *valuep;
401     else
402     *valuep = m->cpus[cpunr]->cd.ppc.xer;
403     *match_register = 1;
404     } else if (strcasecmp(name, "fpscr") == 0) {
405     if (writeflag)
406     m->cpus[cpunr]->cd.ppc.fpscr = *valuep;
407     else
408     *valuep = m->cpus[cpunr]->cd.ppc.fpscr;
409     *match_register = 1;
410     } else if (name[0] == 'f' && isdigit((int)name[1])) {
411     int nr = atoi(name + 1);
412     if (nr >= 0 && nr < PPC_NFPRS) {
413     if (writeflag) {
414     m->cpus[cpunr]->cd.ppc.fpr[nr] = *valuep;
415     } else
416     *valuep = m->cpus[cpunr]->cd.ppc.fpr[nr];
417     *match_register = 1;
418     }
419     }
420     }
421    
422    
423     /*
424     * ppc_cpu_disassemble_instr():
425     *
426     * Convert an instruction word into human readable format, for instruction
427     * tracing.
428     *
429     * If running is 1, cpu->pc should be the address of the instruction.
430     *
431     * If running is 0, things that depend on the runtime environment (eg.
432     * register contents) will not be shown, and addr will be used instead of
433     * cpu->pc for relative addresses.
434     */
435     int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
436     int running, uint64_t dumpaddr, int bintrans)
437     {
438     int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;
439     int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;
440     int bfa;
441     uint64_t offset, addr;
442     uint32_t iword;
443     char *symbol, *mnem = "ERROR";
444     int power = cpu->cd.ppc.mode == MODE_POWER;
445    
446     if (running)
447     dumpaddr = cpu->pc;
448    
449     symbol = get_symbol_name(&cpu->machine->symbol_context,
450     dumpaddr, &offset);
451     if (symbol != NULL && offset==0)
452     debug("<%s>\n", symbol);
453    
454     if (cpu->machine->ncpus > 1 && running)
455     debug("cpu%i: ", cpu->cpu_id);
456    
457     if (cpu->cd.ppc.bits == 32)
458     debug("%08x", (int)dumpaddr);
459     else
460     debug("%016llx", (long long)dumpaddr);
461    
462     /* NOTE: Fixed to big-endian. */
463     iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
464     + instr[3];
465    
466     debug(": %08x\t", iword);
467    
468     if (bintrans && !running) {
469     debug("(bintrans)");
470     goto disasm_ret;
471     }
472    
473     /*
474     * Decode the instruction:
475     */
476    
477     hi6 = iword >> 26;
478    
479     switch (hi6) {
480     case PPC_HI6_MULLI:
481     case PPC_HI6_SUBFIC:
482     rt = (iword >> 21) & 31;
483     ra = (iword >> 16) & 31;
484     imm = (int16_t)(iword & 0xffff);
485     switch (hi6) {
486     case PPC_HI6_MULLI:
487     mnem = power? "muli":"mulli";
488     break;
489     case PPC_HI6_SUBFIC:
490     mnem = power? "sfi":"subfic";
491     break;
492     }
493     debug("%s\tr%i,r%i,%i", mnem, rt, ra, imm);
494     break;
495     case PPC_HI6_CMPLI:
496     case PPC_HI6_CMPI:
497     bf = (iword >> 23) & 7;
498     l_bit = (iword >> 21) & 1;
499     ra = (iword >> 16) & 31;
500     if (hi6 == PPC_HI6_CMPLI) {
501     imm = iword & 0xffff;
502     mnem = "cmpl";
503     } else {
504     imm = (int16_t)(iword & 0xffff);
505     mnem = "cmp";
506     }
507     debug("%s%si\t", mnem, l_bit? "d" : "w");
508     if (bf != 0)
509     debug("cr%i,", bf);
510     debug("r%i,%i", ra, imm);
511     break;
512     case PPC_HI6_ADDIC:
513     case PPC_HI6_ADDIC_DOT:
514     rt = (iword >> 21) & 31;
515     ra = (iword >> 16) & 31;
516     rc = hi6 == PPC_HI6_ADDIC_DOT;
517     imm = (int16_t)(iword & 0xffff);
518     mnem = power? "ai":"addic";
519     if (imm < 0 && !power) {
520     mnem = "subic";
521     imm = -imm;
522     }
523     debug("%s%s\tr%i,r%i,%i", mnem, rc?".":"", rt, ra, imm);
524     break;
525     case PPC_HI6_ADDI:
526     rt = (iword >> 21) & 31;
527     ra = (iword >> 16) & 31;
528     imm = (int16_t)(iword & 0xffff);
529     if (ra == 0)
530     debug("li\tr%i,%i", rt, imm);
531     else {
532     mnem = power? "cal":"addi";
533     if (imm < 0 && !power) {
534     mnem = "subi";
535     imm = -imm;
536     }
537     debug("%s\tr%i,r%i,%i", mnem, rt, ra, imm);
538     }
539     break;
540     case PPC_HI6_ADDIS:
541     rt = (iword >> 21) & 31;
542     ra = (iword >> 16) & 31;
543     imm = (int16_t)(iword & 0xffff);
544     if (ra == 0)
545     debug("lis\tr%i,%i", rt, imm);
546     else
547     debug("%s\tr%i,r%i,%i",
548     power? "cau":"addis", rt, ra, imm);
549     break;
550     case PPC_HI6_BC:
551     aa_bit = (iword & 2) >> 1;
552     lk_bit = iword & 1;
553     bo = (iword >> 21) & 31;
554     bi = (iword >> 16) & 31;
555     /* Sign-extend addr: */
556     addr = (int64_t)(int16_t)(iword & 0xfffc);
557     debug("bc");
558     if (lk_bit)
559     debug("l");
560     if (aa_bit)
561     debug("a");
562     else
563     addr += dumpaddr;
564     debug("\t%i,%i,", bo, bi);
565     if (cpu->cd.ppc.bits == 32)
566     addr &= 0xffffffff;
567     if (cpu->cd.ppc.bits == 32)
568     debug("0x%x", (int)addr);
569     else
570     debug("0x%llx", (long long)addr);
571     symbol = get_symbol_name(&cpu->machine->symbol_context,
572     addr, &offset);
573     if (symbol != NULL)
574     debug("\t<%s>", symbol);
575     break;
576     case PPC_HI6_SC:
577     lev = (iword >> 5) & 0x7f;
578     debug("sc");
579     if (lev != 0) {
580     debug("\t%i", lev);
581     if (lev > 1)
582     debug(" (WARNING! reserved value)");
583     }
584     break;
585     case PPC_HI6_B:
586     aa_bit = (iword & 2) >> 1;
587     lk_bit = iword & 1;
588     /* Sign-extend addr: */
589     addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
590     addr = (int64_t)addr >> 6;
591     debug("b");
592     if (lk_bit)
593     debug("l");
594     if (aa_bit)
595     debug("a");
596     else
597     addr += dumpaddr;
598     if (cpu->cd.ppc.bits == 32)
599     addr &= 0xffffffff;
600     if (cpu->cd.ppc.bits == 32)
601     debug("\t0x%x", (int)addr);
602     else
603     debug("\t0x%llx", (long long)addr);
604     symbol = get_symbol_name(&cpu->machine->symbol_context,
605     addr, &offset);
606     if (symbol != NULL)
607     debug("\t<%s>", symbol);
608     break;
609     case PPC_HI6_19:
610     xo = (iword >> 1) & 1023;
611     switch (xo) {
612     case PPC_19_MCRF:
613     bf = (iword >> 23) & 7;
614     bfa = (iword >> 18) & 7;
615     debug("mcrf\tcr%i,cr%i", bf, bfa);
616     break;
617     case PPC_19_BCLR:
618     case PPC_19_BCCTR:
619     bo = (iword >> 21) & 31;
620     bi = (iword >> 16) & 31;
621     bh = (iword >> 11) & 3;
622     lk_bit = iword & 1;
623     switch (xo) {
624     case PPC_19_BCLR:
625     mnem = power? "bcr" : "bclr"; break;
626     case PPC_19_BCCTR:
627     mnem = power? "bcc" : "bcctr"; break;
628     }
629     debug("%s%s%s\t%i,%i,%i", mnem, lk_bit? "l" : "",
630     bh? (bh==3? "+" : (bh==2? "-" : "?")) : "",
631     bo, bi, bh);
632     break;
633     case PPC_19_ISYNC:
634     debug("%s", power? "ics" : "isync");
635     break;
636     case PPC_19_CRAND:
637     case PPC_19_CRXOR:
638     case PPC_19_CROR:
639     case PPC_19_CRNAND:
640     case PPC_19_CRNOR:
641     case PPC_19_CRANDC:
642     case PPC_19_CREQV:
643     case PPC_19_CRORC:
644     bt = (iword >> 21) & 31;
645     ba = (iword >> 16) & 31;
646     bb = (iword >> 11) & 31;
647     switch (xo) {
648     case PPC_19_CRAND: mnem = "crand"; break;
649     case PPC_19_CRXOR: mnem = "crxor"; break;
650     case PPC_19_CROR: mnem = "cror"; break;
651     case PPC_19_CRNAND: mnem = "crnand"; break;
652     case PPC_19_CRNOR: mnem = "crnor"; break;
653     case PPC_19_CRANDC: mnem = "crandc"; break;
654     case PPC_19_CREQV: mnem = "creqv"; break;
655     case PPC_19_CRORC: mnem = "crorc"; break;
656     }
657     debug("%s\t%i,%i,%i", mnem, bt, ba, bb);
658     break;
659     default:
660     debug("unimplemented hi6_19, xo = 0x%x", xo);
661     }
662     break;
663     case PPC_HI6_RLWIMI:
664     case PPC_HI6_RLWINM:
665     rs = (iword >> 21) & 31;
666     ra = (iword >> 16) & 31;
667     sh = (iword >> 11) & 31;
668     mb = (iword >> 6) & 31;
669     me = (iword >> 1) & 31;
670     rc = iword & 1;
671     switch (hi6) {
672     case PPC_HI6_RLWIMI:
673     mnem = power? "rlimi" : "rlwimi"; break;
674     case PPC_HI6_RLWINM:
675     mnem = power? "rlinm" : "rlwinm"; break;
676     }
677     debug("%s%s\tr%i,r%i,%i,%i,%i",
678     mnem, rc?".":"", ra, rs, sh, mb, me);
679     break;
680     case PPC_HI6_ORI:
681     case PPC_HI6_ORIS:
682     case PPC_HI6_XORI:
683     case PPC_HI6_XORIS:
684     case PPC_HI6_ANDI_DOT:
685     case PPC_HI6_ANDIS_DOT:
686     rs = (iword >> 21) & 31;
687     ra = (iword >> 16) & 31;
688     imm = iword & 0xffff;
689     switch (hi6) {
690     case PPC_HI6_ORI:
691     mnem = power? "oril":"ori";
692     break;
693     case PPC_HI6_ORIS:
694     mnem = power? "oriu":"oris";
695     break;
696     case PPC_HI6_XORI:
697     mnem = power? "xoril":"xori";
698     break;
699     case PPC_HI6_XORIS:
700     mnem = power? "xoriu":"xoris";
701     break;
702     case PPC_HI6_ANDI_DOT:
703     mnem = power? "andil.":"andi.";
704     break;
705     case PPC_HI6_ANDIS_DOT:
706     mnem = power? "andiu.":"andis.";
707     break;
708     }
709     if (hi6 == PPC_HI6_ORI && rs == 0 && ra == 0 && imm == 0)
710     debug("nop");
711     else
712     debug("%s\tr%i,r%i,0x%04x", mnem, ra, rs, imm);
713     break;
714     case PPC_HI6_30:
715     xo = (iword >> 2) & 7;
716     switch (xo) {
717     case PPC_30_RLDICR:
718     rs = (iword >> 21) & 31;
719     ra = (iword >> 16) & 31;
720     sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
721     me = ((iword >> 6) & 31) | (iword & 0x20);
722     rc = iword & 1;
723     debug("rldicr%s\tr%i,r%i,%i,%i",
724     rc?".":"", ra, rs, sh, me);
725     break;
726     default:
727     debug("unimplemented hi6_30, xo = 0x%x", xo);
728     }
729     break;
730     case PPC_HI6_31:
731     xo = (iword >> 1) & 1023;
732     switch (xo) {
733    
734     case PPC_31_CMP:
735     case PPC_31_CMPL:
736     bf = (iword >> 23) & 7;
737     l_bit = (iword >> 21) & 1;
738     ra = (iword >> 16) & 31;
739     rb = (iword >> 11) & 31;
740     if (xo == PPC_31_CMPL)
741     mnem = "cmpl";
742     else
743     mnem = "cmp";
744     debug("%s%s\t", mnem, l_bit? "d" : "w");
745     if (bf != 0)
746     debug("cr%i,", bf);
747     debug("r%i,r%i", ra, rb);
748     break;
749     case PPC_31_MFCR:
750     rt = (iword >> 21) & 31;
751     debug("mfcr\tr%i", rt);
752     break;
753     case PPC_31_DCBST:
754     case PPC_31_ICBI:
755     ra = (iword >> 16) & 31;
756     rb = (iword >> 11) & 31;
757     switch (xo) {
758     case PPC_31_DCBST: mnem = "dcbst"; break;
759     case PPC_31_ICBI: mnem = "icbi"; break;
760     }
761     debug("%s\tr%i,r%i", mnem, ra, rb);
762     break;
763     case PPC_31_MFMSR:
764     rt = (iword >> 21) & 31;
765     debug("mfmsr\tr%i", rt);
766     break;
767     case PPC_31_MTCRF:
768     rs = (iword >> 21) & 31;
769     mb = (iword >> 12) & 255; /* actually fxm, not mb */
770     debug("mtcrf\t%i,r%i", mb, rs);
771     break;
772     case PPC_31_MTMSR:
773     rs = (iword >> 21) & 31;
774     l_bit = (iword >> 16) & 1;
775     debug("mtmsr\tr%i", rs);
776     if (l_bit)
777     debug(",%i", l_bit);
778     break;
779     case PPC_31_LBZX:
780     case PPC_31_LBZUX:
781     case PPC_31_LHZX:
782     case PPC_31_LHZUX:
783     case PPC_31_LWZX:
784     case PPC_31_LWZUX:
785     case PPC_31_STBX:
786     case PPC_31_STBUX:
787     case PPC_31_STHX:
788     case PPC_31_STHUX:
789     case PPC_31_STWX:
790     case PPC_31_STWUX:
791     /* rs for stores, rt for loads, actually */
792     rs = (iword >> 21) & 31;
793     ra = (iword >> 16) & 31;
794     rb = (iword >> 11) & 31;
795     switch (xo) {
796     case PPC_31_LBZX: mnem = "lbzx"; break;
797     case PPC_31_LBZUX: mnem = "lbzux"; break;
798     case PPC_31_LHZX: mnem = "lhzx"; break;
799     case PPC_31_LHZUX: mnem = "lhzux"; break;
800     case PPC_31_LWZX:
801     mnem = power? "lx" : "lwzx";
802     break;
803     case PPC_31_LWZUX:
804     mnem = power? "lux" : "lwzux";
805     break;
806     case PPC_31_STBX: mnem = "stbx"; break;
807     case PPC_31_STBUX: mnem = "stbux"; break;
808     case PPC_31_STHX: mnem = "sthx"; break;
809     case PPC_31_STHUX: mnem = "sthux"; break;
810     case PPC_31_STWX:
811     mnem = power? "stx" : "stwx";
812     break;
813     case PPC_31_STWUX:
814     mnem = power? "stux" : "stwux";
815     break;
816     }
817     debug("%s\tr%i,r%i,r%i", mnem, rs, ra, rb);
818     if (running)
819     goto disasm_ret_nonewline;
820     break;
821     case PPC_31_NEG:
822     case PPC_31_NEGO:
823     rt = (iword >> 21) & 31;
824     ra = (iword >> 16) & 31;
825     oe_bit = (iword >> 10) & 1;
826     rc = iword & 1;
827     switch (xo) {
828     case PPC_31_NEG: mnem = "neg"; break;
829     case PPC_31_NEGO: mnem = "nego"; break;
830     }
831     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
832     break;
833     case PPC_31_ADDZE:
834     case PPC_31_ADDZEO:
835     rt = (iword >> 21) & 31;
836     ra = (iword >> 16) & 31;
837     oe_bit = (iword >> 10) & 1;
838     rc = iword & 1;
839     switch (xo) {
840     case PPC_31_ADDZE:
841     mnem = power? "aze" : "addze";
842     break;
843     case PPC_31_ADDZEO:
844     mnem = power? "azeo" : "addzeo";
845     break;
846     }
847     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
848     break;
849     case PPC_31_MTSR:
850     /* Move to segment register (?) */
851     /* TODO */
852     debug("mtsr\tTODO");
853     break;
854     case PPC_31_MTSRIN:
855     case PPC_31_MFSRIN:
856     /* Move to/from segment register indirect */
857     rt = (iword >> 21) & 31;
858     rb = (iword >> 11) & 31;
859     switch (xo) {
860     case PPC_31_MTSRIN: mnem = "mtsrin"; break;
861     case PPC_31_MFSRIN: mnem = "mfsrin"; break;
862     }
863     debug("%s\tr%i,r%i", mnem, rt, rb);
864     break;
865     case PPC_31_ADDC:
866     case PPC_31_ADDCO:
867     case PPC_31_ADDE:
868     case PPC_31_ADDEO:
869     case PPC_31_ADD:
870     case PPC_31_ADDO:
871     case PPC_31_MULHW:
872     case PPC_31_MULHWU:
873     case PPC_31_MULLW:
874     case PPC_31_MULLWO:
875     case PPC_31_SUBF:
876     case PPC_31_SUBFO:
877     case PPC_31_SUBFC:
878     case PPC_31_SUBFCO:
879     case PPC_31_SUBFE:
880     case PPC_31_SUBFEO:
881     case PPC_31_SUBFZE:
882     case PPC_31_SUBFZEO:
883     rt = (iword >> 21) & 31;
884     ra = (iword >> 16) & 31;
885     rb = (iword >> 11) & 31;
886     oe_bit = (iword >> 10) & 1;
887     rc = iword & 1;
888     switch (xo) {
889     case PPC_31_ADDC:
890     mnem = power? "a" : "addc";
891     break;
892     case PPC_31_ADDCO:
893     mnem = power? "ao" : "addco";
894     break;
895     case PPC_31_ADDE:
896     mnem = power? "ae" : "adde";
897     break;
898     case PPC_31_ADDEO:
899     mnem = power? "aeo" : "addeo";
900     break;
901     case PPC_31_ADD:
902     mnem = power? "cax" : "add";
903     break;
904     case PPC_31_ADDO:
905     mnem = power? "caxo" : "addo";
906     break;
907     case PPC_31_MULHW: mnem = "mulhw"; break;
908     case PPC_31_MULHWU: mnem = "mulhwu"; break;
909     case PPC_31_MULLW:
910     mnem = power? "muls" : "mullw";
911     break;
912     case PPC_31_MULLWO:
913     mnem = power? "mulso" : "mullwo";
914     break;
915     case PPC_31_SUBF: mnem = "subf"; break;
916     case PPC_31_SUBFO: mnem = "subfo"; break;
917     case PPC_31_SUBFC:
918     mnem = power? "sf" : "subfc";
919     break;
920     case PPC_31_SUBFCO:
921     mnem = power? "sfo" : "subfco";
922     break;
923     case PPC_31_SUBFE:
924     mnem = power? "sfe" : "subfe";
925     break;
926     case PPC_31_SUBFEO:
927     mnem = power? "sfeo" : "subfeo";
928     break;
929     case PPC_31_SUBFZE:
930     mnem = power? "sfze" : "subfze";
931     break;
932     case PPC_31_SUBFZEO:
933     mnem = power? "sfzeo" : "subfzeo";
934     break;
935     }
936     debug("%s%s\tr%i,r%i,r%i", mnem, rc? "." : "",
937     rt, ra, rb);
938     break;
939     case PPC_31_MFSPR:
940     rt = (iword >> 21) & 31;
941     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
942     debug("mfspr\tr%i,spr%i", rt, spr);
943     break;
944     case PPC_31_TLBIE:
945     /* TODO: what is ra? The IBM online docs didn't say */
946     ra = 0;
947     rb = (iword >> 11) & 31;
948     if (power)
949     debug("tlbi\tr%i,r%i", ra, rb);
950     else
951     debug("tlbie\tr%i", rb);
952     break;
953     case PPC_31_TLBSYNC:
954     debug("tlbsync");
955     break;
956     case PPC_31_MFTB:
957     rt = (iword >> 21) & 31;
958     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
959     debug("mftb%s\tr%i", spr==268? "" :
960     (spr==269? "u" : "?"), rt);
961     break;
962     case PPC_31_CNTLZW:
963     rs = (iword >> 21) & 31;
964     ra = (iword >> 16) & 31;
965     rc = iword & 1;
966     mnem = power? "cntlz" : "cntlzw";
967     debug("%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
968     break;
969     case PPC_31_SLW:
970     case PPC_31_SRAW:
971     case PPC_31_SRW:
972     case PPC_31_AND:
973     case PPC_31_ANDC:
974     case PPC_31_NOR:
975     case PPC_31_OR:
976     case PPC_31_ORC:
977     case PPC_31_XOR:
978     case PPC_31_NAND:
979     rs = (iword >> 21) & 31;
980     ra = (iword >> 16) & 31;
981     rb = (iword >> 11) & 31;
982     rc = iword & 1;
983     if (rs == rb && xo == PPC_31_OR)
984     debug("mr%s\tr%i,r%i", rc? "." : "", ra, rs);
985     else {
986     switch (xo) {
987     case PPC_31_SLW: mnem =
988     power? "sl" : "slw"; break;
989     case PPC_31_SRAW: mnem =
990     power? "sra" : "sraw"; break;
991     case PPC_31_SRW: mnem =
992     power? "sr" : "srw"; break;
993     case PPC_31_AND: mnem = "and"; break;
994     case PPC_31_NAND: mnem = "nand"; break;
995     case PPC_31_ANDC: mnem = "andc"; break;
996     case PPC_31_NOR: mnem = "nor"; break;
997     case PPC_31_OR: mnem = "or"; break;
998     case PPC_31_ORC: mnem = "orc"; break;
999     case PPC_31_XOR: mnem = "xor"; break;
1000     }
1001     debug("%s%s\tr%i,r%i,r%i", mnem,
1002     rc? "." : "", ra, rs, rb);
1003     }
1004     break;
1005     case PPC_31_DCCCI:
1006     ra = (iword >> 16) & 31;
1007     rb = (iword >> 11) & 31;
1008     debug("dccci\tr%i,r%i", ra, rb);
1009     break;
1010     case PPC_31_ICCCI:
1011     ra = (iword >> 16) & 31;
1012     rb = (iword >> 11) & 31;
1013     debug("iccci\tr%i,r%i", ra, rb);
1014     break;
1015     case PPC_31_DIVW:
1016     case PPC_31_DIVWO:
1017     case PPC_31_DIVWU:
1018     case PPC_31_DIVWUO:
1019     rt = (iword >> 21) & 31;
1020     ra = (iword >> 16) & 31;
1021     rb = (iword >> 11) & 31;
1022     oe_bit = (iword >> 10) & 1;
1023     rc = iword & 1;
1024     switch (xo) {
1025     case PPC_31_DIVWU: mnem = "divwu"; break;
1026     case PPC_31_DIVWUO: mnem = "divwuo"; break;
1027     case PPC_31_DIVW: mnem = "divw"; break;
1028     case PPC_31_DIVWO: mnem = "divwo"; break;
1029     }
1030     debug("%s%s\tr%i,r%i,r%i", mnem, rc? "." : "",
1031     rt, ra, rb);
1032     break;
1033     case PPC_31_MTSPR:
1034     rs = (iword >> 21) & 31;
1035     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1036     debug("mtspr\tspr%i,r%i", spr, rs);
1037     break;
1038     case PPC_31_SYNC:
1039     debug("%s", power? "dcs" : "sync");
1040     break;
1041 dpavlin 4 case PPC_31_LSWI:
1042 dpavlin 2 case PPC_31_STSWI:
1043 dpavlin 4 rs = (iword >> 21) & 31; /* lwsi uses rt */
1044 dpavlin 2 ra = (iword >> 16) & 31;
1045     nb = (iword >> 11) & 31;
1046 dpavlin 4 switch (xo) {
1047     case PPC_31_LSWI:
1048     mnem = power? "lsi" : "lswi"; break;
1049     case PPC_31_STSWI:
1050     mnem = power? "stsi" : "stswi"; break;
1051     }
1052     debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);
1053 dpavlin 2 if (running)
1054     goto disasm_ret_nonewline;
1055     break;
1056     case PPC_31_SRAWI:
1057     rs = (iword >> 21) & 31;
1058     ra = (iword >> 16) & 31;
1059     sh = (iword >> 11) & 31;
1060     rc = iword & 1;
1061     mnem = power? "srai" : "srawi";
1062     debug("%s%s\tr%i,r%i,%i", mnem,
1063     rc? "." : "", ra, rs, sh);
1064     break;
1065     case PPC_31_EIEIO:
1066     debug("%s", power? "eieio?" : "eieio");
1067     break;
1068     case PPC_31_EXTSB:
1069     case PPC_31_EXTSH:
1070     case PPC_31_EXTSW:
1071     rs = (iword >> 21) & 31;
1072     ra = (iword >> 16) & 31;
1073     rc = iword & 1;
1074     switch (xo) {
1075     case PPC_31_EXTSB:
1076     mnem = power? "exts" : "extsb";
1077     break;
1078     case PPC_31_EXTSH:
1079     mnem = "extsh";
1080     break;
1081     case PPC_31_EXTSW:
1082     mnem = "extsw";
1083     break;
1084     }
1085     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1086     break;
1087     default:
1088     debug("unimplemented hi6_31, xo = 0x%x", xo);
1089     }
1090     break;
1091     case PPC_HI6_LWZ:
1092     case PPC_HI6_LWZU:
1093     case PPC_HI6_LHZ:
1094     case PPC_HI6_LHZU:
1095     case PPC_HI6_LHA:
1096     case PPC_HI6_LHAU:
1097     case PPC_HI6_LBZ:
1098     case PPC_HI6_LBZU:
1099     case PPC_HI6_STW:
1100     case PPC_HI6_STWU:
1101     case PPC_HI6_STH:
1102     case PPC_HI6_STHU:
1103     case PPC_HI6_STB:
1104     case PPC_HI6_STBU:
1105     case PPC_HI6_STMW:
1106     case PPC_HI6_LFD:
1107     case PPC_HI6_STFD:
1108     /* NOTE: Loads use rt, not rs, but are otherwise similar
1109     to stores */
1110     rs = (iword >> 21) & 31;
1111     ra = (iword >> 16) & 31;
1112     imm = (int16_t)(iword & 0xffff);
1113     fpreg = 0;
1114     switch (hi6) {
1115     case PPC_HI6_LWZ: mnem = power? "l" : "lwz"; break;
1116     case PPC_HI6_LWZU: mnem = power? "lu" : "lwzu"; break;
1117     case PPC_HI6_LHZ: mnem = "lhz"; break;
1118     case PPC_HI6_LHZU: mnem = "lhzu"; break;
1119     case PPC_HI6_LHA: mnem = "lha"; break;
1120     case PPC_HI6_LHAU: mnem = "lhau"; break;
1121     case PPC_HI6_LBZ: mnem = "lbz"; break;
1122     case PPC_HI6_LBZU: mnem = "lbzu"; break;
1123     case PPC_HI6_STW: mnem = power? "st" : "stw"; break;
1124     case PPC_HI6_STWU: mnem = power? "stu" : "stwu"; break;
1125     case PPC_HI6_STH: mnem = "sth"; break;
1126     case PPC_HI6_STHU: mnem = "sthu"; break;
1127     case PPC_HI6_STB: mnem = "stb"; break;
1128     case PPC_HI6_STBU: mnem = "stbu"; break;
1129     case PPC_HI6_LMW: mnem = power? "lm" : "lmw"; break;
1130     case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1131     case PPC_HI6_LFD: fpreg = 1; mnem = "lfd"; break;
1132     case PPC_HI6_STFD: fpreg = 1; mnem = "stfd"; break;
1133     }
1134     debug("%s\t", mnem);
1135     if (fpreg)
1136     debug("f");
1137     else
1138     debug("r");
1139     debug("%i,%i(r%i)", rs, imm, ra);
1140     if (running)
1141     goto disasm_ret_nonewline;
1142     break;
1143     default:
1144     /* TODO */
1145     debug("unimplemented hi6 = 0x%02x", hi6);
1146     }
1147    
1148     disasm_ret:
1149     debug("\n");
1150     disasm_ret_nonewline:
1151     return sizeof(iword);
1152     }
1153    
1154    
1155     /*
1156     * show_trace():
1157     *
1158     * Show trace tree. This function should be called every time
1159     * a function is called. cpu->cd.ppc.trace_tree_depth is increased here
1160     * and should not be increased by the caller.
1161     *
1162     * Note: This function should not be called if show_trace_tree == 0.
1163     */
1164     static void show_trace(struct cpu *cpu)
1165     {
1166     uint64_t offset, addr = cpu->pc;
1167     int x, n_args_to_print;
1168     char strbuf[60];
1169     char *symbol;
1170    
1171     cpu->cd.ppc.trace_tree_depth ++;
1172    
1173     if (cpu->machine->ncpus > 1)
1174     debug("cpu%i:", cpu->cpu_id);
1175    
1176     symbol = get_symbol_name(&cpu->machine->symbol_context, addr, &offset);
1177    
1178     for (x=0; x<cpu->cd.ppc.trace_tree_depth; x++)
1179     debug(" ");
1180    
1181     /* debug("<%s>\n", symbol!=NULL? symbol : "no symbol"); */
1182    
1183     if (symbol != NULL)
1184     debug("<%s(", symbol);
1185     else {
1186     debug("<0x");
1187     if (cpu->cd.ppc.bits == 32)
1188     debug("%08x", (int)addr);
1189     else
1190     debug("%016llx", (long long)addr);
1191     debug("(");
1192     }
1193    
1194     /*
1195     * TODO: The number of arguments and the symbol type of each
1196     * argument should be taken from the symbol table, in some way.
1197     */
1198     n_args_to_print = 5;
1199    
1200     for (x=0; x<n_args_to_print; x++) {
1201     int64_t d = cpu->cd.ppc.gpr[x + 3];
1202    
1203     if (d > -256 && d < 256)
1204     debug("%i", (int)d);
1205     else if (memory_points_to_string(cpu, cpu->mem, d, 1)) {
1206     debug("\"%s\"", memory_conv_to_string(cpu,
1207     cpu->mem, d, strbuf, sizeof(strbuf)));
1208     if (strlen(strbuf) >= sizeof(strbuf)-1)
1209     debug("..");
1210     } else {
1211     if (cpu->cd.ppc.bits == 32)
1212     debug("0x%x", (int)d);
1213     else
1214     debug("0x%llx", (long long)d);
1215     }
1216    
1217     if (x < n_args_to_print - 1)
1218     debug(",");
1219    
1220     if (x == n_args_to_print - 1)
1221     break;
1222     }
1223    
1224     if (n_args_to_print > 9)
1225     debug("..");
1226    
1227     debug(")>\n");
1228     }
1229    
1230    
1231     /*
1232     * update_cr0():
1233     *
1234     * Sets the top 4 bits of the CR register.
1235     */
1236     static void update_cr0(struct cpu *cpu, uint64_t value)
1237     {
1238     int c;
1239    
1240     if (cpu->cd.ppc.bits == 64) {
1241     if ((int64_t)value < 0)
1242     c = 8;
1243     else if ((int64_t)value > 0)
1244     c = 4;
1245     else
1246     c = 2;
1247     } else {
1248     if ((int32_t)value < 0)
1249     c = 8;
1250     else if ((int32_t)value > 0)
1251     c = 4;
1252     else
1253     c = 2;
1254     }
1255    
1256     /* SO bit, copied from XER: */
1257     c |= ((cpu->cd.ppc.xer >> 31) & 1);
1258    
1259     cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1260     cpu->cd.ppc.cr |= ((uint32_t)c << 28);
1261     }
1262    
1263    
1264     /*
1265     * ppc_cpu_run_instr():
1266     *
1267     * Execute one instruction on a specific CPU.
1268     *
1269     * Return value is the number of instructions executed during this call,
1270     * 0 if no instruction was executed.
1271     */
1272     int ppc_cpu_run_instr(struct emul *emul, struct cpu *cpu)
1273     {
1274     uint32_t iword;
1275     unsigned char buf[4];
1276     unsigned char tmp_data[8];
1277     size_t tmp_data_len;
1278     char *mnem = NULL;
1279     int r, hi6, rt, rs, ra, rb, xo, lev, sh, me, rc, imm, l_bit, oe_bit;
1280     int c, i, spr, aa_bit, bo, bi, bh, lk_bit, bf, ctr_ok, cond_ok;
1281     int update, load, mb, nb, bt, ba, bb, fpreg, arithflag, old_ca, bfa;
1282     uint64_t tmp=0, tmp2, addr;
1283     uint64_t cached_pc;
1284    
1285     cached_pc = cpu->cd.ppc.pc_last = cpu->pc & ~3;
1286    
1287     /* Check PC against breakpoints: */
1288     if (!single_step)
1289     for (i=0; i<cpu->machine->n_breakpoints; i++)
1290     if (cached_pc == cpu->machine->breakpoint_addr[i]) {
1291     fatal("Breakpoint reached, pc=0x");
1292     if (cpu->cd.ppc.bits == 32)
1293     fatal("%08x", (int)cached_pc);
1294     else
1295     fatal("%016llx", (long long)cached_pc);
1296     fatal("\n");
1297     single_step = 1;
1298     return 0;
1299     }
1300    
1301     /* Update the Time Base and Decrementer: */
1302     if ((++ cpu->cd.ppc.tbl) == 0)
1303     cpu->cd.ppc.tbu ++;
1304    
1305     cpu->cd.ppc.dec --;
1306     /* TODO: dec interrupt! */
1307    
1308     /* TODO: hdec for POWER4+ */
1309    
1310     /* ROM emulation: (TODO: non-OF-emuls) */
1311     if (cpu->pc == cpu->cd.ppc.of_emul_addr &&
1312     cpu->machine->prom_emulation) {
1313     int res = of_emul(cpu);
1314     if (res) {
1315     cpu->pc = cpu->cd.ppc.lr;
1316     }
1317     return 100;
1318     }
1319    
1320     r = cpu->memory_rw(cpu, cpu->mem, cached_pc, &buf[0], sizeof(buf),
1321     MEM_READ, CACHE_INSTRUCTION | PHYSICAL);
1322     if (!r)
1323     return 0;
1324    
1325     iword = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
1326    
1327     if (cpu->machine->instruction_trace)
1328     ppc_cpu_disassemble_instr(cpu, buf, 1, 0, 0);
1329    
1330     cpu->pc += sizeof(iword);
1331     cached_pc += sizeof(iword);
1332    
1333     hi6 = iword >> 26;
1334    
1335     switch (hi6) {
1336    
1337     case PPC_HI6_MULLI:
1338     rt = (iword >> 21) & 31;
1339     ra = (iword >> 16) & 31;
1340     imm = (int16_t)(iword & 0xffff);
1341     cpu->cd.ppc.gpr[rt] = (int64_t)cpu->cd.ppc.gpr[ra]
1342     * (int64_t)imm;
1343     break;
1344    
1345     case PPC_HI6_SUBFIC:
1346     rt = (iword >> 21) & 31;
1347     ra = (iword >> 16) & 31;
1348     imm = (int16_t)(iword & 0xffff);
1349     cpu->cd.ppc.xer &= ~PPC_XER_CA;
1350     if (cpu->cd.ppc.bits == 32) {
1351     tmp = (~cpu->cd.ppc.gpr[ra]) & 0xffffffff;
1352     cpu->cd.ppc.gpr[rt] = tmp + imm + 1;
1353     /* TODO: is this CA correct? */
1354     /* printf("subfic: tmp = %016llx\n", (long long)tmp);
1355     printf("subfic: rt = %016llx\n\n",
1356     (long long)cpu->cd.ppc.gpr[rt]); */
1357     if ((tmp >> 32) != (cpu->cd.ppc.gpr[rt] >> 32))
1358     cpu->cd.ppc.xer |= PPC_XER_CA;
1359     /* High 32 bits are probably undefined in
1360     32-bit mode (I hope) */
1361     } else {
1362     /*
1363     * Ugly, but I can't figure out a way right now how
1364     * to get the carry bit out of a 64-bit addition,
1365     * without access to more-than-64-bit operations in C.
1366     */
1367     tmp = ~cpu->cd.ppc.gpr[ra];
1368     tmp2 = (tmp >> 32); /* High 32 bits */
1369     tmp &= 0xffffffff; /* Low 32 bits */
1370    
1371     tmp += imm + 1;
1372     if ((tmp >> 32) == 0) {
1373     /* No change to upper 32 bits */
1374     } else if ((tmp >> 32) == 1) {
1375     /* Positive change: */
1376     tmp2 ++;
1377     } else {
1378     /* Negative change: */
1379     tmp2 --;
1380     }
1381    
1382     tmp &= 0xffffffff;
1383    
1384     /* TODO: is this CA calculation correct? */
1385     if ((tmp2 >> 32) != 0)
1386     cpu->cd.ppc.xer |= PPC_XER_CA;
1387    
1388     cpu->cd.ppc.gpr[rt] = (tmp2 << 32) + tmp;
1389     }
1390     break;
1391    
1392     case PPC_HI6_CMPLI:
1393     case PPC_HI6_CMPI:
1394     bf = (iword >> 23) & 7;
1395     l_bit = (iword >> 21) & 1;
1396     ra = (iword >> 16) & 31;
1397     if (hi6 == PPC_HI6_CMPLI)
1398     imm = iword & 0xffff;
1399     else
1400     imm = (int16_t)(iword & 0xffff);
1401     tmp = cpu->cd.ppc.gpr[ra];
1402    
1403     if (hi6 == PPC_HI6_CMPI) {
1404     if (!l_bit)
1405     tmp = (int64_t)(int32_t)tmp;
1406     if ((int64_t)tmp < (int64_t)imm)
1407     c = 8;
1408     else if ((int64_t)tmp > (int64_t)imm)
1409     c = 4;
1410     else
1411     c = 2;
1412     } else {
1413     if (!l_bit)
1414     tmp &= 0xffffffff;
1415     if ((uint64_t)tmp < (uint64_t)imm)
1416     c = 8;
1417     else if ((uint64_t)tmp > (uint64_t)imm)
1418     c = 4;
1419     else
1420     c = 2;
1421     }
1422    
1423     /* SO bit, copied from XER: */
1424     c |= ((cpu->cd.ppc.xer >> 31) & 1);
1425    
1426     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
1427     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
1428     break;
1429    
1430     case PPC_HI6_ADDIC:
1431     case PPC_HI6_ADDIC_DOT:
1432     rt = (iword >> 21) & 31;
1433     ra = (iword >> 16) & 31;
1434     rc = hi6 == PPC_HI6_ADDIC_DOT;
1435     imm = (int16_t)(iword & 0xffff);
1436     /* NOTE: Addic doesn't clear CA! */
1437     if (cpu->cd.ppc.bits == 32) {
1438     tmp = cpu->cd.ppc.gpr[ra] & 0xffffffff;
1439     cpu->cd.ppc.gpr[rt] = tmp + (uint32_t)imm;
1440     /* TODO: is this CA correct? */
1441     /* printf("addic: tmp = %016llx\n", (long long)tmp);
1442     printf("addic: rt = %016llx\n\n",
1443     (long long)cpu->cd.ppc.gpr[rt]); */
1444     if ((tmp >> 32) != (cpu->cd.ppc.gpr[rt] >> 32))
1445     cpu->cd.ppc.xer |= PPC_XER_CA;
1446     /* High 32 bits are probably undefined in
1447     32-bit mode (I hope) */
1448     } else {
1449     /* See comment about ugliness regarding SUBFIC */
1450     tmp = cpu->cd.ppc.gpr[ra];
1451     tmp2 = (tmp >> 32); /* High 32 bits */
1452     tmp &= 0xffffffff; /* Low 32 bits */
1453    
1454     tmp += (int64_t)imm;
1455     if ((tmp >> 32) == 0) {
1456     /* No change to upper 32 bits */
1457     } else if ((tmp >> 32) == 1) {
1458     /* Positive change: */
1459     tmp2 ++;
1460     } else {
1461     /* Negative change: */
1462     tmp2 --;
1463     }
1464    
1465     tmp &= 0xffffffff;
1466    
1467     /* TODO: is this CA calculation correct? */
1468     if ((tmp2 >> 32) != 0)
1469     cpu->cd.ppc.xer |= PPC_XER_CA;
1470    
1471     cpu->cd.ppc.gpr[rt] = (tmp2 << 32) + tmp;
1472     }
1473     if (rc)
1474     update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
1475     break;
1476    
1477     case PPC_HI6_ADDI:
1478     case PPC_HI6_ADDIS:
1479     rt = (iword >> 21) & 31;
1480     ra = (iword >> 16) & 31;
1481     if (hi6 == PPC_HI6_ADDI)
1482     imm = (int16_t)(iword & 0xffff);
1483     else
1484     imm = (int32_t)((iword & 0xffff) << 16);
1485     if (ra == 0)
1486     tmp = 0;
1487     else
1488     tmp = cpu->cd.ppc.gpr[ra];
1489     cpu->cd.ppc.gpr[rt] = tmp + imm;
1490     break;
1491    
1492     case PPC_HI6_BC:
1493     aa_bit = (iword >> 1) & 1;
1494     lk_bit = iword & 1;
1495     bo = (iword >> 21) & 31;
1496     bi = (iword >> 16) & 31;
1497     /* Sign-extend addr: */
1498     addr = (int64_t)(int16_t)(iword & 0xfffc);
1499    
1500     if (!aa_bit)
1501     addr += cpu->cd.ppc.pc_last;
1502    
1503     if (cpu->cd.ppc.bits == 32)
1504     addr &= 0xffffffff;
1505    
1506     if (!(bo & 4))
1507     cpu->cd.ppc.ctr --;
1508     ctr_ok = (bo >> 2) & 1;
1509     tmp = cpu->cd.ppc.ctr;
1510     if (cpu->cd.ppc.bits == 32)
1511     tmp &= 0xffffffff;
1512     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
1513    
1514     cond_ok = (bo >> 4) & 1;
1515     cond_ok |= ( ((bo >> 3) & 1) ==
1516     ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
1517    
1518     if (lk_bit)
1519     cpu->cd.ppc.lr = cpu->pc;
1520     if (ctr_ok && cond_ok)
1521     cpu->pc = addr & ~3;
1522     if (lk_bit && cpu->machine->show_trace_tree)
1523     show_trace(cpu);
1524     break;
1525    
1526     case PPC_HI6_SC:
1527     lev = (iword >> 5) & 0x7f;
1528     if (cpu->machine->userland_emul != NULL) {
1529     useremul_syscall(cpu, lev);
1530     } else {
1531     fatal("[ PPC: pc = 0x%016llx, sc not yet "
1532     "implemented ]\n", (long long)cached_pc);
1533     cpu->running = 0;
1534     return 0;
1535     }
1536     break;
1537    
1538     case PPC_HI6_B:
1539     aa_bit = (iword & 2) >> 1;
1540     lk_bit = iword & 1;
1541     /* Sign-extend addr: */
1542     addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
1543     addr = (int64_t)addr >> 6;
1544    
1545     if (!aa_bit)
1546     addr += cpu->cd.ppc.pc_last;
1547    
1548     if (cpu->cd.ppc.bits == 32)
1549     addr &= 0xffffffff;
1550    
1551     if (lk_bit)
1552     cpu->cd.ppc.lr = cpu->pc;
1553    
1554     cpu->pc = addr;
1555    
1556     if (lk_bit && cpu->machine->show_trace_tree)
1557     show_trace(cpu);
1558     break;
1559    
1560     case PPC_HI6_19:
1561     xo = (iword >> 1) & 1023;
1562     switch (xo) {
1563    
1564     case PPC_19_MCRF:
1565     bf = (iword >> 23) & 7;
1566     bfa = (iword >> 18) & 7;
1567     tmp = cpu->cd.ppc.cr >> (28 - bfa*4);
1568     tmp &= 0xf;
1569     cpu->cd.ppc.cr &= ~(0xf << (28 - bf*4));
1570     cpu->cd.ppc.cr |= (tmp << (28 - bf*4));
1571     break;
1572    
1573     case PPC_19_BCLR:
1574     case PPC_19_BCCTR:
1575     bo = (iword >> 21) & 31;
1576     bi = (iword >> 16) & 31;
1577     bh = (iword >> 11) & 3;
1578     lk_bit = iword & 1;
1579     if (xo == PPC_19_BCLR) {
1580     addr = cpu->cd.ppc.lr;
1581     if (!(bo & 4))
1582     cpu->cd.ppc.ctr --;
1583     ctr_ok = (bo >> 2) & 1;
1584     tmp = cpu->cd.ppc.ctr;
1585     if (cpu->cd.ppc.bits == 32)
1586     tmp &= 0xffffffff;
1587     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
1588     if (!quiet_mode && !lk_bit &&
1589     cpu->machine->show_trace_tree) {
1590     cpu->cd.ppc.trace_tree_depth --;
1591     /* TODO: show return value? */
1592     }
1593     } else {
1594     addr = cpu->cd.ppc.ctr;
1595     ctr_ok = 1;
1596     }
1597     cond_ok = (bo >> 4) & 1;
1598     cond_ok |= ( ((bo >> 3) & 1) ==
1599     ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
1600     if (lk_bit)
1601     cpu->cd.ppc.lr = cpu->pc;
1602     if (ctr_ok && cond_ok) {
1603     cpu->pc = addr & ~3;
1604     if (cpu->cd.ppc.bits == 32)
1605     cpu->pc &= 0xffffffff;
1606     }
1607     if (lk_bit && cpu->machine->show_trace_tree)
1608     show_trace(cpu);
1609     break;
1610    
1611     case PPC_19_ISYNC:
1612     /* TODO: actually sync */
1613     break;
1614    
1615     case PPC_19_CRAND:
1616     case PPC_19_CRXOR:
1617     case PPC_19_CROR:
1618     case PPC_19_CRNAND:
1619     case PPC_19_CRNOR:
1620     case PPC_19_CRANDC:
1621     case PPC_19_CREQV:
1622     case PPC_19_CRORC:
1623     bt = (iword >> 21) & 31;
1624     ba = (iword >> 16) & 31;
1625     bb = (iword >> 11) & 31;
1626     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1627     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1628     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1629     switch (xo) {
1630     case PPC_19_CRXOR:
1631     if (ba ^ bb)
1632     cpu->cd.ppc.cr |= (1 << (31-bt));
1633     break;
1634     case PPC_19_CROR:
1635     if (ba | bb)
1636     cpu->cd.ppc.cr |= (1 << (31-bt));
1637     break;
1638     default:
1639     fatal("[ TODO: crXXX, xo = %i, "
1640     "pc = 0x%016llx ]\n",
1641     xo, (long long) (cpu->cd.ppc.pc_last));
1642     cpu->running = 0;
1643     return 0;
1644     }
1645     break;
1646    
1647     default:
1648     fatal("[ unimplemented PPC hi6_19, xo = 0x%04x, "
1649     "pc = 0x%016llx ]\n",
1650     xo, (long long) (cpu->cd.ppc.pc_last));
1651     cpu->running = 0;
1652     return 0;
1653     }
1654     break;
1655    
1656     case PPC_HI6_RLWIMI:
1657     case PPC_HI6_RLWINM:
1658     rs = (iword >> 21) & 31;
1659     ra = (iword >> 16) & 31;
1660     sh = (iword >> 11) & 31;
1661     mb = (iword >> 6) & 31;
1662     me = (iword >> 1) & 31;
1663     rc = iword & 1;
1664     tmp = cpu->cd.ppc.gpr[rs];
1665     /* TODO: Fix this, its performance is awful: */
1666     while (sh-- != 0) {
1667     int b = (tmp >> 31) & 1;
1668     tmp = (tmp << 1) | b;
1669     }
1670    
1671     switch (hi6) {
1672     case PPC_HI6_RLWIMI:
1673     for (;;) {
1674     uint64_t mask;
1675     mask = (uint64_t)1 << (31-mb);
1676     cpu->cd.ppc.gpr[ra] &= ~mask;
1677     cpu->cd.ppc.gpr[ra] |= (tmp & mask);
1678     if (mb == me)
1679     break;
1680     mb ++;
1681     if (mb == 32)
1682     mb = 0;
1683     }
1684     break;
1685     case PPC_HI6_RLWINM:
1686     cpu->cd.ppc.gpr[ra] = 0;
1687     for (;;) {
1688     uint64_t mask;
1689     mask = (uint64_t)1 << (31-mb);
1690     cpu->cd.ppc.gpr[ra] |= (tmp & mask);
1691     if (mb == me)
1692     break;
1693     mb ++;
1694     if (mb == 32)
1695     mb = 0;
1696     }
1697     break;
1698     }
1699     if (rc)
1700     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1701     break;
1702    
1703     case PPC_HI6_ORI:
1704     case PPC_HI6_ORIS:
1705     rs = (iword >> 21) & 31;
1706     ra = (iword >> 16) & 31;
1707     if (hi6 == PPC_HI6_ORI)
1708     imm = (iword & 0xffff);
1709     else
1710     imm = (iword & 0xffff) << 16;
1711     tmp = cpu->cd.ppc.gpr[rs];
1712     cpu->cd.ppc.gpr[ra] = tmp | (uint32_t)imm;
1713     break;
1714    
1715     case PPC_HI6_XORI:
1716     case PPC_HI6_XORIS:
1717     rs = (iword >> 21) & 31;
1718     ra = (iword >> 16) & 31;
1719     if (hi6 == PPC_HI6_XORI)
1720     imm = (iword & 0xffff);
1721     else
1722     imm = (iword & 0xffff) << 16;
1723     tmp = cpu->cd.ppc.gpr[rs];
1724     cpu->cd.ppc.gpr[ra] = tmp ^ (uint32_t)imm;
1725     break;
1726    
1727     case PPC_HI6_ANDI_DOT:
1728     case PPC_HI6_ANDIS_DOT:
1729     rs = (iword >> 21) & 31;
1730     ra = (iword >> 16) & 31;
1731     if (hi6 == PPC_HI6_ANDI_DOT)
1732     imm = (iword & 0xffff);
1733     else
1734     imm = (iword & 0xffff) << 16;
1735     tmp = cpu->cd.ppc.gpr[rs];
1736     cpu->cd.ppc.gpr[ra] = tmp & (uint32_t)imm;
1737     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1738     break;
1739    
1740     case PPC_HI6_30:
1741     xo = (iword >> 2) & 7;
1742     switch (xo) {
1743     case PPC_30_RLDICR:
1744     if (cpu->cd.ppc.bits == 32) {
1745     /* TODO: Illegal instruction. */
1746     break;
1747     }
1748     rs = (iword >> 21) & 31;
1749     ra = (iword >> 16) & 31;
1750     sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
1751     me = ((iword >> 6) & 31) | (iword & 0x20);
1752     rc = iword & 1;
1753     tmp = cpu->cd.ppc.gpr[rs];
1754     /* TODO: Fix this, its performance is awful: */
1755     while (sh-- != 0) {
1756     int b = (tmp >> 63) & 1;
1757     tmp = (tmp << 1) | b;
1758     }
1759     while (me++ < 63)
1760     tmp &= ~((uint64_t)1 << (63-me));
1761     cpu->cd.ppc.gpr[ra] = tmp;
1762     if (rc)
1763     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1764     break;
1765     default:
1766     fatal("[ unimplemented PPC hi6_30, xo = 0x%04x, "
1767     "pc = 0x%016llx ]\n",
1768     xo, (long long) (cpu->cd.ppc.pc_last));
1769     cpu->running = 0;
1770     return 0;
1771     }
1772     break;
1773    
1774     case PPC_HI6_31:
1775     xo = (iword >> 1) & 1023;
1776     switch (xo) {
1777    
1778     case PPC_31_CMPL:
1779     case PPC_31_CMP:
1780     bf = (iword >> 23) & 7;
1781     l_bit = (iword >> 21) & 1;
1782     ra = (iword >> 16) & 31;
1783     rb = (iword >> 11) & 31;
1784    
1785     tmp = cpu->cd.ppc.gpr[ra];
1786     tmp2 = cpu->cd.ppc.gpr[rb];
1787    
1788     if (hi6 == PPC_31_CMP) {
1789     if (!l_bit) {
1790     tmp = (int64_t)(int32_t)tmp;
1791     tmp2 = (int64_t)(int32_t)tmp2;
1792     }
1793     if ((int64_t)tmp < (int64_t)tmp2)
1794     c = 8;
1795     else if ((int64_t)tmp > (int64_t)tmp2)
1796     c = 4;
1797     else
1798     c = 2;
1799     } else {
1800     if (!l_bit) {
1801     tmp &= 0xffffffff;
1802     tmp2 &= 0xffffffff;
1803     }
1804     if ((uint64_t)tmp < (uint64_t)tmp2)
1805     c = 8;
1806     else if ((uint64_t)tmp > (uint64_t)tmp2)
1807     c = 4;
1808     else
1809     c = 2;
1810     }
1811    
1812     /* SO bit, copied from XER: */
1813     c |= ((cpu->cd.ppc.xer >> 31) & 1);
1814    
1815     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
1816     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
1817     break;
1818    
1819     case PPC_31_MFCR:
1820     rt = (iword >> 21) & 31;
1821     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.cr;
1822     break;
1823    
1824     case PPC_31_DCBST:
1825     case PPC_31_ICBI:
1826     ra = (iword >> 16) & 31;
1827     rb = (iword >> 11) & 31;
1828     switch (xo) {
1829     case PPC_31_DCBST: mnem = "dcbst"; break;
1830     case PPC_31_ICBI: mnem = "icbi"; break;
1831     }
1832     /* debug("[ %s r%i,r%i: TODO ]\n", mnem, ra, rb); */
1833     break;
1834    
1835     case PPC_31_MFMSR:
1836     rt = (iword >> 21) & 31;
1837     /* TODO: check pr */
1838     reg_access_msr(cpu, &cpu->cd.ppc.gpr[rt], 0);
1839     break;
1840    
1841     case PPC_31_MTCRF:
1842     rs = (iword >> 21) & 31;
1843     mb = (iword >> 12) & 255; /* actually fxm, not mb */
1844     tmp = 0;
1845     for (i=0; i<8; i++, mb <<= 1, tmp <<= 4)
1846     if (mb & 128)
1847     tmp |= 0xf;
1848     cpu->cd.ppc.cr &= ~tmp;
1849     cpu->cd.ppc.cr |= (cpu->cd.ppc.gpr[rs] & tmp);
1850     break;
1851    
1852     case PPC_31_MTMSR:
1853     rs = (iword >> 21) & 31;
1854     l_bit = (iword >> 16) & 1;
1855     /* TODO: the l_bit */
1856     reg_access_msr(cpu, &cpu->cd.ppc.gpr[rs], 1);
1857     break;
1858    
1859     case PPC_31_LBZX:
1860     case PPC_31_LBZUX:
1861     case PPC_31_LHZX:
1862     case PPC_31_LHZUX:
1863     case PPC_31_LWZX:
1864     case PPC_31_LWZUX:
1865     case PPC_31_STBX:
1866     case PPC_31_STBUX:
1867     case PPC_31_STHX:
1868     case PPC_31_STHUX:
1869     case PPC_31_STWX:
1870     case PPC_31_STWUX:
1871     rs = (iword >> 21) & 31;
1872     ra = (iword >> 16) & 31;
1873     rb = (iword >> 11) & 31;
1874     update = 0;
1875     switch (xo) {
1876     case PPC_31_LBZUX:
1877     case PPC_31_LHZUX:
1878     case PPC_31_LWZUX:
1879     case PPC_31_STBUX:
1880     case PPC_31_STHUX:
1881     case PPC_31_STWUX:
1882     update = 1;
1883     }
1884     if (ra == 0)
1885     addr = 0;
1886     else
1887     addr = cpu->cd.ppc.gpr[ra];
1888     addr += cpu->cd.ppc.gpr[rb];
1889     load = 0;
1890     switch (xo) {
1891     case PPC_31_LBZX:
1892     case PPC_31_LBZUX:
1893     case PPC_31_LHZX:
1894     case PPC_31_LHZUX:
1895     case PPC_31_LWZX:
1896     case PPC_31_LWZUX:
1897     load = 1;
1898     }
1899    
1900     if (cpu->machine->instruction_trace) {
1901     if (cpu->cd.ppc.bits == 32)
1902     debug("\t[0x%08llx", (long long)addr);
1903     else
1904     debug("\t[0x%016llx", (long long)addr);
1905     }
1906    
1907     tmp_data_len = 4;
1908     switch (xo) {
1909     case PPC_31_LBZX:
1910     case PPC_31_LBZUX:
1911     case PPC_31_STBX:
1912     case PPC_31_STBUX:
1913     tmp_data_len = 1;
1914     break;
1915     case PPC_31_LHZX:
1916     case PPC_31_LHZUX:
1917     case PPC_31_STHX:
1918     case PPC_31_STHUX:
1919     tmp_data_len = 2;
1920     break;
1921     }
1922    
1923     tmp = 0;
1924    
1925     if (load) {
1926     r = cpu->memory_rw(cpu, cpu->mem, addr,
1927     tmp_data, tmp_data_len, MEM_READ,
1928     CACHE_DATA);
1929     if (r == MEMORY_ACCESS_OK) {
1930     if (cpu->byte_order ==
1931     EMUL_BIG_ENDIAN) {
1932     for (i=0; i<tmp_data_len; i++) {
1933     tmp <<= 8;
1934     tmp += tmp_data[i];
1935     }
1936     } else {
1937     for (i=0; i<tmp_data_len; i++) {
1938     tmp <<= 8;
1939     tmp += tmp_data[
1940     tmp_data_len - 1
1941     - i];
1942     }
1943     }
1944     cpu->cd.ppc.gpr[rs] = tmp;
1945     }
1946     } else {
1947     tmp = cpu->cd.ppc.gpr[rs];
1948     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1949     for (i=0; i<tmp_data_len; i++)
1950     tmp_data[tmp_data_len-1-i] =
1951     tmp >> (8*i);
1952     } else {
1953     for (i=0; i<tmp_data_len; i++)
1954     tmp_data[i] = tmp >> (8*i);
1955     }
1956    
1957     r = cpu->memory_rw(cpu, cpu->mem, addr,
1958     tmp_data, tmp_data_len, MEM_WRITE,
1959     CACHE_DATA);
1960     }
1961    
1962     if (cpu->machine->instruction_trace) {
1963     if (r == MEMORY_ACCESS_OK) {
1964     switch (tmp_data_len) {
1965     case 1: debug(", data = 0x%02x]\n",
1966     (int)tmp);
1967     break;
1968     case 2: debug(", data = 0x%04x]\n",
1969     (int)tmp);
1970     break;
1971     case 4: debug(", data = 0x%08x]\n",
1972     (int)tmp);
1973     break;
1974     default:debug(", data = 0x%016llx]\n",
1975     (long long)tmp);
1976     }
1977     } else
1978     debug(", FAILED]\n");
1979     }
1980    
1981     if (r != MEMORY_ACCESS_OK) {
1982     /* TODO: exception? */
1983     return 0;
1984     }
1985    
1986     if (update && ra != 0)
1987     cpu->cd.ppc.gpr[ra] = addr;
1988     break;
1989    
1990     case PPC_31_NEG:
1991     case PPC_31_NEGO:
1992     rt = (iword >> 21) & 31;
1993     ra = (iword >> 16) & 31;
1994     oe_bit = (iword >> 10) & 1;
1995     rc = iword & 1;
1996     if (oe_bit) {
1997     fatal("[ neg: PPC oe not yet implemeted ]\n");
1998     cpu->running = 0;
1999     return 0;
2000     }
2001     cpu->cd.ppc.gpr[rt] = ~cpu->cd.ppc.gpr[ra] + 1;
2002     if (rc)
2003     update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2004     break;
2005    
2006     case PPC_31_ADDZE:
2007     case PPC_31_ADDZEO:
2008     rt = (iword >> 21) & 31;
2009     ra = (iword >> 16) & 31;
2010     oe_bit = (iword >> 10) & 1;
2011     rc = iword & 1;
2012     if (oe_bit) {
2013     fatal("[ addz: PPC oe not yet implemeted ]\n");
2014     cpu->running = 0;
2015     return 0;
2016     }
2017     old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2018     cpu->cd.ppc.xer &= PPC_XER_CA;
2019     if (cpu->cd.ppc.bits == 32) {
2020     tmp = (uint32_t)cpu->cd.ppc.gpr[ra];
2021     tmp2 = tmp;
2022     /* printf("addze: tmp2 = %016llx\n",
2023     (long long)tmp2); */
2024     if (old_ca)
2025     tmp ++;
2026     /* printf("addze: tmp = %016llx\n\n",
2027     (long long)tmp); */
2028     /* TODO: is this CA correct? */
2029     if ((tmp >> 32) != (tmp2 >> 32))
2030     cpu->cd.ppc.xer |= PPC_XER_CA;
2031     /* High 32 bits are probably undefined
2032     in 32-bit mode (I hope) */
2033     cpu->cd.ppc.gpr[rt] = tmp;
2034     } else {
2035     fatal("ADDZE 64-bit, TODO\n");
2036     }
2037     if (rc)
2038     update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2039     break;
2040    
2041     case PPC_31_MTSR:
2042     /* Move to segment register (?) */
2043     /* TODO */
2044     break;
2045    
2046     case PPC_31_MFSRIN:
2047     case PPC_31_MTSRIN:
2048     /* mfsrin: Move to segment register indirect (?) */
2049     /* mtsrin: Move to segment register indirect (?) */
2050     rt = (iword >> 21) & 31;
2051     rb = (iword >> 11) & 31;
2052    
2053     /* TODO */
2054    
2055     if (xo == PPC_31_MFSRIN)
2056     cpu->cd.ppc.gpr[rt] = 0;
2057     break;
2058    
2059     case PPC_31_ADDC:
2060     case PPC_31_ADDCO:
2061     case PPC_31_ADDE:
2062     case PPC_31_ADDEO:
2063     case PPC_31_ADD:
2064     case PPC_31_ADDO:
2065     case PPC_31_MULHW:
2066     case PPC_31_MULHWU:
2067     case PPC_31_MULLW:
2068     case PPC_31_MULLWO:
2069     case PPC_31_SUBFE:
2070     case PPC_31_SUBFEO:
2071     case PPC_31_SUBFZE:
2072     case PPC_31_SUBFZEO:
2073     case PPC_31_SUBFC:
2074     case PPC_31_SUBFCO:
2075     case PPC_31_SUBF:
2076     case PPC_31_SUBFO:
2077     rt = (iword >> 21) & 31;
2078     ra = (iword >> 16) & 31;
2079     rb = (iword >> 11) & 31;
2080     oe_bit = (iword >> 10) & 1;
2081     rc = iword & 1;
2082     if (oe_bit) {
2083     fatal("[ add: PPC oe not yet implemeted ]\n");
2084     cpu->running = 0;
2085     return 0;
2086     }
2087     switch (xo) {
2088     case PPC_31_ADD:
2089     case PPC_31_ADDO:
2090     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.gpr[ra] +
2091     cpu->cd.ppc.gpr[rb];
2092     break;
2093     case PPC_31_ADDC:
2094     case PPC_31_ADDCO:
2095     case PPC_31_ADDE:
2096     case PPC_31_ADDEO:
2097     old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2098     cpu->cd.ppc.xer &= PPC_XER_CA;
2099     if (cpu->cd.ppc.bits == 32) {
2100     tmp = (uint32_t)cpu->cd.ppc.gpr[ra];
2101     tmp2 = tmp;
2102     /* printf("adde: tmp2 = %016llx\n",
2103     (long long)tmp2); */
2104     tmp += (uint32_t)cpu->cd.ppc.gpr[rb];
2105     if ((xo == PPC_31_ADDE ||
2106     xo == PPC_31_ADDEO) && old_ca)
2107     tmp ++;
2108     /* printf("adde: tmp = %016llx\n\n",
2109     (long long)tmp); */
2110     /* TODO: is this CA correct? */
2111     if ((tmp >> 32) != (tmp2 >> 32))
2112     cpu->cd.ppc.xer |= PPC_XER_CA;
2113     /* High 32 bits are probably undefined
2114     in 32-bit mode (I hope) */
2115     cpu->cd.ppc.gpr[rt] = tmp;
2116     } else {
2117     fatal("ADDE 64-bit, TODO\n");
2118     }
2119     break;
2120     case PPC_31_MULHW:
2121     cpu->cd.ppc.gpr[rt] = (int64_t) (
2122     (int64_t)(int32_t)cpu->cd.ppc.gpr[ra] *
2123     (int64_t)(int32_t)cpu->cd.ppc.gpr[rb]);
2124     cpu->cd.ppc.gpr[rt] >>= 32;
2125     break;
2126     case PPC_31_MULHWU:
2127     cpu->cd.ppc.gpr[rt] = (uint64_t) (
2128     (uint64_t)(uint32_t)cpu->cd.ppc.gpr[ra] *
2129     (uint64_t)(uint32_t)cpu->cd.ppc.gpr[rb]);
2130     cpu->cd.ppc.gpr[rt] >>= 32;
2131     break;
2132     case PPC_31_MULLW:
2133     case PPC_31_MULLWO:
2134     cpu->cd.ppc.gpr[rt] = (int64_t) (
2135     (int32_t)cpu->cd.ppc.gpr[ra] *
2136     (int32_t)cpu->cd.ppc.gpr[rb]);
2137     break;
2138     case PPC_31_SUBF:
2139     case PPC_31_SUBFO:
2140     cpu->cd.ppc.gpr[rt] = ~cpu->cd.ppc.gpr[ra] +
2141     cpu->cd.ppc.gpr[rb] + 1;
2142     break;
2143     case PPC_31_SUBFC:
2144     case PPC_31_SUBFCO:
2145     case PPC_31_SUBFE:
2146     case PPC_31_SUBFEO:
2147     case PPC_31_SUBFZE:
2148     case PPC_31_SUBFZEO:
2149     old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2150     if (xo == PPC_31_SUBFC || xo == PPC_31_SUBFCO)
2151     old_ca = 1;
2152     cpu->cd.ppc.xer &= PPC_XER_CA;
2153     if (cpu->cd.ppc.bits == 32) {
2154     tmp = (~cpu->cd.ppc.gpr[ra])
2155     & 0xffffffff;
2156     tmp2 = tmp;
2157     if (xo != PPC_31_SUBFZE &&
2158     xo != PPC_31_SUBFZEO)
2159     tmp += (cpu->cd.ppc.gpr[rb] &
2160     0xffffffff);
2161     if (old_ca)
2162     tmp ++;
2163     /* printf("subfe: tmp2 = %016llx\n",
2164     (long long)tmp2);
2165     printf("subfe: tmp = %016llx\n\n",
2166     (long long)tmp); */
2167     /* TODO: is this CA correct? */
2168     if ((tmp >> 32) != (tmp2 >> 32))
2169     cpu->cd.ppc.xer |= PPC_XER_CA;
2170     /* High 32 bits are probably undefined
2171     in 32-bit mode (I hope) */
2172     cpu->cd.ppc.gpr[rt] = tmp;
2173     } else {
2174     fatal("SUBFE 64-bit, TODO\n");
2175     }
2176     break;
2177     }
2178     if (rc)
2179     update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2180     break;
2181    
2182     case PPC_31_MFSPR:
2183     case PPC_31_MFTB:
2184     rt = (iword >> 21) & 31;
2185     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2186     switch (spr) {
2187     case 1: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.xer;
2188     break;
2189     case 8: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.lr;
2190     break;
2191     case 9: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.ctr;
2192     break;
2193     case 22:/* TODO: check pr */
2194     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.dec;
2195     break;
2196     case 259: /* NOTE: no pr check */
2197     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg3;
2198     break;
2199     case 268: /* MFTB, NOTE: no pr check */
2200     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.tbl;
2201     break;
2202     case 269: /* MFTBU, NOTE: no pr check */
2203     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.tbu;
2204     break;
2205     case 272:
2206     /* TODO: check pr */
2207     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg0;
2208     break;
2209     case 273:
2210     /* TODO: check pr */
2211     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg1;
2212     break;
2213     case 274:
2214     /* TODO: check pr */
2215     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg2;
2216     break;
2217     case 275:
2218     /* TODO: check pr */
2219     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg3;
2220     break;
2221     case 287:
2222     /* TODO: check pr */
2223     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.pvr;
2224     break;
2225     case 310:/* TODO: check pr */
2226     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.hdec;
2227     break;
2228     case 1023:
2229     /* TODO: check pr */
2230     cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.pir;
2231     break;
2232     default:
2233     fatal("[ unimplemented PPC spr 0x%04x, "
2234     "pc = 0x%016llx ]\n",
2235     spr, (long long) (cpu->cd.ppc.pc_last));
2236     /* cpu->running = 0;
2237     return 0; */
2238     break;
2239     }
2240    
2241     /* TODO: is this correct? */
2242     if (cpu->cd.ppc.bits == 32)
2243     cpu->cd.ppc.gpr[rt] &= 0xffffffff;
2244     break;
2245    
2246     case PPC_31_CNTLZW:
2247     rs = (iword >> 21) & 31;
2248     ra = (iword >> 16) & 31;
2249     rc = iword & 1;
2250     cpu->cd.ppc.gpr[ra] = 0;
2251     for (i=0; i<32; i++) {
2252     if (cpu->cd.ppc.gpr[rs] &
2253     ((uint64_t)1 << (31-i)))
2254     break;
2255     cpu->cd.ppc.gpr[ra] ++;
2256     }
2257     if (rc)
2258     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2259     break;
2260    
2261     case PPC_31_SLW:
2262     case PPC_31_SRAW:
2263     case PPC_31_SRW:
2264     case PPC_31_AND:
2265     case PPC_31_ANDC:
2266     case PPC_31_NOR:
2267     case PPC_31_OR:
2268     case PPC_31_ORC:
2269     case PPC_31_XOR:
2270     case PPC_31_NAND:
2271     rs = (iword >> 21) & 31;
2272     ra = (iword >> 16) & 31;
2273     rb = (iword >> 11) & 31;
2274     rc = iword & 1;
2275     switch (xo) {
2276     case PPC_31_SLW:
2277     sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2278     cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs];
2279     while (sh-- > 0)
2280     cpu->cd.ppc.gpr[ra] <<= 1;
2281     cpu->cd.ppc.gpr[ra] &= 0xffffffff;
2282     break;
2283     case PPC_31_SRAW:
2284     tmp = cpu->cd.ppc.gpr[rs] & 0xffffffff;
2285     cpu->cd.ppc.xer &= ~PPC_XER_CA;
2286     i = 0;
2287     sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2288     if (tmp & 0x80000000)
2289     i = 1;
2290     while (sh-- > 0) {
2291     if (tmp & 1)
2292     i++;
2293     tmp >>= 1;
2294     if (tmp & 0x40000000)
2295     tmp |= 0x80000000;
2296     }
2297     cpu->cd.ppc.gpr[ra] = (int64_t)(int32_t)tmp;
2298     /* Set the CA bit if rs contained a negative
2299     number to begin with, and any 1-bits were
2300     shifted out: */
2301     if (i > 1)
2302     cpu->cd.ppc.xer |= PPC_XER_CA;
2303     break;
2304     case PPC_31_SRW:
2305     sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2306     cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs]
2307     & 0xffffffff;
2308     while (sh-- > 0)
2309     cpu->cd.ppc.gpr[ra] >>= 1;
2310     break;
2311     case PPC_31_AND:
2312     cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] &
2313     cpu->cd.ppc.gpr[rb];
2314     break;
2315     case PPC_31_ANDC:
2316     cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] &
2317     (~cpu->cd.ppc.gpr[rb]);
2318     break;
2319     case PPC_31_NOR:
2320     cpu->cd.ppc.gpr[ra] = ~(cpu->cd.ppc.gpr[rs] |
2321     cpu->cd.ppc.gpr[rb]);
2322     break;
2323     case PPC_31_OR:
2324     cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] |
2325     cpu->cd.ppc.gpr[rb];
2326     break;
2327     case PPC_31_ORC:
2328     cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] |
2329     (~cpu->cd.ppc.gpr[rb]);
2330     break;
2331     case PPC_31_XOR:
2332     cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] ^
2333     cpu->cd.ppc.gpr[rb];
2334     break;
2335     case PPC_31_NAND:
2336     cpu->cd.ppc.gpr[ra] = ~(cpu->cd.ppc.gpr[rs]
2337     & cpu->cd.ppc.gpr[rb]);
2338     break;
2339     }
2340     if (rc)
2341     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2342     break;
2343    
2344     case PPC_31_TLBIE:
2345     rb = (iword >> 11) & 31;
2346     /* TODO */
2347     break;
2348    
2349     case PPC_31_TLBSYNC:
2350     /* Only on 603 and 604 (?) */
2351    
2352     /* TODO */
2353     break;
2354    
2355     case PPC_31_DCCCI:
2356     case PPC_31_ICCCI:
2357     /* Supervisor IBM 4xx Data Cache Congruence Class
2358     Invalidate, see www.xilinx.com/publications/
2359     xcellonline/partners/xc_pdf/xc_ibm_pwrpc42.pdf
2360     or similar */
2361     /* ICCCI is probably Instruction... blah blah */
2362     /* TODO */
2363     break;
2364    
2365     case PPC_31_DIVWU:
2366     case PPC_31_DIVWUO:
2367     case PPC_31_DIVW:
2368     case PPC_31_DIVWO:
2369     rt = (iword >> 21) & 31;
2370     ra = (iword >> 16) & 31;
2371     rb = (iword >> 11) & 31;
2372     oe_bit = (iword >> 10) & 1;
2373     rc = iword & 1;
2374     switch (xo) {
2375     case PPC_31_DIVWU:
2376     case PPC_31_DIVWUO:
2377     tmp = cpu->cd.ppc.gpr[ra] & 0xffffffff;
2378     tmp2 = cpu->cd.ppc.gpr[rb] & 0xffffffff;
2379     if (tmp2 == 0) {
2380     /* Undefined: */
2381     tmp = 0;
2382     } else {
2383     tmp = tmp / tmp2;
2384     }
2385     cpu->cd.ppc.gpr[rt] = (int64_t)(int32_t)tmp;
2386     break;
2387     case PPC_31_DIVW:
2388     case PPC_31_DIVWO:
2389     tmp = (int64_t)(int32_t)cpu->cd.ppc.gpr[ra];
2390     tmp2 = (int64_t)(int32_t)cpu->cd.ppc.gpr[rb];
2391     if (tmp2 == 0) {
2392     /* Undefined: */
2393     tmp = 0;
2394     } else {
2395     tmp = (int64_t)tmp / (int64_t)tmp2;
2396     }
2397     cpu->cd.ppc.gpr[rt] = (int64_t)(int32_t)tmp;
2398     break;
2399     }
2400     if (rc)
2401     update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2402     if (oe_bit) {
2403     fatal("[ divwu: PPC oe not yet implemeted ]\n");
2404     cpu->running = 0;
2405     return 0;
2406     }
2407     break;
2408    
2409     case PPC_31_MTSPR:
2410     rs = (iword >> 21) & 31;
2411     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2412     switch (spr) {
2413     case 1: cpu->cd.ppc.xer = cpu->cd.ppc.gpr[rs];
2414     break;
2415     case 8: cpu->cd.ppc.lr = cpu->cd.ppc.gpr[rs];
2416     break;
2417     case 9: cpu->cd.ppc.ctr = cpu->cd.ppc.gpr[rs];
2418     break;
2419     case 22: /* TODO: check pr */
2420     cpu->cd.ppc.dec = cpu->cd.ppc.gpr[rs];
2421     break;
2422     case 272:
2423     /* TODO: check hypv */
2424     cpu->cd.ppc.sprg0 = cpu->cd.ppc.gpr[rs];
2425     break;
2426     case 273:
2427     /* TODO: check pr */
2428     cpu->cd.ppc.sprg1 = cpu->cd.ppc.gpr[rs];
2429     break;
2430     case 274:
2431     /* TODO: check pr */
2432     cpu->cd.ppc.sprg2 = cpu->cd.ppc.gpr[rs];
2433     break;
2434     case 275:
2435     /* TODO: check pr */
2436     cpu->cd.ppc.sprg3 = cpu->cd.ppc.gpr[rs];
2437     break;
2438     case 284:
2439     /* TODO: check pr */
2440     cpu->cd.ppc.tbl = cpu->cd.ppc.gpr[rs];
2441     break;
2442     case 285:
2443     /* TODO: check pr */
2444     cpu->cd.ppc.tbu = cpu->cd.ppc.gpr[rs];
2445     break;
2446     case 287:
2447     fatal("[ PPC: attempt to write to PVR ]\n");
2448     break;
2449     case 310: /* TODO: check hypv */
2450     cpu->cd.ppc.hdec = cpu->cd.ppc.gpr[rs];
2451     break;
2452     case 1023:
2453     /* TODO: check pr */
2454     cpu->cd.ppc.pir = cpu->cd.ppc.gpr[rs];
2455     break;
2456     default:
2457     fatal("[ unimplemented PPC spr 0x%04x, "
2458     "pc = 0x%016llx ]\n",
2459     spr, (long long) (cpu->cd.ppc.pc_last));
2460     /* cpu->running = 0;
2461     return 0; */
2462     break;
2463     }
2464     break;
2465    
2466     case PPC_31_SYNC:
2467     /* TODO: actually sync */
2468     break;
2469    
2470 dpavlin 4 case PPC_31_LSWI:
2471 dpavlin 2 case PPC_31_STSWI:
2472     rs = (iword >> 21) & 31;
2473     ra = (iword >> 16) & 31;
2474     nb = (iword >> 11) & 31;
2475     if (nb == 0)
2476     nb = 32;
2477     if (ra == 0)
2478     addr = 0;
2479     else
2480     addr = cpu->cd.ppc.gpr[ra];
2481    
2482 dpavlin 4 load = 0;
2483     if (xo == PPC_31_LSWI)
2484     load = 1;
2485    
2486 dpavlin 2 if (cpu->machine->instruction_trace) {
2487     if (cpu->cd.ppc.bits == 32)
2488     debug("\t[0x%08llx", (long long)addr);
2489     else
2490     debug("\t[0x%016llx", (long long)addr);
2491     }
2492    
2493     i = 24;
2494 dpavlin 4 r = 0; /* Error count. */
2495     while (nb-- > 0) {
2496     if (load) {
2497     /* (Actually rt should be used.) */
2498     if (cpu->memory_rw(cpu, cpu->mem, addr,
2499     tmp_data, 1, MEM_READ, CACHE_DATA)
2500     != MEMORY_ACCESS_OK) {
2501     r++;
2502     break;
2503     }
2504     if (i == 24)
2505     cpu->cd.ppc.gpr[rs] = 0;
2506     cpu->cd.ppc.gpr[rs] |=
2507     (tmp_data[0] << i);
2508     } else {
2509     tmp_data[0] = cpu->cd.ppc.gpr[rs] >> i;
2510     if (cpu->memory_rw(cpu, cpu->mem, addr,
2511     tmp_data, 1, MEM_WRITE, CACHE_DATA)
2512     != MEMORY_ACCESS_OK) {
2513     r++;
2514     break;
2515     }
2516     }
2517     addr++; i-=8;
2518 dpavlin 2 if (i < 0) {
2519     i = 24;
2520     rs = (rs + 1) % 32;
2521     }
2522     }
2523    
2524     if (cpu->machine->instruction_trace) {
2525     if (r == 0)
2526     debug(", ...]\n");
2527     else
2528     debug(", FAILED]\n");
2529     }
2530    
2531     if (r > 0) {
2532     /* TODO: exception */
2533 dpavlin 4 fatal("TODO: exception.\n");
2534 dpavlin 2 return 0;
2535     }
2536     break;
2537    
2538     case PPC_31_SRAWI:
2539     rs = (iword >> 21) & 31;
2540     ra = (iword >> 16) & 31;
2541     sh = (iword >> 11) & 31;
2542     rc = iword & 1;
2543     tmp = cpu->cd.ppc.gpr[rs] & 0xffffffff;
2544     cpu->cd.ppc.xer &= ~PPC_XER_CA;
2545     i = 0;
2546     if (tmp & 0x80000000)
2547     i = 1;
2548     while (sh-- > 0) {
2549     if (tmp & 1)
2550     i++;
2551     tmp >>= 1;
2552     if (tmp & 0x40000000)
2553     tmp |= 0x80000000;
2554     }
2555     cpu->cd.ppc.gpr[ra] = (int64_t)(int32_t)tmp;
2556     /* Set the CA bit if rs contained a negative
2557     number to begin with, and any 1-bits were
2558     shifted out: */
2559     if (i > 1)
2560     cpu->cd.ppc.xer |= PPC_XER_CA;
2561     if (rc)
2562     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2563     break;
2564    
2565     case PPC_31_EIEIO:
2566     /* TODO: actually eieio */
2567     break;
2568    
2569     case PPC_31_EXTSB:
2570     case PPC_31_EXTSH:
2571     case PPC_31_EXTSW:
2572     rs = (iword >> 21) & 31;
2573     ra = (iword >> 16) & 31;
2574     rc = iword & 1;
2575     switch (xo) {
2576     case PPC_31_EXTSB:
2577     cpu->cd.ppc.gpr[ra] = (int64_t)
2578     (int8_t)cpu->cd.ppc.gpr[rs];
2579     break;
2580     case PPC_31_EXTSH:
2581     cpu->cd.ppc.gpr[ra] = (int64_t)
2582     (int16_t)cpu->cd.ppc.gpr[rs];
2583     break;
2584     case PPC_31_EXTSW:
2585     cpu->cd.ppc.gpr[ra] = (int64_t)
2586     (int32_t)cpu->cd.ppc.gpr[rs];
2587     break;
2588     }
2589     if (rc)
2590     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2591     break;
2592    
2593     default:
2594     fatal("[ unimplemented PPC hi6_31, xo = 0x%04x, "
2595     "pc = 0x%016llx ]\n",
2596     xo, (long long) (cpu->cd.ppc.pc_last));
2597     cpu->running = 0;
2598     return 0;
2599     }
2600     break;
2601    
2602     case PPC_HI6_LWZ:
2603     case PPC_HI6_LWZU:
2604     case PPC_HI6_LHZ:
2605     case PPC_HI6_LHZU:
2606     case PPC_HI6_LHA:
2607     case PPC_HI6_LHAU:
2608     case PPC_HI6_LBZ:
2609     case PPC_HI6_LBZU:
2610     case PPC_HI6_STW:
2611     case PPC_HI6_STWU:
2612     case PPC_HI6_STH:
2613     case PPC_HI6_STHU:
2614     case PPC_HI6_STB:
2615     case PPC_HI6_STBU:
2616     case PPC_HI6_LFD:
2617     case PPC_HI6_STFD:
2618     /* NOTE: Loads use rt, not rs, but are otherwise similar
2619     to stores. This code uses rs for both. */
2620     rs = (iword >> 21) & 31;
2621     ra = (iword >> 16) & 31;
2622     imm = (int16_t)(iword & 0xffff);
2623    
2624     fpreg = 0; load = 1; update = 0; tmp_data_len = 4;
2625     arithflag = 0;
2626    
2627     switch (hi6) {
2628     case PPC_HI6_LWZU:
2629     case PPC_HI6_LHZU:
2630     case PPC_HI6_LHAU:
2631     case PPC_HI6_LBZU:
2632     case PPC_HI6_STBU:
2633     case PPC_HI6_STHU:
2634     case PPC_HI6_STWU:
2635     update = 1;
2636     }
2637    
2638     switch (hi6) {
2639     case PPC_HI6_STW:
2640     case PPC_HI6_STWU:
2641     case PPC_HI6_STH:
2642     case PPC_HI6_STHU:
2643     case PPC_HI6_STB:
2644     case PPC_HI6_STBU:
2645     case PPC_HI6_STFD:
2646     load = 0;
2647     }
2648    
2649     switch (hi6) {
2650     case PPC_HI6_LFD:
2651     case PPC_HI6_STFD:
2652     tmp_data_len = 8;
2653     break;
2654     case PPC_HI6_LBZ:
2655     case PPC_HI6_LBZU:
2656     case PPC_HI6_STB:
2657     case PPC_HI6_STBU:
2658     tmp_data_len = 1;
2659     break;
2660     case PPC_HI6_LHZ:
2661     case PPC_HI6_LHZU:
2662     case PPC_HI6_LHA:
2663     case PPC_HI6_LHAU:
2664     case PPC_HI6_STH:
2665     case PPC_HI6_STHU:
2666     tmp_data_len = 2;
2667     break;
2668     }
2669    
2670     switch (hi6) {
2671     case PPC_HI6_LFD:
2672     case PPC_HI6_STFD:
2673     fpreg = 1;
2674     }
2675    
2676     switch (hi6) {
2677     case PPC_HI6_LHA:
2678     case PPC_HI6_LHAU:
2679     arithflag = 1;
2680     }
2681    
2682     if (ra == 0) {
2683     if (update)
2684     fatal("[ PPC WARNING: invalid Update form ]\n");
2685     addr = 0;
2686     } else
2687     addr = cpu->cd.ppc.gpr[ra];
2688    
2689     if (load && update && ra == rs)
2690     fatal("[ PPC WARNING: invalid Update load form ]\n");
2691    
2692     addr += imm;
2693    
2694     /* TODO: alignment check? */
2695    
2696     if (cpu->machine->instruction_trace) {
2697     if (cpu->cd.ppc.bits == 32)
2698     debug("\t[0x%08llx", (long long)addr);
2699     else
2700     debug("\t[0x%016llx", (long long)addr);
2701     }
2702    
2703     if (load) {
2704     r = cpu->memory_rw(cpu, cpu->mem, addr, tmp_data,
2705     tmp_data_len, MEM_READ, CACHE_DATA);
2706    
2707     if (r == MEMORY_ACCESS_OK) {
2708     tmp = 0;
2709     if (arithflag) {
2710     if (cpu->byte_order ==
2711     EMUL_BIG_ENDIAN) {
2712     if (tmp_data[0] & 0x80)
2713     tmp --;
2714     } else {
2715     if (tmp_data[tmp_data_len-1]
2716     & 0x80)
2717     tmp --;
2718     }
2719     }
2720     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2721     for (i=0; i<tmp_data_len; i++) {
2722     tmp <<= 8;
2723     tmp += tmp_data[i];
2724     }
2725     } else {
2726     for (i=0; i<tmp_data_len; i++) {
2727     tmp <<= 8;
2728     tmp += tmp_data[
2729     tmp_data_len - 1 -i];
2730     }
2731     }
2732    
2733     if (!fpreg)
2734     cpu->cd.ppc.gpr[rs] = tmp;
2735     else
2736     cpu->cd.ppc.fpr[rs] = tmp;
2737     }
2738     } else {
2739     if (!fpreg)
2740     tmp = cpu->cd.ppc.gpr[rs];
2741     else
2742     tmp = cpu->cd.ppc.fpr[rs];
2743    
2744     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2745     for (i=0; i<tmp_data_len; i++)
2746     tmp_data[tmp_data_len-1-i] =
2747     tmp >> (8*i);
2748     } else {
2749     for (i=0; i<tmp_data_len; i++)
2750     tmp_data[i] = tmp >> (8*i);
2751     }
2752    
2753     r = cpu->memory_rw(cpu, cpu->mem, addr, tmp_data,
2754     tmp_data_len, MEM_WRITE, CACHE_DATA);
2755     }
2756    
2757     if (cpu->machine->instruction_trace) {
2758     if (r == MEMORY_ACCESS_OK) {
2759     switch (tmp_data_len) {
2760     case 1: debug(", data = 0x%02x]\n", (int)tmp);
2761     break;
2762     case 2: debug(", data = 0x%04x]\n", (int)tmp);
2763     break;
2764     case 4: debug(", data = 0x%08x]\n", (int)tmp);
2765     break;
2766     default:debug(", data = 0x%016llx]\n",
2767     (long long)tmp);
2768     }
2769     } else
2770     debug(", FAILED]\n");
2771     }
2772    
2773     if (r != MEMORY_ACCESS_OK) {
2774     /* TODO: exception? */
2775     return 0;
2776     }
2777    
2778     if (update && ra != 0)
2779     cpu->cd.ppc.gpr[ra] = addr;
2780     break;
2781    
2782     case PPC_HI6_LMW:
2783     case PPC_HI6_STMW:
2784     /* NOTE: Loads use rt, not rs, but are otherwise similar
2785     to stores. This code uses rs for both. */
2786     rs = (iword >> 21) & 31;
2787     ra = (iword >> 16) & 31;
2788     imm = (int16_t)(iword & 0xffff);
2789    
2790     load = 1; tmp_data_len = 4;
2791    
2792     switch (hi6) {
2793     case PPC_HI6_STMW:
2794     load = 0;
2795     }
2796    
2797     if (ra == 0) {
2798     addr = 0;
2799     } else
2800     addr = cpu->cd.ppc.gpr[ra];
2801    
2802     if (load && rs == 0)
2803     fatal("[ PPC WARNING: invalid LMW form ]\n");
2804    
2805     addr += imm;
2806    
2807     /* TODO: alignment check? */
2808    
2809     if (cpu->machine->instruction_trace) {
2810     if (cpu->cd.ppc.bits == 32)
2811     debug("\t[0x%08llx", (long long)addr);
2812     else
2813     debug("\t[0x%016llx", (long long)addr);
2814     }
2815    
2816     /* There can be multiple errors! */
2817     r = 0;
2818    
2819     while (rs <= 31) {
2820     if (load) {
2821     if (cpu->memory_rw(cpu, cpu->mem, addr,
2822     tmp_data, tmp_data_len, MEM_READ,
2823     CACHE_DATA) != MEMORY_ACCESS_OK)
2824     r++;
2825    
2826     if (r == 0) {
2827     tmp = 0;
2828     if (cpu->byte_order ==
2829     EMUL_BIG_ENDIAN) {
2830     for (i=0; i<tmp_data_len; i++) {
2831     tmp <<= 8;
2832     tmp += tmp_data[i];
2833     }
2834     } else {
2835     for (i=0; i<tmp_data_len; i++) {
2836     tmp <<= 8;
2837     tmp += tmp_data[
2838     tmp_data_len - 1
2839     - i];
2840     }
2841     }
2842    
2843     cpu->cd.ppc.gpr[rs] = tmp;
2844     }
2845     } else {
2846     tmp = cpu->cd.ppc.gpr[rs];
2847    
2848     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2849     for (i=0; i<tmp_data_len; i++)
2850     tmp_data[tmp_data_len-1-i] =
2851     tmp >> (8*i);
2852     } else {
2853     for (i=0; i<tmp_data_len; i++)
2854     tmp_data[i] = tmp >> (8*i);
2855     }
2856    
2857     if (cpu->memory_rw(cpu, cpu->mem, addr,
2858     tmp_data, tmp_data_len, MEM_WRITE,
2859     CACHE_DATA) != MEMORY_ACCESS_OK)
2860     r ++;
2861     }
2862    
2863     /* TODO: Exception! */
2864    
2865     /* Go to next register, multiword... */
2866     rs ++;
2867     addr += tmp_data_len;
2868     }
2869    
2870     if (cpu->machine->instruction_trace) {
2871     if (r == 0) {
2872     debug(", data = ...]\n");
2873     } else
2874     debug(", FAILED]\n");
2875     }
2876    
2877     if (r > 0)
2878     return 0;
2879     break;
2880    
2881     default:
2882     fatal("[ unimplemented PPC hi6 = 0x%02x, pc = 0x%016llx ]\n",
2883     hi6, (long long) (cpu->cd.ppc.pc_last));
2884     cpu->running = 0;
2885     return 0;
2886     }
2887    
2888     return 1;
2889     }
2890    
2891    
2892     #define CPU_RUN ppc_cpu_run
2893     #define CPU_RINSTR ppc_cpu_run_instr
2894     #define CPU_RUN_PPC
2895     #include "cpu_run.c"
2896     #undef CPU_RINSTR
2897     #undef CPU_RUN_PPC
2898     #undef CPU_RUN
2899    
2900    
2901     #define MEMORY_RW ppc_memory_rw
2902     #define MEM_PPC
2903     #include "memory_rw.c"
2904     #undef MEM_PPC
2905     #undef MEMORY_RW
2906    
2907    
2908     /*
2909     * ppc_cpu_family_init():
2910     *
2911     * Fill in the cpu_family struct for PPC.
2912     */
2913     int ppc_cpu_family_init(struct cpu_family *fp)
2914     {
2915     fp->name = "PPC";
2916     fp->cpu_new = ppc_cpu_new;
2917     fp->list_available_types = ppc_cpu_list_available_types;
2918     fp->register_match = ppc_cpu_register_match;
2919     fp->disassemble_instr = ppc_cpu_disassemble_instr;
2920     fp->register_dump = ppc_cpu_register_dump;
2921     fp->run = ppc_cpu_run;
2922     fp->dumpinfo = ppc_cpu_dumpinfo;
2923     /* fp->show_full_statistics = ppc_cpu_show_full_statistics; */
2924     /* fp->tlbdump = ppc_cpu_tlbdump; */
2925     /* fp->interrupt = ppc_cpu_interrupt; */
2926     /* fp->interrupt_ack = ppc_cpu_interrupt_ack; */
2927     return 1;
2928     }
2929    
2930    
2931     #endif /* ENABLE_PPC */

  ViewVC Help
Powered by ViewVC 1.1.26