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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 17 - (hide annotations)
Mon Oct 8 16:19:05 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 37988 byte(s)
0.3.6.1
1 dpavlin 14 /*
2     * Copyright (C) 2005 Anders Gavare. All rights reserved.
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28     * $Id: cpu_ppc.c,v 1.12 2005/09/24 23:44:18 debug Exp $
29     *
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     #include "opcodes_ppc.h"
44     #include "symbol.h"
45    
46     #define DYNTRANS_DUALMODE_32
47     #include "tmp_ppc_head.c"
48    
49    
50     /*
51     * ppc_cpu_new():
52     *
53     * Create a new PPC cpu object.
54     *
55     * Returns 1 on success, 0 if there was no matching PPC processor with
56     * this cpu_type_name.
57     */
58     int ppc_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine,
59     int cpu_id, char *cpu_type_name)
60     {
61     int any_cache = 0;
62     int i, found;
63     struct ppc_cpu_type_def cpu_type_defs[] = PPC_CPU_TYPE_DEFS;
64    
65     /* Scan the cpu_type_defs list for this cpu type: */
66     i = 0;
67     found = -1;
68     while (i >= 0 && cpu_type_defs[i].name != NULL) {
69     if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
70     found = i;
71     break;
72     }
73     i++;
74     }
75     if (found == -1)
76     return 0;
77    
78     cpu->memory_rw = ppc_memory_rw;
79    
80     cpu->cd.ppc.cpu_type = cpu_type_defs[found];
81     cpu->name = cpu->cd.ppc.cpu_type.name;
82     cpu->byte_order = EMUL_BIG_ENDIAN;
83     cpu->cd.ppc.mode = MODE_PPC; /* TODO */
84    
85     /* Current operating mode: */
86     cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;
87     cpu->cd.ppc.pvr = cpu->cd.ppc.cpu_type.pvr;
88    
89     cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;
90    
91     if (cpu->is_32bit) {
92     cpu->update_translation_table = ppc32_update_translation_table;
93     cpu->invalidate_translation_caches_paddr =
94     ppc32_invalidate_translation_caches_paddr;
95     cpu->invalidate_code_translation =
96     ppc32_invalidate_code_translation;
97     } else {
98     cpu->update_translation_table = ppc_update_translation_table;
99     cpu->invalidate_translation_caches_paddr =
100     ppc_invalidate_translation_caches_paddr;
101     cpu->invalidate_code_translation =
102     ppc_invalidate_code_translation;
103     }
104    
105     cpu->translate_address = ppc_translate_address;
106    
107     /* Only show name and caches etc for CPU nr 0 (in SMP machines): */
108     if (cpu_id == 0) {
109     debug("%s", cpu->cd.ppc.cpu_type.name);
110    
111     if (cpu->cd.ppc.cpu_type.icache_shift != 0)
112     any_cache = 1;
113     if (cpu->cd.ppc.cpu_type.dcache_shift != 0)
114     any_cache = 1;
115     if (cpu->cd.ppc.cpu_type.l2cache_shift != 0)
116     any_cache = 1;
117    
118     if (any_cache) {
119     debug(" (I+D = %i+%i KB",
120     (int)(1 << (cpu->cd.ppc.cpu_type.icache_shift-10)),
121     (int)(1 << (cpu->cd.ppc.cpu_type.dcache_shift-10)));
122     if (cpu->cd.ppc.cpu_type.l2cache_shift != 0) {
123     debug(", L2 = %i KB",
124     (int)(1 << (cpu->cd.ppc.cpu_type.
125     l2cache_shift-10)));
126     }
127     debug(")");
128     }
129     }
130    
131     cpu->cd.ppc.pir = cpu_id;
132    
133     /* Some default stack pointer value. TODO: move this? */
134     cpu->cd.ppc.gpr[1] = machine->physical_ram_in_mb * 1048576 - 4096;
135    
136     /*
137     * NOTE/TODO: Ugly hack for OpenFirmware emulation:
138     */
139     if (cpu->machine->prom_emulation)
140     cpu->cd.ppc.of_emul_addr = 0xfff00000;
141    
142     return 1;
143     }
144    
145    
146     /*
147     * ppc_cpu_list_available_types():
148     *
149     * Print a list of available PPC CPU types.
150     */
151     void ppc_cpu_list_available_types(void)
152     {
153     int i, j;
154     struct ppc_cpu_type_def tdefs[] = PPC_CPU_TYPE_DEFS;
155    
156     i = 0;
157     while (tdefs[i].name != NULL) {
158     debug("%s", tdefs[i].name);
159     for (j=10 - strlen(tdefs[i].name); j>0; j--)
160     debug(" ");
161     i++;
162     if ((i % 6) == 0 || tdefs[i].name == NULL)
163     debug("\n");
164     }
165     }
166    
167    
168     /*
169     * ppc_cpu_dumpinfo():
170     */
171     void ppc_cpu_dumpinfo(struct cpu *cpu)
172     {
173     struct ppc_cpu_type_def *ct = &cpu->cd.ppc.cpu_type;
174    
175     debug(" (%i-bit ", cpu->cd.ppc.bits);
176    
177     switch (cpu->cd.ppc.mode) {
178     case MODE_PPC:
179     debug("PPC");
180     break;
181     case MODE_POWER:
182     debug("POWER");
183     break;
184     default:
185     debug("_INTERNAL ERROR_");
186     }
187    
188     debug(", I+D = %i+%i KB",
189     (1 << ct->icache_shift) / 1024,
190     (1 << ct->dcache_shift) / 1024);
191    
192     if (ct->l2cache_shift) {
193     int kb = (1 << ct->l2cache_shift) / 1024;
194     debug(", L2 = %i %cB",
195     kb >= 1024? kb / 1024 : kb,
196     kb >= 1024? 'M' : 'K');
197     }
198    
199     debug(")\n");
200     }
201    
202    
203     /*
204     * reg_access_msr():
205     */
206     void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag)
207     {
208     if (valuep == NULL) {
209     fatal("reg_access_msr(): NULL\n");
210     return;
211     }
212    
213     if (writeflag)
214     cpu->cd.ppc.msr = *valuep;
215    
216     /* TODO: Is the little-endian bit writable? */
217    
218     cpu->cd.ppc.msr &= ~PPC_MSR_LE;
219     if (cpu->byte_order != EMUL_BIG_ENDIAN)
220     cpu->cd.ppc.msr |= PPC_MSR_LE;
221    
222     if (!writeflag)
223     *valuep = cpu->cd.ppc.msr;
224     }
225    
226    
227     /*
228     * ppc_cpu_register_dump():
229     *
230     * Dump cpu registers in a relatively readable format.
231     *
232     * gprs: set to non-zero to dump GPRs and some special-purpose registers.
233     * coprocs: if bit i is set, then we should dump registers from coproc i.
234     */
235     void ppc_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
236     {
237     char *symbol;
238     uint64_t offset, tmp;
239     int i, x = cpu->cpu_id;
240     int bits32 = cpu->cd.ppc.bits == 32;
241    
242     if (gprs) {
243     /* Special registers (pc, ...) first: */
244     symbol = get_symbol_name(&cpu->machine->symbol_context,
245     cpu->pc, &offset);
246    
247     debug("cpu%i: pc = 0x", x);
248     if (bits32)
249     debug("%08x", (int)cpu->pc);
250     else
251     debug("%016llx", (long long)cpu->pc);
252     debug(" <%s>\n", symbol != NULL? symbol : " no symbol ");
253    
254     debug("cpu%i: lr = 0x", x);
255     if (bits32)
256     debug("%08x", (int)cpu->cd.ppc.lr);
257     else
258     debug("%016llx", (long long)cpu->cd.ppc.lr);
259     debug(" cr = 0x%08x\n", (int)cpu->cd.ppc.cr);
260    
261     debug("cpu%i: ctr = 0x", x);
262     if (bits32)
263     debug("%08x", (int)cpu->cd.ppc.ctr);
264     else
265     debug("%016llx", (long long)cpu->cd.ppc.ctr);
266    
267     debug(" xer = 0x", x);
268     if (bits32)
269     debug("%08x\n", (int)cpu->cd.ppc.xer);
270     else
271     debug("%016llx\n", (long long)cpu->cd.ppc.xer);
272    
273     if (bits32) {
274     /* 32-bit: */
275     for (i=0; i<PPC_NGPRS; i++) {
276     if ((i % 4) == 0)
277     debug("cpu%i:", x);
278     debug(" r%02i = 0x%08x ", i,
279     (int)cpu->cd.ppc.gpr[i]);
280     if ((i % 4) == 3)
281     debug("\n");
282     }
283     } else {
284     /* 64-bit: */
285     for (i=0; i<PPC_NGPRS; i++) {
286     int r = (i >> 1) + ((i & 1) << 4);
287     if ((i % 2) == 0)
288     debug("cpu%i:", x);
289     debug(" r%02i = 0x%016llx ", r,
290     (long long)cpu->cd.ppc.gpr[r]);
291     if ((i % 2) == 1)
292     debug("\n");
293     }
294     }
295    
296     /* Other special registers: */
297     debug("cpu%i: srr0 = 0x%016llx srr1 = 0x%016llx\n", x,
298     (long long)cpu->cd.ppc.srr0, (long long)cpu->cd.ppc.srr1);
299     reg_access_msr(cpu, &tmp, 0);
300     debug("cpu%i: msr = 0x%016llx ", x, (long long)tmp);
301     debug("tb = 0x%08x%08x\n",
302     (int)cpu->cd.ppc.tbu, (int)cpu->cd.ppc.tbl);
303     debug("cpu%i: dec = 0x%08x hdec = 0x%08x\n",
304     x, (int)cpu->cd.ppc.dec, (int)cpu->cd.ppc.hdec);
305     }
306    
307     if (coprocs & 1) {
308     debug("cpu%i: fpscr = 0x%08x\n", x, (int)cpu->cd.ppc.fpscr);
309    
310     /* TODO: show floating-point values :-) */
311    
312     /* TODO: 32-bit fprs on 32-bit PPC cpus? */
313    
314     for (i=0; i<PPC_NFPRS; i++) {
315     if ((i % 2) == 0)
316     debug("cpu%i:", x);
317     debug(" f%02i = 0x%016llx ", i,
318     (long long)cpu->cd.ppc.fpr[i]);
319     if ((i % 2) == 1)
320     debug("\n");
321     }
322     }
323    
324     if (coprocs & 2) {
325     debug("cpu%i: sdr1 = 0x%llx\n", x,
326     (long long)cpu->cd.ppc.sdr1);
327     for (i=0; i<4; i++)
328     debug("cpu%i: ibat%iu = 0x%08x ibat%il = 0x%08x\n",
329     x, i, cpu->cd.ppc.ibat_u[i],
330     i, cpu->cd.ppc.ibat_l[i]);
331     for (i=0; i<4; i++)
332     debug("cpu%i: dbat%iu = 0x%08x dbat%il = 0x%08x\n",
333     x, i, cpu->cd.ppc.dbat_u[i],
334     i, cpu->cd.ppc.dbat_l[i]);
335     }
336     }
337    
338    
339     /*
340     * ppc_cpu_register_match():
341     */
342     void ppc_cpu_register_match(struct machine *m, char *name,
343     int writeflag, uint64_t *valuep, int *match_register)
344     {
345     int cpunr = 0;
346    
347     /* CPU number: */
348    
349     /* TODO */
350    
351     /* Register name: */
352     if (strcasecmp(name, "pc") == 0) {
353     if (writeflag) {
354     m->cpus[cpunr]->pc = *valuep;
355     } else
356     *valuep = m->cpus[cpunr]->pc;
357     *match_register = 1;
358     } else if (strcasecmp(name, "msr") == 0) {
359     if (writeflag)
360     m->cpus[cpunr]->cd.ppc.msr = *valuep;
361     else
362     *valuep = m->cpus[cpunr]->cd.ppc.msr;
363     *match_register = 1;
364     } else if (strcasecmp(name, "lr") == 0) {
365     if (writeflag)
366     m->cpus[cpunr]->cd.ppc.lr = *valuep;
367     else
368     *valuep = m->cpus[cpunr]->cd.ppc.lr;
369     *match_register = 1;
370     } else if (strcasecmp(name, "cr") == 0) {
371     if (writeflag)
372     m->cpus[cpunr]->cd.ppc.cr = *valuep;
373     else
374     *valuep = m->cpus[cpunr]->cd.ppc.cr;
375     *match_register = 1;
376     } else if (strcasecmp(name, "dec") == 0) {
377     if (writeflag)
378     m->cpus[cpunr]->cd.ppc.dec = *valuep;
379     else
380     *valuep = m->cpus[cpunr]->cd.ppc.dec;
381     *match_register = 1;
382     } else if (strcasecmp(name, "hdec") == 0) {
383     if (writeflag)
384     m->cpus[cpunr]->cd.ppc.hdec = *valuep;
385     else
386     *valuep = m->cpus[cpunr]->cd.ppc.hdec;
387     *match_register = 1;
388     } else if (strcasecmp(name, "ctr") == 0) {
389     if (writeflag)
390     m->cpus[cpunr]->cd.ppc.ctr = *valuep;
391     else
392     *valuep = m->cpus[cpunr]->cd.ppc.ctr;
393     *match_register = 1;
394     } else if (name[0] == 'r' && isdigit((int)name[1])) {
395     int nr = atoi(name + 1);
396     if (nr >= 0 && nr < PPC_NGPRS) {
397     if (writeflag) {
398     m->cpus[cpunr]->cd.ppc.gpr[nr] = *valuep;
399     } else
400     *valuep = m->cpus[cpunr]->cd.ppc.gpr[nr];
401     *match_register = 1;
402     }
403     } else if (strcasecmp(name, "xer") == 0) {
404     if (writeflag)
405     m->cpus[cpunr]->cd.ppc.xer = *valuep;
406     else
407     *valuep = m->cpus[cpunr]->cd.ppc.xer;
408     *match_register = 1;
409     } else if (strcasecmp(name, "fpscr") == 0) {
410     if (writeflag)
411     m->cpus[cpunr]->cd.ppc.fpscr = *valuep;
412     else
413     *valuep = m->cpus[cpunr]->cd.ppc.fpscr;
414     *match_register = 1;
415     } else if (name[0] == 'f' && isdigit((int)name[1])) {
416     int nr = atoi(name + 1);
417     if (nr >= 0 && nr < PPC_NFPRS) {
418     if (writeflag) {
419     m->cpus[cpunr]->cd.ppc.fpr[nr] = *valuep;
420     } else
421     *valuep = m->cpus[cpunr]->cd.ppc.fpr[nr];
422     *match_register = 1;
423     }
424     }
425     }
426    
427    
428     /*
429     * ppc_cpu_show_full_statistics():
430     *
431     * Show detailed statistics on opcode usage on each cpu.
432     */
433     void ppc_cpu_show_full_statistics(struct machine *m)
434     {
435     fatal("ppc_cpu_show_full_statistics(): TODO\n");
436     }
437    
438    
439     /*
440     * ppc_cpu_tlbdump():
441     *
442     * Called from the debugger to dump the TLB in a readable format.
443     * x is the cpu number to dump, or -1 to dump all CPUs.
444     *
445     * If rawflag is nonzero, then the TLB contents isn't formated nicely,
446     * just dumped.
447     */
448     void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)
449     {
450     fatal("ppc_cpu_tlbdump(): TODO\n");
451     }
452    
453    
454     /*
455     * ppc_cpu_interrupt():
456     */
457     int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
458     {
459     fatal("ppc_cpu_interrupt(): TODO\n");
460     return 0;
461     }
462    
463    
464     /*
465     * ppc_cpu_interrupt_ack():
466     */
467     int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
468     {
469     /* fatal("ppc_cpu_interrupt_ack(): TODO\n"); */
470     return 0;
471     }
472    
473    
474     /*
475     * ppc_cpu_disassemble_instr():
476     *
477     * Convert an instruction word into human readable format, for instruction
478     * tracing.
479     *
480     * If running is 1, cpu->pc should be the address of the instruction.
481     *
482     * If running is 0, things that depend on the runtime environment (eg.
483     * register contents) will not be shown, and addr will be used instead of
484     * cpu->pc for relative addresses.
485     */
486     int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
487     int running, uint64_t dumpaddr, int bintrans)
488     {
489     int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;
490     int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;
491     int bfa, to, load, wlen, no_rb = 0;
492     uint64_t offset, addr;
493     uint32_t iword;
494     char *symbol, *mnem = "ERROR";
495     int power = cpu->cd.ppc.mode == MODE_POWER;
496    
497     if (running)
498     dumpaddr = cpu->pc;
499    
500     symbol = get_symbol_name(&cpu->machine->symbol_context,
501     dumpaddr, &offset);
502     if (symbol != NULL && offset==0)
503     debug("<%s>\n", symbol);
504    
505     if (cpu->machine->ncpus > 1 && running)
506     debug("cpu%i: ", cpu->cpu_id);
507    
508     if (cpu->cd.ppc.bits == 32)
509     debug("%08x", (int)dumpaddr);
510     else
511     debug("%016llx", (long long)dumpaddr);
512    
513     /* NOTE: Fixed to big-endian. */
514     iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
515     + instr[3];
516    
517     debug(": %08x\t", iword);
518    
519     /*
520     * Decode the instruction:
521     */
522    
523     hi6 = iword >> 26;
524    
525     switch (hi6) {
526     case PPC_HI6_MULLI:
527     case PPC_HI6_SUBFIC:
528     rt = (iword >> 21) & 31;
529     ra = (iword >> 16) & 31;
530     imm = (int16_t)(iword & 0xffff);
531     switch (hi6) {
532     case PPC_HI6_MULLI:
533     mnem = power? "muli":"mulli";
534     break;
535     case PPC_HI6_SUBFIC:
536     mnem = power? "sfi":"subfic";
537     break;
538     }
539     debug("%s\tr%i,r%i,%i", mnem, rt, ra, imm);
540     break;
541     case PPC_HI6_CMPLI:
542     case PPC_HI6_CMPI:
543     bf = (iword >> 23) & 7;
544     l_bit = (iword >> 21) & 1;
545     ra = (iword >> 16) & 31;
546     if (hi6 == PPC_HI6_CMPLI) {
547     imm = iword & 0xffff;
548     mnem = "cmpl";
549     } else {
550     imm = (int16_t)(iword & 0xffff);
551     mnem = "cmp";
552     }
553     debug("%s%si\t", mnem, l_bit? "d" : "w");
554     if (bf != 0)
555     debug("cr%i,", bf);
556     debug("r%i,%i", ra, imm);
557     break;
558     case PPC_HI6_ADDIC:
559     case PPC_HI6_ADDIC_DOT:
560     rt = (iword >> 21) & 31;
561     ra = (iword >> 16) & 31;
562     rc = hi6 == PPC_HI6_ADDIC_DOT;
563     imm = (int16_t)(iword & 0xffff);
564     mnem = power? "ai":"addic";
565     if (imm < 0 && !power) {
566     mnem = "subic";
567     imm = -imm;
568     }
569     debug("%s%s\tr%i,r%i,%i", mnem, rc?".":"", rt, ra, imm);
570     break;
571     case PPC_HI6_ADDI:
572     rt = (iword >> 21) & 31;
573     ra = (iword >> 16) & 31;
574     imm = (int16_t)(iword & 0xffff);
575     if (ra == 0)
576     debug("li\tr%i,%i", rt, imm);
577     else {
578     mnem = power? "cal":"addi";
579     if (imm < 0 && !power) {
580     mnem = "subi";
581     imm = -imm;
582     }
583     debug("%s\tr%i,r%i,%i", mnem, rt, ra, imm);
584     }
585     break;
586     case PPC_HI6_ADDIS:
587     rt = (iword >> 21) & 31;
588     ra = (iword >> 16) & 31;
589     imm = (int16_t)(iword & 0xffff);
590     if (ra == 0)
591     debug("lis\tr%i,%i", rt, imm);
592     else
593     debug("%s\tr%i,r%i,%i",
594     power? "cau":"addis", rt, ra, imm);
595     break;
596     case PPC_HI6_BC:
597     aa_bit = (iword & 2) >> 1;
598     lk_bit = iword & 1;
599     bo = (iword >> 21) & 31;
600     bi = (iword >> 16) & 31;
601     /* Sign-extend addr: */
602     addr = (int64_t)(int16_t)(iword & 0xfffc);
603     debug("bc");
604     if (lk_bit)
605     debug("l");
606     if (aa_bit)
607     debug("a");
608     else
609     addr += dumpaddr;
610     debug("\t%i,%i,", bo, bi);
611     if (cpu->cd.ppc.bits == 32)
612     addr &= 0xffffffff;
613     if (cpu->cd.ppc.bits == 32)
614     debug("0x%x", (int)addr);
615     else
616     debug("0x%llx", (long long)addr);
617     symbol = get_symbol_name(&cpu->machine->symbol_context,
618     addr, &offset);
619     if (symbol != NULL)
620     debug("\t<%s>", symbol);
621     break;
622     case PPC_HI6_SC:
623     lev = (iword >> 5) & 0x7f;
624     debug("sc");
625     if (lev != 0) {
626     debug("\t%i", lev);
627     if (lev > 1)
628     debug(" (WARNING! reserved value)");
629     }
630     break;
631     case PPC_HI6_B:
632     aa_bit = (iword & 2) >> 1;
633     lk_bit = iword & 1;
634     /* Sign-extend addr: */
635     addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
636     addr = (int64_t)addr >> 6;
637     debug("b");
638     if (lk_bit)
639     debug("l");
640     if (aa_bit)
641     debug("a");
642     else
643     addr += dumpaddr;
644     if (cpu->cd.ppc.bits == 32)
645     addr &= 0xffffffff;
646     if (cpu->cd.ppc.bits == 32)
647     debug("\t0x%x", (int)addr);
648     else
649     debug("\t0x%llx", (long long)addr);
650     symbol = get_symbol_name(&cpu->machine->symbol_context,
651     addr, &offset);
652     if (symbol != NULL)
653     debug("\t<%s>", symbol);
654     break;
655     case PPC_HI6_19:
656     xo = (iword >> 1) & 1023;
657     switch (xo) {
658     case PPC_19_MCRF:
659     bf = (iword >> 23) & 7;
660     bfa = (iword >> 18) & 7;
661     debug("mcrf\tcr%i,cr%i", bf, bfa);
662     break;
663     case PPC_19_RFI:
664     debug("rfi");
665     break;
666     case PPC_19_RFID:
667     debug("rfid");
668     break;
669     case PPC_19_RFSVC:
670     debug("rfsvc%s", power?"":"\t(INVALID for PowerPC)");
671     break;
672     case PPC_19_BCLR:
673     case PPC_19_BCCTR:
674     bo = (iword >> 21) & 31;
675     bi = (iword >> 16) & 31;
676     bh = (iword >> 11) & 3;
677     lk_bit = iword & 1;
678     switch (xo) {
679     case PPC_19_BCLR:
680     mnem = power? "bcr" : "bclr"; break;
681     case PPC_19_BCCTR:
682     mnem = power? "bcc" : "bcctr"; break;
683     }
684     debug("%s%s%s\t%i,%i,%i", mnem, lk_bit? "l" : "",
685     bh? (bh==3? "+" : (bh==2? "-" : "?")) : "",
686     bo, bi, bh);
687     break;
688     case PPC_19_ISYNC:
689     debug("%s", power? "ics" : "isync");
690     break;
691     case PPC_19_CRAND:
692     case PPC_19_CRXOR:
693     case PPC_19_CROR:
694     case PPC_19_CRNAND:
695     case PPC_19_CRNOR:
696     case PPC_19_CRANDC:
697     case PPC_19_CREQV:
698     case PPC_19_CRORC:
699     bt = (iword >> 21) & 31;
700     ba = (iword >> 16) & 31;
701     bb = (iword >> 11) & 31;
702     switch (xo) {
703     case PPC_19_CRAND: mnem = "crand"; break;
704     case PPC_19_CRXOR: mnem = "crxor"; break;
705     case PPC_19_CROR: mnem = "cror"; break;
706     case PPC_19_CRNAND: mnem = "crnand"; break;
707     case PPC_19_CRNOR: mnem = "crnor"; break;
708     case PPC_19_CRANDC: mnem = "crandc"; break;
709     case PPC_19_CREQV: mnem = "creqv"; break;
710     case PPC_19_CRORC: mnem = "crorc"; break;
711     }
712     debug("%s\t%i,%i,%i", mnem, bt, ba, bb);
713     break;
714     default:
715     debug("unimplemented hi6_19, xo = 0x%x", xo);
716     }
717     break;
718     case PPC_HI6_RLWIMI:
719     case PPC_HI6_RLWINM:
720     rs = (iword >> 21) & 31;
721     ra = (iword >> 16) & 31;
722     sh = (iword >> 11) & 31;
723     mb = (iword >> 6) & 31;
724     me = (iword >> 1) & 31;
725     rc = iword & 1;
726     switch (hi6) {
727     case PPC_HI6_RLWIMI:
728     mnem = power? "rlimi" : "rlwimi"; break;
729     case PPC_HI6_RLWINM:
730     mnem = power? "rlinm" : "rlwinm"; break;
731     }
732     debug("%s%s\tr%i,r%i,%i,%i,%i",
733     mnem, rc?".":"", ra, rs, sh, mb, me);
734     break;
735     case PPC_HI6_ORI:
736     case PPC_HI6_ORIS:
737     case PPC_HI6_XORI:
738     case PPC_HI6_XORIS:
739     case PPC_HI6_ANDI_DOT:
740     case PPC_HI6_ANDIS_DOT:
741     rs = (iword >> 21) & 31;
742     ra = (iword >> 16) & 31;
743     imm = iword & 0xffff;
744     switch (hi6) {
745     case PPC_HI6_ORI:
746     mnem = power? "oril":"ori";
747     break;
748     case PPC_HI6_ORIS:
749     mnem = power? "oriu":"oris";
750     break;
751     case PPC_HI6_XORI:
752     mnem = power? "xoril":"xori";
753     break;
754     case PPC_HI6_XORIS:
755     mnem = power? "xoriu":"xoris";
756     break;
757     case PPC_HI6_ANDI_DOT:
758     mnem = power? "andil.":"andi.";
759     break;
760     case PPC_HI6_ANDIS_DOT:
761     mnem = power? "andiu.":"andis.";
762     break;
763     }
764     if (hi6 == PPC_HI6_ORI && rs == 0 && ra == 0 && imm == 0)
765     debug("nop");
766     else
767     debug("%s\tr%i,r%i,0x%04x", mnem, ra, rs, imm);
768     break;
769     case PPC_HI6_30:
770     xo = (iword >> 2) & 7;
771     switch (xo) {
772     case PPC_30_RLDICR:
773     rs = (iword >> 21) & 31;
774     ra = (iword >> 16) & 31;
775     sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
776     me = ((iword >> 6) & 31) | (iword & 0x20);
777     rc = iword & 1;
778     debug("rldicr%s\tr%i,r%i,%i,%i",
779     rc?".":"", ra, rs, sh, me);
780     break;
781     default:
782     debug("unimplemented hi6_30, xo = 0x%x", xo);
783     }
784     break;
785     case PPC_HI6_31:
786     xo = (iword >> 1) & 1023;
787     switch (xo) {
788    
789     case PPC_31_CMP:
790     case PPC_31_CMPL:
791     bf = (iword >> 23) & 7;
792     l_bit = (iword >> 21) & 1;
793     ra = (iword >> 16) & 31;
794     rb = (iword >> 11) & 31;
795     if (xo == PPC_31_CMPL)
796     mnem = "cmpl";
797     else
798     mnem = "cmp";
799     debug("%s%s\t", mnem, l_bit? "d" : "w");
800     if (bf != 0)
801     debug("cr%i,", bf);
802     debug("r%i,r%i", ra, rb);
803     break;
804     case PPC_31_MFCR:
805     rt = (iword >> 21) & 31;
806     debug("mfcr\tr%i", rt);
807     break;
808     case PPC_31_MFMSR:
809     rt = (iword >> 21) & 31;
810     debug("mfmsr\tr%i", rt);
811     break;
812     case PPC_31_MTCRF:
813     rs = (iword >> 21) & 31;
814     mb = (iword >> 12) & 255; /* actually fxm, not mb */
815     debug("mtcrf\t%i,r%i", mb, rs);
816     break;
817     case PPC_31_MTMSR:
818     rs = (iword >> 21) & 31;
819     l_bit = (iword >> 16) & 1;
820     debug("mtmsr\tr%i", rs);
821     if (l_bit)
822     debug(",%i", l_bit);
823     break;
824     case PPC_31_TW:
825     case PPC_31_TD:
826     to = (iword >> 21) & 31;
827     ra = (iword >> 16) & 31;
828     rb = (iword >> 11) & 31;
829     switch (xo) {
830     case PPC_31_TW: mnem = power? "t" : "tw"; break;
831     case PPC_31_TD: mnem = "td"; break;
832     }
833     debug("%s\t%i,r%i,r%i", mnem, to, ra, rb);
834     break;
835     case PPC_31_LWARX:
836     case PPC_31_LDARX:
837     case PPC_31_LBZX:
838     case PPC_31_LBZUX:
839     case PPC_31_LHZX:
840     case PPC_31_LHZUX:
841     case PPC_31_LWZX:
842     case PPC_31_LWZUX:
843     case PPC_31_STWCX_DOT:
844     case PPC_31_STDCX_DOT:
845     case PPC_31_STBX:
846     case PPC_31_STBUX:
847     case PPC_31_STHX:
848     case PPC_31_STHUX:
849     case PPC_31_STWX:
850     case PPC_31_STWUX:
851     case PPC_31_STDX:
852     case PPC_31_STDUX:
853     /* rs for stores, rt for loads, actually */
854     load = 0; wlen = 0;
855     rs = (iword >> 21) & 31;
856     ra = (iword >> 16) & 31;
857     rb = (iword >> 11) & 31;
858     switch (xo) {
859     case PPC_31_LWARX: wlen=4;load=1; mnem = "lwarx"; break;
860     case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;
861     case PPC_31_LBZX: wlen=1;load=1; mnem = "lbzx"; break;
862     case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;
863     case PPC_31_LHZX: wlen=2;load=1; mnem = "lhzx"; break;
864     case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;
865     case PPC_31_LWZX: wlen = 4; load = 1;
866     mnem = power? "lx" : "lwzx";
867     break;
868     case PPC_31_LWZUX: wlen = 4; load = 1;
869     mnem = power? "lux":"lwzux";
870     break;
871     case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;
872     case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;
873     case PPC_31_STBX: wlen=1; mnem = "stbx"; break;
874     case PPC_31_STBUX: wlen=1; mnem = "stbux"; break;
875     case PPC_31_STHX: wlen=2; mnem = "sthx"; break;
876     case PPC_31_STHUX: wlen=2; mnem = "sthux"; break;
877     case PPC_31_STWX:
878     wlen = 4; mnem = power? "stx" : "stwx";
879     break;
880     case PPC_31_STWUX:
881     wlen = 4; mnem = power? "stux" : "stwux";
882     break;
883     case PPC_31_STDX: wlen = 8; mnem = "stdx"; break;
884     case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;
885     }
886     debug("%s\tr%i,r%i,r%i", mnem, rs, ra, rb);
887     if (!running)
888     break;
889     addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +
890     cpu->cd.ppc.gpr[rb];
891     symbol = get_symbol_name(&cpu->machine->symbol_context,
892     addr, &offset);
893     if (symbol != NULL)
894     debug(" \t<%s", symbol);
895     else
896     debug(" \t<0x%llx", (long long)addr);
897     if (wlen > 0) {
898     /* TODO */
899     }
900     debug(">");
901     break;
902     case PPC_31_NEG:
903     case PPC_31_NEGO:
904     rt = (iword >> 21) & 31;
905     ra = (iword >> 16) & 31;
906     oe_bit = (iword >> 10) & 1;
907     rc = iword & 1;
908     switch (xo) {
909     case PPC_31_NEG: mnem = "neg"; break;
910     case PPC_31_NEGO: mnem = "nego"; break;
911     }
912     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
913     break;
914     case PPC_31_ADDZE:
915     case PPC_31_ADDZEO:
916     rt = (iword >> 21) & 31;
917     ra = (iword >> 16) & 31;
918     oe_bit = (iword >> 10) & 1;
919     rc = iword & 1;
920     switch (xo) {
921     case PPC_31_ADDZE:
922     mnem = power? "aze" : "addze";
923     break;
924     case PPC_31_ADDZEO:
925     mnem = power? "azeo" : "addzeo";
926     break;
927     }
928     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
929     break;
930     case PPC_31_MTSR:
931     /* Move to segment register */
932     rt = (iword >> 21) & 31;
933     ra = (iword >> 16) & 15; /* actually: sr */
934     debug("mtsr\t%i,r%i", ra, rt);
935     break;
936     case PPC_31_MTSRIN:
937     case PPC_31_MFSRIN:
938     /* Move to/from segment register indirect */
939     rt = (iword >> 21) & 31;
940     rb = (iword >> 11) & 31;
941     switch (xo) {
942     case PPC_31_MTSRIN: mnem = "mtsrin"; break;
943     case PPC_31_MFSRIN: mnem = "mfsrin"; break;
944     }
945     debug("%s\tr%i,r%i", mnem, rt, rb);
946     break;
947     case PPC_31_ADDC:
948     case PPC_31_ADDCO:
949     case PPC_31_ADDE:
950     case PPC_31_ADDEO:
951     case PPC_31_ADDME:
952     case PPC_31_ADDMEO:
953     case PPC_31_ADD:
954     case PPC_31_ADDO:
955     case PPC_31_MULHW:
956     case PPC_31_MULHWU:
957     case PPC_31_MULLW:
958     case PPC_31_MULLWO:
959     case PPC_31_SUBF:
960     case PPC_31_SUBFO:
961     case PPC_31_SUBFC:
962     case PPC_31_SUBFCO:
963     case PPC_31_SUBFE:
964     case PPC_31_SUBFEO:
965     case PPC_31_SUBFZE:
966     case PPC_31_SUBFZEO:
967     rt = (iword >> 21) & 31;
968     ra = (iword >> 16) & 31;
969     rb = (iword >> 11) & 31;
970     oe_bit = (iword >> 10) & 1;
971     rc = iword & 1;
972     switch (xo) {
973     case PPC_31_ADDC:
974     mnem = power? "a" : "addc";
975     break;
976     case PPC_31_ADDCO:
977     mnem = power? "ao" : "addco";
978     break;
979     case PPC_31_ADDE:
980     mnem = power? "ae" : "adde";
981     break;
982     case PPC_31_ADDEO:
983     mnem = power? "aeo" : "addeo";
984     break;
985     case PPC_31_ADDME:
986     mnem = power? "ame" : "addme";
987     no_rb = 1;
988     break;
989     case PPC_31_ADDMEO:
990     mnem = power? "ameo" : "addmeo";
991     no_rb = 1;
992     break;
993     case PPC_31_ADD:
994     mnem = power? "cax" : "add";
995     break;
996     case PPC_31_ADDO:
997     mnem = power? "caxo" : "addo";
998     break;
999     case PPC_31_MULHW: mnem = "mulhw"; break;
1000     case PPC_31_MULHWU: mnem = "mulhwu"; break;
1001     case PPC_31_MULLW:
1002     mnem = power? "muls" : "mullw";
1003     break;
1004     case PPC_31_MULLWO:
1005     mnem = power? "mulso" : "mullwo";
1006     break;
1007     case PPC_31_SUBF: mnem = "subf"; break;
1008     case PPC_31_SUBFO: mnem = "subfo"; break;
1009     case PPC_31_SUBFC:
1010     mnem = power? "sf" : "subfc";
1011     break;
1012     case PPC_31_SUBFCO:
1013     mnem = power? "sfo" : "subfco";
1014     break;
1015     case PPC_31_SUBFE:
1016     mnem = power? "sfe" : "subfe";
1017     break;
1018     case PPC_31_SUBFEO:
1019     mnem = power? "sfeo" : "subfeo";
1020     break;
1021     case PPC_31_SUBFZE:
1022     mnem = power? "sfze" : "subfze";
1023     no_rb = 1;
1024     break;
1025     case PPC_31_SUBFZEO:
1026     mnem = power? "sfzeo" : "subfzeo";
1027     no_rb = 1;
1028     break;
1029     }
1030     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1031     if (!no_rb)
1032     debug(",r%i", rb);
1033     break;
1034     case PPC_31_MFSPR:
1035     rt = (iword >> 21) & 31;
1036     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1037     switch (spr) {
1038     case 8: debug("mflr\tr%i", rt); break;
1039     case 9: debug("mfctr\tr%i", rt); break;
1040     case 26: debug("mfsrr0\tr%i", rt); break;
1041     case 27: debug("mfsrr1\tr%i", rt); break;
1042     case 272: debug("mfsprg\t0,r%i", rt); break;
1043     case 273: debug("mfsprg\t1,r%i", rt); break;
1044     case 274: debug("mfsprg\t2,r%i", rt); break;
1045     case 275: debug("mfsprg\t3,r%i", rt); break;
1046     case 287: debug("mfpvr\tr%i", rt); break;
1047     /* TODO: 1008 = hid0? */
1048     case 1008: debug("mfdbsr\tr%i", rt); break;
1049     case 1009: debug("mfhid1\tr%i", rt); break;
1050     case 1017: debug("mfl2cr\tr%i", rt); break;
1051     case 1018: debug("mfl3cr\tr%i", rt); break;
1052     default:debug("mfspr\tr%i,spr%i", rt, spr);
1053     }
1054     break;
1055     case PPC_31_TLBIE:
1056     /* TODO: what is ra? The IBM online docs didn't say */
1057     ra = 0;
1058     rb = (iword >> 11) & 31;
1059     if (power)
1060     debug("tlbi\tr%i,r%i", ra, rb);
1061     else
1062     debug("tlbie\tr%i", rb);
1063     break;
1064     case PPC_31_TLBSYNC:
1065     debug("tlbsync");
1066     break;
1067     case PPC_31_MFTB:
1068     rt = (iword >> 21) & 31;
1069     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1070     debug("mftb%s\tr%i", spr==268? "" :
1071     (spr==269? "u" : "?"), rt);
1072     break;
1073     case PPC_31_CNTLZW:
1074     rs = (iword >> 21) & 31;
1075     ra = (iword >> 16) & 31;
1076     rc = iword & 1;
1077     mnem = power? "cntlz" : "cntlzw";
1078     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1079     break;
1080     case PPC_31_CLF: /* POWER only */
1081     case PPC_31_CLI: /* POWER only */
1082     case PPC_31_DCLST: /* POWER only */
1083     case PPC_31_DCBF: /* PowerPC only */
1084     case PPC_31_DCBI: /* PowerPC only */
1085     case PPC_31_DCBST: /* PowerPC only */
1086     case PPC_31_DCBTST: /* PowerPC only */
1087     case PPC_31_DCBT: /* PowerPC only */
1088     case PPC_31_ICBI: /* PowerPC only */
1089     case PPC_31_DCBZ: /* POWER/PowerPC */
1090     ra = (iword >> 16) & 31;
1091     rb = (iword >> 11) & 31;
1092     switch (xo) {
1093     case PPC_31_CLF: mnem = "clf"; break;
1094     case PPC_31_CLI: mnem = "cli"; break;
1095     case PPC_31_DCLST: mnem = "dclst"; break;
1096     case PPC_31_DCBF: mnem = "dcbf"; break;
1097     case PPC_31_DCBI: mnem = "dcbi"; break;
1098     case PPC_31_DCBST: mnem = "dcbst"; break;
1099     case PPC_31_DCBTST:mnem = "dcbtst"; break;
1100     case PPC_31_DCBT: mnem = "dcbt"; break;
1101     case PPC_31_ICBI: mnem = "icbi"; break;
1102     case PPC_31_DCBZ: mnem = power ?
1103     "dclz" : "dcbz"; break;
1104     }
1105     debug("%s\tr%i,r%i", mnem, ra, rb);
1106     break;
1107     case PPC_31_SLW:
1108     case PPC_31_SRAW:
1109     case PPC_31_SRW:
1110     case PPC_31_AND:
1111     case PPC_31_ANDC:
1112     case PPC_31_NOR:
1113     case PPC_31_OR:
1114     case PPC_31_ORC:
1115     case PPC_31_XOR:
1116     case PPC_31_NAND:
1117     rs = (iword >> 21) & 31;
1118     ra = (iword >> 16) & 31;
1119     rb = (iword >> 11) & 31;
1120     rc = iword & 1;
1121     if (rs == rb && xo == PPC_31_OR)
1122     debug("mr%s\tr%i,r%i", rc? "." : "", ra, rs);
1123     else {
1124     switch (xo) {
1125     case PPC_31_SLW: mnem =
1126     power? "sl" : "slw"; break;
1127     case PPC_31_SRAW: mnem =
1128     power? "sra" : "sraw"; break;
1129     case PPC_31_SRW: mnem =
1130     power? "sr" : "srw"; break;
1131     case PPC_31_AND: mnem = "and"; break;
1132     case PPC_31_NAND: mnem = "nand"; break;
1133     case PPC_31_ANDC: mnem = "andc"; break;
1134     case PPC_31_NOR: mnem = "nor"; break;
1135     case PPC_31_OR: mnem = "or"; break;
1136     case PPC_31_ORC: mnem = "orc"; break;
1137     case PPC_31_XOR: mnem = "xor"; break;
1138     }
1139     debug("%s%s\tr%i,r%i,r%i", mnem,
1140     rc? "." : "", ra, rs, rb);
1141     }
1142     break;
1143     case PPC_31_DCCCI:
1144     ra = (iword >> 16) & 31;
1145     rb = (iword >> 11) & 31;
1146     debug("dccci\tr%i,r%i", ra, rb);
1147     break;
1148     case PPC_31_ICCCI:
1149     ra = (iword >> 16) & 31;
1150     rb = (iword >> 11) & 31;
1151     debug("iccci\tr%i,r%i", ra, rb);
1152     break;
1153     case PPC_31_DIVW:
1154     case PPC_31_DIVWO:
1155     case PPC_31_DIVWU:
1156     case PPC_31_DIVWUO:
1157     rt = (iword >> 21) & 31;
1158     ra = (iword >> 16) & 31;
1159     rb = (iword >> 11) & 31;
1160     oe_bit = (iword >> 10) & 1;
1161     rc = iword & 1;
1162     switch (xo) {
1163     case PPC_31_DIVWU: mnem = "divwu"; break;
1164     case PPC_31_DIVWUO: mnem = "divwuo"; break;
1165     case PPC_31_DIVW: mnem = "divw"; break;
1166     case PPC_31_DIVWO: mnem = "divwo"; break;
1167     }
1168     debug("%s%s\tr%i,r%i,r%i", mnem, rc? "." : "",
1169     rt, ra, rb);
1170     break;
1171     case PPC_31_MTSPR:
1172     rs = (iword >> 21) & 31;
1173     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1174     switch (spr) {
1175     case 8: debug("mtlr\tr%i", rs); break;
1176     case 9: debug("mtctr\tr%i", rs); break;
1177     case 26: debug("mtsrr0\tr%i", rs); break;
1178     case 27: debug("mtsrr1\tr%i", rs); break;
1179     case 272: debug("mtsprg\t0,r%i", rs); break;
1180     case 273: debug("mtsprg\t1,r%i", rs); break;
1181     case 274: debug("mtsprg\t2,r%i", rs); break;
1182     case 275: debug("mtsprg\t3,r%i", rs); break;
1183     case 528: debug("mtibatu\t0,r%i", rs); break;
1184     case 529: debug("mtibatl\t0,r%i", rs); break;
1185     case 530: debug("mtibatu\t1,r%i", rs); break;
1186     case 531: debug("mtibatl\t1,r%i", rs); break;
1187     case 532: debug("mtibatu\t2,r%i", rs); break;
1188     case 533: debug("mtibatl\t2,r%i", rs); break;
1189     case 534: debug("mtibatu\t3,r%i", rs); break;
1190     case 535: debug("mtibatl\t3,r%i", rs); break;
1191     case 536: debug("mtdbatu\t0,r%i", rs); break;
1192     case 537: debug("mtdbatl\t0,r%i", rs); break;
1193     case 538: debug("mtdbatu\t1,r%i", rs); break;
1194     case 539: debug("mtdbatl\t1,r%i", rs); break;
1195     case 540: debug("mtdbatu\t2,r%i", rs); break;
1196     case 541: debug("mtdbatl\t2,r%i", rs); break;
1197     case 542: debug("mtdbatu\t3,r%i", rs); break;
1198     case 543: debug("mtdbatl\t3,r%i", rs); break;
1199     case 1008: debug("mtdbsr\tr%i", rs); break;
1200     default:debug("mtspr\tspr%i,r%i", spr, rs);
1201     }
1202     break;
1203     case PPC_31_SYNC:
1204     debug("%s", power? "dcs" : "sync");
1205     break;
1206     case PPC_31_LSWI:
1207     case PPC_31_STSWI:
1208     rs = (iword >> 21) & 31; /* lwsi uses rt */
1209     ra = (iword >> 16) & 31;
1210     nb = (iword >> 11) & 31;
1211     switch (xo) {
1212     case PPC_31_LSWI:
1213     mnem = power? "lsi" : "lswi"; break;
1214     case PPC_31_STSWI:
1215     mnem = power? "stsi" : "stswi"; break;
1216     }
1217     debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);
1218     break;
1219     case PPC_31_LHBRX:
1220     case PPC_31_LWBRX:
1221     case PPC_31_STHBRX:
1222     case PPC_31_STWBRX:
1223     rt = (iword >> 21) & 31; /* stores use rs */
1224     ra = (iword >> 16) & 31;
1225     rb = (iword >> 11) & 31;
1226     switch (xo) {
1227     case PPC_31_LHBRX: mnem = "lhbrx"; break;
1228     case PPC_31_LWBRX: mnem = power?
1229     "lbrx" : "lwbrx"; break;
1230     case PPC_31_STHBRX: mnem = "sthbrx"; break;
1231     case PPC_31_STWBRX: mnem = power?
1232     "stbrx" : "stwbrx"; break;
1233     }
1234     debug("%s\tr%i,r%i,r%i", mnem, rt, ra, rb);
1235     break;
1236     case PPC_31_SRAWI:
1237     rs = (iword >> 21) & 31;
1238     ra = (iword >> 16) & 31;
1239     sh = (iword >> 11) & 31;
1240     rc = iword & 1;
1241     mnem = power? "srai" : "srawi";
1242     debug("%s%s\tr%i,r%i,%i", mnem,
1243     rc? "." : "", ra, rs, sh);
1244     break;
1245     case PPC_31_EIEIO:
1246     debug("%s", power? "eieio?" : "eieio");
1247     break;
1248     case PPC_31_EXTSB:
1249     case PPC_31_EXTSH:
1250     case PPC_31_EXTSW:
1251     rs = (iword >> 21) & 31;
1252     ra = (iword >> 16) & 31;
1253     rc = iword & 1;
1254     switch (xo) {
1255     case PPC_31_EXTSB:
1256     mnem = power? "exts" : "extsb";
1257     break;
1258     case PPC_31_EXTSH:
1259     mnem = "extsh";
1260     break;
1261     case PPC_31_EXTSW:
1262     mnem = "extsw";
1263     break;
1264     }
1265     debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1266     break;
1267     default:
1268     debug("unimplemented hi6_31, xo = 0x%x", xo);
1269     }
1270     break;
1271     case PPC_HI6_LWZ:
1272     case PPC_HI6_LWZU:
1273     case PPC_HI6_LHZ:
1274     case PPC_HI6_LHZU:
1275     case PPC_HI6_LHA:
1276     case PPC_HI6_LHAU:
1277     case PPC_HI6_LBZ:
1278     case PPC_HI6_LBZU:
1279     case PPC_HI6_LMW:
1280     case PPC_HI6_STW:
1281     case PPC_HI6_STWU:
1282     case PPC_HI6_STH:
1283     case PPC_HI6_STHU:
1284     case PPC_HI6_STB:
1285     case PPC_HI6_STBU:
1286     case PPC_HI6_STMW:
1287     case PPC_HI6_LFD:
1288     case PPC_HI6_STFD:
1289     /* NOTE: Loads use rt, not rs, but are otherwise similar
1290     to stores */
1291     load = 0; wlen = 0;
1292     rs = (iword >> 21) & 31;
1293     ra = (iword >> 16) & 31;
1294     imm = (int16_t)(iword & 0xffff);
1295     fpreg = 0;
1296     switch (hi6) {
1297     case PPC_HI6_LWZ: load=1; wlen = 4;
1298     mnem = power? "l" : "lwz"; break;
1299     case PPC_HI6_LWZU: load=1; wlen = 4;
1300     mnem = power? "lu" : "lwzu"; break;
1301     case PPC_HI6_LHZ: load=1; wlen = 2;
1302     mnem = "lhz"; break;
1303     case PPC_HI6_LHZU: load=1; wlen = 2;
1304     mnem = "lhzu"; break;
1305     case PPC_HI6_LHA: load=2; wlen = 2;
1306     mnem = "lha"; break;
1307     case PPC_HI6_LHAU: load=2; wlen = 2;
1308     mnem = "lhau"; break;
1309     case PPC_HI6_LBZ: load=1; wlen = 1;
1310     mnem = "lbz"; break;
1311     case PPC_HI6_LBZU: load=1; wlen = 1;
1312     mnem = "lbzu"; break;
1313     case PPC_HI6_STW: wlen=4; mnem = power? "st" : "stw"; break;
1314     case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;
1315     case PPC_HI6_STH: wlen=2; mnem = "sth"; break;
1316     case PPC_HI6_STHU: wlen=2; mnem = "sthu"; break;
1317     case PPC_HI6_STB: wlen=1; mnem = "stb"; break;
1318     case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;
1319     case PPC_HI6_LMW: load=1; mnem = power? "lm" : "lmw"; break;
1320     case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1321     case PPC_HI6_LFD: load=1; fpreg = 1; mnem = "lfd"; break;
1322     case PPC_HI6_STFD: fpreg = 1; mnem = "stfd"; break;
1323     }
1324     debug("%s\t", mnem);
1325     if (fpreg)
1326     debug("f");
1327     else
1328     debug("r");
1329     debug("%i,%i(r%i)", rs, imm, ra);
1330     if (!running)
1331     break;
1332     addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;
1333     symbol = get_symbol_name(&cpu->machine->symbol_context,
1334     addr, &offset);
1335     if (symbol != NULL)
1336     debug(" \t<%s", symbol);
1337     else
1338     debug(" \t<0x%llx", (long long)addr);
1339     if (wlen > 0 && load && wlen > 0) {
1340     unsigned char tw[8];
1341     uint64_t tdata = 0;
1342     int i, res = cpu->memory_rw(cpu, cpu->mem, addr, tw,
1343     wlen, MEM_READ, NO_EXCEPTIONS);
1344     if (res) {
1345     if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1346     for (i=0; i<wlen; i++) {
1347     tdata <<= 8;
1348     tdata |= tw[wlen-1-i];
1349     }
1350     else
1351     for (i=0; i<wlen; i++) {
1352     tdata <<= 8;
1353     tdata |= tw[i];
1354     }
1355     debug(": ");
1356     if (wlen >= 4) {
1357     symbol = get_symbol_name(&cpu->machine->
1358     symbol_context, tdata, &offset);
1359     if (symbol != NULL)
1360     debug("%s", symbol);
1361     else
1362     debug("0x%llx",
1363     (long long)tdata);
1364     } else {
1365     /* TODO: if load==2, then this is
1366     a _signed_ load. */
1367     debug("0x%llx", (long long)tdata);
1368     }
1369     } else
1370     debug(": unreadable");
1371     }
1372     if (wlen > 0 && !load && wlen > 0) {
1373     int64_t tdata = 0;
1374     int i;
1375     for (i=0; i<wlen; i++)
1376     tdata |= (cpu->cd.ppc.gpr[rs] &
1377     ((uint64_t)0xff << i));
1378     debug(": ");
1379     if (wlen >= 4) {
1380     symbol = get_symbol_name(&cpu->machine->
1381     symbol_context, tdata, &offset);
1382     if (symbol != NULL)
1383     debug("%s", symbol);
1384     else
1385     debug("0x%llx",
1386     (long long)tdata);
1387     } else {
1388     if (tdata > -256 && tdata < 256)
1389     debug("%i", (int)tdata);
1390     else
1391     debug("0x%llx", (long long)tdata);
1392     }
1393     }
1394     debug(">");
1395     break;
1396     case PPC_HI6_63:
1397     xo = (iword >> 1) & 1023;
1398     switch (xo) {
1399     case PPC_63_FMR:
1400     rt = (iword >> 21) & 31;
1401     ra = (iword >> 16) & 31;
1402     rb = (iword >> 11) & 31;
1403     rc = iword & 1;
1404     switch (xo) {
1405     case PPC_63_FMR:
1406     debug("fmr%s\tf%i,f%i", rc? "." : "", rt, rb);
1407     break;
1408     }
1409     break;
1410     default:
1411     debug("unimplemented hi6_31, xo = 0x%x", xo);
1412     }
1413     break;
1414     default:
1415     /* TODO */
1416     debug("unimplemented hi6 = 0x%02x", hi6);
1417     }
1418    
1419     debug("\n");
1420     return sizeof(iword);
1421     }
1422    
1423    
1424     /*
1425     * update_cr0():
1426     *
1427     * Sets the top 4 bits of the CR register.
1428     */
1429     void update_cr0(struct cpu *cpu, uint64_t value)
1430     {
1431     int c;
1432    
1433     if (cpu->cd.ppc.bits == 64) {
1434     if ((int64_t)value < 0)
1435     c = 8;
1436     else if ((int64_t)value > 0)
1437     c = 4;
1438     else
1439     c = 2;
1440     } else {
1441     if ((int32_t)value < 0)
1442     c = 8;
1443     else if ((int32_t)value > 0)
1444     c = 4;
1445     else
1446     c = 2;
1447     }
1448    
1449     /* SO bit, copied from XER: */
1450     c |= ((cpu->cd.ppc.xer >> 31) & 1);
1451    
1452     cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1453     cpu->cd.ppc.cr |= ((uint32_t)c << 28);
1454     }
1455    
1456    
1457     #include "memory_ppc.c"
1458    
1459    
1460     #include "tmp_ppc_tail.c"
1461    

  ViewVC Help
Powered by ViewVC 1.1.26