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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations)
Mon Oct 8 16:18:00 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 69460 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.707 2005/04/27 16:37:33 debug Exp $
20050408	Some minor updates to the wdc. Linux now doesn't complain
		anymore if a disk is non-present.
20050409	Various minor fixes (a bintrans bug, and some other things).
		The wdc seems to work with Playstation2 emulation, but there
		is a _long_ annoying delay when disks are detected.
		Fixing a really important bintrans bug (when devices and RAM
		are mixed within 4KB pages), which was triggered with
		NetBSD/playstation2 kernels.
20050410	Adding a dummy dev_ps2_ether (just so that NetBSD doesn't
		complain as much during bootup).
		Symbols starting with '$' are now ignored.
		Renaming dev_ps2_ohci.c to dev_ohci.c, etc.
20050411	Moving the bintrans-cache-isolation check from cpu_mips.c to
		cpu_mips_coproc.c. (I thought this would give a speedup, but
		it's not noticable.)
		Better playstation2 sbus interrupt code.
		Skip ahead many ticks if the count register is read manually.
		(This increases the speed of delay-loops that simply read
		the count register.)
20050412	Updates to the playstation2 timer/interrupt code.
		Some other minor updates.
20050413	NetBSD/cobalt runs from a disk image :-) including userland;
		updating the documentation on how to install NetBSD/cobalt
		using NetBSD/pmax (!).
		Some minor bintrans updates (no real speed improvement) and
		other minor updates (playstation2 now uses the -o options).
20050414	Adding a dummy x86 (and AMD64) mode.
20050415	Adding some (32-bit and 16-bit) x86 instructions.
		Adding some initial support for non-SCSI, non-IDE floppy
		images. (The x86 mode can boot from these, more or less.)
		Moving the devices/ and include/ directories to src/devices/
		and src/include/, respectively.
20050416	Continuing on the x86 stuff. (Adding pc_bios.c and some simple
		support for software interrupts in 16-bit mode.)
20050417	Ripping out most of the x86 instruction decoding stuff, trying
		to rewrite it in a cleaner way.
		Disabling some of the least working CPU families in the
		configure script (sparc, x86, alpha, hppa), so that they are
		not enabled by default.
20050418	Trying to fix the bug which caused problems when turning on
		and off bintrans interactively, by flushing the bintrans cache
		whenever bintrans is manually (re)enabled.
20050419	Adding the 'lswi' ppc instruction.
		Minor updates to the x86 instruction decoding.
20050420	Renaming x86 register name indices from R_xx to X86_R_xx (this
		makes building on Tru64 nicer).
20050422	Adding a check for duplicate MIPS TLB entries on tlbwr/tlbwi.
20050427	Adding screenshots to guestoses.html.
		Some minor fixes and testing for the next release.

==============  RELEASE 0.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