/[gxemul]/trunk/src/cpus/cpu_ppc.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/cpus/cpu_ppc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_ppc.c,v 1.12 2005/09/24 23:44:18 debug Exp $   *  $Id: cpu_ppc.c,v 1.61 2006/07/24 21:14:52 debug Exp $
29   *   *
30   *  PowerPC/POWER CPU emulation.   *  PowerPC/POWER CPU emulation.
31   */   */
# Line 40  Line 40 
40  #include "machine.h"  #include "machine.h"
41  #include "memory.h"  #include "memory.h"
42  #include "misc.h"  #include "misc.h"
43    #include "of.h"
44  #include "opcodes_ppc.h"  #include "opcodes_ppc.h"
45    #include "ppc_bat.h"
46    #include "ppc_pte.h"
47    #include "ppc_spr.h"
48    #include "ppc_spr_strings.h"
49  #include "symbol.h"  #include "symbol.h"
50    
51  #define DYNTRANS_DUALMODE_32  #define DYNTRANS_DUALMODE_32
52  #include "tmp_ppc_head.c"  #include "tmp_ppc_head.c"
53    
54    
55    void ppc_pc_to_pointers(struct cpu *);
56    void ppc32_pc_to_pointers(struct cpu *);
57    
58    
59  /*  /*
60   *  ppc_cpu_new():   *  ppc_cpu_new():
61   *   *
# Line 84  int ppc_cpu_new(struct cpu *cpu, struct Line 93  int ppc_cpu_new(struct cpu *cpu, struct
93    
94          /*  Current operating mode:  */          /*  Current operating mode:  */
95          cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;          cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;
96          cpu->cd.ppc.pvr = cpu->cd.ppc.cpu_type.pvr;          cpu->cd.ppc.spr[SPR_PVR] = cpu->cd.ppc.cpu_type.pvr;
97    
98            /*  cpu->cd.ppc.msr = PPC_MSR_IR | PPC_MSR_DR |
99                PPC_MSR_SF | PPC_MSR_FP;  */
100    
101            cpu->cd.ppc.spr[SPR_IBAT0U] = 0x00001ffc | BAT_Vs;
102            cpu->cd.ppc.spr[SPR_IBAT0L] = 0x00000000 | BAT_PP_RW;
103            cpu->cd.ppc.spr[SPR_IBAT1U] = 0xc0001ffc | BAT_Vs;
104            cpu->cd.ppc.spr[SPR_IBAT1L] = 0x00000000 | BAT_PP_RW;
105            cpu->cd.ppc.spr[SPR_IBAT3U] = 0xf0001ffc | BAT_Vs;
106            cpu->cd.ppc.spr[SPR_IBAT3L] = 0xf0000000 | BAT_PP_RW;
107            cpu->cd.ppc.spr[SPR_DBAT0U] = 0x00001ffc | BAT_Vs;
108            cpu->cd.ppc.spr[SPR_DBAT0L] = 0x00000000 | BAT_PP_RW;
109            cpu->cd.ppc.spr[SPR_DBAT1U] = 0xc0001ffc | BAT_Vs;
110            cpu->cd.ppc.spr[SPR_DBAT1L] = 0x00000000 | BAT_PP_RW;
111            cpu->cd.ppc.spr[SPR_DBAT2U] = 0xe0001ffc | BAT_Vs;
112            cpu->cd.ppc.spr[SPR_DBAT2L] = 0xe0000000 | BAT_PP_RW;
113            cpu->cd.ppc.spr[SPR_DBAT3U] = 0xf0001ffc | BAT_Vs;
114            cpu->cd.ppc.spr[SPR_DBAT3L] = 0xf0000000 | BAT_PP_RW;
115    
116          cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;          cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;
117    
118          if (cpu->is_32bit) {          if (cpu->is_32bit) {
119                    cpu->run_instr = ppc32_run_instr;
120                  cpu->update_translation_table = ppc32_update_translation_table;                  cpu->update_translation_table = ppc32_update_translation_table;
121                  cpu->invalidate_translation_caches_paddr =                  cpu->invalidate_translation_caches =
122                      ppc32_invalidate_translation_caches_paddr;                      ppc32_invalidate_translation_caches;
123                  cpu->invalidate_code_translation =                  cpu->invalidate_code_translation =
124                      ppc32_invalidate_code_translation;                      ppc32_invalidate_code_translation;
125          } else {          } else {
126                    cpu->run_instr = ppc_run_instr;
127                  cpu->update_translation_table = ppc_update_translation_table;                  cpu->update_translation_table = ppc_update_translation_table;
128                  cpu->invalidate_translation_caches_paddr =                  cpu->invalidate_translation_caches =
129                      ppc_invalidate_translation_caches_paddr;                      ppc_invalidate_translation_caches;
130                  cpu->invalidate_code_translation =                  cpu->invalidate_code_translation =
131                      ppc_invalidate_code_translation;                      ppc_invalidate_code_translation;
132          }          }
133    
134          cpu->translate_address = ppc_translate_address;          cpu->translate_v2p = ppc_translate_v2p;
135    
136          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */
137          if (cpu_id == 0) {          if (cpu_id == 0) {
# Line 128  int ppc_cpu_new(struct cpu *cpu, struct Line 157  int ppc_cpu_new(struct cpu *cpu, struct
157                  }                  }
158          }          }
159    
160          cpu->cd.ppc.pir = cpu_id;          cpu->cd.ppc.spr[SPR_PIR] = cpu_id;
161    
162          /*  Some default stack pointer value.  TODO: move this?  */          /*  Some default stack pointer value.  TODO: move this?  */
163          cpu->cd.ppc.gpr[1] = machine->physical_ram_in_mb * 1048576 - 4096;          cpu->cd.ppc.gpr[1] = machine->physical_ram_in_mb * 1048576 - 4096;
# Line 203  void ppc_cpu_dumpinfo(struct cpu *cpu) Line 232  void ppc_cpu_dumpinfo(struct cpu *cpu)
232  /*  /*
233   *  reg_access_msr():   *  reg_access_msr():
234   */   */
235  void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag)  void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag,
236            int check_for_interrupts)
237  {  {
238            uint64_t old = cpu->cd.ppc.msr;
239    
240          if (valuep == NULL) {          if (valuep == NULL) {
241                  fatal("reg_access_msr(): NULL\n");                  fatal("reg_access_msr(): NULL\n");
242                  return;                  return;
243          }          }
244    
245          if (writeflag)          if (writeflag) {
246                  cpu->cd.ppc.msr = *valuep;                  cpu->cd.ppc.msr = *valuep;
247    
248                    /*  Switching between temporary and real gpr 0..3?  */
249                    if ((old & PPC_MSR_TGPR) != (cpu->cd.ppc.msr & PPC_MSR_TGPR)) {
250                            int i;
251                            for (i=0; i<PPC_N_TGPRS; i++) {
252                                    uint64_t t = cpu->cd.ppc.gpr[i];
253                                    cpu->cd.ppc.gpr[i] = cpu->cd.ppc.tgpr[i];
254                                    cpu->cd.ppc.tgpr[i] = t;
255                            }
256                    }
257    
258                    if (cpu->cd.ppc.msr & PPC_MSR_IP) {
259                            fatal("\n[ Reboot hack for NetBSD/prep. TODO: "
260                                "fix this. ]\n");
261                            cpu->running = 0;
262                    }
263            }
264    
265          /*  TODO: Is the little-endian bit writable?  */          /*  TODO: Is the little-endian bit writable?  */
266    
267          cpu->cd.ppc.msr &= ~PPC_MSR_LE;          cpu->cd.ppc.msr &= ~PPC_MSR_LE;
# Line 221  void reg_access_msr(struct cpu *cpu, uin Line 270  void reg_access_msr(struct cpu *cpu, uin
270    
271          if (!writeflag)          if (!writeflag)
272                  *valuep = cpu->cd.ppc.msr;                  *valuep = cpu->cd.ppc.msr;
273    
274            if (check_for_interrupts && cpu->cd.ppc.msr & PPC_MSR_EE) {
275                    if (cpu->cd.ppc.dec_intr_pending &&
276                        !(cpu->cd.ppc.cpu_type.flags & PPC_NO_DEC)) {
277                            ppc_exception(cpu, PPC_EXCEPTION_DEC);
278                            cpu->cd.ppc.dec_intr_pending = 0;
279                    } else if (cpu->cd.ppc.irq_asserted)
280                            ppc_exception(cpu, PPC_EXCEPTION_EI);
281            }
282    }
283    
284    
285    /*
286     *  ppc_exception():
287     */
288    void ppc_exception(struct cpu *cpu, int exception_nr)
289    {
290            /*  Save PC and MSR:  */
291            cpu->cd.ppc.spr[SPR_SRR0] = cpu->pc;
292    
293            if (exception_nr >= 0x10 && exception_nr <= 0x13)
294                    cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0xffff)
295                        | (cpu->cd.ppc.cr & 0xf0000000);
296            else
297                    cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);
298    
299            if (!quiet_mode)
300                    fatal("[ PPC Exception 0x%x; pc=0x%"PRIx64" ]\n", exception_nr,
301                        (long long)cpu->pc);
302    
303            /*  Disable External Interrupts, Recoverable Interrupt Mode,
304                and go to Supervisor mode  */
305            cpu->cd.ppc.msr &= ~(PPC_MSR_EE | PPC_MSR_RI | PPC_MSR_PR);
306    
307            cpu->pc = exception_nr * 0x100;
308            if (cpu->cd.ppc.msr & PPC_MSR_IP)
309                    cpu->pc += 0xfff00000ULL;
310    
311            if (cpu->is_32bit)
312                    ppc32_pc_to_pointers(cpu);
313            else
314                    ppc_pc_to_pointers(cpu);
315  }  }
316    
317    
# Line 246  void ppc_cpu_register_dump(struct cpu *c Line 337  void ppc_cpu_register_dump(struct cpu *c
337    
338                  debug("cpu%i: pc  = 0x", x);                  debug("cpu%i: pc  = 0x", x);
339                  if (bits32)                  if (bits32)
340                          debug("%08x", (int)cpu->pc);                          debug("%08"PRIx32, (uint32_t)cpu->pc);
341                  else                  else
342                          debug("%016llx", (long long)cpu->pc);                          debug("%016"PRIx64, (uint64_t)cpu->pc);
343                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
344    
345                  debug("cpu%i: lr  = 0x", x);                  debug("cpu%i: lr  = 0x", x);
346                  if (bits32)                  if (bits32)
347                          debug("%08x", (int)cpu->cd.ppc.lr);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_LR]);
348                  else                  else
349                          debug("%016llx", (long long)cpu->cd.ppc.lr);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_LR]);
350                  debug("  cr  = 0x%08x\n", (int)cpu->cd.ppc.cr);                  debug("  cr  = 0x%08"PRIx32, (uint32_t)cpu->cd.ppc.cr);
351    
                 debug("cpu%i: ctr = 0x", x);  
352                  if (bits32)                  if (bits32)
353                          debug("%08x", (int)cpu->cd.ppc.ctr);                          debug("  ");
354                    else
355                            debug("\ncpu%i: ", x);
356                    debug("ctr = 0x", x);
357                    if (bits32)
358                            debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_CTR]);
359                  else                  else
360                          debug("%016llx", (long long)cpu->cd.ppc.ctr);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_CTR]);
361    
362                  debug("  xer = 0x", x);                  debug("  xer = 0x", x);
363                  if (bits32)                  if (bits32)
364                          debug("%08x\n", (int)cpu->cd.ppc.xer);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_XER]);
365                  else                  else
366                          debug("%016llx\n", (long long)cpu->cd.ppc.xer);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_XER]);
367    
368                    debug("\n");
369    
370                  if (bits32) {                  if (bits32) {
371                          /*  32-bit:  */                          /*  32-bit:  */
# Line 294  void ppc_cpu_register_dump(struct cpu *c Line 391  void ppc_cpu_register_dump(struct cpu *c
391                  }                  }
392    
393                  /*  Other special registers:  */                  /*  Other special registers:  */
394                  debug("cpu%i: srr0 = 0x%016llx  srr1 = 0x%016llx\n", x,                  if (bits32) {
395                      (long long)cpu->cd.ppc.srr0, (long long)cpu->cd.ppc.srr1);                          debug("cpu%i: srr0 = 0x%08x srr1 = 0x%08x\n", x,
396                  reg_access_msr(cpu, &tmp, 0);                              (int)cpu->cd.ppc.spr[SPR_SRR0],
397                  debug("cpu%i: msr = 0x%016llx  ", x, (long long)tmp);                              (int)cpu->cd.ppc.spr[SPR_SRR1]);
398                  debug("tb  = 0x%08x%08x\n",                  } else {
399                      (int)cpu->cd.ppc.tbu, (int)cpu->cd.ppc.tbl);                          debug("cpu%i: srr0 = 0x%016llx  srr1 = 0x%016llx\n", x,
400                  debug("cpu%i: dec = 0x%08x  hdec = 0x%08x\n",                              (long long)cpu->cd.ppc.spr[SPR_SRR0],
401                      x, (int)cpu->cd.ppc.dec, (int)cpu->cd.ppc.hdec);                              (long long)cpu->cd.ppc.spr[SPR_SRR1]);
402                    }
403                    debug("cpu%i: msr = ", x);
404                    reg_access_msr(cpu, &tmp, 0, 0);
405                    if (bits32)
406                            debug("0x%08x  ", (int)tmp);
407                    else
408                            debug("0x%016llx  ", (long long)tmp);
409                    debug("tb  = 0x%08x%08x\n", (int)cpu->cd.ppc.spr[SPR_TBU],
410                        (int)cpu->cd.ppc.spr[SPR_TBL]);
411                    debug("cpu%i: dec = 0x%08x", x, (int)cpu->cd.ppc.spr[SPR_DEC]);
412                    if (!bits32)
413                            debug("  hdec = 0x%08x\n",
414                                (int)cpu->cd.ppc.spr[SPR_HDEC]);
415                    debug("\n");
416          }          }
417    
418          if (coprocs & 1) {          if (coprocs & 1) {
# Line 323  void ppc_cpu_register_dump(struct cpu *c Line 434  void ppc_cpu_register_dump(struct cpu *c
434    
435          if (coprocs & 2) {          if (coprocs & 2) {
436                  debug("cpu%i:  sdr1 = 0x%llx\n", x,                  debug("cpu%i:  sdr1 = 0x%llx\n", x,
437                      (long long)cpu->cd.ppc.sdr1);                      (long long)cpu->cd.ppc.spr[SPR_SDR1]);
438                  for (i=0; i<4; i++)                  if (cpu->cd.ppc.cpu_type.flags & PPC_601)
439                          debug("cpu%i:  ibat%iu = 0x%08x  ibat%il = 0x%08x\n",                          debug("cpu%i:  PPC601-style, TODO!\n");
440                              x, i, cpu->cd.ppc.ibat_u[i],                  else {
441                              i, cpu->cd.ppc.ibat_l[i]);                          for (i=0; i<8; i++) {
442                  for (i=0; i<4; i++)                                  int spr = SPR_IBAT0U + i*2;
443                          debug("cpu%i:  dbat%iu = 0x%08x  dbat%il = 0x%08x\n",                                  uint32_t upper = cpu->cd.ppc.spr[spr];
444                              x, i, cpu->cd.ppc.dbat_u[i],                                  uint32_t lower = cpu->cd.ppc.spr[spr+1];
445                              i, cpu->cd.ppc.dbat_l[i]);                                  uint32_t len = (((upper & BAT_BL) << 15)
446                                        | 0x1ffff) + 1;
447                                    debug("cpu%i:  %sbat%i: u=0x%08x l=0x%08x ",
448                                        x, i<4? "i" : "d", i&3, upper, lower);
449                                    if (!(upper & BAT_V)) {
450                                            debug(" (not valid)\n");
451                                            continue;
452                                    }
453                                    if (len < 1048576)
454                                            debug(" (%i KB, ", len >> 10);
455                                    else
456                                            debug(" (%i MB, ", len >> 20);
457                                    if (upper & BAT_Vu)
458                                            debug("user, ");
459                                    if (upper & BAT_Vs)
460                                            debug("supervisor, ");
461                                    if (lower & (BAT_W | BAT_I | BAT_M | BAT_G))
462                                            debug("%s%s%s%s, ",
463                                                lower & BAT_W? "W" : "",
464                                                lower & BAT_I? "I" : "",
465                                                lower & BAT_M? "M" : "",
466                                                lower & BAT_G? "G" : "");
467                                    switch (lower & BAT_PP) {
468                                    case BAT_PP_NONE: debug("NO access"); break;
469                                    case BAT_PP_RO_S: debug("read-only, soft");
470                                                      break;
471                                    case BAT_PP_RO:   debug("read-only"); break;
472                                    case BAT_PP_RW:   debug("read/write"); break;
473                                    }
474                                    debug(")\n");
475                            }
476                    }
477            }
478    
479            if (coprocs & 4) {
480                    for (i=0; i<16; i++) {
481                            uint32_t s = cpu->cd.ppc.sr[i];
482                            debug("cpu%i:", x);
483                            debug("  sr%2i = 0x%08x", i, (int)s);
484                            s &= (SR_TYPE | SR_SUKEY | SR_PRKEY | SR_NOEXEC);
485                            if (s != 0) {
486                                    debug("  (");
487                                    if (s & SR_TYPE) {
488                                            debug("NON-memory type");
489                                            s &= ~SR_TYPE;
490                                            if (s != 0)
491                                                    debug(", ");
492                                    }
493                                    if (s & SR_SUKEY) {
494                                            debug("supervisor-key");
495                                            s &= ~SR_SUKEY;
496                                            if (s != 0)
497                                                    debug(", ");
498                                    }
499                                    if (s & SR_PRKEY) {
500                                            debug("user-key");
501                                            s &= ~SR_PRKEY;
502                                            if (s != 0)
503                                                    debug(", ");
504                                    }
505                                    if (s & SR_NOEXEC)
506                                            debug("NOEXEC");
507                                    debug(")");
508                            }
509                            debug("\n");
510                    }
511          }          }
512  }  }
513    
# Line 363  void ppc_cpu_register_match(struct machi Line 539  void ppc_cpu_register_match(struct machi
539                  *match_register = 1;                  *match_register = 1;
540          } else if (strcasecmp(name, "lr") == 0) {          } else if (strcasecmp(name, "lr") == 0) {
541                  if (writeflag)                  if (writeflag)
542                          m->cpus[cpunr]->cd.ppc.lr = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_LR] = *valuep;
543                  else                  else
544                          *valuep = m->cpus[cpunr]->cd.ppc.lr;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_LR];
545                  *match_register = 1;                  *match_register = 1;
546          } else if (strcasecmp(name, "cr") == 0) {          } else if (strcasecmp(name, "cr") == 0) {
547                  if (writeflag)                  if (writeflag)
# Line 375  void ppc_cpu_register_match(struct machi Line 551  void ppc_cpu_register_match(struct machi
551                  *match_register = 1;                  *match_register = 1;
552          } else if (strcasecmp(name, "dec") == 0) {          } else if (strcasecmp(name, "dec") == 0) {
553                  if (writeflag)                  if (writeflag)
554                          m->cpus[cpunr]->cd.ppc.dec = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_DEC] = *valuep;
555                  else                  else
556                          *valuep = m->cpus[cpunr]->cd.ppc.dec;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_DEC];
557                  *match_register = 1;                  *match_register = 1;
558          } else if (strcasecmp(name, "hdec") == 0) {          } else if (strcasecmp(name, "hdec") == 0) {
559                  if (writeflag)                  if (writeflag)
560                          m->cpus[cpunr]->cd.ppc.hdec = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_HDEC] = *valuep;
561                  else                  else
562                          *valuep = m->cpus[cpunr]->cd.ppc.hdec;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_HDEC];
563                  *match_register = 1;                  *match_register = 1;
564          } else if (strcasecmp(name, "ctr") == 0) {          } else if (strcasecmp(name, "ctr") == 0) {
565                  if (writeflag)                  if (writeflag)
566                          m->cpus[cpunr]->cd.ppc.ctr = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_CTR] = *valuep;
567                  else                  else
568                          *valuep = m->cpus[cpunr]->cd.ppc.ctr;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_CTR];
569                  *match_register = 1;                  *match_register = 1;
570          } else if (name[0] == 'r' && isdigit((int)name[1])) {          } else if (name[0] == 'r' && isdigit((int)name[1])) {
571                  int nr = atoi(name + 1);                  int nr = atoi(name + 1);
# Line 402  void ppc_cpu_register_match(struct machi Line 578  void ppc_cpu_register_match(struct machi
578                  }                  }
579          } else if (strcasecmp(name, "xer") == 0) {          } else if (strcasecmp(name, "xer") == 0) {
580                  if (writeflag)                  if (writeflag)
581                          m->cpus[cpunr]->cd.ppc.xer = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_XER] = *valuep;
582                  else                  else
583                          *valuep = m->cpus[cpunr]->cd.ppc.xer;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_XER];
584                  *match_register = 1;                  *match_register = 1;
585          } else if (strcasecmp(name, "fpscr") == 0) {          } else if (strcasecmp(name, "fpscr") == 0) {
586                  if (writeflag)                  if (writeflag)
# Line 426  void ppc_cpu_register_match(struct machi Line 602  void ppc_cpu_register_match(struct machi
602    
603    
604  /*  /*
605   *  ppc_cpu_show_full_statistics():   *  ppc_cpu_tlbdump():
606   *   *
607   *  Show detailed statistics on opcode usage on each cpu.   *  Not currently used for PPC.
608   */   */
609  void ppc_cpu_show_full_statistics(struct machine *m)  void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)
610  {  {
611          fatal("ppc_cpu_show_full_statistics(): TODO\n");  }
612    
613    
614    static void add_response_word(struct cpu *cpu, char *r, uint64_t value,
615            size_t maxlen, int len)
616    {
617            char *format = (len == 4)? "%08"PRIx64 : "%016"PRIx64;
618            if (len == 4)
619                    value &= 0xffffffffULL;
620            if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
621                    if (len == 4) {
622                            value = ((value & 0xff) << 24) +
623                                    ((value & 0xff00) << 8) +
624                                    ((value & 0xff0000) >> 8) +
625                                    ((value & 0xff000000) >> 24);
626                    } else {
627                            value = ((value & 0xff) << 56) +
628                                    ((value & 0xff00) << 40) +
629                                    ((value & 0xff0000) << 24) +
630                                    ((value & 0xff000000ULL) << 8) +
631                                    ((value & 0xff00000000ULL) >> 8) +
632                                    ((value & 0xff0000000000ULL) >> 24) +
633                                    ((value & 0xff000000000000ULL) >> 40) +
634                                    ((value & 0xff00000000000000ULL) >> 56);
635                    }
636            }
637            snprintf(r + strlen(r), maxlen - strlen(r), format, (uint64_t)value);
638  }  }
639    
640    
641  /*  /*
642   *  ppc_cpu_tlbdump():   *  ppc_cpu_gdb_stub():
  *  
  *  Called from the debugger to dump the TLB in a readable format.  
  *  x is the cpu number to dump, or -1 to dump all CPUs.  
643   *   *
644   *  If rawflag is nonzero, then the TLB contents isn't formated nicely,   *  Execute a "remote GDB" command. Returns a newly allocated response string
645   *  just dumped.   *  on success, NULL on failure.
646   */   */
647  void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)  char *ppc_cpu_gdb_stub(struct cpu *cpu, char *cmd)
648  {  {
649          fatal("ppc_cpu_tlbdump(): TODO\n");          if (strcmp(cmd, "g") == 0) {
650                    int i;
651                    char *r;
652                    size_t wlen = cpu->is_32bit?
653                        sizeof(uint32_t) : sizeof(uint64_t);
654                    size_t len = 1 + 76 * wlen;
655                    r = malloc(len);
656                    if (r == NULL) {
657                            fprintf(stderr, "out of memory\n");
658                            exit(1);
659                    }
660                    r[0] = '\0';
661                    for (i=0; i<128; i++)
662                            add_response_word(cpu, r, i, len, wlen);
663                    return r;
664            }
665    
666            if (cmd[0] == 'p') {
667                    int regnr = strtol(cmd + 1, NULL, 16);
668                    size_t wlen = cpu->is_32bit?
669                        sizeof(uint32_t) : sizeof(uint64_t);
670                    size_t len = 2 * wlen + 1;
671                    char *r = malloc(len);
672                    r[0] = '\0';
673                    if (regnr >= 0 && regnr <= 31) {
674                            add_response_word(cpu, r,
675                                cpu->cd.ppc.gpr[regnr], len, wlen);
676                    } else if (regnr == 0x40) {
677                            add_response_word(cpu, r, cpu->pc, len, wlen);
678                    } else if (regnr == 0x42) {
679                            add_response_word(cpu, r, cpu->cd.ppc.cr, len, wlen);
680                    } else if (regnr == 0x43) {
681                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_LR],
682                                len, wlen);
683                    } else if (regnr == 0x44) {
684                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_CTR],
685                                len, wlen);
686                    } else if (regnr == 0x45) {
687                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_XER],
688                                len, wlen);
689                    } else {
690                            /*  Unimplemented:  */
691                            add_response_word(cpu, r, 0xcc000 + regnr, len, wlen);
692                    }
693                    return r;
694            }
695    
696            fatal("ppc_cpu_gdb_stub(): TODO\n");
697            return NULL;
698  }  }
699    
700    
701  /*  /*
702   *  ppc_cpu_interrupt():   *  ppc_cpu_interrupt():
703     *
704     *  0..31 are used as BeBox interrupt numbers, 32..47 = ISA,
705     *  64 is used as a "re-assert" signal to cpu->machine->md_interrupt().
706     *
707     *  TODO: don't hardcode to BeBox!
708   */   */
709  int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
710  {  {
711          fatal("ppc_cpu_interrupt(): TODO\n");          /*  fatal("ppc_cpu_interrupt(): 0x%x\n", (int)irq_nr);  */
712          return 0;          if (irq_nr <= 64) {
713                    if (cpu->machine->md_interrupt != NULL)
714                            cpu->machine->md_interrupt(
715                                cpu->machine, cpu, irq_nr, 1);
716                    else
717                            fatal("ppc_cpu_interrupt(): md_interrupt == NULL\n");
718            } else {
719                    /*  Assert PPC IRQ:  */
720                    cpu->cd.ppc.irq_asserted = 1;
721            }
722            return 1;
723  }  }
724    
725    
# Line 466  int ppc_cpu_interrupt(struct cpu *cpu, u Line 728  int ppc_cpu_interrupt(struct cpu *cpu, u
728   */   */
729  int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
730  {  {
731          /*  fatal("ppc_cpu_interrupt_ack(): TODO\n");  */          if (irq_nr <= 64) {
732          return 0;                  if (cpu->machine->md_interrupt != NULL)
733                            cpu->machine->md_interrupt(cpu->machine,
734                                cpu, irq_nr, 0);
735            } else {
736                    /*  De-assert PPC IRQ:  */
737                    cpu->cd.ppc.irq_asserted = 0;
738            }
739            return 1;
740  }  }
741    
742    
# Line 484  int ppc_cpu_interrupt_ack(struct cpu *cp Line 753  int ppc_cpu_interrupt_ack(struct cpu *cp
753   *  cpu->pc for relative addresses.   *  cpu->pc for relative addresses.
754   */   */
755  int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,  int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
756          int running, uint64_t dumpaddr, int bintrans)          int running, uint64_t dumpaddr)
757  {  {
758          int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;          int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;
759          int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;          int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;
# Line 523  int ppc_cpu_disassemble_instr(struct cpu Line 792  int ppc_cpu_disassemble_instr(struct cpu
792          hi6 = iword >> 26;          hi6 = iword >> 26;
793    
794          switch (hi6) {          switch (hi6) {
795            case 0x4:
796                    debug("ALTIVEC TODO");
797                    /*  vxor etc  */
798                    break;
799          case PPC_HI6_MULLI:          case PPC_HI6_MULLI:
800          case PPC_HI6_SUBFIC:          case PPC_HI6_SUBFIC:
801                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
# Line 715  int ppc_cpu_disassemble_instr(struct cpu Line 988  int ppc_cpu_disassemble_instr(struct cpu
988                          debug("unimplemented hi6_19, xo = 0x%x", xo);                          debug("unimplemented hi6_19, xo = 0x%x", xo);
989                  }                  }
990                  break;                  break;
991            case PPC_HI6_RLWNM:
992          case PPC_HI6_RLWIMI:          case PPC_HI6_RLWIMI:
993          case PPC_HI6_RLWINM:          case PPC_HI6_RLWINM:
994                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
995                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
996                  sh = (iword >> 11) & 31;                  sh = (iword >> 11) & 31;        /*  actually rb for rlwnm  */
997                  mb = (iword >> 6) & 31;                  mb = (iword >> 6) & 31;
998                  me = (iword >> 1) & 31;                  me = (iword >> 1) & 31;
999                  rc = iword & 1;                  rc = iword & 1;
1000                  switch (hi6) {                  switch (hi6) {
1001                    case PPC_HI6_RLWNM:
1002                            mnem = power? "rlnm" : "rlwnm"; break;
1003                  case PPC_HI6_RLWIMI:                  case PPC_HI6_RLWIMI:
1004                          mnem = power? "rlimi" : "rlwimi"; break;                          mnem = power? "rlimi" : "rlwimi"; break;
1005                  case PPC_HI6_RLWINM:                  case PPC_HI6_RLWINM:
1006                          mnem = power? "rlinm" : "rlwinm"; break;                          mnem = power? "rlinm" : "rlwinm"; break;
1007                  }                  }
1008                  debug("%s%s\tr%i,r%i,%i,%i,%i",                  debug("%s%s\tr%i,r%i,%s%i,%i,%i",
1009                      mnem, rc?".":"", ra, rs, sh, mb, me);                      mnem, rc?".":"", ra, rs,
1010                        hi6 == PPC_HI6_RLWNM? "r" : "",
1011                        sh, mb, me);
1012                  break;                  break;
1013          case PPC_HI6_ORI:          case PPC_HI6_ORI:
1014          case PPC_HI6_ORIS:          case PPC_HI6_ORIS:
# Line 769  int ppc_cpu_disassemble_instr(struct cpu Line 1047  int ppc_cpu_disassemble_instr(struct cpu
1047          case PPC_HI6_30:          case PPC_HI6_30:
1048                  xo = (iword >> 2) & 7;                  xo = (iword >> 2) & 7;
1049                  switch (xo) {                  switch (xo) {
1050                    case PPC_30_RLDICL:
1051                  case PPC_30_RLDICR:                  case PPC_30_RLDICR:
1052                    case PPC_30_RLDIMI:     /*  mb, not me  */
1053                            mnem = NULL;
1054                            switch (xo) {
1055                            case PPC_30_RLDICL: mnem = "rldicl"; break;
1056                            case PPC_30_RLDICR: mnem = "rldicr"; break;
1057                            case PPC_30_RLDIMI: mnem = "rldimi"; break;
1058                            }
1059                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1060                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1061                          sh = ((iword >> 11) & 31) | ((iword & 2) << 4);                          sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
1062                          me = ((iword >> 6) & 31) | (iword & 0x20);                          me = ((iword >> 6) & 31) | (iword & 0x20);
1063                          rc = iword & 1;                          rc = iword & 1;
1064                          debug("rldicr%s\tr%i,r%i,%i,%i",                          debug("%s%s\tr%i,r%i,%i,%i",
1065                              rc?".":"", ra, rs, sh, me);                              mnem, rc?".":"", ra, rs, sh, me);
1066                          break;                          break;
1067                  default:                  default:
1068                          debug("unimplemented hi6_30, xo = 0x%x", xo);                          debug("unimplemented hi6_30, xo = 0x%x", xo);
# Line 836  int ppc_cpu_disassemble_instr(struct cpu Line 1122  int ppc_cpu_disassemble_instr(struct cpu
1122                  case PPC_31_LDARX:                  case PPC_31_LDARX:
1123                  case PPC_31_LBZX:                  case PPC_31_LBZX:
1124                  case PPC_31_LBZUX:                  case PPC_31_LBZUX:
1125                    case PPC_31_LHAX:
1126                    case PPC_31_LHAUX:
1127                  case PPC_31_LHZX:                  case PPC_31_LHZX:
1128                  case PPC_31_LHZUX:                  case PPC_31_LHZUX:
1129                  case PPC_31_LWZX:                  case PPC_31_LWZX:
1130                  case PPC_31_LWZUX:                  case PPC_31_LWZUX:
1131                    case PPC_31_LHBRX:
1132                    case PPC_31_LWBRX:
1133                    case PPC_31_LFDX:
1134                    case PPC_31_LFSX:
1135                  case PPC_31_STWCX_DOT:                  case PPC_31_STWCX_DOT:
1136                  case PPC_31_STDCX_DOT:                  case PPC_31_STDCX_DOT:
1137                  case PPC_31_STBX:                  case PPC_31_STBX:
# Line 850  int ppc_cpu_disassemble_instr(struct cpu Line 1142  int ppc_cpu_disassemble_instr(struct cpu
1142                  case PPC_31_STWUX:                  case PPC_31_STWUX:
1143                  case PPC_31_STDX:                  case PPC_31_STDX:
1144                  case PPC_31_STDUX:                  case PPC_31_STDUX:
1145                    case PPC_31_STHBRX:
1146                    case PPC_31_STWBRX:
1147                    case PPC_31_STFDX:
1148                    case PPC_31_STFSX:
1149                          /*  rs for stores, rt for loads, actually  */                          /*  rs for stores, rt for loads, actually  */
1150                          load = 0; wlen = 0;                          load = 0; wlen = 0; fpreg = 0;
1151                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1152                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1153                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
# Line 860  int ppc_cpu_disassemble_instr(struct cpu Line 1156  int ppc_cpu_disassemble_instr(struct cpu
1156                          case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;                          case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;
1157                          case PPC_31_LBZX:  wlen=1;load=1; mnem = "lbzx"; break;                          case PPC_31_LBZX:  wlen=1;load=1; mnem = "lbzx"; break;
1158                          case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;                          case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;
1159                            case PPC_31_LHAX:  wlen=2;load=1; mnem = "lhax"; break;
1160                            case PPC_31_LHAUX: wlen=2;load=1; mnem = "lhaux"; break;
1161                          case PPC_31_LHZX:  wlen=2;load=1; mnem = "lhzx"; break;                          case PPC_31_LHZX:  wlen=2;load=1; mnem = "lhzx"; break;
1162                          case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;                          case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;
1163                          case PPC_31_LWZX:  wlen = 4; load = 1;                          case PPC_31_LWZX:  wlen = 4; load = 1;
# Line 868  int ppc_cpu_disassemble_instr(struct cpu Line 1166  int ppc_cpu_disassemble_instr(struct cpu
1166                          case PPC_31_LWZUX: wlen = 4; load = 1;                          case PPC_31_LWZUX: wlen = 4; load = 1;
1167                                  mnem = power? "lux":"lwzux";                                  mnem = power? "lux":"lwzux";
1168                                  break;                                  break;
1169                            case PPC_31_LFDX: fpreg = 1; wlen = 8; load = 1;
1170                                    mnem = "lfdx"; break;
1171                            case PPC_31_LFSX: fpreg = 1; wlen = 4; load = 1;
1172                                    mnem = "lfsx"; break;
1173                          case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;                          case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;
1174                          case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;                          case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;
1175                          case PPC_31_STBX:  wlen=1; mnem = "stbx"; break;                          case PPC_31_STBX:  wlen=1; mnem = "stbx"; break;
# Line 882  int ppc_cpu_disassemble_instr(struct cpu Line 1184  int ppc_cpu_disassemble_instr(struct cpu
1184                                  break;                                  break;
1185                          case PPC_31_STDX:  wlen = 8; mnem = "stdx"; break;                          case PPC_31_STDX:  wlen = 8; mnem = "stdx"; break;
1186                          case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;                          case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;
1187                            case PPC_31_LHBRX:  wlen = 2; mnem = "lhbrx"; break;
1188                            case PPC_31_LWBRX:  wlen = 4; mnem = power?
1189                                                "lbrx" : "lwbrx"; break;
1190                            case PPC_31_STHBRX: wlen = 2; mnem = "sthbrx"; break;
1191                            case PPC_31_STWBRX: wlen = 4; mnem = power?
1192                                                "stbrx" : "stwbrx"; break;
1193                            case PPC_31_STFDX: fpreg = 1; wlen = 8;
1194                                    mnem = "stfdx"; break;
1195                            case PPC_31_STFSX: fpreg = 1; wlen = 4;
1196                                    mnem = "stfsx"; break;
1197                          }                          }
1198                          debug("%s\tr%i,r%i,r%i", mnem, rs, ra, rb);                          debug("%s\t%s%i,r%i,r%i", mnem,
1199                                fpreg? "f" : "r", rs, ra, rb);
1200                          if (!running)                          if (!running)
1201                                  break;                                  break;
1202                          addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +                          addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +
1203                              cpu->cd.ppc.gpr[rb];                              cpu->cd.ppc.gpr[rb];
1204                            if (cpu->cd.ppc.bits == 32)
1205                                    addr &= 0xffffffff;
1206                          symbol = get_symbol_name(&cpu->machine->symbol_context,                          symbol = get_symbol_name(&cpu->machine->symbol_context,
1207                              addr, &offset);                              addr, &offset);
1208                          if (symbol != NULL)                          if (symbol != NULL)
1209                                  debug(" \t<%s", symbol);                                  debug(" \t<%s", symbol);
1210                          else                          else
1211                                  debug(" \t<0x%llx", (long long)addr);                                  debug(" \t<0x%llx", (long long)addr);
1212                          if (wlen > 0) {                          if (wlen > 0 && !fpreg /* && !reverse */) {
1213                                  /*  TODO  */                                  /*  TODO  */
1214                          }                          }
1215                          debug(">");                          debug(">");
# Line 911  int ppc_cpu_disassemble_instr(struct cpu Line 1226  int ppc_cpu_disassemble_instr(struct cpu
1226                          }                          }
1227                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1228                          break;                          break;
1229                    case PPC_31_WRTEEI:
1230                            debug("wrteei\t%i", iword & 0x8000? 1 : 0);
1231                            break;
1232                    case PPC_31_MTMSRD:
1233                            /*  TODO: Just a guess based on MTMSR  */
1234                            rs = (iword >> 21) & 31;
1235                            l_bit = (iword >> 16) & 1;
1236                            debug("mtmsrd\tr%i", rs);
1237                            if (l_bit)
1238                                    debug(",%i", l_bit);
1239                            break;
1240                  case PPC_31_ADDZE:                  case PPC_31_ADDZE:
1241                  case PPC_31_ADDZEO:                  case PPC_31_ADDZEO:
1242                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 928  int ppc_cpu_disassemble_instr(struct cpu Line 1254  int ppc_cpu_disassemble_instr(struct cpu
1254                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1255                          break;                          break;
1256                  case PPC_31_MTSR:                  case PPC_31_MTSR:
1257                          /*  Move to segment register  */                  case PPC_31_MFSR:
1258                            /*  Move to/from segment register  */
1259                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1260                          ra = (iword >> 16) & 15;        /*  actually: sr  */                          ra = (iword >> 16) & 15;        /*  actually: sr  */
1261                          debug("mtsr\t%i,r%i", ra, rt);                          switch (xo) {
1262                            case PPC_31_MTSR:  mnem = "mtsr"; break;
1263                            case PPC_31_MFSR:  mnem = "mfsr"; break;
1264                            }
1265                            debug("%s\tr%i,%i", mnem, rt, ra);
1266                          break;                          break;
1267                  case PPC_31_MTSRIN:                  case PPC_31_MTSRIN:
1268                  case PPC_31_MFSRIN:                  case PPC_31_MFSRIN:
# Line 962  int ppc_cpu_disassemble_instr(struct cpu Line 1293  int ppc_cpu_disassemble_instr(struct cpu
1293                  case PPC_31_SUBFCO:                  case PPC_31_SUBFCO:
1294                  case PPC_31_SUBFE:                  case PPC_31_SUBFE:
1295                  case PPC_31_SUBFEO:                  case PPC_31_SUBFEO:
1296                    case PPC_31_SUBFME:
1297                    case PPC_31_SUBFMEO:
1298                  case PPC_31_SUBFZE:                  case PPC_31_SUBFZE:
1299                  case PPC_31_SUBFZEO:                  case PPC_31_SUBFZEO:
1300                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 1007  int ppc_cpu_disassemble_instr(struct cpu Line 1340  int ppc_cpu_disassemble_instr(struct cpu
1340                          case PPC_31_SUBF:   mnem = "subf"; break;                          case PPC_31_SUBF:   mnem = "subf"; break;
1341                          case PPC_31_SUBFO:  mnem = "subfo"; break;                          case PPC_31_SUBFO:  mnem = "subfo"; break;
1342                          case PPC_31_SUBFC:                          case PPC_31_SUBFC:
1343                                  mnem = power? "sf" : "subfc";                                  mnem = power? "sf" : "subfc"; break;
                                 break;  
1344                          case PPC_31_SUBFCO:                          case PPC_31_SUBFCO:
1345                                  mnem = power? "sfo" : "subfco";                                  mnem = power? "sfo" : "subfco"; break;
                                 break;  
1346                          case PPC_31_SUBFE:                          case PPC_31_SUBFE:
1347                                  mnem = power? "sfe" : "subfe";                                  mnem = power? "sfe" : "subfe"; break;
                                 break;  
1348                          case PPC_31_SUBFEO:                          case PPC_31_SUBFEO:
1349                                  mnem = power? "sfeo" : "subfeo";                                  mnem = power? "sfeo" : "subfeo"; break;
1350                                  break;                          case PPC_31_SUBFME:
1351                                    mnem = power? "sfme" : "subfme"; break;
1352                            case PPC_31_SUBFMEO:
1353                                    mnem = power? "sfmeo" : "subfmeo"; break;
1354                          case PPC_31_SUBFZE:                          case PPC_31_SUBFZE:
1355                                  mnem = power? "sfze" : "subfze";                                  mnem = power? "sfze" : "subfze";
1356                                  no_rb = 1;                                  no_rb = 1;
# Line 1035  int ppc_cpu_disassemble_instr(struct cpu Line 1368  int ppc_cpu_disassemble_instr(struct cpu
1368                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1369                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1370                          switch (spr) {                          switch (spr) {
1371                            /*  Some very common ones:  */
1372                          case 8:    debug("mflr\tr%i", rt); break;                          case 8:    debug("mflr\tr%i", rt); break;
1373                          case 9:    debug("mfctr\tr%i", rt); break;                          case 9:    debug("mfctr\tr%i", rt); break;
                         case 26:   debug("mfsrr0\tr%i", rt); break;  
                         case 27:   debug("mfsrr1\tr%i", rt); break;  
                         case 272:  debug("mfsprg\t0,r%i", rt); break;  
                         case 273:  debug("mfsprg\t1,r%i", rt); break;  
                         case 274:  debug("mfsprg\t2,r%i", rt); break;  
                         case 275:  debug("mfsprg\t3,r%i", rt); break;  
                         case 287:  debug("mfpvr\tr%i", rt); break;  
                         /*  TODO: 1008 = hid0?  */  
                         case 1008: debug("mfdbsr\tr%i", rt); break;  
                         case 1009: debug("mfhid1\tr%i", rt); break;  
                         case 1017: debug("mfl2cr\tr%i", rt); break;  
                         case 1018: debug("mfl3cr\tr%i", rt); break;  
1374                          default:debug("mfspr\tr%i,spr%i", rt, spr);                          default:debug("mfspr\tr%i,spr%i", rt, spr);
1375                          }                          }
1376                            if (spr == 8 || spr == 9)
1377                                    debug("\t");
1378                            debug("\t<%s%s", running? "read from " : "",
1379                                ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1380                            if (running) {
1381                                    if (cpu->cd.ppc.bits == 32)
1382                                            debug(": 0x%x", (int)
1383                                                cpu->cd.ppc.spr[spr]);
1384                                    else
1385                                            debug(": 0x%llx", (long long)
1386                                                cpu->cd.ppc.spr[spr]);
1387                            }
1388                            debug(">");
1389                            break;
1390                    case PPC_31_TLBIA:
1391                            debug("tlbia");
1392                            break;
1393                    case PPC_31_SLBIA:
1394                            debug("slbia");
1395                            break;
1396                    case PPC_31_TLBLD:
1397                    case PPC_31_TLBLI:
1398                            rb = (iword >> 11) & 31;
1399                            debug("tlbl%s\tr%i", xo == PPC_31_TLBLD? "d" : "i", rb);
1400                          break;                          break;
1401                  case PPC_31_TLBIE:                  case PPC_31_TLBIE:
1402                          /*  TODO: what is ra? The IBM online docs didn't say  */                          /*  TODO: what is ra? The IBM online docs didn't say  */
# Line 1061  int ppc_cpu_disassemble_instr(struct cpu Line 1407  int ppc_cpu_disassemble_instr(struct cpu
1407                          else                          else
1408                                  debug("tlbie\tr%i", rb);                                  debug("tlbie\tr%i", rb);
1409                          break;                          break;
1410                    case PPC_31_TLBSX_DOT:
1411                            rs = (iword >> 21) & 31;
1412                            ra = (iword >> 16) & 31;
1413                            rb = (iword >> 11) & 31;
1414                            debug("tlbsx.\tr%i,r%i,r%i", rs, ra, rb);
1415                            break;
1416                  case PPC_31_TLBSYNC:                  case PPC_31_TLBSYNC:
1417                          debug("tlbsync");                          debug("tlbsync");
1418                          break;                          break;
# Line 1105  int ppc_cpu_disassemble_instr(struct cpu Line 1457  int ppc_cpu_disassemble_instr(struct cpu
1457                          debug("%s\tr%i,r%i", mnem, ra, rb);                          debug("%s\tr%i,r%i", mnem, ra, rb);
1458                          break;                          break;
1459                  case PPC_31_SLW:                  case PPC_31_SLW:
1460                    case PPC_31_SLD:
1461                  case PPC_31_SRAW:                  case PPC_31_SRAW:
1462                  case PPC_31_SRW:                  case PPC_31_SRW:
1463                  case PPC_31_AND:                  case PPC_31_AND:
1464                  case PPC_31_ANDC:                  case PPC_31_ANDC:
1465                  case PPC_31_NOR:                  case PPC_31_NOR:
1466                    case PPC_31_EQV:
1467                  case PPC_31_OR:                  case PPC_31_OR:
1468                  case PPC_31_ORC:                  case PPC_31_ORC:
1469                  case PPC_31_XOR:                  case PPC_31_XOR:
# Line 1124  int ppc_cpu_disassemble_instr(struct cpu Line 1478  int ppc_cpu_disassemble_instr(struct cpu
1478                                  switch (xo) {                                  switch (xo) {
1479                                  case PPC_31_SLW:  mnem =                                  case PPC_31_SLW:  mnem =
1480                                          power? "sl" : "slw"; break;                                          power? "sl" : "slw"; break;
1481                                    case PPC_31_SLD:  mnem = "sld"; break;
1482                                  case PPC_31_SRAW:  mnem =                                  case PPC_31_SRAW:  mnem =
1483                                          power? "sra" : "sraw"; break;                                          power? "sra" : "sraw"; break;
1484                                  case PPC_31_SRW:  mnem =                                  case PPC_31_SRW:  mnem =
# Line 1132  int ppc_cpu_disassemble_instr(struct cpu Line 1487  int ppc_cpu_disassemble_instr(struct cpu
1487                                  case PPC_31_NAND: mnem = "nand"; break;                                  case PPC_31_NAND: mnem = "nand"; break;
1488                                  case PPC_31_ANDC: mnem = "andc"; break;                                  case PPC_31_ANDC: mnem = "andc"; break;
1489                                  case PPC_31_NOR:  mnem = "nor"; break;                                  case PPC_31_NOR:  mnem = "nor"; break;
1490                                    case PPC_31_EQV:  mnem = "eqv"; break;
1491                                  case PPC_31_OR:   mnem = "or"; break;                                  case PPC_31_OR:   mnem = "or"; break;
1492                                  case PPC_31_ORC:  mnem = "orc"; break;                                  case PPC_31_ORC:  mnem = "orc"; break;
1493                                  case PPC_31_XOR:  mnem = "xor"; break;                                  case PPC_31_XOR:  mnem = "xor"; break;
# Line 1172  int ppc_cpu_disassemble_instr(struct cpu Line 1528  int ppc_cpu_disassemble_instr(struct cpu
1528                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1529                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1530                          switch (spr) {                          switch (spr) {
1531                            /*  Some very common ones:  */
1532                          case 8:    debug("mtlr\tr%i", rs); break;                          case 8:    debug("mtlr\tr%i", rs); break;
1533                          case 9:    debug("mtctr\tr%i", rs); break;                          case 9:    debug("mtctr\tr%i", rs); break;
                         case 26:   debug("mtsrr0\tr%i", rs); break;  
                         case 27:   debug("mtsrr1\tr%i", rs); break;  
                         case 272:  debug("mtsprg\t0,r%i", rs); break;  
                         case 273:  debug("mtsprg\t1,r%i", rs); break;  
                         case 274:  debug("mtsprg\t2,r%i", rs); break;  
                         case 275:  debug("mtsprg\t3,r%i", rs); break;  
                         case 528:  debug("mtibatu\t0,r%i", rs); break;  
                         case 529:  debug("mtibatl\t0,r%i", rs); break;  
                         case 530:  debug("mtibatu\t1,r%i", rs); break;  
                         case 531:  debug("mtibatl\t1,r%i", rs); break;  
                         case 532:  debug("mtibatu\t2,r%i", rs); break;  
                         case 533:  debug("mtibatl\t2,r%i", rs); break;  
                         case 534:  debug("mtibatu\t3,r%i", rs); break;  
                         case 535:  debug("mtibatl\t3,r%i", rs); break;  
                         case 536:  debug("mtdbatu\t0,r%i", rs); break;  
                         case 537:  debug("mtdbatl\t0,r%i", rs); break;  
                         case 538:  debug("mtdbatu\t1,r%i", rs); break;  
                         case 539:  debug("mtdbatl\t1,r%i", rs); break;  
                         case 540:  debug("mtdbatu\t2,r%i", rs); break;  
                         case 541:  debug("mtdbatl\t2,r%i", rs); break;  
                         case 542:  debug("mtdbatu\t3,r%i", rs); break;  
                         case 543:  debug("mtdbatl\t3,r%i", rs); break;  
                         case 1008: debug("mtdbsr\tr%i", rs); break;  
1534                          default:debug("mtspr\tspr%i,r%i", spr, rs);                          default:debug("mtspr\tspr%i,r%i", spr, rs);
1535                          }                          }
1536                            if (spr == 8 || spr == 9)
1537                                    debug("\t");
1538                            debug("\t<%s%s", running? "write to " : "",
1539                                ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1540                            if (running) {
1541                                    if (cpu->cd.ppc.bits == 32)
1542                                            debug(": 0x%x", (int)
1543                                                cpu->cd.ppc.gpr[rs]);
1544                                    else
1545                                            debug(": 0x%llx", (long long)
1546                                                cpu->cd.ppc.gpr[rs]);
1547                            }
1548                            debug(">");
1549                          break;                          break;
1550                  case PPC_31_SYNC:                  case PPC_31_SYNC:
1551                          debug("%s", power? "dcs" : "sync");                          debug("%s", power? "dcs" : "sync");
# Line 1216  int ppc_cpu_disassemble_instr(struct cpu Line 1563  int ppc_cpu_disassemble_instr(struct cpu
1563                          }                          }
1564                          debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);                          debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);
1565                          break;                          break;
                 case PPC_31_LHBRX:  
                 case PPC_31_LWBRX:  
                 case PPC_31_STHBRX:  
                 case PPC_31_STWBRX:  
                         rt = (iword >> 21) & 31;        /*  stores use rs  */  
                         ra = (iword >> 16) & 31;  
                         rb = (iword >> 11) & 31;  
                         switch (xo) {  
                         case PPC_31_LHBRX:  mnem = "lhbrx"; break;  
                         case PPC_31_LWBRX:  mnem = power?  
                                             "lbrx" : "lwbrx"; break;  
                         case PPC_31_STHBRX: mnem = "sthbrx"; break;  
                         case PPC_31_STWBRX: mnem = power?  
                                             "stbrx" : "stwbrx"; break;  
                         }  
                         debug("%s\tr%i,r%i,r%i", mnem, rt, ra, rb);  
                         break;  
1566                  case PPC_31_SRAWI:                  case PPC_31_SRAWI:
1567                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1568                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
# Line 1242  int ppc_cpu_disassemble_instr(struct cpu Line 1572  int ppc_cpu_disassemble_instr(struct cpu
1572                          debug("%s%s\tr%i,r%i,%i", mnem,                          debug("%s%s\tr%i,r%i,%i", mnem,
1573                              rc? "." : "", ra, rs, sh);                              rc? "." : "", ra, rs, sh);
1574                          break;                          break;
1575                    case PPC_31_DSSALL:
1576                            debug("dssall");
1577                            break;
1578                  case PPC_31_EIEIO:                  case PPC_31_EIEIO:
1579                          debug("%s", power? "eieio?" : "eieio");                          debug("%s", power? "eieio?" : "eieio");
1580                          break;                          break;
# Line 1264  int ppc_cpu_disassemble_instr(struct cpu Line 1597  int ppc_cpu_disassemble_instr(struct cpu
1597                          }                          }
1598                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1599                          break;                          break;
1600                    case PPC_31_LVX:
1601                    case PPC_31_LVXL:
1602                    case PPC_31_STVX:
1603                    case PPC_31_STVXL:
1604                            rs = (iword >> 21) & 31;        /*  vs for stores,  */
1605                            ra = (iword >> 16) & 31;        /*  rs=vl for loads  */
1606                            rb = (iword >> 11) & 31;
1607                            rc = iword & 1;
1608                            switch (xo) {
1609                            case PPC_31_LVX:   mnem = "lvx";  break;
1610                            case PPC_31_LVXL:  mnem = "lvxl"; break;
1611                            case PPC_31_STVX:  mnem = "stvx";  break;
1612                            case PPC_31_STVXL: mnem = "stvxl"; break;
1613                            }
1614                            debug("%s%s\tv%i,r%i,r%i", mnem, rc? "." : "",
1615                                rs, ra, rb);
1616                            break;
1617                  default:                  default:
1618                          debug("unimplemented hi6_31, xo = 0x%x", xo);                          debug("unimplemented hi6_31, xo = 0x%x", xo);
1619                  }                  }
1620                  break;                  break;
1621            case PPC_HI6_LD:
1622          case PPC_HI6_LWZ:          case PPC_HI6_LWZ:
1623          case PPC_HI6_LWZU:          case PPC_HI6_LWZU:
1624          case PPC_HI6_LHZ:          case PPC_HI6_LHZ:
# Line 1276  int ppc_cpu_disassemble_instr(struct cpu Line 1627  int ppc_cpu_disassemble_instr(struct cpu
1627          case PPC_HI6_LHAU:          case PPC_HI6_LHAU:
1628          case PPC_HI6_LBZ:          case PPC_HI6_LBZ:
1629          case PPC_HI6_LBZU:          case PPC_HI6_LBZU:
1630            case PPC_HI6_LFD:
1631            case PPC_HI6_LFS:
1632          case PPC_HI6_LMW:          case PPC_HI6_LMW:
1633            case PPC_HI6_STD:
1634          case PPC_HI6_STW:          case PPC_HI6_STW:
1635          case PPC_HI6_STWU:          case PPC_HI6_STWU:
1636          case PPC_HI6_STH:          case PPC_HI6_STH:
# Line 1284  int ppc_cpu_disassemble_instr(struct cpu Line 1638  int ppc_cpu_disassemble_instr(struct cpu
1638          case PPC_HI6_STB:          case PPC_HI6_STB:
1639          case PPC_HI6_STBU:          case PPC_HI6_STBU:
1640          case PPC_HI6_STMW:          case PPC_HI6_STMW:
         case PPC_HI6_LFD:  
1641          case PPC_HI6_STFD:          case PPC_HI6_STFD:
1642            case PPC_HI6_STFS:
1643                  /*  NOTE: Loads use rt, not rs, but are otherwise similar                  /*  NOTE: Loads use rt, not rs, but are otherwise similar
1644                      to stores  */                      to stores  */
1645                  load = 0; wlen = 0;                  load = 0; wlen = 0;
# Line 1294  int ppc_cpu_disassemble_instr(struct cpu Line 1648  int ppc_cpu_disassemble_instr(struct cpu
1648                  imm = (int16_t)(iword & 0xffff);                  imm = (int16_t)(iword & 0xffff);
1649                  fpreg = 0;                  fpreg = 0;
1650                  switch (hi6) {                  switch (hi6) {
1651                    case PPC_HI6_LD:  load=1; wlen = 8; mnem = "ld"; break;
1652                  case PPC_HI6_LWZ:  load=1; wlen = 4;                  case PPC_HI6_LWZ:  load=1; wlen = 4;
1653                          mnem = power? "l" : "lwz"; break;                          mnem = power? "l" : "lwz"; break;
1654                  case PPC_HI6_LWZU: load=1; wlen = 4;                  case PPC_HI6_LWZU: load=1; wlen = 4;
# Line 1310  int ppc_cpu_disassemble_instr(struct cpu Line 1665  int ppc_cpu_disassemble_instr(struct cpu
1665                          mnem = "lbz"; break;                          mnem = "lbz"; break;
1666                  case PPC_HI6_LBZU: load=1; wlen = 1;                  case PPC_HI6_LBZU: load=1; wlen = 1;
1667                          mnem = "lbzu"; break;                          mnem = "lbzu"; break;
1668                    case PPC_HI6_LFD:  load=1; fpreg=1; wlen=8; mnem = "lfd"; break;
1669                    case PPC_HI6_LFS:  load=1; fpreg=1; wlen=4; mnem = "lfs"; break;
1670                    case PPC_HI6_STD:  wlen=8; mnem = "std"; break;
1671                  case PPC_HI6_STW:  wlen=4; mnem = power? "st" : "stw"; break;                  case PPC_HI6_STW:  wlen=4; mnem = power? "st" : "stw"; break;
1672                  case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;                  case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;
1673                  case PPC_HI6_STH:  wlen=2; mnem = "sth"; break;                  case PPC_HI6_STH:  wlen=2; mnem = "sth"; break;
# Line 1318  int ppc_cpu_disassemble_instr(struct cpu Line 1676  int ppc_cpu_disassemble_instr(struct cpu
1676                  case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;                  case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;
1677                  case PPC_HI6_LMW:  load=1; mnem = power? "lm" : "lmw"; break;                  case PPC_HI6_LMW:  load=1; mnem = power? "lm" : "lmw"; break;
1678                  case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;                  case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1679                  case PPC_HI6_LFD:  load=1; fpreg = 1; mnem = "lfd"; break;                  case PPC_HI6_STFD: fpreg=1; wlen=8; mnem = "stfd"; break;
1680                  case PPC_HI6_STFD: fpreg = 1; mnem = "stfd"; break;                  case PPC_HI6_STFS: fpreg=1; wlen=4; mnem = "stfs"; break;
1681                  }                  }
1682                  debug("%s\t", mnem);                  debug("%s\t", mnem);
1683                  if (fpreg)                  if (fpreg)
# Line 1330  int ppc_cpu_disassemble_instr(struct cpu Line 1688  int ppc_cpu_disassemble_instr(struct cpu
1688                  if (!running)                  if (!running)
1689                          break;                          break;
1690                  addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;                  addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;
1691                    if (cpu->cd.ppc.bits == 32)
1692                            addr &= 0xffffffff;
1693                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
1694                      addr, &offset);                      addr, &offset);
1695                  if (symbol != NULL)                  if (symbol != NULL)
# Line 1374  int ppc_cpu_disassemble_instr(struct cpu Line 1734  int ppc_cpu_disassemble_instr(struct cpu
1734                          int i;                          int i;
1735                          for (i=0; i<wlen; i++)                          for (i=0; i<wlen; i++)
1736                                  tdata |= (cpu->cd.ppc.gpr[rs] &                                  tdata |= (cpu->cd.ppc.gpr[rs] &
1737                                      ((uint64_t)0xff << i));                                      ((uint64_t)0xff << (i*8)));
1738                          debug(": ");                          debug(": ");
1739                          if (wlen >= 4) {                          if (wlen >= 4) {
1740                                  symbol = get_symbol_name(&cpu->machine->                                  symbol = get_symbol_name(&cpu->machine->
# Line 1382  int ppc_cpu_disassemble_instr(struct cpu Line 1742  int ppc_cpu_disassemble_instr(struct cpu
1742                                  if (symbol != NULL)                                  if (symbol != NULL)
1743                                          debug("%s", symbol);                                          debug("%s", symbol);
1744                                  else                                  else
1745                                          debug("0x%llx",                                          debug("0x%llx", (long long)tdata);
                                             (long long)tdata);  
1746                          } else {                          } else {
1747                                  if (tdata > -256 && tdata < 256)                                  if (tdata > -256 && tdata < 256)
1748                                          debug("%i", (int)tdata);                                          debug("%i", (int)tdata);
# Line 1393  int ppc_cpu_disassemble_instr(struct cpu Line 1752  int ppc_cpu_disassemble_instr(struct cpu
1752                  }                  }
1753                  debug(">");                  debug(">");
1754                  break;                  break;
1755            case PPC_HI6_59:
1756                    xo = (iword >> 1) & 1023;
1757                    /*  NOTE: Some floating point instructions only use the
1758                        lowest 5 bits of xo, some use all 10 bits!  */
1759                    switch (xo & 31) {
1760                    case PPC_59_FDIVS:
1761                    case PPC_59_FSUBS:
1762                    case PPC_59_FADDS:
1763                    case PPC_59_FMULS:
1764                    case PPC_59_FMADDS:
1765                            rt = (iword >> 21) & 31;
1766                            ra = (iword >> 16) & 31;
1767                            rb = (iword >> 11) & 31;
1768                            rs = (iword >>  6) & 31;        /*  actually frc  */
1769                            rc = iword & 1;
1770                            switch (xo & 31) {
1771                            case PPC_59_FDIVS:      mnem = "fdivs"; break;
1772                            case PPC_59_FSUBS:      mnem = "fsubs"; break;
1773                            case PPC_59_FADDS:      mnem = "fadds"; break;
1774                            case PPC_59_FMULS:      mnem = "fmuls"; break;
1775                            case PPC_59_FMADDS:     mnem = "fmadds"; break;
1776                            }
1777                            debug("%s%s\t", mnem, rc? "." : "");
1778                            switch (xo & 31) {
1779                            case PPC_59_FMULS:
1780                                    debug("f%i,f%i,f%i", rt, ra, rs);
1781                                    break;
1782                            case PPC_59_FMADDS:
1783                                    debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1784                                    break;
1785                            default:debug("f%i,f%i,f%i", rt, ra, rb);
1786                            }
1787                            break;
1788                    default:/*  TODO: similar to hi6_63  */
1789                            debug("unimplemented hi6_59, xo = 0x%x", xo);
1790                    }
1791                    break;
1792          case PPC_HI6_63:          case PPC_HI6_63:
1793                  xo = (iword >> 1) & 1023;                  xo = (iword >> 1) & 1023;
1794                  switch (xo) {                  /*  NOTE: Some floating point instructions only use the
1795                  case PPC_63_FMR:                      lowest 5 bits of xo, some use all 10 bits!  */
1796                    switch (xo & 31) {
1797                    case PPC_63_FDIV:
1798                    case PPC_63_FSUB:
1799                    case PPC_63_FADD:
1800                    case PPC_63_FMUL:
1801                    case PPC_63_FMSUB:
1802                    case PPC_63_FMADD:
1803                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1804                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1805                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
1806                            rs = (iword >>  6) & 31;        /*  actually frc  */
1807                            rc = iword & 1;
1808                            switch (xo & 31) {
1809                            case PPC_63_FDIV:
1810                                    mnem = power? "fd" : "fdiv"; break;
1811                            case PPC_63_FSUB:
1812                                    mnem = power? "fs" : "fsub"; break;
1813                            case PPC_63_FADD:
1814                                    mnem = power? "fa" : "fadd"; break;
1815                            case PPC_63_FMUL:
1816                                    mnem = power? "fm" : "fmul"; break;
1817                            case PPC_63_FMSUB:
1818                                    mnem = power? "fms" : "fmsub"; break;
1819                            case PPC_63_FMADD:
1820                                    mnem = power? "fma" : "fmadd"; break;
1821                            }
1822                            debug("%s%s\t", mnem, rc? "." : "");
1823                            switch (xo & 31) {
1824                            case PPC_63_FMUL:
1825                                    debug("f%i,f%i,f%i", rt, ra, rs);
1826                                    break;
1827                            case PPC_63_FMADD:
1828                                    debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1829                                    break;
1830                            default:debug("f%i,f%i,f%i", rt, ra, rb);
1831                            }
1832                            break;
1833                    default:rt = (iword >> 21) & 31;
1834                            ra = (iword >> 16) & 31;
1835                            rb = (iword >> 11) & 31;
1836                          rc = iword & 1;                          rc = iword & 1;
1837                          switch (xo) {                          switch (xo) {
1838                            case PPC_63_FCMPU:
1839                            case PPC_63_FRSP:
1840                            case PPC_63_FCTIWZ:
1841                            case PPC_63_FNEG:
1842                          case PPC_63_FMR:                          case PPC_63_FMR:
1843                                  debug("fmr%s\tf%i,f%i", rc? "." : "", rt, rb);                          case PPC_63_FNABS:
1844                            case PPC_63_FABS:
1845                                    switch (xo) {
1846                                    case PPC_63_FCMPU:      mnem = "fcmpu"; break;
1847                                    case PPC_63_FCTIWZ:
1848                                            mnem = power? "fcirz" : "fctiwz"; break;
1849                                    case PPC_63_FRSP:       mnem = "frsp"; break;
1850                                    case PPC_63_FNEG:       mnem = "fneg"; break;
1851                                    case PPC_63_FMR:        mnem = "fmr"; break;
1852                                    case PPC_63_FNABS:      mnem = "fnabs"; break;
1853                                    case PPC_63_FABS:       mnem = "fabs"; break;
1854                                    }
1855                                    debug("%s%s\t", mnem, rc? "." : "");
1856                                    switch (xo) {
1857                                    case PPC_63_FCMPU:
1858                                            debug("%i,f%i,f%i", rt >> 2, ra, rb);
1859                                            break;
1860                                    case PPC_63_FCTIWZ:
1861                                    case PPC_63_FRSP:
1862                                    case PPC_63_FNEG:
1863                                    case PPC_63_FMR:
1864                                    case PPC_63_FNABS:
1865                                    case PPC_63_FABS:
1866                                            debug("f%i,f%i", rt, rb);
1867                                            break;
1868                                    default:debug("f%i,f%i,f%i", rt, ra, rb);
1869                                    }
1870                                    break;
1871                            case PPC_63_MFFS:
1872                                    debug("mffs%s\tf%i", rc?".":"", rt);
1873                                  break;                                  break;
1874                            case PPC_63_MTFSF:
1875                                    ra = (iword >> 17) & 255;       /*  flm  */
1876                                    debug("mtfsf%s\t0x%02x,f%i", rc?".":"", ra, rb);
1877                                    break;
1878                            default:debug("unimplemented hi6_63, xo = 0x%x", xo);
1879                          }                          }
                         break;  
                 default:  
                         debug("unimplemented hi6_31, xo = 0x%x", xo);  
1880                  }                  }
1881                  break;                  break;
1882          default:          default:
# Line 1422  int ppc_cpu_disassemble_instr(struct cpu Line 1890  int ppc_cpu_disassemble_instr(struct cpu
1890    
1891    
1892  /*  /*
1893     *  debug_spr_usage():
1894     *
1895     *  Helper function. To speed up overall development speed of the emulator,
1896     *  all SPR accesses are allowed. This function causes unknown/unimplemented
1897     *  SPRs to give a warning.
1898     */
1899    static void debug_spr_usage(uint64_t pc, int spr)
1900    {
1901            static uint32_t spr_used[1024 / sizeof(uint32_t)];
1902            static int initialized = 0;
1903    
1904            if (!initialized) {
1905                    memset(spr_used, 0, sizeof(spr_used));
1906                    initialized = 1;
1907            }
1908    
1909            spr &= 1023;
1910            if (spr_used[spr >> 2] & (1 << (spr & 3)))
1911                    return;
1912    
1913            switch (spr) {
1914            /*  Known/implemented SPRs:  */
1915            case SPR_XER:
1916            case SPR_LR:
1917            case SPR_CTR:
1918            case SPR_DSISR:
1919            case SPR_DAR:
1920            case SPR_DEC:
1921            case SPR_SDR1:
1922            case SPR_SRR0:
1923            case SPR_SRR1:
1924            case SPR_SPRG0:
1925            case SPR_SPRG1:
1926            case SPR_SPRG2:
1927            case SPR_SPRG3:
1928            case SPR_PVR:
1929            case SPR_DMISS:
1930            case SPR_DCMP:
1931            case SPR_HASH1:
1932            case SPR_HASH2:
1933            case SPR_IMISS:
1934            case SPR_ICMP:
1935            case SPR_DBSR:
1936            case SPR_PIR:
1937                    break;
1938            default:if (spr >= SPR_IBAT0U && spr <= SPR_DBAT3L) {
1939                            break;
1940                    } else
1941                            fatal("[ using UNIMPLEMENTED spr %i (%s), pc = "
1942                                "0x%llx ]\n", spr, ppc_spr_names[spr] == NULL?
1943                                "UNKNOWN" : ppc_spr_names[spr], (long long)pc);
1944            }
1945    
1946            spr_used[spr >> 2] |= (1 << (spr & 3));
1947    }
1948    
1949    
1950    /*
1951   *  update_cr0():   *  update_cr0():
1952   *   *
1953   *  Sets the top 4 bits of the CR register.   *  Sets the top 4 bits of the CR register.
# Line 1447  void update_cr0(struct cpu *cpu, uint64_ Line 1973  void update_cr0(struct cpu *cpu, uint64_
1973          }          }
1974    
1975          /*  SO bit, copied from XER:  */          /*  SO bit, copied from XER:  */
1976          c |= ((cpu->cd.ppc.xer >> 31) & 1);          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
1977    
1978          cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);          cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1979          cpu->cd.ppc.cr |= ((uint32_t)c << 28);          cpu->cd.ppc.cr |= ((uint32_t)c << 28);
# Line 1459  void update_cr0(struct cpu *cpu, uint64_ Line 1985  void update_cr0(struct cpu *cpu, uint64_
1985    
1986  #include "tmp_ppc_tail.c"  #include "tmp_ppc_tail.c"
1987    
1988    

Legend:
Removed from v.14  
changed lines
  Added in v.30

  ViewVC Help
Powered by ViewVC 1.1.26