/[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 46 by dpavlin, Wed Oct 10 21:07:01 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2007  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.72 2007/06/28 13:36:46 debug Exp $
29   *   *
30   *  PowerPC/POWER CPU emulation.   *  PowerPC/POWER CPU emulation.
31   */   */
# Line 37  Line 37 
37    
38  #include "cpu.h"  #include "cpu.h"
39  #include "devices.h"  #include "devices.h"
40    #include "interrupt.h"
41  #include "machine.h"  #include "machine.h"
42  #include "memory.h"  #include "memory.h"
43  #include "misc.h"  #include "misc.h"
44    #include "of.h"
45  #include "opcodes_ppc.h"  #include "opcodes_ppc.h"
46    #include "ppc_bat.h"
47    #include "ppc_pte.h"
48    #include "ppc_spr.h"
49    #include "ppc_spr_strings.h"
50    #include "settings.h"
51  #include "symbol.h"  #include "symbol.h"
52    #include "useremul.h"
53    
54    
55  #define DYNTRANS_DUALMODE_32  #define DYNTRANS_DUALMODE_32
56  #include "tmp_ppc_head.c"  #include "tmp_ppc_head.c"
57    
58    
59    void ppc_pc_to_pointers(struct cpu *);
60    void ppc32_pc_to_pointers(struct cpu *);
61    
62    void ppc_irq_interrupt_assert(struct interrupt *interrupt);
63    void ppc_irq_interrupt_deassert(struct interrupt *interrupt);
64    
65    
66  /*  /*
67   *  ppc_cpu_new():   *  ppc_cpu_new():
68   *   *
# Line 77  int ppc_cpu_new(struct cpu *cpu, struct Line 93  int ppc_cpu_new(struct cpu *cpu, struct
93    
94          cpu->memory_rw = ppc_memory_rw;          cpu->memory_rw = ppc_memory_rw;
95    
96          cpu->cd.ppc.cpu_type    = cpu_type_defs[found];          cpu->cd.ppc.cpu_type = cpu_type_defs[found];
97          cpu->name               = cpu->cd.ppc.cpu_type.name;          cpu->name            = cpu->cd.ppc.cpu_type.name;
98          cpu->byte_order         = EMUL_BIG_ENDIAN;          cpu->byte_order      = EMUL_BIG_ENDIAN;
99          cpu->cd.ppc.mode        = MODE_PPC;     /*  TODO  */          cpu->cd.ppc.mode     = MODE_PPC;        /*  TODO  */
100    
101          /*  Current operating mode:  */          /*  Current operating mode:  */
102          cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;          cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;
103          cpu->cd.ppc.pvr = cpu->cd.ppc.cpu_type.pvr;          cpu->cd.ppc.spr[SPR_PVR] = cpu->cd.ppc.cpu_type.pvr;
104    
105            /*  cpu->cd.ppc.msr = PPC_MSR_IR | PPC_MSR_DR |
106                PPC_MSR_SF | PPC_MSR_FP;  */
107    
108            cpu->cd.ppc.spr[SPR_IBAT0U] = 0x00001ffc | BAT_Vs;
109            cpu->cd.ppc.spr[SPR_IBAT0L] = 0x00000000 | BAT_PP_RW;
110            cpu->cd.ppc.spr[SPR_IBAT1U] = 0xc0001ffc | BAT_Vs;
111            cpu->cd.ppc.spr[SPR_IBAT1L] = 0x00000000 | BAT_PP_RW;
112            cpu->cd.ppc.spr[SPR_IBAT3U] = 0xf0001ffc | BAT_Vs;
113            cpu->cd.ppc.spr[SPR_IBAT3L] = 0xf0000000 | BAT_PP_RW;
114            cpu->cd.ppc.spr[SPR_DBAT0U] = 0x00001ffc | BAT_Vs;
115            cpu->cd.ppc.spr[SPR_DBAT0L] = 0x00000000 | BAT_PP_RW;
116            cpu->cd.ppc.spr[SPR_DBAT1U] = 0xc0001ffc | BAT_Vs;
117            cpu->cd.ppc.spr[SPR_DBAT1L] = 0x00000000 | BAT_PP_RW;
118            cpu->cd.ppc.spr[SPR_DBAT2U] = 0xe0001ffc | BAT_Vs;
119            cpu->cd.ppc.spr[SPR_DBAT2L] = 0xe0000000 | BAT_PP_RW;
120            cpu->cd.ppc.spr[SPR_DBAT3U] = 0xf0001ffc | BAT_Vs;
121            cpu->cd.ppc.spr[SPR_DBAT3L] = 0xf0000000 | BAT_PP_RW;
122    
123          cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;          cpu->is_32bit = (cpu->cd.ppc.bits == 32)? 1 : 0;
124    
125          if (cpu->is_32bit) {          if (cpu->is_32bit) {
126                    cpu->run_instr = ppc32_run_instr;
127                  cpu->update_translation_table = ppc32_update_translation_table;                  cpu->update_translation_table = ppc32_update_translation_table;
128                  cpu->invalidate_translation_caches =                  cpu->invalidate_translation_caches =
129                      ppc32_invalidate_translation_caches;                      ppc32_invalidate_translation_caches;
130                  cpu->invalidate_code_translation =                  cpu->invalidate_code_translation =
131                      ppc32_invalidate_code_translation;                      ppc32_invalidate_code_translation;
132          } else {          } else {
133                    cpu->run_instr = ppc_run_instr;
134                  cpu->update_translation_table = ppc_update_translation_table;                  cpu->update_translation_table = ppc_update_translation_table;
135                  cpu->invalidate_translation_caches =                  cpu->invalidate_translation_caches =
136                      ppc_invalidate_translation_caches;                      ppc_invalidate_translation_caches;
# Line 102  int ppc_cpu_new(struct cpu *cpu, struct Line 138  int ppc_cpu_new(struct cpu *cpu, struct
138                      ppc_invalidate_code_translation;                      ppc_invalidate_code_translation;
139          }          }
140    
141          cpu->translate_address = ppc_translate_address;          cpu->translate_v2p = ppc_translate_v2p;
142    
143          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */
144          if (cpu_id == 0) {          if (cpu_id == 0) {
# Line 128  int ppc_cpu_new(struct cpu *cpu, struct Line 164  int ppc_cpu_new(struct cpu *cpu, struct
164                  }                  }
165          }          }
166    
167          cpu->cd.ppc.pir = cpu_id;          cpu->cd.ppc.spr[SPR_PIR] = cpu_id;
168    
169          /*  Some default stack pointer value.  TODO: move this?  */          /*  Some default stack pointer value.  TODO: move this?  */
170          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 139  int ppc_cpu_new(struct cpu *cpu, struct Line 175  int ppc_cpu_new(struct cpu *cpu, struct
175          if (cpu->machine->prom_emulation)          if (cpu->machine->prom_emulation)
176                  cpu->cd.ppc.of_emul_addr = 0xfff00000;                  cpu->cd.ppc.of_emul_addr = 0xfff00000;
177    
178            /*  Add all register names to the settings:  */
179            CPU_SETTINGS_ADD_REGISTER64("pc", cpu->pc);
180            CPU_SETTINGS_ADD_REGISTER64("msr", cpu->cd.ppc.msr);
181            CPU_SETTINGS_ADD_REGISTER64("ctr", cpu->cd.ppc.spr[SPR_CTR]);
182            CPU_SETTINGS_ADD_REGISTER64("xer", cpu->cd.ppc.spr[SPR_XER]);
183            CPU_SETTINGS_ADD_REGISTER64("dec", cpu->cd.ppc.spr[SPR_DEC]);
184            CPU_SETTINGS_ADD_REGISTER64("hdec", cpu->cd.ppc.spr[SPR_HDEC]);
185            CPU_SETTINGS_ADD_REGISTER64("srr0", cpu->cd.ppc.spr[SPR_SRR0]);
186            CPU_SETTINGS_ADD_REGISTER64("srr1", cpu->cd.ppc.spr[SPR_SRR1]);
187            CPU_SETTINGS_ADD_REGISTER64("sdr1", cpu->cd.ppc.spr[SPR_SDR1]);
188            CPU_SETTINGS_ADD_REGISTER64("ibat0u", cpu->cd.ppc.spr[SPR_IBAT0U]);
189            CPU_SETTINGS_ADD_REGISTER64("ibat0l", cpu->cd.ppc.spr[SPR_IBAT0L]);
190            CPU_SETTINGS_ADD_REGISTER64("ibat1u", cpu->cd.ppc.spr[SPR_IBAT1U]);
191            CPU_SETTINGS_ADD_REGISTER64("ibat1l", cpu->cd.ppc.spr[SPR_IBAT1L]);
192            CPU_SETTINGS_ADD_REGISTER64("ibat2u", cpu->cd.ppc.spr[SPR_IBAT2U]);
193            CPU_SETTINGS_ADD_REGISTER64("ibat2l", cpu->cd.ppc.spr[SPR_IBAT2L]);
194            CPU_SETTINGS_ADD_REGISTER64("ibat3u", cpu->cd.ppc.spr[SPR_IBAT3U]);
195            CPU_SETTINGS_ADD_REGISTER64("ibat3l", cpu->cd.ppc.spr[SPR_IBAT3L]);
196            CPU_SETTINGS_ADD_REGISTER64("dbat0u", cpu->cd.ppc.spr[SPR_DBAT0U]);
197            CPU_SETTINGS_ADD_REGISTER64("dbat0l", cpu->cd.ppc.spr[SPR_DBAT0L]);
198            CPU_SETTINGS_ADD_REGISTER64("dbat1u", cpu->cd.ppc.spr[SPR_DBAT1U]);
199            CPU_SETTINGS_ADD_REGISTER64("dbat1l", cpu->cd.ppc.spr[SPR_DBAT1L]);
200            CPU_SETTINGS_ADD_REGISTER64("dbat2u", cpu->cd.ppc.spr[SPR_DBAT2U]);
201            CPU_SETTINGS_ADD_REGISTER64("dbat2l", cpu->cd.ppc.spr[SPR_DBAT2L]);
202            CPU_SETTINGS_ADD_REGISTER64("dbat3u", cpu->cd.ppc.spr[SPR_DBAT3U]);
203            CPU_SETTINGS_ADD_REGISTER64("dbat3l", cpu->cd.ppc.spr[SPR_DBAT3L]);
204            CPU_SETTINGS_ADD_REGISTER64("lr", cpu->cd.ppc.spr[SPR_LR]);
205            CPU_SETTINGS_ADD_REGISTER32("cr", cpu->cd.ppc.cr);
206            CPU_SETTINGS_ADD_REGISTER32("fpscr", cpu->cd.ppc.fpscr);
207            /*  Integer GPRs, floating point registers, and segment registers:  */
208            for (i=0; i<PPC_NGPRS; i++) {
209                    char tmpstr[5];
210                    snprintf(tmpstr, sizeof(tmpstr), "r%i", i);
211                    CPU_SETTINGS_ADD_REGISTER64(tmpstr, cpu->cd.ppc.gpr[i]);
212            }
213            for (i=0; i<PPC_NFPRS; i++) {
214                    char tmpstr[5];
215                    snprintf(tmpstr, sizeof(tmpstr), "f%i", i);
216                    CPU_SETTINGS_ADD_REGISTER64(tmpstr, cpu->cd.ppc.fpr[i]);
217            }
218            for (i=0; i<16; i++) {
219                    char tmpstr[5];
220                    snprintf(tmpstr, sizeof(tmpstr), "sr%i", i);
221                    CPU_SETTINGS_ADD_REGISTER32(tmpstr, cpu->cd.ppc.sr[i]);
222            }
223    
224            /*  Register the CPU as an interrupt handler:  */
225            {
226                    struct interrupt template;
227                    char name[150];
228                    snprintf(name, sizeof(name), "%s", cpu->path);
229                    memset(&template, 0, sizeof(template));
230                    template.line = 0;
231                    template.name = name;
232                    template.extra = cpu;
233                    template.interrupt_assert = ppc_irq_interrupt_assert;
234                    template.interrupt_deassert = ppc_irq_interrupt_deassert;
235                    interrupt_handler_register(&template);
236            }
237    
238          return 1;          return 1;
239  }  }
240    
# Line 203  void ppc_cpu_dumpinfo(struct cpu *cpu) Line 299  void ppc_cpu_dumpinfo(struct cpu *cpu)
299  /*  /*
300   *  reg_access_msr():   *  reg_access_msr():
301   */   */
302  void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag)  void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag,
303            int check_for_interrupts)
304  {  {
305            uint64_t old = cpu->cd.ppc.msr;
306    
307          if (valuep == NULL) {          if (valuep == NULL) {
308                  fatal("reg_access_msr(): NULL\n");                  fatal("reg_access_msr(): NULL\n");
309                  return;                  return;
310          }          }
311    
312          if (writeflag)          if (writeflag) {
313                  cpu->cd.ppc.msr = *valuep;                  cpu->cd.ppc.msr = *valuep;
314    
315                    /*  Switching between temporary and real gpr 0..3?  */
316                    if ((old & PPC_MSR_TGPR) != (cpu->cd.ppc.msr & PPC_MSR_TGPR)) {
317                            int i;
318                            for (i=0; i<PPC_N_TGPRS; i++) {
319                                    uint64_t t = cpu->cd.ppc.gpr[i];
320                                    cpu->cd.ppc.gpr[i] = cpu->cd.ppc.tgpr[i];
321                                    cpu->cd.ppc.tgpr[i] = t;
322                            }
323                    }
324    
325                    if (cpu->cd.ppc.msr & PPC_MSR_IP) {
326                            fatal("\n[ Reboot hack for NetBSD/prep. TODO: "
327                                "fix this. ]\n");
328                            cpu->running = 0;
329                    }
330            }
331    
332          /*  TODO: Is the little-endian bit writable?  */          /*  TODO: Is the little-endian bit writable?  */
333    
334          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 337  void reg_access_msr(struct cpu *cpu, uin
337    
338          if (!writeflag)          if (!writeflag)
339                  *valuep = cpu->cd.ppc.msr;                  *valuep = cpu->cd.ppc.msr;
340    
341            if (check_for_interrupts && cpu->cd.ppc.msr & PPC_MSR_EE) {
342                    if (cpu->cd.ppc.dec_intr_pending &&
343                        !(cpu->cd.ppc.cpu_type.flags & PPC_NO_DEC)) {
344                            ppc_exception(cpu, PPC_EXCEPTION_DEC);
345                            cpu->cd.ppc.dec_intr_pending = 0;
346                    } else if (cpu->cd.ppc.irq_asserted)
347                            ppc_exception(cpu, PPC_EXCEPTION_EI);
348            }
349    }
350    
351    
352    /*
353     *  ppc_exception():
354     */
355    void ppc_exception(struct cpu *cpu, int exception_nr)
356    {
357            /*  Save PC and MSR:  */
358            cpu->cd.ppc.spr[SPR_SRR0] = cpu->pc;
359    
360            if (exception_nr >= 0x10 && exception_nr <= 0x13)
361                    cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0xffff)
362                        | (cpu->cd.ppc.cr & 0xf0000000);
363            else
364                    cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);
365    
366            if (!quiet_mode)
367                    fatal("[ PPC Exception 0x%x; pc=0x%"PRIx64" ]\n",
368                        exception_nr, cpu->pc);
369    
370            /*  Disable External Interrupts, Recoverable Interrupt Mode,
371                and go to Supervisor mode  */
372            cpu->cd.ppc.msr &= ~(PPC_MSR_EE | PPC_MSR_RI | PPC_MSR_PR);
373    
374            cpu->pc = exception_nr * 0x100;
375            if (cpu->cd.ppc.msr & PPC_MSR_IP)
376                    cpu->pc += 0xfff00000ULL;
377    
378            if (cpu->is_32bit)
379                    ppc32_pc_to_pointers(cpu);
380            else
381                    ppc_pc_to_pointers(cpu);
382  }  }
383    
384    
# Line 246  void ppc_cpu_register_dump(struct cpu *c Line 404  void ppc_cpu_register_dump(struct cpu *c
404    
405                  debug("cpu%i: pc  = 0x", x);                  debug("cpu%i: pc  = 0x", x);
406                  if (bits32)                  if (bits32)
407                          debug("%08x", (int)cpu->pc);                          debug("%08"PRIx32, (uint32_t)cpu->pc);
408                  else                  else
409                          debug("%016llx", (long long)cpu->pc);                          debug("%016"PRIx64, (uint64_t)cpu->pc);
410                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
411    
412                  debug("cpu%i: lr  = 0x", x);                  debug("cpu%i: lr  = 0x", x);
413                  if (bits32)                  if (bits32)
414                          debug("%08x", (int)cpu->cd.ppc.lr);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_LR]);
415                  else                  else
416                          debug("%016llx", (long long)cpu->cd.ppc.lr);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_LR]);
417                  debug("  cr  = 0x%08x\n", (int)cpu->cd.ppc.cr);                  debug("  cr  = 0x%08"PRIx32, (uint32_t)cpu->cd.ppc.cr);
418    
                 debug("cpu%i: ctr = 0x", x);  
419                  if (bits32)                  if (bits32)
420                          debug("%08x", (int)cpu->cd.ppc.ctr);                          debug("  ");
421                  else                  else
422                          debug("%016llx", (long long)cpu->cd.ppc.ctr);                          debug("\ncpu%i: ", x);
423                    debug("ctr = 0x", x);
424                    if (bits32)
425                            debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_CTR]);
426                    else
427                            debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_CTR]);
428    
429                  debug("  xer = 0x", x);                  debug("  xer = 0x", x);
430                  if (bits32)                  if (bits32)
431                          debug("%08x\n", (int)cpu->cd.ppc.xer);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_XER]);
432                  else                  else
433                          debug("%016llx\n", (long long)cpu->cd.ppc.xer);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_XER]);
434    
435                    debug("\n");
436    
437                  if (bits32) {                  if (bits32) {
438                          /*  32-bit:  */                          /*  32-bit:  */
439                          for (i=0; i<PPC_NGPRS; i++) {                          for (i=0; i<PPC_NGPRS; i++) {
440                                  if ((i % 4) == 0)                                  if ((i % 4) == 0)
441                                          debug("cpu%i:", x);                                          debug("cpu%i:", x);
442                                  debug(" r%02i = 0x%08x ", i,                                  debug(" r%02i = 0x%08"PRIx32" ", i,
443                                      (int)cpu->cd.ppc.gpr[i]);                                      (uint32_t) cpu->cd.ppc.gpr[i]);
444                                  if ((i % 4) == 3)                                  if ((i % 4) == 3)
445                                          debug("\n");                                          debug("\n");
446                          }                          }
# Line 286  void ppc_cpu_register_dump(struct cpu *c Line 450  void ppc_cpu_register_dump(struct cpu *c
450                                  int r = (i >> 1) + ((i & 1) << 4);                                  int r = (i >> 1) + ((i & 1) << 4);
451                                  if ((i % 2) == 0)                                  if ((i % 2) == 0)
452                                          debug("cpu%i:", x);                                          debug("cpu%i:", x);
453                                  debug(" r%02i = 0x%016llx ", r,                                  debug(" r%02i = 0x%016"PRIx64" ", r,
454                                      (long long)cpu->cd.ppc.gpr[r]);                                      (uint64_t) cpu->cd.ppc.gpr[r]);
455                                  if ((i % 2) == 1)                                  if ((i % 2) == 1)
456                                          debug("\n");                                          debug("\n");
457                          }                          }
458                  }                  }
459    
460                  /*  Other special registers:  */                  /*  Other special registers:  */
461                  debug("cpu%i: srr0 = 0x%016llx  srr1 = 0x%016llx\n", x,                  if (bits32) {
462                      (long long)cpu->cd.ppc.srr0, (long long)cpu->cd.ppc.srr1);                          debug("cpu%i: srr0 = 0x%08"PRIx32
463                  reg_access_msr(cpu, &tmp, 0);                              " srr1 = 0x%08"PRIx32"\n", x,
464                  debug("cpu%i: msr = 0x%016llx  ", x, (long long)tmp);                              (uint32_t) cpu->cd.ppc.spr[SPR_SRR0],
465                  debug("tb  = 0x%08x%08x\n",                              (uint32_t) cpu->cd.ppc.spr[SPR_SRR1]);
466                      (int)cpu->cd.ppc.tbu, (int)cpu->cd.ppc.tbl);                  } else {
467                  debug("cpu%i: dec = 0x%08x  hdec = 0x%08x\n",                          debug("cpu%i: srr0 = 0x%016"PRIx64
468                      x, (int)cpu->cd.ppc.dec, (int)cpu->cd.ppc.hdec);                              "  srr1 = 0x%016"PRIx64"\n", x,
469                                (uint64_t) cpu->cd.ppc.spr[SPR_SRR0],
470                                (uint64_t) cpu->cd.ppc.spr[SPR_SRR1]);
471                    }
472    
473                    debug("cpu%i: msr = ", x);
474                    reg_access_msr(cpu, &tmp, 0, 0);
475                    if (bits32)
476                            debug("0x%08"PRIx32, (uint32_t) tmp);
477                    else
478                            debug("0x%016"PRIx64, (uint64_t) tmp);
479    
480                    debug("  tb  = 0x%08"PRIx32"%08"PRIx32"\n",
481                        (uint32_t) cpu->cd.ppc.spr[SPR_TBU],
482                        (uint32_t) cpu->cd.ppc.spr[SPR_TBL]);
483    
484                    debug("cpu%i: dec = 0x%08"PRIx32,
485                        x, (uint32_t) cpu->cd.ppc.spr[SPR_DEC]);
486                    if (!bits32)
487                            debug("  hdec = 0x%08"PRIx32"\n",
488                                (uint32_t) cpu->cd.ppc.spr[SPR_HDEC]);
489    
490                    debug("\n");
491          }          }
492    
493          if (coprocs & 1) {          if (coprocs & 1) {
494                  debug("cpu%i: fpscr = 0x%08x\n", x, (int)cpu->cd.ppc.fpscr);                  debug("cpu%i: fpscr = 0x%08"PRIx32"\n",
495                        x, (uint32_t) cpu->cd.ppc.fpscr);
496    
497                  /*  TODO: show floating-point values :-)  */                  /*  TODO: show floating-point values :-)  */
498    
# Line 314  void ppc_cpu_register_dump(struct cpu *c Line 501  void ppc_cpu_register_dump(struct cpu *c
501                  for (i=0; i<PPC_NFPRS; i++) {                  for (i=0; i<PPC_NFPRS; i++) {
502                          if ((i % 2) == 0)                          if ((i % 2) == 0)
503                                  debug("cpu%i:", x);                                  debug("cpu%i:", x);
504                          debug(" f%02i = 0x%016llx ", i,                          debug(" f%02i = 0x%016"PRIx64" ", i,
505                              (long long)cpu->cd.ppc.fpr[i]);                              (uint64_t) cpu->cd.ppc.fpr[i]);
506                          if ((i % 2) == 1)                          if ((i % 2) == 1)
507                                  debug("\n");                                  debug("\n");
508                  }                  }
509          }          }
510    
511          if (coprocs & 2) {          if (coprocs & 2) {
512                  debug("cpu%i:  sdr1 = 0x%llx\n", x,                  debug("cpu%i:  sdr1 = 0x%"PRIx64"\n", x,
513                      (long long)cpu->cd.ppc.sdr1);                      (uint64_t) cpu->cd.ppc.spr[SPR_SDR1]);
514                  for (i=0; i<4; i++)                  if (cpu->cd.ppc.cpu_type.flags & PPC_601)
515                          debug("cpu%i:  ibat%iu = 0x%08x  ibat%il = 0x%08x\n",                          debug("cpu%i:  PPC601-style, TODO!\n");
516                              x, i, cpu->cd.ppc.ibat_u[i],                  else {
517                              i, cpu->cd.ppc.ibat_l[i]);                          for (i=0; i<8; i++) {
518                  for (i=0; i<4; i++)                                  int spr = SPR_IBAT0U + i*2;
519                          debug("cpu%i:  dbat%iu = 0x%08x  dbat%il = 0x%08x\n",                                  uint32_t upper = cpu->cd.ppc.spr[spr];
520                              x, i, cpu->cd.ppc.dbat_u[i],                                  uint32_t lower = cpu->cd.ppc.spr[spr+1];
521                              i, cpu->cd.ppc.dbat_l[i]);                                  uint32_t len = (((upper & BAT_BL) << 15)
522                                        | 0x1ffff) + 1;
523                                    debug("cpu%i:  %sbat%i: u=0x%08"PRIx32
524                                        " l=0x%08"PRIx32" ",
525                                        x, i<4? "i" : "d", i&3, upper, lower);
526                                    if (!(upper & BAT_V)) {
527                                            debug(" (not valid)\n");
528                                            continue;
529                                    }
530                                    if (len < 1048576)
531                                            debug(" (%i KB, ", len >> 10);
532                                    else
533                                            debug(" (%i MB, ", len >> 20);
534                                    if (upper & BAT_Vu)
535                                            debug("user, ");
536                                    if (upper & BAT_Vs)
537                                            debug("supervisor, ");
538                                    if (lower & (BAT_W | BAT_I | BAT_M | BAT_G))
539                                            debug("%s%s%s%s, ",
540                                                lower & BAT_W? "W" : "",
541                                                lower & BAT_I? "I" : "",
542                                                lower & BAT_M? "M" : "",
543                                                lower & BAT_G? "G" : "");
544                                    switch (lower & BAT_PP) {
545                                    case BAT_PP_NONE: debug("NO access"); break;
546                                    case BAT_PP_RO_S: debug("read-only, soft");
547                                                      break;
548                                    case BAT_PP_RO:   debug("read-only"); break;
549                                    case BAT_PP_RW:   debug("read/write"); break;
550                                    }
551                                    debug(")\n");
552                            }
553                    }
554          }          }
 }  
   
   
 /*  
  *  ppc_cpu_register_match():  
  */  
 void ppc_cpu_register_match(struct machine *m, char *name,  
         int writeflag, uint64_t *valuep, int *match_register)  
 {  
         int cpunr = 0;  
   
         /*  CPU number:  */  
   
         /*  TODO  */  
555    
556          /*  Register name:  */          if (coprocs & 4) {
557          if (strcasecmp(name, "pc") == 0) {                  for (i=0; i<16; i++) {
558                  if (writeflag) {                          uint32_t s = cpu->cd.ppc.sr[i];
559                          m->cpus[cpunr]->pc = *valuep;  
560                  } else                          debug("cpu%i:", x);
561                          *valuep = m->cpus[cpunr]->pc;                          debug("  sr%-2i = 0x%08"PRIx32, i, s);
562                  *match_register = 1;  
563          } else if (strcasecmp(name, "msr") == 0) {                          s &= (SR_TYPE | SR_SUKEY | SR_PRKEY | SR_NOEXEC);
564                  if (writeflag)                          if (s != 0) {
565                          m->cpus[cpunr]->cd.ppc.msr = *valuep;                                  debug("  (");
566                  else                                  if (s & SR_TYPE) {
567                          *valuep = m->cpus[cpunr]->cd.ppc.msr;                                          debug("NON-memory type");
568                  *match_register = 1;                                          s &= ~SR_TYPE;
569          } else if (strcasecmp(name, "lr") == 0) {                                          if (s != 0)
570                  if (writeflag)                                                  debug(", ");
571                          m->cpus[cpunr]->cd.ppc.lr = *valuep;                                  }
572                  else                                  if (s & SR_SUKEY) {
573                          *valuep = m->cpus[cpunr]->cd.ppc.lr;                                          debug("supervisor-key");
574                  *match_register = 1;                                          s &= ~SR_SUKEY;
575          } else if (strcasecmp(name, "cr") == 0) {                                          if (s != 0)
576                  if (writeflag)                                                  debug(", ");
577                          m->cpus[cpunr]->cd.ppc.cr = *valuep;                                  }
578                  else                                  if (s & SR_PRKEY) {
579                          *valuep = m->cpus[cpunr]->cd.ppc.cr;                                          debug("user-key");
580                  *match_register = 1;                                          s &= ~SR_PRKEY;
581          } else if (strcasecmp(name, "dec") == 0) {                                          if (s != 0)
582                  if (writeflag)                                                  debug(", ");
583                          m->cpus[cpunr]->cd.ppc.dec = *valuep;                                  }
584                  else                                  if (s & SR_NOEXEC)
585                          *valuep = m->cpus[cpunr]->cd.ppc.dec;                                          debug("NOEXEC");
586                  *match_register = 1;                                  debug(")");
587          } else if (strcasecmp(name, "hdec") == 0) {                          }
588                  if (writeflag)                          debug("\n");
                         m->cpus[cpunr]->cd.ppc.hdec = *valuep;  
                 else  
                         *valuep = m->cpus[cpunr]->cd.ppc.hdec;  
                 *match_register = 1;  
         } else if (strcasecmp(name, "ctr") == 0) {  
                 if (writeflag)  
                         m->cpus[cpunr]->cd.ppc.ctr = *valuep;  
                 else  
                         *valuep = m->cpus[cpunr]->cd.ppc.ctr;  
                 *match_register = 1;  
         } else if (name[0] == 'r' && isdigit((int)name[1])) {  
                 int nr = atoi(name + 1);  
                 if (nr >= 0 && nr < PPC_NGPRS) {  
                         if (writeflag) {  
                                 m->cpus[cpunr]->cd.ppc.gpr[nr] = *valuep;  
                         } else  
                                 *valuep = m->cpus[cpunr]->cd.ppc.gpr[nr];  
                         *match_register = 1;  
                 }  
         } else if (strcasecmp(name, "xer") == 0) {  
                 if (writeflag)  
                         m->cpus[cpunr]->cd.ppc.xer = *valuep;  
                 else  
                         *valuep = m->cpus[cpunr]->cd.ppc.xer;  
                 *match_register = 1;  
         } else if (strcasecmp(name, "fpscr") == 0) {  
                 if (writeflag)  
                         m->cpus[cpunr]->cd.ppc.fpscr = *valuep;  
                 else  
                         *valuep = m->cpus[cpunr]->cd.ppc.fpscr;  
                 *match_register = 1;  
         } else if (name[0] == 'f' && isdigit((int)name[1])) {  
                 int nr = atoi(name + 1);  
                 if (nr >= 0 && nr < PPC_NFPRS) {  
                         if (writeflag) {  
                                 m->cpus[cpunr]->cd.ppc.fpr[nr] = *valuep;  
                         } else  
                                 *valuep = m->cpus[cpunr]->cd.ppc.fpr[nr];  
                         *match_register = 1;  
589                  }                  }
590          }          }
591  }  }
592    
593    
594  /*  /*
  *  ppc_cpu_show_full_statistics():  
  *  
  *  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");  
 }  
   
   
 /*  
595   *  ppc_cpu_tlbdump():   *  ppc_cpu_tlbdump():
596   *   *
597   *  Called from the debugger to dump the TLB in a readable format.   *  Not currently used for PPC.
  *  x is the cpu number to dump, or -1 to dump all CPUs.  
  *  
  *  If rawflag is nonzero, then the TLB contents isn't formated nicely,  
  *  just dumped.  
598   */   */
599  void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)  void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)
600  {  {
         fatal("ppc_cpu_tlbdump(): TODO\n");  
601  }  }
602    
603    
604  /*  /*
605   *  ppc_cpu_interrupt():   *  ppc_irq_interrupt_assert():
606   */   */
607  int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  void ppc_irq_interrupt_assert(struct interrupt *interrupt)
608  {  {
609          fatal("ppc_cpu_interrupt(): TODO\n");          struct cpu *cpu = (struct cpu *) interrupt->extra;
610          return 0;          cpu->cd.ppc.irq_asserted = 1;
611  }  }
612    
613    
614  /*  /*
615   *  ppc_cpu_interrupt_ack():   *  ppc_irq_interrupt_deassert():
616   */   */
617  int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  void ppc_irq_interrupt_deassert(struct interrupt *interrupt)
618  {  {
619          /*  fatal("ppc_cpu_interrupt_ack(): TODO\n");  */          struct cpu *cpu = (struct cpu *) interrupt->extra;
620          return 0;          cpu->cd.ppc.irq_asserted = 0;
621  }  }
622    
623    
# Line 484  int ppc_cpu_interrupt_ack(struct cpu *cp Line 634  int ppc_cpu_interrupt_ack(struct cpu *cp
634   *  cpu->pc for relative addresses.   *  cpu->pc for relative addresses.
635   */   */
636  int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,  int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
637          int running, uint64_t dumpaddr, int bintrans)          int running, uint64_t dumpaddr)
638  {  {
639          int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;          int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;
640          int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;          int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;
# Line 506  int ppc_cpu_disassemble_instr(struct cpu Line 656  int ppc_cpu_disassemble_instr(struct cpu
656                  debug("cpu%i: ", cpu->cpu_id);                  debug("cpu%i: ", cpu->cpu_id);
657    
658          if (cpu->cd.ppc.bits == 32)          if (cpu->cd.ppc.bits == 32)
659                  debug("%08x", (int)dumpaddr);                  debug("%08"PRIx32, (uint32_t) dumpaddr);
660          else          else
661                  debug("%016llx", (long long)dumpaddr);                  debug("%016"PRIx64, (uint64_t) dumpaddr);
662    
663          /*  NOTE: Fixed to big-endian.  */          /*  NOTE: Fixed to big-endian.  */
664          iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)          iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
665              + instr[3];              + instr[3];
666    
667          debug(": %08x\t", iword);          debug(": %08"PRIx32"\t", iword);
668    
669          /*          /*
670           *  Decode the instruction:           *  Decode the instruction:
# Line 523  int ppc_cpu_disassemble_instr(struct cpu Line 673  int ppc_cpu_disassemble_instr(struct cpu
673          hi6 = iword >> 26;          hi6 = iword >> 26;
674    
675          switch (hi6) {          switch (hi6) {
676            case 0x4:
677                    debug("ALTIVEC TODO");
678                    /*  vxor etc  */
679                    break;
680          case PPC_HI6_MULLI:          case PPC_HI6_MULLI:
681          case PPC_HI6_SUBFIC:          case PPC_HI6_SUBFIC:
682                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
# Line 611  int ppc_cpu_disassemble_instr(struct cpu Line 765  int ppc_cpu_disassemble_instr(struct cpu
765                  if (cpu->cd.ppc.bits == 32)                  if (cpu->cd.ppc.bits == 32)
766                          addr &= 0xffffffff;                          addr &= 0xffffffff;
767                  if (cpu->cd.ppc.bits == 32)                  if (cpu->cd.ppc.bits == 32)
768                          debug("0x%x", (int)addr);                          debug("0x%"PRIx32, (uint32_t) addr);
769                  else                  else
770                          debug("0x%llx", (long long)addr);                          debug("0x%"PRIx64, (uint64_t) addr);
771                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
772                      addr, &offset);                      addr, &offset);
773                  if (symbol != NULL)                  if (symbol != NULL)
# Line 644  int ppc_cpu_disassemble_instr(struct cpu Line 798  int ppc_cpu_disassemble_instr(struct cpu
798                  if (cpu->cd.ppc.bits == 32)                  if (cpu->cd.ppc.bits == 32)
799                          addr &= 0xffffffff;                          addr &= 0xffffffff;
800                  if (cpu->cd.ppc.bits == 32)                  if (cpu->cd.ppc.bits == 32)
801                          debug("\t0x%x", (int)addr);                          debug("\t0x%"PRIx32, (uint32_t) addr);
802                  else                  else
803                          debug("\t0x%llx", (long long)addr);                          debug("\t0x%"PRIx64, (uint64_t) addr);
804                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
805                      addr, &offset);                      addr, &offset);
806                  if (symbol != NULL)                  if (symbol != NULL)
# Line 715  int ppc_cpu_disassemble_instr(struct cpu Line 869  int ppc_cpu_disassemble_instr(struct cpu
869                          debug("unimplemented hi6_19, xo = 0x%x", xo);                          debug("unimplemented hi6_19, xo = 0x%x", xo);
870                  }                  }
871                  break;                  break;
872            case PPC_HI6_RLWNM:
873          case PPC_HI6_RLWIMI:          case PPC_HI6_RLWIMI:
874          case PPC_HI6_RLWINM:          case PPC_HI6_RLWINM:
875                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
876                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
877                  sh = (iword >> 11) & 31;                  sh = (iword >> 11) & 31;        /*  actually rb for rlwnm  */
878                  mb = (iword >> 6) & 31;                  mb = (iword >> 6) & 31;
879                  me = (iword >> 1) & 31;                  me = (iword >> 1) & 31;
880                  rc = iword & 1;                  rc = iword & 1;
881                  switch (hi6) {                  switch (hi6) {
882                    case PPC_HI6_RLWNM:
883                            mnem = power? "rlnm" : "rlwnm"; break;
884                  case PPC_HI6_RLWIMI:                  case PPC_HI6_RLWIMI:
885                          mnem = power? "rlimi" : "rlwimi"; break;                          mnem = power? "rlimi" : "rlwimi"; break;
886                  case PPC_HI6_RLWINM:                  case PPC_HI6_RLWINM:
887                          mnem = power? "rlinm" : "rlwinm"; break;                          mnem = power? "rlinm" : "rlwinm"; break;
888                  }                  }
889                  debug("%s%s\tr%i,r%i,%i,%i,%i",                  debug("%s%s\tr%i,r%i,%s%i,%i,%i",
890                      mnem, rc?".":"", ra, rs, sh, mb, me);                      mnem, rc?".":"", ra, rs,
891                        hi6 == PPC_HI6_RLWNM? "r" : "",
892                        sh, mb, me);
893                  break;                  break;
894          case PPC_HI6_ORI:          case PPC_HI6_ORI:
895          case PPC_HI6_ORIS:          case PPC_HI6_ORIS:
# Line 769  int ppc_cpu_disassemble_instr(struct cpu Line 928  int ppc_cpu_disassemble_instr(struct cpu
928          case PPC_HI6_30:          case PPC_HI6_30:
929                  xo = (iword >> 2) & 7;                  xo = (iword >> 2) & 7;
930                  switch (xo) {                  switch (xo) {
931                    case PPC_30_RLDICL:
932                  case PPC_30_RLDICR:                  case PPC_30_RLDICR:
933                    case PPC_30_RLDIMI:     /*  mb, not me  */
934                            mnem = NULL;
935                            switch (xo) {
936                            case PPC_30_RLDICL: mnem = "rldicl"; break;
937                            case PPC_30_RLDICR: mnem = "rldicr"; break;
938                            case PPC_30_RLDIMI: mnem = "rldimi"; break;
939                            }
940                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
941                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
942                          sh = ((iword >> 11) & 31) | ((iword & 2) << 4);                          sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
943                          me = ((iword >> 6) & 31) | (iword & 0x20);                          me = ((iword >> 6) & 31) | (iword & 0x20);
944                          rc = iword & 1;                          rc = iword & 1;
945                          debug("rldicr%s\tr%i,r%i,%i,%i",                          debug("%s%s\tr%i,r%i,%i,%i",
946                              rc?".":"", ra, rs, sh, me);                              mnem, rc?".":"", ra, rs, sh, me);
947                          break;                          break;
948                  default:                  default:
949                          debug("unimplemented hi6_30, xo = 0x%x", xo);                          debug("unimplemented hi6_30, xo = 0x%x", xo);
# Line 836  int ppc_cpu_disassemble_instr(struct cpu Line 1003  int ppc_cpu_disassemble_instr(struct cpu
1003                  case PPC_31_LDARX:                  case PPC_31_LDARX:
1004                  case PPC_31_LBZX:                  case PPC_31_LBZX:
1005                  case PPC_31_LBZUX:                  case PPC_31_LBZUX:
1006                    case PPC_31_LHAX:
1007                    case PPC_31_LHAUX:
1008                  case PPC_31_LHZX:                  case PPC_31_LHZX:
1009                  case PPC_31_LHZUX:                  case PPC_31_LHZUX:
1010                  case PPC_31_LWZX:                  case PPC_31_LWZX:
1011                  case PPC_31_LWZUX:                  case PPC_31_LWZUX:
1012                    case PPC_31_LHBRX:
1013                    case PPC_31_LWBRX:
1014                    case PPC_31_LFDX:
1015                    case PPC_31_LFSX:
1016                  case PPC_31_STWCX_DOT:                  case PPC_31_STWCX_DOT:
1017                  case PPC_31_STDCX_DOT:                  case PPC_31_STDCX_DOT:
1018                  case PPC_31_STBX:                  case PPC_31_STBX:
# Line 850  int ppc_cpu_disassemble_instr(struct cpu Line 1023  int ppc_cpu_disassemble_instr(struct cpu
1023                  case PPC_31_STWUX:                  case PPC_31_STWUX:
1024                  case PPC_31_STDX:                  case PPC_31_STDX:
1025                  case PPC_31_STDUX:                  case PPC_31_STDUX:
1026                    case PPC_31_STHBRX:
1027                    case PPC_31_STWBRX:
1028                    case PPC_31_STFDX:
1029                    case PPC_31_STFSX:
1030                          /*  rs for stores, rt for loads, actually  */                          /*  rs for stores, rt for loads, actually  */
1031                          load = 0; wlen = 0;                          load = 0; wlen = 0; fpreg = 0;
1032                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1033                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1034                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
# Line 860  int ppc_cpu_disassemble_instr(struct cpu Line 1037  int ppc_cpu_disassemble_instr(struct cpu
1037                          case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;                          case PPC_31_LDARX: wlen=8;load=1; mnem = "ldarx"; break;
1038                          case PPC_31_LBZX:  wlen=1;load=1; mnem = "lbzx"; break;                          case PPC_31_LBZX:  wlen=1;load=1; mnem = "lbzx"; break;
1039                          case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;                          case PPC_31_LBZUX: wlen=1;load=1; mnem = "lbzux"; break;
1040                            case PPC_31_LHAX:  wlen=2;load=1; mnem = "lhax"; break;
1041                            case PPC_31_LHAUX: wlen=2;load=1; mnem = "lhaux"; break;
1042                          case PPC_31_LHZX:  wlen=2;load=1; mnem = "lhzx"; break;                          case PPC_31_LHZX:  wlen=2;load=1; mnem = "lhzx"; break;
1043                          case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;                          case PPC_31_LHZUX: wlen=2;load=1; mnem = "lhzux"; break;
1044                          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 1047  int ppc_cpu_disassemble_instr(struct cpu
1047                          case PPC_31_LWZUX: wlen = 4; load = 1;                          case PPC_31_LWZUX: wlen = 4; load = 1;
1048                                  mnem = power? "lux":"lwzux";                                  mnem = power? "lux":"lwzux";
1049                                  break;                                  break;
1050                            case PPC_31_LFDX: fpreg = 1; wlen = 8; load = 1;
1051                                    mnem = "lfdx"; break;
1052                            case PPC_31_LFSX: fpreg = 1; wlen = 4; load = 1;
1053                                    mnem = "lfsx"; break;
1054                          case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;                          case PPC_31_STWCX_DOT: wlen=4; mnem = "stwcx."; break;
1055                          case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;                          case PPC_31_STDCX_DOT: wlen=8; mnem = "stdcx."; break;
1056                          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 1065  int ppc_cpu_disassemble_instr(struct cpu
1065                                  break;                                  break;
1066                          case PPC_31_STDX:  wlen = 8; mnem = "stdx"; break;                          case PPC_31_STDX:  wlen = 8; mnem = "stdx"; break;
1067                          case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;                          case PPC_31_STDUX: wlen = 8; mnem = "stdux"; break;
1068                            case PPC_31_LHBRX:  wlen = 2; mnem = "lhbrx"; break;
1069                            case PPC_31_LWBRX:  wlen = 4; mnem = power?
1070                                                "lbrx" : "lwbrx"; break;
1071                            case PPC_31_STHBRX: wlen = 2; mnem = "sthbrx"; break;
1072                            case PPC_31_STWBRX: wlen = 4; mnem = power?
1073                                                "stbrx" : "stwbrx"; break;
1074                            case PPC_31_STFDX: fpreg = 1; wlen = 8;
1075                                    mnem = "stfdx"; break;
1076                            case PPC_31_STFSX: fpreg = 1; wlen = 4;
1077                                    mnem = "stfsx"; break;
1078                          }                          }
1079                          debug("%s\tr%i,r%i,r%i", mnem, rs, ra, rb);                          debug("%s\t%s%i,r%i,r%i", mnem,
1080                                fpreg? "f" : "r", rs, ra, rb);
1081                          if (!running)                          if (!running)
1082                                  break;                                  break;
1083                          addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +                          addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) +
1084                              cpu->cd.ppc.gpr[rb];                              cpu->cd.ppc.gpr[rb];
1085                            if (cpu->cd.ppc.bits == 32)
1086                                    addr &= 0xffffffff;
1087                          symbol = get_symbol_name(&cpu->machine->symbol_context,                          symbol = get_symbol_name(&cpu->machine->symbol_context,
1088                              addr, &offset);                              addr, &offset);
1089                          if (symbol != NULL)                          if (symbol != NULL)
1090                                  debug(" \t<%s", symbol);                                  debug(" \t<%s", symbol);
1091                          else                          else
1092                                  debug(" \t<0x%llx", (long long)addr);                                  debug(" \t<0x%"PRIx64, (uint64_t) addr);
1093                          if (wlen > 0) {                          if (wlen > 0 && !fpreg /* && !reverse */) {
1094                                  /*  TODO  */                                  /*  TODO  */
1095                          }                          }
1096                          debug(">");                          debug(">");
# Line 911  int ppc_cpu_disassemble_instr(struct cpu Line 1107  int ppc_cpu_disassemble_instr(struct cpu
1107                          }                          }
1108                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1109                          break;                          break;
1110                    case PPC_31_WRTEEI:
1111                            debug("wrteei\t%i", iword & 0x8000? 1 : 0);
1112                            break;
1113                    case PPC_31_MTMSRD:
1114                            /*  TODO: Just a guess based on MTMSR  */
1115                            rs = (iword >> 21) & 31;
1116                            l_bit = (iword >> 16) & 1;
1117                            debug("mtmsrd\tr%i", rs);
1118                            if (l_bit)
1119                                    debug(",%i", l_bit);
1120                            break;
1121                  case PPC_31_ADDZE:                  case PPC_31_ADDZE:
1122                  case PPC_31_ADDZEO:                  case PPC_31_ADDZEO:
1123                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 928  int ppc_cpu_disassemble_instr(struct cpu Line 1135  int ppc_cpu_disassemble_instr(struct cpu
1135                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", rt, ra);
1136                          break;                          break;
1137                  case PPC_31_MTSR:                  case PPC_31_MTSR:
1138                          /*  Move to segment register  */                  case PPC_31_MFSR:
1139                            /*  Move to/from segment register  */
1140                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1141                          ra = (iword >> 16) & 15;        /*  actually: sr  */                          ra = (iword >> 16) & 15;        /*  actually: sr  */
1142                          debug("mtsr\t%i,r%i", ra, rt);                          switch (xo) {
1143                            case PPC_31_MTSR:  mnem = "mtsr"; break;
1144                            case PPC_31_MFSR:  mnem = "mfsr"; break;
1145                            }
1146                            debug("%s\tr%i,%i", mnem, rt, ra);
1147                          break;                          break;
1148                  case PPC_31_MTSRIN:                  case PPC_31_MTSRIN:
1149                  case PPC_31_MFSRIN:                  case PPC_31_MFSRIN:
# Line 962  int ppc_cpu_disassemble_instr(struct cpu Line 1174  int ppc_cpu_disassemble_instr(struct cpu
1174                  case PPC_31_SUBFCO:                  case PPC_31_SUBFCO:
1175                  case PPC_31_SUBFE:                  case PPC_31_SUBFE:
1176                  case PPC_31_SUBFEO:                  case PPC_31_SUBFEO:
1177                    case PPC_31_SUBFME:
1178                    case PPC_31_SUBFMEO:
1179                  case PPC_31_SUBFZE:                  case PPC_31_SUBFZE:
1180                  case PPC_31_SUBFZEO:                  case PPC_31_SUBFZEO:
1181                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 1007  int ppc_cpu_disassemble_instr(struct cpu Line 1221  int ppc_cpu_disassemble_instr(struct cpu
1221                          case PPC_31_SUBF:   mnem = "subf"; break;                          case PPC_31_SUBF:   mnem = "subf"; break;
1222                          case PPC_31_SUBFO:  mnem = "subfo"; break;                          case PPC_31_SUBFO:  mnem = "subfo"; break;
1223                          case PPC_31_SUBFC:                          case PPC_31_SUBFC:
1224                                  mnem = power? "sf" : "subfc";                                  mnem = power? "sf" : "subfc"; break;
                                 break;  
1225                          case PPC_31_SUBFCO:                          case PPC_31_SUBFCO:
1226                                  mnem = power? "sfo" : "subfco";                                  mnem = power? "sfo" : "subfco"; break;
                                 break;  
1227                          case PPC_31_SUBFE:                          case PPC_31_SUBFE:
1228                                  mnem = power? "sfe" : "subfe";                                  mnem = power? "sfe" : "subfe"; break;
                                 break;  
1229                          case PPC_31_SUBFEO:                          case PPC_31_SUBFEO:
1230                                  mnem = power? "sfeo" : "subfeo";                                  mnem = power? "sfeo" : "subfeo"; break;
1231                                  break;                          case PPC_31_SUBFME:
1232                                    mnem = power? "sfme" : "subfme"; break;
1233                            case PPC_31_SUBFMEO:
1234                                    mnem = power? "sfmeo" : "subfmeo"; break;
1235                          case PPC_31_SUBFZE:                          case PPC_31_SUBFZE:
1236                                  mnem = power? "sfze" : "subfze";                                  mnem = power? "sfze" : "subfze";
1237                                  no_rb = 1;                                  no_rb = 1;
# Line 1035  int ppc_cpu_disassemble_instr(struct cpu Line 1249  int ppc_cpu_disassemble_instr(struct cpu
1249                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1250                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1251                          switch (spr) {                          switch (spr) {
1252                            /*  Some very common ones:  */
1253                          case 8:    debug("mflr\tr%i", rt); break;                          case 8:    debug("mflr\tr%i", rt); break;
1254                          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;  
1255                          default:debug("mfspr\tr%i,spr%i", rt, spr);                          default:debug("mfspr\tr%i,spr%i", rt, spr);
1256                          }                          }
1257                            if (spr == 8 || spr == 9)
1258                                    debug("\t");
1259                            debug("\t<%s%s", running? "read from " : "",
1260                                ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1261                            if (running) {
1262                                    if (cpu->cd.ppc.bits == 32)
1263                                            debug(": 0x%"PRIx32, (uint32_t)
1264                                                cpu->cd.ppc.spr[spr]);
1265                                    else
1266                                            debug(": 0x%"PRIx64, (uint64_t)
1267                                                cpu->cd.ppc.spr[spr]);
1268                            }
1269                            debug(">");
1270                            break;
1271                    case PPC_31_TLBIA:
1272                            debug("tlbia");
1273                            break;
1274                    case PPC_31_SLBIA:
1275                            debug("slbia");
1276                            break;
1277                    case PPC_31_TLBLD:
1278                    case PPC_31_TLBLI:
1279                            rb = (iword >> 11) & 31;
1280                            debug("tlbl%s\tr%i", xo == PPC_31_TLBLD? "d" : "i", rb);
1281                          break;                          break;
1282                  case PPC_31_TLBIE:                  case PPC_31_TLBIE:
1283                          /*  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 1288  int ppc_cpu_disassemble_instr(struct cpu
1288                          else                          else
1289                                  debug("tlbie\tr%i", rb);                                  debug("tlbie\tr%i", rb);
1290                          break;                          break;
1291                    case PPC_31_TLBSX_DOT:
1292                            rs = (iword >> 21) & 31;
1293                            ra = (iword >> 16) & 31;
1294                            rb = (iword >> 11) & 31;
1295                            debug("tlbsx.\tr%i,r%i,r%i", rs, ra, rb);
1296                            break;
1297                  case PPC_31_TLBSYNC:                  case PPC_31_TLBSYNC:
1298                          debug("tlbsync");                          debug("tlbsync");
1299                          break;                          break;
# Line 1105  int ppc_cpu_disassemble_instr(struct cpu Line 1338  int ppc_cpu_disassemble_instr(struct cpu
1338                          debug("%s\tr%i,r%i", mnem, ra, rb);                          debug("%s\tr%i,r%i", mnem, ra, rb);
1339                          break;                          break;
1340                  case PPC_31_SLW:                  case PPC_31_SLW:
1341                    case PPC_31_SLD:
1342                  case PPC_31_SRAW:                  case PPC_31_SRAW:
1343                  case PPC_31_SRW:                  case PPC_31_SRW:
1344                  case PPC_31_AND:                  case PPC_31_AND:
1345                  case PPC_31_ANDC:                  case PPC_31_ANDC:
1346                  case PPC_31_NOR:                  case PPC_31_NOR:
1347                    case PPC_31_EQV:
1348                  case PPC_31_OR:                  case PPC_31_OR:
1349                  case PPC_31_ORC:                  case PPC_31_ORC:
1350                  case PPC_31_XOR:                  case PPC_31_XOR:
# Line 1124  int ppc_cpu_disassemble_instr(struct cpu Line 1359  int ppc_cpu_disassemble_instr(struct cpu
1359                                  switch (xo) {                                  switch (xo) {
1360                                  case PPC_31_SLW:  mnem =                                  case PPC_31_SLW:  mnem =
1361                                          power? "sl" : "slw"; break;                                          power? "sl" : "slw"; break;
1362                                    case PPC_31_SLD:  mnem = "sld"; break;
1363                                  case PPC_31_SRAW:  mnem =                                  case PPC_31_SRAW:  mnem =
1364                                          power? "sra" : "sraw"; break;                                          power? "sra" : "sraw"; break;
1365                                  case PPC_31_SRW:  mnem =                                  case PPC_31_SRW:  mnem =
# Line 1132  int ppc_cpu_disassemble_instr(struct cpu Line 1368  int ppc_cpu_disassemble_instr(struct cpu
1368                                  case PPC_31_NAND: mnem = "nand"; break;                                  case PPC_31_NAND: mnem = "nand"; break;
1369                                  case PPC_31_ANDC: mnem = "andc"; break;                                  case PPC_31_ANDC: mnem = "andc"; break;
1370                                  case PPC_31_NOR:  mnem = "nor"; break;                                  case PPC_31_NOR:  mnem = "nor"; break;
1371                                    case PPC_31_EQV:  mnem = "eqv"; break;
1372                                  case PPC_31_OR:   mnem = "or"; break;                                  case PPC_31_OR:   mnem = "or"; break;
1373                                  case PPC_31_ORC:  mnem = "orc"; break;                                  case PPC_31_ORC:  mnem = "orc"; break;
1374                                  case PPC_31_XOR:  mnem = "xor"; break;                                  case PPC_31_XOR:  mnem = "xor"; break;
# Line 1172  int ppc_cpu_disassemble_instr(struct cpu Line 1409  int ppc_cpu_disassemble_instr(struct cpu
1409                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1410                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1411                          switch (spr) {                          switch (spr) {
1412                            /*  Some very common ones:  */
1413                          case 8:    debug("mtlr\tr%i", rs); break;                          case 8:    debug("mtlr\tr%i", rs); break;
1414                          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;  
1415                          default:debug("mtspr\tspr%i,r%i", spr, rs);                          default:debug("mtspr\tspr%i,r%i", spr, rs);
1416                          }                          }
1417                            if (spr == 8 || spr == 9)
1418                                    debug("\t");
1419                            debug("\t<%s%s", running? "write to " : "",
1420                                ppc_spr_names[spr]==NULL? "?" : ppc_spr_names[spr]);
1421                            if (running) {
1422                                    if (cpu->cd.ppc.bits == 32)
1423                                            debug(": 0x%"PRIx32, (uint32_t)
1424                                                cpu->cd.ppc.gpr[rs]);
1425                                    else
1426                                            debug(": 0x%"PRIx64, (uint64_t)
1427                                                cpu->cd.ppc.gpr[rs]);
1428                            }
1429                            debug(">");
1430                          break;                          break;
1431                  case PPC_31_SYNC:                  case PPC_31_SYNC:
1432                          debug("%s", power? "dcs" : "sync");                          debug("%s", power? "dcs" : "sync");
# Line 1216  int ppc_cpu_disassemble_instr(struct cpu Line 1444  int ppc_cpu_disassemble_instr(struct cpu
1444                          }                          }
1445                          debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);                          debug("%s\tr%i,r%i,%i", mnem, rs, ra, nb);
1446                          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;  
1447                  case PPC_31_SRAWI:                  case PPC_31_SRAWI:
1448                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1449                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
# Line 1242  int ppc_cpu_disassemble_instr(struct cpu Line 1453  int ppc_cpu_disassemble_instr(struct cpu
1453                          debug("%s%s\tr%i,r%i,%i", mnem,                          debug("%s%s\tr%i,r%i,%i", mnem,
1454                              rc? "." : "", ra, rs, sh);                              rc? "." : "", ra, rs, sh);
1455                          break;                          break;
1456                    case PPC_31_DSSALL:
1457                            debug("dssall");
1458                            break;
1459                  case PPC_31_EIEIO:                  case PPC_31_EIEIO:
1460                          debug("%s", power? "eieio?" : "eieio");                          debug("%s", power? "eieio?" : "eieio");
1461                          break;                          break;
# Line 1264  int ppc_cpu_disassemble_instr(struct cpu Line 1478  int ppc_cpu_disassemble_instr(struct cpu
1478                          }                          }
1479                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1480                          break;                          break;
1481                    case PPC_31_LVX:
1482                    case PPC_31_LVXL:
1483                    case PPC_31_STVX:
1484                    case PPC_31_STVXL:
1485                            rs = (iword >> 21) & 31;        /*  vs for stores,  */
1486                            ra = (iword >> 16) & 31;        /*  rs=vl for loads  */
1487                            rb = (iword >> 11) & 31;
1488                            rc = iword & 1;
1489                            switch (xo) {
1490                            case PPC_31_LVX:   mnem = "lvx";  break;
1491                            case PPC_31_LVXL:  mnem = "lvxl"; break;
1492                            case PPC_31_STVX:  mnem = "stvx";  break;
1493                            case PPC_31_STVXL: mnem = "stvxl"; break;
1494                            }
1495                            debug("%s%s\tv%i,r%i,r%i", mnem, rc? "." : "",
1496                                rs, ra, rb);
1497                            break;
1498                  default:                  default:
1499                          debug("unimplemented hi6_31, xo = 0x%x", xo);                          debug("unimplemented hi6_31, xo = 0x%x", xo);
1500                  }                  }
1501                  break;                  break;
1502            case PPC_HI6_LD:
1503          case PPC_HI6_LWZ:          case PPC_HI6_LWZ:
1504          case PPC_HI6_LWZU:          case PPC_HI6_LWZU:
1505          case PPC_HI6_LHZ:          case PPC_HI6_LHZ:
# Line 1276  int ppc_cpu_disassemble_instr(struct cpu Line 1508  int ppc_cpu_disassemble_instr(struct cpu
1508          case PPC_HI6_LHAU:          case PPC_HI6_LHAU:
1509          case PPC_HI6_LBZ:          case PPC_HI6_LBZ:
1510          case PPC_HI6_LBZU:          case PPC_HI6_LBZU:
1511            case PPC_HI6_LFD:
1512            case PPC_HI6_LFS:
1513          case PPC_HI6_LMW:          case PPC_HI6_LMW:
1514            case PPC_HI6_STD:
1515          case PPC_HI6_STW:          case PPC_HI6_STW:
1516          case PPC_HI6_STWU:          case PPC_HI6_STWU:
1517          case PPC_HI6_STH:          case PPC_HI6_STH:
# Line 1284  int ppc_cpu_disassemble_instr(struct cpu Line 1519  int ppc_cpu_disassemble_instr(struct cpu
1519          case PPC_HI6_STB:          case PPC_HI6_STB:
1520          case PPC_HI6_STBU:          case PPC_HI6_STBU:
1521          case PPC_HI6_STMW:          case PPC_HI6_STMW:
         case PPC_HI6_LFD:  
1522          case PPC_HI6_STFD:          case PPC_HI6_STFD:
1523            case PPC_HI6_STFS:
1524                  /*  NOTE: Loads use rt, not rs, but are otherwise similar                  /*  NOTE: Loads use rt, not rs, but are otherwise similar
1525                      to stores  */                      to stores  */
1526                  load = 0; wlen = 0;                  load = 0; wlen = 0;
# Line 1294  int ppc_cpu_disassemble_instr(struct cpu Line 1529  int ppc_cpu_disassemble_instr(struct cpu
1529                  imm = (int16_t)(iword & 0xffff);                  imm = (int16_t)(iword & 0xffff);
1530                  fpreg = 0;                  fpreg = 0;
1531                  switch (hi6) {                  switch (hi6) {
1532                    case PPC_HI6_LD:  load=1; wlen = 8; mnem = "ld"; break;
1533                  case PPC_HI6_LWZ:  load=1; wlen = 4;                  case PPC_HI6_LWZ:  load=1; wlen = 4;
1534                          mnem = power? "l" : "lwz"; break;                          mnem = power? "l" : "lwz"; break;
1535                  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 1546  int ppc_cpu_disassemble_instr(struct cpu
1546                          mnem = "lbz"; break;                          mnem = "lbz"; break;
1547                  case PPC_HI6_LBZU: load=1; wlen = 1;                  case PPC_HI6_LBZU: load=1; wlen = 1;
1548                          mnem = "lbzu"; break;                          mnem = "lbzu"; break;
1549                    case PPC_HI6_LFD:  load=1; fpreg=1; wlen=8; mnem = "lfd"; break;
1550                    case PPC_HI6_LFS:  load=1; fpreg=1; wlen=4; mnem = "lfs"; break;
1551                    case PPC_HI6_STD:  wlen=8; mnem = "std"; break;
1552                  case PPC_HI6_STW:  wlen=4; mnem = power? "st" : "stw"; break;                  case PPC_HI6_STW:  wlen=4; mnem = power? "st" : "stw"; break;
1553                  case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;                  case PPC_HI6_STWU: wlen=4; mnem = power? "stu" : "stwu"; break;
1554                  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 1557  int ppc_cpu_disassemble_instr(struct cpu
1557                  case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;                  case PPC_HI6_STBU: wlen=1; mnem = "stbu"; break;
1558                  case PPC_HI6_LMW:  load=1; mnem = power? "lm" : "lmw"; break;                  case PPC_HI6_LMW:  load=1; mnem = power? "lm" : "lmw"; break;
1559                  case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;                  case PPC_HI6_STMW: mnem = power? "stm" : "stmw"; break;
1560                  case PPC_HI6_LFD:  load=1; fpreg = 1; mnem = "lfd"; break;                  case PPC_HI6_STFD: fpreg=1; wlen=8; mnem = "stfd"; break;
1561                  case PPC_HI6_STFD: fpreg = 1; mnem = "stfd"; break;                  case PPC_HI6_STFS: fpreg=1; wlen=4; mnem = "stfs"; break;
1562                  }                  }
1563                  debug("%s\t", mnem);                  debug("%s\t", mnem);
1564                  if (fpreg)                  if (fpreg)
# Line 1330  int ppc_cpu_disassemble_instr(struct cpu Line 1569  int ppc_cpu_disassemble_instr(struct cpu
1569                  if (!running)                  if (!running)
1570                          break;                          break;
1571                  addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;                  addr = (ra==0? 0 : cpu->cd.ppc.gpr[ra]) + imm;
1572                    if (cpu->cd.ppc.bits == 32)
1573                            addr &= 0xffffffff;
1574                  symbol = get_symbol_name(&cpu->machine->symbol_context,                  symbol = get_symbol_name(&cpu->machine->symbol_context,
1575                      addr, &offset);                      addr, &offset);
1576                  if (symbol != NULL)                  if (symbol != NULL)
1577                          debug(" \t<%s", symbol);                          debug(" \t<%s", symbol);
1578                  else                  else
1579                          debug(" \t<0x%llx", (long long)addr);                          debug(" \t<0x%"PRIx64, (uint64_t) addr);
1580                  if (wlen > 0 && load && wlen > 0) {                  if (wlen > 0 && load && wlen > 0) {
1581                          unsigned char tw[8];                          unsigned char tw[8];
1582                          uint64_t tdata = 0;                          uint64_t tdata = 0;
# Line 1359  int ppc_cpu_disassemble_instr(struct cpu Line 1600  int ppc_cpu_disassemble_instr(struct cpu
1600                                          if (symbol != NULL)                                          if (symbol != NULL)
1601                                                  debug("%s", symbol);                                                  debug("%s", symbol);
1602                                          else                                          else
1603                                                  debug("0x%llx",                                                  debug("0x%"PRIx64,
1604                                                      (long long)tdata);                                                      (uint64_t) tdata);
1605                                  } else {                                  } else {
1606                                          /*  TODO: if load==2, then this is                                          /*  TODO: if load==2, then this is
1607                                              a _signed_ load.  */                                              a _signed_ load.  */
1608                                          debug("0x%llx", (long long)tdata);                                          debug("0x%"PRIx64, (uint64_t) tdata);
1609                                  }                                  }
1610                          } else                          } else
1611                                  debug(": unreadable");                                  debug(": unreadable");
# Line 1374  int ppc_cpu_disassemble_instr(struct cpu Line 1615  int ppc_cpu_disassemble_instr(struct cpu
1615                          int i;                          int i;
1616                          for (i=0; i<wlen; i++)                          for (i=0; i<wlen; i++)
1617                                  tdata |= (cpu->cd.ppc.gpr[rs] &                                  tdata |= (cpu->cd.ppc.gpr[rs] &
1618                                      ((uint64_t)0xff << i));                                      ((uint64_t)0xff << (i*8)));
1619                          debug(": ");                          debug(": ");
1620                          if (wlen >= 4) {                          if (wlen >= 4) {
1621                                  symbol = get_symbol_name(&cpu->machine->                                  symbol = get_symbol_name(&cpu->machine->
# Line 1382  int ppc_cpu_disassemble_instr(struct cpu Line 1623  int ppc_cpu_disassemble_instr(struct cpu
1623                                  if (symbol != NULL)                                  if (symbol != NULL)
1624                                          debug("%s", symbol);                                          debug("%s", symbol);
1625                                  else                                  else
1626                                          debug("0x%llx",                                          debug("0x%"PRIx64, (uint64_t) tdata);
                                             (long long)tdata);  
1627                          } else {                          } else {
1628                                  if (tdata > -256 && tdata < 256)                                  if (tdata > -256 && tdata < 256)
1629                                          debug("%i", (int)tdata);                                          debug("%i", (int)tdata);
1630                                  else                                  else
1631                                          debug("0x%llx", (long long)tdata);                                          debug("0x%"PRIx64, (uint64_t) tdata);
1632                          }                          }
1633                  }                  }
1634                  debug(">");                  debug(">");
1635                  break;                  break;
1636            case PPC_HI6_59:
1637                    xo = (iword >> 1) & 1023;
1638                    /*  NOTE: Some floating point instructions only use the
1639                        lowest 5 bits of xo, some use all 10 bits!  */
1640                    switch (xo & 31) {
1641                    case PPC_59_FDIVS:
1642                    case PPC_59_FSUBS:
1643                    case PPC_59_FADDS:
1644                    case PPC_59_FMULS:
1645                    case PPC_59_FMADDS:
1646                            rt = (iword >> 21) & 31;
1647                            ra = (iword >> 16) & 31;
1648                            rb = (iword >> 11) & 31;
1649                            rs = (iword >>  6) & 31;        /*  actually frc  */
1650                            rc = iword & 1;
1651                            switch (xo & 31) {
1652                            case PPC_59_FDIVS:      mnem = "fdivs"; break;
1653                            case PPC_59_FSUBS:      mnem = "fsubs"; break;
1654                            case PPC_59_FADDS:      mnem = "fadds"; break;
1655                            case PPC_59_FMULS:      mnem = "fmuls"; break;
1656                            case PPC_59_FMADDS:     mnem = "fmadds"; break;
1657                            }
1658                            debug("%s%s\t", mnem, rc? "." : "");
1659                            switch (xo & 31) {
1660                            case PPC_59_FMULS:
1661                                    debug("f%i,f%i,f%i", rt, ra, rs);
1662                                    break;
1663                            case PPC_59_FMADDS:
1664                                    debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1665                                    break;
1666                            default:debug("f%i,f%i,f%i", rt, ra, rb);
1667                            }
1668                            break;
1669                    default:/*  TODO: similar to hi6_63  */
1670                            debug("unimplemented hi6_59, xo = 0x%x", xo);
1671                    }
1672                    break;
1673          case PPC_HI6_63:          case PPC_HI6_63:
1674                  xo = (iword >> 1) & 1023;                  xo = (iword >> 1) & 1023;
1675                  switch (xo) {                  /*  NOTE: Some floating point instructions only use the
1676                  case PPC_63_FMR:                      lowest 5 bits of xo, some use all 10 bits!  */
1677                    switch (xo & 31) {
1678                    case PPC_63_FDIV:
1679                    case PPC_63_FSUB:
1680                    case PPC_63_FADD:
1681                    case PPC_63_FMUL:
1682                    case PPC_63_FMSUB:
1683                    case PPC_63_FMADD:
1684                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
1685                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1686                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
1687                            rs = (iword >>  6) & 31;        /*  actually frc  */
1688                            rc = iword & 1;
1689                            switch (xo & 31) {
1690                            case PPC_63_FDIV:
1691                                    mnem = power? "fd" : "fdiv"; break;
1692                            case PPC_63_FSUB:
1693                                    mnem = power? "fs" : "fsub"; break;
1694                            case PPC_63_FADD:
1695                                    mnem = power? "fa" : "fadd"; break;
1696                            case PPC_63_FMUL:
1697                                    mnem = power? "fm" : "fmul"; break;
1698                            case PPC_63_FMSUB:
1699                                    mnem = power? "fms" : "fmsub"; break;
1700                            case PPC_63_FMADD:
1701                                    mnem = power? "fma" : "fmadd"; break;
1702                            }
1703                            debug("%s%s\t", mnem, rc? "." : "");
1704                            switch (xo & 31) {
1705                            case PPC_63_FMUL:
1706                                    debug("f%i,f%i,f%i", rt, ra, rs);
1707                                    break;
1708                            case PPC_63_FMADD:
1709                                    debug("f%i,f%i,f%i,f%i", rt, ra, rs, rb);
1710                                    break;
1711                            default:debug("f%i,f%i,f%i", rt, ra, rb);
1712                            }
1713                            break;
1714                    default:rt = (iword >> 21) & 31;
1715                            ra = (iword >> 16) & 31;
1716                            rb = (iword >> 11) & 31;
1717                          rc = iword & 1;                          rc = iword & 1;
1718                          switch (xo) {                          switch (xo) {
1719                            case PPC_63_FCMPU:
1720                            case PPC_63_FRSP:
1721                            case PPC_63_FCTIWZ:
1722                            case PPC_63_FNEG:
1723                          case PPC_63_FMR:                          case PPC_63_FMR:
1724                                  debug("fmr%s\tf%i,f%i", rc? "." : "", rt, rb);                          case PPC_63_FNABS:
1725                            case PPC_63_FABS:
1726                                    switch (xo) {
1727                                    case PPC_63_FCMPU:      mnem = "fcmpu"; break;
1728                                    case PPC_63_FCTIWZ:
1729                                            mnem = power? "fcirz" : "fctiwz"; break;
1730                                    case PPC_63_FRSP:       mnem = "frsp"; break;
1731                                    case PPC_63_FNEG:       mnem = "fneg"; break;
1732                                    case PPC_63_FMR:        mnem = "fmr"; break;
1733                                    case PPC_63_FNABS:      mnem = "fnabs"; break;
1734                                    case PPC_63_FABS:       mnem = "fabs"; break;
1735                                    }
1736                                    debug("%s%s\t", mnem, rc? "." : "");
1737                                    switch (xo) {
1738                                    case PPC_63_FCMPU:
1739                                            debug("%i,f%i,f%i", rt >> 2, ra, rb);
1740                                            break;
1741                                    case PPC_63_FCTIWZ:
1742                                    case PPC_63_FRSP:
1743                                    case PPC_63_FNEG:
1744                                    case PPC_63_FMR:
1745                                    case PPC_63_FNABS:
1746                                    case PPC_63_FABS:
1747                                            debug("f%i,f%i", rt, rb);
1748                                            break;
1749                                    default:debug("f%i,f%i,f%i", rt, ra, rb);
1750                                    }
1751                                  break;                                  break;
1752                            case PPC_63_MFFS:
1753                                    debug("mffs%s\tf%i", rc?".":"", rt);
1754                                    break;
1755                            case PPC_63_MTFSF:
1756                                    ra = (iword >> 17) & 255;       /*  flm  */
1757                                    debug("mtfsf%s\t0x%02x,f%i", rc?".":"", ra, rb);
1758                                    break;
1759                            default:debug("unimplemented hi6_63, xo = 0x%x", xo);
1760                          }                          }
                         break;  
                 default:  
                         debug("unimplemented hi6_31, xo = 0x%x", xo);  
1761                  }                  }
1762                  break;                  break;
1763          default:          default:
# Line 1422  int ppc_cpu_disassemble_instr(struct cpu Line 1771  int ppc_cpu_disassemble_instr(struct cpu
1771    
1772    
1773  /*  /*
1774     *  debug_spr_usage():
1775     *
1776     *  Helper function. To speed up overall development speed of the emulator,
1777     *  all SPR accesses are allowed. This function causes unknown/unimplemented
1778     *  SPRs to give a warning.
1779     */
1780    static void debug_spr_usage(uint64_t pc, int spr)
1781    {
1782            static uint32_t spr_used[1024 / sizeof(uint32_t)];
1783            static int initialized = 0;
1784    
1785            if (!initialized) {
1786                    memset(spr_used, 0, sizeof(spr_used));
1787                    initialized = 1;
1788            }
1789    
1790            spr &= 1023;
1791            if (spr_used[spr >> 2] & (1 << (spr & 3)))
1792                    return;
1793    
1794            switch (spr) {
1795            /*  Known/implemented SPRs:  */
1796            case SPR_XER:
1797            case SPR_LR:
1798            case SPR_CTR:
1799            case SPR_DSISR:
1800            case SPR_DAR:
1801            case SPR_DEC:
1802            case SPR_SDR1:
1803            case SPR_SRR0:
1804            case SPR_SRR1:
1805            case SPR_SPRG0:
1806            case SPR_SPRG1:
1807            case SPR_SPRG2:
1808            case SPR_SPRG3:
1809            case SPR_PVR:
1810            case SPR_DMISS:
1811            case SPR_DCMP:
1812            case SPR_HASH1:
1813            case SPR_HASH2:
1814            case SPR_IMISS:
1815            case SPR_ICMP:
1816            case SPR_DBSR:
1817            case SPR_PIR:
1818                    break;
1819            default:if (spr >= SPR_IBAT0U && spr <= SPR_DBAT3L) {
1820                            break;
1821                    } else
1822                            fatal("[ using UNIMPLEMENTED spr %i 0x%04x (%s), pc = "
1823                                "0x%"PRIx64" ]\n", spr, spr, ppc_spr_names[spr] == NULL?
1824                                "UNKNOWN" : ppc_spr_names[spr], (uint64_t) pc);
1825            }
1826    
1827            spr_used[spr >> 2] |= (1 << (spr & 3));
1828    }
1829    
1830    
1831    /*
1832   *  update_cr0():   *  update_cr0():
1833   *   *
1834   *  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 1854  void update_cr0(struct cpu *cpu, uint64_
1854          }          }
1855    
1856          /*  SO bit, copied from XER:  */          /*  SO bit, copied from XER:  */
1857          c |= ((cpu->cd.ppc.xer >> 31) & 1);          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
1858    
1859          cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);          cpu->cd.ppc.cr &= ~((uint32_t)0xf << 28);
1860          cpu->cd.ppc.cr |= ((uint32_t)c << 28);          cpu->cd.ppc.cr |= ((uint32_t)c << 28);
# Line 1459  void update_cr0(struct cpu *cpu, uint64_ Line 1866  void update_cr0(struct cpu *cpu, uint64_
1866    
1867  #include "tmp_ppc_tail.c"  #include "tmp_ppc_tail.c"
1868    
1869    

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

  ViewVC Help
Powered by ViewVC 1.1.26