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

  ViewVC Help
Powered by ViewVC 1.1.26