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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (show annotations)
Mon Oct 8 16:18:00 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 69460 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.707 2005/04/27 16:37:33 debug Exp $
20050408	Some minor updates to the wdc. Linux now doesn't complain
		anymore if a disk is non-present.
20050409	Various minor fixes (a bintrans bug, and some other things).
		The wdc seems to work with Playstation2 emulation, but there
		is a _long_ annoying delay when disks are detected.
		Fixing a really important bintrans bug (when devices and RAM
		are mixed within 4KB pages), which was triggered with
		NetBSD/playstation2 kernels.
20050410	Adding a dummy dev_ps2_ether (just so that NetBSD doesn't
		complain as much during bootup).
		Symbols starting with '$' are now ignored.
		Renaming dev_ps2_ohci.c to dev_ohci.c, etc.
20050411	Moving the bintrans-cache-isolation check from cpu_mips.c to
		cpu_mips_coproc.c. (I thought this would give a speedup, but
		it's not noticable.)
		Better playstation2 sbus interrupt code.
		Skip ahead many ticks if the count register is read manually.
		(This increases the speed of delay-loops that simply read
		the count register.)
20050412	Updates to the playstation2 timer/interrupt code.
		Some other minor updates.
20050413	NetBSD/cobalt runs from a disk image :-) including userland;
		updating the documentation on how to install NetBSD/cobalt
		using NetBSD/pmax (!).
		Some minor bintrans updates (no real speed improvement) and
		other minor updates (playstation2 now uses the -o options).
20050414	Adding a dummy x86 (and AMD64) mode.
20050415	Adding some (32-bit and 16-bit) x86 instructions.
		Adding some initial support for non-SCSI, non-IDE floppy
		images. (The x86 mode can boot from these, more or less.)
		Moving the devices/ and include/ directories to src/devices/
		and src/include/, respectively.
20050416	Continuing on the x86 stuff. (Adding pc_bios.c and some simple
		support for software interrupts in 16-bit mode.)
20050417	Ripping out most of the x86 instruction decoding stuff, trying
		to rewrite it in a cleaner way.
		Disabling some of the least working CPU families in the
		configure script (sparc, x86, alpha, hppa), so that they are
		not enabled by default.
20050418	Trying to fix the bug which caused problems when turning on
		and off bintrans interactively, by flushing the bintrans cache
		whenever bintrans is manually (re)enabled.
20050419	Adding the 'lswi' ppc instruction.
		Minor updates to the x86 instruction decoding.
20050420	Renaming x86 register name indices from R_xx to X86_R_xx (this
		makes building on Tru64 nicer).
20050422	Adding a check for duplicate MIPS TLB entries on tlbwr/tlbwi.
20050427	Adding screenshots to guestoses.html.
		Some minor fixes and testing for the next release.

==============  RELEASE 0.3.2  ==============


1 /*
2 * Copyright (C) 2005 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: cpu_ppc.c,v 1.62 2005/04/18 23:00:56 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 "misc.h"
39
40
41 #ifndef ENABLE_PPC
42
43
44 #include "cpu_ppc.h"
45
46
47 /*
48 * ppc_cpu_family_init():
49 *
50 * Bogus function.
51 */
52 int ppc_cpu_family_init(struct cpu_family *fp)
53 {
54 return 0;
55 }
56
57
58 #else /* ENABLE_PPC */
59
60
61 #include "cpu.h"
62 #include "cpu_ppc.h"
63 #include "machine.h"
64 #include "memory.h"
65 #include "opcodes_ppc.h"
66 #include "symbol.h"
67
68
69 extern volatile int single_step;
70 extern int old_show_trace_tree;
71 extern int old_instruction_trace;
72 extern int old_quiet_mode;
73 extern int quiet_mode;
74
75
76 /*
77 * ppc_cpu_new():
78 *
79 * Create a new PPC cpu object.
80 */
81 struct cpu *ppc_cpu_new(struct memory *mem, struct machine *machine,
82 int cpu_id, char *cpu_type_name)
83 {
84 struct cpu *cpu;
85 int any_cache = 0;
86 int i, found;
87 struct ppc_cpu_type_def cpu_type_defs[] = PPC_CPU_TYPE_DEFS;
88
89 /* Scan the cpu_type_defs list for this cpu type: */
90 i = 0;
91 found = -1;
92 while (i >= 0 && cpu_type_defs[i].name != NULL) {
93 if (strcasecmp(cpu_type_defs[i].name, cpu_type_name) == 0) {
94 found = i;
95 break;
96 }
97 i++;
98 }
99 if (found == -1)
100 return NULL;
101
102 cpu = malloc(sizeof(struct cpu));
103 if (cpu == NULL) {
104 fprintf(stderr, "out of memory\n");
105 exit(1);
106 }
107
108 memset(cpu, 0, sizeof(struct cpu));
109 cpu->memory_rw = ppc_memory_rw;
110 cpu->cd.ppc.cpu_type = cpu_type_defs[found];
111 cpu->name = cpu->cd.ppc.cpu_type.name;
112 cpu->mem = mem;
113 cpu->machine = machine;
114 cpu->cpu_id = cpu_id;
115 cpu->byte_order = EMUL_BIG_ENDIAN;
116 cpu->cd.ppc.mode = MODE_PPC; /* TODO */
117 cpu->cd.ppc.of_emul_addr = 0xff000000; /* TODO */
118
119 /* Current operating mode: */
120 cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;
121 cpu->bootstrap_cpu_flag = 0;
122 cpu->running = 0;
123
124 /* Only show name and caches etc for CPU nr 0 (in SMP machines): */
125 if (cpu_id == 0) {
126 debug("%s", cpu->cd.ppc.cpu_type.name);
127
128 if (cpu->cd.ppc.cpu_type.icache_shift != 0)
129 any_cache = 1;
130 if (cpu->cd.ppc.cpu_type.dcache_shift != 0)
131 any_cache = 1;
132 if (cpu->cd.ppc.cpu_type.l2cache_shift != 0)
133 any_cache = 1;
134
135 if (any_cache) {
136 debug(" (I+D = %i+%i KB",
137 (int)(1 << (cpu->cd.ppc.cpu_type.icache_shift-10)),
138 (int)(1 << (cpu->cd.ppc.cpu_type.dcache_shift-10)));
139 if (cpu->cd.ppc.cpu_type.l2cache_shift != 0) {
140 debug(", L2 = %i KB",
141 (int)(1 << (cpu->cd.ppc.cpu_type.
142 l2cache_shift-10)));
143 }
144 debug(")");
145 }
146 }
147
148 cpu->cd.ppc.pir = cpu_id;
149
150 /* Some default stack pointer value. TODO: move this? */
151 cpu->cd.ppc.gpr[1] = machine->physical_ram_in_mb * 1048576 - 4096;
152
153 return cpu;
154 }
155
156
157 /*
158 * ppc_cpu_list_available_types():
159 *
160 * Print a list of available PPC CPU types.
161 */
162 void ppc_cpu_list_available_types(void)
163 {
164 int i, j;
165 struct ppc_cpu_type_def tdefs[] = PPC_CPU_TYPE_DEFS;
166
167 i = 0;
168 while (tdefs[i].name != NULL) {
169 debug("%s", tdefs[i].name);
170 for (j=10 - strlen(tdefs[i].name); j>0; j--)
171 debug(" ");
172 i++;
173 if ((i % 6) == 0 || tdefs[i].name == NULL)
174 debug("\n");
175 }
176 }
177
178
179 /*
180 * ppc_cpu_dumpinfo():
181 */
182 void ppc_cpu_dumpinfo(struct cpu *cpu)
183 {
184 struct ppc_cpu_type_def *ct = &cpu->cd.ppc.cpu_type;
185
186 debug(" (%i-bit ", cpu->cd.ppc.bits);
187
188 switch (cpu->cd.ppc.mode) {
189 case MODE_PPC:
190 debug("PPC");
191 break;
192 case MODE_POWER:
193 debug("POWER");
194 break;
195 default:
196 debug("_INTERNAL ERROR_");
197 }
198
199 debug(", I+D = %i+%i KB",
200 (1 << ct->icache_shift) / 1024,
201 (1 << ct->dcache_shift) / 1024);
202
203 if (ct->l2cache_shift) {
204 int kb = (1 << ct->l2cache_shift) / 1024;
205 debug(", L2 = %i %cB",
206 kb >= 1024? kb / 1024 : kb,
207 kb >= 1024? 'M' : 'K');
208 }
209
210 debug(")\n");
211 }
212
213
214 /*
215 * reg_access_msr():
216 */
217 static void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag)
218 {
219 if (valuep == NULL) {
220 fatal("reg_access_msr(): NULL\n");
221 return;
222 }
223
224 if (writeflag)
225 cpu->cd.ppc.msr = *valuep;
226
227 /* TODO: Is the little-endian bit writable? */
228
229 cpu->cd.ppc.msr &= ~PPC_MSR_LE;
230 if (cpu->byte_order != EMUL_BIG_ENDIAN)
231 cpu->cd.ppc.msr |= PPC_MSR_LE;
232
233 if (!writeflag)
234 *valuep = cpu->cd.ppc.msr;
235 }
236
237
238 /*
239 * ppc_cpu_register_dump():
240 *
241 * Dump cpu registers in a relatively readable format.
242 *
243 * gprs: set to non-zero to dump GPRs and some special-purpose registers.
244 * coprocs: set bit 0..3 to dump registers in coproc 0..3.
245 */
246 void ppc_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
247 {
248 char *symbol;
249 uint64_t offset, tmp;
250 int i, x = cpu->cpu_id;
251 int bits32 = cpu->cd.ppc.bits == 32;
252
253 if (gprs) {
254 /* Special registers (pc, ...) first: */
255 symbol = get_symbol_name(&cpu->machine->symbol_context,
256 cpu->pc, &offset);
257
258 debug("cpu%i: pc = 0x", x);
259 if (bits32)
260 debug("%08x", (int)cpu->pc);
261 else
262 debug("%016llx", (long long)cpu->pc);
263 debug(" <%s>\n", symbol != NULL? symbol : " no symbol ");
264
265 debug("cpu%i: lr = 0x", x);
266 if (bits32)
267 debug("%08x", (int)cpu->cd.ppc.lr);
268 else
269 debug("%016llx", (long long)cpu->cd.ppc.lr);
270 debug(" cr = 0x%08x\n", (int)cpu->cd.ppc.cr);
271
272 debug("cpu%i: ctr = 0x", x);
273 if (bits32)
274 debug("%08x", (int)cpu->cd.ppc.ctr);
275 else
276 debug("%016llx", (long long)cpu->cd.ppc.ctr);
277
278 debug(" xer = 0x", x);
279 if (bits32)
280 debug("%08x\n", (int)cpu->cd.ppc.xer);
281 else
282 debug("%016llx\n", (long long)cpu->cd.ppc.xer);
283
284 if (bits32) {
285 /* 32-bit: */
286 for (i=0; i<PPC_NGPRS; i++) {
287 if ((i % 4) == 0)
288 debug("cpu%i:", x);
289 debug(" r%02i = 0x%08x ", i,
290 (int)cpu->cd.ppc.gpr[i]);
291 if ((i % 4) == 3)
292 debug("\n");
293 }
294 } else {
295 /* 64-bit: */
296 for (i=0; i<PPC_NGPRS; i++) {
297 if ((i % 2) == 0)
298 debug("cpu%i:", x);
299 debug(" r%02i = 0x%016llx ", i,
300 (long long)cpu->cd.ppc.gpr[i]);
301 if ((i % 2) == 1)
302 debug("\n");
303 }
304 }
305
306 /* Other special registers: */
307 reg_access_msr(cpu, &tmp, 0);
308 debug("cpu%i: msr = 0x%016llx ", x, (long long)tmp);
309 debug("tb = 0x%08x%08x\n",
310 (int)cpu->cd.ppc.tbu, (int)cpu->cd.ppc.tbl);
311 debug("cpu%i: dec = 0x%08x hdec = 0x%08x\n",
312 x, (int)cpu->cd.ppc.dec, (int)cpu->cd.ppc.hdec);
313 }
314
315 if (coprocs) {
316 debug("cpu%i: fpscr = 0x%08x\n", x, (int)cpu->cd.ppc.fpscr);
317
318 /* TODO: show floating-point values :-) */
319
320 /* TODO: 32-bit fprs on 32-bit PPC cpus? */
321
322 for (i=0; i<PPC_NFPRS; i++) {
323 if ((i % 2) == 0)
324 debug("cpu%i:", x);
325 debug(" f%02i = 0x%016llx ", i,
326 (long long)cpu->cd.ppc.fpr[i]);
327 if ((i % 2) == 1)
328 debug("\n");
329 }
330 }
331 }
332
333
334 /*
335 * ppc_cpu_register_match():
336 */
337 void ppc_cpu_register_match(struct machine *m, char *name,
338 int writeflag, uint64_t *valuep, int *match_register)
339 {
340 int cpunr = 0;
341
342 /* CPU number: */
343
344 /* TODO */
345
346 /* Register name: */
347 if (strcasecmp(name, "pc") == 0) {
348 if (writeflag) {
349 m->cpus[cpunr]->pc = *valuep;
350 } else
351 *valuep = m->cpus[cpunr]->pc;
352 *match_register = 1;
353 } else if (strcasecmp(name, "msr") == 0) {
354 if (writeflag)
355 m->cpus[cpunr]->cd.ppc.msr = *valuep;
356 else
357 *valuep = m->cpus[cpunr]->cd.ppc.msr;
358 *match_register = 1;
359 } else if (strcasecmp(name, "lr") == 0) {
360 if (writeflag)
361 m->cpus[cpunr]->cd.ppc.lr = *valuep;
362 else
363 *valuep = m->cpus[cpunr]->cd.ppc.lr;
364 *match_register = 1;
365 } else if (strcasecmp(name, "cr") == 0) {
366 if (writeflag)
367 m->cpus[cpunr]->cd.ppc.cr = *valuep;
368 else
369 *valuep = m->cpus[cpunr]->cd.ppc.cr;
370 *match_register = 1;
371 } else if (strcasecmp(name, "dec") == 0) {
372 if (writeflag)
373 m->cpus[cpunr]->cd.ppc.dec = *valuep;
374 else
375 *valuep = m->cpus[cpunr]->cd.ppc.dec;
376 *match_register = 1;
377 } else if (strcasecmp(name, "hdec") == 0) {
378 if (writeflag)
379 m->cpus[cpunr]->cd.ppc.hdec = *valuep;
380 else
381 *valuep = m->cpus[cpunr]->cd.ppc.hdec;
382 *match_register = 1;
383 } else if (strcasecmp(name, "ctr") == 0) {
384 if (writeflag)
385 m->cpus[cpunr]->cd.ppc.ctr = *valuep;
386 else
387 *valuep = m->cpus[cpunr]->cd.ppc.ctr;
388 *match_register = 1;
389 } else if (name[0] == 'r' && isdigit((int)name[1])) {
390 int nr = atoi(name + 1);
391 if (nr >= 0 && nr < PPC_NGPRS) {
392 if (writeflag) {
393 m->cpus[cpunr]->cd.ppc.gpr[nr] = *valuep;
394 } else
395 *valuep = m->cpus[cpunr]->cd.ppc.gpr[nr];
396 *match_register = 1;
397 }
398 } else if (strcasecmp(name, "xer") == 0) {
399 if (writeflag)
400 m->cpus[cpunr]->cd.ppc.xer = *valuep;
401 else
402 *valuep = m->cpus[cpunr]->cd.ppc.xer;
403 *match_register = 1;
404 } else if (strcasecmp(name, "fpscr") == 0) {
405 if (writeflag)
406 m->cpus[cpunr]->cd.ppc.fpscr = *valuep;
407 else
408 *valuep = m->cpus[cpunr]->cd.ppc.fpscr;
409 *match_register = 1;
410 } else if (name[0] == 'f' && isdigit((int)name[1])) {
411 int nr = atoi(name + 1);
412 if (nr >= 0 && nr < PPC_NFPRS) {
413 if (writeflag) {
414 m->cpus[cpunr]->cd.ppc.fpr[nr] = *valuep;
415 } else
416 *valuep = m->cpus[cpunr]->cd.ppc.fpr[nr];
417 *match_register = 1;
418 }
419 }
420 }
421
422
423 /*
424 * ppc_cpu_disassemble_instr():
425 *
426 * Convert an instruction word into human readable format, for instruction
427 * tracing.
428 *
429 * If running is 1, cpu->pc should be the address of the instruction.
430 *
431 * If running is 0, things that depend on the runtime environment (eg.
432 * register contents) will not be shown, and addr will be used instead of
433 * cpu->pc for relative addresses.
434 */
435 int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
436 int running, uint64_t dumpaddr, int bintrans)
437 {
438 int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;
439 int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;
440 int bfa;
441 uint64_t offset, addr;
442 uint32_t iword;
443 char *symbol, *mnem = "ERROR";
444 int power = cpu->cd.ppc.mode == MODE_POWER;
445
446 if (running)
447 dumpaddr = cpu->pc;
448
449 symbol = get_symbol_name(&cpu->machine->symbol_context,
450 dumpaddr, &offset);
451 if (symbol != NULL && offset==0)
452 debug("<%s>\n", symbol);
453
454 if (cpu->machine->ncpus > 1 && running)
455 debug("cpu%i: ", cpu->cpu_id);
456
457 if (cpu->cd.ppc.bits == 32)
458 debug("%08x", (int)dumpaddr);
459 else
460 debug("%016llx", (long long)dumpaddr);
461
462 /* NOTE: Fixed to big-endian. */
463 iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
464 + instr[3];
465
466 debug(": %08x\t", iword);
467
468 if (bintrans && !running) {
469 debug("(bintrans)");
470 goto disasm_ret;
471 }
472
473 /*
474 * Decode the instruction:
475 */
476
477 hi6 = iword >> 26;
478
479 switch (hi6) {
480 case PPC_HI6_MULLI:
481 case PPC_HI6_SUBFIC:
482 rt = (iword >> 21) & 31;
483 ra = (iword >> 16) & 31;
484 imm = (int16_t)(iword & 0xffff);
485 switch (hi6) {
486 case PPC_HI6_MULLI:
487 mnem = power? "muli":"mulli";
488 break;
489 case PPC_HI6_SUBFIC:
490 mnem = power? "sfi":"subfic";
491 break;
492 }
493 debug("%s\tr%i,r%i,%i", mnem, rt, ra, imm);
494 break;
495 case PPC_HI6_CMPLI:
496 case PPC_HI6_CMPI:
497 bf = (iword >> 23) & 7;
498 l_bit = (iword >> 21) & 1;
499 ra = (iword >> 16) & 31;
500 if (hi6 == PPC_HI6_CMPLI) {
501 imm = iword & 0xffff;
502 mnem = "cmpl";
503 } else {
504 imm = (int16_t)(iword & 0xffff);
505 mnem = "cmp";
506 }
507 debug("%s%si\t", mnem, l_bit? "d" : "w");
508 if (bf != 0)
509 debug("cr%i,", bf);
510 debug("r%i,%i", ra, imm);
511 break;
512 case PPC_HI6_ADDIC:
513 case PPC_HI6_ADDIC_DOT:
514 rt = (iword >> 21) & 31;
515 ra = (iword >> 16) & 31;
516 rc = hi6 == PPC_HI6_ADDIC_DOT;
517 imm = (int16_t)(iword & 0xffff);
518 mnem = power? "ai":"addic";
519 if (imm < 0 && !power) {
520 mnem = "subic";
521 imm = -imm;
522 }
523 debug("%s%s\tr%i,r%i,%i", mnem, rc?".":"", rt, ra, imm);
524 break;
525 case PPC_HI6_ADDI:
526 rt = (iword >> 21) & 31;
527 ra = (iword >> 16) & 31;
528 imm = (int16_t)(iword & 0xffff);
529 if (ra == 0)
530 debug("li\tr%i,%i", rt, imm);
531 else {
532 mnem = power? "cal":"addi";
533 if (imm < 0 && !power) {
534 mnem = "subi";
535 imm = -imm;
536 }
537 debug("%s\tr%i,r%i,%i", mnem, rt, ra, imm);
538 }
539 break;
540 case PPC_HI6_ADDIS:
541 rt = (iword >> 21) & 31;
542 ra = (iword >> 16) & 31;
543 imm = (int16_t)(iword & 0xffff);
544 if (ra == 0)
545 debug("lis\tr%i,%i", rt, imm);
546 else
547 debug("%s\tr%i,r%i,%i",
548 power? "cau":"addis", rt, ra, imm);
549 break;
550 case PPC_HI6_BC:
551 aa_bit = (iword & 2) >> 1;
552 lk_bit = iword & 1;
553 bo = (iword >> 21) & 31;
554 bi = (iword >> 16) & 31;
555 /* Sign-extend addr: */
556 addr = (int64_t)(int16_t)(iword & 0xfffc);
557 debug("bc");
558 if (lk_bit)
559 debug("l");
560 if (aa_bit)
561 debug("a");
562 else
563 addr += dumpaddr;
564 debug("\t%i,%i,", bo, bi);
565 if (cpu->cd.ppc.bits == 32)
566 addr &= 0xffffffff;
567 if (cpu->cd.ppc.bits == 32)
568 debug("0x%x", (int)addr);
569 else
570 debug("0x%llx", (long long)addr);
571 symbol = get_symbol_name(&cpu->machine->symbol_context,
572 addr, &offset);
573 if (symbol != NULL)
574 debug("\t<%s>", symbol);
575 break;
576 case PPC_HI6_SC:
577 lev = (iword >> 5) & 0x7f;
578 debug("sc");
579 if (lev != 0) {
580 debug("\t%i", lev);
581 if (lev > 1)
582 debug(" (WARNING! reserved value)");
583 }
584 break;
585 case PPC_HI6_B:
586 aa_bit = (iword & 2) >> 1;
587 lk_bit = iword & 1;
588 /* Sign-extend addr: */
589 addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
590 addr = (int64_t)addr >> 6;
591 debug("b");
592 if (lk_bit)
593 debug("l");
594 if (aa_bit)
595 debug("a");
596 else
597 addr += dumpaddr;
598 if (cpu->cd.ppc.bits == 32)
599 addr &= 0xffffffff;
600 if (cpu->cd.ppc.bits == 32)
601 debug("\t0x%x", (int)addr);
602 else
603 debug("\t0x%llx", (long long)addr);
604 symbol = get_symbol_name(&cpu->machine->symbol_context,
605 addr, &offset);
606 if (symbol != NULL)
607 debug("\t<%s>", symbol);
608 break;
609 case PPC_HI6_19:
610 xo = (iword >> 1) & 1023;
611 switch (xo) {
612 case PPC_19_MCRF:
613 bf = (iword >> 23) & 7;
614 bfa = (iword >> 18) & 7;
615 debug("mcrf\tcr%i,cr%i", bf, bfa);
616 break;
617 case PPC_19_BCLR:
618 case PPC_19_BCCTR:
619 bo = (iword >> 21) & 31;
620 bi = (iword >> 16) & 31;
621 bh = (iword >> 11) & 3;
622 lk_bit = iword & 1;
623 switch (xo) {
624 case PPC_19_BCLR:
625 mnem = power? "bcr" : "bclr"; break;
626 case PPC_19_BCCTR:
627 mnem = power? "bcc" : "bcctr"; break;
628 }
629 debug("%s%s%s\t%i,%i,%i", mnem, lk_bit? "l" : "",
630 bh? (bh==3? "+" : (bh==2? "-" : "?")) : "",
631 bo, bi, bh);
632 break;
633 case PPC_19_ISYNC:
634 debug("%s", power? "ics" : "isync");
635 break;
636 case PPC_19_CRAND:
637 case PPC_19_CRXOR:
638 case PPC_19_CROR:
639 case PPC_19_CRNAND:
640 case PPC_19_CRNOR:
641 case PPC_19_CRANDC:
642 case PPC_19_CREQV:
643 case PPC_19_CRORC:
644 bt = (iword >> 21) & 31;
645 ba = (iword >> 16) & 31;
646 bb = (iword >> 11) & 31;
647 switch (xo) {
648 case PPC_19_CRAND: mnem = "crand"; break;
649 case PPC_19_CRXOR: mnem = "crxor"; break;
650 case PPC_19_CROR: mnem = "cror"; break;
651 case PPC_19_CRNAND: mnem = "crnand"; break;
652 case PPC_19_CRNOR: mnem = "crnor"; break;
653 case PPC_19_CRANDC: mnem = "crandc"; break;
654 case PPC_19_CREQV: mnem = "creqv"; break;
655 case PPC_19_CRORC: mnem = "crorc"; break;
656 }
657 debug("%s\t%i,%i,%i", mnem, bt, ba, bb);
658 break;
659 default:
660 debug("unimplemented hi6_19, xo = 0x%x", xo);
661 }
662 break;
663 case PPC_HI6_RLWIMI:
664 case PPC_HI6_RLWINM:
665 rs = (iword >> 21) & 31;
666 ra = (iword >> 16) & 31;
667 sh = (iword >> 11) & 31;
668 mb = (iword >> 6) & 31;
669 me = (iword >> 1) & 31;
670 rc = iword & 1;
671 switch (hi6) {
672 case PPC_HI6_RLWIMI:
673 mnem = power? "rlimi" : "rlwimi"; break;
674 case PPC_HI6_RLWINM:
675 mnem = power? "rlinm" : "rlwinm"; break;
676 }
677 debug("%s%s\tr%i,r%i,%i,%i,%i",
678 mnem, rc?".":"", ra, rs, sh, mb, me);
679 break;
680 case PPC_HI6_ORI:
681 case PPC_HI6_ORIS:
682 case PPC_HI6_XORI:
683 case PPC_HI6_XORIS:
684 case PPC_HI6_ANDI_DOT:
685 case PPC_HI6_ANDIS_DOT:
686 rs = (iword >> 21) & 31;
687 ra = (iword >> 16) & 31;
688 imm = iword & 0xffff;
689 switch (hi6) {
690 case PPC_HI6_ORI:
691 mnem = power? "oril":"ori";
692 break;
693 case PPC_HI6_ORIS:
694 mnem = power? "oriu":"oris";
695 break;
696 case PPC_HI6_XORI:
697 mnem = power? "xoril":"xori";
698 break;
699 case PPC_HI6_XORIS:
700 mnem = power? "xoriu":"xoris";
701 break;
702 case PPC_HI6_ANDI_DOT:
703 mnem = power? "andil.":"andi.";
704 break;
705 case PPC_HI6_ANDIS_DOT:
706 mnem = power? "andiu.":"andis.";
707 break;
708 }
709 if (hi6 == PPC_HI6_ORI && rs == 0 && ra == 0 && imm == 0)
710 debug("nop");
711 else
712 debug("%s\tr%i,r%i,0x%04x", mnem, ra, rs, imm);
713 break;
714 case PPC_HI6_30:
715 xo = (iword >> 2) & 7;
716 switch (xo) {
717 case PPC_30_RLDICR:
718 rs = (iword >> 21) & 31;
719 ra = (iword >> 16) & 31;
720 sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
721 me = ((iword >> 6) & 31) | (iword & 0x20);
722 rc = iword & 1;
723 debug("rldicr%s\tr%i,r%i,%i,%i",
724 rc?".":"", ra, rs, sh, me);
725 break;
726 default:
727 debug("unimplemented hi6_30, xo = 0x%x", xo);
728 }
729 break;
730 case PPC_HI6_31:
731 xo = (iword >> 1) & 1023;
732 switch (xo) {
733
734 case PPC_31_CMP:
735 case PPC_31_CMPL:
736 bf = (iword >> 23) & 7;
737 l_bit = (iword >> 21) & 1;
738 ra = (iword >> 16) & 31;
739 rb = (iword >> 11) & 31;
740 if (xo == PPC_31_CMPL)
741 mnem = "cmpl";
742 else
743 mnem = "cmp";
744 debug("%s%s\t", mnem, l_bit? "d" : "w");
745 if (bf != 0)
746 debug("cr%i,", bf);
747 debug("r%i,r%i", ra, rb);
748 break;
749 case PPC_31_MFCR:
750 rt = (iword >> 21) & 31;
751 debug("mfcr\tr%i", rt);
752 break;
753 case PPC_31_DCBST:
754 case PPC_31_ICBI:
755 ra = (iword >> 16) & 31;
756 rb = (iword >> 11) & 31;
757 switch (xo) {
758 case PPC_31_DCBST: mnem = "dcbst"; break;
759 case PPC_31_ICBI: mnem = "icbi"; break;
760 }
761 debug("%s\tr%i,r%i", mnem, ra, rb);
762 break;
763 case PPC_31_MFMSR:
764 rt = (iword >> 21) & 31;
765 debug("mfmsr\tr%i", rt);
766 break;
767 case PPC_31_MTCRF:
768 rs = (iword >> 21) & 31;
769 mb = (iword >> 12) & 255; /* actually fxm, not mb */
770 debug("mtcrf\t%i,r%i", mb, rs);
771 break;
772 case PPC_31_MTMSR:
773 rs = (iword >> 21) & 31;
774 l_bit = (iword >> 16) & 1;
775 debug("mtmsr\tr%i", rs);
776 if (l_bit)
777 debug(",%i", l_bit);
778 break;
779 case PPC_31_LBZX:
780 case PPC_31_LBZUX:
781 case PPC_31_LHZX:
782 case PPC_31_LHZUX:
783 case PPC_31_LWZX:
784 case PPC_31_LWZUX:
785 case PPC_31_STBX:
786 case PPC_31_STBUX:
787 case PPC_31_STHX:
788 case PPC_31_STHUX:
789 case PPC_31_STWX:
790 case PPC_31_STWUX:
791 /* rs for stores, rt for loads, actually */
792 rs = (iword >> 21) & 31;
793 ra = (iword >> 16) & 31;
794 rb = (iword >> 11) & 31;
795 switch (xo) {
796 case PPC_31_LBZX: mnem = "lbzx"; break;
797 case PPC_31_LBZUX: mnem = "lbzux"; break;
798 case PPC_31_LHZX: mnem = "lhzx"; break;
799 case PPC_31_LHZUX: mnem = "lhzux"; break;
800 case PPC_31_LWZX:
801 mnem = power? "lx" : "lwzx";
802 break;
803 case PPC_31_LWZUX:
804 mnem = power? "lux" : "lwzux";
805 break;
806 case PPC_31_STBX: mnem = "stbx"; break;
807 case PPC_31_STBUX: mnem = "stbux"; break;
808 case PPC_31_STHX: mnem = "sthx"; break;
809 case PPC_31_STHUX: mnem = "sthux"; break;
810 case PPC_31_STWX:
811 mnem = power? "stx" : "stwx";
812 break;
813 case PPC_31_STWUX:
814 mnem = power? "stux" : "stwux";
815 break;
816 }
817 debug("%s\tr%i,r%i,r%i", mnem, rs, ra, rb);
818 if (running)
819 goto disasm_ret_nonewline;
820 break;
821 case PPC_31_NEG:
822 case PPC_31_NEGO:
823 rt = (iword >> 21) & 31;
824 ra = (iword >> 16) & 31;
825 oe_bit = (iword >> 10) & 1;
826 rc = iword & 1;
827 switch (xo) {
828 case PPC_31_NEG: mnem = "neg"; break;
829 case PPC_31_NEGO: mnem = "nego"; break;
830 }
831 debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
832 break;
833 case PPC_31_ADDZE:
834 case PPC_31_ADDZEO:
835 rt = (iword >> 21) & 31;
836 ra = (iword >> 16) & 31;
837 oe_bit = (iword >> 10) & 1;
838 rc = iword & 1;
839 switch (xo) {
840 case PPC_31_ADDZE:
841 mnem = power? "aze" : "addze";
842 break;
843 case PPC_31_ADDZEO:
844 mnem = power? "azeo" : "addzeo";
845 break;
846 }
847 debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
848 break;
849 case PPC_31_MTSR:
850 /* Move to segment register (?) */
851 /* TODO */
852 debug("mtsr\tTODO");
853 break;
854 case PPC_31_MTSRIN:
855 case PPC_31_MFSRIN:
856 /* Move to/from segment register indirect */
857 rt = (iword >> 21) & 31;
858 rb = (iword >> 11) & 31;
859 switch (xo) {
860 case PPC_31_MTSRIN: mnem = "mtsrin"; break;
861 case PPC_31_MFSRIN: mnem = "mfsrin"; break;
862 }
863 debug("%s\tr%i,r%i", mnem, rt, rb);
864 break;
865 case PPC_31_ADDC:
866 case PPC_31_ADDCO:
867 case PPC_31_ADDE:
868 case PPC_31_ADDEO:
869 case PPC_31_ADD:
870 case PPC_31_ADDO:
871 case PPC_31_MULHW:
872 case PPC_31_MULHWU:
873 case PPC_31_MULLW:
874 case PPC_31_MULLWO:
875 case PPC_31_SUBF:
876 case PPC_31_SUBFO:
877 case PPC_31_SUBFC:
878 case PPC_31_SUBFCO:
879 case PPC_31_SUBFE:
880 case PPC_31_SUBFEO:
881 case PPC_31_SUBFZE:
882 case PPC_31_SUBFZEO:
883 rt = (iword >> 21) & 31;
884 ra = (iword >> 16) & 31;
885 rb = (iword >> 11) & 31;
886 oe_bit = (iword >> 10) & 1;
887 rc = iword & 1;
888 switch (xo) {
889 case PPC_31_ADDC:
890 mnem = power? "a" : "addc";
891 break;
892 case PPC_31_ADDCO:
893 mnem = power? "ao" : "addco";
894 break;
895 case PPC_31_ADDE:
896 mnem = power? "ae" : "adde";
897 break;
898 case PPC_31_ADDEO:
899 mnem = power? "aeo" : "addeo";
900 break;
901 case PPC_31_ADD:
902 mnem = power? "cax" : "add";
903 break;
904 case PPC_31_ADDO:
905 mnem = power? "caxo" : "addo";
906 break;
907 case PPC_31_MULHW: mnem = "mulhw"; break;
908 case PPC_31_MULHWU: mnem = "mulhwu"; break;
909 case PPC_31_MULLW:
910 mnem = power? "muls" : "mullw";
911 break;
912 case PPC_31_MULLWO:
913 mnem = power? "mulso" : "mullwo";
914 break;
915 case PPC_31_SUBF: mnem = "subf"; break;
916 case PPC_31_SUBFO: mnem = "subfo"; break;
917 case PPC_31_SUBFC:
918 mnem = power? "sf" : "subfc";
919 break;
920 case PPC_31_SUBFCO:
921 mnem = power? "sfo" : "subfco";
922 break;
923 case PPC_31_SUBFE:
924 mnem = power? "sfe" : "subfe";
925 break;
926 case PPC_31_SUBFEO:
927 mnem = power? "sfeo" : "subfeo";
928 break;
929 case PPC_31_SUBFZE:
930 mnem = power? "sfze" : "subfze";
931 break;
932 case PPC_31_SUBFZEO:
933 mnem = power? "sfzeo" : "subfzeo";
934 break;
935 }
936 debug("%s%s\tr%i,r%i,r%i", mnem, rc? "." : "",
937 rt, ra, rb);
938 break;
939 case PPC_31_MFSPR:
940 rt = (iword >> 21) & 31;
941 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
942 debug("mfspr\tr%i,spr%i", rt, spr);
943 break;
944 case PPC_31_TLBIE:
945 /* TODO: what is ra? The IBM online docs didn't say */
946 ra = 0;
947 rb = (iword >> 11) & 31;
948 if (power)
949 debug("tlbi\tr%i,r%i", ra, rb);
950 else
951 debug("tlbie\tr%i", rb);
952 break;
953 case PPC_31_TLBSYNC:
954 debug("tlbsync");
955 break;
956 case PPC_31_MFTB:
957 rt = (iword >> 21) & 31;
958 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
959 debug("mftb%s\tr%i", spr==268? "" :
960 (spr==269? "u" : "?"), rt);
961 break;
962 case PPC_31_CNTLZW:
963 rs = (iword >> 21) & 31;
964 ra = (iword >> 16) & 31;
965 rc = iword & 1;
966 mnem = power? "cntlz" : "cntlzw";
967 debug("%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
968 break;
969 case PPC_31_SLW:
970 case PPC_31_SRAW:
971 case PPC_31_SRW:
972 case PPC_31_AND:
973 case PPC_31_ANDC:
974 case PPC_31_NOR:
975 case PPC_31_OR:
976 case PPC_31_ORC:
977 case PPC_31_XOR:
978 case PPC_31_NAND:
979 rs = (iword >> 21) & 31;
980 ra = (iword >> 16) & 31;
981 rb = (iword >> 11) & 31;
982 rc = iword & 1;
983 if (rs == rb && xo == PPC_31_OR)
984 debug("mr%s\tr%i,r%i", rc? "." : "", ra, rs);
985 else {
986 switch (xo) {
987 case PPC_31_SLW: mnem =
988 power? "sl" : "slw"; break;
989 case PPC_31_SRAW: mnem =
990 power? "sra" : "sraw"; break;
991 case PPC_31_SRW: mnem =
992 power? "sr" : "srw"; break;
993 case PPC_31_AND: mnem = "and"; break;
994 case PPC_31_NAND: mnem = "nand"; break;
995 case PPC_31_ANDC: mnem = "andc"; break;
996 case PPC_31_NOR: mnem = "nor"; break;
997 case PPC_31_OR: mnem = "or"; break;
998 case PPC_31_ORC: mnem = "orc"; break;
999 case PPC_31_XOR: mnem = "xor"; break;
1000 }
1001 debug("%s%s\tr%i,r%i,r%i", mnem,
1002 rc? "." : "", ra, rs, rb);
1003 }
1004 break;
1005 case PPC_31_DCCCI:
1006 ra = (iword >> 16) & 31;
1007 rb = (iword >> 11) & 31;
1008 debug("dccci\tr%i,r%i", ra, rb);
1009 break;
1010 case PPC_31_ICCCI:
1011 ra = (iword >> 16) & 31;
1012 rb = (iword >> 11) & 31;
1013 debug("iccci\tr%i,r%i", ra, rb);
1014 break;
1015 case PPC_31_DIVW:
1016 case PPC_31_DIVWO:
1017 case PPC_31_DIVWU:
1018 case PPC_31_DIVWUO:
1019 rt = (iword >> 21) & 31;
1020 ra = (iword >> 16) & 31;
1021 rb = (iword >> 11) & 31;
1022 oe_bit = (iword >> 10) & 1;
1023 rc = iword & 1;
1024 switch (xo) {
1025 case PPC_31_DIVWU: mnem = "divwu"; break;
1026 case PPC_31_DIVWUO: mnem = "divwuo"; break;
1027 case PPC_31_DIVW: mnem = "divw"; break;
1028 case PPC_31_DIVWO: mnem = "divwo"; break;
1029 }
1030 debug("%s%s\tr%i,r%i,r%i", mnem, rc? "." : "",
1031 rt, ra, rb);
1032 break;
1033 case PPC_31_MTSPR:
1034 rs = (iword >> 21) & 31;
1035 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1036 debug("mtspr\tspr%i,r%i", spr, rs);
1037 break;
1038 case PPC_31_SYNC:
1039 debug("%s", power? "dcs" : "sync");
1040 break;
1041 case PPC_31_LSWI:
1042 case PPC_31_STSWI:
1043 rs = (iword >> 21) & 31; /* lwsi uses rt */
1044 ra = (iword >> 16) & 31;
1045 nb = (iword >> 11) & 31;
1046 switch (xo) {
1047 case PPC_31_LSWI:
1048 mnem = power? "lsi" : "lswi"; break;
1049 case PPC_31_STSWI:
1050 mnem = power? "stsi" : "stswi"; break;
1051 }
1052 debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);
1053 if (running)
1054 goto disasm_ret_nonewline;
1055 break;
1056 case PPC_31_SRAWI:
1057 rs = (iword >> 21) & 31;
1058 ra = (iword >> 16) & 31;
1059 sh = (iword >> 11) & 31;
1060 rc = iword & 1;
1061 mnem = power? "srai" : "srawi";
1062 debug("%s%s\tr%i,r%i,%i", mnem,
1063 rc? "." : "", ra, rs, sh);
1064 break;
1065 case PPC_31_EIEIO:
1066 debug("%s", power? "eieio?" : "eieio");
1067 break;
1068 case PPC_31_EXTSB:
1069 case PPC_31_EXTSH:
1070 case PPC_31_EXTSW:
1071 rs = (iword >> 21) & 31;
1072 ra = (iword >> 16) & 31;
1073 rc = iword & 1;
1074 switch (xo) {
1075 case PPC_31_EXTSB:
1076 mnem = power? "exts" : "extsb";
1077 break;
1078 case PPC_31_EXTSH:
1079 mnem = "extsh";
1080 break;
1081 case PPC_31_EXTSW:
1082 mnem = "extsw";
1083 break;
1084 }
1085 debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1086 break;
1087 default:
1088 debug("unimplemented hi6_31, xo = 0x%x", xo);
1089 }
1090 break;
1091 case PPC_HI6_LWZ:
1092 case PPC_HI6_LWZU:
1093 case PPC_HI6_LHZ:
1094 case PPC_HI6_LHZU:
1095 case PPC_HI6_LHA:
1096 case PPC_HI6_LHAU:
1097 case PPC_HI6_LBZ:
1098 case PPC_HI6_LBZU:
1099 case PPC_HI6_STW:
1100 case PPC_HI6_STWU:
1101 case PPC_HI6_STH:
1102 case PPC_HI6_STHU:
1103 case PPC_HI6_STB:
1104 case PPC_HI6_STBU:
1105 case PPC_HI6_STMW:
1106 case PPC_HI6_LFD:
1107 case PPC_HI6_STFD:
1108 /* NOTE: Loads use rt, not rs, but are otherwise similar
1109 to stores */
1110 rs = (iword >> 21) & 31;
1111 ra = (iword >> 16) & 31;
1112 imm = (int16_t)(iword & 0xffff);
1113 fpreg = 0;
1114 switch (hi6) {
1115 case PPC_HI6_LWZ: mnem = power? "l" : "lwz"; break;
1116 case PPC_HI6_LWZU: mnem = power? "lu" : "lwzu"; break;
1117 case PPC_HI6_LHZ: mnem = "lhz"; break;
1118 case PPC_HI6_LHZU: mnem = "lhzu"; break;
1119 case PPC_HI6_LHA: mnem = "lha"; break;
1120 case PPC_HI6_LHAU: mnem = "lhau"; break;
1121 case PPC_HI6_LBZ: mnem = "lbz"; break;
1122 case PPC_HI6_LBZU: mnem = "lbzu"; break;
1123 case PPC_HI6_STW: mnem = power? "st" : "stw"; break;
1124 case PPC_HI6_STWU: mnem = power? "stu" : "stwu"; break;
1125 case PPC_HI6_STH: mnem = "sth"; break;
1126 case PPC_HI6_STHU: mnem = "sthu"; break;
1127 case PPC_HI6_STB: mnem = "stb"; break;
1128 case PPC_HI6_STBU: mnem = "stbu"; break;
1129 case PPC_HI6_LMW: mnem = power? "lm" : "lmw"; break;
1130 case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1131 case PPC_HI6_LFD: fpreg = 1; mnem = "lfd"; break;
1132 case PPC_HI6_STFD: fpreg = 1; mnem = "stfd"; break;
1133 }
1134 debug("%s\t", mnem);
1135 if (fpreg)
1136 debug("f");
1137 else
1138 debug("r");
1139 debug("%i,%i(r%i)", rs, imm, ra);
1140 if (running)
1141 goto disasm_ret_nonewline;
1142 break;
1143 default:
1144 /* TODO */
1145 debug("unimplemented hi6 = 0x%02x", hi6);
1146 }
1147
1148 disasm_ret:
1149 debug("\n");
1150 disasm_ret_nonewline:
1151 return sizeof(iword);
1152 }
1153
1154
1155 /*
1156 * show_trace():
1157 *
1158 * Show trace tree. This function should be called every time
1159 * a function is called. cpu->cd.ppc.trace_tree_depth is increased here
1160 * and should not be increased by the caller.
1161 *
1162 * Note: This function should not be called if show_trace_tree == 0.
1163 */
1164 static void show_trace(struct cpu *cpu)
1165 {
1166 uint64_t offset, addr = cpu->pc;
1167 int x, n_args_to_print;
1168 char strbuf[60];
1169 char *symbol;
1170
1171 cpu->cd.ppc.trace_tree_depth ++;
1172
1173 if (cpu->machine->ncpus > 1)
1174 debug("cpu%i:", cpu->cpu_id);
1175
1176 symbol = get_symbol_name(&cpu->machine->symbol_context, addr, &offset);
1177
1178 for (x=0; x<cpu->cd.ppc.trace_tree_depth; x++)
1179 debug(" ");
1180
1181 /* debug("<%s>\n", symbol!=NULL? symbol : "no symbol"); */
1182
1183 if (symbol != NULL)
1184 debug("<%s(", symbol);
1185 else {
1186 debug("<0x");
1187 if (cpu->cd.ppc.bits == 32)
1188 debug("%08x", (int)addr);
1189 else
1190 debug("%016llx", (long long)addr);
1191 debug("(");
1192 }
1193
1194 /*
1195 * TODO: The number of arguments and the symbol type of each
1196 * argument should be taken from the symbol table, in some way.
1197 */
1198 n_args_to_print = 5;
1199
1200 for (x=0; x<n_args_to_print; x++) {
1201 int64_t d = cpu->cd.ppc.gpr[x + 3];
1202
1203 if (d > -256 && d < 256)
1204 debug("%i", (int)d);
1205 else if (memory_points_to_string(cpu, cpu->mem, d, 1)) {
1206 debug("\"%s\"", memory_conv_to_string(cpu,
1207 cpu->mem, d, strbuf, sizeof(strbuf)));
1208 if (strlen(strbuf) >= sizeof(strbuf)-1)
1209 debug("..");
1210 } else {
1211 if (cpu->cd.ppc.bits == 32)
1212 debug("0x%x", (int)d);
1213 else
1214 debug("0x%llx", (long long)d);
1215 }
1216
1217 if (x < n_args_to_print - 1)
1218 debug(",");
1219
1220 if (x == n_args_to_print - 1)
1221 break;
1222 }
1223
1224 if (n_args_to_print > 9)
1225 debug("..");
1226
1227 debug(")>\n");
1228 }
1229
1230
1231 /*
1232 * update_cr0():
1233 *
1234 * Sets the top 4 bits of the CR register.
1235 */
1236 static void update_cr0(struct cpu *cpu, uint64_t value)
1237 {
1238 int c;
1239
1240 if (cpu->cd.ppc.bits == 64) {
1241 if ((int64_t)value < 0)
1242 c = 8;
1243 else if ((int64_t)value > 0)
1244 c = 4;
1245 else
1246 c = 2;
1247 } else {
1248 if ((int32_t)value < 0)
1249 c = 8;
1250 else if ((int32_t)value > 0)
1251 c = 4;
1252 else
1253 c = 2;
1254 }
1255
1256 /* SO bit, copied from XER: */
1257 c |= ((cpu->cd.ppc.xer >> 31) & 1);
1258
1259 cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1260 cpu->cd.ppc.cr |= ((uint32_t)c << 28);
1261 }
1262
1263
1264 /*
1265 * ppc_cpu_run_instr():
1266 *
1267 * Execute one instruction on a specific CPU.
1268 *
1269 * Return value is the number of instructions executed during this call,
1270 * 0 if no instruction was executed.
1271 */
1272 int ppc_cpu_run_instr(struct emul *emul, struct cpu *cpu)
1273 {
1274 uint32_t iword;
1275 unsigned char buf[4];
1276 unsigned char tmp_data[8];
1277 size_t tmp_data_len;
1278 char *mnem = NULL;
1279 int r, hi6, rt, rs, ra, rb, xo, lev, sh, me, rc, imm, l_bit, oe_bit;
1280 int c, i, spr, aa_bit, bo, bi, bh, lk_bit, bf, ctr_ok, cond_ok;
1281 int update, load, mb, nb, bt, ba, bb, fpreg, arithflag, old_ca, bfa;
1282 uint64_t tmp=0, tmp2, addr;
1283 uint64_t cached_pc;
1284
1285 cached_pc = cpu->cd.ppc.pc_last = cpu->pc & ~3;
1286
1287 /* Check PC against breakpoints: */
1288 if (!single_step)
1289 for (i=0; i<cpu->machine->n_breakpoints; i++)
1290 if (cached_pc == cpu->machine->breakpoint_addr[i]) {
1291 fatal("Breakpoint reached, pc=0x");
1292 if (cpu->cd.ppc.bits == 32)
1293 fatal("%08x", (int)cached_pc);
1294 else
1295 fatal("%016llx", (long long)cached_pc);
1296 fatal("\n");
1297 single_step = 1;
1298 return 0;
1299 }
1300
1301 /* Update the Time Base and Decrementer: */
1302 if ((++ cpu->cd.ppc.tbl) == 0)
1303 cpu->cd.ppc.tbu ++;
1304
1305 cpu->cd.ppc.dec --;
1306 /* TODO: dec interrupt! */
1307
1308 /* TODO: hdec for POWER4+ */
1309
1310 /* ROM emulation: (TODO: non-OF-emuls) */
1311 if (cpu->pc == cpu->cd.ppc.of_emul_addr &&
1312 cpu->machine->prom_emulation) {
1313 int res = of_emul(cpu);
1314 if (res) {
1315 cpu->pc = cpu->cd.ppc.lr;
1316 }
1317 return 100;
1318 }
1319
1320 r = cpu->memory_rw(cpu, cpu->mem, cached_pc, &buf[0], sizeof(buf),
1321 MEM_READ, CACHE_INSTRUCTION | PHYSICAL);
1322 if (!r)
1323 return 0;
1324
1325 iword = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
1326
1327 if (cpu->machine->instruction_trace)
1328 ppc_cpu_disassemble_instr(cpu, buf, 1, 0, 0);
1329
1330 cpu->pc += sizeof(iword);
1331 cached_pc += sizeof(iword);
1332
1333 hi6 = iword >> 26;
1334
1335 switch (hi6) {
1336
1337 case PPC_HI6_MULLI:
1338 rt = (iword >> 21) & 31;
1339 ra = (iword >> 16) & 31;
1340 imm = (int16_t)(iword & 0xffff);
1341 cpu->cd.ppc.gpr[rt] = (int64_t)cpu->cd.ppc.gpr[ra]
1342 * (int64_t)imm;
1343 break;
1344
1345 case PPC_HI6_SUBFIC:
1346 rt = (iword >> 21) & 31;
1347 ra = (iword >> 16) & 31;
1348 imm = (int16_t)(iword & 0xffff);
1349 cpu->cd.ppc.xer &= ~PPC_XER_CA;
1350 if (cpu->cd.ppc.bits == 32) {
1351 tmp = (~cpu->cd.ppc.gpr[ra]) & 0xffffffff;
1352 cpu->cd.ppc.gpr[rt] = tmp + imm + 1;
1353 /* TODO: is this CA correct? */
1354 /* printf("subfic: tmp = %016llx\n", (long long)tmp);
1355 printf("subfic: rt = %016llx\n\n",
1356 (long long)cpu->cd.ppc.gpr[rt]); */
1357 if ((tmp >> 32) != (cpu->cd.ppc.gpr[rt] >> 32))
1358 cpu->cd.ppc.xer |= PPC_XER_CA;
1359 /* High 32 bits are probably undefined in
1360 32-bit mode (I hope) */
1361 } else {
1362 /*
1363 * Ugly, but I can't figure out a way right now how
1364 * to get the carry bit out of a 64-bit addition,
1365 * without access to more-than-64-bit operations in C.
1366 */
1367 tmp = ~cpu->cd.ppc.gpr[ra];
1368 tmp2 = (tmp >> 32); /* High 32 bits */
1369 tmp &= 0xffffffff; /* Low 32 bits */
1370
1371 tmp += imm + 1;
1372 if ((tmp >> 32) == 0) {
1373 /* No change to upper 32 bits */
1374 } else if ((tmp >> 32) == 1) {
1375 /* Positive change: */
1376 tmp2 ++;
1377 } else {
1378 /* Negative change: */
1379 tmp2 --;
1380 }
1381
1382 tmp &= 0xffffffff;
1383
1384 /* TODO: is this CA calculation correct? */
1385 if ((tmp2 >> 32) != 0)
1386 cpu->cd.ppc.xer |= PPC_XER_CA;
1387
1388 cpu->cd.ppc.gpr[rt] = (tmp2 << 32) + tmp;
1389 }
1390 break;
1391
1392 case PPC_HI6_CMPLI:
1393 case PPC_HI6_CMPI:
1394 bf = (iword >> 23) & 7;
1395 l_bit = (iword >> 21) & 1;
1396 ra = (iword >> 16) & 31;
1397 if (hi6 == PPC_HI6_CMPLI)
1398 imm = iword & 0xffff;
1399 else
1400 imm = (int16_t)(iword & 0xffff);
1401 tmp = cpu->cd.ppc.gpr[ra];
1402
1403 if (hi6 == PPC_HI6_CMPI) {
1404 if (!l_bit)
1405 tmp = (int64_t)(int32_t)tmp;
1406 if ((int64_t)tmp < (int64_t)imm)
1407 c = 8;
1408 else if ((int64_t)tmp > (int64_t)imm)
1409 c = 4;
1410 else
1411 c = 2;
1412 } else {
1413 if (!l_bit)
1414 tmp &= 0xffffffff;
1415 if ((uint64_t)tmp < (uint64_t)imm)
1416 c = 8;
1417 else if ((uint64_t)tmp > (uint64_t)imm)
1418 c = 4;
1419 else
1420 c = 2;
1421 }
1422
1423 /* SO bit, copied from XER: */
1424 c |= ((cpu->cd.ppc.xer >> 31) & 1);
1425
1426 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
1427 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
1428 break;
1429
1430 case PPC_HI6_ADDIC:
1431 case PPC_HI6_ADDIC_DOT:
1432 rt = (iword >> 21) & 31;
1433 ra = (iword >> 16) & 31;
1434 rc = hi6 == PPC_HI6_ADDIC_DOT;
1435 imm = (int16_t)(iword & 0xffff);
1436 /* NOTE: Addic doesn't clear CA! */
1437 if (cpu->cd.ppc.bits == 32) {
1438 tmp = cpu->cd.ppc.gpr[ra] & 0xffffffff;
1439 cpu->cd.ppc.gpr[rt] = tmp + (uint32_t)imm;
1440 /* TODO: is this CA correct? */
1441 /* printf("addic: tmp = %016llx\n", (long long)tmp);
1442 printf("addic: rt = %016llx\n\n",
1443 (long long)cpu->cd.ppc.gpr[rt]); */
1444 if ((tmp >> 32) != (cpu->cd.ppc.gpr[rt] >> 32))
1445 cpu->cd.ppc.xer |= PPC_XER_CA;
1446 /* High 32 bits are probably undefined in
1447 32-bit mode (I hope) */
1448 } else {
1449 /* See comment about ugliness regarding SUBFIC */
1450 tmp = cpu->cd.ppc.gpr[ra];
1451 tmp2 = (tmp >> 32); /* High 32 bits */
1452 tmp &= 0xffffffff; /* Low 32 bits */
1453
1454 tmp += (int64_t)imm;
1455 if ((tmp >> 32) == 0) {
1456 /* No change to upper 32 bits */
1457 } else if ((tmp >> 32) == 1) {
1458 /* Positive change: */
1459 tmp2 ++;
1460 } else {
1461 /* Negative change: */
1462 tmp2 --;
1463 }
1464
1465 tmp &= 0xffffffff;
1466
1467 /* TODO: is this CA calculation correct? */
1468 if ((tmp2 >> 32) != 0)
1469 cpu->cd.ppc.xer |= PPC_XER_CA;
1470
1471 cpu->cd.ppc.gpr[rt] = (tmp2 << 32) + tmp;
1472 }
1473 if (rc)
1474 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
1475 break;
1476
1477 case PPC_HI6_ADDI:
1478 case PPC_HI6_ADDIS:
1479 rt = (iword >> 21) & 31;
1480 ra = (iword >> 16) & 31;
1481 if (hi6 == PPC_HI6_ADDI)
1482 imm = (int16_t)(iword & 0xffff);
1483 else
1484 imm = (int32_t)((iword & 0xffff) << 16);
1485 if (ra == 0)
1486 tmp = 0;
1487 else
1488 tmp = cpu->cd.ppc.gpr[ra];
1489 cpu->cd.ppc.gpr[rt] = tmp + imm;
1490 break;
1491
1492 case PPC_HI6_BC:
1493 aa_bit = (iword >> 1) & 1;
1494 lk_bit = iword & 1;
1495 bo = (iword >> 21) & 31;
1496 bi = (iword >> 16) & 31;
1497 /* Sign-extend addr: */
1498 addr = (int64_t)(int16_t)(iword & 0xfffc);
1499
1500 if (!aa_bit)
1501 addr += cpu->cd.ppc.pc_last;
1502
1503 if (cpu->cd.ppc.bits == 32)
1504 addr &= 0xffffffff;
1505
1506 if (!(bo & 4))
1507 cpu->cd.ppc.ctr --;
1508 ctr_ok = (bo >> 2) & 1;
1509 tmp = cpu->cd.ppc.ctr;
1510 if (cpu->cd.ppc.bits == 32)
1511 tmp &= 0xffffffff;
1512 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
1513
1514 cond_ok = (bo >> 4) & 1;
1515 cond_ok |= ( ((bo >> 3) & 1) ==
1516 ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
1517
1518 if (lk_bit)
1519 cpu->cd.ppc.lr = cpu->pc;
1520 if (ctr_ok && cond_ok)
1521 cpu->pc = addr & ~3;
1522 if (lk_bit && cpu->machine->show_trace_tree)
1523 show_trace(cpu);
1524 break;
1525
1526 case PPC_HI6_SC:
1527 lev = (iword >> 5) & 0x7f;
1528 if (cpu->machine->userland_emul != NULL) {
1529 useremul_syscall(cpu, lev);
1530 } else {
1531 fatal("[ PPC: pc = 0x%016llx, sc not yet "
1532 "implemented ]\n", (long long)cached_pc);
1533 cpu->running = 0;
1534 return 0;
1535 }
1536 break;
1537
1538 case PPC_HI6_B:
1539 aa_bit = (iword & 2) >> 1;
1540 lk_bit = iword & 1;
1541 /* Sign-extend addr: */
1542 addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
1543 addr = (int64_t)addr >> 6;
1544
1545 if (!aa_bit)
1546 addr += cpu->cd.ppc.pc_last;
1547
1548 if (cpu->cd.ppc.bits == 32)
1549 addr &= 0xffffffff;
1550
1551 if (lk_bit)
1552 cpu->cd.ppc.lr = cpu->pc;
1553
1554 cpu->pc = addr;
1555
1556 if (lk_bit && cpu->machine->show_trace_tree)
1557 show_trace(cpu);
1558 break;
1559
1560 case PPC_HI6_19:
1561 xo = (iword >> 1) & 1023;
1562 switch (xo) {
1563
1564 case PPC_19_MCRF:
1565 bf = (iword >> 23) & 7;
1566 bfa = (iword >> 18) & 7;
1567 tmp = cpu->cd.ppc.cr >> (28 - bfa*4);
1568 tmp &= 0xf;
1569 cpu->cd.ppc.cr &= ~(0xf << (28 - bf*4));
1570 cpu->cd.ppc.cr |= (tmp << (28 - bf*4));
1571 break;
1572
1573 case PPC_19_BCLR:
1574 case PPC_19_BCCTR:
1575 bo = (iword >> 21) & 31;
1576 bi = (iword >> 16) & 31;
1577 bh = (iword >> 11) & 3;
1578 lk_bit = iword & 1;
1579 if (xo == PPC_19_BCLR) {
1580 addr = cpu->cd.ppc.lr;
1581 if (!(bo & 4))
1582 cpu->cd.ppc.ctr --;
1583 ctr_ok = (bo >> 2) & 1;
1584 tmp = cpu->cd.ppc.ctr;
1585 if (cpu->cd.ppc.bits == 32)
1586 tmp &= 0xffffffff;
1587 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
1588 if (!quiet_mode && !lk_bit &&
1589 cpu->machine->show_trace_tree) {
1590 cpu->cd.ppc.trace_tree_depth --;
1591 /* TODO: show return value? */
1592 }
1593 } else {
1594 addr = cpu->cd.ppc.ctr;
1595 ctr_ok = 1;
1596 }
1597 cond_ok = (bo >> 4) & 1;
1598 cond_ok |= ( ((bo >> 3) & 1) ==
1599 ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
1600 if (lk_bit)
1601 cpu->cd.ppc.lr = cpu->pc;
1602 if (ctr_ok && cond_ok) {
1603 cpu->pc = addr & ~3;
1604 if (cpu->cd.ppc.bits == 32)
1605 cpu->pc &= 0xffffffff;
1606 }
1607 if (lk_bit && cpu->machine->show_trace_tree)
1608 show_trace(cpu);
1609 break;
1610
1611 case PPC_19_ISYNC:
1612 /* TODO: actually sync */
1613 break;
1614
1615 case PPC_19_CRAND:
1616 case PPC_19_CRXOR:
1617 case PPC_19_CROR:
1618 case PPC_19_CRNAND:
1619 case PPC_19_CRNOR:
1620 case PPC_19_CRANDC:
1621 case PPC_19_CREQV:
1622 case PPC_19_CRORC:
1623 bt = (iword >> 21) & 31;
1624 ba = (iword >> 16) & 31;
1625 bb = (iword >> 11) & 31;
1626 ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1627 bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1628 cpu->cd.ppc.cr &= ~(1 << (31-bt));
1629 switch (xo) {
1630 case PPC_19_CRXOR:
1631 if (ba ^ bb)
1632 cpu->cd.ppc.cr |= (1 << (31-bt));
1633 break;
1634 case PPC_19_CROR:
1635 if (ba | bb)
1636 cpu->cd.ppc.cr |= (1 << (31-bt));
1637 break;
1638 default:
1639 fatal("[ TODO: crXXX, xo = %i, "
1640 "pc = 0x%016llx ]\n",
1641 xo, (long long) (cpu->cd.ppc.pc_last));
1642 cpu->running = 0;
1643 return 0;
1644 }
1645 break;
1646
1647 default:
1648 fatal("[ unimplemented PPC hi6_19, xo = 0x%04x, "
1649 "pc = 0x%016llx ]\n",
1650 xo, (long long) (cpu->cd.ppc.pc_last));
1651 cpu->running = 0;
1652 return 0;
1653 }
1654 break;
1655
1656 case PPC_HI6_RLWIMI:
1657 case PPC_HI6_RLWINM:
1658 rs = (iword >> 21) & 31;
1659 ra = (iword >> 16) & 31;
1660 sh = (iword >> 11) & 31;
1661 mb = (iword >> 6) & 31;
1662 me = (iword >> 1) & 31;
1663 rc = iword & 1;
1664 tmp = cpu->cd.ppc.gpr[rs];
1665 /* TODO: Fix this, its performance is awful: */
1666 while (sh-- != 0) {
1667 int b = (tmp >> 31) & 1;
1668 tmp = (tmp << 1) | b;
1669 }
1670
1671 switch (hi6) {
1672 case PPC_HI6_RLWIMI:
1673 for (;;) {
1674 uint64_t mask;
1675 mask = (uint64_t)1 << (31-mb);
1676 cpu->cd.ppc.gpr[ra] &= ~mask;
1677 cpu->cd.ppc.gpr[ra] |= (tmp & mask);
1678 if (mb == me)
1679 break;
1680 mb ++;
1681 if (mb == 32)
1682 mb = 0;
1683 }
1684 break;
1685 case PPC_HI6_RLWINM:
1686 cpu->cd.ppc.gpr[ra] = 0;
1687 for (;;) {
1688 uint64_t mask;
1689 mask = (uint64_t)1 << (31-mb);
1690 cpu->cd.ppc.gpr[ra] |= (tmp & mask);
1691 if (mb == me)
1692 break;
1693 mb ++;
1694 if (mb == 32)
1695 mb = 0;
1696 }
1697 break;
1698 }
1699 if (rc)
1700 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1701 break;
1702
1703 case PPC_HI6_ORI:
1704 case PPC_HI6_ORIS:
1705 rs = (iword >> 21) & 31;
1706 ra = (iword >> 16) & 31;
1707 if (hi6 == PPC_HI6_ORI)
1708 imm = (iword & 0xffff);
1709 else
1710 imm = (iword & 0xffff) << 16;
1711 tmp = cpu->cd.ppc.gpr[rs];
1712 cpu->cd.ppc.gpr[ra] = tmp | (uint32_t)imm;
1713 break;
1714
1715 case PPC_HI6_XORI:
1716 case PPC_HI6_XORIS:
1717 rs = (iword >> 21) & 31;
1718 ra = (iword >> 16) & 31;
1719 if (hi6 == PPC_HI6_XORI)
1720 imm = (iword & 0xffff);
1721 else
1722 imm = (iword & 0xffff) << 16;
1723 tmp = cpu->cd.ppc.gpr[rs];
1724 cpu->cd.ppc.gpr[ra] = tmp ^ (uint32_t)imm;
1725 break;
1726
1727 case PPC_HI6_ANDI_DOT:
1728 case PPC_HI6_ANDIS_DOT:
1729 rs = (iword >> 21) & 31;
1730 ra = (iword >> 16) & 31;
1731 if (hi6 == PPC_HI6_ANDI_DOT)
1732 imm = (iword & 0xffff);
1733 else
1734 imm = (iword & 0xffff) << 16;
1735 tmp = cpu->cd.ppc.gpr[rs];
1736 cpu->cd.ppc.gpr[ra] = tmp & (uint32_t)imm;
1737 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1738 break;
1739
1740 case PPC_HI6_30:
1741 xo = (iword >> 2) & 7;
1742 switch (xo) {
1743 case PPC_30_RLDICR:
1744 if (cpu->cd.ppc.bits == 32) {
1745 /* TODO: Illegal instruction. */
1746 break;
1747 }
1748 rs = (iword >> 21) & 31;
1749 ra = (iword >> 16) & 31;
1750 sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
1751 me = ((iword >> 6) & 31) | (iword & 0x20);
1752 rc = iword & 1;
1753 tmp = cpu->cd.ppc.gpr[rs];
1754 /* TODO: Fix this, its performance is awful: */
1755 while (sh-- != 0) {
1756 int b = (tmp >> 63) & 1;
1757 tmp = (tmp << 1) | b;
1758 }
1759 while (me++ < 63)
1760 tmp &= ~((uint64_t)1 << (63-me));
1761 cpu->cd.ppc.gpr[ra] = tmp;
1762 if (rc)
1763 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1764 break;
1765 default:
1766 fatal("[ unimplemented PPC hi6_30, xo = 0x%04x, "
1767 "pc = 0x%016llx ]\n",
1768 xo, (long long) (cpu->cd.ppc.pc_last));
1769 cpu->running = 0;
1770 return 0;
1771 }
1772 break;
1773
1774 case PPC_HI6_31:
1775 xo = (iword >> 1) & 1023;
1776 switch (xo) {
1777
1778 case PPC_31_CMPL:
1779 case PPC_31_CMP:
1780 bf = (iword >> 23) & 7;
1781 l_bit = (iword >> 21) & 1;
1782 ra = (iword >> 16) & 31;
1783 rb = (iword >> 11) & 31;
1784
1785 tmp = cpu->cd.ppc.gpr[ra];
1786 tmp2 = cpu->cd.ppc.gpr[rb];
1787
1788 if (hi6 == PPC_31_CMP) {
1789 if (!l_bit) {
1790 tmp = (int64_t)(int32_t)tmp;
1791 tmp2 = (int64_t)(int32_t)tmp2;
1792 }
1793 if ((int64_t)tmp < (int64_t)tmp2)
1794 c = 8;
1795 else if ((int64_t)tmp > (int64_t)tmp2)
1796 c = 4;
1797 else
1798 c = 2;
1799 } else {
1800 if (!l_bit) {
1801 tmp &= 0xffffffff;
1802 tmp2 &= 0xffffffff;
1803 }
1804 if ((uint64_t)tmp < (uint64_t)tmp2)
1805 c = 8;
1806 else if ((uint64_t)tmp > (uint64_t)tmp2)
1807 c = 4;
1808 else
1809 c = 2;
1810 }
1811
1812 /* SO bit, copied from XER: */
1813 c |= ((cpu->cd.ppc.xer >> 31) & 1);
1814
1815 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
1816 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
1817 break;
1818
1819 case PPC_31_MFCR:
1820 rt = (iword >> 21) & 31;
1821 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.cr;
1822 break;
1823
1824 case PPC_31_DCBST:
1825 case PPC_31_ICBI:
1826 ra = (iword >> 16) & 31;
1827 rb = (iword >> 11) & 31;
1828 switch (xo) {
1829 case PPC_31_DCBST: mnem = "dcbst"; break;
1830 case PPC_31_ICBI: mnem = "icbi"; break;
1831 }
1832 /* debug("[ %s r%i,r%i: TODO ]\n", mnem, ra, rb); */
1833 break;
1834
1835 case PPC_31_MFMSR:
1836 rt = (iword >> 21) & 31;
1837 /* TODO: check pr */
1838 reg_access_msr(cpu, &cpu->cd.ppc.gpr[rt], 0);
1839 break;
1840
1841 case PPC_31_MTCRF:
1842 rs = (iword >> 21) & 31;
1843 mb = (iword >> 12) & 255; /* actually fxm, not mb */
1844 tmp = 0;
1845 for (i=0; i<8; i++, mb <<= 1, tmp <<= 4)
1846 if (mb & 128)
1847 tmp |= 0xf;
1848 cpu->cd.ppc.cr &= ~tmp;
1849 cpu->cd.ppc.cr |= (cpu->cd.ppc.gpr[rs] & tmp);
1850 break;
1851
1852 case PPC_31_MTMSR:
1853 rs = (iword >> 21) & 31;
1854 l_bit = (iword >> 16) & 1;
1855 /* TODO: the l_bit */
1856 reg_access_msr(cpu, &cpu->cd.ppc.gpr[rs], 1);
1857 break;
1858
1859 case PPC_31_LBZX:
1860 case PPC_31_LBZUX:
1861 case PPC_31_LHZX:
1862 case PPC_31_LHZUX:
1863 case PPC_31_LWZX:
1864 case PPC_31_LWZUX:
1865 case PPC_31_STBX:
1866 case PPC_31_STBUX:
1867 case PPC_31_STHX:
1868 case PPC_31_STHUX:
1869 case PPC_31_STWX:
1870 case PPC_31_STWUX:
1871 rs = (iword >> 21) & 31;
1872 ra = (iword >> 16) & 31;
1873 rb = (iword >> 11) & 31;
1874 update = 0;
1875 switch (xo) {
1876 case PPC_31_LBZUX:
1877 case PPC_31_LHZUX:
1878 case PPC_31_LWZUX:
1879 case PPC_31_STBUX:
1880 case PPC_31_STHUX:
1881 case PPC_31_STWUX:
1882 update = 1;
1883 }
1884 if (ra == 0)
1885 addr = 0;
1886 else
1887 addr = cpu->cd.ppc.gpr[ra];
1888 addr += cpu->cd.ppc.gpr[rb];
1889 load = 0;
1890 switch (xo) {
1891 case PPC_31_LBZX:
1892 case PPC_31_LBZUX:
1893 case PPC_31_LHZX:
1894 case PPC_31_LHZUX:
1895 case PPC_31_LWZX:
1896 case PPC_31_LWZUX:
1897 load = 1;
1898 }
1899
1900 if (cpu->machine->instruction_trace) {
1901 if (cpu->cd.ppc.bits == 32)
1902 debug("\t[0x%08llx", (long long)addr);
1903 else
1904 debug("\t[0x%016llx", (long long)addr);
1905 }
1906
1907 tmp_data_len = 4;
1908 switch (xo) {
1909 case PPC_31_LBZX:
1910 case PPC_31_LBZUX:
1911 case PPC_31_STBX:
1912 case PPC_31_STBUX:
1913 tmp_data_len = 1;
1914 break;
1915 case PPC_31_LHZX:
1916 case PPC_31_LHZUX:
1917 case PPC_31_STHX:
1918 case PPC_31_STHUX:
1919 tmp_data_len = 2;
1920 break;
1921 }
1922
1923 tmp = 0;
1924
1925 if (load) {
1926 r = cpu->memory_rw(cpu, cpu->mem, addr,
1927 tmp_data, tmp_data_len, MEM_READ,
1928 CACHE_DATA);
1929 if (r == MEMORY_ACCESS_OK) {
1930 if (cpu->byte_order ==
1931 EMUL_BIG_ENDIAN) {
1932 for (i=0; i<tmp_data_len; i++) {
1933 tmp <<= 8;
1934 tmp += tmp_data[i];
1935 }
1936 } else {
1937 for (i=0; i<tmp_data_len; i++) {
1938 tmp <<= 8;
1939 tmp += tmp_data[
1940 tmp_data_len - 1
1941 - i];
1942 }
1943 }
1944 cpu->cd.ppc.gpr[rs] = tmp;
1945 }
1946 } else {
1947 tmp = cpu->cd.ppc.gpr[rs];
1948 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1949 for (i=0; i<tmp_data_len; i++)
1950 tmp_data[tmp_data_len-1-i] =
1951 tmp >> (8*i);
1952 } else {
1953 for (i=0; i<tmp_data_len; i++)
1954 tmp_data[i] = tmp >> (8*i);
1955 }
1956
1957 r = cpu->memory_rw(cpu, cpu->mem, addr,
1958 tmp_data, tmp_data_len, MEM_WRITE,
1959 CACHE_DATA);
1960 }
1961
1962 if (cpu->machine->instruction_trace) {
1963 if (r == MEMORY_ACCESS_OK) {
1964 switch (tmp_data_len) {
1965 case 1: debug(", data = 0x%02x]\n",
1966 (int)tmp);
1967 break;
1968 case 2: debug(", data = 0x%04x]\n",
1969 (int)tmp);
1970 break;
1971 case 4: debug(", data = 0x%08x]\n",
1972 (int)tmp);
1973 break;
1974 default:debug(", data = 0x%016llx]\n",
1975 (long long)tmp);
1976 }
1977 } else
1978 debug(", FAILED]\n");
1979 }
1980
1981 if (r != MEMORY_ACCESS_OK) {
1982 /* TODO: exception? */
1983 return 0;
1984 }
1985
1986 if (update && ra != 0)
1987 cpu->cd.ppc.gpr[ra] = addr;
1988 break;
1989
1990 case PPC_31_NEG:
1991 case PPC_31_NEGO:
1992 rt = (iword >> 21) & 31;
1993 ra = (iword >> 16) & 31;
1994 oe_bit = (iword >> 10) & 1;
1995 rc = iword & 1;
1996 if (oe_bit) {
1997 fatal("[ neg: PPC oe not yet implemeted ]\n");
1998 cpu->running = 0;
1999 return 0;
2000 }
2001 cpu->cd.ppc.gpr[rt] = ~cpu->cd.ppc.gpr[ra] + 1;
2002 if (rc)
2003 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2004 break;
2005
2006 case PPC_31_ADDZE:
2007 case PPC_31_ADDZEO:
2008 rt = (iword >> 21) & 31;
2009 ra = (iword >> 16) & 31;
2010 oe_bit = (iword >> 10) & 1;
2011 rc = iword & 1;
2012 if (oe_bit) {
2013 fatal("[ addz: PPC oe not yet implemeted ]\n");
2014 cpu->running = 0;
2015 return 0;
2016 }
2017 old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2018 cpu->cd.ppc.xer &= PPC_XER_CA;
2019 if (cpu->cd.ppc.bits == 32) {
2020 tmp = (uint32_t)cpu->cd.ppc.gpr[ra];
2021 tmp2 = tmp;
2022 /* printf("addze: tmp2 = %016llx\n",
2023 (long long)tmp2); */
2024 if (old_ca)
2025 tmp ++;
2026 /* printf("addze: tmp = %016llx\n\n",
2027 (long long)tmp); */
2028 /* TODO: is this CA correct? */
2029 if ((tmp >> 32) != (tmp2 >> 32))
2030 cpu->cd.ppc.xer |= PPC_XER_CA;
2031 /* High 32 bits are probably undefined
2032 in 32-bit mode (I hope) */
2033 cpu->cd.ppc.gpr[rt] = tmp;
2034 } else {
2035 fatal("ADDZE 64-bit, TODO\n");
2036 }
2037 if (rc)
2038 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2039 break;
2040
2041 case PPC_31_MTSR:
2042 /* Move to segment register (?) */
2043 /* TODO */
2044 break;
2045
2046 case PPC_31_MFSRIN:
2047 case PPC_31_MTSRIN:
2048 /* mfsrin: Move to segment register indirect (?) */
2049 /* mtsrin: Move to segment register indirect (?) */
2050 rt = (iword >> 21) & 31;
2051 rb = (iword >> 11) & 31;
2052
2053 /* TODO */
2054
2055 if (xo == PPC_31_MFSRIN)
2056 cpu->cd.ppc.gpr[rt] = 0;
2057 break;
2058
2059 case PPC_31_ADDC:
2060 case PPC_31_ADDCO:
2061 case PPC_31_ADDE:
2062 case PPC_31_ADDEO:
2063 case PPC_31_ADD:
2064 case PPC_31_ADDO:
2065 case PPC_31_MULHW:
2066 case PPC_31_MULHWU:
2067 case PPC_31_MULLW:
2068 case PPC_31_MULLWO:
2069 case PPC_31_SUBFE:
2070 case PPC_31_SUBFEO:
2071 case PPC_31_SUBFZE:
2072 case PPC_31_SUBFZEO:
2073 case PPC_31_SUBFC:
2074 case PPC_31_SUBFCO:
2075 case PPC_31_SUBF:
2076 case PPC_31_SUBFO:
2077 rt = (iword >> 21) & 31;
2078 ra = (iword >> 16) & 31;
2079 rb = (iword >> 11) & 31;
2080 oe_bit = (iword >> 10) & 1;
2081 rc = iword & 1;
2082 if (oe_bit) {
2083 fatal("[ add: PPC oe not yet implemeted ]\n");
2084 cpu->running = 0;
2085 return 0;
2086 }
2087 switch (xo) {
2088 case PPC_31_ADD:
2089 case PPC_31_ADDO:
2090 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.gpr[ra] +
2091 cpu->cd.ppc.gpr[rb];
2092 break;
2093 case PPC_31_ADDC:
2094 case PPC_31_ADDCO:
2095 case PPC_31_ADDE:
2096 case PPC_31_ADDEO:
2097 old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2098 cpu->cd.ppc.xer &= PPC_XER_CA;
2099 if (cpu->cd.ppc.bits == 32) {
2100 tmp = (uint32_t)cpu->cd.ppc.gpr[ra];
2101 tmp2 = tmp;
2102 /* printf("adde: tmp2 = %016llx\n",
2103 (long long)tmp2); */
2104 tmp += (uint32_t)cpu->cd.ppc.gpr[rb];
2105 if ((xo == PPC_31_ADDE ||
2106 xo == PPC_31_ADDEO) && old_ca)
2107 tmp ++;
2108 /* printf("adde: tmp = %016llx\n\n",
2109 (long long)tmp); */
2110 /* TODO: is this CA correct? */
2111 if ((tmp >> 32) != (tmp2 >> 32))
2112 cpu->cd.ppc.xer |= PPC_XER_CA;
2113 /* High 32 bits are probably undefined
2114 in 32-bit mode (I hope) */
2115 cpu->cd.ppc.gpr[rt] = tmp;
2116 } else {
2117 fatal("ADDE 64-bit, TODO\n");
2118 }
2119 break;
2120 case PPC_31_MULHW:
2121 cpu->cd.ppc.gpr[rt] = (int64_t) (
2122 (int64_t)(int32_t)cpu->cd.ppc.gpr[ra] *
2123 (int64_t)(int32_t)cpu->cd.ppc.gpr[rb]);
2124 cpu->cd.ppc.gpr[rt] >>= 32;
2125 break;
2126 case PPC_31_MULHWU:
2127 cpu->cd.ppc.gpr[rt] = (uint64_t) (
2128 (uint64_t)(uint32_t)cpu->cd.ppc.gpr[ra] *
2129 (uint64_t)(uint32_t)cpu->cd.ppc.gpr[rb]);
2130 cpu->cd.ppc.gpr[rt] >>= 32;
2131 break;
2132 case PPC_31_MULLW:
2133 case PPC_31_MULLWO:
2134 cpu->cd.ppc.gpr[rt] = (int64_t) (
2135 (int32_t)cpu->cd.ppc.gpr[ra] *
2136 (int32_t)cpu->cd.ppc.gpr[rb]);
2137 break;
2138 case PPC_31_SUBF:
2139 case PPC_31_SUBFO:
2140 cpu->cd.ppc.gpr[rt] = ~cpu->cd.ppc.gpr[ra] +
2141 cpu->cd.ppc.gpr[rb] + 1;
2142 break;
2143 case PPC_31_SUBFC:
2144 case PPC_31_SUBFCO:
2145 case PPC_31_SUBFE:
2146 case PPC_31_SUBFEO:
2147 case PPC_31_SUBFZE:
2148 case PPC_31_SUBFZEO:
2149 old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2150 if (xo == PPC_31_SUBFC || xo == PPC_31_SUBFCO)
2151 old_ca = 1;
2152 cpu->cd.ppc.xer &= PPC_XER_CA;
2153 if (cpu->cd.ppc.bits == 32) {
2154 tmp = (~cpu->cd.ppc.gpr[ra])
2155 & 0xffffffff;
2156 tmp2 = tmp;
2157 if (xo != PPC_31_SUBFZE &&
2158 xo != PPC_31_SUBFZEO)
2159 tmp += (cpu->cd.ppc.gpr[rb] &
2160 0xffffffff);
2161 if (old_ca)
2162 tmp ++;
2163 /* printf("subfe: tmp2 = %016llx\n",
2164 (long long)tmp2);
2165 printf("subfe: tmp = %016llx\n\n",
2166 (long long)tmp); */
2167 /* TODO: is this CA correct? */
2168 if ((tmp >> 32) != (tmp2 >> 32))
2169 cpu->cd.ppc.xer |= PPC_XER_CA;
2170 /* High 32 bits are probably undefined
2171 in 32-bit mode (I hope) */
2172 cpu->cd.ppc.gpr[rt] = tmp;
2173 } else {
2174 fatal("SUBFE 64-bit, TODO\n");
2175 }
2176 break;
2177 }
2178 if (rc)
2179 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2180 break;
2181
2182 case PPC_31_MFSPR:
2183 case PPC_31_MFTB:
2184 rt = (iword >> 21) & 31;
2185 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2186 switch (spr) {
2187 case 1: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.xer;
2188 break;
2189 case 8: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.lr;
2190 break;
2191 case 9: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.ctr;
2192 break;
2193 case 22:/* TODO: check pr */
2194 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.dec;
2195 break;
2196 case 259: /* NOTE: no pr check */
2197 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg3;
2198 break;
2199 case 268: /* MFTB, NOTE: no pr check */
2200 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.tbl;
2201 break;
2202 case 269: /* MFTBU, NOTE: no pr check */
2203 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.tbu;
2204 break;
2205 case 272:
2206 /* TODO: check pr */
2207 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg0;
2208 break;
2209 case 273:
2210 /* TODO: check pr */
2211 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg1;
2212 break;
2213 case 274:
2214 /* TODO: check pr */
2215 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg2;
2216 break;
2217 case 275:
2218 /* TODO: check pr */
2219 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg3;
2220 break;
2221 case 287:
2222 /* TODO: check pr */
2223 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.pvr;
2224 break;
2225 case 310:/* TODO: check pr */
2226 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.hdec;
2227 break;
2228 case 1023:
2229 /* TODO: check pr */
2230 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.pir;
2231 break;
2232 default:
2233 fatal("[ unimplemented PPC spr 0x%04x, "
2234 "pc = 0x%016llx ]\n",
2235 spr, (long long) (cpu->cd.ppc.pc_last));
2236 /* cpu->running = 0;
2237 return 0; */
2238 break;
2239 }
2240
2241 /* TODO: is this correct? */
2242 if (cpu->cd.ppc.bits == 32)
2243 cpu->cd.ppc.gpr[rt] &= 0xffffffff;
2244 break;
2245
2246 case PPC_31_CNTLZW:
2247 rs = (iword >> 21) & 31;
2248 ra = (iword >> 16) & 31;
2249 rc = iword & 1;
2250 cpu->cd.ppc.gpr[ra] = 0;
2251 for (i=0; i<32; i++) {
2252 if (cpu->cd.ppc.gpr[rs] &
2253 ((uint64_t)1 << (31-i)))
2254 break;
2255 cpu->cd.ppc.gpr[ra] ++;
2256 }
2257 if (rc)
2258 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2259 break;
2260
2261 case PPC_31_SLW:
2262 case PPC_31_SRAW:
2263 case PPC_31_SRW:
2264 case PPC_31_AND:
2265 case PPC_31_ANDC:
2266 case PPC_31_NOR:
2267 case PPC_31_OR:
2268 case PPC_31_ORC:
2269 case PPC_31_XOR:
2270 case PPC_31_NAND:
2271 rs = (iword >> 21) & 31;
2272 ra = (iword >> 16) & 31;
2273 rb = (iword >> 11) & 31;
2274 rc = iword & 1;
2275 switch (xo) {
2276 case PPC_31_SLW:
2277 sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2278 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs];
2279 while (sh-- > 0)
2280 cpu->cd.ppc.gpr[ra] <<= 1;
2281 cpu->cd.ppc.gpr[ra] &= 0xffffffff;
2282 break;
2283 case PPC_31_SRAW:
2284 tmp = cpu->cd.ppc.gpr[rs] & 0xffffffff;
2285 cpu->cd.ppc.xer &= ~PPC_XER_CA;
2286 i = 0;
2287 sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2288 if (tmp & 0x80000000)
2289 i = 1;
2290 while (sh-- > 0) {
2291 if (tmp & 1)
2292 i++;
2293 tmp >>= 1;
2294 if (tmp & 0x40000000)
2295 tmp |= 0x80000000;
2296 }
2297 cpu->cd.ppc.gpr[ra] = (int64_t)(int32_t)tmp;
2298 /* Set the CA bit if rs contained a negative
2299 number to begin with, and any 1-bits were
2300 shifted out: */
2301 if (i > 1)
2302 cpu->cd.ppc.xer |= PPC_XER_CA;
2303 break;
2304 case PPC_31_SRW:
2305 sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2306 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs]
2307 & 0xffffffff;
2308 while (sh-- > 0)
2309 cpu->cd.ppc.gpr[ra] >>= 1;
2310 break;
2311 case PPC_31_AND:
2312 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] &
2313 cpu->cd.ppc.gpr[rb];
2314 break;
2315 case PPC_31_ANDC:
2316 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] &
2317 (~cpu->cd.ppc.gpr[rb]);
2318 break;
2319 case PPC_31_NOR:
2320 cpu->cd.ppc.gpr[ra] = ~(cpu->cd.ppc.gpr[rs] |
2321 cpu->cd.ppc.gpr[rb]);
2322 break;
2323 case PPC_31_OR:
2324 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] |
2325 cpu->cd.ppc.gpr[rb];
2326 break;
2327 case PPC_31_ORC:
2328 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] |
2329 (~cpu->cd.ppc.gpr[rb]);
2330 break;
2331 case PPC_31_XOR:
2332 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] ^
2333 cpu->cd.ppc.gpr[rb];
2334 break;
2335 case PPC_31_NAND:
2336 cpu->cd.ppc.gpr[ra] = ~(cpu->cd.ppc.gpr[rs]
2337 & cpu->cd.ppc.gpr[rb]);
2338 break;
2339 }
2340 if (rc)
2341 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2342 break;
2343
2344 case PPC_31_TLBIE:
2345 rb = (iword >> 11) & 31;
2346 /* TODO */
2347 break;
2348
2349 case PPC_31_TLBSYNC:
2350 /* Only on 603 and 604 (?) */
2351
2352 /* TODO */
2353 break;
2354
2355 case PPC_31_DCCCI:
2356 case PPC_31_ICCCI:
2357 /* Supervisor IBM 4xx Data Cache Congruence Class
2358 Invalidate, see www.xilinx.com/publications/
2359 xcellonline/partners/xc_pdf/xc_ibm_pwrpc42.pdf
2360 or similar */
2361 /* ICCCI is probably Instruction... blah blah */
2362 /* TODO */
2363 break;
2364
2365 case PPC_31_DIVWU:
2366 case PPC_31_DIVWUO:
2367 case PPC_31_DIVW:
2368 case PPC_31_DIVWO:
2369 rt = (iword >> 21) & 31;
2370 ra = (iword >> 16) & 31;
2371 rb = (iword >> 11) & 31;
2372 oe_bit = (iword >> 10) & 1;
2373 rc = iword & 1;
2374 switch (xo) {
2375 case PPC_31_DIVWU:
2376 case PPC_31_DIVWUO:
2377 tmp = cpu->cd.ppc.gpr[ra] & 0xffffffff;
2378 tmp2 = cpu->cd.ppc.gpr[rb] & 0xffffffff;
2379 if (tmp2 == 0) {
2380 /* Undefined: */
2381 tmp = 0;
2382 } else {
2383 tmp = tmp / tmp2;
2384 }
2385 cpu->cd.ppc.gpr[rt] = (int64_t)(int32_t)tmp;
2386 break;
2387 case PPC_31_DIVW:
2388 case PPC_31_DIVWO:
2389 tmp = (int64_t)(int32_t)cpu->cd.ppc.gpr[ra];
2390 tmp2 = (int64_t)(int32_t)cpu->cd.ppc.gpr[rb];
2391 if (tmp2 == 0) {
2392 /* Undefined: */
2393 tmp = 0;
2394 } else {
2395 tmp = (int64_t)tmp / (int64_t)tmp2;
2396 }
2397 cpu->cd.ppc.gpr[rt] = (int64_t)(int32_t)tmp;
2398 break;
2399 }
2400 if (rc)
2401 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2402 if (oe_bit) {
2403 fatal("[ divwu: PPC oe not yet implemeted ]\n");
2404 cpu->running = 0;
2405 return 0;
2406 }
2407 break;
2408
2409 case PPC_31_MTSPR:
2410 rs = (iword >> 21) & 31;
2411 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2412 switch (spr) {
2413 case 1: cpu->cd.ppc.xer = cpu->cd.ppc.gpr[rs];
2414 break;
2415 case 8: cpu->cd.ppc.lr = cpu->cd.ppc.gpr[rs];
2416 break;
2417 case 9: cpu->cd.ppc.ctr = cpu->cd.ppc.gpr[rs];
2418 break;
2419 case 22: /* TODO: check pr */
2420 cpu->cd.ppc.dec = cpu->cd.ppc.gpr[rs];
2421 break;
2422 case 272:
2423 /* TODO: check hypv */
2424 cpu->cd.ppc.sprg0 = cpu->cd.ppc.gpr[rs];
2425 break;
2426 case 273:
2427 /* TODO: check pr */
2428 cpu->cd.ppc.sprg1 = cpu->cd.ppc.gpr[rs];
2429 break;
2430 case 274:
2431 /* TODO: check pr */
2432 cpu->cd.ppc.sprg2 = cpu->cd.ppc.gpr[rs];
2433 break;
2434 case 275:
2435 /* TODO: check pr */
2436 cpu->cd.ppc.sprg3 = cpu->cd.ppc.gpr[rs];
2437 break;
2438 case 284:
2439 /* TODO: check pr */
2440 cpu->cd.ppc.tbl = cpu->cd.ppc.gpr[rs];
2441 break;
2442 case 285:
2443 /* TODO: check pr */
2444 cpu->cd.ppc.tbu = cpu->cd.ppc.gpr[rs];
2445 break;
2446 case 287:
2447 fatal("[ PPC: attempt to write to PVR ]\n");
2448 break;
2449 case 310: /* TODO: check hypv */
2450 cpu->cd.ppc.hdec = cpu->cd.ppc.gpr[rs];
2451 break;
2452 case 1023:
2453 /* TODO: check pr */
2454 cpu->cd.ppc.pir = cpu->cd.ppc.gpr[rs];
2455 break;
2456 default:
2457 fatal("[ unimplemented PPC spr 0x%04x, "
2458 "pc = 0x%016llx ]\n",
2459 spr, (long long) (cpu->cd.ppc.pc_last));
2460 /* cpu->running = 0;
2461 return 0; */
2462 break;
2463 }
2464 break;
2465
2466 case PPC_31_SYNC:
2467 /* TODO: actually sync */
2468 break;
2469
2470 case PPC_31_LSWI:
2471 case PPC_31_STSWI:
2472 rs = (iword >> 21) & 31;
2473 ra = (iword >> 16) & 31;
2474 nb = (iword >> 11) & 31;
2475 if (nb == 0)
2476 nb = 32;
2477 if (ra == 0)
2478 addr = 0;
2479 else
2480 addr = cpu->cd.ppc.gpr[ra];
2481
2482 load = 0;
2483 if (xo == PPC_31_LSWI)
2484 load = 1;
2485
2486 if (cpu->machine->instruction_trace) {
2487 if (cpu->cd.ppc.bits == 32)
2488 debug("\t[0x%08llx", (long long)addr);
2489 else
2490 debug("\t[0x%016llx", (long long)addr);
2491 }
2492
2493 i = 24;
2494 r = 0; /* Error count. */
2495 while (nb-- > 0) {
2496 if (load) {
2497 /* (Actually rt should be used.) */
2498 if (cpu->memory_rw(cpu, cpu->mem, addr,
2499 tmp_data, 1, MEM_READ, CACHE_DATA)
2500 != MEMORY_ACCESS_OK) {
2501 r++;
2502 break;
2503 }
2504 if (i == 24)
2505 cpu->cd.ppc.gpr[rs] = 0;
2506 cpu->cd.ppc.gpr[rs] |=
2507 (tmp_data[0] << i);
2508 } else {
2509 tmp_data[0] = cpu->cd.ppc.gpr[rs] >> i;
2510 if (cpu->memory_rw(cpu, cpu->mem, addr,
2511 tmp_data, 1, MEM_WRITE, CACHE_DATA)
2512 != MEMORY_ACCESS_OK) {
2513 r++;
2514 break;
2515 }
2516 }
2517 addr++; i-=8;
2518 if (i < 0) {
2519 i = 24;
2520 rs = (rs + 1) % 32;
2521 }
2522 }
2523
2524 if (cpu->machine->instruction_trace) {
2525 if (r == 0)
2526 debug(", ...]\n");
2527 else
2528 debug(", FAILED]\n");
2529 }
2530
2531 if (r > 0) {
2532 /* TODO: exception */
2533 fatal("TODO: exception.\n");
2534 return 0;
2535 }
2536 break;
2537
2538 case PPC_31_SRAWI:
2539 rs = (iword >> 21) & 31;
2540 ra = (iword >> 16) & 31;
2541 sh = (iword >> 11) & 31;
2542 rc = iword & 1;
2543 tmp = cpu->cd.ppc.gpr[rs] & 0xffffffff;
2544 cpu->cd.ppc.xer &= ~PPC_XER_CA;
2545 i = 0;
2546 if (tmp & 0x80000000)
2547 i = 1;
2548 while (sh-- > 0) {
2549 if (tmp & 1)
2550 i++;
2551 tmp >>= 1;
2552 if (tmp & 0x40000000)
2553 tmp |= 0x80000000;
2554 }
2555 cpu->cd.ppc.gpr[ra] = (int64_t)(int32_t)tmp;
2556 /* Set the CA bit if rs contained a negative
2557 number to begin with, and any 1-bits were
2558 shifted out: */
2559 if (i > 1)
2560 cpu->cd.ppc.xer |= PPC_XER_CA;
2561 if (rc)
2562 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2563 break;
2564
2565 case PPC_31_EIEIO:
2566 /* TODO: actually eieio */
2567 break;
2568
2569 case PPC_31_EXTSB:
2570 case PPC_31_EXTSH:
2571 case PPC_31_EXTSW:
2572 rs = (iword >> 21) & 31;
2573 ra = (iword >> 16) & 31;
2574 rc = iword & 1;
2575 switch (xo) {
2576 case PPC_31_EXTSB:
2577 cpu->cd.ppc.gpr[ra] = (int64_t)
2578 (int8_t)cpu->cd.ppc.gpr[rs];
2579 break;
2580 case PPC_31_EXTSH:
2581 cpu->cd.ppc.gpr[ra] = (int64_t)
2582 (int16_t)cpu->cd.ppc.gpr[rs];
2583 break;
2584 case PPC_31_EXTSW:
2585 cpu->cd.ppc.gpr[ra] = (int64_t)
2586 (int32_t)cpu->cd.ppc.gpr[rs];
2587 break;
2588 }
2589 if (rc)
2590 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2591 break;
2592
2593 default:
2594 fatal("[ unimplemented PPC hi6_31, xo = 0x%04x, "
2595 "pc = 0x%016llx ]\n",
2596 xo, (long long) (cpu->cd.ppc.pc_last));
2597 cpu->running = 0;
2598 return 0;
2599 }
2600 break;
2601
2602 case PPC_HI6_LWZ:
2603 case PPC_HI6_LWZU:
2604 case PPC_HI6_LHZ:
2605 case PPC_HI6_LHZU:
2606 case PPC_HI6_LHA:
2607 case PPC_HI6_LHAU:
2608 case PPC_HI6_LBZ:
2609 case PPC_HI6_LBZU:
2610 case PPC_HI6_STW:
2611 case PPC_HI6_STWU:
2612 case PPC_HI6_STH:
2613 case PPC_HI6_STHU:
2614 case PPC_HI6_STB:
2615 case PPC_HI6_STBU:
2616 case PPC_HI6_LFD:
2617 case PPC_HI6_STFD:
2618 /* NOTE: Loads use rt, not rs, but are otherwise similar
2619 to stores. This code uses rs for both. */
2620 rs = (iword >> 21) & 31;
2621 ra = (iword >> 16) & 31;
2622 imm = (int16_t)(iword & 0xffff);
2623
2624 fpreg = 0; load = 1; update = 0; tmp_data_len = 4;
2625 arithflag = 0;
2626
2627 switch (hi6) {
2628 case PPC_HI6_LWZU:
2629 case PPC_HI6_LHZU:
2630 case PPC_HI6_LHAU:
2631 case PPC_HI6_LBZU:
2632 case PPC_HI6_STBU:
2633 case PPC_HI6_STHU:
2634 case PPC_HI6_STWU:
2635 update = 1;
2636 }
2637
2638 switch (hi6) {
2639 case PPC_HI6_STW:
2640 case PPC_HI6_STWU:
2641 case PPC_HI6_STH:
2642 case PPC_HI6_STHU:
2643 case PPC_HI6_STB:
2644 case PPC_HI6_STBU:
2645 case PPC_HI6_STFD:
2646 load = 0;
2647 }
2648
2649 switch (hi6) {
2650 case PPC_HI6_LFD:
2651 case PPC_HI6_STFD:
2652 tmp_data_len = 8;
2653 break;
2654 case PPC_HI6_LBZ:
2655 case PPC_HI6_LBZU:
2656 case PPC_HI6_STB:
2657 case PPC_HI6_STBU:
2658 tmp_data_len = 1;
2659 break;
2660 case PPC_HI6_LHZ:
2661 case PPC_HI6_LHZU:
2662 case PPC_HI6_LHA:
2663 case PPC_HI6_LHAU:
2664 case PPC_HI6_STH:
2665 case PPC_HI6_STHU:
2666 tmp_data_len = 2;
2667 break;
2668 }
2669
2670 switch (hi6) {
2671 case PPC_HI6_LFD:
2672 case PPC_HI6_STFD:
2673 fpreg = 1;
2674 }
2675
2676 switch (hi6) {
2677 case PPC_HI6_LHA:
2678 case PPC_HI6_LHAU:
2679 arithflag = 1;
2680 }
2681
2682 if (ra == 0) {
2683 if (update)
2684 fatal("[ PPC WARNING: invalid Update form ]\n");
2685 addr = 0;
2686 } else
2687 addr = cpu->cd.ppc.gpr[ra];
2688
2689 if (load && update && ra == rs)
2690 fatal("[ PPC WARNING: invalid Update load form ]\n");
2691
2692 addr += imm;
2693
2694 /* TODO: alignment check? */
2695
2696 if (cpu->machine->instruction_trace) {
2697 if (cpu->cd.ppc.bits == 32)
2698 debug("\t[0x%08llx", (long long)addr);
2699 else
2700 debug("\t[0x%016llx", (long long)addr);
2701 }
2702
2703 if (load) {
2704 r = cpu->memory_rw(cpu, cpu->mem, addr, tmp_data,
2705 tmp_data_len, MEM_READ, CACHE_DATA);
2706
2707 if (r == MEMORY_ACCESS_OK) {
2708 tmp = 0;
2709 if (arithflag) {
2710 if (cpu->byte_order ==
2711 EMUL_BIG_ENDIAN) {
2712 if (tmp_data[0] & 0x80)
2713 tmp --;
2714 } else {
2715 if (tmp_data[tmp_data_len-1]
2716 & 0x80)
2717 tmp --;
2718 }
2719 }
2720 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2721 for (i=0; i<tmp_data_len; i++) {
2722 tmp <<= 8;
2723 tmp += tmp_data[i];
2724 }
2725 } else {
2726 for (i=0; i<tmp_data_len; i++) {
2727 tmp <<= 8;
2728 tmp += tmp_data[
2729 tmp_data_len - 1 -i];
2730 }
2731 }
2732
2733 if (!fpreg)
2734 cpu->cd.ppc.gpr[rs] = tmp;
2735 else
2736 cpu->cd.ppc.fpr[rs] = tmp;
2737 }
2738 } else {
2739 if (!fpreg)
2740 tmp = cpu->cd.ppc.gpr[rs];
2741 else
2742 tmp = cpu->cd.ppc.fpr[rs];
2743
2744 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2745 for (i=0; i<tmp_data_len; i++)
2746 tmp_data[tmp_data_len-1-i] =
2747 tmp >> (8*i);
2748 } else {
2749 for (i=0; i<tmp_data_len; i++)
2750 tmp_data[i] = tmp >> (8*i);
2751 }
2752
2753 r = cpu->memory_rw(cpu, cpu->mem, addr, tmp_data,
2754 tmp_data_len, MEM_WRITE, CACHE_DATA);
2755 }
2756
2757 if (cpu->machine->instruction_trace) {
2758 if (r == MEMORY_ACCESS_OK) {
2759 switch (tmp_data_len) {
2760 case 1: debug(", data = 0x%02x]\n", (int)tmp);
2761 break;
2762 case 2: debug(", data = 0x%04x]\n", (int)tmp);
2763 break;
2764 case 4: debug(", data = 0x%08x]\n", (int)tmp);
2765 break;
2766 default:debug(", data = 0x%016llx]\n",
2767 (long long)tmp);
2768 }
2769 } else
2770 debug(", FAILED]\n");
2771 }
2772
2773 if (r != MEMORY_ACCESS_OK) {
2774 /* TODO: exception? */
2775 return 0;
2776 }
2777
2778 if (update && ra != 0)
2779 cpu->cd.ppc.gpr[ra] = addr;
2780 break;
2781
2782 case PPC_HI6_LMW:
2783 case PPC_HI6_STMW:
2784 /* NOTE: Loads use rt, not rs, but are otherwise similar
2785 to stores. This code uses rs for both. */
2786 rs = (iword >> 21) & 31;
2787 ra = (iword >> 16) & 31;
2788 imm = (int16_t)(iword & 0xffff);
2789
2790 load = 1; tmp_data_len = 4;
2791
2792 switch (hi6) {
2793 case PPC_HI6_STMW:
2794 load = 0;
2795 }
2796
2797 if (ra == 0) {
2798 addr = 0;
2799 } else
2800 addr = cpu->cd.ppc.gpr[ra];
2801
2802 if (load && rs == 0)
2803 fatal("[ PPC WARNING: invalid LMW form ]\n");
2804
2805 addr += imm;
2806
2807 /* TODO: alignment check? */
2808
2809 if (cpu->machine->instruction_trace) {
2810 if (cpu->cd.ppc.bits == 32)
2811 debug("\t[0x%08llx", (long long)addr);
2812 else
2813 debug("\t[0x%016llx", (long long)addr);
2814 }
2815
2816 /* There can be multiple errors! */
2817 r = 0;
2818
2819 while (rs <= 31) {
2820 if (load) {
2821 if (cpu->memory_rw(cpu, cpu->mem, addr,
2822 tmp_data, tmp_data_len, MEM_READ,
2823 CACHE_DATA) != MEMORY_ACCESS_OK)
2824 r++;
2825
2826 if (r == 0) {
2827 tmp = 0;
2828 if (cpu->byte_order ==
2829 EMUL_BIG_ENDIAN) {
2830 for (i=0; i<tmp_data_len; i++) {
2831 tmp <<= 8;
2832 tmp += tmp_data[i];
2833 }
2834 } else {
2835 for (i=0; i<tmp_data_len; i++) {
2836 tmp <<= 8;
2837 tmp += tmp_data[
2838 tmp_data_len - 1
2839 - i];
2840 }
2841 }
2842
2843 cpu->cd.ppc.gpr[rs] = tmp;
2844 }
2845 } else {
2846 tmp = cpu->cd.ppc.gpr[rs];
2847
2848 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2849 for (i=0; i<tmp_data_len; i++)
2850 tmp_data[tmp_data_len-1-i] =
2851 tmp >> (8*i);
2852 } else {
2853 for (i=0; i<tmp_data_len; i++)
2854 tmp_data[i] = tmp >> (8*i);
2855 }
2856
2857 if (cpu->memory_rw(cpu, cpu->mem, addr,
2858 tmp_data, tmp_data_len, MEM_WRITE,
2859 CACHE_DATA) != MEMORY_ACCESS_OK)
2860 r ++;
2861 }
2862
2863 /* TODO: Exception! */
2864
2865 /* Go to next register, multiword... */
2866 rs ++;
2867 addr += tmp_data_len;
2868 }
2869
2870 if (cpu->machine->instruction_trace) {
2871 if (r == 0) {
2872 debug(", data = ...]\n");
2873 } else
2874 debug(", FAILED]\n");
2875 }
2876
2877 if (r > 0)
2878 return 0;
2879 break;
2880
2881 default:
2882 fatal("[ unimplemented PPC hi6 = 0x%02x, pc = 0x%016llx ]\n",
2883 hi6, (long long) (cpu->cd.ppc.pc_last));
2884 cpu->running = 0;
2885 return 0;
2886 }
2887
2888 return 1;
2889 }
2890
2891
2892 #define CPU_RUN ppc_cpu_run
2893 #define CPU_RINSTR ppc_cpu_run_instr
2894 #define CPU_RUN_PPC
2895 #include "cpu_run.c"
2896 #undef CPU_RINSTR
2897 #undef CPU_RUN_PPC
2898 #undef CPU_RUN
2899
2900
2901 #define MEMORY_RW ppc_memory_rw
2902 #define MEM_PPC
2903 #include "memory_rw.c"
2904 #undef MEM_PPC
2905 #undef MEMORY_RW
2906
2907
2908 /*
2909 * ppc_cpu_family_init():
2910 *
2911 * Fill in the cpu_family struct for PPC.
2912 */
2913 int ppc_cpu_family_init(struct cpu_family *fp)
2914 {
2915 fp->name = "PPC";
2916 fp->cpu_new = ppc_cpu_new;
2917 fp->list_available_types = ppc_cpu_list_available_types;
2918 fp->register_match = ppc_cpu_register_match;
2919 fp->disassemble_instr = ppc_cpu_disassemble_instr;
2920 fp->register_dump = ppc_cpu_register_dump;
2921 fp->run = ppc_cpu_run;
2922 fp->dumpinfo = ppc_cpu_dumpinfo;
2923 /* fp->show_full_statistics = ppc_cpu_show_full_statistics; */
2924 /* fp->tlbdump = ppc_cpu_tlbdump; */
2925 /* fp->interrupt = ppc_cpu_interrupt; */
2926 /* fp->interrupt_ack = ppc_cpu_interrupt_ack; */
2927 return 1;
2928 }
2929
2930
2931 #endif /* ENABLE_PPC */

  ViewVC Help
Powered by ViewVC 1.1.26