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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26