/[gxemul]/upstream/0.4.4.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

Contents of /upstream/0.4.4.1/src/cpus/cpu_ppc.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26