/[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 26 - (hide annotations)
Mon Oct 8 16:20:10 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 51647 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1264 2006/06/25 11:08:04 debug Exp $
20060624	Replacing the error-prone machine type initialization stuff
		with something more reasonable.
		Finally removing the old "cpu_run" kludge; moving around stuff
		in machine.c and emul.c to better suit the dyntrans system.
		Various minor dyntrans cleanups (renaming translate_address to
		translate_v2p, and experimenting with template physpages).
20060625	Removing the speed hack which separated the vph entries into
		two halves (code vs data); things seem a lot more stable now.
		Minor performance hack: R2000/R3000 cache isolation now only
		clears address translations when going into isolation, not
		when going out of it.
		Fixing the MIPS interrupt problems by letting mtc0 immediately
		cause interrupts.

==============  RELEASE 0.4.0.1  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26