/[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 22 by dpavlin, Mon Oct 8 16:19:37 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.13 2005/10/22 17:24:21 debug Exp $   *  $Id: cpu_ppc.c,v 1.45 2006/01/24 21:26:01 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.spr[SPR_IBAT0U] = 0x00001ffc | BAT_Vs;
99            cpu->cd.ppc.spr[SPR_IBAT0L] = 0x00000000 | BAT_PP_RW;
100            cpu->cd.ppc.spr[SPR_IBAT1U] = 0xc0001ffc | BAT_Vs;
101            cpu->cd.ppc.spr[SPR_IBAT1L] = 0x00000000 | BAT_PP_RW;
102            cpu->cd.ppc.spr[SPR_IBAT3U] = 0xf0001ffc | BAT_Vs;
103            cpu->cd.ppc.spr[SPR_IBAT3L] = 0xf0000000 | BAT_PP_RW;
104            cpu->cd.ppc.spr[SPR_DBAT0U] = 0x00001ffc | BAT_Vs;
105            cpu->cd.ppc.spr[SPR_DBAT0L] = 0x00000000 | BAT_PP_RW;
106            cpu->cd.ppc.spr[SPR_DBAT1U] = 0xc0001ffc | BAT_Vs;
107            cpu->cd.ppc.spr[SPR_DBAT1L] = 0x00000000 | BAT_PP_RW;
108            cpu->cd.ppc.spr[SPR_DBAT2U] = 0xe0001ffc | BAT_Vs;
109            cpu->cd.ppc.spr[SPR_DBAT2L] = 0xe0000000 | BAT_PP_RW;
110            cpu->cd.ppc.spr[SPR_DBAT3U] = 0xf0001ffc | BAT_Vs;
111            cpu->cd.ppc.spr[SPR_DBAT3L] = 0xf0000000 | BAT_PP_RW;
112    
113          cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;          cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;
114    
# Line 128  int ppc_cpu_new(struct cpu *cpu, struct Line 152  int ppc_cpu_new(struct cpu *cpu, struct
152                  }                  }
153          }          }
154    
155          cpu->cd.ppc.pir = cpu_id;          cpu->cd.ppc.spr[SPR_PIR] = cpu_id;
156    
157          /*  Some default stack pointer value.  TODO: move this?  */          /*  Some default stack pointer value.  TODO: move this?  */
158          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 227  void ppc_cpu_dumpinfo(struct cpu *cpu)
227  /*  /*
228   *  reg_access_msr():   *  reg_access_msr():
229   */   */
230  void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag)  void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag,
231            int check_for_interrupts)
232  {  {
233            uint64_t old = cpu->cd.ppc.msr;
234    
235          if (valuep == NULL) {          if (valuep == NULL) {
236                  fatal("reg_access_msr(): NULL\n");                  fatal("reg_access_msr(): NULL\n");
237                  return;                  return;
238          }          }
239    
240          if (writeflag)          if (writeflag) {
241                  cpu->cd.ppc.msr = *valuep;                  cpu->cd.ppc.msr = *valuep;
242    
243                    /*  Switching between temporary and real gpr 0..3?  */
244                    if ((old & PPC_MSR_TGPR) != (cpu->cd.ppc.msr & PPC_MSR_TGPR)) {
245                            int i;
246                            for (i=0; i<PPC_N_TGPRS; i++) {
247                                    uint64_t t = cpu->cd.ppc.gpr[i];
248                                    cpu->cd.ppc.gpr[i] = cpu->cd.ppc.tgpr[i];
249                                    cpu->cd.ppc.tgpr[i] = t;
250                            }
251                    }
252    
253                    if (cpu->cd.ppc.msr & PPC_MSR_IP) {
254                            fatal("\n[ Reboot hack for NetBSD/prep. TODO: "
255                                "fix this. ]\n");
256                            cpu->running = 0;
257                    }
258            }
259    
260          /*  TODO: Is the little-endian bit writable?  */          /*  TODO: Is the little-endian bit writable?  */
261    
262          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 265  void reg_access_msr(struct cpu *cpu, uin
265    
266          if (!writeflag)          if (!writeflag)
267                  *valuep = cpu->cd.ppc.msr;                  *valuep = cpu->cd.ppc.msr;
268    
269            if (check_for_interrupts && cpu->cd.ppc.msr & PPC_MSR_EE) {
270                    if (cpu->cd.ppc.dec_intr_pending) {
271                            ppc_exception(cpu, PPC_EXCEPTION_DEC);
272                            cpu->cd.ppc.dec_intr_pending = 0;
273                    } else if (cpu->cd.ppc.irq_asserted)
274                            ppc_exception(cpu, PPC_EXCEPTION_EI);
275            }
276    }
277    
278    
279    /*
280     *  ppc_exception():
281     */
282    void ppc_exception(struct cpu *cpu, int exception_nr)
283    {
284            /*  Save PC and MSR:  */
285            cpu->cd.ppc.spr[SPR_SRR0] = cpu->pc;
286    
287            if (exception_nr >= 0x10 && exception_nr <= 0x13)
288                    cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0xffff)
289                        | (cpu->cd.ppc.cr & 0xf0000000);
290            else
291                    cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);
292    
293            if (!quiet_mode)
294                    fatal("[ PPC Exception 0x%x; pc=0x%llx ]\n", exception_nr,
295                        (long long)cpu->pc);
296    
297            /*  Disable External Interrupts, Recoverable Interrupt Mode,
298                and go to Supervisor mode  */
299            cpu->cd.ppc.msr &= ~(PPC_MSR_EE | PPC_MSR_RI | PPC_MSR_PR);
300    
301            cpu->pc = exception_nr * 0x100;
302            if (cpu->cd.ppc.msr & PPC_MSR_IP)
303                    cpu->pc += 0xfff00000ULL;
304    
305            if (cpu->is_32bit)
306                    ppc32_pc_to_pointers(cpu);
307            else
308                    ppc_pc_to_pointers(cpu);
309  }  }
310    
311    
# Line 253  void ppc_cpu_register_dump(struct cpu *c Line 338  void ppc_cpu_register_dump(struct cpu *c
338    
339                  debug("cpu%i: lr  = 0x", x);                  debug("cpu%i: lr  = 0x", x);
340                  if (bits32)                  if (bits32)
341                          debug("%08x", (int)cpu->cd.ppc.lr);                          debug("%08x", (int)cpu->cd.ppc.spr[SPR_LR]);
342                  else                  else
343                          debug("%016llx", (long long)cpu->cd.ppc.lr);                          debug("%016llx", (long long)cpu->cd.ppc.spr[SPR_LR]);
344                  debug("  cr  = 0x%08x\n", (int)cpu->cd.ppc.cr);                  debug("  cr  = 0x%08x", (int)cpu->cd.ppc.cr);
345    
                 debug("cpu%i: ctr = 0x", x);  
346                  if (bits32)                  if (bits32)
347                          debug("%08x", (int)cpu->cd.ppc.ctr);                          debug("  ");
348                    else
349                            debug("\ncpu%i: ", x);
350                    debug("ctr = 0x", x);
351                    if (bits32)
352                            debug("%08x", (int)cpu->cd.ppc.spr[SPR_CTR]);
353                  else                  else
354                          debug("%016llx", (long long)cpu->cd.ppc.ctr);                          debug("%016llx", (long long)cpu->cd.ppc.spr[SPR_CTR]);
355    
356                  debug("  xer = 0x", x);                  debug("  xer = 0x", x);
357                  if (bits32)                  if (bits32)
358                          debug("%08x\n", (int)cpu->cd.ppc.xer);                          debug("%08x\n", (int)cpu->cd.ppc.spr[SPR_XER]);
359                  else                  else
360                          debug("%016llx\n", (long long)cpu->cd.ppc.xer);                          debug("%016llx\n", (long long)cpu->cd.ppc.spr[SPR_XER]);
361    
362                  if (bits32) {                  if (bits32) {
363                          /*  32-bit:  */                          /*  32-bit:  */
# Line 294  void ppc_cpu_register_dump(struct cpu *c Line 383  void ppc_cpu_register_dump(struct cpu *c
383                  }                  }
384    
385                  /*  Other special registers:  */                  /*  Other special registers:  */
386                  debug("cpu%i: srr0 = 0x%016llx  srr1 = 0x%016llx\n", x,                  if (bits32) {
387                      (long long)cpu->cd.ppc.srr0, (long long)cpu->cd.ppc.srr1);                          debug("cpu%i: srr0 = 0x%08x srr1 = 0x%08x\n", x,
388                  reg_access_msr(cpu, &tmp, 0);                              (int)cpu->cd.ppc.spr[SPR_SRR0],
389                  debug("cpu%i: msr = 0x%016llx  ", x, (long long)tmp);                              (int)cpu->cd.ppc.spr[SPR_SRR1]);
390                  debug("tb  = 0x%08x%08x\n",                  } else {
391                      (int)cpu->cd.ppc.tbu, (int)cpu->cd.ppc.tbl);                          debug("cpu%i: srr0 = 0x%016llx  srr1 = 0x%016llx\n", x,
392                  debug("cpu%i: dec = 0x%08x  hdec = 0x%08x\n",                              (long long)cpu->cd.ppc.spr[SPR_SRR0],
393                      x, (int)cpu->cd.ppc.dec, (int)cpu->cd.ppc.hdec);                              (long long)cpu->cd.ppc.spr[SPR_SRR1]);
394                    }
395                    debug("cpu%i: msr = ", x);
396                    reg_access_msr(cpu, &tmp, 0, 0);
397                    if (bits32)
398                            debug("0x%08x  ", (int)tmp);
399                    else
400                            debug("0x%016llx  ", (long long)tmp);
401                    debug("tb  = 0x%08x%08x\n", (int)cpu->cd.ppc.spr[SPR_TBU],
402                        (int)cpu->cd.ppc.spr[SPR_TBL]);
403                    debug("cpu%i: dec = 0x%08x", x, (int)cpu->cd.ppc.spr[SPR_DEC]);
404                    if (!bits32)
405                            debug("  hdec = 0x%08x\n",
406                                (int)cpu->cd.ppc.spr[SPR_HDEC]);
407                    debug("\n");
408          }          }
409    
410          if (coprocs & 1) {          if (coprocs & 1) {
# Line 323  void ppc_cpu_register_dump(struct cpu *c Line 426  void ppc_cpu_register_dump(struct cpu *c
426    
427          if (coprocs & 2) {          if (coprocs & 2) {
428                  debug("cpu%i:  sdr1 = 0x%llx\n", x,                  debug("cpu%i:  sdr1 = 0x%llx\n", x,
429                      (long long)cpu->cd.ppc.sdr1);                      (long long)cpu->cd.ppc.spr[SPR_SDR1]);
430                  for (i=0; i<4; i++)                  if (cpu->cd.ppc.cpu_type.flags & PPC_601)
431                          debug("cpu%i:  ibat%iu = 0x%08x  ibat%il = 0x%08x\n",                          debug("cpu%i:  PPC601-style, TODO!\n");
432                              x, i, cpu->cd.ppc.ibat_u[i],                  else {
433                              i, cpu->cd.ppc.ibat_l[i]);                          for (i=0; i<8; i++) {
434                  for (i=0; i<4; i++)                                  int spr = SPR_IBAT0U + i*2;
435                          debug("cpu%i:  dbat%iu = 0x%08x  dbat%il = 0x%08x\n",                                  uint32_t upper = cpu->cd.ppc.spr[spr];
436                              x, i, cpu->cd.ppc.dbat_u[i],                                  uint32_t lower = cpu->cd.ppc.spr[spr+1];
437                              i, cpu->cd.ppc.dbat_l[i]);                                  uint32_t len = (((upper & BAT_BL) << 15)
438                                        | 0x1ffff) + 1;
439                                    debug("cpu%i:  %sbat%i: u=0x%08x l=0x%08x ",
440                                        x, i<4? "i" : "d", i&3, upper, lower);
441                                    if (!(upper & BAT_V)) {
442                                            debug(" (not valid)\n");
443                                            continue;
444                                    }
445                                    if (len < 1048576)
446                                            debug(" (%i KB, ", len >> 10);
447                                    else
448                                            debug(" (%i MB, ", len >> 20);
449                                    if (upper & BAT_Vu)
450                                            debug("user, ");
451                                    if (upper & BAT_Vs)
452                                            debug("supervisor, ");
453                                    if (lower & (BAT_W | BAT_I | BAT_M | BAT_G))
454                                            debug("%s%s%s%s, ",
455                                                lower & BAT_W? "W" : "",
456                                                lower & BAT_I? "I" : "",
457                                                lower & BAT_M? "M" : "",
458                                                lower & BAT_G? "G" : "");
459                                    switch (lower & BAT_PP) {
460                                    case BAT_PP_NONE: debug("NO access"); break;
461                                    case BAT_PP_RO_S: debug("read-only, soft");
462                                                      break;
463                                    case BAT_PP_RO:   debug("read-only"); break;
464                                    case BAT_PP_RW:   debug("read/write"); break;
465                                    }
466                                    debug(")\n");
467                            }
468                    }
469            }
470    
471            if (coprocs & 4) {
472                    for (i=0; i<16; i++) {
473                            uint32_t s = cpu->cd.ppc.sr[i];
474                            debug("cpu%i:", x);
475                            debug("  sr%2i = 0x%08x", i, (int)s);
476                            s &= (SR_TYPE | SR_SUKEY | SR_PRKEY | SR_NOEXEC);
477                            if (s != 0) {
478                                    debug("  (");
479                                    if (s & SR_TYPE) {
480                                            debug("NON-memory type");
481                                            s &= ~SR_TYPE;
482                                            if (s != 0)
483                                                    debug(", ");
484                                    }
485                                    if (s & SR_SUKEY) {
486                                            debug("supervisor-key");
487                                            s &= ~SR_SUKEY;
488                                            if (s != 0)
489                                                    debug(", ");
490                                    }
491                                    if (s & SR_PRKEY) {
492                                            debug("user-key");
493                                            s &= ~SR_PRKEY;
494                                            if (s != 0)
495                                                    debug(", ");
496                                    }
497                                    if (s & SR_NOEXEC)
498                                            debug("NOEXEC");
499                                    debug(")");
500                            }
501                            debug("\n");
502                    }
503          }          }
504  }  }
505    
# Line 363  void ppc_cpu_register_match(struct machi Line 531  void ppc_cpu_register_match(struct machi
531                  *match_register = 1;                  *match_register = 1;
532          } else if (strcasecmp(name, "lr") == 0) {          } else if (strcasecmp(name, "lr") == 0) {
533                  if (writeflag)                  if (writeflag)
534                          m->cpus[cpunr]->cd.ppc.lr = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_LR] = *valuep;
535                  else                  else
536                          *valuep = m->cpus[cpunr]->cd.ppc.lr;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_LR];
537                  *match_register = 1;                  *match_register = 1;
538          } else if (strcasecmp(name, "cr") == 0) {          } else if (strcasecmp(name, "cr") == 0) {
539                  if (writeflag)                  if (writeflag)
# Line 375  void ppc_cpu_register_match(struct machi Line 543  void ppc_cpu_register_match(struct machi
543                  *match_register = 1;                  *match_register = 1;
544          } else if (strcasecmp(name, "dec") == 0) {          } else if (strcasecmp(name, "dec") == 0) {
545                  if (writeflag)                  if (writeflag)
546                          m->cpus[cpunr]->cd.ppc.dec = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_DEC] = *valuep;
547                  else                  else
548                          *valuep = m->cpus[cpunr]->cd.ppc.dec;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_DEC];
549                  *match_register = 1;                  *match_register = 1;
550          } else if (strcasecmp(name, "hdec") == 0) {          } else if (strcasecmp(name, "hdec") == 0) {
551                  if (writeflag)                  if (writeflag)
552                          m->cpus[cpunr]->cd.ppc.hdec = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_HDEC] = *valuep;
553                  else                  else
554                          *valuep = m->cpus[cpunr]->cd.ppc.hdec;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_HDEC];
555                  *match_register = 1;                  *match_register = 1;
556          } else if (strcasecmp(name, "ctr") == 0) {          } else if (strcasecmp(name, "ctr") == 0) {
557                  if (writeflag)                  if (writeflag)
558                          m->cpus[cpunr]->cd.ppc.ctr = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_CTR] = *valuep;
559                  else                  else
560                          *valuep = m->cpus[cpunr]->cd.ppc.ctr;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_CTR];
561                  *match_register = 1;                  *match_register = 1;
562          } else if (name[0] == 'r' && isdigit((int)name[1])) {          } else if (name[0] == 'r' && isdigit((int)name[1])) {
563                  int nr = atoi(name + 1);                  int nr = atoi(name + 1);
# Line 402  void ppc_cpu_register_match(struct machi Line 570  void ppc_cpu_register_match(struct machi
570                  }                  }
571          } else if (strcasecmp(name, "xer") == 0) {          } else if (strcasecmp(name, "xer") == 0) {
572                  if (writeflag)                  if (writeflag)
573                          m->cpus[cpunr]->cd.ppc.xer = *valuep;                          m->cpus[cpunr]->cd.ppc.spr[SPR_XER] = *valuep;
574                  else                  else
575                          *valuep = m->cpus[cpunr]->cd.ppc.xer;                          *valuep = m->cpus[cpunr]->cd.ppc.spr[SPR_XER];
576                  *match_register = 1;                  *match_register = 1;
577          } else if (strcasecmp(name, "fpscr") == 0) {          } else if (strcasecmp(name, "fpscr") == 0) {
578                  if (writeflag)                  if (writeflag)
# Line 426  void ppc_cpu_register_match(struct machi Line 594  void ppc_cpu_register_match(struct machi
594    
595    
596  /*  /*
597   *  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():  
598   *   *
599   *  Called from the debugger to dump the TLB in a readable format.   *  0..31 are used as BeBox interrupt numbers, 32..47 = ISA,
600   *  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().
601   *   *
602   *  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():  
603   */   */
604  int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)
605  {  {
606          fatal("ppc_cpu_interrupt(): TODO\n");          /*  fatal("ppc_cpu_interrupt(): 0x%x\n", (int)irq_nr);  */
607          return 0;          if (irq_nr <= 64) {
608                    if (cpu->machine->md_interrupt != NULL)
609                            cpu->machine->md_interrupt(
610                                cpu->machine, cpu, irq_nr, 1);
611                    else
612                            fatal("ppc_cpu_interrupt(): md_interrupt == NULL\n");
613            } else {
614                    /*  Assert PPC IRQ:  */
615                    cpu->cd.ppc.irq_asserted = 1;
616            }
617            return 1;
618  }  }
619    
620    
# Line 466  int ppc_cpu_interrupt(struct cpu *cpu, u Line 623  int ppc_cpu_interrupt(struct cpu *cpu, u
623   */   */
624  int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)
625  {  {
626          /*  fatal("ppc_cpu_interrupt_ack(): TODO\n");  */          if (irq_nr <= 64) {
627          return 0;                  if (cpu->machine->md_interrupt != NULL)
628                            cpu->machine->md_interrupt(cpu->machine,
629                                cpu, irq_nr, 0);
630            } else {
631                    /*  De-assert PPC IRQ:  */
632                    cpu->cd.ppc.irq_asserted = 0;
633            }
634            return 1;
635  }  }
636    
637    
# Line 523  int ppc_cpu_disassemble_instr(struct cpu Line 687  int ppc_cpu_disassemble_instr(struct cpu
687          hi6 = iword >> 26;          hi6 = iword >> 26;
688    
689          switch (hi6) {          switch (hi6) {
690            case 0x4:
691                    debug("ALTIVEC TODO");
692                    /*  vxor etc  */
693                    break;
694          case PPC_HI6_MULLI:          case PPC_HI6_MULLI:
695          case PPC_HI6_SUBFIC:          case PPC_HI6_SUBFIC:
696                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
# Line 715  int ppc_cpu_disassemble_instr(struct cpu Line 883  int ppc_cpu_disassemble_instr(struct cpu
883                          debug("unimplemented hi6_19, xo = 0x%x", xo);                          debug("unimplemented hi6_19, xo = 0x%x", xo);
884                  }                  }
885                  break;                  break;
886            case PPC_HI6_RLWNM:
887          case PPC_HI6_RLWIMI:          case PPC_HI6_RLWIMI:
888          case PPC_HI6_RLWINM:          case PPC_HI6_RLWINM:
889                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
890                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
891                  sh = (iword >> 11) & 31;                  sh = (iword >> 11) & 31;        /*  actually rb for rlwnm  */
892                  mb = (iword >> 6) & 31;                  mb = (iword >> 6) & 31;
893                  me = (iword >> 1) & 31;                  me = (iword >> 1) & 31;
894                  rc = iword & 1;                  rc = iword & 1;
895                  switch (hi6) {                  switch (hi6) {
896                    case PPC_HI6_RLWNM:
897                            mnem = power? "rlnm" : "rlwnm"; break;
898                  case PPC_HI6_RLWIMI:                  case PPC_HI6_RLWIMI:
899                          mnem = power? "rlimi" : "rlwimi"; break;                          mnem = power? "rlimi" : "rlwimi"; break;
900                  case PPC_HI6_RLWINM:                  case PPC_HI6_RLWINM:
901                          mnem = power? "rlinm" : "rlwinm"; break;                          mnem = power? "rlinm" : "rlwinm"; break;
902                  }                  }
903                  debug("%s%s\tr%i,r%i,%i,%i,%i",                  debug("%s%s\tr%i,r%i,%s%i,%i,%i",
904                      mnem, rc?".":"", ra, rs, sh, mb, me);                      mnem, rc?".":"", ra, rs,
905                        hi6 == PPC_HI6_RLWNM? "r" : "",
906                        sh, mb, me);
907                  break;                  break;
908          case PPC_HI6_ORI:          case PPC_HI6_ORI:
909          case PPC_HI6_ORIS:          case PPC_HI6_ORIS:
# Line 836  int ppc_cpu_disassemble_instr(struct cpu Line 1009  int ppc_cpu_disassemble_instr(struct cpu
1009                  case PPC_31_LDARX:                  case PPC_31_LDARX:
1010                  case PPC_31_LBZX:                  case PPC_31_LBZX:
1011                  case PPC_31_LBZUX:                  case PPC_31_LBZUX:
1012                    case PPC_31_LHAX:
1013                    case PPC_31_LHAUX:
1014                  case PPC_31_LHZX:                  case PPC_31_LHZX:
1015                  case PPC_31_LHZUX:                  case PPC_31_LHZUX:
1016                  case PPC_31_LWZX:                  case PPC_31_LWZX:
1017                  case PPC_31_LWZUX:                  case PPC_31_LWZUX:
1018                    case PPC_31_LHBRX:
1019                    case PPC_31_LWBRX:
1020                    case PPC_31_LFDX:
1021                    case PPC_31_LFSX:
1022                  case PPC_31_STWCX_DOT:                  case PPC_31_STWCX_DOT:
1023                  case PPC_31_STDCX_DOT:                  case PPC_31_STDCX_DOT:
1024                  case PPC_31_STBX:                  case PPC_31_STBX:
# Line 850  int ppc_cpu_disassemble_instr(struct cpu Line 1029  int ppc_cpu_disassemble_instr(struct cpu
1029                  case PPC_31_STWUX:                  case PPC_31_STWUX:
1030                  case PPC_31_STDX:                  case PPC_31_STDX:
1031                  case PPC_31_STDUX:                  case PPC_31_STDUX:
1032                    case PPC_31_STHBRX:
1033                    case PPC_31_STWBRX:
1034                    case PPC_31_STFDX:
1035                    case PPC_31_STFSX:
1036                          /*  rs for stores, rt for loads, actually  */                          /*  rs for stores, rt for loads, actually  */
1037                          load = 0; wlen = 0;                          load = 0; wlen = 0; fpreg = 0;
1038                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1039                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1040                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
# Line 860  int ppc_cpu_disassemble_instr(struct cpu Line 1043  int ppc_cpu_disassemble_instr(struct cpu
1043                          case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;                          case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;
1044                          case PPC_31_LBZX:  wlen=1;load=1; mnem = "lbzx"; break;                          case PPC_31_LBZX:  wlen=1;load=1; mnem = "lbzx"; break;
1045                          case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;                          case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;
1046                            case PPC_31_LHAX:  wlen=2;load=1; mnem = "lhax"; break;
1047                            case PPC_31_LHAUX: wlen=2;load=1; mnem = "lhaux"; break;
1048                          case PPC_31_LHZX:  wlen=2;load=1; mnem = "lhzx"; break;                          case PPC_31_LHZX:  wlen=2;load=1; mnem = "lhzx"; break;
1049                          case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;                          case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;
1050                          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 1053  int ppc_cpu_disassemble_instr(struct cpu
1053                          case PPC_31_LWZUX: wlen = 4; load = 1;                          case PPC_31_LWZUX: wlen = 4; load = 1;
1054                                  mnem = power? "lux":"lwzux";                                  mnem = power? "lux":"lwzux";
1055                                  break;                                  break;
1056                            case PPC_31_LFDX: fpreg = 1; wlen = 8; load = 1;
1057                                    mnem = "lfdx"; break;
1058                            case PPC_31_LFSX: fpreg = 1; wlen = 4; load = 1;
1059                                    mnem = "lfsx"; break;
1060                          case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;                          case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;
1061                          case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;                          case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;
1062                          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 1071  int ppc_cpu_disassemble_instr(struct cpu
1071                                  break;                                  break;
1072                          case PPC_31_STDX:  wlen = 8; mnem = "stdx"; break;                          case PPC_31_STDX:  wlen = 8; mnem = "stdx"; break;
1073                          case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;                          case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;
1074                            case PPC_31_LHBRX:  wlen = 2; mnem = "lhbrx"; break;
1075                            case PPC_31_LWBRX:  wlen = 4; mnem = power?
1076                                                "lbrx" : "lwbrx"; break;
1077                            case PPC_31_STHBRX: wlen = 2; mnem = "sthbrx"; break;
1078                            case PPC_31_STWBRX: wlen = 4; mnem = power?
1079                                                "stbrx" : "stwbrx"; break;
1080                            case PPC_31_STFDX: fpreg = 1; wlen = 8;
1081                                    mnem = "stfdx"; break;
1082                            case PPC_31_STFSX: fpreg = 1; wlen = 4;
1083                                    mnem = "stfsx"; break;
1084                          }                          }
1085                          debug("%s\tr%i,r%i,r%i", mnem, rs, ra, rb);                          debug("%s\t%s%i,r%i,r%i", mnem,
1086                                fpreg? "f" : "r", rs, ra, rb);
1087                          if (!running)                          if (!running)
1088                                  break;                                  break;
1089                          addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +                          addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +
1090                              cpu->cd.ppc.gpr[rb];                              cpu->cd.ppc.gpr[rb];
1091                            if (cpu->cd.ppc.bits == 32)
1092                                    addr &= 0xffffffff;
1093                          symbol = get_symbol_name(&cpu->machine->symbol_context,                          symbol = get_symbol_name(&cpu->machine->symbol_context,
1094                              addr, &offset);                              addr, &offset);
1095                          if (symbol != NULL)                          if (symbol != NULL)
1096                                  debug(" \t<%s", symbol);                                  debug(" \t<%s", symbol);
1097                          else                          else
1098                                  debug(" \t<0x%llx", (long long)addr);                                  debug(" \t<0x%llx", (long long)addr);
1099                          if (wlen > 0) {                          if (wlen > 0 && !fpreg /* && !reverse */) {
1100                                  /*  TODO  */                                  /*  TODO  */
1101                          }                          }
1102                          debug(">");                          debug(">");
# Line 911  int ppc_cpu_disassemble_instr(struct cpu Line 1113  int ppc_cpu_disassemble_instr(struct cpu
1113                          }                          }
1114                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1115                          break;                          break;
1116                    case PPC_31_WRTEEI:
1117                            debug("wrteei\t%i", iword & 0x8000? 1 : 0);
1118                            break;
1119                  case PPC_31_ADDZE:                  case PPC_31_ADDZE:
1120                  case PPC_31_ADDZEO:                  case PPC_31_ADDZEO:
1121                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 928  int ppc_cpu_disassemble_instr(struct cpu Line 1133  int ppc_cpu_disassemble_instr(struct cpu
1133                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1134                          break;                          break;
1135                  case PPC_31_MTSR:                  case PPC_31_MTSR:
1136                          /*  Move to segment register  */                  case PPC_31_MFSR:
1137                            /*  Move to/from segment register  */
1138                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1139                          ra = (iword >> 16) & 15;        /*  actually: sr  */                          ra = (iword >> 16) & 15;        /*  actually: sr  */
1140                          debug("mtsr\t%i,r%i", ra, rt);                          switch (xo) {
1141                            case PPC_31_MTSR:  mnem = "mtsr"; break;
1142                            case PPC_31_MFSR:  mnem = "mfsr"; break;
1143                            }
1144                            debug("%s\tr%i,%i", mnem, rt, ra);
1145                          break;                          break;
1146                  case PPC_31_MTSRIN:                  case PPC_31_MTSRIN:
1147                  case PPC_31_MFSRIN:                  case PPC_31_MFSRIN:
# Line 962  int ppc_cpu_disassemble_instr(struct cpu Line 1172  int ppc_cpu_disassemble_instr(struct cpu
1172                  case PPC_31_SUBFCO:                  case PPC_31_SUBFCO:
1173                  case PPC_31_SUBFE:                  case PPC_31_SUBFE:
1174                  case PPC_31_SUBFEO:                  case PPC_31_SUBFEO:
1175                    case PPC_31_SUBFME:
1176                    case PPC_31_SUBFMEO:
1177                  case PPC_31_SUBFZE:                  case PPC_31_SUBFZE:
1178                  case PPC_31_SUBFZEO:                  case PPC_31_SUBFZEO:
1179                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 1007  int ppc_cpu_disassemble_instr(struct cpu Line 1219  int ppc_cpu_disassemble_instr(struct cpu
1219                          case PPC_31_SUBF:   mnem = "subf"; break;                          case PPC_31_SUBF:   mnem = "subf"; break;
1220                          case PPC_31_SUBFO:  mnem = "subfo"; break;                          case PPC_31_SUBFO:  mnem = "subfo"; break;
1221                          case PPC_31_SUBFC:                          case PPC_31_SUBFC:
1222                                  mnem = power? "sf" : "subfc";                                  mnem = power? "sf" : "subfc"; break;
                                 break;  
1223                          case PPC_31_SUBFCO:                          case PPC_31_SUBFCO:
1224                                  mnem = power? "sfo" : "subfco";                                  mnem = power? "sfo" : "subfco"; break;
                                 break;  
1225                          case PPC_31_SUBFE:                          case PPC_31_SUBFE:
1226                                  mnem = power? "sfe" : "subfe";                                  mnem = power? "sfe" : "subfe"; break;
                                 break;  
1227                          case PPC_31_SUBFEO:                          case PPC_31_SUBFEO:
1228                                  mnem = power? "sfeo" : "subfeo";                                  mnem = power? "sfeo" : "subfeo"; break;
1229                                  break;                          case PPC_31_SUBFME:
1230                                    mnem = power? "sfme" : "subfme"; break;
1231                            case PPC_31_SUBFMEO:
1232                                    mnem = power? "sfmeo" : "subfmeo"; break;
1233                          case PPC_31_SUBFZE:                          case PPC_31_SUBFZE:
1234                                  mnem = power? "sfze" : "subfze";                                  mnem = power? "sfze" : "subfze";
1235                                  no_rb = 1;                                  no_rb = 1;
# Line 1035  int ppc_cpu_disassemble_instr(struct cpu Line 1247  int ppc_cpu_disassemble_instr(struct cpu
1247                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1248                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1249                          switch (spr) {                          switch (spr) {
1250                            /*  Some very common ones:  */
1251                          case 8:    debug("mflr\tr%i", rt); break;                          case 8:    debug("mflr\tr%i", rt); break;
1252                          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;  
1253                          default:debug("mfspr\tr%i,spr%i", rt, spr);                          default:debug("mfspr\tr%i,spr%i", rt, spr);
1254                          }                          }
1255                            if (spr == 8 || spr == 9)
1256                                    debug("\t");
1257                            debug("\t<%s%s", running? "read from " : "",
1258                                ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1259                            if (running) {
1260                                    if (cpu->cd.ppc.bits == 32)
1261                                            debug(": 0x%x", (int)
1262                                                cpu->cd.ppc.spr[spr]);
1263                                    else
1264                                            debug(": 0x%llx", (long long)
1265                                                cpu->cd.ppc.spr[spr]);
1266                            }
1267                            debug(">");
1268                            break;
1269                    case PPC_31_TLBIA:
1270                            debug("tlbia");
1271                            break;
1272                    case PPC_31_SLBIA:
1273                            debug("slbia");
1274                            break;
1275                    case PPC_31_TLBLD:
1276                    case PPC_31_TLBLI:
1277                            rb = (iword >> 11) & 31;
1278                            debug("tlbl%s\tr%i", xo == PPC_31_TLBLD? "d" : "i", rb);
1279                          break;                          break;
1280                  case PPC_31_TLBIE:                  case PPC_31_TLBIE:
1281                          /*  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 1286  int ppc_cpu_disassemble_instr(struct cpu
1286                          else                          else
1287                                  debug("tlbie\tr%i", rb);                                  debug("tlbie\tr%i", rb);
1288                          break;                          break;
1289                    case PPC_31_TLBSX_DOT:
1290                            rs = (iword >> 21) & 31;
1291                            ra = (iword >> 16) & 31;
1292                            rb = (iword >> 11) & 31;
1293                            debug("tlbsx.\tr%i,r%i,r%i", rs, ra, rb);
1294                            break;
1295                  case PPC_31_TLBSYNC:                  case PPC_31_TLBSYNC:
1296                          debug("tlbsync");                          debug("tlbsync");
1297                          break;                          break;
# Line 1172  int ppc_cpu_disassemble_instr(struct cpu Line 1403  int ppc_cpu_disassemble_instr(struct cpu
1403                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1404                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1405                          switch (spr) {                          switch (spr) {
1406                            /*  Some very common ones:  */
1407                          case 8:    debug("mtlr\tr%i", rs); break;                          case 8:    debug("mtlr\tr%i", rs); break;
1408                          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;  
1409                          default:debug("mtspr\tspr%i,r%i", spr, rs);                          default:debug("mtspr\tspr%i,r%i", spr, rs);
1410                          }                          }
1411                            if (spr == 8 || spr == 9)
1412                                    debug("\t");
1413                            debug("\t<%s%s", running? "write to " : "",
1414                                ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1415                            if (running) {
1416                                    if (cpu->cd.ppc.bits == 32)
1417                                            debug(": 0x%x", (int)
1418                                                cpu->cd.ppc.gpr[rs]);
1419                                    else
1420                                            debug(": 0x%llx", (long long)
1421                                                cpu->cd.ppc.gpr[rs]);
1422                            }
1423                            debug(">");
1424                          break;                          break;
1425                  case PPC_31_SYNC:                  case PPC_31_SYNC:
1426                          debug("%s", power? "dcs" : "sync");                          debug("%s", power? "dcs" : "sync");
# Line 1216  int ppc_cpu_disassemble_instr(struct cpu Line 1438  int ppc_cpu_disassemble_instr(struct cpu
1438                          }                          }
1439                          debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);                          debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);
1440                          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;  
1441                  case PPC_31_SRAWI:                  case PPC_31_SRAWI:
1442                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1443                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
# Line 1264  int ppc_cpu_disassemble_instr(struct cpu Line 1469  int ppc_cpu_disassemble_instr(struct cpu
1469                          }                          }
1470                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1471                          break;                          break;
1472                    case 359:
1473                            debug("TODO: ALTIVEC 359");
1474                            break;
1475                    case PPC_31_LVX:
1476                            debug("lvx\tTODO: ALTIVEC");
1477                            break;
1478                    case PPC_31_STVX:
1479                            debug("stvx\tTODO: ALTIVEC");
1480                            break;
1481                    case PPC_31_STVXL:
1482                            debug("stvxl\tTODO: ALTIVEC");
1483                            break;
1484                  default:                  default:
1485                          debug("unimplemented hi6_31, xo = 0x%x", xo);                          debug("unimplemented hi6_31, xo = 0x%x", xo);
1486                  }                  }
1487                  break;                  break;
1488            case PPC_HI6_LD:
1489          case PPC_HI6_LWZ:          case PPC_HI6_LWZ:
1490          case PPC_HI6_LWZU:          case PPC_HI6_LWZU:
1491          case PPC_HI6_LHZ:          case PPC_HI6_LHZ:
# Line 1276  int ppc_cpu_disassemble_instr(struct cpu Line 1494  int ppc_cpu_disassemble_instr(struct cpu
1494          case PPC_HI6_LHAU:          case PPC_HI6_LHAU:
1495          case PPC_HI6_LBZ:          case PPC_HI6_LBZ:
1496          case PPC_HI6_LBZU:          case PPC_HI6_LBZU:
1497            case PPC_HI6_LFD:
1498            case PPC_HI6_LFS:
1499          case PPC_HI6_LMW:          case PPC_HI6_LMW:
1500            case PPC_HI6_STD:
1501          case PPC_HI6_STW:          case PPC_HI6_STW:
1502          case PPC_HI6_STWU:          case PPC_HI6_STWU:
1503          case PPC_HI6_STH:          case PPC_HI6_STH:
# Line 1284  int ppc_cpu_disassemble_instr(struct cpu Line 1505  int ppc_cpu_disassemble_instr(struct cpu
1505          case PPC_HI6_STB:          case PPC_HI6_STB:
1506          case PPC_HI6_STBU:          case PPC_HI6_STBU:
1507          case PPC_HI6_STMW:          case PPC_HI6_STMW:
         case PPC_HI6_LFD:  
1508          case PPC_HI6_STFD:          case PPC_HI6_STFD:
1509            case PPC_HI6_STFS:
1510                  /*  NOTE: Loads use rt, not rs, but are otherwise similar                  /*  NOTE: Loads use rt, not rs, but are otherwise similar
1511                      to stores  */                      to stores  */
1512                  load = 0; wlen = 0;                  load = 0; wlen = 0;
# Line 1294  int ppc_cpu_disassemble_instr(struct cpu Line 1515  int ppc_cpu_disassemble_instr(struct cpu
1515                  imm = (int16_t)(iword & 0xffff);                  imm = (int16_t)(iword & 0xffff);
1516                  fpreg = 0;                  fpreg = 0;
1517                  switch (hi6) {                  switch (hi6) {
1518                    case PPC_HI6_LD:  load=1; wlen = 8; mnem = "ld"; break;
1519                  case PPC_HI6_LWZ:  load=1; wlen = 4;                  case PPC_HI6_LWZ:  load=1; wlen = 4;
1520                          mnem = power? "l" : "lwz"; break;                          mnem = power? "l" : "lwz"; break;
1521                  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 1532  int ppc_cpu_disassemble_instr(struct cpu
1532                          mnem = "lbz"; break;                          mnem = "lbz"; break;
1533                  case PPC_HI6_LBZU: load=1; wlen = 1;                  case PPC_HI6_LBZU: load=1; wlen = 1;
1534                          mnem = "lbzu"; break;                          mnem = "lbzu"; break;
1535                    case PPC_HI6_LFD:  load=1; fpreg=1; wlen=8; mnem = "lfd"; break;
1536                    case PPC_HI6_LFS:  load=1; fpreg=1; wlen=4; mnem = "lfs"; break;
1537                    case PPC_HI6_STD:  wlen=8; mnem = "std"; break;
1538                  case PPC_HI6_STW:  wlen=4; mnem = power? "st" : "stw"; break;                  case PPC_HI6_STW:  wlen=4; mnem = power? "st" : "stw"; break;
1539                  case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;                  case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;
1540                  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 1543  int ppc_cpu_disassemble_instr(struct cpu
1543                  case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;                  case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;
1544                  case PPC_HI6_LMW:  load=1; mnem = power? "lm" : "lmw"; break;                  case PPC_HI6_LMW:  load=1; mnem = power? "lm" : "lmw"; break;
1545                  case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;                  case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1546                  case PPC_HI6_LFD:  load=1; fpreg = 1; mnem = "lfd"; break;                  case PPC_HI6_STFD: fpreg=1; wlen=8; mnem = "stfd"; break;
1547                  case PPC_HI6_STFD: fpreg = 1; mnem = "stfd"; break;                  case PPC_HI6_STFS: fpreg=1; wlen=4; mnem = "stfs"; break;
1548                  }                  }
1549                  debug("%s\t", mnem);                  debug("%s\t", mnem);
1550                  if (fpreg)                  if (fpreg)
# Line 1330  int ppc_cpu_disassemble_instr(struct cpu Line 1555  int ppc_cpu_disassemble_instr(struct cpu
1555                  if (!running)                  if (!running)
1556                          break;                          break;
1557                  addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;                  addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;
1558                    if (cpu->cd.ppc.bits == 32)
1559                            addr &= 0xffffffff;
1560                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
1561                      addr, &offset);                      addr, &offset);
1562                  if (symbol != NULL)                  if (symbol != NULL)
# Line 1374  int ppc_cpu_disassemble_instr(struct cpu Line 1601  int ppc_cpu_disassemble_instr(struct cpu
1601                          int i;                          int i;
1602                          for (i=0; i<wlen; i++)                          for (i=0; i<wlen; i++)
1603                                  tdata |= (cpu->cd.ppc.gpr[rs] &                                  tdata |= (cpu->cd.ppc.gpr[rs] &
1604                                      ((uint64_t)0xff << i));                                      ((uint64_t)0xff << (i*8)));
1605                          debug(": ");                          debug(": ");
1606                          if (wlen >= 4) {                          if (wlen >= 4) {
1607                                  symbol = get_symbol_name(&cpu->machine->                                  symbol = get_symbol_name(&cpu->machine->
# Line 1382  int ppc_cpu_disassemble_instr(struct cpu Line 1609  int ppc_cpu_disassemble_instr(struct cpu
1609                                  if (symbol != NULL)                                  if (symbol != NULL)
1610                                          debug("%s", symbol);                                          debug("%s", symbol);
1611                                  else                                  else
1612                                          debug("0x%llx",                                          debug("0x%llx", (long long)tdata);
                                             (long long)tdata);  
1613                          } else {                          } else {
1614                                  if (tdata > -256 && tdata < 256)                                  if (tdata > -256 && tdata < 256)
1615                                          debug("%i", (int)tdata);                                          debug("%i", (int)tdata);
# Line 1393  int ppc_cpu_disassemble_instr(struct cpu Line 1619  int ppc_cpu_disassemble_instr(struct cpu
1619                  }                  }
1620                  debug(">");                  debug(">");
1621                  break;                  break;
1622            case PPC_HI6_59:
1623                    xo = (iword >> 1) & 1023;
1624                    /*  NOTE: Some floating point instructions only use the
1625                        lowest 5 bits of xo, some use all 10 bits!  */
1626                    switch (xo & 31) {
1627                    case PPC_59_FDIVS:
1628                    case PPC_59_FSUBS:
1629                    case PPC_59_FADDS:
1630                    case PPC_59_FMULS:
1631                    case PPC_59_FMADDS:
1632                            rt = (iword >> 21) & 31;
1633                            ra = (iword >> 16) & 31;
1634                            rb = (iword >> 11) & 31;
1635                            rs = (iword >>  6) & 31;        /*  actually frc  */
1636                            rc = iword & 1;
1637                            switch (xo & 31) {
1638                            case PPC_59_FDIVS:      mnem = "fdivs"; break;
1639                            case PPC_59_FSUBS:      mnem = "fsubs"; break;
1640                            case PPC_59_FADDS:      mnem = "fadds"; break;
1641                            case PPC_59_FMULS:      mnem = "fmuls"; break;
1642                            case PPC_59_FMADDS:     mnem = "fmadds"; break;
1643                            }
1644                            debug("%s%s\t", mnem, rc? "." : "");
1645                            switch (xo & 31) {
1646                            case PPC_59_FMULS:
1647                                    debug("f%i,f%i,f%i", rt, ra, rs);
1648                                    break;
1649                            case PPC_59_FMADDS:
1650                                    debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1651                                    break;
1652                            default:debug("f%i,f%i,f%i", rt, ra, rb);
1653                            }
1654                            break;
1655                    default:/*  TODO: similar to hi6_63  */
1656                            debug("unimplemented hi6_59, xo = 0x%x", xo);
1657                    }
1658                    break;
1659          case PPC_HI6_63:          case PPC_HI6_63:
1660                  xo = (iword >> 1) & 1023;                  xo = (iword >> 1) & 1023;
1661                  switch (xo) {                  /*  NOTE: Some floating point instructions only use the
1662                  case PPC_63_FMR:                      lowest 5 bits of xo, some use all 10 bits!  */
1663                    switch (xo & 31) {
1664                    case PPC_63_FDIV:
1665                    case PPC_63_FSUB:
1666                    case PPC_63_FADD:
1667                    case PPC_63_FMUL:
1668                    case PPC_63_FMSUB:
1669                    case PPC_63_FMADD:
1670                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1671                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1672                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
1673                            rs = (iword >>  6) & 31;        /*  actually frc  */
1674                            rc = iword & 1;
1675                            switch (xo & 31) {
1676                            case PPC_63_FDIV:
1677                                    mnem = power? "fd" : "fdiv"; break;
1678                            case PPC_63_FSUB:
1679                                    mnem = power? "fs" : "fsub"; break;
1680                            case PPC_63_FADD:
1681                                    mnem = power? "fa" : "fadd"; break;
1682                            case PPC_63_FMUL:
1683                                    mnem = power? "fm" : "fmul"; break;
1684                            case PPC_63_FMSUB:
1685                                    mnem = power? "fms" : "fmsub"; break;
1686                            case PPC_63_FMADD:
1687                                    mnem = power? "fma" : "fmadd"; break;
1688                            }
1689                            debug("%s%s\t", mnem, rc? "." : "");
1690                            switch (xo & 31) {
1691                            case PPC_63_FMUL:
1692                                    debug("f%i,f%i,f%i", rt, ra, rs);
1693                                    break;
1694                            case PPC_63_FMADD:
1695                                    debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1696                                    break;
1697                            default:debug("f%i,f%i,f%i", rt, ra, rb);
1698                            }
1699                            break;
1700                    default:rt = (iword >> 21) & 31;
1701                            ra = (iword >> 16) & 31;
1702                            rb = (iword >> 11) & 31;
1703                          rc = iword & 1;                          rc = iword & 1;
1704                          switch (xo) {                          switch (xo) {
1705                            case PPC_63_FCMPU:
1706                            case PPC_63_FRSP:
1707                            case PPC_63_FCTIWZ:
1708                            case PPC_63_FNEG:
1709                          case PPC_63_FMR:                          case PPC_63_FMR:
1710                                  debug("fmr%s\tf%i,f%i", rc? "." : "", rt, rb);                          case PPC_63_FNABS:
1711                            case PPC_63_FABS:
1712                                    switch (xo) {
1713                                    case PPC_63_FCMPU:      mnem = "fcmpu"; break;
1714                                    case PPC_63_FCTIWZ:
1715                                            mnem = power? "fcirz" : "fctiwz"; break;
1716                                    case PPC_63_FRSP:       mnem = "frsp"; break;
1717                                    case PPC_63_FNEG:       mnem = "fneg"; break;
1718                                    case PPC_63_FMR:        mnem = "fmr"; break;
1719                                    case PPC_63_FNABS:      mnem = "fnabs"; break;
1720                                    case PPC_63_FABS:       mnem = "fabs"; break;
1721                                    }
1722                                    debug("%s%s\t", mnem, rc? "." : "");
1723                                    switch (xo) {
1724                                    case PPC_63_FCMPU:
1725                                            debug("%i,f%i,f%i", rt >> 2, ra, rb);
1726                                            break;
1727                                    case PPC_63_FCTIWZ:
1728                                    case PPC_63_FRSP:
1729                                    case PPC_63_FNEG:
1730                                    case PPC_63_FMR:
1731                                    case PPC_63_FNABS:
1732                                    case PPC_63_FABS:
1733                                            debug("f%i,f%i", rt, rb);
1734                                            break;
1735                                    default:debug("f%i,f%i,f%i", rt, ra, rb);
1736                                    }
1737                                    break;
1738                            case PPC_63_MFFS:
1739                                    debug("mffs%s\tf%i", rc?".":"", rt);
1740                                    break;
1741                            case PPC_63_MTFSF:
1742                                    ra = (iword >> 17) & 255;       /*  flm  */
1743                                    debug("mtfsf%s\t0x%02x,f%i", rc?".":"", ra, rb);
1744                                  break;                                  break;
1745                            default:debug("unimplemented hi6_63, xo = 0x%x", xo);
1746                          }                          }
                         break;  
                 default:  
                         debug("unimplemented hi6_31, xo = 0x%x", xo);  
1747                  }                  }
1748                  break;                  break;
1749          default:          default:
# Line 1422  int ppc_cpu_disassemble_instr(struct cpu Line 1757  int ppc_cpu_disassemble_instr(struct cpu
1757    
1758    
1759  /*  /*
1760     *  debug_spr_usage():
1761     *
1762     *  Helper function. To speed up overall development speed of the emulator,
1763     *  all SPR accesses are allowed. This function causes unknown/unimplemented
1764     *  SPRs to give a warning.
1765     */
1766    static void debug_spr_usage(uint64_t pc, int spr)
1767    {
1768            static uint32_t spr_used[1024 / sizeof(uint32_t)];
1769            static int initialized = 0;
1770    
1771            if (!initialized) {
1772                    memset(spr_used, 0, sizeof(spr_used));
1773                    initialized = 1;
1774            }
1775    
1776            spr &= 1023;
1777            if (spr_used[spr >> 2] & (1 << (spr & 3)))
1778                    return;
1779    
1780            switch (spr) {
1781            /*  Known/implemented SPRs:  */
1782            case SPR_XER:
1783            case SPR_LR:
1784            case SPR_CTR:
1785            case SPR_DSISR:
1786            case SPR_DAR:
1787            case SPR_DEC:
1788            case SPR_SDR1:
1789            case SPR_SRR0:
1790            case SPR_SRR1:
1791            case SPR_SPRG0:
1792            case SPR_SPRG1:
1793            case SPR_SPRG2:
1794            case SPR_SPRG3:
1795            case SPR_PVR:
1796            case SPR_DMISS:
1797            case SPR_DCMP:
1798            case SPR_HASH1:
1799            case SPR_HASH2:
1800            case SPR_IMISS:
1801            case SPR_ICMP:
1802            case SPR_DBSR:
1803            case SPR_PIR:
1804                    break;
1805            default:if (spr >= SPR_IBAT0U && spr <= SPR_DBAT3L) {
1806                            break;
1807                    } else
1808                            fatal("[ using UNIMPLEMENTED spr %i (%s), pc = "
1809                                "0x%llx ]\n", spr, ppc_spr_names[spr] == NULL?
1810                                "UNKNOWN" : ppc_spr_names[spr], (long long)pc);
1811            }
1812    
1813            spr_used[spr >> 2] |= (1 << (spr & 3));
1814    }
1815    
1816    
1817    /*
1818   *  update_cr0():   *  update_cr0():
1819   *   *
1820   *  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 1840  void update_cr0(struct cpu *cpu, uint64_
1840          }          }
1841    
1842          /*  SO bit, copied from XER:  */          /*  SO bit, copied from XER:  */
1843          c |= ((cpu->cd.ppc.xer >> 31) & 1);          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
1844    
1845          cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);          cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1846          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.22

  ViewVC Help
Powered by ViewVC 1.1.26