/[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 18 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_ppc.c,v 1.13 2005/10/22 17:24:21 debug Exp $   *  $Id: cpu_ppc.c,v 1.35 2005/11/24 01:15:06 debug Exp $
29   *   *
30   *  PowerPC/POWER CPU emulation.   *  PowerPC/POWER CPU emulation.
31   */   */
# Line 41  Line 41 
41  #include "memory.h"  #include "memory.h"
42  #include "misc.h"  #include "misc.h"
43  #include "opcodes_ppc.h"  #include "opcodes_ppc.h"
44    #include "ppc_bat.h"
45    #include "ppc_pte.h"
46    #include "ppc_spr.h"
47    #include "ppc_spr_strings.h"
48  #include "symbol.h"  #include "symbol.h"
49    
50  #define DYNTRANS_DUALMODE_32  #define DYNTRANS_DUALMODE_32
51  #include "tmp_ppc_head.c"  #include "tmp_ppc_head.c"
52    
53    
54    void ppc_pc_to_pointers(struct cpu *);
55    void ppc32_pc_to_pointers(struct cpu *);
56    
57    
58  /*  /*
59   *  ppc_cpu_new():   *  ppc_cpu_new():
60   *   *
# Line 84  int ppc_cpu_new(struct cpu *cpu, struct Line 92  int ppc_cpu_new(struct cpu *cpu, struct
92    
93          /*  Current operating mode:  */          /*  Current operating mode:  */
94          cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;          cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;
95          cpu->cd.ppc.pvr = cpu->cd.ppc.cpu_type.pvr;          cpu->cd.ppc.spr[SPR_PVR] = cpu->cd.ppc.cpu_type.pvr;
96    
97          cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;          cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;
98    
# Line 128  int ppc_cpu_new(struct cpu *cpu, struct Line 136  int ppc_cpu_new(struct cpu *cpu, struct
136                  }                  }
137          }          }
138    
139          cpu->cd.ppc.pir = cpu_id;          cpu->cd.ppc.spr[SPR_PIR] = cpu_id;
140    
141          /*  Some default stack pointer value.  TODO: move this?  */          /*  Some default stack pointer value.  TODO: move this?  */
142          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 211  void ppc_cpu_dumpinfo(struct cpu *cpu)
211  /*  /*
212   *  reg_access_msr():   *  reg_access_msr():
213   */   */
214  void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag)  void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag,
215            int check_for_interrupts)
216  {  {
217            uint64_t old = cpu->cd.ppc.msr;
218    
219          if (valuep == NULL) {          if (valuep == NULL) {
220                  fatal("reg_access_msr(): NULL\n");                  fatal("reg_access_msr(): NULL\n");
221                  return;                  return;
222          }          }
223    
224          if (writeflag)          if (writeflag) {
225                  cpu->cd.ppc.msr = *valuep;                  cpu->cd.ppc.msr = *valuep;
226    
227                    /*  Switching between temporary and real gpr 0..3?  */
228                    if ((old & PPC_MSR_TGPR) != (cpu->cd.ppc.msr & PPC_MSR_TGPR)) {
229                            int i;
230                            for (i=0; i<PPC_N_TGPRS; i++) {
231                                    uint64_t t = cpu->cd.ppc.gpr[i];
232                                    cpu->cd.ppc.gpr[i] = cpu->cd.ppc.tgpr[i];
233                                    cpu->cd.ppc.tgpr[i] = t;
234                            }
235                    }
236    
237                    if (cpu->cd.ppc.msr & PPC_MSR_IP) {
238                            fatal("\n[ Reboot hack for NetBSD/prep. TODO: "
239                                "fix this. ]\n");
240                            cpu->running = 0;
241                    }
242            }
243    
244          /*  TODO: Is the little-endian bit writable?  */          /*  TODO: Is the little-endian bit writable?  */
245    
246          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 249  void reg_access_msr(struct cpu *cpu, uin
249    
250          if (!writeflag)          if (!writeflag)
251                  *valuep = cpu->cd.ppc.msr;                  *valuep = cpu->cd.ppc.msr;
252    
253            if (check_for_interrupts && cpu->cd.ppc.msr & PPC_MSR_EE) {
254                    if (cpu->cd.ppc.dec_intr_pending) {
255                            ppc_exception(cpu, PPC_EXCEPTION_DEC);
256                            cpu->cd.ppc.dec_intr_pending = 0;
257                    } else if (cpu->cd.ppc.irq_asserted)
258                            ppc_exception(cpu, PPC_EXCEPTION_EI);
259            }
260    }
261    
262    
263    /*
264     *  ppc_exception():
265     */
266    void ppc_exception(struct cpu *cpu, int exception_nr)
267    {
268            /*  Save PC and MSR:  */
269            cpu->cd.ppc.spr[SPR_SRR0] = cpu->pc;
270    
271            if (exception_nr >= 0x10 && exception_nr <= 0x13)
272                    cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0xffff)
273                        | (cpu->cd.ppc.cr & 0xf0000000);
274            else
275                    cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);
276    
277            if (!quiet_mode)
278                    fatal("[ PPC Exception 0x%x; pc=0x%llx ]\n", exception_nr,
279                        (long long)cpu->pc);
280    
281            /*  Disable External Interrupts, Recoverable Interrupt Mode,
282                and go to Supervisor mode  */
283            cpu->cd.ppc.msr &= ~(PPC_MSR_EE | PPC_MSR_RI | PPC_MSR_PR);
284    
285            cpu->pc = exception_nr * 0x100;
286            if (cpu->cd.ppc.msr & PPC_MSR_IP)
287                    cpu->pc += 0xfff00000;
288    
289            if (cpu->is_32bit)
290                    ppc32_pc_to_pointers(cpu);
291            else
292                    ppc_pc_to_pointers(cpu);
293  }  }
294    
295    
# Line 253  void ppc_cpu_register_dump(struct cpu *c Line 322  void ppc_cpu_register_dump(struct cpu *c
322    
323                  debug("cpu%i: lr  = 0x", x);                  debug("cpu%i: lr  = 0x", x);
324                  if (bits32)                  if (bits32)
325                          debug("%08x", (int)cpu->cd.ppc.lr);                          debug("%08x", (int)cpu->cd.ppc.spr[SPR_LR]);
326                  else                  else
327                          debug("%016llx", (long long)cpu->cd.ppc.lr);                          debug("%016llx", (long long)cpu->cd.ppc.spr[SPR_LR]);
328                  debug("  cr  = 0x%08x\n", (int)cpu->cd.ppc.cr);                  debug("  cr  = 0x%08x\n", (int)cpu->cd.ppc.cr);
329    
330                  debug("cpu%i: ctr = 0x", x);                  debug("cpu%i: ctr = 0x", x);
331                  if (bits32)                  if (bits32)
332                          debug("%08x", (int)cpu->cd.ppc.ctr);                          debug("%08x", (int)cpu->cd.ppc.spr[SPR_CTR]);
333                  else                  else
334                          debug("%016llx", (long long)cpu->cd.ppc.ctr);                          debug("%016llx", (long long)cpu->cd.ppc.spr[SPR_CTR]);
335    
336                  debug("  xer = 0x", x);                  debug("  xer = 0x", x);
337                  if (bits32)                  if (bits32)
338                          debug("%08x\n", (int)cpu->cd.ppc.xer);                          debug("%08x\n", (int)cpu->cd.ppc.spr[SPR_XER]);
339                  else                  else
340                          debug("%016llx\n", (long long)cpu->cd.ppc.xer);                          debug("%016llx\n", (long long)cpu->cd.ppc.spr[SPR_XER]);
341    
342                  if (bits32) {                  if (bits32) {
343                          /*  32-bit:  */                          /*  32-bit:  */
# Line 295  void ppc_cpu_register_dump(struct cpu *c Line 364  void ppc_cpu_register_dump(struct cpu *c
364    
365                  /*  Other special registers:  */                  /*  Other special registers:  */
366                  debug("cpu%i: srr0 = 0x%016llx  srr1 = 0x%016llx\n", x,                  debug("cpu%i: srr0 = 0x%016llx  srr1 = 0x%016llx\n", x,
367                      (long long)cpu->cd.ppc.srr0, (long long)cpu->cd.ppc.srr1);                      (long long)cpu->cd.ppc.spr[SPR_SRR0],
368                  reg_access_msr(cpu, &tmp, 0);                      (long long)cpu->cd.ppc.spr[SPR_SRR1]);
369                    reg_access_msr(cpu, &tmp, 0, 0);
370                  debug("cpu%i: msr = 0x%016llx  ", x, (long long)tmp);                  debug("cpu%i: msr = 0x%016llx  ", x, (long long)tmp);
371                  debug("tb  = 0x%08x%08x\n",                  debug("tb  = 0x%08x%08x\n", (int)cpu->cd.ppc.spr[SPR_TBU],
372                      (int)cpu->cd.ppc.tbu, (int)cpu->cd.ppc.tbl);                      (int)cpu->cd.ppc.spr[SPR_TBL]);
373                  debug("cpu%i: dec = 0x%08x  hdec = 0x%08x\n",                  debug("cpu%i: dec = 0x%08x  hdec = 0x%08x\n",
374                      x, (int)cpu->cd.ppc.dec, (int)cpu->cd.ppc.hdec);                      x, (int)cpu->cd.ppc.spr[SPR_DEC],
375                        (int)cpu->cd.ppc.spr[SPR_HDEC]);
376          }          }
377    
378          if (coprocs & 1) {          if (coprocs & 1) {
# Line 323  void ppc_cpu_register_dump(struct cpu *c Line 394  void ppc_cpu_register_dump(struct cpu *c
394    
395          if (coprocs & 2) {          if (coprocs & 2) {
396                  debug("cpu%i:  sdr1 = 0x%llx\n", x,                  debug("cpu%i:  sdr1 = 0x%llx\n", x,
397                      (long long)cpu->cd.ppc.sdr1);                      (long long)cpu->cd.ppc.spr[SPR_SDR1]);
398                  for (i=0; i<4; i++)                  if (cpu->cd.ppc.cpu_type.flags & PPC_601)
399                          debug("cpu%i:  ibat%iu = 0x%08x  ibat%il = 0x%08x\n",                          debug("cpu%i:  PPC601-style, TODO!\n");
400                              x, i, cpu->cd.ppc.ibat_u[i],                  else {
401                              i, cpu->cd.ppc.ibat_l[i]);                          for (i=0; i<8; i++) {
402                  for (i=0; i<4; i++)                                  int spr = SPR_IBAT0U + i*2;
403                          debug("cpu%i:  dbat%iu = 0x%08x  dbat%il = 0x%08x\n",                                  uint32_t upper = cpu->cd.ppc.spr[spr];
404                              x, i, cpu->cd.ppc.dbat_u[i],                                  uint32_t lower = cpu->cd.ppc.spr[spr+1];
405                              i, cpu->cd.ppc.dbat_l[i]);                                  uint32_t len = (((upper & BAT_BL) << 15)
406                                        | 0x1ffff) + 1;
407                                    debug("cpu%i:  %sbat%i: u=0x%08x l=0x%08x ",
408                                        x, i<4? "i" : "d", i&3, upper, lower);
409                                    if (!(upper & BAT_V)) {
410                                            debug(" (not valid)\n");
411                                            continue;
412                                    }
413                                    if (len < 1048576)
414                                            debug(" (%i KB, ", len >> 10);
415                                    else
416                                            debug(" (%i MB, ", len >> 20);
417                                    if (upper & BAT_Vu)
418                                            debug("user, ");
419                                    if (upper & BAT_Vs)
420                                            debug("supervisor, ");
421                                    if (lower & (BAT_W | BAT_I | BAT_M | BAT_G))
422                                            debug("%s%s%s%s, ",
423                                                lower & BAT_W? "W" : "",
424                                                lower & BAT_I? "I" : "",
425                                                lower & BAT_M? "M" : "",
426                                                lower & BAT_G? "G" : "");
427                                    switch (lower & BAT_PP) {
428                                    case BAT_PP_NONE: debug("NO access"); break;
429                                    case BAT_PP_RO_S: debug("read-only, soft");
430                                                      break;
431                                    case BAT_PP_RO:   debug("read-only"); break;
432                                    case BAT_PP_RW:   debug("read/write"); break;
433                                    }
434                                    debug(")\n");
435                            }
436                    }
437            }
438    
439            if (coprocs & 4) {
440                    for (i=0; i<16; i++) {
441                            uint32_t s = cpu->cd.ppc.sr[i];
442                            debug("cpu%i:", x);
443                            debug("  sr%2i = 0x%08x", i, (int)s);
444                            s &= (SR_TYPE | SR_SUKEY | SR_PRKEY | SR_NOEXEC);
445                            if (s != 0) {
446                                    debug("  (");
447                                    if (s & SR_TYPE) {
448                                            debug("NON-memory type");
449                                            s &= ~SR_TYPE;
450                                            if (s != 0)
451                                                    debug(", ");
452                                    }
453                                    if (s & SR_SUKEY) {
454                                            debug("supervisor-key");
455                                            s &= ~SR_SUKEY;
456                                            if (s != 0)
457                                                    debug(", ");
458                                    }
459                                    if (s & SR_PRKEY) {
460                                            debug("user-key");
461                                            s &= ~SR_PRKEY;
462                                            if (s != 0)
463                                                    debug(", ");
464                                    }
465                                    if (s & SR_NOEXEC)
466                                            debug("NOEXEC");
467                                    debug(")");
468                            }
469                            debug("\n");
470                    }
471          }          }
472  }  }
473    
# Line 363  void ppc_cpu_register_match(struct machi Line 499  void ppc_cpu_register_match(struct machi
499                  *match_register = 1;                  *match_register = 1;
500          } else if (strcasecmp(name, "lr") == 0) {          } else if (strcasecmp(name, "lr") == 0) {
501                  if (writeflag)                  if (writeflag)
502                          m->cpus[cpunr]->cd.ppc.lr = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_LR] = *valuep;
503                  else                  else
504                          *valuep = m->cpus[cpunr]->cd.ppc.lr;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_LR];
505                  *match_register = 1;                  *match_register = 1;
506          } else if (strcasecmp(name, "cr") == 0) {          } else if (strcasecmp(name, "cr") == 0) {
507                  if (writeflag)                  if (writeflag)
# Line 375  void ppc_cpu_register_match(struct machi Line 511  void ppc_cpu_register_match(struct machi
511                  *match_register = 1;                  *match_register = 1;
512          } else if (strcasecmp(name, "dec") == 0) {          } else if (strcasecmp(name, "dec") == 0) {
513                  if (writeflag)                  if (writeflag)
514                          m->cpus[cpunr]->cd.ppc.dec = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_DEC] = *valuep;
515                  else                  else
516                          *valuep = m->cpus[cpunr]->cd.ppc.dec;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_DEC];
517                  *match_register = 1;                  *match_register = 1;
518          } else if (strcasecmp(name, "hdec") == 0) {          } else if (strcasecmp(name, "hdec") == 0) {
519                  if (writeflag)                  if (writeflag)
520                          m->cpus[cpunr]->cd.ppc.hdec = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_HDEC] = *valuep;
521                  else                  else
522                          *valuep = m->cpus[cpunr]->cd.ppc.hdec;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_HDEC];
523                  *match_register = 1;                  *match_register = 1;
524          } else if (strcasecmp(name, "ctr") == 0) {          } else if (strcasecmp(name, "ctr") == 0) {
525                  if (writeflag)                  if (writeflag)
526                          m->cpus[cpunr]->cd.ppc.ctr = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_CTR] = *valuep;
527                  else                  else
528                          *valuep = m->cpus[cpunr]->cd.ppc.ctr;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_CTR];
529                  *match_register = 1;                  *match_register = 1;
530          } else if (name[0] == 'r' && isdigit((int)name[1])) {          } else if (name[0] == 'r' && isdigit((int)name[1])) {
531                  int nr = atoi(name + 1);                  int nr = atoi(name + 1);
# Line 402  void ppc_cpu_register_match(struct machi Line 538  void ppc_cpu_register_match(struct machi
538                  }                  }
539          } else if (strcasecmp(name, "xer") == 0) {          } else if (strcasecmp(name, "xer") == 0) {
540                  if (writeflag)                  if (writeflag)
541                          m->cpus[cpunr]->cd.ppc.xer = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_XER] = *valuep;
542                  else                  else
543                          *valuep = m->cpus[cpunr]->cd.ppc.xer;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_XER];
544                  *match_register = 1;                  *match_register = 1;
545          } else if (strcasecmp(name, "fpscr") == 0) {          } else if (strcasecmp(name, "fpscr") == 0) {
546                  if (writeflag)                  if (writeflag)
# Line 426  void ppc_cpu_register_match(struct machi Line 562  void ppc_cpu_register_match(struct machi
562    
563    
564  /*  /*
565   *  ppc_cpu_show_full_statistics():   *  ppc_cpu_interrupt():
  *  
  *  Show detailed statistics on opcode usage on each cpu.  
  */  
 void ppc_cpu_show_full_statistics(struct machine *m)  
 {  
         fatal("ppc_cpu_show_full_statistics(): TODO\n");  
 }  
   
   
 /*  
  *  ppc_cpu_tlbdump():  
566   *   *
567   *  Called from the debugger to dump the TLB in a readable format.   *  0..31 are used as BeBox interrupt numbers, 32..47 = ISA,
568   *  x is the cpu number to dump, or -1 to dump all CPUs.   *  64 is used as a "re-assert" signal to cpu->machine->md_interrupt().
569   *   *
570   *  If rawflag is nonzero, then the TLB contents isn't formated nicely,   *  TODO: don't hardcode to BeBox!
  *  just dumped.  
  */  
 void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)  
 {  
         fatal("ppc_cpu_tlbdump(): TODO\n");  
 }  
   
   
 /*  
  *  ppc_cpu_interrupt():  
571   */   */
572  int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
573  {  {
574          fatal("ppc_cpu_interrupt(): TODO\n");          /*  fatal("ppc_cpu_interrupt(): 0x%x\n", (int)irq_nr);  */
575          return 0;          if (irq_nr <= 64) {
576                    if (cpu->machine->md_interrupt != NULL)
577                            cpu->machine->md_interrupt(
578                                cpu->machine, cpu, irq_nr, 1);
579                    else
580                            fatal("ppc_cpu_interrupt(): md_interrupt == NULL\n");
581            } else {
582                    /*  Assert PPC IRQ:  */
583                    cpu->cd.ppc.irq_asserted = 1;
584            }
585            return 1;
586  }  }
587    
588    
# Line 466  int ppc_cpu_interrupt(struct cpu *cpu, u Line 591  int ppc_cpu_interrupt(struct cpu *cpu, u
591   */   */
592  int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
593  {  {
594          /*  fatal("ppc_cpu_interrupt_ack(): TODO\n");  */          if (irq_nr <= 64) {
595          return 0;                  if (cpu->machine->md_interrupt != NULL)
596                            cpu->machine->md_interrupt(cpu->machine,
597                                cpu, irq_nr, 0);
598            } else {
599                    /*  De-assert PPC IRQ:  */
600                    cpu->cd.ppc.irq_asserted = 0;
601            }
602            return 1;
603  }  }
604    
605    
# Line 715  int ppc_cpu_disassemble_instr(struct cpu Line 847  int ppc_cpu_disassemble_instr(struct cpu
847                          debug("unimplemented hi6_19, xo = 0x%x", xo);                          debug("unimplemented hi6_19, xo = 0x%x", xo);
848                  }                  }
849                  break;                  break;
850            case PPC_HI6_RLWNM:
851          case PPC_HI6_RLWIMI:          case PPC_HI6_RLWIMI:
852          case PPC_HI6_RLWINM:          case PPC_HI6_RLWINM:
853                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
854                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
855                  sh = (iword >> 11) & 31;                  sh = (iword >> 11) & 31;        /*  actually rb for rlwnm  */
856                  mb = (iword >> 6) & 31;                  mb = (iword >> 6) & 31;
857                  me = (iword >> 1) & 31;                  me = (iword >> 1) & 31;
858                  rc = iword & 1;                  rc = iword & 1;
859                  switch (hi6) {                  switch (hi6) {
860                    case PPC_HI6_RLWNM:
861                            mnem = power? "rlnm" : "rlwnm"; break;
862                  case PPC_HI6_RLWIMI:                  case PPC_HI6_RLWIMI:
863                          mnem = power? "rlimi" : "rlwimi"; break;                          mnem = power? "rlimi" : "rlwimi"; break;
864                  case PPC_HI6_RLWINM:                  case PPC_HI6_RLWINM:
865                          mnem = power? "rlinm" : "rlwinm"; break;                          mnem = power? "rlinm" : "rlwinm"; break;
866                  }                  }
867                  debug("%s%s\tr%i,r%i,%i,%i,%i",                  debug("%s%s\tr%i,r%i,%s%i,%i,%i",
868                      mnem, rc?".":"", ra, rs, sh, mb, me);                      mnem, rc?".":"", ra, rs,
869                        hi6 == PPC_HI6_RLWNM? "r" : "",
870                        sh, mb, me);
871                  break;                  break;
872          case PPC_HI6_ORI:          case PPC_HI6_ORI:
873          case PPC_HI6_ORIS:          case PPC_HI6_ORIS:
# Line 836  int ppc_cpu_disassemble_instr(struct cpu Line 973  int ppc_cpu_disassemble_instr(struct cpu
973                  case PPC_31_LDARX:                  case PPC_31_LDARX:
974                  case PPC_31_LBZX:                  case PPC_31_LBZX:
975                  case PPC_31_LBZUX:                  case PPC_31_LBZUX:
976                    case PPC_31_LHAX:
977                    case PPC_31_LHAUX:
978                  case PPC_31_LHZX:                  case PPC_31_LHZX:
979                  case PPC_31_LHZUX:                  case PPC_31_LHZUX:
980                  case PPC_31_LWZX:                  case PPC_31_LWZX:
981                  case PPC_31_LWZUX:                  case PPC_31_LWZUX:
982                    case PPC_31_LHBRX:
983                    case PPC_31_LWBRX:
984                    case PPC_31_LFDX:
985                    case PPC_31_LFSX:
986                  case PPC_31_STWCX_DOT:                  case PPC_31_STWCX_DOT:
987                  case PPC_31_STDCX_DOT:                  case PPC_31_STDCX_DOT:
988                  case PPC_31_STBX:                  case PPC_31_STBX:
# Line 850  int ppc_cpu_disassemble_instr(struct cpu Line 993  int ppc_cpu_disassemble_instr(struct cpu
993                  case PPC_31_STWUX:                  case PPC_31_STWUX:
994                  case PPC_31_STDX:                  case PPC_31_STDX:
995                  case PPC_31_STDUX:                  case PPC_31_STDUX:
996                    case PPC_31_STHBRX:
997                    case PPC_31_STWBRX:
998                    case PPC_31_STFDX:
999                    case PPC_31_STFSX:
1000                          /*  rs for stores, rt for loads, actually  */                          /*  rs for stores, rt for loads, actually  */
1001                          load = 0; wlen = 0;                          load = 0; wlen = 0; fpreg = 0;
1002                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1003                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1004                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
# Line 860  int ppc_cpu_disassemble_instr(struct cpu Line 1007  int ppc_cpu_disassemble_instr(struct cpu
1007                          case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;                          case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;
1008                          case PPC_31_LBZX:  wlen=1;load=1; mnem = "lbzx"; break;                          case PPC_31_LBZX:  wlen=1;load=1; mnem = "lbzx"; break;
1009                          case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;                          case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;
1010                            case PPC_31_LHAX:  wlen=2;load=1; mnem = "lhax"; break;
1011                            case PPC_31_LHAUX: wlen=2;load=1; mnem = "lhaux"; break;
1012                          case PPC_31_LHZX:  wlen=2;load=1; mnem = "lhzx"; break;                          case PPC_31_LHZX:  wlen=2;load=1; mnem = "lhzx"; break;
1013                          case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;                          case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;
1014                          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 1017  int ppc_cpu_disassemble_instr(struct cpu
1017                          case PPC_31_LWZUX: wlen = 4; load = 1;                          case PPC_31_LWZUX: wlen = 4; load = 1;
1018                                  mnem = power? "lux":"lwzux";                                  mnem = power? "lux":"lwzux";
1019                                  break;                                  break;
1020                            case PPC_31_LFDX: fpreg = 1; wlen = 8; load = 1;
1021                                    mnem = "lfdx"; break;
1022                            case PPC_31_LFSX: fpreg = 1; wlen = 4; load = 1;
1023                                    mnem = "lfsx"; break;
1024                          case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;                          case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;
1025                          case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;                          case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;
1026                          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 1035  int ppc_cpu_disassemble_instr(struct cpu
1035                                  break;                                  break;
1036                          case PPC_31_STDX:  wlen = 8; mnem = "stdx"; break;                          case PPC_31_STDX:  wlen = 8; mnem = "stdx"; break;
1037                          case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;                          case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;
1038                            case PPC_31_LHBRX:  wlen = 2; mnem = "lhbrx"; break;
1039                            case PPC_31_LWBRX:  wlen = 4; mnem = power?
1040                                                "lbrx" : "lwbrx"; break;
1041                            case PPC_31_STHBRX: wlen = 2; mnem = "sthbrx"; break;
1042                            case PPC_31_STWBRX: wlen = 4; mnem = power?
1043                                                "stbrx" : "stwbrx"; break;
1044                            case PPC_31_STFDX: fpreg = 1; wlen = 8;
1045                                    mnem = "stfdx"; break;
1046                            case PPC_31_STFSX: fpreg = 1; wlen = 4;
1047                                    mnem = "stfsx"; break;
1048                          }                          }
1049                          debug("%s\tr%i,r%i,r%i", mnem, rs, ra, rb);                          debug("%s\t%s%i,r%i,r%i", mnem,
1050                                fpreg? "f" : "r", rs, ra, rb);
1051                          if (!running)                          if (!running)
1052                                  break;                                  break;
1053                          addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +                          addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +
1054                              cpu->cd.ppc.gpr[rb];                              cpu->cd.ppc.gpr[rb];
1055                            if (cpu->cd.ppc.bits == 32)
1056                                    addr &= 0xffffffff;
1057                          symbol = get_symbol_name(&cpu->machine->symbol_context,                          symbol = get_symbol_name(&cpu->machine->symbol_context,
1058                              addr, &offset);                              addr, &offset);
1059                          if (symbol != NULL)                          if (symbol != NULL)
1060                                  debug(" \t<%s", symbol);                                  debug(" \t<%s", symbol);
1061                          else                          else
1062                                  debug(" \t<0x%llx", (long long)addr);                                  debug(" \t<0x%llx", (long long)addr);
1063                          if (wlen > 0) {                          if (wlen > 0 && !fpreg /* && !reverse */) {
1064                                  /*  TODO  */                                  /*  TODO  */
1065                          }                          }
1066                          debug(">");                          debug(">");
# Line 928  int ppc_cpu_disassemble_instr(struct cpu Line 1094  int ppc_cpu_disassemble_instr(struct cpu
1094                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1095                          break;                          break;
1096                  case PPC_31_MTSR:                  case PPC_31_MTSR:
1097                          /*  Move to segment register  */                  case PPC_31_MFSR:
1098                            /*  Move to/from segment register  */
1099                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1100                          ra = (iword >> 16) & 15;        /*  actually: sr  */                          ra = (iword >> 16) & 15;        /*  actually: sr  */
1101                          debug("mtsr\t%i,r%i", ra, rt);                          switch (xo) {
1102                            case PPC_31_MTSR:  mnem = "mtsr"; break;
1103                            case PPC_31_MFSR:  mnem = "mfsr"; break;
1104                            }
1105                            debug("%s\tr%i,%i", mnem, rt, ra);
1106                          break;                          break;
1107                  case PPC_31_MTSRIN:                  case PPC_31_MTSRIN:
1108                  case PPC_31_MFSRIN:                  case PPC_31_MFSRIN:
# Line 962  int ppc_cpu_disassemble_instr(struct cpu Line 1133  int ppc_cpu_disassemble_instr(struct cpu
1133                  case PPC_31_SUBFCO:                  case PPC_31_SUBFCO:
1134                  case PPC_31_SUBFE:                  case PPC_31_SUBFE:
1135                  case PPC_31_SUBFEO:                  case PPC_31_SUBFEO:
1136                    case PPC_31_SUBFME:
1137                    case PPC_31_SUBFMEO:
1138                  case PPC_31_SUBFZE:                  case PPC_31_SUBFZE:
1139                  case PPC_31_SUBFZEO:                  case PPC_31_SUBFZEO:
1140                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 1007  int ppc_cpu_disassemble_instr(struct cpu Line 1180  int ppc_cpu_disassemble_instr(struct cpu
1180                          case PPC_31_SUBF:   mnem = "subf"; break;                          case PPC_31_SUBF:   mnem = "subf"; break;
1181                          case PPC_31_SUBFO:  mnem = "subfo"; break;                          case PPC_31_SUBFO:  mnem = "subfo"; break;
1182                          case PPC_31_SUBFC:                          case PPC_31_SUBFC:
1183                                  mnem = power? "sf" : "subfc";                                  mnem = power? "sf" : "subfc"; break;
                                 break;  
1184                          case PPC_31_SUBFCO:                          case PPC_31_SUBFCO:
1185                                  mnem = power? "sfo" : "subfco";                                  mnem = power? "sfo" : "subfco"; break;
                                 break;  
1186                          case PPC_31_SUBFE:                          case PPC_31_SUBFE:
1187                                  mnem = power? "sfe" : "subfe";                                  mnem = power? "sfe" : "subfe"; break;
                                 break;  
1188                          case PPC_31_SUBFEO:                          case PPC_31_SUBFEO:
1189                                  mnem = power? "sfeo" : "subfeo";                                  mnem = power? "sfeo" : "subfeo"; break;
1190                                  break;                          case PPC_31_SUBFME:
1191                                    mnem = power? "sfme" : "subfme"; break;
1192                            case PPC_31_SUBFMEO:
1193                                    mnem = power? "sfmeo" : "subfmeo"; break;
1194                          case PPC_31_SUBFZE:                          case PPC_31_SUBFZE:
1195                                  mnem = power? "sfze" : "subfze";                                  mnem = power? "sfze" : "subfze";
1196                                  no_rb = 1;                                  no_rb = 1;
# Line 1035  int ppc_cpu_disassemble_instr(struct cpu Line 1208  int ppc_cpu_disassemble_instr(struct cpu
1208                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1209                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1210                          switch (spr) {                          switch (spr) {
1211                            /*  Some very common ones:  */
1212                          case 8:    debug("mflr\tr%i", rt); break;                          case 8:    debug("mflr\tr%i", rt); break;
1213                          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;  
1214                          default:debug("mfspr\tr%i,spr%i", rt, spr);                          default:debug("mfspr\tr%i,spr%i", rt, spr);
1215                          }                          }
1216                            if (spr == 8 || spr == 9)
1217                                    debug("\t");
1218                            debug("\t<%s%s", running? "read from " : "",
1219                                ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1220                            if (running) {
1221                                    if (cpu->cd.ppc.bits == 32)
1222                                            debug(": 0x%x", (int)
1223                                                cpu->cd.ppc.spr[spr]);
1224                                    else
1225                                            debug(": 0x%llx", (long long)
1226                                                cpu->cd.ppc.spr[spr]);
1227                            }
1228                            debug(">");
1229                            break;
1230                    case PPC_31_TLBIA:
1231                            debug("tlbia");
1232                            break;
1233                    case PPC_31_SLBIA:
1234                            debug("slbia");
1235                            break;
1236                    case PPC_31_TLBLD:
1237                    case PPC_31_TLBLI:
1238                            rb = (iword >> 11) & 31;
1239                            debug("tlbl%s\tr%i", xo == PPC_31_TLBLD? "d" : "i", rb);
1240                          break;                          break;
1241                  case PPC_31_TLBIE:                  case PPC_31_TLBIE:
1242                          /*  TODO: what is ra? The IBM online docs didn't say  */                          /*  TODO: what is ra? The IBM online docs didn't say  */
# Line 1172  int ppc_cpu_disassemble_instr(struct cpu Line 1358  int ppc_cpu_disassemble_instr(struct cpu
1358                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1359                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1360                          switch (spr) {                          switch (spr) {
1361                            /*  Some very common ones:  */
1362                          case 8:    debug("mtlr\tr%i", rs); break;                          case 8:    debug("mtlr\tr%i", rs); break;
1363                          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;  
1364                          default:debug("mtspr\tspr%i,r%i", spr, rs);                          default:debug("mtspr\tspr%i,r%i", spr, rs);
1365                          }                          }
1366                            if (spr == 8 || spr == 9)
1367                                    debug("\t");
1368                            debug("\t<%s%s", running? "write to " : "",
1369                                ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1370                            if (running) {
1371                                    if (cpu->cd.ppc.bits == 32)
1372                                            debug(": 0x%x", (int)
1373                                                cpu->cd.ppc.gpr[rs]);
1374                                    else
1375                                            debug(": 0x%llx", (long long)
1376                                                cpu->cd.ppc.gpr[rs]);
1377                            }
1378                            debug(">");
1379                          break;                          break;
1380                  case PPC_31_SYNC:                  case PPC_31_SYNC:
1381                          debug("%s", power? "dcs" : "sync");                          debug("%s", power? "dcs" : "sync");
# Line 1216  int ppc_cpu_disassemble_instr(struct cpu Line 1393  int ppc_cpu_disassemble_instr(struct cpu
1393                          }                          }
1394                          debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);                          debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);
1395                          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;  
1396                  case PPC_31_SRAWI:                  case PPC_31_SRAWI:
1397                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1398                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
# Line 1268  int ppc_cpu_disassemble_instr(struct cpu Line 1428  int ppc_cpu_disassemble_instr(struct cpu
1428                          debug("unimplemented hi6_31, xo = 0x%x", xo);                          debug("unimplemented hi6_31, xo = 0x%x", xo);
1429                  }                  }
1430                  break;                  break;
1431            case PPC_HI6_LD:
1432          case PPC_HI6_LWZ:          case PPC_HI6_LWZ:
1433          case PPC_HI6_LWZU:          case PPC_HI6_LWZU:
1434          case PPC_HI6_LHZ:          case PPC_HI6_LHZ:
# Line 1276  int ppc_cpu_disassemble_instr(struct cpu Line 1437  int ppc_cpu_disassemble_instr(struct cpu
1437          case PPC_HI6_LHAU:          case PPC_HI6_LHAU:
1438          case PPC_HI6_LBZ:          case PPC_HI6_LBZ:
1439          case PPC_HI6_LBZU:          case PPC_HI6_LBZU:
1440            case PPC_HI6_LFD:
1441            case PPC_HI6_LFS:
1442          case PPC_HI6_LMW:          case PPC_HI6_LMW:
1443            case PPC_HI6_STD:
1444          case PPC_HI6_STW:          case PPC_HI6_STW:
1445          case PPC_HI6_STWU:          case PPC_HI6_STWU:
1446          case PPC_HI6_STH:          case PPC_HI6_STH:
# Line 1284  int ppc_cpu_disassemble_instr(struct cpu Line 1448  int ppc_cpu_disassemble_instr(struct cpu
1448          case PPC_HI6_STB:          case PPC_HI6_STB:
1449          case PPC_HI6_STBU:          case PPC_HI6_STBU:
1450          case PPC_HI6_STMW:          case PPC_HI6_STMW:
         case PPC_HI6_LFD:  
1451          case PPC_HI6_STFD:          case PPC_HI6_STFD:
1452            case PPC_HI6_STFS:
1453                  /*  NOTE: Loads use rt, not rs, but are otherwise similar                  /*  NOTE: Loads use rt, not rs, but are otherwise similar
1454                      to stores  */                      to stores  */
1455                  load = 0; wlen = 0;                  load = 0; wlen = 0;
# Line 1294  int ppc_cpu_disassemble_instr(struct cpu Line 1458  int ppc_cpu_disassemble_instr(struct cpu
1458                  imm = (int16_t)(iword & 0xffff);                  imm = (int16_t)(iword & 0xffff);
1459                  fpreg = 0;                  fpreg = 0;
1460                  switch (hi6) {                  switch (hi6) {
1461                    case PPC_HI6_LD:  load=1; wlen = 8; mnem = "ld"; break;
1462                  case PPC_HI6_LWZ:  load=1; wlen = 4;                  case PPC_HI6_LWZ:  load=1; wlen = 4;
1463                          mnem = power? "l" : "lwz"; break;                          mnem = power? "l" : "lwz"; break;
1464                  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 1475  int ppc_cpu_disassemble_instr(struct cpu
1475                          mnem = "lbz"; break;                          mnem = "lbz"; break;
1476                  case PPC_HI6_LBZU: load=1; wlen = 1;                  case PPC_HI6_LBZU: load=1; wlen = 1;
1477                          mnem = "lbzu"; break;                          mnem = "lbzu"; break;
1478                    case PPC_HI6_LFD:  load=1; fpreg=1; wlen=8; mnem = "lfd"; break;
1479                    case PPC_HI6_LFS:  load=1; fpreg=1; wlen=4; mnem = "lfs"; break;
1480                    case PPC_HI6_STD:  wlen=8; mnem = "std"; break;
1481                  case PPC_HI6_STW:  wlen=4; mnem = power? "st" : "stw"; break;                  case PPC_HI6_STW:  wlen=4; mnem = power? "st" : "stw"; break;
1482                  case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;                  case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;
1483                  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 1486  int ppc_cpu_disassemble_instr(struct cpu
1486                  case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;                  case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;
1487                  case PPC_HI6_LMW:  load=1; mnem = power? "lm" : "lmw"; break;                  case PPC_HI6_LMW:  load=1; mnem = power? "lm" : "lmw"; break;
1488                  case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;                  case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1489                  case PPC_HI6_LFD:  load=1; fpreg = 1; mnem = "lfd"; break;                  case PPC_HI6_STFD: fpreg=1; wlen=8; mnem = "stfd"; break;
1490                  case PPC_HI6_STFD: fpreg = 1; mnem = "stfd"; break;                  case PPC_HI6_STFS: fpreg=1; wlen=4; mnem = "stfs"; break;
1491                  }                  }
1492                  debug("%s\t", mnem);                  debug("%s\t", mnem);
1493                  if (fpreg)                  if (fpreg)
# Line 1330  int ppc_cpu_disassemble_instr(struct cpu Line 1498  int ppc_cpu_disassemble_instr(struct cpu
1498                  if (!running)                  if (!running)
1499                          break;                          break;
1500                  addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;                  addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;
1501                    if (cpu->cd.ppc.bits == 32)
1502                            addr &= 0xffffffff;
1503                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
1504                      addr, &offset);                      addr, &offset);
1505                  if (symbol != NULL)                  if (symbol != NULL)
# Line 1374  int ppc_cpu_disassemble_instr(struct cpu Line 1544  int ppc_cpu_disassemble_instr(struct cpu
1544                          int i;                          int i;
1545                          for (i=0; i<wlen; i++)                          for (i=0; i<wlen; i++)
1546                                  tdata |= (cpu->cd.ppc.gpr[rs] &                                  tdata |= (cpu->cd.ppc.gpr[rs] &
1547                                      ((uint64_t)0xff << i));                                      ((uint64_t)0xff << (i*8)));
1548                          debug(": ");                          debug(": ");
1549                          if (wlen >= 4) {                          if (wlen >= 4) {
1550                                  symbol = get_symbol_name(&cpu->machine->                                  symbol = get_symbol_name(&cpu->machine->
# Line 1382  int ppc_cpu_disassemble_instr(struct cpu Line 1552  int ppc_cpu_disassemble_instr(struct cpu
1552                                  if (symbol != NULL)                                  if (symbol != NULL)
1553                                          debug("%s", symbol);                                          debug("%s", symbol);
1554                                  else                                  else
1555                                          debug("0x%llx",                                          debug("0x%llx", (long long)tdata);
                                             (long long)tdata);  
1556                          } else {                          } else {
1557                                  if (tdata > -256 && tdata < 256)                                  if (tdata > -256 && tdata < 256)
1558                                          debug("%i", (int)tdata);                                          debug("%i", (int)tdata);
# Line 1393  int ppc_cpu_disassemble_instr(struct cpu Line 1562  int ppc_cpu_disassemble_instr(struct cpu
1562                  }                  }
1563                  debug(">");                  debug(">");
1564                  break;                  break;
1565            case PPC_HI6_59:
1566                    xo = (iword >> 1) & 1023;
1567                    /*  NOTE: Some floating point instructions only use the
1568                        lowest 5 bits of xo, some use all 10 bits!  */
1569                    switch (xo & 31) {
1570                    case PPC_59_FDIVS:
1571                    case PPC_59_FSUBS:
1572                    case PPC_59_FADDS:
1573                    case PPC_59_FMULS:
1574                    case PPC_59_FMADDS:
1575                            rt = (iword >> 21) & 31;
1576                            ra = (iword >> 16) & 31;
1577                            rb = (iword >> 11) & 31;
1578                            rs = (iword >>  6) & 31;        /*  actually frc  */
1579                            rc = iword & 1;
1580                            switch (xo & 31) {
1581                            case PPC_59_FDIVS:      mnem = "fdivs"; break;
1582                            case PPC_59_FSUBS:      mnem = "fsubs"; break;
1583                            case PPC_59_FADDS:      mnem = "fadds"; break;
1584                            case PPC_59_FMULS:      mnem = "fmuls"; break;
1585                            case PPC_59_FMADDS:     mnem = "fmadds"; break;
1586                            }
1587                            debug("%s%s\t", mnem, rc? "." : "");
1588                            switch (xo & 31) {
1589                            case PPC_59_FMULS:
1590                                    debug("f%i,f%i,f%i", rt, ra, rs);
1591                                    break;
1592                            case PPC_59_FMADDS:
1593                                    debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1594                                    break;
1595                            default:debug("f%i,f%i,f%i", rt, ra, rb);
1596                            }
1597                            break;
1598                    default:/*  TODO: similar to hi6_63  */
1599                            debug("unimplemented hi6_59, xo = 0x%x", xo);
1600                    }
1601                    break;
1602          case PPC_HI6_63:          case PPC_HI6_63:
1603                  xo = (iword >> 1) & 1023;                  xo = (iword >> 1) & 1023;
1604                  switch (xo) {                  /*  NOTE: Some floating point instructions only use the
1605                  case PPC_63_FMR:                      lowest 5 bits of xo, some use all 10 bits!  */
1606                    switch (xo & 31) {
1607                    case PPC_63_FDIV:
1608                    case PPC_63_FSUB:
1609                    case PPC_63_FADD:
1610                    case PPC_63_FMUL:
1611                    case PPC_63_FMSUB:
1612                    case PPC_63_FMADD:
1613                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1614                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1615                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
1616                            rs = (iword >>  6) & 31;        /*  actually frc  */
1617                            rc = iword & 1;
1618                            switch (xo & 31) {
1619                            case PPC_63_FDIV:
1620                                    mnem = power? "fd" : "fdiv"; break;
1621                            case PPC_63_FSUB:
1622                                    mnem = power? "fs" : "fsub"; break;
1623                            case PPC_63_FADD:
1624                                    mnem = power? "fa" : "fadd"; break;
1625                            case PPC_63_FMUL:
1626                                    mnem = power? "fm" : "fmul"; break;
1627                            case PPC_63_FMSUB:
1628                                    mnem = power? "fms" : "fmsub"; break;
1629                            case PPC_63_FMADD:
1630                                    mnem = power? "fma" : "fmadd"; break;
1631                            }
1632                            debug("%s%s\t", mnem, rc? "." : "");
1633                            switch (xo & 31) {
1634                            case PPC_63_FMUL:
1635                                    debug("f%i,f%i,f%i", rt, ra, rs);
1636                                    break;
1637                            case PPC_63_FMADD:
1638                                    debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1639                                    break;
1640                            default:debug("f%i,f%i,f%i", rt, ra, rb);
1641                            }
1642                            break;
1643                    default:rt = (iword >> 21) & 31;
1644                            ra = (iword >> 16) & 31;
1645                            rb = (iword >> 11) & 31;
1646                          rc = iword & 1;                          rc = iword & 1;
1647                          switch (xo) {                          switch (xo) {
1648                            case PPC_63_FCMPU:
1649                            case PPC_63_FRSP:
1650                            case PPC_63_FCTIWZ:
1651                            case PPC_63_FNEG:
1652                          case PPC_63_FMR:                          case PPC_63_FMR:
1653                                  debug("fmr%s\tf%i,f%i", rc? "." : "", rt, rb);                          case PPC_63_FNABS:
1654                            case PPC_63_FABS:
1655                                    switch (xo) {
1656                                    case PPC_63_FCMPU:      mnem = "fcmpu"; break;
1657                                    case PPC_63_FCTIWZ:
1658                                            mnem = power? "fcirz" : "fctiwz"; break;
1659                                    case PPC_63_FRSP:       mnem = "frsp"; break;
1660                                    case PPC_63_FNEG:       mnem = "fneg"; break;
1661                                    case PPC_63_FMR:        mnem = "fmr"; break;
1662                                    case PPC_63_FNABS:      mnem = "fnabs"; break;
1663                                    case PPC_63_FABS:       mnem = "fabs"; break;
1664                                    }
1665                                    debug("%s%s\t", mnem, rc? "." : "");
1666                                    switch (xo) {
1667                                    case PPC_63_FCMPU:
1668                                            debug("%i,f%i,f%i", rt >> 2, ra, rb);
1669                                            break;
1670                                    case PPC_63_FCTIWZ:
1671                                    case PPC_63_FRSP:
1672                                    case PPC_63_FNEG:
1673                                    case PPC_63_FMR:
1674                                    case PPC_63_FNABS:
1675                                    case PPC_63_FABS:
1676                                            debug("f%i,f%i", rt, rb);
1677                                            break;
1678                                    default:debug("f%i,f%i,f%i", rt, ra, rb);
1679                                    }
1680                                    break;
1681                            case PPC_63_MFFS:
1682                                    debug("mffs%s\tf%i", rc?".":"", rt);
1683                                  break;                                  break;
1684                            case PPC_63_MTFSF:
1685                                    ra = (iword >> 17) & 255;       /*  flm  */
1686                                    debug("mtfsf%s\t0x%02x,f%i", rc?".":"", ra, rb);
1687                                    break;
1688                            default:debug("unimplemented hi6_63, xo = 0x%x", xo);
1689                          }                          }
                         break;  
                 default:  
                         debug("unimplemented hi6_31, xo = 0x%x", xo);  
1690                  }                  }
1691                  break;                  break;
1692          default:          default:
# Line 1422  int ppc_cpu_disassemble_instr(struct cpu Line 1700  int ppc_cpu_disassemble_instr(struct cpu
1700    
1701    
1702  /*  /*
1703     *  debug_spr_usage():
1704     *
1705     *  Helper function. To speed up overall development speed of the emulator,
1706     *  all SPR accesses are allowed. This function causes unknown/unimplemented
1707     *  SPRs to give a warning.
1708     */
1709    static void debug_spr_usage(uint64_t pc, int spr)
1710    {
1711            static uint32_t spr_used[1024 / sizeof(uint32_t)];
1712            static int initialized = 0;
1713    
1714            if (!initialized) {
1715                    memset(spr_used, 0, sizeof(spr_used));
1716                    initialized = 1;
1717            }
1718    
1719            spr &= 1023;
1720            if (spr_used[spr >> 2] & (1 << (spr & 3)))
1721                    return;
1722    
1723            switch (spr) {
1724            /*  Known/implemented SPRs:  */
1725            case SPR_XER:
1726            case SPR_LR:
1727            case SPR_CTR:
1728            case SPR_DSISR:
1729            case SPR_DAR:
1730            case SPR_DEC:
1731            case SPR_SDR1:
1732            case SPR_SRR0:
1733            case SPR_SRR1:
1734            case SPR_SPRG0:
1735            case SPR_SPRG1:
1736            case SPR_SPRG2:
1737            case SPR_SPRG3:
1738            case SPR_PVR:
1739            case SPR_DMISS:
1740            case SPR_DCMP:
1741            case SPR_HASH1:
1742            case SPR_HASH2:
1743            case SPR_IMISS:
1744            case SPR_ICMP:
1745            case SPR_DBSR:
1746            case SPR_PIR:
1747                    break;
1748            default:if (spr >= SPR_IBAT0U && spr <= SPR_DBAT3L) {
1749                            break;
1750                    } else
1751                            fatal("[ using UNIMPLEMENTED spr %i (%s), pc = "
1752                                "0x%llx ]\n", spr, ppc_spr_names[spr] == NULL?
1753                                "UNKNOWN" : ppc_spr_names[spr], (long long)pc);
1754            }
1755    
1756            spr_used[spr >> 2] |= (1 << (spr & 3));
1757    }
1758    
1759    
1760    /*
1761   *  update_cr0():   *  update_cr0():
1762   *   *
1763   *  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 1783  void update_cr0(struct cpu *cpu, uint64_
1783          }          }
1784    
1785          /*  SO bit, copied from XER:  */          /*  SO bit, copied from XER:  */
1786          c |= ((cpu->cd.ppc.xer >> 31) & 1);          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
1787    
1788          cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);          cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1789          cpu->cd.ppc.cr |= ((uint32_t)c << 28);          cpu->cd.ppc.cr |= ((uint32_t)c << 28);

Legend:
Removed from v.18  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26