/[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 10 - (hide annotations)
Mon Oct 8 16:18:27 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 69237 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.815 2005/06/27 23:04:35 debug Exp $
20050617	Experimenting some more with netbooting OpenBSD/sgi. Adding
		a hack which allows emulated ethernet networks to be
		distributed across multiple emulator processes.
20050618	Minor updates (documentation, dummy YAMON emulation, etc).
20050620	strcpy/strcat -> strlcpy/strlcat updates.
		Some more progress on evbmips (Malta).
20050621	Adding a section to doc/configfiles.html about ethernet
		emulation across multiple hosts.
		Beginning the work on the ARM translation engine (using the
		dynamic-but-not-binary translation method).
		Fixing a bintrans bug: 0x9fc00000 should always be treated as
		PROM area, just as 0xbfc00000 is.
		Minor progress on Malta emulation (the PCI-ISA bus).
20050622	NetBSD/evbmips can now be installed (using another emulated
		machine) and run (including userland and so on). :-)
		Spliting up the bintrans haddr_entry field into two (one for
		read, one for write). Probably not much of a speed increase,
		though.
		Updating some NetBSD 2.0 -> 2.0.2 in the documentation.
20050623	Minor updates (documentation, the TODO file, etc).
		gzipped kernels are now always automagically gunzipped when
		loaded.
20050624	Adding a dummy Playstation Portable (PSP) mode, just barely
		enough to run Hello World (in weird colors :-).
		Removing the -b command line option; old bintrans is enabled
		by default instead. It makes more sense.
		Trying to finally fix the non-working performance measurement
		thing (instr/second etc).
20050625	Continuing on the essential basics for ARM emulation. Two
		instructions seem to work, a branch and a simple "mov". (The
		mov arguments are not correct yet.) Performance is definitely
		reasonable.
		Various other minor updates.
		Adding the ARM "bl" instruction.
		Adding support for combining multiple ARM instructions into one
		function call. ("mov" + "mov" is the only one implemented so
		far, but it seems to work.)
		Cleaning up some IP32 interrupt things (crime/mace); disabling
		the PS/2 keyboard controller on IP32, so that NetBSD/sgimips
		boots into userland again.
20050626	Finally! NetBSD/sgimips netboots. Adding instructions to
		doc/guestoses.html on how to set up an nfs server etc.
		Various other minor fixes.
		Playstation Portable ".pbp" files can now be used directly.
		(The ELF part of the .pbp is extracted transparently.)
		Converting some sprintf -> snprintf.
		Adding some more instructions to the ARM disassembler.
20050627	More ARM updates. Adding some simple ldr(b), str(b),
		cmps, and conditional branch instructions, enough to run
		a simple Hello World program.
		All ARM instructions are now inlined/generated for all possible
		condition codes.
		Adding add and sub, and more load/store instructions.
		Removing dummy files: cpu_alpha.c, cpu_hppa.c, and cpu_sparc.c.
		Some minor documentation updates; preparing for a 0.3.4
		release. Updating some URLs.

==============  RELEASE 0.3.4  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26