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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 38 - (hide annotations)
Mon Oct 8 16:21:53 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 49511 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1515 2007/04/14 05:39:46 debug Exp $
20070324	Adding a "--debug" option to the configure script, to disable
		optimizations in unstable development builds.
		Moving out SCSI-specific stuff from diskimage.c into a new
		diskimage_scsicmd.c.
		Applying Hĺvard Eidnes' patch for SCSICDROM_READ_DISKINFO and
		SCSICDROM_READ_TRACKINFO. (Not really tested yet.)
		Implementing disk image "overlays" (to allow simple roll-back
		to previous disk state). Adding a 'V' disk flag for this, and
		updating the man page and misc.html.
20070325	Stability fix to cpu_dyntrans.c, when multiple physical pages
		share the same initial table entry. (The ppp == NULL check
		should be physpage_ofs == 0.) Bug found by analysing GXemul
		against a version patched for Godson.
		Fixing a second occurance of the same problem (also in
		cpu_dyntrans.c).
		Fixing a MAJOR physical page leak in cpu_dyntrans.c; pages
		weren't _added_ to the set of translated pages, they _replaced_
		all previous pages. It's amazing that this bug has been able
		to live for this long. (Triggered when emulating >128MB RAM.)
20070326	Removing the GDB debugging stub support; it was too hackish
		and ugly.
20070328	Moving around some native code generation skeleton code.
20070329	The -lm check in the configure script now also checks for sin()
		in addition to sqrt(). (Thanks to Nigel Horne for noticing that
		sqrt was not enough on Fedora Core 6.) (Not verified yet.)
20070330	Fixing an indexing bug in dev_sh4.c, found by using gcc version
		4.3.0 20070323.
20070331	Some more experimentation with native code generation.
20070404	Attempting to fix some more SH4 SCIF interrupt bugs; rewriting
		the SH interrupt assertion/deassertion code somewhat.
20070410	Splitting src/file.c into separate files in src/file/.
		Cleanup: Removing the dummy TS7200, Walnut, PB1000, and
		Meshcube emulation modes, and dev_epcom and dev_au1x00.
		Removing the experimental CHIP8/RCA180x code; it wasn't really
		working much lately, anyway. It was fun while it lasted.
		Also removing the experimental Transputer CPU support.
20070412	Moving the section about how the dynamic translation system
		works from intro.html to a separate translation.html file.
		Minor SH fixes; attempting to get OpenBSD/landisk to run
		without randomly bugging out, but no success yet.
20070413	SH SCI (serial bit interface) should now work together with a
		(new) RS5C313 clock device (for Landisk emulation).
20070414	Moving Redhat/MIPS down from supported to experimental, in
		guestoses.html.
		Preparing for a new release; doing some regression testing etc.

==============  RELEASE 0.4.5  ==============


1 dpavlin 14 /*
2 dpavlin 34 * Copyright (C) 2005-2007 Anders Gavare. All rights reserved.
3 dpavlin 14 *
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 38 * $Id: cpu_ppc.c,v 1.68 2007/03/26 02:01:36 debug Exp $
29 dpavlin 14 *
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 "cpu.h"
39     #include "devices.h"
40 dpavlin 34 #include "interrupt.h"
41 dpavlin 14 #include "machine.h"
42     #include "memory.h"
43     #include "misc.h"
44 dpavlin 22 #include "of.h"
45 dpavlin 14 #include "opcodes_ppc.h"
46 dpavlin 20 #include "ppc_bat.h"
47     #include "ppc_pte.h"
48     #include "ppc_spr.h"
49     #include "ppc_spr_strings.h"
50 dpavlin 32 #include "settings.h"
51 dpavlin 14 #include "symbol.h"
52    
53     #define DYNTRANS_DUALMODE_32
54     #include "tmp_ppc_head.c"
55    
56    
57 dpavlin 20 void ppc_pc_to_pointers(struct cpu *);
58     void ppc32_pc_to_pointers(struct cpu *);
59    
60 dpavlin 34 void ppc_irq_interrupt_assert(struct interrupt *interrupt);
61     void ppc_irq_interrupt_deassert(struct interrupt *interrupt);
62 dpavlin 20
63 dpavlin 34
64 dpavlin 14 /*
65     * ppc_cpu_new():
66     *
67     * Create a new PPC cpu object.
68     *
69     * Returns 1 on success, 0 if there was no matching PPC processor with
70     * this cpu_type_name.
71     */
72     int ppc_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
73     int cpu_id, char *cpu_type_name)
74     {
75     int any_cache = 0;
76     int i, found;
77     struct ppc_cpu_type_def cpu_type_defs[] = PPC_CPU_TYPE_DEFS;
78    
79     /* Scan the cpu_type_defs list for this cpu type: */
80     i = 0;
81     found = -1;
82     while (i >= 0 && cpu_type_defs[i].name != NULL) {
83     if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
84     found = i;
85     break;
86     }
87     i++;
88     }
89     if (found == -1)
90     return 0;
91    
92     cpu->memory_rw = ppc_memory_rw;
93    
94 dpavlin 32 cpu->cd.ppc.cpu_type = cpu_type_defs[found];
95     cpu->name = cpu->cd.ppc.cpu_type.name;
96     cpu->byte_order = EMUL_BIG_ENDIAN;
97     cpu->cd.ppc.mode = MODE_PPC; /* TODO */
98 dpavlin 14
99     /* Current operating mode: */
100     cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;
101 dpavlin 20 cpu->cd.ppc.spr[SPR_PVR] = cpu->cd.ppc.cpu_type.pvr;
102 dpavlin 14
103 dpavlin 24 /* cpu->cd.ppc.msr = PPC_MSR_IR | PPC_MSR_DR |
104     PPC_MSR_SF | PPC_MSR_FP; */
105    
106 dpavlin 22 cpu->cd.ppc.spr[SPR_IBAT0U] = 0x00001ffc | BAT_Vs;
107     cpu->cd.ppc.spr[SPR_IBAT0L] = 0x00000000 | BAT_PP_RW;
108     cpu->cd.ppc.spr[SPR_IBAT1U] = 0xc0001ffc | BAT_Vs;
109     cpu->cd.ppc.spr[SPR_IBAT1L] = 0x00000000 | BAT_PP_RW;
110     cpu->cd.ppc.spr[SPR_IBAT3U] = 0xf0001ffc | BAT_Vs;
111     cpu->cd.ppc.spr[SPR_IBAT3L] = 0xf0000000 | BAT_PP_RW;
112     cpu->cd.ppc.spr[SPR_DBAT0U] = 0x00001ffc | BAT_Vs;
113     cpu->cd.ppc.spr[SPR_DBAT0L] = 0x00000000 | BAT_PP_RW;
114     cpu->cd.ppc.spr[SPR_DBAT1U] = 0xc0001ffc | BAT_Vs;
115     cpu->cd.ppc.spr[SPR_DBAT1L] = 0x00000000 | BAT_PP_RW;
116     cpu->cd.ppc.spr[SPR_DBAT2U] = 0xe0001ffc | BAT_Vs;
117     cpu->cd.ppc.spr[SPR_DBAT2L] = 0xe0000000 | BAT_PP_RW;
118     cpu->cd.ppc.spr[SPR_DBAT3U] = 0xf0001ffc | BAT_Vs;
119     cpu->cd.ppc.spr[SPR_DBAT3L] = 0xf0000000 | BAT_PP_RW;
120    
121 dpavlin 14 cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;
122    
123     if (cpu->is_32bit) {
124 dpavlin 28 cpu->run_instr = ppc32_run_instr;
125 dpavlin 14 cpu->update_translation_table = ppc32_update_translation_table;
126 dpavlin 18 cpu->invalidate_translation_caches =
127     ppc32_invalidate_translation_caches;
128 dpavlin 14 cpu->invalidate_code_translation =
129     ppc32_invalidate_code_translation;
130     } else {
131 dpavlin 28 cpu->run_instr = ppc_run_instr;
132 dpavlin 14 cpu->update_translation_table = ppc_update_translation_table;
133 dpavlin 18 cpu->invalidate_translation_caches =
134     ppc_invalidate_translation_caches;
135 dpavlin 14 cpu->invalidate_code_translation =
136     ppc_invalidate_code_translation;
137     }
138    
139 dpavlin 26 cpu->translate_v2p = ppc_translate_v2p;
140 dpavlin 14
141     /* Only show name and caches etc for CPU nr 0 (in SMP machines): */
142     if (cpu_id == 0) {
143     debug("%s", cpu->cd.ppc.cpu_type.name);
144    
145     if (cpu->cd.ppc.cpu_type.icache_shift != 0)
146     any_cache = 1;
147     if (cpu->cd.ppc.cpu_type.dcache_shift != 0)
148     any_cache = 1;
149     if (cpu->cd.ppc.cpu_type.l2cache_shift != 0)
150     any_cache = 1;
151    
152     if (any_cache) {
153     debug(" (I+D = %i+%i KB",
154     (int)(1 << (cpu->cd.ppc.cpu_type.icache_shift-10)),
155     (int)(1 << (cpu->cd.ppc.cpu_type.dcache_shift-10)));
156     if (cpu->cd.ppc.cpu_type.l2cache_shift != 0) {
157     debug(", L2 = %i KB",
158     (int)(1 << (cpu->cd.ppc.cpu_type.
159     l2cache_shift-10)));
160     }
161     debug(")");
162     }
163     }
164    
165 dpavlin 20 cpu->cd.ppc.spr[SPR_PIR] = cpu_id;
166 dpavlin 14
167     /* Some default stack pointer value. TODO: move this? */
168     cpu->cd.ppc.gpr[1] = machine->physical_ram_in_mb * 1048576 - 4096;
169    
170     /*
171     * NOTE/TODO: Ugly hack for OpenFirmware emulation:
172     */
173     if (cpu->machine->prom_emulation)
174     cpu->cd.ppc.of_emul_addr = 0xfff00000;
175    
176 dpavlin 32 /* Add all register names to the settings: */
177     CPU_SETTINGS_ADD_REGISTER64("pc", cpu->pc);
178     CPU_SETTINGS_ADD_REGISTER64("msr", cpu->cd.ppc.msr);
179     CPU_SETTINGS_ADD_REGISTER64("ctr", cpu->cd.ppc.spr[SPR_CTR]);
180     CPU_SETTINGS_ADD_REGISTER64("xer", cpu->cd.ppc.spr[SPR_XER]);
181     CPU_SETTINGS_ADD_REGISTER64("dec", cpu->cd.ppc.spr[SPR_DEC]);
182     CPU_SETTINGS_ADD_REGISTER64("hdec", cpu->cd.ppc.spr[SPR_HDEC]);
183     CPU_SETTINGS_ADD_REGISTER64("srr0", cpu->cd.ppc.spr[SPR_SRR0]);
184     CPU_SETTINGS_ADD_REGISTER64("srr1", cpu->cd.ppc.spr[SPR_SRR1]);
185     CPU_SETTINGS_ADD_REGISTER64("sdr1", cpu->cd.ppc.spr[SPR_SDR1]);
186     CPU_SETTINGS_ADD_REGISTER64("ibat0u", cpu->cd.ppc.spr[SPR_IBAT0U]);
187     CPU_SETTINGS_ADD_REGISTER64("ibat0l", cpu->cd.ppc.spr[SPR_IBAT0L]);
188     CPU_SETTINGS_ADD_REGISTER64("ibat1u", cpu->cd.ppc.spr[SPR_IBAT1U]);
189     CPU_SETTINGS_ADD_REGISTER64("ibat1l", cpu->cd.ppc.spr[SPR_IBAT1L]);
190     CPU_SETTINGS_ADD_REGISTER64("ibat2u", cpu->cd.ppc.spr[SPR_IBAT2U]);
191     CPU_SETTINGS_ADD_REGISTER64("ibat2l", cpu->cd.ppc.spr[SPR_IBAT2L]);
192     CPU_SETTINGS_ADD_REGISTER64("ibat3u", cpu->cd.ppc.spr[SPR_IBAT3U]);
193     CPU_SETTINGS_ADD_REGISTER64("ibat3l", cpu->cd.ppc.spr[SPR_IBAT3L]);
194     CPU_SETTINGS_ADD_REGISTER64("dbat0u", cpu->cd.ppc.spr[SPR_DBAT0U]);
195     CPU_SETTINGS_ADD_REGISTER64("dbat0l", cpu->cd.ppc.spr[SPR_DBAT0L]);
196     CPU_SETTINGS_ADD_REGISTER64("dbat1u", cpu->cd.ppc.spr[SPR_DBAT1U]);
197     CPU_SETTINGS_ADD_REGISTER64("dbat1l", cpu->cd.ppc.spr[SPR_DBAT1L]);
198     CPU_SETTINGS_ADD_REGISTER64("dbat2u", cpu->cd.ppc.spr[SPR_DBAT2U]);
199     CPU_SETTINGS_ADD_REGISTER64("dbat2l", cpu->cd.ppc.spr[SPR_DBAT2L]);
200     CPU_SETTINGS_ADD_REGISTER64("dbat3u", cpu->cd.ppc.spr[SPR_DBAT3U]);
201     CPU_SETTINGS_ADD_REGISTER64("dbat3l", cpu->cd.ppc.spr[SPR_DBAT3L]);
202     CPU_SETTINGS_ADD_REGISTER64("lr", cpu->cd.ppc.spr[SPR_LR]);
203     CPU_SETTINGS_ADD_REGISTER32("cr", cpu->cd.ppc.cr);
204     CPU_SETTINGS_ADD_REGISTER32("fpscr", cpu->cd.ppc.fpscr);
205     /* Integer GPRs, floating point registers, and segment registers: */
206     for (i=0; i<PPC_NGPRS; i++) {
207     char tmpstr[5];
208     snprintf(tmpstr, sizeof(tmpstr), "r%i", i);
209     CPU_SETTINGS_ADD_REGISTER64(tmpstr, cpu->cd.ppc.gpr[i]);
210     }
211     for (i=0; i<PPC_NFPRS; i++) {
212     char tmpstr[5];
213     snprintf(tmpstr, sizeof(tmpstr), "f%i", i);
214     CPU_SETTINGS_ADD_REGISTER64(tmpstr, cpu->cd.ppc.fpr[i]);
215     }
216     for (i=0; i<16; i++) {
217     char tmpstr[5];
218     snprintf(tmpstr, sizeof(tmpstr), "sr%i", i);
219     CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.ppc.sr[i]);
220     }
221    
222 dpavlin 34 /* Register the CPU as an interrupt handler: */
223     {
224     struct interrupt template;
225     char name[150];
226     snprintf(name, sizeof(name), "%s", cpu->path);
227     memset(&template, 0, sizeof(template));
228     template.line = 0;
229     template.name = name;
230     template.extra = cpu;
231     template.interrupt_assert = ppc_irq_interrupt_assert;
232     template.interrupt_deassert = ppc_irq_interrupt_deassert;
233     interrupt_handler_register(&template);
234     }
235    
236 dpavlin 14 return 1;
237     }
238    
239    
240     /*
241     * ppc_cpu_list_available_types():
242     *
243     * Print a list of available PPC CPU types.
244     */
245     void ppc_cpu_list_available_types(void)
246     {
247     int i, j;
248     struct ppc_cpu_type_def tdefs[] = PPC_CPU_TYPE_DEFS;
249    
250     i = 0;
251     while (tdefs[i].name != NULL) {
252     debug("%s", tdefs[i].name);
253     for (j=10 - strlen(tdefs[i].name); j>0; j--)
254     debug(" ");
255     i++;
256     if ((i % 6) == 0 || tdefs[i].name == NULL)
257     debug("\n");
258     }
259     }
260    
261    
262     /*
263     * ppc_cpu_dumpinfo():
264     */
265     void ppc_cpu_dumpinfo(struct cpu *cpu)
266     {
267     struct ppc_cpu_type_def *ct = &cpu->cd.ppc.cpu_type;
268    
269     debug(" (%i-bit ", cpu->cd.ppc.bits);
270    
271     switch (cpu->cd.ppc.mode) {
272     case MODE_PPC:
273     debug("PPC");
274     break;
275     case MODE_POWER:
276     debug("POWER");
277     break;
278     default:
279     debug("_INTERNAL ERROR_");
280     }
281    
282     debug(", I+D = %i+%i KB",
283     (1 << ct->icache_shift) / 1024,
284     (1 << ct->dcache_shift) / 1024);
285    
286     if (ct->l2cache_shift) {
287     int kb = (1 << ct->l2cache_shift) / 1024;
288     debug(", L2 = %i %cB",
289     kb >= 1024? kb / 1024 : kb,
290     kb >= 1024? 'M' : 'K');
291     }
292    
293     debug(")\n");
294     }
295    
296    
297     /*
298     * reg_access_msr():
299     */
300 dpavlin 20 void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag,
301     int check_for_interrupts)
302 dpavlin 14 {
303 dpavlin 20 uint64_t old = cpu->cd.ppc.msr;
304    
305 dpavlin 14 if (valuep == NULL) {
306     fatal("reg_access_msr(): NULL\n");
307     return;
308     }
309    
310 dpavlin 20 if (writeflag) {
311 dpavlin 14 cpu->cd.ppc.msr = *valuep;
312    
313 dpavlin 20 /* Switching between temporary and real gpr 0..3? */
314     if ((old & PPC_MSR_TGPR) != (cpu->cd.ppc.msr & PPC_MSR_TGPR)) {
315     int i;
316     for (i=0; i<PPC_N_TGPRS; i++) {
317     uint64_t t = cpu->cd.ppc.gpr[i];
318     cpu->cd.ppc.gpr[i] = cpu->cd.ppc.tgpr[i];
319     cpu->cd.ppc.tgpr[i] = t;
320     }
321     }
322    
323     if (cpu->cd.ppc.msr & PPC_MSR_IP) {
324     fatal("\n[ Reboot hack for NetBSD/prep. TODO: "
325     "fix this. ]\n");
326     cpu->running = 0;
327     }
328     }
329    
330 dpavlin 14 /* TODO: Is the little-endian bit writable? */
331    
332     cpu->cd.ppc.msr &= ~PPC_MSR_LE;
333     if (cpu->byte_order != EMUL_BIG_ENDIAN)
334     cpu->cd.ppc.msr |= PPC_MSR_LE;
335    
336     if (!writeflag)
337     *valuep = cpu->cd.ppc.msr;
338 dpavlin 20
339     if (check_for_interrupts && cpu->cd.ppc.msr & PPC_MSR_EE) {
340 dpavlin 30 if (cpu->cd.ppc.dec_intr_pending &&
341     !(cpu->cd.ppc.cpu_type.flags & PPC_NO_DEC)) {
342 dpavlin 20 ppc_exception(cpu, PPC_EXCEPTION_DEC);
343     cpu->cd.ppc.dec_intr_pending = 0;
344     } else if (cpu->cd.ppc.irq_asserted)
345     ppc_exception(cpu, PPC_EXCEPTION_EI);
346     }
347 dpavlin 14 }
348    
349    
350     /*
351 dpavlin 20 * ppc_exception():
352     */
353     void ppc_exception(struct cpu *cpu, int exception_nr)
354     {
355     /* Save PC and MSR: */
356     cpu->cd.ppc.spr[SPR_SRR0] = cpu->pc;
357    
358     if (exception_nr >= 0x10 && exception_nr <= 0x13)
359     cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0xffff)
360     | (cpu->cd.ppc.cr & 0xf0000000);
361     else
362     cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);
363    
364     if (!quiet_mode)
365 dpavlin 24 fatal("[ PPC Exception 0x%x; pc=0x%"PRIx64" ]\n", exception_nr,
366 dpavlin 20 (long long)cpu->pc);
367    
368     /* Disable External Interrupts, Recoverable Interrupt Mode,
369     and go to Supervisor mode */
370     cpu->cd.ppc.msr &= ~(PPC_MSR_EE | PPC_MSR_RI | PPC_MSR_PR);
371    
372     cpu->pc = exception_nr * 0x100;
373     if (cpu->cd.ppc.msr & PPC_MSR_IP)
374 dpavlin 22 cpu->pc += 0xfff00000ULL;
375 dpavlin 20
376     if (cpu->is_32bit)
377     ppc32_pc_to_pointers(cpu);
378     else
379     ppc_pc_to_pointers(cpu);
380     }
381    
382    
383     /*
384 dpavlin 14 * ppc_cpu_register_dump():
385     *
386     * Dump cpu registers in a relatively readable format.
387     *
388     * gprs: set to non-zero to dump GPRs and some special-purpose registers.
389     * coprocs: if bit i is set, then we should dump registers from coproc i.
390     */
391     void ppc_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
392     {
393     char *symbol;
394     uint64_t offset, tmp;
395     int i, x = cpu->cpu_id;
396     int bits32 = cpu->cd.ppc.bits == 32;
397    
398     if (gprs) {
399     /* Special registers (pc, ...) first: */
400     symbol = get_symbol_name(&cpu->machine->symbol_context,
401     cpu->pc, &offset);
402    
403     debug("cpu%i: pc = 0x", x);
404     if (bits32)
405 dpavlin 24 debug("%08"PRIx32, (uint32_t)cpu->pc);
406 dpavlin 14 else
407 dpavlin 24 debug("%016"PRIx64, (uint64_t)cpu->pc);
408 dpavlin 14 debug(" <%s>\n", symbol != NULL? symbol : " no symbol ");
409    
410     debug("cpu%i: lr = 0x", x);
411     if (bits32)
412 dpavlin 24 debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_LR]);
413 dpavlin 14 else
414 dpavlin 24 debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_LR]);
415     debug(" cr = 0x%08"PRIx32, (uint32_t)cpu->cd.ppc.cr);
416 dpavlin 14
417     if (bits32)
418 dpavlin 22 debug(" ");
419     else
420     debug("\ncpu%i: ", x);
421     debug("ctr = 0x", x);
422     if (bits32)
423 dpavlin 24 debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_CTR]);
424 dpavlin 14 else
425 dpavlin 24 debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_CTR]);
426 dpavlin 14
427     debug(" xer = 0x", x);
428     if (bits32)
429 dpavlin 24 debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_XER]);
430 dpavlin 14 else
431 dpavlin 24 debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_XER]);
432 dpavlin 14
433 dpavlin 24 debug("\n");
434    
435 dpavlin 14 if (bits32) {
436     /* 32-bit: */
437     for (i=0; i<PPC_NGPRS; i++) {
438     if ((i % 4) == 0)
439     debug("cpu%i:", x);
440     debug(" r%02i = 0x%08x ", i,
441     (int)cpu->cd.ppc.gpr[i]);
442     if ((i % 4) == 3)
443     debug("\n");
444     }
445     } else {
446     /* 64-bit: */
447     for (i=0; i<PPC_NGPRS; i++) {
448     int r = (i >> 1) + ((i & 1) << 4);
449     if ((i % 2) == 0)
450     debug("cpu%i:", x);
451     debug(" r%02i = 0x%016llx ", r,
452     (long long)cpu->cd.ppc.gpr[r]);
453     if ((i % 2) == 1)
454     debug("\n");
455     }
456     }
457    
458     /* Other special registers: */
459 dpavlin 22 if (bits32) {
460     debug("cpu%i: srr0 = 0x%08x srr1 = 0x%08x\n", x,
461     (int)cpu->cd.ppc.spr[SPR_SRR0],
462     (int)cpu->cd.ppc.spr[SPR_SRR1]);
463     } else {
464     debug("cpu%i: srr0 = 0x%016llx srr1 = 0x%016llx\n", x,
465     (long long)cpu->cd.ppc.spr[SPR_SRR0],
466     (long long)cpu->cd.ppc.spr[SPR_SRR1]);
467     }
468     debug("cpu%i: msr = ", x);
469 dpavlin 20 reg_access_msr(cpu, &tmp, 0, 0);
470 dpavlin 22 if (bits32)
471     debug("0x%08x ", (int)tmp);
472     else
473     debug("0x%016llx ", (long long)tmp);
474 dpavlin 20 debug("tb = 0x%08x%08x\n", (int)cpu->cd.ppc.spr[SPR_TBU],
475     (int)cpu->cd.ppc.spr[SPR_TBL]);
476 dpavlin 22 debug("cpu%i: dec = 0x%08x", x, (int)cpu->cd.ppc.spr[SPR_DEC]);
477     if (!bits32)
478     debug(" hdec = 0x%08x\n",
479     (int)cpu->cd.ppc.spr[SPR_HDEC]);
480     debug("\n");
481 dpavlin 14 }
482    
483     if (coprocs & 1) {
484     debug("cpu%i: fpscr = 0x%08x\n", x, (int)cpu->cd.ppc.fpscr);
485    
486     /* TODO: show floating-point values :-) */
487    
488     /* TODO: 32-bit fprs on 32-bit PPC cpus? */
489    
490     for (i=0; i<PPC_NFPRS; i++) {
491     if ((i % 2) == 0)
492     debug("cpu%i:", x);
493     debug(" f%02i = 0x%016llx ", i,
494     (long long)cpu->cd.ppc.fpr[i]);
495     if ((i % 2) == 1)
496     debug("\n");
497     }
498     }
499    
500     if (coprocs & 2) {
501     debug("cpu%i: sdr1 = 0x%llx\n", x,
502 dpavlin 20 (long long)cpu->cd.ppc.spr[SPR_SDR1]);
503     if (cpu->cd.ppc.cpu_type.flags & PPC_601)
504     debug("cpu%i: PPC601-style, TODO!\n");
505     else {
506     for (i=0; i<8; i++) {
507     int spr = SPR_IBAT0U + i*2;
508     uint32_t upper = cpu->cd.ppc.spr[spr];
509     uint32_t lower = cpu->cd.ppc.spr[spr+1];
510     uint32_t len = (((upper & BAT_BL) << 15)
511     | 0x1ffff) + 1;
512     debug("cpu%i: %sbat%i: u=0x%08x l=0x%08x ",
513     x, i<4? "i" : "d", i&3, upper, lower);
514     if (!(upper & BAT_V)) {
515     debug(" (not valid)\n");
516     continue;
517     }
518     if (len < 1048576)
519     debug(" (%i KB, ", len >> 10);
520     else
521     debug(" (%i MB, ", len >> 20);
522     if (upper & BAT_Vu)
523     debug("user, ");
524     if (upper & BAT_Vs)
525     debug("supervisor, ");
526     if (lower & (BAT_W | BAT_I | BAT_M | BAT_G))
527     debug("%s%s%s%s, ",
528     lower & BAT_W? "W" : "",
529     lower & BAT_I? "I" : "",
530     lower & BAT_M? "M" : "",
531     lower & BAT_G? "G" : "");
532     switch (lower & BAT_PP) {
533     case BAT_PP_NONE: debug("NO access"); break;
534     case BAT_PP_RO_S: debug("read-only, soft");
535     break;
536     case BAT_PP_RO: debug("read-only"); break;
537     case BAT_PP_RW: debug("read/write"); break;
538     }
539     debug(")\n");
540     }
541     }
542 dpavlin 14 }
543 dpavlin 20
544     if (coprocs & 4) {
545     for (i=0; i<16; i++) {
546     uint32_t s = cpu->cd.ppc.sr[i];
547     debug("cpu%i:", x);
548 dpavlin 32 debug(" sr%-2i = 0x%08x", i, (int)s);
549 dpavlin 20 s &= (SR_TYPE | SR_SUKEY | SR_PRKEY | SR_NOEXEC);
550     if (s != 0) {
551     debug(" (");
552     if (s & SR_TYPE) {
553     debug("NON-memory type");
554     s &= ~SR_TYPE;
555     if (s != 0)
556     debug(", ");
557     }
558     if (s & SR_SUKEY) {
559     debug("supervisor-key");
560     s &= ~SR_SUKEY;
561     if (s != 0)
562     debug(", ");
563     }
564     if (s & SR_PRKEY) {
565     debug("user-key");
566     s &= ~SR_PRKEY;
567     if (s != 0)
568     debug(", ");
569     }
570     if (s & SR_NOEXEC)
571     debug("NOEXEC");
572     debug(")");
573     }
574     debug("\n");
575     }
576     }
577 dpavlin 14 }
578    
579    
580     /*
581 dpavlin 24 * ppc_cpu_tlbdump():
582     *
583     * Not currently used for PPC.
584     */
585     void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)
586     {
587     }
588    
589    
590     /*
591 dpavlin 34 * ppc_irq_interrupt_assert():
592 dpavlin 14 */
593 dpavlin 34 void ppc_irq_interrupt_assert(struct interrupt *interrupt)
594 dpavlin 14 {
595 dpavlin 34 struct cpu *cpu = (struct cpu *) interrupt->extra;
596     cpu->cd.ppc.irq_asserted = 1;
597 dpavlin 14 }
598    
599    
600     /*
601 dpavlin 34 * ppc_irq_interrupt_deassert():
602 dpavlin 14 */
603 dpavlin 34 void ppc_irq_interrupt_deassert(struct interrupt *interrupt)
604 dpavlin 14 {
605 dpavlin 34 struct cpu *cpu = (struct cpu *) interrupt->extra;
606     cpu->cd.ppc.irq_asserted = 0;
607 dpavlin 14 }
608    
609    
610     /*
611     * ppc_cpu_disassemble_instr():
612     *
613     * Convert an instruction word into human readable format, for instruction
614     * tracing.
615     *
616     * If running is 1, cpu->pc should be the address of the instruction.
617     *
618     * If running is 0, things that depend on the runtime environment (eg.
619     * register contents) will not be shown, and addr will be used instead of
620     * cpu->pc for relative addresses.
621     */
622     int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
623 dpavlin 24 int running, uint64_t dumpaddr)
624 dpavlin 14 {
625     int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;
626     int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;
627     int bfa, to, load, wlen, no_rb = 0;
628     uint64_t offset, addr;
629     uint32_t iword;
630     char *symbol, *mnem = "ERROR";
631     int power = cpu->cd.ppc.mode == MODE_POWER;
632    
633     if (running)
634     dumpaddr = cpu->pc;
635    
636     symbol = get_symbol_name(&cpu->machine->symbol_context,
637     dumpaddr, &offset);
638     if (symbol != NULL && offset==0)
639     debug("<%s>\n", symbol);
640    
641     if (cpu->machine->ncpus > 1 && running)
642     debug("cpu%i: ", cpu->cpu_id);
643    
644     if (cpu->cd.ppc.bits == 32)
645     debug("%08x", (int)dumpaddr);
646     else
647     debug("%016llx", (long long)dumpaddr);
648    
649     /* NOTE: Fixed to big-endian. */
650     iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
651     + instr[3];
652    
653     debug(": %08x\t", iword);
654    
655     /*
656     * Decode the instruction:
657     */
658    
659     hi6 = iword >> 26;
660    
661     switch (hi6) {
662 dpavlin 22 case 0x4:
663     debug("ALTIVEC TODO");
664     /* vxor etc */
665     break;
666 dpavlin 14 case PPC_HI6_MULLI:
667     case PPC_HI6_SUBFIC:
668     rt = (iword >> 21) & 31;
669     ra = (iword >> 16) & 31;
670     imm = (int16_t)(iword & 0xffff);
671     switch (hi6) {
672     case PPC_HI6_MULLI:
673     mnem = power? "muli":"mulli";
674     break;
675     case PPC_HI6_SUBFIC:
676     mnem = power? "sfi":"subfic";
677     break;
678     }
679     debug("%s\tr%i,r%i,%i", mnem, rt, ra, imm);
680     break;
681     case PPC_HI6_CMPLI:
682     case PPC_HI6_CMPI:
683     bf = (iword >> 23) & 7;
684     l_bit = (iword >> 21) & 1;
685     ra = (iword >> 16) & 31;
686     if (hi6 == PPC_HI6_CMPLI) {
687     imm = iword & 0xffff;
688     mnem = "cmpl";
689     } else {
690     imm = (int16_t)(iword & 0xffff);
691     mnem = "cmp";
692     }
693     debug("%s%si\t", mnem, l_bit? "d" : "w");
694     if (bf != 0)
695     debug("cr%i,", bf);
696     debug("r%i,%i", ra, imm);
697     break;
698     case PPC_HI6_ADDIC:
699     case PPC_HI6_ADDIC_DOT:
700     rt = (iword >> 21) & 31;
701     ra = (iword >> 16) & 31;
702     rc = hi6 == PPC_HI6_ADDIC_DOT;
703     imm = (int16_t)(iword & 0xffff);
704     mnem = power? "ai":"addic";
705     if (imm < 0 && !power) {
706     mnem = "subic";
707     imm = -imm;
708     }
709     debug("%s%s\tr%i,r%i,%i", mnem, rc?".":"", rt, ra, imm);
710     break;
711     case PPC_HI6_ADDI:
712     rt = (iword >> 21) & 31;
713     ra = (iword >> 16) & 31;
714     imm = (int16_t)(iword & 0xffff);
715     if (ra == 0)
716     debug("li\tr%i,%i", rt, imm);
717     else {
718     mnem = power? "cal":"addi";
719     if (imm < 0 && !power) {
720     mnem = "subi";
721     imm = -imm;
722     }
723     debug("%s\tr%i,r%i,%i", mnem, rt, ra, imm);
724     }
725     break;
726     case PPC_HI6_ADDIS:
727     rt = (iword >> 21) & 31;
728     ra = (iword >> 16) & 31;
729     imm = (int16_t)(iword & 0xffff);
730     if (ra == 0)
731     debug("lis\tr%i,%i", rt, imm);
732     else
733     debug("%s\tr%i,r%i,%i",
734     power? "cau":"addis", rt, ra, imm);
735     break;
736     case PPC_HI6_BC:
737     aa_bit = (iword & 2) >> 1;
738     lk_bit = iword & 1;
739     bo = (iword >> 21) & 31;
740     bi = (iword >> 16) & 31;
741     /* Sign-extend addr: */
742     addr = (int64_t)(int16_t)(iword & 0xfffc);
743     debug("bc");
744     if (lk_bit)
745     debug("l");
746     if (aa_bit)
747     debug("a");
748     else
749     addr += dumpaddr;
750     debug("\t%i,%i,", bo, bi);
751     if (cpu->cd.ppc.bits == 32)
752     addr &= 0xffffffff;
753     if (cpu->cd.ppc.bits == 32)
754     debug("0x%x", (int)addr);
755     else
756     debug("0x%llx", (long long)addr);
757     symbol = get_symbol_name(&cpu->machine->symbol_context,
758     addr, &offset);
759     if (symbol != NULL)
760     debug("\t<%s>", symbol);
761     break;
762     case PPC_HI6_SC:
763     lev = (iword >> 5) & 0x7f;
764     debug("sc");
765     if (lev != 0) {
766     debug("\t%i", lev);
767     if (lev > 1)
768     debug(" (WARNING! reserved value)");
769     }
770     break;
771     case PPC_HI6_B:
772     aa_bit = (iword & 2) >> 1;
773     lk_bit = iword & 1;
774     /* Sign-extend addr: */
775     addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
776     addr = (int64_t)addr >> 6;
777     debug("b");
778     if (lk_bit)
779     debug("l");
780     if (aa_bit)
781     debug("a");
782     else
783     addr += dumpaddr;
784     if (cpu->cd.ppc.bits == 32)
785     addr &= 0xffffffff;
786     if (cpu->cd.ppc.bits == 32)
787     debug("\t0x%x", (int)addr);
788     else
789     debug("\t0x%llx", (long long)addr);
790     symbol = get_symbol_name(&cpu->machine->symbol_context,
791     addr, &offset);
792     if (symbol != NULL)
793     debug("\t<%s>", symbol);
794     break;
795     case PPC_HI6_19:
796     xo = (iword >> 1) & 1023;
797     switch (xo) {
798     case PPC_19_MCRF:
799     bf = (iword >> 23) & 7;
800     bfa = (iword >> 18) & 7;
801     debug("mcrf\tcr%i,cr%i", bf, bfa);
802     break;
803     case PPC_19_RFI:
804     debug("rfi");
805     break;
806     case PPC_19_RFID:
807     debug("rfid");
808     break;
809     case PPC_19_RFSVC:
810     debug("rfsvc%s", power?"":"\t(INVALID for PowerPC)");
811     break;
812     case PPC_19_BCLR:
813     case PPC_19_BCCTR:
814     bo = (iword >> 21) & 31;
815     bi = (iword >> 16) & 31;
816     bh = (iword >> 11) & 3;
817     lk_bit = iword & 1;
818     switch (xo) {
819     case PPC_19_BCLR:
820     mnem = power? "bcr" : "bclr"; break;
821     case PPC_19_BCCTR:
822     mnem = power? "bcc" : "bcctr"; break;
823     }
824     debug("%s%s%s\t%i,%i,%i", mnem, lk_bit? "l" : "",
825     bh? (bh==3? "+" : (bh==2? "-" : "?")) : "",
826     bo, bi, bh);
827     break;
828     case PPC_19_ISYNC:
829     debug("%s", power? "ics" : "isync");
830     break;
831     case PPC_19_CRAND:
832     case PPC_19_CRXOR:
833     case PPC_19_CROR:
834     case PPC_19_CRNAND:
835     case PPC_19_CRNOR:
836     case PPC_19_CRANDC:
837     case PPC_19_CREQV:
838     case PPC_19_CRORC:
839     bt = (iword >> 21) & 31;
840     ba = (iword >> 16) & 31;
841     bb = (iword >> 11) & 31;
842     switch (xo) {
843     case PPC_19_CRAND: mnem = "crand"; break;
844     case PPC_19_CRXOR: mnem = "crxor"; break;
845     case PPC_19_CROR: mnem = "cror"; break;
846     case PPC_19_CRNAND: mnem = "crnand"; break;
847     case PPC_19_CRNOR: mnem = "crnor"; break;
848     case PPC_19_CRANDC: mnem = "crandc"; break;
849     case PPC_19_CREQV: mnem = "creqv"; break;
850     case PPC_19_CRORC: mnem = "crorc"; break;
851     }
852     debug("%s\t%i,%i,%i", mnem, bt, ba, bb);
853     break;
854     default:
855     debug("unimplemented hi6_19, xo = 0x%x", xo);
856     }
857     break;
858 dpavlin 20 case PPC_HI6_RLWNM:
859 dpavlin 14 case PPC_HI6_RLWIMI:
860     case PPC_HI6_RLWINM:
861     rs = (iword >> 21) & 31;
862     ra = (iword >> 16) & 31;
863 dpavlin 20 sh = (iword >> 11) & 31; /* actually rb for rlwnm */
864 dpavlin 14 mb = (iword >> 6) & 31;
865     me = (iword >> 1) & 31;
866     rc = iword & 1;
867     switch (hi6) {
868 dpavlin 20 case PPC_HI6_RLWNM:
869     mnem = power? "rlnm" : "rlwnm"; break;
870 dpavlin 14 case PPC_HI6_RLWIMI:
871     mnem = power? "rlimi" : "rlwimi"; break;
872     case PPC_HI6_RLWINM:
873     mnem = power? "rlinm" : "rlwinm"; break;
874     }
875 dpavlin 20 debug("%s%s\tr%i,r%i,%s%i,%i,%i",
876     mnem, rc?".":"", ra, rs,
877     hi6 == PPC_HI6_RLWNM? "r" : "",
878     sh, mb, me);
879 dpavlin 14 break;
880     case PPC_HI6_ORI:
881     case PPC_HI6_ORIS:
882     case PPC_HI6_XORI:
883     case PPC_HI6_XORIS:
884     case PPC_HI6_ANDI_DOT:
885     case PPC_HI6_ANDIS_DOT:
886     rs = (iword >> 21) & 31;
887     ra = (iword >> 16) & 31;
888     imm = iword & 0xffff;
889     switch (hi6) {
890     case PPC_HI6_ORI:
891     mnem = power? "oril":"ori";
892     break;
893     case PPC_HI6_ORIS:
894     mnem = power? "oriu":"oris";
895     break;
896     case PPC_HI6_XORI:
897     mnem = power? "xoril":"xori";
898     break;
899     case PPC_HI6_XORIS:
900     mnem = power? "xoriu":"xoris";
901     break;
902     case PPC_HI6_ANDI_DOT:
903     mnem = power? "andil.":"andi.";
904     break;
905     case PPC_HI6_ANDIS_DOT:
906     mnem = power? "andiu.":"andis.";
907     break;
908     }
909     if (hi6 == PPC_HI6_ORI && rs == 0 && ra == 0 && imm == 0)
910     debug("nop");
911     else
912     debug("%s\tr%i,r%i,0x%04x", mnem, ra, rs, imm);
913     break;
914     case PPC_HI6_30:
915     xo = (iword >> 2) & 7;
916     switch (xo) {
917 dpavlin 24 case PPC_30_RLDICL:
918 dpavlin 14 case PPC_30_RLDICR:
919 dpavlin 24 case PPC_30_RLDIMI: /* mb, not me */
920     mnem = NULL;
921     switch (xo) {
922     case PPC_30_RLDICL: mnem = "rldicl"; break;
923     case PPC_30_RLDICR: mnem = "rldicr"; break;
924     case PPC_30_RLDIMI: mnem = "rldimi"; break;
925     }
926 dpavlin 14 rs = (iword >> 21) & 31;
927     ra = (iword >> 16) & 31;
928     sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
929     me = ((iword >> 6) & 31) | (iword & 0x20);
930     rc = iword & 1;
931 dpavlin 24 debug("%s%s\tr%i,r%i,%i,%i",
932     mnem, rc?".":"", ra, rs, sh, me);
933 dpavlin 14 break;
934     default:
935     debug("unimplemented hi6_30, xo = 0x%x", xo);
936     }
937     break;
938     case PPC_HI6_31:
939     xo = (iword >> 1) & 1023;
940     switch (xo) {
941    
942     case PPC_31_CMP:
943     case PPC_31_CMPL:
944     bf = (iword >> 23) & 7;
945     l_bit = (iword >> 21) & 1;
946     ra = (iword >> 16) & 31;
947     rb = (iword >> 11) & 31;
948     if (xo == PPC_31_CMPL)
949     mnem = "cmpl";
950     else
951     mnem = "cmp";
952     debug("%s%s\t", mnem, l_bit? "d" : "w");
953     if (bf != 0)
954     debug("cr%i,", bf);
955     debug("r%i,r%i", ra, rb);
956     break;
957     case PPC_31_MFCR:
958     rt = (iword >> 21) & 31;
959     debug("mfcr\tr%i", rt);
960     break;
961     case PPC_31_MFMSR:
962     rt = (iword >> 21) & 31;
963     debug("mfmsr\tr%i", rt);
964     break;
965     case PPC_31_MTCRF:
966     rs = (iword >> 21) & 31;
967     mb = (iword >> 12) & 255; /* actually fxm, not mb */
968     debug("mtcrf\t%i,r%i", mb, rs);
969     break;
970     case PPC_31_MTMSR:
971     rs = (iword >> 21) & 31;
972     l_bit = (iword >> 16) & 1;
973     debug("mtmsr\tr%i", rs);
974     if (l_bit)
975     debug(",%i", l_bit);
976     break;
977     case PPC_31_TW:
978     case PPC_31_TD:
979     to = (iword >> 21) & 31;
980     ra = (iword >> 16) & 31;
981     rb = (iword >> 11) & 31;
982     switch (xo) {
983     case PPC_31_TW: mnem = power? "t" : "tw"; break;
984     case PPC_31_TD: mnem = "td"; break;
985     }
986     debug("%s\t%i,r%i,r%i", mnem, to, ra, rb);
987     break;
988     case PPC_31_LWARX:
989     case PPC_31_LDARX:
990     case PPC_31_LBZX:
991     case PPC_31_LBZUX:
992 dpavlin 20 case PPC_31_LHAX:
993     case PPC_31_LHAUX:
994 dpavlin 14 case PPC_31_LHZX:
995     case PPC_31_LHZUX:
996     case PPC_31_LWZX:
997     case PPC_31_LWZUX:
998 dpavlin 20 case PPC_31_LHBRX:
999     case PPC_31_LWBRX:
1000     case PPC_31_LFDX:
1001     case PPC_31_LFSX:
1002 dpavlin 14 case PPC_31_STWCX_DOT:
1003     case PPC_31_STDCX_DOT:
1004     case PPC_31_STBX:
1005     case PPC_31_STBUX:
1006     case PPC_31_STHX:
1007     case PPC_31_STHUX:
1008     case PPC_31_STWX:
1009     case PPC_31_STWUX:
1010     case PPC_31_STDX:
1011     case PPC_31_STDUX:
1012 dpavlin 20 case PPC_31_STHBRX:
1013     case PPC_31_STWBRX:
1014     case PPC_31_STFDX:
1015     case PPC_31_STFSX:
1016 dpavlin 14 /* rs for stores, rt for loads, actually */
1017 dpavlin 20 load = 0; wlen = 0; fpreg = 0;
1018 dpavlin 14 rs = (iword >> 21) & 31;
1019     ra = (iword >> 16) & 31;
1020     rb = (iword >> 11) & 31;
1021     switch (xo) {
1022     case PPC_31_LWARX: wlen=4;load=1; mnem = "lwarx"; break;
1023     case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;
1024     case PPC_31_LBZX: wlen=1;load=1; mnem = "lbzx"; break;
1025     case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;
1026 dpavlin 20 case PPC_31_LHAX: wlen=2;load=1; mnem = "lhax"; break;
1027     case PPC_31_LHAUX: wlen=2;load=1; mnem = "lhaux"; break;
1028 dpavlin 14 case PPC_31_LHZX: wlen=2;load=1; mnem = "lhzx"; break;
1029     case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;
1030     case PPC_31_LWZX: wlen = 4; load = 1;
1031     mnem = power? "lx" : "lwzx";
1032     break;
1033     case PPC_31_LWZUX: wlen = 4; load = 1;
1034     mnem = power? "lux":"lwzux";
1035     break;
1036 dpavlin 20 case PPC_31_LFDX: fpreg = 1; wlen = 8; load = 1;
1037     mnem = "lfdx"; break;
1038     case PPC_31_LFSX: fpreg = 1; wlen = 4; load = 1;
1039     mnem = "lfsx"; break;
1040 dpavlin 14 case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;
1041     case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;
1042     case PPC_31_STBX: wlen=1; mnem = "stbx"; break;
1043     case PPC_31_STBUX: wlen=1; mnem = "stbux"; break;
1044     case PPC_31_STHX: wlen=2; mnem = "sthx"; break;
1045     case PPC_31_STHUX: wlen=2; mnem = "sthux"; break;
1046     case PPC_31_STWX:
1047     wlen = 4; mnem = power? "stx" : "stwx";
1048     break;
1049     case PPC_31_STWUX:
1050     wlen = 4; mnem = power? "stux" : "stwux";
1051     break;
1052     case PPC_31_STDX: wlen = 8; mnem = "stdx"; break;
1053     case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;
1054 dpavlin 20 case PPC_31_LHBRX: wlen = 2; mnem = "lhbrx"; break;
1055     case PPC_31_LWBRX: wlen = 4; mnem = power?
1056     "lbrx" : "lwbrx"; break;
1057     case PPC_31_STHBRX: wlen = 2; mnem = "sthbrx"; break;
1058     case PPC_31_STWBRX: wlen = 4; mnem = power?
1059     "stbrx" : "stwbrx"; break;
1060     case PPC_31_STFDX: fpreg = 1; wlen = 8;
1061     mnem = "stfdx"; break;
1062     case PPC_31_STFSX: fpreg = 1; wlen = 4;
1063     mnem = "stfsx"; break;
1064 dpavlin 14 }
1065 dpavlin 20 debug("%s\t%s%i,r%i,r%i", mnem,
1066     fpreg? "f" : "r", rs, ra, rb);
1067 dpavlin 14 if (!running)
1068     break;
1069     addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +
1070     cpu->cd.ppc.gpr[rb];
1071 dpavlin 20 if (cpu->cd.ppc.bits == 32)
1072     addr &= 0xffffffff;
1073 dpavlin 14 symbol = get_symbol_name(&cpu->machine->symbol_context,
1074     addr, &offset);
1075     if (symbol != NULL)
1076     debug(" \t<%s", symbol);
1077     else
1078     debug(" \t<0x%llx", (long long)addr);
1079 dpavlin 20 if (wlen > 0 && !fpreg /* && !reverse */) {
1080 dpavlin 14 /* TODO */
1081     }
1082     debug(">");
1083     break;
1084     case PPC_31_NEG:
1085     case PPC_31_NEGO:
1086     rt = (iword >> 21) & 31;
1087     ra = (iword >> 16) & 31;
1088     oe_bit = (iword >> 10) & 1;
1089     rc = iword & 1;
1090     switch (xo) {
1091     case PPC_31_NEG: mnem = "neg"; break;
1092     case PPC_31_NEGO: mnem = "nego"; break;
1093     }
1094     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1095     break;
1096 dpavlin 22 case PPC_31_WRTEEI:
1097     debug("wrteei\t%i", iword & 0x8000? 1 : 0);
1098     break;
1099 dpavlin 24 case PPC_31_MTMSRD:
1100     /* TODO: Just a guess based on MTMSR */
1101     rs = (iword >> 21) & 31;
1102     l_bit = (iword >> 16) & 1;
1103     debug("mtmsrd\tr%i", rs);
1104     if (l_bit)
1105     debug(",%i", l_bit);
1106     break;
1107 dpavlin 14 case PPC_31_ADDZE:
1108     case PPC_31_ADDZEO:
1109     rt = (iword >> 21) & 31;
1110     ra = (iword >> 16) & 31;
1111     oe_bit = (iword >> 10) & 1;
1112     rc = iword & 1;
1113     switch (xo) {
1114     case PPC_31_ADDZE:
1115     mnem = power? "aze" : "addze";
1116     break;
1117     case PPC_31_ADDZEO:
1118     mnem = power? "azeo" : "addzeo";
1119     break;
1120     }
1121     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1122     break;
1123     case PPC_31_MTSR:
1124 dpavlin 20 case PPC_31_MFSR:
1125     /* Move to/from segment register */
1126 dpavlin 14 rt = (iword >> 21) & 31;
1127     ra = (iword >> 16) & 15; /* actually: sr */
1128 dpavlin 20 switch (xo) {
1129     case PPC_31_MTSR: mnem = "mtsr"; break;
1130     case PPC_31_MFSR: mnem = "mfsr"; break;
1131     }
1132     debug("%s\tr%i,%i", mnem, rt, ra);
1133 dpavlin 14 break;
1134     case PPC_31_MTSRIN:
1135     case PPC_31_MFSRIN:
1136     /* Move to/from segment register indirect */
1137     rt = (iword >> 21) & 31;
1138     rb = (iword >> 11) & 31;
1139     switch (xo) {
1140     case PPC_31_MTSRIN: mnem = "mtsrin"; break;
1141     case PPC_31_MFSRIN: mnem = "mfsrin"; break;
1142     }
1143     debug("%s\tr%i,r%i", mnem, rt, rb);
1144     break;
1145     case PPC_31_ADDC:
1146     case PPC_31_ADDCO:
1147     case PPC_31_ADDE:
1148     case PPC_31_ADDEO:
1149     case PPC_31_ADDME:
1150     case PPC_31_ADDMEO:
1151     case PPC_31_ADD:
1152     case PPC_31_ADDO:
1153     case PPC_31_MULHW:
1154     case PPC_31_MULHWU:
1155     case PPC_31_MULLW:
1156     case PPC_31_MULLWO:
1157     case PPC_31_SUBF:
1158     case PPC_31_SUBFO:
1159     case PPC_31_SUBFC:
1160     case PPC_31_SUBFCO:
1161     case PPC_31_SUBFE:
1162     case PPC_31_SUBFEO:
1163 dpavlin 20 case PPC_31_SUBFME:
1164     case PPC_31_SUBFMEO:
1165 dpavlin 14 case PPC_31_SUBFZE:
1166     case PPC_31_SUBFZEO:
1167     rt = (iword >> 21) & 31;
1168     ra = (iword >> 16) & 31;
1169     rb = (iword >> 11) & 31;
1170     oe_bit = (iword >> 10) & 1;
1171     rc = iword & 1;
1172     switch (xo) {
1173     case PPC_31_ADDC:
1174     mnem = power? "a" : "addc";
1175     break;
1176     case PPC_31_ADDCO:
1177     mnem = power? "ao" : "addco";
1178     break;
1179     case PPC_31_ADDE:
1180     mnem = power? "ae" : "adde";
1181     break;
1182     case PPC_31_ADDEO:
1183     mnem = power? "aeo" : "addeo";
1184     break;
1185     case PPC_31_ADDME:
1186     mnem = power? "ame" : "addme";
1187     no_rb = 1;
1188     break;
1189     case PPC_31_ADDMEO:
1190     mnem = power? "ameo" : "addmeo";
1191     no_rb = 1;
1192     break;
1193     case PPC_31_ADD:
1194     mnem = power? "cax" : "add";
1195     break;
1196     case PPC_31_ADDO:
1197     mnem = power? "caxo" : "addo";
1198     break;
1199     case PPC_31_MULHW: mnem = "mulhw"; break;
1200     case PPC_31_MULHWU: mnem = "mulhwu"; break;
1201     case PPC_31_MULLW:
1202     mnem = power? "muls" : "mullw";
1203     break;
1204     case PPC_31_MULLWO:
1205     mnem = power? "mulso" : "mullwo";
1206     break;
1207     case PPC_31_SUBF: mnem = "subf"; break;
1208     case PPC_31_SUBFO: mnem = "subfo"; break;
1209     case PPC_31_SUBFC:
1210 dpavlin 20 mnem = power? "sf" : "subfc"; break;
1211 dpavlin 14 case PPC_31_SUBFCO:
1212 dpavlin 20 mnem = power? "sfo" : "subfco"; break;
1213 dpavlin 14 case PPC_31_SUBFE:
1214 dpavlin 20 mnem = power? "sfe" : "subfe"; break;
1215 dpavlin 14 case PPC_31_SUBFEO:
1216 dpavlin 20 mnem = power? "sfeo" : "subfeo"; break;
1217     case PPC_31_SUBFME:
1218     mnem = power? "sfme" : "subfme"; break;
1219     case PPC_31_SUBFMEO:
1220     mnem = power? "sfmeo" : "subfmeo"; break;
1221 dpavlin 14 case PPC_31_SUBFZE:
1222     mnem = power? "sfze" : "subfze";
1223     no_rb = 1;
1224     break;
1225     case PPC_31_SUBFZEO:
1226     mnem = power? "sfzeo" : "subfzeo";
1227     no_rb = 1;
1228     break;
1229     }
1230     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1231     if (!no_rb)
1232     debug(",r%i", rb);
1233     break;
1234     case PPC_31_MFSPR:
1235     rt = (iword >> 21) & 31;
1236     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1237     switch (spr) {
1238 dpavlin 20 /* Some very common ones: */
1239 dpavlin 14 case 8: debug("mflr\tr%i", rt); break;
1240     case 9: debug("mfctr\tr%i", rt); break;
1241     default:debug("mfspr\tr%i,spr%i", rt, spr);
1242     }
1243 dpavlin 20 if (spr == 8 || spr == 9)
1244     debug("\t");
1245     debug("\t<%s%s", running? "read from " : "",
1246     ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1247     if (running) {
1248     if (cpu->cd.ppc.bits == 32)
1249     debug(": 0x%x", (int)
1250     cpu->cd.ppc.spr[spr]);
1251     else
1252     debug(": 0x%llx", (long long)
1253     cpu->cd.ppc.spr[spr]);
1254     }
1255     debug(">");
1256 dpavlin 14 break;
1257 dpavlin 20 case PPC_31_TLBIA:
1258     debug("tlbia");
1259     break;
1260     case PPC_31_SLBIA:
1261     debug("slbia");
1262     break;
1263     case PPC_31_TLBLD:
1264     case PPC_31_TLBLI:
1265     rb = (iword >> 11) & 31;
1266     debug("tlbl%s\tr%i", xo == PPC_31_TLBLD? "d" : "i", rb);
1267     break;
1268 dpavlin 14 case PPC_31_TLBIE:
1269     /* TODO: what is ra? The IBM online docs didn't say */
1270     ra = 0;
1271     rb = (iword >> 11) & 31;
1272     if (power)
1273     debug("tlbi\tr%i,r%i", ra, rb);
1274     else
1275     debug("tlbie\tr%i", rb);
1276     break;
1277 dpavlin 22 case PPC_31_TLBSX_DOT:
1278     rs = (iword >> 21) & 31;
1279     ra = (iword >> 16) & 31;
1280     rb = (iword >> 11) & 31;
1281     debug("tlbsx.\tr%i,r%i,r%i", rs, ra, rb);
1282     break;
1283 dpavlin 14 case PPC_31_TLBSYNC:
1284     debug("tlbsync");
1285     break;
1286     case PPC_31_MFTB:
1287     rt = (iword >> 21) & 31;
1288     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1289     debug("mftb%s\tr%i", spr==268? "" :
1290     (spr==269? "u" : "?"), rt);
1291     break;
1292     case PPC_31_CNTLZW:
1293     rs = (iword >> 21) & 31;
1294     ra = (iword >> 16) & 31;
1295     rc = iword & 1;
1296     mnem = power? "cntlz" : "cntlzw";
1297     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1298     break;
1299     case PPC_31_CLF: /* POWER only */
1300     case PPC_31_CLI: /* POWER only */
1301     case PPC_31_DCLST: /* POWER only */
1302     case PPC_31_DCBF: /* PowerPC only */
1303     case PPC_31_DCBI: /* PowerPC only */
1304     case PPC_31_DCBST: /* PowerPC only */
1305     case PPC_31_DCBTST: /* PowerPC only */
1306     case PPC_31_DCBT: /* PowerPC only */
1307     case PPC_31_ICBI: /* PowerPC only */
1308     case PPC_31_DCBZ: /* POWER/PowerPC */
1309     ra = (iword >> 16) & 31;
1310     rb = (iword >> 11) & 31;
1311     switch (xo) {
1312     case PPC_31_CLF: mnem = "clf"; break;
1313     case PPC_31_CLI: mnem = "cli"; break;
1314     case PPC_31_DCLST: mnem = "dclst"; break;
1315     case PPC_31_DCBF: mnem = "dcbf"; break;
1316     case PPC_31_DCBI: mnem = "dcbi"; break;
1317     case PPC_31_DCBST: mnem = "dcbst"; break;
1318     case PPC_31_DCBTST:mnem = "dcbtst"; break;
1319     case PPC_31_DCBT: mnem = "dcbt"; break;
1320     case PPC_31_ICBI: mnem = "icbi"; break;
1321     case PPC_31_DCBZ: mnem = power ?
1322     "dclz" : "dcbz"; break;
1323     }
1324     debug("%s\tr%i,r%i", mnem, ra, rb);
1325     break;
1326     case PPC_31_SLW:
1327 dpavlin 24 case PPC_31_SLD:
1328 dpavlin 14 case PPC_31_SRAW:
1329     case PPC_31_SRW:
1330     case PPC_31_AND:
1331     case PPC_31_ANDC:
1332     case PPC_31_NOR:
1333 dpavlin 24 case PPC_31_EQV:
1334 dpavlin 14 case PPC_31_OR:
1335     case PPC_31_ORC:
1336     case PPC_31_XOR:
1337     case PPC_31_NAND:
1338     rs = (iword >> 21) & 31;
1339     ra = (iword >> 16) & 31;
1340     rb = (iword >> 11) & 31;
1341     rc = iword & 1;
1342     if (rs == rb && xo == PPC_31_OR)
1343     debug("mr%s\tr%i,r%i", rc? "." : "", ra, rs);
1344     else {
1345     switch (xo) {
1346     case PPC_31_SLW: mnem =
1347     power? "sl" : "slw"; break;
1348 dpavlin 24 case PPC_31_SLD: mnem = "sld"; break;
1349 dpavlin 14 case PPC_31_SRAW: mnem =
1350     power? "sra" : "sraw"; break;
1351     case PPC_31_SRW: mnem =
1352     power? "sr" : "srw"; break;
1353     case PPC_31_AND: mnem = "and"; break;
1354     case PPC_31_NAND: mnem = "nand"; break;
1355     case PPC_31_ANDC: mnem = "andc"; break;
1356     case PPC_31_NOR: mnem = "nor"; break;
1357 dpavlin 24 case PPC_31_EQV: mnem = "eqv"; break;
1358 dpavlin 14 case PPC_31_OR: mnem = "or"; break;
1359     case PPC_31_ORC: mnem = "orc"; break;
1360     case PPC_31_XOR: mnem = "xor"; break;
1361     }
1362     debug("%s%s\tr%i,r%i,r%i", mnem,
1363     rc? "." : "", ra, rs, rb);
1364     }
1365     break;
1366     case PPC_31_DCCCI:
1367     ra = (iword >> 16) & 31;
1368     rb = (iword >> 11) & 31;
1369     debug("dccci\tr%i,r%i", ra, rb);
1370     break;
1371     case PPC_31_ICCCI:
1372     ra = (iword >> 16) & 31;
1373     rb = (iword >> 11) & 31;
1374     debug("iccci\tr%i,r%i", ra, rb);
1375     break;
1376     case PPC_31_DIVW:
1377     case PPC_31_DIVWO:
1378     case PPC_31_DIVWU:
1379     case PPC_31_DIVWUO:
1380     rt = (iword >> 21) & 31;
1381     ra = (iword >> 16) & 31;
1382     rb = (iword >> 11) & 31;
1383     oe_bit = (iword >> 10) & 1;
1384     rc = iword & 1;
1385     switch (xo) {
1386     case PPC_31_DIVWU: mnem = "divwu"; break;
1387     case PPC_31_DIVWUO: mnem = "divwuo"; break;
1388     case PPC_31_DIVW: mnem = "divw"; break;
1389     case PPC_31_DIVWO: mnem = "divwo"; break;
1390     }
1391     debug("%s%s\tr%i,r%i,r%i", mnem, rc? "." : "",
1392     rt, ra, rb);
1393     break;
1394     case PPC_31_MTSPR:
1395     rs = (iword >> 21) & 31;
1396     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1397     switch (spr) {
1398 dpavlin 20 /* Some very common ones: */
1399 dpavlin 14 case 8: debug("mtlr\tr%i", rs); break;
1400     case 9: debug("mtctr\tr%i", rs); break;
1401     default:debug("mtspr\tspr%i,r%i", spr, rs);
1402     }
1403 dpavlin 20 if (spr == 8 || spr == 9)
1404     debug("\t");
1405     debug("\t<%s%s", running? "write to " : "",
1406     ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1407     if (running) {
1408     if (cpu->cd.ppc.bits == 32)
1409     debug(": 0x%x", (int)
1410     cpu->cd.ppc.gpr[rs]);
1411     else
1412     debug(": 0x%llx", (long long)
1413     cpu->cd.ppc.gpr[rs]);
1414     }
1415     debug(">");
1416 dpavlin 14 break;
1417     case PPC_31_SYNC:
1418     debug("%s", power? "dcs" : "sync");
1419     break;
1420     case PPC_31_LSWI:
1421     case PPC_31_STSWI:
1422     rs = (iword >> 21) & 31; /* lwsi uses rt */
1423     ra = (iword >> 16) & 31;
1424     nb = (iword >> 11) & 31;
1425     switch (xo) {
1426     case PPC_31_LSWI:
1427     mnem = power? "lsi" : "lswi"; break;
1428     case PPC_31_STSWI:
1429     mnem = power? "stsi" : "stswi"; break;
1430     }
1431     debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);
1432     break;
1433     case PPC_31_SRAWI:
1434     rs = (iword >> 21) & 31;
1435     ra = (iword >> 16) & 31;
1436     sh = (iword >> 11) & 31;
1437     rc = iword & 1;
1438     mnem = power? "srai" : "srawi";
1439     debug("%s%s\tr%i,r%i,%i", mnem,
1440     rc? "." : "", ra, rs, sh);
1441     break;
1442 dpavlin 24 case PPC_31_DSSALL:
1443     debug("dssall");
1444     break;
1445 dpavlin 14 case PPC_31_EIEIO:
1446     debug("%s", power? "eieio?" : "eieio");
1447     break;
1448     case PPC_31_EXTSB:
1449     case PPC_31_EXTSH:
1450     case PPC_31_EXTSW:
1451     rs = (iword >> 21) & 31;
1452     ra = (iword >> 16) & 31;
1453     rc = iword & 1;
1454     switch (xo) {
1455     case PPC_31_EXTSB:
1456     mnem = power? "exts" : "extsb";
1457     break;
1458     case PPC_31_EXTSH:
1459     mnem = "extsh";
1460     break;
1461     case PPC_31_EXTSW:
1462     mnem = "extsw";
1463     break;
1464     }
1465     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1466     break;
1467 dpavlin 22 case PPC_31_LVX:
1468 dpavlin 24 case PPC_31_LVXL:
1469 dpavlin 22 case PPC_31_STVX:
1470     case PPC_31_STVXL:
1471 dpavlin 24 rs = (iword >> 21) & 31; /* vs for stores, */
1472     ra = (iword >> 16) & 31; /* rs=vl for loads */
1473     rb = (iword >> 11) & 31;
1474     rc = iword & 1;
1475     switch (xo) {
1476     case PPC_31_LVX: mnem = "lvx"; break;
1477     case PPC_31_LVXL: mnem = "lvxl"; break;
1478     case PPC_31_STVX: mnem = "stvx"; break;
1479     case PPC_31_STVXL: mnem = "stvxl"; break;
1480     }
1481     debug("%s%s\tv%i,r%i,r%i", mnem, rc? "." : "",
1482     rs, ra, rb);
1483 dpavlin 22 break;
1484 dpavlin 14 default:
1485     debug("unimplemented hi6_31, xo = 0x%x", xo);
1486     }
1487     break;
1488 dpavlin 20 case PPC_HI6_LD:
1489 dpavlin 14 case PPC_HI6_LWZ:
1490     case PPC_HI6_LWZU:
1491     case PPC_HI6_LHZ:
1492     case PPC_HI6_LHZU:
1493     case PPC_HI6_LHA:
1494     case PPC_HI6_LHAU:
1495     case PPC_HI6_LBZ:
1496     case PPC_HI6_LBZU:
1497 dpavlin 20 case PPC_HI6_LFD:
1498     case PPC_HI6_LFS:
1499 dpavlin 14 case PPC_HI6_LMW:
1500 dpavlin 20 case PPC_HI6_STD:
1501 dpavlin 14 case PPC_HI6_STW:
1502     case PPC_HI6_STWU:
1503     case PPC_HI6_STH:
1504     case PPC_HI6_STHU:
1505     case PPC_HI6_STB:
1506     case PPC_HI6_STBU:
1507     case PPC_HI6_STMW:
1508     case PPC_HI6_STFD:
1509 dpavlin 20 case PPC_HI6_STFS:
1510 dpavlin 14 /* NOTE: Loads use rt, not rs, but are otherwise similar
1511     to stores */
1512     load = 0; wlen = 0;
1513     rs = (iword >> 21) & 31;
1514     ra = (iword >> 16) & 31;
1515     imm = (int16_t)(iword & 0xffff);
1516     fpreg = 0;
1517     switch (hi6) {
1518 dpavlin 20 case PPC_HI6_LD: load=1; wlen = 8; mnem = "ld"; break;
1519 dpavlin 14 case PPC_HI6_LWZ: load=1; wlen = 4;
1520     mnem = power? "l" : "lwz"; break;
1521     case PPC_HI6_LWZU: load=1; wlen = 4;
1522     mnem = power? "lu" : "lwzu"; break;
1523     case PPC_HI6_LHZ: load=1; wlen = 2;
1524     mnem = "lhz"; break;
1525     case PPC_HI6_LHZU: load=1; wlen = 2;
1526     mnem = "lhzu"; break;
1527     case PPC_HI6_LHA: load=2; wlen = 2;
1528     mnem = "lha"; break;
1529     case PPC_HI6_LHAU: load=2; wlen = 2;
1530     mnem = "lhau"; break;
1531     case PPC_HI6_LBZ: load=1; wlen = 1;
1532     mnem = "lbz"; break;
1533     case PPC_HI6_LBZU: load=1; wlen = 1;
1534     mnem = "lbzu"; break;
1535 dpavlin 20 case PPC_HI6_LFD: load=1; fpreg=1; wlen=8; mnem = "lfd"; break;
1536     case PPC_HI6_LFS: load=1; fpreg=1; wlen=4; mnem = "lfs"; break;
1537     case PPC_HI6_STD: wlen=8; mnem = "std"; break;
1538 dpavlin 14 case PPC_HI6_STW: wlen=4; mnem = power? "st" : "stw"; break;
1539     case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;
1540     case PPC_HI6_STH: wlen=2; mnem = "sth"; break;
1541     case PPC_HI6_STHU: wlen=2; mnem = "sthu"; break;
1542     case PPC_HI6_STB: wlen=1; mnem = "stb"; break;
1543     case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;
1544     case PPC_HI6_LMW: load=1; mnem = power? "lm" : "lmw"; break;
1545     case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1546 dpavlin 20 case PPC_HI6_STFD: fpreg=1; wlen=8; mnem = "stfd"; break;
1547     case PPC_HI6_STFS: fpreg=1; wlen=4; mnem = "stfs"; break;
1548 dpavlin 14 }
1549     debug("%s\t", mnem);
1550     if (fpreg)
1551     debug("f");
1552     else
1553     debug("r");
1554     debug("%i,%i(r%i)", rs, imm, ra);
1555     if (!running)
1556     break;
1557     addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;
1558 dpavlin 20 if (cpu->cd.ppc.bits == 32)
1559     addr &= 0xffffffff;
1560 dpavlin 14 symbol = get_symbol_name(&cpu->machine->symbol_context,
1561     addr, &offset);
1562     if (symbol != NULL)
1563     debug(" \t<%s", symbol);
1564     else
1565     debug(" \t<0x%llx", (long long)addr);
1566     if (wlen > 0 && load && wlen > 0) {
1567     unsigned char tw[8];
1568     uint64_t tdata = 0;
1569     int i, res = cpu->memory_rw(cpu, cpu->mem, addr, tw,
1570     wlen, MEM_READ, NO_EXCEPTIONS);
1571     if (res) {
1572     if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1573     for (i=0; i<wlen; i++) {
1574     tdata <<= 8;
1575     tdata |= tw[wlen-1-i];
1576     }
1577     else
1578     for (i=0; i<wlen; i++) {
1579     tdata <<= 8;
1580     tdata |= tw[i];
1581     }
1582     debug(": ");
1583     if (wlen >= 4) {
1584     symbol = get_symbol_name(&cpu->machine->
1585     symbol_context, tdata, &offset);
1586     if (symbol != NULL)
1587     debug("%s", symbol);
1588     else
1589     debug("0x%llx",
1590     (long long)tdata);
1591     } else {
1592     /* TODO: if load==2, then this is
1593     a _signed_ load. */
1594     debug("0x%llx", (long long)tdata);
1595     }
1596     } else
1597     debug(": unreadable");
1598     }
1599     if (wlen > 0 && !load && wlen > 0) {
1600     int64_t tdata = 0;
1601     int i;
1602     for (i=0; i<wlen; i++)
1603     tdata |= (cpu->cd.ppc.gpr[rs] &
1604 dpavlin 20 ((uint64_t)0xff << (i*8)));
1605 dpavlin 14 debug(": ");
1606     if (wlen >= 4) {
1607     symbol = get_symbol_name(&cpu->machine->
1608     symbol_context, tdata, &offset);
1609     if (symbol != NULL)
1610     debug("%s", symbol);
1611     else
1612 dpavlin 20 debug("0x%llx", (long long)tdata);
1613 dpavlin 14 } else {
1614     if (tdata > -256 && tdata < 256)
1615     debug("%i", (int)tdata);
1616     else
1617     debug("0x%llx", (long long)tdata);
1618     }
1619     }
1620     debug(">");
1621     break;
1622 dpavlin 20 case PPC_HI6_59:
1623     xo = (iword >> 1) & 1023;
1624     /* NOTE: Some floating point instructions only use the
1625     lowest 5 bits of xo, some use all 10 bits! */
1626     switch (xo & 31) {
1627     case PPC_59_FDIVS:
1628     case PPC_59_FSUBS:
1629     case PPC_59_FADDS:
1630     case PPC_59_FMULS:
1631     case PPC_59_FMADDS:
1632     rt = (iword >> 21) & 31;
1633     ra = (iword >> 16) & 31;
1634     rb = (iword >> 11) & 31;
1635     rs = (iword >> 6) & 31; /* actually frc */
1636     rc = iword & 1;
1637     switch (xo & 31) {
1638     case PPC_59_FDIVS: mnem = "fdivs"; break;
1639     case PPC_59_FSUBS: mnem = "fsubs"; break;
1640     case PPC_59_FADDS: mnem = "fadds"; break;
1641     case PPC_59_FMULS: mnem = "fmuls"; break;
1642     case PPC_59_FMADDS: mnem = "fmadds"; break;
1643     }
1644     debug("%s%s\t", mnem, rc? "." : "");
1645     switch (xo & 31) {
1646     case PPC_59_FMULS:
1647     debug("f%i,f%i,f%i", rt, ra, rs);
1648     break;
1649     case PPC_59_FMADDS:
1650     debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1651     break;
1652     default:debug("f%i,f%i,f%i", rt, ra, rb);
1653     }
1654     break;
1655     default:/* TODO: similar to hi6_63 */
1656     debug("unimplemented hi6_59, xo = 0x%x", xo);
1657     }
1658     break;
1659 dpavlin 14 case PPC_HI6_63:
1660     xo = (iword >> 1) & 1023;
1661 dpavlin 20 /* NOTE: Some floating point instructions only use the
1662     lowest 5 bits of xo, some use all 10 bits! */
1663     switch (xo & 31) {
1664     case PPC_63_FDIV:
1665     case PPC_63_FSUB:
1666     case PPC_63_FADD:
1667     case PPC_63_FMUL:
1668     case PPC_63_FMSUB:
1669     case PPC_63_FMADD:
1670 dpavlin 14 rt = (iword >> 21) & 31;
1671     ra = (iword >> 16) & 31;
1672     rb = (iword >> 11) & 31;
1673 dpavlin 20 rs = (iword >> 6) & 31; /* actually frc */
1674 dpavlin 14 rc = iword & 1;
1675 dpavlin 20 switch (xo & 31) {
1676     case PPC_63_FDIV:
1677     mnem = power? "fd" : "fdiv"; break;
1678     case PPC_63_FSUB:
1679     mnem = power? "fs" : "fsub"; break;
1680     case PPC_63_FADD:
1681     mnem = power? "fa" : "fadd"; break;
1682     case PPC_63_FMUL:
1683     mnem = power? "fm" : "fmul"; break;
1684     case PPC_63_FMSUB:
1685     mnem = power? "fms" : "fmsub"; break;
1686     case PPC_63_FMADD:
1687     mnem = power? "fma" : "fmadd"; break;
1688     }
1689     debug("%s%s\t", mnem, rc? "." : "");
1690     switch (xo & 31) {
1691     case PPC_63_FMUL:
1692     debug("f%i,f%i,f%i", rt, ra, rs);
1693     break;
1694     case PPC_63_FMADD:
1695     debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1696     break;
1697     default:debug("f%i,f%i,f%i", rt, ra, rb);
1698     }
1699     break;
1700     default:rt = (iword >> 21) & 31;
1701     ra = (iword >> 16) & 31;
1702     rb = (iword >> 11) & 31;
1703     rc = iword & 1;
1704 dpavlin 14 switch (xo) {
1705 dpavlin 20 case PPC_63_FCMPU:
1706     case PPC_63_FRSP:
1707     case PPC_63_FCTIWZ:
1708     case PPC_63_FNEG:
1709 dpavlin 14 case PPC_63_FMR:
1710 dpavlin 20 case PPC_63_FNABS:
1711     case PPC_63_FABS:
1712     switch (xo) {
1713     case PPC_63_FCMPU: mnem = "fcmpu"; break;
1714     case PPC_63_FCTIWZ:
1715     mnem = power? "fcirz" : "fctiwz"; break;
1716     case PPC_63_FRSP: mnem = "frsp"; break;
1717     case PPC_63_FNEG: mnem = "fneg"; break;
1718     case PPC_63_FMR: mnem = "fmr"; break;
1719     case PPC_63_FNABS: mnem = "fnabs"; break;
1720     case PPC_63_FABS: mnem = "fabs"; break;
1721     }
1722     debug("%s%s\t", mnem, rc? "." : "");
1723     switch (xo) {
1724     case PPC_63_FCMPU:
1725     debug("%i,f%i,f%i", rt >> 2, ra, rb);
1726     break;
1727     case PPC_63_FCTIWZ:
1728     case PPC_63_FRSP:
1729     case PPC_63_FNEG:
1730     case PPC_63_FMR:
1731     case PPC_63_FNABS:
1732     case PPC_63_FABS:
1733     debug("f%i,f%i", rt, rb);
1734     break;
1735     default:debug("f%i,f%i,f%i", rt, ra, rb);
1736     }
1737 dpavlin 14 break;
1738 dpavlin 20 case PPC_63_MFFS:
1739     debug("mffs%s\tf%i", rc?".":"", rt);
1740     break;
1741     case PPC_63_MTFSF:
1742     ra = (iword >> 17) & 255; /* flm */
1743     debug("mtfsf%s\t0x%02x,f%i", rc?".":"", ra, rb);
1744     break;
1745     default:debug("unimplemented hi6_63, xo = 0x%x", xo);
1746 dpavlin 14 }
1747     }
1748     break;
1749     default:
1750     /* TODO */
1751     debug("unimplemented hi6 = 0x%02x", hi6);
1752     }
1753    
1754     debug("\n");
1755     return sizeof(iword);
1756     }
1757    
1758    
1759     /*
1760 dpavlin 20 * debug_spr_usage():
1761     *
1762     * Helper function. To speed up overall development speed of the emulator,
1763     * all SPR accesses are allowed. This function causes unknown/unimplemented
1764     * SPRs to give a warning.
1765     */
1766     static void debug_spr_usage(uint64_t pc, int spr)
1767     {
1768     static uint32_t spr_used[1024 / sizeof(uint32_t)];
1769     static int initialized = 0;
1770    
1771     if (!initialized) {
1772     memset(spr_used, 0, sizeof(spr_used));
1773     initialized = 1;
1774     }
1775    
1776     spr &= 1023;
1777     if (spr_used[spr >> 2] & (1 << (spr & 3)))
1778     return;
1779    
1780     switch (spr) {
1781     /* Known/implemented SPRs: */
1782     case SPR_XER:
1783     case SPR_LR:
1784     case SPR_CTR:
1785     case SPR_DSISR:
1786     case SPR_DAR:
1787     case SPR_DEC:
1788     case SPR_SDR1:
1789     case SPR_SRR0:
1790     case SPR_SRR1:
1791     case SPR_SPRG0:
1792     case SPR_SPRG1:
1793     case SPR_SPRG2:
1794     case SPR_SPRG3:
1795     case SPR_PVR:
1796     case SPR_DMISS:
1797     case SPR_DCMP:
1798     case SPR_HASH1:
1799     case SPR_HASH2:
1800     case SPR_IMISS:
1801     case SPR_ICMP:
1802     case SPR_DBSR:
1803     case SPR_PIR:
1804     break;
1805     default:if (spr >= SPR_IBAT0U && spr <= SPR_DBAT3L) {
1806     break;
1807     } else
1808     fatal("[ using UNIMPLEMENTED spr %i (%s), pc = "
1809     "0x%llx ]\n", spr, ppc_spr_names[spr] == NULL?
1810     "UNKNOWN" : ppc_spr_names[spr], (long long)pc);
1811     }
1812    
1813     spr_used[spr >> 2] |= (1 << (spr & 3));
1814     }
1815    
1816    
1817     /*
1818 dpavlin 14 * update_cr0():
1819     *
1820     * Sets the top 4 bits of the CR register.
1821     */
1822     void update_cr0(struct cpu *cpu, uint64_t value)
1823     {
1824     int c;
1825    
1826     if (cpu->cd.ppc.bits == 64) {
1827     if ((int64_t)value < 0)
1828     c = 8;
1829     else if ((int64_t)value > 0)
1830     c = 4;
1831     else
1832     c = 2;
1833     } else {
1834     if ((int32_t)value < 0)
1835     c = 8;
1836     else if ((int32_t)value > 0)
1837     c = 4;
1838     else
1839     c = 2;
1840     }
1841    
1842     /* SO bit, copied from XER: */
1843 dpavlin 20 c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
1844 dpavlin 14
1845     cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1846     cpu->cd.ppc.cr |= ((uint32_t)c << 28);
1847     }
1848    
1849    
1850     #include "memory_ppc.c"
1851    
1852    
1853     #include "tmp_ppc_tail.c"
1854    
1855 dpavlin 24

  ViewVC Help
Powered by ViewVC 1.1.26