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