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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (show annotations)
Mon Oct 8 16:18:22 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 69460 byte(s)
0.3.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