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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Mon Oct 8 16:17:52 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 68845 byte(s)
0.3.1
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.61 2005/04/01 16:44:36 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_STSWI:
1042 rs = (iword >> 21) & 31;
1043 ra = (iword >> 16) & 31;
1044 nb = (iword >> 11) & 31;
1045 debug("%s\tr%i,r%i,%i", power? "stsi" : "stswi",
1046 rs, ra, nb);
1047 if (running)
1048 goto disasm_ret_nonewline;
1049 break;
1050 case PPC_31_SRAWI:
1051 rs = (iword >> 21) & 31;
1052 ra = (iword >> 16) & 31;
1053 sh = (iword >> 11) & 31;
1054 rc = iword & 1;
1055 mnem = power? "srai" : "srawi";
1056 debug("%s%s\tr%i,r%i,%i", mnem,
1057 rc? "." : "", ra, rs, sh);
1058 break;
1059 case PPC_31_EIEIO:
1060 debug("%s", power? "eieio?" : "eieio");
1061 break;
1062 case PPC_31_EXTSB:
1063 case PPC_31_EXTSH:
1064 case PPC_31_EXTSW:
1065 rs = (iword >> 21) & 31;
1066 ra = (iword >> 16) & 31;
1067 rc = iword & 1;
1068 switch (xo) {
1069 case PPC_31_EXTSB:
1070 mnem = power? "exts" : "extsb";
1071 break;
1072 case PPC_31_EXTSH:
1073 mnem = "extsh";
1074 break;
1075 case PPC_31_EXTSW:
1076 mnem = "extsw";
1077 break;
1078 }
1079 debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1080 break;
1081 default:
1082 debug("unimplemented hi6_31, xo = 0x%x", xo);
1083 }
1084 break;
1085 case PPC_HI6_LWZ:
1086 case PPC_HI6_LWZU:
1087 case PPC_HI6_LHZ:
1088 case PPC_HI6_LHZU:
1089 case PPC_HI6_LHA:
1090 case PPC_HI6_LHAU:
1091 case PPC_HI6_LBZ:
1092 case PPC_HI6_LBZU:
1093 case PPC_HI6_STW:
1094 case PPC_HI6_STWU:
1095 case PPC_HI6_STH:
1096 case PPC_HI6_STHU:
1097 case PPC_HI6_STB:
1098 case PPC_HI6_STBU:
1099 case PPC_HI6_STMW:
1100 case PPC_HI6_LFD:
1101 case PPC_HI6_STFD:
1102 /* NOTE: Loads use rt, not rs, but are otherwise similar
1103 to stores */
1104 rs = (iword >> 21) & 31;
1105 ra = (iword >> 16) & 31;
1106 imm = (int16_t)(iword & 0xffff);
1107 fpreg = 0;
1108 switch (hi6) {
1109 case PPC_HI6_LWZ: mnem = power? "l" : "lwz"; break;
1110 case PPC_HI6_LWZU: mnem = power? "lu" : "lwzu"; break;
1111 case PPC_HI6_LHZ: mnem = "lhz"; break;
1112 case PPC_HI6_LHZU: mnem = "lhzu"; break;
1113 case PPC_HI6_LHA: mnem = "lha"; break;
1114 case PPC_HI6_LHAU: mnem = "lhau"; break;
1115 case PPC_HI6_LBZ: mnem = "lbz"; break;
1116 case PPC_HI6_LBZU: mnem = "lbzu"; break;
1117 case PPC_HI6_STW: mnem = power? "st" : "stw"; break;
1118 case PPC_HI6_STWU: mnem = power? "stu" : "stwu"; break;
1119 case PPC_HI6_STH: mnem = "sth"; break;
1120 case PPC_HI6_STHU: mnem = "sthu"; break;
1121 case PPC_HI6_STB: mnem = "stb"; break;
1122 case PPC_HI6_STBU: mnem = "stbu"; break;
1123 case PPC_HI6_LMW: mnem = power? "lm" : "lmw"; break;
1124 case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1125 case PPC_HI6_LFD: fpreg = 1; mnem = "lfd"; break;
1126 case PPC_HI6_STFD: fpreg = 1; mnem = "stfd"; break;
1127 }
1128 debug("%s\t", mnem);
1129 if (fpreg)
1130 debug("f");
1131 else
1132 debug("r");
1133 debug("%i,%i(r%i)", rs, imm, ra);
1134 if (running)
1135 goto disasm_ret_nonewline;
1136 break;
1137 default:
1138 /* TODO */
1139 debug("unimplemented hi6 = 0x%02x", hi6);
1140 }
1141
1142 disasm_ret:
1143 debug("\n");
1144 disasm_ret_nonewline:
1145 return sizeof(iword);
1146 }
1147
1148
1149 /*
1150 * show_trace():
1151 *
1152 * Show trace tree. This function should be called every time
1153 * a function is called. cpu->cd.ppc.trace_tree_depth is increased here
1154 * and should not be increased by the caller.
1155 *
1156 * Note: This function should not be called if show_trace_tree == 0.
1157 */
1158 static void show_trace(struct cpu *cpu)
1159 {
1160 uint64_t offset, addr = cpu->pc;
1161 int x, n_args_to_print;
1162 char strbuf[60];
1163 char *symbol;
1164
1165 cpu->cd.ppc.trace_tree_depth ++;
1166
1167 if (cpu->machine->ncpus > 1)
1168 debug("cpu%i:", cpu->cpu_id);
1169
1170 symbol = get_symbol_name(&cpu->machine->symbol_context, addr, &offset);
1171
1172 for (x=0; x<cpu->cd.ppc.trace_tree_depth; x++)
1173 debug(" ");
1174
1175 /* debug("<%s>\n", symbol!=NULL? symbol : "no symbol"); */
1176
1177 if (symbol != NULL)
1178 debug("<%s(", symbol);
1179 else {
1180 debug("<0x");
1181 if (cpu->cd.ppc.bits == 32)
1182 debug("%08x", (int)addr);
1183 else
1184 debug("%016llx", (long long)addr);
1185 debug("(");
1186 }
1187
1188 /*
1189 * TODO: The number of arguments and the symbol type of each
1190 * argument should be taken from the symbol table, in some way.
1191 */
1192 n_args_to_print = 5;
1193
1194 for (x=0; x<n_args_to_print; x++) {
1195 int64_t d = cpu->cd.ppc.gpr[x + 3];
1196
1197 if (d > -256 && d < 256)
1198 debug("%i", (int)d);
1199 else if (memory_points_to_string(cpu, cpu->mem, d, 1)) {
1200 debug("\"%s\"", memory_conv_to_string(cpu,
1201 cpu->mem, d, strbuf, sizeof(strbuf)));
1202 if (strlen(strbuf) >= sizeof(strbuf)-1)
1203 debug("..");
1204 } else {
1205 if (cpu->cd.ppc.bits == 32)
1206 debug("0x%x", (int)d);
1207 else
1208 debug("0x%llx", (long long)d);
1209 }
1210
1211 if (x < n_args_to_print - 1)
1212 debug(",");
1213
1214 if (x == n_args_to_print - 1)
1215 break;
1216 }
1217
1218 if (n_args_to_print > 9)
1219 debug("..");
1220
1221 debug(")>\n");
1222 }
1223
1224
1225 /*
1226 * update_cr0():
1227 *
1228 * Sets the top 4 bits of the CR register.
1229 */
1230 static void update_cr0(struct cpu *cpu, uint64_t value)
1231 {
1232 int c;
1233
1234 if (cpu->cd.ppc.bits == 64) {
1235 if ((int64_t)value < 0)
1236 c = 8;
1237 else if ((int64_t)value > 0)
1238 c = 4;
1239 else
1240 c = 2;
1241 } else {
1242 if ((int32_t)value < 0)
1243 c = 8;
1244 else if ((int32_t)value > 0)
1245 c = 4;
1246 else
1247 c = 2;
1248 }
1249
1250 /* SO bit, copied from XER: */
1251 c |= ((cpu->cd.ppc.xer >> 31) & 1);
1252
1253 cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1254 cpu->cd.ppc.cr |= ((uint32_t)c << 28);
1255 }
1256
1257
1258 /*
1259 * ppc_cpu_run_instr():
1260 *
1261 * Execute one instruction on a specific CPU.
1262 *
1263 * Return value is the number of instructions executed during this call,
1264 * 0 if no instruction was executed.
1265 */
1266 int ppc_cpu_run_instr(struct emul *emul, struct cpu *cpu)
1267 {
1268 uint32_t iword;
1269 unsigned char buf[4];
1270 unsigned char tmp_data[8];
1271 size_t tmp_data_len;
1272 char *mnem = NULL;
1273 int r, hi6, rt, rs, ra, rb, xo, lev, sh, me, rc, imm, l_bit, oe_bit;
1274 int c, i, spr, aa_bit, bo, bi, bh, lk_bit, bf, ctr_ok, cond_ok;
1275 int update, load, mb, nb, bt, ba, bb, fpreg, arithflag, old_ca, bfa;
1276 uint64_t tmp=0, tmp2, addr;
1277 uint64_t cached_pc;
1278
1279 cached_pc = cpu->cd.ppc.pc_last = cpu->pc & ~3;
1280
1281 /* Check PC against breakpoints: */
1282 if (!single_step)
1283 for (i=0; i<cpu->machine->n_breakpoints; i++)
1284 if (cached_pc == cpu->machine->breakpoint_addr[i]) {
1285 fatal("Breakpoint reached, pc=0x");
1286 if (cpu->cd.ppc.bits == 32)
1287 fatal("%08x", (int)cached_pc);
1288 else
1289 fatal("%016llx", (long long)cached_pc);
1290 fatal("\n");
1291 single_step = 1;
1292 return 0;
1293 }
1294
1295 /* Update the Time Base and Decrementer: */
1296 if ((++ cpu->cd.ppc.tbl) == 0)
1297 cpu->cd.ppc.tbu ++;
1298
1299 cpu->cd.ppc.dec --;
1300 /* TODO: dec interrupt! */
1301
1302 /* TODO: hdec for POWER4+ */
1303
1304 /* ROM emulation: (TODO: non-OF-emuls) */
1305 if (cpu->pc == cpu->cd.ppc.of_emul_addr &&
1306 cpu->machine->prom_emulation) {
1307 int res = of_emul(cpu);
1308 if (res) {
1309 cpu->pc = cpu->cd.ppc.lr;
1310 }
1311 return 100;
1312 }
1313
1314 r = cpu->memory_rw(cpu, cpu->mem, cached_pc, &buf[0], sizeof(buf),
1315 MEM_READ, CACHE_INSTRUCTION | PHYSICAL);
1316 if (!r)
1317 return 0;
1318
1319 iword = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
1320
1321 if (cpu->machine->instruction_trace)
1322 ppc_cpu_disassemble_instr(cpu, buf, 1, 0, 0);
1323
1324 cpu->pc += sizeof(iword);
1325 cached_pc += sizeof(iword);
1326
1327 hi6 = iword >> 26;
1328
1329 switch (hi6) {
1330
1331 case PPC_HI6_MULLI:
1332 rt = (iword >> 21) & 31;
1333 ra = (iword >> 16) & 31;
1334 imm = (int16_t)(iword & 0xffff);
1335 cpu->cd.ppc.gpr[rt] = (int64_t)cpu->cd.ppc.gpr[ra]
1336 * (int64_t)imm;
1337 break;
1338
1339 case PPC_HI6_SUBFIC:
1340 rt = (iword >> 21) & 31;
1341 ra = (iword >> 16) & 31;
1342 imm = (int16_t)(iword & 0xffff);
1343 cpu->cd.ppc.xer &= ~PPC_XER_CA;
1344 if (cpu->cd.ppc.bits == 32) {
1345 tmp = (~cpu->cd.ppc.gpr[ra]) & 0xffffffff;
1346 cpu->cd.ppc.gpr[rt] = tmp + imm + 1;
1347 /* TODO: is this CA correct? */
1348 /* printf("subfic: tmp = %016llx\n", (long long)tmp);
1349 printf("subfic: rt = %016llx\n\n",
1350 (long long)cpu->cd.ppc.gpr[rt]); */
1351 if ((tmp >> 32) != (cpu->cd.ppc.gpr[rt] >> 32))
1352 cpu->cd.ppc.xer |= PPC_XER_CA;
1353 /* High 32 bits are probably undefined in
1354 32-bit mode (I hope) */
1355 } else {
1356 /*
1357 * Ugly, but I can't figure out a way right now how
1358 * to get the carry bit out of a 64-bit addition,
1359 * without access to more-than-64-bit operations in C.
1360 */
1361 tmp = ~cpu->cd.ppc.gpr[ra];
1362 tmp2 = (tmp >> 32); /* High 32 bits */
1363 tmp &= 0xffffffff; /* Low 32 bits */
1364
1365 tmp += imm + 1;
1366 if ((tmp >> 32) == 0) {
1367 /* No change to upper 32 bits */
1368 } else if ((tmp >> 32) == 1) {
1369 /* Positive change: */
1370 tmp2 ++;
1371 } else {
1372 /* Negative change: */
1373 tmp2 --;
1374 }
1375
1376 tmp &= 0xffffffff;
1377
1378 /* TODO: is this CA calculation correct? */
1379 if ((tmp2 >> 32) != 0)
1380 cpu->cd.ppc.xer |= PPC_XER_CA;
1381
1382 cpu->cd.ppc.gpr[rt] = (tmp2 << 32) + tmp;
1383 }
1384 break;
1385
1386 case PPC_HI6_CMPLI:
1387 case PPC_HI6_CMPI:
1388 bf = (iword >> 23) & 7;
1389 l_bit = (iword >> 21) & 1;
1390 ra = (iword >> 16) & 31;
1391 if (hi6 == PPC_HI6_CMPLI)
1392 imm = iword & 0xffff;
1393 else
1394 imm = (int16_t)(iword & 0xffff);
1395 tmp = cpu->cd.ppc.gpr[ra];
1396
1397 if (hi6 == PPC_HI6_CMPI) {
1398 if (!l_bit)
1399 tmp = (int64_t)(int32_t)tmp;
1400 if ((int64_t)tmp < (int64_t)imm)
1401 c = 8;
1402 else if ((int64_t)tmp > (int64_t)imm)
1403 c = 4;
1404 else
1405 c = 2;
1406 } else {
1407 if (!l_bit)
1408 tmp &= 0xffffffff;
1409 if ((uint64_t)tmp < (uint64_t)imm)
1410 c = 8;
1411 else if ((uint64_t)tmp > (uint64_t)imm)
1412 c = 4;
1413 else
1414 c = 2;
1415 }
1416
1417 /* SO bit, copied from XER: */
1418 c |= ((cpu->cd.ppc.xer >> 31) & 1);
1419
1420 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
1421 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
1422 break;
1423
1424 case PPC_HI6_ADDIC:
1425 case PPC_HI6_ADDIC_DOT:
1426 rt = (iword >> 21) & 31;
1427 ra = (iword >> 16) & 31;
1428 rc = hi6 == PPC_HI6_ADDIC_DOT;
1429 imm = (int16_t)(iword & 0xffff);
1430 /* NOTE: Addic doesn't clear CA! */
1431 if (cpu->cd.ppc.bits == 32) {
1432 tmp = cpu->cd.ppc.gpr[ra] & 0xffffffff;
1433 cpu->cd.ppc.gpr[rt] = tmp + (uint32_t)imm;
1434 /* TODO: is this CA correct? */
1435 /* printf("addic: tmp = %016llx\n", (long long)tmp);
1436 printf("addic: rt = %016llx\n\n",
1437 (long long)cpu->cd.ppc.gpr[rt]); */
1438 if ((tmp >> 32) != (cpu->cd.ppc.gpr[rt] >> 32))
1439 cpu->cd.ppc.xer |= PPC_XER_CA;
1440 /* High 32 bits are probably undefined in
1441 32-bit mode (I hope) */
1442 } else {
1443 /* See comment about ugliness regarding SUBFIC */
1444 tmp = cpu->cd.ppc.gpr[ra];
1445 tmp2 = (tmp >> 32); /* High 32 bits */
1446 tmp &= 0xffffffff; /* Low 32 bits */
1447
1448 tmp += (int64_t)imm;
1449 if ((tmp >> 32) == 0) {
1450 /* No change to upper 32 bits */
1451 } else if ((tmp >> 32) == 1) {
1452 /* Positive change: */
1453 tmp2 ++;
1454 } else {
1455 /* Negative change: */
1456 tmp2 --;
1457 }
1458
1459 tmp &= 0xffffffff;
1460
1461 /* TODO: is this CA calculation correct? */
1462 if ((tmp2 >> 32) != 0)
1463 cpu->cd.ppc.xer |= PPC_XER_CA;
1464
1465 cpu->cd.ppc.gpr[rt] = (tmp2 << 32) + tmp;
1466 }
1467 if (rc)
1468 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
1469 break;
1470
1471 case PPC_HI6_ADDI:
1472 case PPC_HI6_ADDIS:
1473 rt = (iword >> 21) & 31;
1474 ra = (iword >> 16) & 31;
1475 if (hi6 == PPC_HI6_ADDI)
1476 imm = (int16_t)(iword & 0xffff);
1477 else
1478 imm = (int32_t)((iword & 0xffff) << 16);
1479 if (ra == 0)
1480 tmp = 0;
1481 else
1482 tmp = cpu->cd.ppc.gpr[ra];
1483 cpu->cd.ppc.gpr[rt] = tmp + imm;
1484 break;
1485
1486 case PPC_HI6_BC:
1487 aa_bit = (iword >> 1) & 1;
1488 lk_bit = iword & 1;
1489 bo = (iword >> 21) & 31;
1490 bi = (iword >> 16) & 31;
1491 /* Sign-extend addr: */
1492 addr = (int64_t)(int16_t)(iword & 0xfffc);
1493
1494 if (!aa_bit)
1495 addr += cpu->cd.ppc.pc_last;
1496
1497 if (cpu->cd.ppc.bits == 32)
1498 addr &= 0xffffffff;
1499
1500 if (!(bo & 4))
1501 cpu->cd.ppc.ctr --;
1502 ctr_ok = (bo >> 2) & 1;
1503 tmp = cpu->cd.ppc.ctr;
1504 if (cpu->cd.ppc.bits == 32)
1505 tmp &= 0xffffffff;
1506 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
1507
1508 cond_ok = (bo >> 4) & 1;
1509 cond_ok |= ( ((bo >> 3) & 1) ==
1510 ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
1511
1512 if (lk_bit)
1513 cpu->cd.ppc.lr = cpu->pc;
1514 if (ctr_ok && cond_ok)
1515 cpu->pc = addr & ~3;
1516 if (lk_bit && cpu->machine->show_trace_tree)
1517 show_trace(cpu);
1518 break;
1519
1520 case PPC_HI6_SC:
1521 lev = (iword >> 5) & 0x7f;
1522 if (cpu->machine->userland_emul != NULL) {
1523 useremul_syscall(cpu, lev);
1524 } else {
1525 fatal("[ PPC: pc = 0x%016llx, sc not yet "
1526 "implemented ]\n", (long long)cached_pc);
1527 cpu->running = 0;
1528 return 0;
1529 }
1530 break;
1531
1532 case PPC_HI6_B:
1533 aa_bit = (iword & 2) >> 1;
1534 lk_bit = iword & 1;
1535 /* Sign-extend addr: */
1536 addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
1537 addr = (int64_t)addr >> 6;
1538
1539 if (!aa_bit)
1540 addr += cpu->cd.ppc.pc_last;
1541
1542 if (cpu->cd.ppc.bits == 32)
1543 addr &= 0xffffffff;
1544
1545 if (lk_bit)
1546 cpu->cd.ppc.lr = cpu->pc;
1547
1548 cpu->pc = addr;
1549
1550 if (lk_bit && cpu->machine->show_trace_tree)
1551 show_trace(cpu);
1552 break;
1553
1554 case PPC_HI6_19:
1555 xo = (iword >> 1) & 1023;
1556 switch (xo) {
1557
1558 case PPC_19_MCRF:
1559 bf = (iword >> 23) & 7;
1560 bfa = (iword >> 18) & 7;
1561 tmp = cpu->cd.ppc.cr >> (28 - bfa*4);
1562 tmp &= 0xf;
1563 cpu->cd.ppc.cr &= ~(0xf << (28 - bf*4));
1564 cpu->cd.ppc.cr |= (tmp << (28 - bf*4));
1565 break;
1566
1567 case PPC_19_BCLR:
1568 case PPC_19_BCCTR:
1569 bo = (iword >> 21) & 31;
1570 bi = (iword >> 16) & 31;
1571 bh = (iword >> 11) & 3;
1572 lk_bit = iword & 1;
1573 if (xo == PPC_19_BCLR) {
1574 addr = cpu->cd.ppc.lr;
1575 if (!(bo & 4))
1576 cpu->cd.ppc.ctr --;
1577 ctr_ok = (bo >> 2) & 1;
1578 tmp = cpu->cd.ppc.ctr;
1579 if (cpu->cd.ppc.bits == 32)
1580 tmp &= 0xffffffff;
1581 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
1582 if (!quiet_mode && !lk_bit &&
1583 cpu->machine->show_trace_tree) {
1584 cpu->cd.ppc.trace_tree_depth --;
1585 /* TODO: show return value? */
1586 }
1587 } else {
1588 addr = cpu->cd.ppc.ctr;
1589 ctr_ok = 1;
1590 }
1591 cond_ok = (bo >> 4) & 1;
1592 cond_ok |= ( ((bo >> 3) & 1) ==
1593 ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
1594 if (lk_bit)
1595 cpu->cd.ppc.lr = cpu->pc;
1596 if (ctr_ok && cond_ok) {
1597 cpu->pc = addr & ~3;
1598 if (cpu->cd.ppc.bits == 32)
1599 cpu->pc &= 0xffffffff;
1600 }
1601 if (lk_bit && cpu->machine->show_trace_tree)
1602 show_trace(cpu);
1603 break;
1604
1605 case PPC_19_ISYNC:
1606 /* TODO: actually sync */
1607 break;
1608
1609 case PPC_19_CRAND:
1610 case PPC_19_CRXOR:
1611 case PPC_19_CROR:
1612 case PPC_19_CRNAND:
1613 case PPC_19_CRNOR:
1614 case PPC_19_CRANDC:
1615 case PPC_19_CREQV:
1616 case PPC_19_CRORC:
1617 bt = (iword >> 21) & 31;
1618 ba = (iword >> 16) & 31;
1619 bb = (iword >> 11) & 31;
1620 ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1621 bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1622 cpu->cd.ppc.cr &= ~(1 << (31-bt));
1623 switch (xo) {
1624 case PPC_19_CRXOR:
1625 if (ba ^ bb)
1626 cpu->cd.ppc.cr |= (1 << (31-bt));
1627 break;
1628 case PPC_19_CROR:
1629 if (ba | bb)
1630 cpu->cd.ppc.cr |= (1 << (31-bt));
1631 break;
1632 default:
1633 fatal("[ TODO: crXXX, xo = %i, "
1634 "pc = 0x%016llx ]\n",
1635 xo, (long long) (cpu->cd.ppc.pc_last));
1636 cpu->running = 0;
1637 return 0;
1638 }
1639 break;
1640
1641 default:
1642 fatal("[ unimplemented PPC hi6_19, xo = 0x%04x, "
1643 "pc = 0x%016llx ]\n",
1644 xo, (long long) (cpu->cd.ppc.pc_last));
1645 cpu->running = 0;
1646 return 0;
1647 }
1648 break;
1649
1650 case PPC_HI6_RLWIMI:
1651 case PPC_HI6_RLWINM:
1652 rs = (iword >> 21) & 31;
1653 ra = (iword >> 16) & 31;
1654 sh = (iword >> 11) & 31;
1655 mb = (iword >> 6) & 31;
1656 me = (iword >> 1) & 31;
1657 rc = iword & 1;
1658 tmp = cpu->cd.ppc.gpr[rs];
1659 /* TODO: Fix this, its performance is awful: */
1660 while (sh-- != 0) {
1661 int b = (tmp >> 31) & 1;
1662 tmp = (tmp << 1) | b;
1663 }
1664
1665 switch (hi6) {
1666 case PPC_HI6_RLWIMI:
1667 for (;;) {
1668 uint64_t mask;
1669 mask = (uint64_t)1 << (31-mb);
1670 cpu->cd.ppc.gpr[ra] &= ~mask;
1671 cpu->cd.ppc.gpr[ra] |= (tmp & mask);
1672 if (mb == me)
1673 break;
1674 mb ++;
1675 if (mb == 32)
1676 mb = 0;
1677 }
1678 break;
1679 case PPC_HI6_RLWINM:
1680 cpu->cd.ppc.gpr[ra] = 0;
1681 for (;;) {
1682 uint64_t mask;
1683 mask = (uint64_t)1 << (31-mb);
1684 cpu->cd.ppc.gpr[ra] |= (tmp & mask);
1685 if (mb == me)
1686 break;
1687 mb ++;
1688 if (mb == 32)
1689 mb = 0;
1690 }
1691 break;
1692 }
1693 if (rc)
1694 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1695 break;
1696
1697 case PPC_HI6_ORI:
1698 case PPC_HI6_ORIS:
1699 rs = (iword >> 21) & 31;
1700 ra = (iword >> 16) & 31;
1701 if (hi6 == PPC_HI6_ORI)
1702 imm = (iword & 0xffff);
1703 else
1704 imm = (iword & 0xffff) << 16;
1705 tmp = cpu->cd.ppc.gpr[rs];
1706 cpu->cd.ppc.gpr[ra] = tmp | (uint32_t)imm;
1707 break;
1708
1709 case PPC_HI6_XORI:
1710 case PPC_HI6_XORIS:
1711 rs = (iword >> 21) & 31;
1712 ra = (iword >> 16) & 31;
1713 if (hi6 == PPC_HI6_XORI)
1714 imm = (iword & 0xffff);
1715 else
1716 imm = (iword & 0xffff) << 16;
1717 tmp = cpu->cd.ppc.gpr[rs];
1718 cpu->cd.ppc.gpr[ra] = tmp ^ (uint32_t)imm;
1719 break;
1720
1721 case PPC_HI6_ANDI_DOT:
1722 case PPC_HI6_ANDIS_DOT:
1723 rs = (iword >> 21) & 31;
1724 ra = (iword >> 16) & 31;
1725 if (hi6 == PPC_HI6_ANDI_DOT)
1726 imm = (iword & 0xffff);
1727 else
1728 imm = (iword & 0xffff) << 16;
1729 tmp = cpu->cd.ppc.gpr[rs];
1730 cpu->cd.ppc.gpr[ra] = tmp & (uint32_t)imm;
1731 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1732 break;
1733
1734 case PPC_HI6_30:
1735 xo = (iword >> 2) & 7;
1736 switch (xo) {
1737 case PPC_30_RLDICR:
1738 if (cpu->cd.ppc.bits == 32) {
1739 /* TODO: Illegal instruction. */
1740 break;
1741 }
1742 rs = (iword >> 21) & 31;
1743 ra = (iword >> 16) & 31;
1744 sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
1745 me = ((iword >> 6) & 31) | (iword & 0x20);
1746 rc = iword & 1;
1747 tmp = cpu->cd.ppc.gpr[rs];
1748 /* TODO: Fix this, its performance is awful: */
1749 while (sh-- != 0) {
1750 int b = (tmp >> 63) & 1;
1751 tmp = (tmp << 1) | b;
1752 }
1753 while (me++ < 63)
1754 tmp &= ~((uint64_t)1 << (63-me));
1755 cpu->cd.ppc.gpr[ra] = tmp;
1756 if (rc)
1757 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1758 break;
1759 default:
1760 fatal("[ unimplemented PPC hi6_30, xo = 0x%04x, "
1761 "pc = 0x%016llx ]\n",
1762 xo, (long long) (cpu->cd.ppc.pc_last));
1763 cpu->running = 0;
1764 return 0;
1765 }
1766 break;
1767
1768 case PPC_HI6_31:
1769 xo = (iword >> 1) & 1023;
1770 switch (xo) {
1771
1772 case PPC_31_CMPL:
1773 case PPC_31_CMP:
1774 bf = (iword >> 23) & 7;
1775 l_bit = (iword >> 21) & 1;
1776 ra = (iword >> 16) & 31;
1777 rb = (iword >> 11) & 31;
1778
1779 tmp = cpu->cd.ppc.gpr[ra];
1780 tmp2 = cpu->cd.ppc.gpr[rb];
1781
1782 if (hi6 == PPC_31_CMP) {
1783 if (!l_bit) {
1784 tmp = (int64_t)(int32_t)tmp;
1785 tmp2 = (int64_t)(int32_t)tmp2;
1786 }
1787 if ((int64_t)tmp < (int64_t)tmp2)
1788 c = 8;
1789 else if ((int64_t)tmp > (int64_t)tmp2)
1790 c = 4;
1791 else
1792 c = 2;
1793 } else {
1794 if (!l_bit) {
1795 tmp &= 0xffffffff;
1796 tmp2 &= 0xffffffff;
1797 }
1798 if ((uint64_t)tmp < (uint64_t)tmp2)
1799 c = 8;
1800 else if ((uint64_t)tmp > (uint64_t)tmp2)
1801 c = 4;
1802 else
1803 c = 2;
1804 }
1805
1806 /* SO bit, copied from XER: */
1807 c |= ((cpu->cd.ppc.xer >> 31) & 1);
1808
1809 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
1810 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
1811 break;
1812
1813 case PPC_31_MFCR:
1814 rt = (iword >> 21) & 31;
1815 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.cr;
1816 break;
1817
1818 case PPC_31_DCBST:
1819 case PPC_31_ICBI:
1820 ra = (iword >> 16) & 31;
1821 rb = (iword >> 11) & 31;
1822 switch (xo) {
1823 case PPC_31_DCBST: mnem = "dcbst"; break;
1824 case PPC_31_ICBI: mnem = "icbi"; break;
1825 }
1826 /* debug("[ %s r%i,r%i: TODO ]\n", mnem, ra, rb); */
1827 break;
1828
1829 case PPC_31_MFMSR:
1830 rt = (iword >> 21) & 31;
1831 /* TODO: check pr */
1832 reg_access_msr(cpu, &cpu->cd.ppc.gpr[rt], 0);
1833 break;
1834
1835 case PPC_31_MTCRF:
1836 rs = (iword >> 21) & 31;
1837 mb = (iword >> 12) & 255; /* actually fxm, not mb */
1838 tmp = 0;
1839 for (i=0; i<8; i++, mb <<= 1, tmp <<= 4)
1840 if (mb & 128)
1841 tmp |= 0xf;
1842 cpu->cd.ppc.cr &= ~tmp;
1843 cpu->cd.ppc.cr |= (cpu->cd.ppc.gpr[rs] & tmp);
1844 break;
1845
1846 case PPC_31_MTMSR:
1847 rs = (iword >> 21) & 31;
1848 l_bit = (iword >> 16) & 1;
1849 /* TODO: the l_bit */
1850 reg_access_msr(cpu, &cpu->cd.ppc.gpr[rs], 1);
1851 break;
1852
1853 case PPC_31_LBZX:
1854 case PPC_31_LBZUX:
1855 case PPC_31_LHZX:
1856 case PPC_31_LHZUX:
1857 case PPC_31_LWZX:
1858 case PPC_31_LWZUX:
1859 case PPC_31_STBX:
1860 case PPC_31_STBUX:
1861 case PPC_31_STHX:
1862 case PPC_31_STHUX:
1863 case PPC_31_STWX:
1864 case PPC_31_STWUX:
1865 rs = (iword >> 21) & 31;
1866 ra = (iword >> 16) & 31;
1867 rb = (iword >> 11) & 31;
1868 update = 0;
1869 switch (xo) {
1870 case PPC_31_LBZUX:
1871 case PPC_31_LHZUX:
1872 case PPC_31_LWZUX:
1873 case PPC_31_STBUX:
1874 case PPC_31_STHUX:
1875 case PPC_31_STWUX:
1876 update = 1;
1877 }
1878 if (ra == 0)
1879 addr = 0;
1880 else
1881 addr = cpu->cd.ppc.gpr[ra];
1882 addr += cpu->cd.ppc.gpr[rb];
1883 load = 0;
1884 switch (xo) {
1885 case PPC_31_LBZX:
1886 case PPC_31_LBZUX:
1887 case PPC_31_LHZX:
1888 case PPC_31_LHZUX:
1889 case PPC_31_LWZX:
1890 case PPC_31_LWZUX:
1891 load = 1;
1892 }
1893
1894 if (cpu->machine->instruction_trace) {
1895 if (cpu->cd.ppc.bits == 32)
1896 debug("\t[0x%08llx", (long long)addr);
1897 else
1898 debug("\t[0x%016llx", (long long)addr);
1899 }
1900
1901 tmp_data_len = 4;
1902 switch (xo) {
1903 case PPC_31_LBZX:
1904 case PPC_31_LBZUX:
1905 case PPC_31_STBX:
1906 case PPC_31_STBUX:
1907 tmp_data_len = 1;
1908 break;
1909 case PPC_31_LHZX:
1910 case PPC_31_LHZUX:
1911 case PPC_31_STHX:
1912 case PPC_31_STHUX:
1913 tmp_data_len = 2;
1914 break;
1915 }
1916
1917 tmp = 0;
1918
1919 if (load) {
1920 r = cpu->memory_rw(cpu, cpu->mem, addr,
1921 tmp_data, tmp_data_len, MEM_READ,
1922 CACHE_DATA);
1923 if (r == MEMORY_ACCESS_OK) {
1924 if (cpu->byte_order ==
1925 EMUL_BIG_ENDIAN) {
1926 for (i=0; i<tmp_data_len; i++) {
1927 tmp <<= 8;
1928 tmp += tmp_data[i];
1929 }
1930 } else {
1931 for (i=0; i<tmp_data_len; i++) {
1932 tmp <<= 8;
1933 tmp += tmp_data[
1934 tmp_data_len - 1
1935 - i];
1936 }
1937 }
1938 cpu->cd.ppc.gpr[rs] = tmp;
1939 }
1940 } else {
1941 tmp = cpu->cd.ppc.gpr[rs];
1942 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1943 for (i=0; i<tmp_data_len; i++)
1944 tmp_data[tmp_data_len-1-i] =
1945 tmp >> (8*i);
1946 } else {
1947 for (i=0; i<tmp_data_len; i++)
1948 tmp_data[i] = tmp >> (8*i);
1949 }
1950
1951 r = cpu->memory_rw(cpu, cpu->mem, addr,
1952 tmp_data, tmp_data_len, MEM_WRITE,
1953 CACHE_DATA);
1954 }
1955
1956 if (cpu->machine->instruction_trace) {
1957 if (r == MEMORY_ACCESS_OK) {
1958 switch (tmp_data_len) {
1959 case 1: debug(", data = 0x%02x]\n",
1960 (int)tmp);
1961 break;
1962 case 2: debug(", data = 0x%04x]\n",
1963 (int)tmp);
1964 break;
1965 case 4: debug(", data = 0x%08x]\n",
1966 (int)tmp);
1967 break;
1968 default:debug(", data = 0x%016llx]\n",
1969 (long long)tmp);
1970 }
1971 } else
1972 debug(", FAILED]\n");
1973 }
1974
1975 if (r != MEMORY_ACCESS_OK) {
1976 /* TODO: exception? */
1977 return 0;
1978 }
1979
1980 if (update && ra != 0)
1981 cpu->cd.ppc.gpr[ra] = addr;
1982 break;
1983
1984 case PPC_31_NEG:
1985 case PPC_31_NEGO:
1986 rt = (iword >> 21) & 31;
1987 ra = (iword >> 16) & 31;
1988 oe_bit = (iword >> 10) & 1;
1989 rc = iword & 1;
1990 if (oe_bit) {
1991 fatal("[ neg: PPC oe not yet implemeted ]\n");
1992 cpu->running = 0;
1993 return 0;
1994 }
1995 cpu->cd.ppc.gpr[rt] = ~cpu->cd.ppc.gpr[ra] + 1;
1996 if (rc)
1997 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
1998 break;
1999
2000 case PPC_31_ADDZE:
2001 case PPC_31_ADDZEO:
2002 rt = (iword >> 21) & 31;
2003 ra = (iword >> 16) & 31;
2004 oe_bit = (iword >> 10) & 1;
2005 rc = iword & 1;
2006 if (oe_bit) {
2007 fatal("[ addz: PPC oe not yet implemeted ]\n");
2008 cpu->running = 0;
2009 return 0;
2010 }
2011 old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2012 cpu->cd.ppc.xer &= PPC_XER_CA;
2013 if (cpu->cd.ppc.bits == 32) {
2014 tmp = (uint32_t)cpu->cd.ppc.gpr[ra];
2015 tmp2 = tmp;
2016 /* printf("addze: tmp2 = %016llx\n",
2017 (long long)tmp2); */
2018 if (old_ca)
2019 tmp ++;
2020 /* printf("addze: tmp = %016llx\n\n",
2021 (long long)tmp); */
2022 /* TODO: is this CA correct? */
2023 if ((tmp >> 32) != (tmp2 >> 32))
2024 cpu->cd.ppc.xer |= PPC_XER_CA;
2025 /* High 32 bits are probably undefined
2026 in 32-bit mode (I hope) */
2027 cpu->cd.ppc.gpr[rt] = tmp;
2028 } else {
2029 fatal("ADDZE 64-bit, TODO\n");
2030 }
2031 if (rc)
2032 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2033 break;
2034
2035 case PPC_31_MTSR:
2036 /* Move to segment register (?) */
2037 /* TODO */
2038 break;
2039
2040 case PPC_31_MFSRIN:
2041 case PPC_31_MTSRIN:
2042 /* mfsrin: Move to segment register indirect (?) */
2043 /* mtsrin: Move to segment register indirect (?) */
2044 rt = (iword >> 21) & 31;
2045 rb = (iword >> 11) & 31;
2046
2047 /* TODO */
2048
2049 if (xo == PPC_31_MFSRIN)
2050 cpu->cd.ppc.gpr[rt] = 0;
2051 break;
2052
2053 case PPC_31_ADDC:
2054 case PPC_31_ADDCO:
2055 case PPC_31_ADDE:
2056 case PPC_31_ADDEO:
2057 case PPC_31_ADD:
2058 case PPC_31_ADDO:
2059 case PPC_31_MULHW:
2060 case PPC_31_MULHWU:
2061 case PPC_31_MULLW:
2062 case PPC_31_MULLWO:
2063 case PPC_31_SUBFE:
2064 case PPC_31_SUBFEO:
2065 case PPC_31_SUBFZE:
2066 case PPC_31_SUBFZEO:
2067 case PPC_31_SUBFC:
2068 case PPC_31_SUBFCO:
2069 case PPC_31_SUBF:
2070 case PPC_31_SUBFO:
2071 rt = (iword >> 21) & 31;
2072 ra = (iword >> 16) & 31;
2073 rb = (iword >> 11) & 31;
2074 oe_bit = (iword >> 10) & 1;
2075 rc = iword & 1;
2076 if (oe_bit) {
2077 fatal("[ add: PPC oe not yet implemeted ]\n");
2078 cpu->running = 0;
2079 return 0;
2080 }
2081 switch (xo) {
2082 case PPC_31_ADD:
2083 case PPC_31_ADDO:
2084 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.gpr[ra] +
2085 cpu->cd.ppc.gpr[rb];
2086 break;
2087 case PPC_31_ADDC:
2088 case PPC_31_ADDCO:
2089 case PPC_31_ADDE:
2090 case PPC_31_ADDEO:
2091 old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2092 cpu->cd.ppc.xer &= PPC_XER_CA;
2093 if (cpu->cd.ppc.bits == 32) {
2094 tmp = (uint32_t)cpu->cd.ppc.gpr[ra];
2095 tmp2 = tmp;
2096 /* printf("adde: tmp2 = %016llx\n",
2097 (long long)tmp2); */
2098 tmp += (uint32_t)cpu->cd.ppc.gpr[rb];
2099 if ((xo == PPC_31_ADDE ||
2100 xo == PPC_31_ADDEO) && old_ca)
2101 tmp ++;
2102 /* printf("adde: tmp = %016llx\n\n",
2103 (long long)tmp); */
2104 /* TODO: is this CA correct? */
2105 if ((tmp >> 32) != (tmp2 >> 32))
2106 cpu->cd.ppc.xer |= PPC_XER_CA;
2107 /* High 32 bits are probably undefined
2108 in 32-bit mode (I hope) */
2109 cpu->cd.ppc.gpr[rt] = tmp;
2110 } else {
2111 fatal("ADDE 64-bit, TODO\n");
2112 }
2113 break;
2114 case PPC_31_MULHW:
2115 cpu->cd.ppc.gpr[rt] = (int64_t) (
2116 (int64_t)(int32_t)cpu->cd.ppc.gpr[ra] *
2117 (int64_t)(int32_t)cpu->cd.ppc.gpr[rb]);
2118 cpu->cd.ppc.gpr[rt] >>= 32;
2119 break;
2120 case PPC_31_MULHWU:
2121 cpu->cd.ppc.gpr[rt] = (uint64_t) (
2122 (uint64_t)(uint32_t)cpu->cd.ppc.gpr[ra] *
2123 (uint64_t)(uint32_t)cpu->cd.ppc.gpr[rb]);
2124 cpu->cd.ppc.gpr[rt] >>= 32;
2125 break;
2126 case PPC_31_MULLW:
2127 case PPC_31_MULLWO:
2128 cpu->cd.ppc.gpr[rt] = (int64_t) (
2129 (int32_t)cpu->cd.ppc.gpr[ra] *
2130 (int32_t)cpu->cd.ppc.gpr[rb]);
2131 break;
2132 case PPC_31_SUBF:
2133 case PPC_31_SUBFO:
2134 cpu->cd.ppc.gpr[rt] = ~cpu->cd.ppc.gpr[ra] +
2135 cpu->cd.ppc.gpr[rb] + 1;
2136 break;
2137 case PPC_31_SUBFC:
2138 case PPC_31_SUBFCO:
2139 case PPC_31_SUBFE:
2140 case PPC_31_SUBFEO:
2141 case PPC_31_SUBFZE:
2142 case PPC_31_SUBFZEO:
2143 old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
2144 if (xo == PPC_31_SUBFC || xo == PPC_31_SUBFCO)
2145 old_ca = 1;
2146 cpu->cd.ppc.xer &= PPC_XER_CA;
2147 if (cpu->cd.ppc.bits == 32) {
2148 tmp = (~cpu->cd.ppc.gpr[ra])
2149 & 0xffffffff;
2150 tmp2 = tmp;
2151 if (xo != PPC_31_SUBFZE &&
2152 xo != PPC_31_SUBFZEO)
2153 tmp += (cpu->cd.ppc.gpr[rb] &
2154 0xffffffff);
2155 if (old_ca)
2156 tmp ++;
2157 /* printf("subfe: tmp2 = %016llx\n",
2158 (long long)tmp2);
2159 printf("subfe: tmp = %016llx\n\n",
2160 (long long)tmp); */
2161 /* TODO: is this CA correct? */
2162 if ((tmp >> 32) != (tmp2 >> 32))
2163 cpu->cd.ppc.xer |= PPC_XER_CA;
2164 /* High 32 bits are probably undefined
2165 in 32-bit mode (I hope) */
2166 cpu->cd.ppc.gpr[rt] = tmp;
2167 } else {
2168 fatal("SUBFE 64-bit, TODO\n");
2169 }
2170 break;
2171 }
2172 if (rc)
2173 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2174 break;
2175
2176 case PPC_31_MFSPR:
2177 case PPC_31_MFTB:
2178 rt = (iword >> 21) & 31;
2179 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2180 switch (spr) {
2181 case 1: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.xer;
2182 break;
2183 case 8: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.lr;
2184 break;
2185 case 9: cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.ctr;
2186 break;
2187 case 22:/* TODO: check pr */
2188 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.dec;
2189 break;
2190 case 259: /* NOTE: no pr check */
2191 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg3;
2192 break;
2193 case 268: /* MFTB, NOTE: no pr check */
2194 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.tbl;
2195 break;
2196 case 269: /* MFTBU, NOTE: no pr check */
2197 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.tbu;
2198 break;
2199 case 272:
2200 /* TODO: check pr */
2201 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg0;
2202 break;
2203 case 273:
2204 /* TODO: check pr */
2205 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg1;
2206 break;
2207 case 274:
2208 /* TODO: check pr */
2209 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg2;
2210 break;
2211 case 275:
2212 /* TODO: check pr */
2213 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.sprg3;
2214 break;
2215 case 287:
2216 /* TODO: check pr */
2217 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.pvr;
2218 break;
2219 case 310:/* TODO: check pr */
2220 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.hdec;
2221 break;
2222 case 1023:
2223 /* TODO: check pr */
2224 cpu->cd.ppc.gpr[rt] = cpu->cd.ppc.pir;
2225 break;
2226 default:
2227 fatal("[ unimplemented PPC spr 0x%04x, "
2228 "pc = 0x%016llx ]\n",
2229 spr, (long long) (cpu->cd.ppc.pc_last));
2230 /* cpu->running = 0;
2231 return 0; */
2232 break;
2233 }
2234
2235 /* TODO: is this correct? */
2236 if (cpu->cd.ppc.bits == 32)
2237 cpu->cd.ppc.gpr[rt] &= 0xffffffff;
2238 break;
2239
2240 case PPC_31_CNTLZW:
2241 rs = (iword >> 21) & 31;
2242 ra = (iword >> 16) & 31;
2243 rc = iword & 1;
2244 cpu->cd.ppc.gpr[ra] = 0;
2245 for (i=0; i<32; i++) {
2246 if (cpu->cd.ppc.gpr[rs] &
2247 ((uint64_t)1 << (31-i)))
2248 break;
2249 cpu->cd.ppc.gpr[ra] ++;
2250 }
2251 if (rc)
2252 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2253 break;
2254
2255 case PPC_31_SLW:
2256 case PPC_31_SRAW:
2257 case PPC_31_SRW:
2258 case PPC_31_AND:
2259 case PPC_31_ANDC:
2260 case PPC_31_NOR:
2261 case PPC_31_OR:
2262 case PPC_31_ORC:
2263 case PPC_31_XOR:
2264 case PPC_31_NAND:
2265 rs = (iword >> 21) & 31;
2266 ra = (iword >> 16) & 31;
2267 rb = (iword >> 11) & 31;
2268 rc = iword & 1;
2269 switch (xo) {
2270 case PPC_31_SLW:
2271 sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2272 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs];
2273 while (sh-- > 0)
2274 cpu->cd.ppc.gpr[ra] <<= 1;
2275 cpu->cd.ppc.gpr[ra] &= 0xffffffff;
2276 break;
2277 case PPC_31_SRAW:
2278 tmp = cpu->cd.ppc.gpr[rs] & 0xffffffff;
2279 cpu->cd.ppc.xer &= ~PPC_XER_CA;
2280 i = 0;
2281 sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2282 if (tmp & 0x80000000)
2283 i = 1;
2284 while (sh-- > 0) {
2285 if (tmp & 1)
2286 i++;
2287 tmp >>= 1;
2288 if (tmp & 0x40000000)
2289 tmp |= 0x80000000;
2290 }
2291 cpu->cd.ppc.gpr[ra] = (int64_t)(int32_t)tmp;
2292 /* Set the CA bit if rs contained a negative
2293 number to begin with, and any 1-bits were
2294 shifted out: */
2295 if (i > 1)
2296 cpu->cd.ppc.xer |= PPC_XER_CA;
2297 break;
2298 case PPC_31_SRW:
2299 sh = cpu->cd.ppc.gpr[rb] & 0x3f;
2300 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs]
2301 & 0xffffffff;
2302 while (sh-- > 0)
2303 cpu->cd.ppc.gpr[ra] >>= 1;
2304 break;
2305 case PPC_31_AND:
2306 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] &
2307 cpu->cd.ppc.gpr[rb];
2308 break;
2309 case PPC_31_ANDC:
2310 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] &
2311 (~cpu->cd.ppc.gpr[rb]);
2312 break;
2313 case PPC_31_NOR:
2314 cpu->cd.ppc.gpr[ra] = ~(cpu->cd.ppc.gpr[rs] |
2315 cpu->cd.ppc.gpr[rb]);
2316 break;
2317 case PPC_31_OR:
2318 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] |
2319 cpu->cd.ppc.gpr[rb];
2320 break;
2321 case PPC_31_ORC:
2322 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] |
2323 (~cpu->cd.ppc.gpr[rb]);
2324 break;
2325 case PPC_31_XOR:
2326 cpu->cd.ppc.gpr[ra] = cpu->cd.ppc.gpr[rs] ^
2327 cpu->cd.ppc.gpr[rb];
2328 break;
2329 case PPC_31_NAND:
2330 cpu->cd.ppc.gpr[ra] = ~(cpu->cd.ppc.gpr[rs]
2331 & cpu->cd.ppc.gpr[rb]);
2332 break;
2333 }
2334 if (rc)
2335 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2336 break;
2337
2338 case PPC_31_TLBIE:
2339 rb = (iword >> 11) & 31;
2340 /* TODO */
2341 break;
2342
2343 case PPC_31_TLBSYNC:
2344 /* Only on 603 and 604 (?) */
2345
2346 /* TODO */
2347 break;
2348
2349 case PPC_31_DCCCI:
2350 case PPC_31_ICCCI:
2351 /* Supervisor IBM 4xx Data Cache Congruence Class
2352 Invalidate, see www.xilinx.com/publications/
2353 xcellonline/partners/xc_pdf/xc_ibm_pwrpc42.pdf
2354 or similar */
2355 /* ICCCI is probably Instruction... blah blah */
2356 /* TODO */
2357 break;
2358
2359 case PPC_31_DIVWU:
2360 case PPC_31_DIVWUO:
2361 case PPC_31_DIVW:
2362 case PPC_31_DIVWO:
2363 rt = (iword >> 21) & 31;
2364 ra = (iword >> 16) & 31;
2365 rb = (iword >> 11) & 31;
2366 oe_bit = (iword >> 10) & 1;
2367 rc = iword & 1;
2368 switch (xo) {
2369 case PPC_31_DIVWU:
2370 case PPC_31_DIVWUO:
2371 tmp = cpu->cd.ppc.gpr[ra] & 0xffffffff;
2372 tmp2 = cpu->cd.ppc.gpr[rb] & 0xffffffff;
2373 if (tmp2 == 0) {
2374 /* Undefined: */
2375 tmp = 0;
2376 } else {
2377 tmp = tmp / tmp2;
2378 }
2379 cpu->cd.ppc.gpr[rt] = (int64_t)(int32_t)tmp;
2380 break;
2381 case PPC_31_DIVW:
2382 case PPC_31_DIVWO:
2383 tmp = (int64_t)(int32_t)cpu->cd.ppc.gpr[ra];
2384 tmp2 = (int64_t)(int32_t)cpu->cd.ppc.gpr[rb];
2385 if (tmp2 == 0) {
2386 /* Undefined: */
2387 tmp = 0;
2388 } else {
2389 tmp = (int64_t)tmp / (int64_t)tmp2;
2390 }
2391 cpu->cd.ppc.gpr[rt] = (int64_t)(int32_t)tmp;
2392 break;
2393 }
2394 if (rc)
2395 update_cr0(cpu, cpu->cd.ppc.gpr[rt]);
2396 if (oe_bit) {
2397 fatal("[ divwu: PPC oe not yet implemeted ]\n");
2398 cpu->running = 0;
2399 return 0;
2400 }
2401 break;
2402
2403 case PPC_31_MTSPR:
2404 rs = (iword >> 21) & 31;
2405 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2406 switch (spr) {
2407 case 1: cpu->cd.ppc.xer = cpu->cd.ppc.gpr[rs];
2408 break;
2409 case 8: cpu->cd.ppc.lr = cpu->cd.ppc.gpr[rs];
2410 break;
2411 case 9: cpu->cd.ppc.ctr = cpu->cd.ppc.gpr[rs];
2412 break;
2413 case 22: /* TODO: check pr */
2414 cpu->cd.ppc.dec = cpu->cd.ppc.gpr[rs];
2415 break;
2416 case 272:
2417 /* TODO: check hypv */
2418 cpu->cd.ppc.sprg0 = cpu->cd.ppc.gpr[rs];
2419 break;
2420 case 273:
2421 /* TODO: check pr */
2422 cpu->cd.ppc.sprg1 = cpu->cd.ppc.gpr[rs];
2423 break;
2424 case 274:
2425 /* TODO: check pr */
2426 cpu->cd.ppc.sprg2 = cpu->cd.ppc.gpr[rs];
2427 break;
2428 case 275:
2429 /* TODO: check pr */
2430 cpu->cd.ppc.sprg3 = cpu->cd.ppc.gpr[rs];
2431 break;
2432 case 284:
2433 /* TODO: check pr */
2434 cpu->cd.ppc.tbl = cpu->cd.ppc.gpr[rs];
2435 break;
2436 case 285:
2437 /* TODO: check pr */
2438 cpu->cd.ppc.tbu = cpu->cd.ppc.gpr[rs];
2439 break;
2440 case 287:
2441 fatal("[ PPC: attempt to write to PVR ]\n");
2442 break;
2443 case 310: /* TODO: check hypv */
2444 cpu->cd.ppc.hdec = cpu->cd.ppc.gpr[rs];
2445 break;
2446 case 1023:
2447 /* TODO: check pr */
2448 cpu->cd.ppc.pir = cpu->cd.ppc.gpr[rs];
2449 break;
2450 default:
2451 fatal("[ unimplemented PPC spr 0x%04x, "
2452 "pc = 0x%016llx ]\n",
2453 spr, (long long) (cpu->cd.ppc.pc_last));
2454 /* cpu->running = 0;
2455 return 0; */
2456 break;
2457 }
2458 break;
2459
2460 case PPC_31_SYNC:
2461 /* TODO: actually sync */
2462 break;
2463
2464 case PPC_31_STSWI:
2465 rs = (iword >> 21) & 31;
2466 ra = (iword >> 16) & 31;
2467 nb = (iword >> 11) & 31;
2468 if (nb == 0)
2469 nb = 32;
2470 if (ra == 0)
2471 addr = 0;
2472 else
2473 addr = cpu->cd.ppc.gpr[ra];
2474
2475 if (cpu->machine->instruction_trace) {
2476 if (cpu->cd.ppc.bits == 32)
2477 debug("\t[0x%08llx", (long long)addr);
2478 else
2479 debug("\t[0x%016llx", (long long)addr);
2480 }
2481
2482 i = 24;
2483 r = 0; /* There can be multiple errors */
2484 while (nb > 0) {
2485 tmp_data[0] = cpu->cd.ppc.gpr[rs] >> i;
2486 if (cpu->memory_rw(cpu, cpu->mem, addr,
2487 tmp_data, 1, MEM_WRITE, CACHE_DATA)
2488 != MEMORY_ACCESS_OK)
2489 r++;
2490 nb--; addr++; i-=8;
2491 if (i < 0) {
2492 i = 24;
2493 rs = (rs + 1) % 32;
2494 }
2495 }
2496
2497 if (cpu->machine->instruction_trace) {
2498 if (r == 0)
2499 debug(", ...]\n");
2500 else
2501 debug(", FAILED]\n");
2502 }
2503
2504 if (r > 0) {
2505 /* TODO: exception */
2506 return 0;
2507 }
2508 break;
2509
2510 case PPC_31_SRAWI:
2511 rs = (iword >> 21) & 31;
2512 ra = (iword >> 16) & 31;
2513 sh = (iword >> 11) & 31;
2514 rc = iword & 1;
2515 tmp = cpu->cd.ppc.gpr[rs] & 0xffffffff;
2516 cpu->cd.ppc.xer &= ~PPC_XER_CA;
2517 i = 0;
2518 if (tmp & 0x80000000)
2519 i = 1;
2520 while (sh-- > 0) {
2521 if (tmp & 1)
2522 i++;
2523 tmp >>= 1;
2524 if (tmp & 0x40000000)
2525 tmp |= 0x80000000;
2526 }
2527 cpu->cd.ppc.gpr[ra] = (int64_t)(int32_t)tmp;
2528 /* Set the CA bit if rs contained a negative
2529 number to begin with, and any 1-bits were
2530 shifted out: */
2531 if (i > 1)
2532 cpu->cd.ppc.xer |= PPC_XER_CA;
2533 if (rc)
2534 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2535 break;
2536
2537 case PPC_31_EIEIO:
2538 /* TODO: actually eieio */
2539 break;
2540
2541 case PPC_31_EXTSB:
2542 case PPC_31_EXTSH:
2543 case PPC_31_EXTSW:
2544 rs = (iword >> 21) & 31;
2545 ra = (iword >> 16) & 31;
2546 rc = iword & 1;
2547 switch (xo) {
2548 case PPC_31_EXTSB:
2549 cpu->cd.ppc.gpr[ra] = (int64_t)
2550 (int8_t)cpu->cd.ppc.gpr[rs];
2551 break;
2552 case PPC_31_EXTSH:
2553 cpu->cd.ppc.gpr[ra] = (int64_t)
2554 (int16_t)cpu->cd.ppc.gpr[rs];
2555 break;
2556 case PPC_31_EXTSW:
2557 cpu->cd.ppc.gpr[ra] = (int64_t)
2558 (int32_t)cpu->cd.ppc.gpr[rs];
2559 break;
2560 }
2561 if (rc)
2562 update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
2563 break;
2564
2565 default:
2566 fatal("[ unimplemented PPC hi6_31, xo = 0x%04x, "
2567 "pc = 0x%016llx ]\n",
2568 xo, (long long) (cpu->cd.ppc.pc_last));
2569 cpu->running = 0;
2570 return 0;
2571 }
2572 break;
2573
2574 case PPC_HI6_LWZ:
2575 case PPC_HI6_LWZU:
2576 case PPC_HI6_LHZ:
2577 case PPC_HI6_LHZU:
2578 case PPC_HI6_LHA:
2579 case PPC_HI6_LHAU:
2580 case PPC_HI6_LBZ:
2581 case PPC_HI6_LBZU:
2582 case PPC_HI6_STW:
2583 case PPC_HI6_STWU:
2584 case PPC_HI6_STH:
2585 case PPC_HI6_STHU:
2586 case PPC_HI6_STB:
2587 case PPC_HI6_STBU:
2588 case PPC_HI6_LFD:
2589 case PPC_HI6_STFD:
2590 /* NOTE: Loads use rt, not rs, but are otherwise similar
2591 to stores. This code uses rs for both. */
2592 rs = (iword >> 21) & 31;
2593 ra = (iword >> 16) & 31;
2594 imm = (int16_t)(iword & 0xffff);
2595
2596 fpreg = 0; load = 1; update = 0; tmp_data_len = 4;
2597 arithflag = 0;
2598
2599 switch (hi6) {
2600 case PPC_HI6_LWZU:
2601 case PPC_HI6_LHZU:
2602 case PPC_HI6_LHAU:
2603 case PPC_HI6_LBZU:
2604 case PPC_HI6_STBU:
2605 case PPC_HI6_STHU:
2606 case PPC_HI6_STWU:
2607 update = 1;
2608 }
2609
2610 switch (hi6) {
2611 case PPC_HI6_STW:
2612 case PPC_HI6_STWU:
2613 case PPC_HI6_STH:
2614 case PPC_HI6_STHU:
2615 case PPC_HI6_STB:
2616 case PPC_HI6_STBU:
2617 case PPC_HI6_STFD:
2618 load = 0;
2619 }
2620
2621 switch (hi6) {
2622 case PPC_HI6_LFD:
2623 case PPC_HI6_STFD:
2624 tmp_data_len = 8;
2625 break;
2626 case PPC_HI6_LBZ:
2627 case PPC_HI6_LBZU:
2628 case PPC_HI6_STB:
2629 case PPC_HI6_STBU:
2630 tmp_data_len = 1;
2631 break;
2632 case PPC_HI6_LHZ:
2633 case PPC_HI6_LHZU:
2634 case PPC_HI6_LHA:
2635 case PPC_HI6_LHAU:
2636 case PPC_HI6_STH:
2637 case PPC_HI6_STHU:
2638 tmp_data_len = 2;
2639 break;
2640 }
2641
2642 switch (hi6) {
2643 case PPC_HI6_LFD:
2644 case PPC_HI6_STFD:
2645 fpreg = 1;
2646 }
2647
2648 switch (hi6) {
2649 case PPC_HI6_LHA:
2650 case PPC_HI6_LHAU:
2651 arithflag = 1;
2652 }
2653
2654 if (ra == 0) {
2655 if (update)
2656 fatal("[ PPC WARNING: invalid Update form ]\n");
2657 addr = 0;
2658 } else
2659 addr = cpu->cd.ppc.gpr[ra];
2660
2661 if (load && update && ra == rs)
2662 fatal("[ PPC WARNING: invalid Update load form ]\n");
2663
2664 addr += imm;
2665
2666 /* TODO: alignment check? */
2667
2668 if (cpu->machine->instruction_trace) {
2669 if (cpu->cd.ppc.bits == 32)
2670 debug("\t[0x%08llx", (long long)addr);
2671 else
2672 debug("\t[0x%016llx", (long long)addr);
2673 }
2674
2675 if (load) {
2676 r = cpu->memory_rw(cpu, cpu->mem, addr, tmp_data,
2677 tmp_data_len, MEM_READ, CACHE_DATA);
2678
2679 if (r == MEMORY_ACCESS_OK) {
2680 tmp = 0;
2681 if (arithflag) {
2682 if (cpu->byte_order ==
2683 EMUL_BIG_ENDIAN) {
2684 if (tmp_data[0] & 0x80)
2685 tmp --;
2686 } else {
2687 if (tmp_data[tmp_data_len-1]
2688 & 0x80)
2689 tmp --;
2690 }
2691 }
2692 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2693 for (i=0; i<tmp_data_len; i++) {
2694 tmp <<= 8;
2695 tmp += tmp_data[i];
2696 }
2697 } else {
2698 for (i=0; i<tmp_data_len; i++) {
2699 tmp <<= 8;
2700 tmp += tmp_data[
2701 tmp_data_len - 1 -i];
2702 }
2703 }
2704
2705 if (!fpreg)
2706 cpu->cd.ppc.gpr[rs] = tmp;
2707 else
2708 cpu->cd.ppc.fpr[rs] = tmp;
2709 }
2710 } else {
2711 if (!fpreg)
2712 tmp = cpu->cd.ppc.gpr[rs];
2713 else
2714 tmp = cpu->cd.ppc.fpr[rs];
2715
2716 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2717 for (i=0; i<tmp_data_len; i++)
2718 tmp_data[tmp_data_len-1-i] =
2719 tmp >> (8*i);
2720 } else {
2721 for (i=0; i<tmp_data_len; i++)
2722 tmp_data[i] = tmp >> (8*i);
2723 }
2724
2725 r = cpu->memory_rw(cpu, cpu->mem, addr, tmp_data,
2726 tmp_data_len, MEM_WRITE, CACHE_DATA);
2727 }
2728
2729 if (cpu->machine->instruction_trace) {
2730 if (r == MEMORY_ACCESS_OK) {
2731 switch (tmp_data_len) {
2732 case 1: debug(", data = 0x%02x]\n", (int)tmp);
2733 break;
2734 case 2: debug(", data = 0x%04x]\n", (int)tmp);
2735 break;
2736 case 4: debug(", data = 0x%08x]\n", (int)tmp);
2737 break;
2738 default:debug(", data = 0x%016llx]\n",
2739 (long long)tmp);
2740 }
2741 } else
2742 debug(", FAILED]\n");
2743 }
2744
2745 if (r != MEMORY_ACCESS_OK) {
2746 /* TODO: exception? */
2747 return 0;
2748 }
2749
2750 if (update && ra != 0)
2751 cpu->cd.ppc.gpr[ra] = addr;
2752 break;
2753
2754 case PPC_HI6_LMW:
2755 case PPC_HI6_STMW:
2756 /* NOTE: Loads use rt, not rs, but are otherwise similar
2757 to stores. This code uses rs for both. */
2758 rs = (iword >> 21) & 31;
2759 ra = (iword >> 16) & 31;
2760 imm = (int16_t)(iword & 0xffff);
2761
2762 load = 1; tmp_data_len = 4;
2763
2764 switch (hi6) {
2765 case PPC_HI6_STMW:
2766 load = 0;
2767 }
2768
2769 if (ra == 0) {
2770 addr = 0;
2771 } else
2772 addr = cpu->cd.ppc.gpr[ra];
2773
2774 if (load && rs == 0)
2775 fatal("[ PPC WARNING: invalid LMW form ]\n");
2776
2777 addr += imm;
2778
2779 /* TODO: alignment check? */
2780
2781 if (cpu->machine->instruction_trace) {
2782 if (cpu->cd.ppc.bits == 32)
2783 debug("\t[0x%08llx", (long long)addr);
2784 else
2785 debug("\t[0x%016llx", (long long)addr);
2786 }
2787
2788 /* There can be multiple errors! */
2789 r = 0;
2790
2791 while (rs <= 31) {
2792 if (load) {
2793 if (cpu->memory_rw(cpu, cpu->mem, addr,
2794 tmp_data, tmp_data_len, MEM_READ,
2795 CACHE_DATA) != MEMORY_ACCESS_OK)
2796 r++;
2797
2798 if (r == 0) {
2799 tmp = 0;
2800 if (cpu->byte_order ==
2801 EMUL_BIG_ENDIAN) {
2802 for (i=0; i<tmp_data_len; i++) {
2803 tmp <<= 8;
2804 tmp += tmp_data[i];
2805 }
2806 } else {
2807 for (i=0; i<tmp_data_len; i++) {
2808 tmp <<= 8;
2809 tmp += tmp_data[
2810 tmp_data_len - 1
2811 - i];
2812 }
2813 }
2814
2815 cpu->cd.ppc.gpr[rs] = tmp;
2816 }
2817 } else {
2818 tmp = cpu->cd.ppc.gpr[rs];
2819
2820 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
2821 for (i=0; i<tmp_data_len; i++)
2822 tmp_data[tmp_data_len-1-i] =
2823 tmp >> (8*i);
2824 } else {
2825 for (i=0; i<tmp_data_len; i++)
2826 tmp_data[i] = tmp >> (8*i);
2827 }
2828
2829 if (cpu->memory_rw(cpu, cpu->mem, addr,
2830 tmp_data, tmp_data_len, MEM_WRITE,
2831 CACHE_DATA) != MEMORY_ACCESS_OK)
2832 r ++;
2833 }
2834
2835 /* TODO: Exception! */
2836
2837 /* Go to next register, multiword... */
2838 rs ++;
2839 addr += tmp_data_len;
2840 }
2841
2842 if (cpu->machine->instruction_trace) {
2843 if (r == 0) {
2844 debug(", data = ...]\n");
2845 } else
2846 debug(", FAILED]\n");
2847 }
2848
2849 if (r > 0)
2850 return 0;
2851 break;
2852
2853 default:
2854 fatal("[ unimplemented PPC hi6 = 0x%02x, pc = 0x%016llx ]\n",
2855 hi6, (long long) (cpu->cd.ppc.pc_last));
2856 cpu->running = 0;
2857 return 0;
2858 }
2859
2860 return 1;
2861 }
2862
2863
2864 #define CPU_RUN ppc_cpu_run
2865 #define CPU_RINSTR ppc_cpu_run_instr
2866 #define CPU_RUN_PPC
2867 #include "cpu_run.c"
2868 #undef CPU_RINSTR
2869 #undef CPU_RUN_PPC
2870 #undef CPU_RUN
2871
2872
2873 #define MEMORY_RW ppc_memory_rw
2874 #define MEM_PPC
2875 #include "memory_rw.c"
2876 #undef MEM_PPC
2877 #undef MEMORY_RW
2878
2879
2880 /*
2881 * ppc_cpu_family_init():
2882 *
2883 * Fill in the cpu_family struct for PPC.
2884 */
2885 int ppc_cpu_family_init(struct cpu_family *fp)
2886 {
2887 fp->name = "PPC";
2888 fp->cpu_new = ppc_cpu_new;
2889 fp->list_available_types = ppc_cpu_list_available_types;
2890 fp->register_match = ppc_cpu_register_match;
2891 fp->disassemble_instr = ppc_cpu_disassemble_instr;
2892 fp->register_dump = ppc_cpu_register_dump;
2893 fp->run = ppc_cpu_run;
2894 fp->dumpinfo = ppc_cpu_dumpinfo;
2895 /* fp->show_full_statistics = ppc_cpu_show_full_statistics; */
2896 /* fp->tlbdump = ppc_cpu_tlbdump; */
2897 /* fp->interrupt = ppc_cpu_interrupt; */
2898 /* fp->interrupt_ack = ppc_cpu_interrupt_ack; */
2899 return 1;
2900 }
2901
2902
2903 #endif /* ENABLE_PPC */

  ViewVC Help
Powered by ViewVC 1.1.26