/[gxemul]/trunk/src/cpus/cpu_mips.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_mips.c

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

revision 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC revision 38 by dpavlin, Mon Oct 8 16:21:53 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-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_mips.c,v 1.63 2006/08/12 11:43:13 debug Exp $   *  $Id: cpu_mips.c,v 1.77 2007/04/10 17:52:27 debug Exp $
29   *   *
30   *  MIPS core CPU emulation.   *  MIPS core CPU emulation.
31   */   */
# Line 50  Line 50 
50  #include "memory.h"  #include "memory.h"
51  #include "mips_cpu_types.h"  #include "mips_cpu_types.h"
52  #include "opcodes_mips.h"  #include "opcodes_mips.h"
53    #include "settings.h"
54  #include "symbol.h"  #include "symbol.h"
55    
56    
# Line 60  static char *exception_names[] = EXCEPTI Line 61  static char *exception_names[] = EXCEPTI
61  static char *hi6_names[] = HI6_NAMES;  static char *hi6_names[] = HI6_NAMES;
62  static char *regimm_names[] = REGIMM_NAMES;  static char *regimm_names[] = REGIMM_NAMES;
63  static char *special_names[] = SPECIAL_NAMES;  static char *special_names[] = SPECIAL_NAMES;
64    static char *special_rot_names[] = SPECIAL_ROT_NAMES;
65  static char *special2_names[] = SPECIAL2_NAMES;  static char *special2_names[] = SPECIAL2_NAMES;
66  static char *mmi_names[] = MMI_NAMES;  static char *mmi_names[] = MMI_NAMES;
67  static char *mmi0_names[] = MMI0_NAMES;  static char *mmi0_names[] = MMI0_NAMES;
# Line 86  void mips32_pc_to_pointers(struct cpu *) Line 88  void mips32_pc_to_pointers(struct cpu *)
88   *  Convert a register number into either 'r0', 'r31' etc, or a symbolic   *  Convert a register number into either 'r0', 'r31' etc, or a symbolic
89   *  name, depending on machine->show_symbolic_register_names.   *  name, depending on machine->show_symbolic_register_names.
90   *   *
91   *  NOTE: _NOT_ reentrant.   *  NOTE: This helper function is _NOT_ reentrant.
92   */   */
93  static char *regname(struct machine *machine, int r)  static char *regname(struct machine *machine, int r)
94  {  {
# Line 302  int mips_cpu_new(struct cpu *cpu, struct Line 304  int mips_cpu_new(struct cpu *cpu, struct
304                  debug(")");                  debug(")");
305          }          }
306    
307            /*  Register the CPU's interrupts:  */
308            for (i=2; i<8; i++) {
309                    struct interrupt template;
310                    char name[50];
311                    snprintf(name, sizeof(name), "%s.%i", cpu->path, i);
312                    memset(&template, 0, sizeof(template));
313                    template.line = 1 << (STATUS_IM_SHIFT + i);
314                    template.name = name;
315                    template.extra = cpu;
316                    template.interrupt_assert = mips_cpu_interrupt_assert;
317                    template.interrupt_deassert = mips_cpu_interrupt_deassert;
318                    interrupt_handler_register(&template);
319    
320                    if (i == 7)
321                            INTERRUPT_CONNECT(name, cpu->cd.mips.irq_compare);
322            }
323    
324          /*  System coprocessor (0), and FPU (1):  */          /*  System coprocessor (0), and FPU (1):  */
325          cpu->cd.mips.coproc[0] = mips_coproc_new(cpu, 0);          cpu->cd.mips.coproc[0] = mips_coproc_new(cpu, 0);
326          cpu->cd.mips.coproc[1] = mips_coproc_new(cpu, 1);          cpu->cd.mips.coproc[1] = mips_coproc_new(cpu, 1);
# Line 323  int mips_cpu_new(struct cpu *cpu, struct Line 342  int mips_cpu_new(struct cpu *cpu, struct
342                          cpu->translate_v2p = translate_v2p_generic;                          cpu->translate_v2p = translate_v2p_generic;
343          }          }
344    
345            if (cpu->machine->prom_emulation) {
346                    /*
347                     *  Default behaviour of jumping to 0xbfc00000 should be
348                     *  a reboot, unless machine-specific initialization code
349                     *  overrides this.
350                     *
351                     *  Note: Specifically big-endian machines should override
352                     *  this, since the default MIPS CPU is little-endian!
353                     */
354                    store_32bit_word(cpu, 0xffffffff9fc00000ULL, 0x00c0de0d);
355            }
356    
357            /*  Add all register names to the settings:  */
358            CPU_SETTINGS_ADD_REGISTER64("pc", cpu->pc);
359            CPU_SETTINGS_ADD_REGISTER64("hi", cpu->cd.mips.hi);
360            CPU_SETTINGS_ADD_REGISTER64("lo", cpu->cd.mips.lo);
361            for (i=0; i<N_MIPS_GPRS; i++)
362                    CPU_SETTINGS_ADD_REGISTER64(regnames[i], cpu->cd.mips.gpr[i]);
363            /*  TODO: Write via special handler function!  */
364            for (i=0; i<N_MIPS_COPROC_REGS; i++)
365                    CPU_SETTINGS_ADD_REGISTER64(cop0_names[i],
366                        cpu->cd.mips.coproc[0]->reg[i]);
367    
368          return 1;          return 1;
369  }  }
370    
# Line 491  void mips_cpu_tlbdump(struct machine *m, Line 533  void mips_cpu_tlbdump(struct machine *m,
533          /*  Raw output:  */          /*  Raw output:  */
534          if (rawflag) {          if (rawflag) {
535                  for (i=0; i<m->ncpus; i++) {                  for (i=0; i<m->ncpus; i++) {
536                            struct mips_coproc *cop0 =
537                                m->cpus[i]->cd.mips.coproc[0];
538    
539                          if (x >= 0 && i != x)                          if (x >= 0 && i != x)
540                                  continue;                                  continue;
541    
# Line 498  void mips_cpu_tlbdump(struct machine *m, Line 543  void mips_cpu_tlbdump(struct machine *m,
543                          printf("cpu%i: (", i);                          printf("cpu%i: (", i);
544    
545                          if (m->cpus[i]->is_32bit)                          if (m->cpus[i]->is_32bit)
546                                  printf("index=0x%08x random=0x%08x", (int)m->                                  printf("index=0x%08x random=0x%08x",
547                                      cpus[i]->cd.mips.coproc[0]->reg[COP0_INDEX],                                      (int) cop0->reg[COP0_INDEX],
548                                      (int)m->cpus[i]->cd.mips.coproc[0]->reg                                      (int) cop0->reg[COP0_RANDOM]);
                                     [COP0_RANDOM]);  
549                          else                          else
550                                  printf("index=0x%016"PRIx64                                  printf("index=0x%016"PRIx64
551                                      " random=0x%016"PRIx64,                                      " random=0x%016"PRIx64,
552                                      (uint64_t)m->cpus[i]->cd.mips.coproc[0]->                                      (uint64_t) cop0->reg[COP0_INDEX],
553                                      reg[COP0_INDEX], (uint64_t)m->cpus[i]->                                      (uint64_t) cop0->reg[COP0_RANDOM]);
                                     cd.mips.coproc[0]->reg[COP0_RANDOM]);  
554    
555                          if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)                          if (m->cpus[i]->cd.mips.cpu_type.isa_level >= 3)
556                                  printf(" wired=0x%"PRIx64, (uint64_t) m->cpus                                  printf(" wired=0x%"PRIx64,
557                                      [i]->cd.mips.coproc[0]->reg[COP0_WIRED]);                                      (uint64_t) cop0->reg[COP0_WIRED]);
558    
559                          printf(")\n");                          printf(")\n");
560    
# Line 519  void mips_cpu_tlbdump(struct machine *m, Line 562  void mips_cpu_tlbdump(struct machine *m,
562                              nr_of_tlb_entries; j++) {                              nr_of_tlb_entries; j++) {
563                                  if (m->cpus[i]->cd.mips.cpu_type.mmu_model ==                                  if (m->cpus[i]->cd.mips.cpu_type.mmu_model ==
564                                      MMU3K)                                      MMU3K)
565                                          printf("%3i: hi=0x%08x lo=0x%08x\n", j,                                          printf("%3i: hi=0x%08"PRIx32" lo=0x%08"
566                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                                              PRIx32"\n", j,
567                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0);                                              (uint32_t) cop0->tlbs[j].hi,
568                                                (uint32_t) cop0->tlbs[j].lo0);
569                                  else if (m->cpus[i]->is_32bit)                                  else if (m->cpus[i]->is_32bit)
570                                          printf("%3i: hi=0x%08x mask=0x%08x "                                          printf("%3i: hi=0x%08"PRIx32" mask=0x"
571                                              "lo0=0x%08x lo1=0x%08x\n", j,                                              "%08"PRIx32" lo0=0x%08"PRIx32
572                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                                              " lo1=0x%08"PRIx32"\n", j,
573                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,                                              (uint32_t) cop0->tlbs[j].hi,
574                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,                                              (uint32_t) cop0->tlbs[j].mask,
575                                              (int)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);                                              (uint32_t) cop0->tlbs[j].lo0,
576                                                (uint32_t) cop0->tlbs[j].lo1);
577                                  else                                  else
578                                          printf("%3i: hi=0x%016"PRIx64" mask=0x%016"PRIx64" "                                          printf("%3i: hi=0x%016"PRIx64" mask="
579                                              "lo0=0x%016"PRIx64" lo1=0x%016"PRIx64"\n", j,                                              "0x%016"PRIx64" lo0=0x%016"PRIx64
580                                              (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi,                                              " lo1=0x%016"PRIx64"\n", j,
581                                              (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask,                                              (uint64_t) cop0->tlbs[j].hi,
582                                              (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0,                                              (uint64_t) cop0->tlbs[j].mask,
583                                              (uint64_t)m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1);                                              (uint64_t) cop0->tlbs[j].lo0,
584                                                (uint64_t) cop0->tlbs[j].lo1);
585                          }                          }
586                  }                  }
587    
588                  return;                  return;
589          }          }
590    
591          /*  Nicely formatted output:  */          /*  Nicely formatted output:  */
592          for (i=0; i<m->ncpus; i++) {          for (i=0; i<m->ncpus; i++) {
593                  int pageshift = 12;                  int pageshift = 12;
594                    struct mips_coproc *cop0 = m->cpus[i]->cd.mips.coproc[0];
595    
596                  if (x >= 0 && i != x)                  if (x >= 0 && i != x)
597                          continue;                          continue;
# Line 556  void mips_cpu_tlbdump(struct machine *m, Line 604  void mips_cpu_tlbdump(struct machine *m,
604                  switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {                  switch (m->cpus[i]->cd.mips.cpu_type.isa_level) {
605                  case 1:                  case 1:
606                  case 2: printf("index=0x%x random=0x%x",                  case 2: printf("index=0x%x random=0x%x",
607                              (int) ((m->cpus[i]->cd.mips.coproc[0]->                              (int) ((cop0->reg[COP0_INDEX] & R2K3K_INDEX_MASK)
                             reg[COP0_INDEX] & R2K3K_INDEX_MASK)  
608                              >> R2K3K_INDEX_SHIFT),                              >> R2K3K_INDEX_SHIFT),
609                              (int) ((m->cpus[i]->cd.mips.coproc[0]->                              (int) ((cop0->reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)
                             reg[COP0_RANDOM] & R2K3K_RANDOM_MASK)  
610                              >> R2K3K_RANDOM_SHIFT));                              >> R2K3K_RANDOM_SHIFT));
611                          break;                          break;
612                  default:printf("index=0x%x random=0x%x",                  default:printf("index=0x%x random=0x%x",
613                              (int) (m->cpus[i]->cd.mips.coproc[0]->                              (int) (cop0->reg[COP0_INDEX] & INDEX_MASK),
614                              reg[COP0_INDEX] & INDEX_MASK),                              (int) (cop0->reg[COP0_RANDOM] & RANDOM_MASK));
615                              (int) (m->cpus[i]->cd.mips.coproc[0]->                          printf(" wired=0x%"PRIx64,
616                              reg[COP0_RANDOM] & RANDOM_MASK));                              (uint64_t) cop0->reg[COP0_WIRED]);
                         printf(" wired=0x%"PRIx64, (uint64_t)  
                             m->cpus[i]->cd.mips.coproc[0]->reg[COP0_WIRED]);  
617                  }                  }
618    
619                  printf(")\n");                  printf(")\n");
620    
621                  for (j=0; j<m->cpus[i]->cd.mips.cpu_type.                  for (j=0; j<m->cpus[i]->cd.mips.cpu_type.
622                      nr_of_tlb_entries; j++) {                      nr_of_tlb_entries; j++) {
623                          uint64_t hi,lo0,lo1,mask;                          uint64_t hi = cop0->tlbs[j].hi;
624                          hi = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].hi;                          uint64_t lo0 = cop0->tlbs[j].lo0;
625                          lo0 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo0;                          uint64_t lo1 = cop0->tlbs[j].lo1;
626                          lo1 = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].lo1;                          uint64_t mask = cop0->tlbs[j].mask;
                         mask = m->cpus[i]->cd.mips.coproc[0]->tlbs[j].mask;  
627    
628                          printf("%3i: ", j);                          printf("%3i: ", j);
629                          switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {                          switch (m->cpus[i]->cd.mips.cpu_type.mmu_model) {
# Line 606  void mips_cpu_tlbdump(struct machine *m, Line 649  void mips_cpu_tlbdump(struct machine *m,
649                                  printf("\n");                                  printf("\n");
650                                  break;                                  break;
651                          default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){                          default:switch (m->cpus[i]->cd.mips.cpu_type.mmu_model){
                                 case MMU10K:  
                                         printf("vaddr=0x%1x..%011"PRIx64" ",  
                                             (int) (hi >> 60), (uint64_t)  
                                             (hi&ENTRYHI_VPN2_MASK_R10K));  
                                         break;  
652                                  case MMU32:                                  case MMU32:
653                                          printf("vaddr=0x%08"PRIx32" ",                                          printf("vaddr=0x%08"PRIx32" ",
654                                              (uint32_t)(hi&ENTRYHI_VPN2_MASK));                                              (uint32_t) hi);
655                                          break;                                          break;
656                                    case MMU10K:
657                                  default:/*  R4000 etc.  */                                  default:/*  R4000 etc.  */
658                                          printf("vaddr=0x%1x..%010"PRIx64" ",                                          printf("vaddr=%016"PRIx64" ",
659                                              (int) (hi >> 60),                                              (uint64_t) hi);
                                             (uint64_t) (hi&ENTRYHI_VPN2_MASK));  
660                                  }                                  }
661                                  if (hi & TLB_G)                                  if (hi & TLB_G)
662                                          printf("(global): ");                                          printf("(global): ");
# Line 664  void mips_cpu_tlbdump(struct machine *m, Line 702  void mips_cpu_tlbdump(struct machine *m,
702    
703    
704  /*  /*
  *  mips_cpu_register_match():  
  */  
 void mips_cpu_register_match(struct machine *m, char *name,  
         int writeflag, uint64_t *valuep, int *match_register)  
 {  
         int cpunr = 0;  
   
         /*  CPU number:  */  
   
         /*  TODO  */  
   
         /*  Register name:  */  
         if (strcasecmp(name, "pc") == 0) {  
                 if (writeflag) {  
                         m->cpus[cpunr]->pc = *valuep;  
                         if (m->cpus[cpunr]->delay_slot) {  
                                 printf("NOTE: Clearing the delay slot"  
                                     " flag! (It was set before.)\n");  
                                 m->cpus[cpunr]->delay_slot = 0;  
                         }  
                         if (m->cpus[cpunr]->cd.mips.nullify_next) {  
                                 printf("NOTE: Clearing the nullify-ne"  
                                     "xt flag! (It was set before.)\n");  
                                 m->cpus[cpunr]->cd.mips.nullify_next = 0;  
                         }  
                 } else  
                         *valuep = m->cpus[cpunr]->pc;  
                 *match_register = 1;  
         } else if (strcasecmp(name, "hi") == 0) {  
                 if (writeflag)  
                         m->cpus[cpunr]->cd.mips.hi = *valuep;  
                 else  
                         *valuep = m->cpus[cpunr]->cd.mips.hi;  
                 *match_register = 1;  
         } else if (strcasecmp(name, "lo") == 0) {  
                 if (writeflag)  
                         m->cpus[cpunr]->cd.mips.lo = *valuep;  
                 else  
                         *valuep = m->cpus[cpunr]->cd.mips.lo;  
                 *match_register = 1;  
         } else if (name[0] == 'r' && isdigit((int)name[1])) {  
                 int nr = atoi(name + 1);  
                 if (nr >= 0 && nr < N_MIPS_GPRS) {  
                         if (writeflag) {  
                                 if (nr != 0)  
                                         m->cpus[cpunr]->cd.mips.gpr[nr] = *valuep;  
                                 else  
                                         printf("WARNING: Attempt to modify r0.\n");  
                         } else  
                                 *valuep = m->cpus[cpunr]->cd.mips.gpr[nr];  
                         *match_register = 1;  
                 }  
         } else {  
                 /*  Check for a symbolic name such as "t6" or "at":  */  
                 int nr;  
                 for (nr=0; nr<N_MIPS_GPRS; nr++)  
                         if (strcmp(name, regnames[nr]) == 0) {  
                                 if (writeflag) {  
                                         if (nr != 0)  
                                                 m->cpus[cpunr]->cd.mips.gpr[nr] = *valuep;  
                                         else  
                                                 printf("WARNING: Attempt to modify r0.\n");  
                                 } else  
                                         *valuep = m->cpus[cpunr]->cd.mips.gpr[nr];  
                                 *match_register = 1;  
                         }  
         }  
   
         if (!(*match_register)) {  
                 /*  Check for a symbolic coproc0 name:  */  
                 int nr;  
                 for (nr=0; nr<32; nr++)  
                         if (strcmp(name, cop0_names[nr]) == 0) {  
                                 if (writeflag) {  
                                         coproc_register_write(m->cpus[cpunr],  
                                             m->cpus[cpunr]->cd.mips.coproc[0], nr,  
                                             valuep, 1, 0);  
                                 } else {  
                                         /*  TODO: Use coproc_register_read instead?  */  
                                         *valuep = m->cpus[cpunr]->cd.mips.coproc[0]->reg[nr];  
                                 }  
                                 *match_register = 1;  
                         }  
         }  
   
         /*  TODO: Coprocessor 1,2,3 registers.  */  
   
         /*  Only return lowest 32 bits when doing 32-bit emulation:  */  
         if (!writeflag && m->cpus[cpunr]->is_32bit)  
                 *valuep = (uint32_t) (*valuep);  
 }  
   
   
 /*  
  *  cpu_flags():  
  *  
  *  Returns a pointer to a string containing "(d)" "(j)" "(dj)" or "",  
  *  depending on the cpu's current delay_slot and last_was_jumptoself  
  *  flags.  
  */  
 static const char *cpu_flags(struct cpu *cpu)  
 {  
         if (cpu->delay_slot) {  
                 if (cpu->cd.mips.last_was_jumptoself)  
                         return " (dj)";  
                 else  
                         return " (d)";  
         } else {  
                 if (cpu->cd.mips.last_was_jumptoself)  
                         return " (j)";  
                 else  
                         return "";  
         }  
 }  
   
   
 /*  
705   *  mips_cpu_disassemble_instr():   *  mips_cpu_disassemble_instr():
706   *   *
707   *  Convert an instruction word into human readable format, for instruction   *  Convert an instruction word into human readable format, for instruction
# Line 797  static const char *cpu_flags(struct cpu Line 718  static const char *cpu_flags(struct cpu
718  int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr,  int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr,
719          int running, uint64_t dumpaddr)          int running, uint64_t dumpaddr)
720  {  {
721          int hi6, special6, regimm5;          int hi6, special6, regimm5, sub;
722          int rt, rd, rs, sa, imm, copz, cache_op, which_cache, showtag;          int rt, rd, rs, sa, imm, copz, cache_op, which_cache, showtag;
723          uint64_t addr, offset;          uint64_t addr, offset;
724          uint32_t instrword;          uint32_t instrword;
# Line 839  int mips_cpu_disassemble_instr(struct cp Line 760  int mips_cpu_disassemble_instr(struct cp
760          debug(": %02x%02x%02x%02x",          debug(": %02x%02x%02x%02x",
761              instr[3], instr[2], instr[1], instr[0]);              instr[3], instr[2], instr[1], instr[0]);
762    
763          if (running)          if (running && cpu->delay_slot)
764                  debug("%s", cpu_flags(cpu));                  debug(" (d)");
765    
766          debug("\t");          debug("\t");
767    
# Line 848  int mips_cpu_disassemble_instr(struct cp Line 769  int mips_cpu_disassemble_instr(struct cp
769           *  Decode the instruction:           *  Decode the instruction:
770           */           */
771    
         if (cpu->cd.mips.nullify_next && running) {  
                 debug("(nullified)");  
                 goto disasm_ret;  
         }  
   
772          hi6 = (instr[3] >> 2) & 0x3f;          hi6 = (instr[3] >> 2) & 0x3f;
773    
774          switch (hi6) {          switch (hi6) {
# Line 868  int mips_cpu_disassemble_instr(struct cp Line 784  int mips_cpu_disassemble_instr(struct cp
784                  case SPECIAL_DSLL32:                  case SPECIAL_DSLL32:
785                  case SPECIAL_DSRL32:                  case SPECIAL_DSRL32:
786                  case SPECIAL_DSRA32:                  case SPECIAL_DSRA32:
787                            sub = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
788                          rt = instr[2] & 31;                          rt = instr[2] & 31;
789                          rd = (instr[1] >> 3) & 31;                          rd = (instr[1] >> 3) & 31;
790                          sa = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);                          sa = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
# Line 881  int mips_cpu_disassemble_instr(struct cp Line 798  int mips_cpu_disassemble_instr(struct cp
798                                          debug("ehb");                                          debug("ehb");
799                                  else                                  else
800                                          debug("nop (weird, sa=%i)", sa);                                          debug("nop (weird, sa=%i)", sa);
801                                  goto disasm_ret;                                  break;
802                          } else                          }
803    
804                            switch (sub) {
805                            case 0x00:
806                                  debug("%s\t%s,",                                  debug("%s\t%s,",
807                                      special_names[special6],                                      special_names[special6],
808                                      regname(cpu->machine, rd));                                      regname(cpu->machine, rd));
809                                  debug("%s,%i", regname(cpu->machine, rt), sa);                                  debug("%s,%i", regname(cpu->machine, rt), sa);
810                                    break;
811                            case 0x01:
812                                    debug("%s\t%s,",
813                                        special_rot_names[special6],
814                                        regname(cpu->machine, rd));
815                                    debug("%s,%i", regname(cpu->machine, rt), sa);
816                                    break;
817                            default:debug("UNIMPLEMENTED special, sub=0x%02x\n",
818                                        sub);
819                            }
820                          break;                          break;
821                  case SPECIAL_DSRLV:                  case SPECIAL_DSRLV:
822                  case SPECIAL_DSRAV:                  case SPECIAL_DSRAV:
# Line 897  int mips_cpu_disassemble_instr(struct cp Line 827  int mips_cpu_disassemble_instr(struct cp
827                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
828                          rt = instr[2] & 31;                          rt = instr[2] & 31;
829                          rd = (instr[1] >> 3) & 31;                          rd = (instr[1] >> 3) & 31;
830                          debug("%s\t%s",                          sub = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
831                              special_names[special6], regname(cpu->machine, rd));  
832                          debug(",%s", regname(cpu->machine, rt));                          switch (sub) {
833                          debug(",%s", regname(cpu->machine, rs));                          case 0x00:
834                                    debug("%s\t%s", special_names[special6],
835                                        regname(cpu->machine, rd));
836                                    debug(",%s", regname(cpu->machine, rt));
837                                    debug(",%s", regname(cpu->machine, rs));
838                                    break;
839                            case 0x01:
840                                    debug("%s\t%s", special_rot_names[special6],
841                                        regname(cpu->machine, rd));
842                                    debug(",%s", regname(cpu->machine, rt));
843                                    debug(",%s", regname(cpu->machine, rs));
844                                    break;
845                            default:debug("UNIMPLEMENTED special, sub=0x%02x\n",
846                                        sub);
847                            }
848                          break;                          break;
849                  case SPECIAL_JR:                  case SPECIAL_JR:
850                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
851                          symbol = get_symbol_name(&cpu->machine->symbol_context,                          symbol = get_symbol_name(&cpu->machine->symbol_context,
852                              cpu->cd.mips.gpr[rs], &offset);                              cpu->cd.mips.gpr[rs], &offset);
853                          debug("jr\t%s", regname(cpu->machine, rs));                          /*  .hb = hazard barrier hint on MIPS32/64 rev 2  */
854                            debug("jr%s\t%s",
855                                (instr[1] & 0x04) ? ".hb" : "",
856                                regname(cpu->machine, rs));
857                          if (running && symbol != NULL)                          if (running && symbol != NULL)
858                                  debug("\t<%s>", symbol);                                  debug("\t<%s>", symbol);
859                          break;                          break;
# Line 915  int mips_cpu_disassemble_instr(struct cp Line 862  int mips_cpu_disassemble_instr(struct cp
862                          rd = (instr[1] >> 3) & 31;                          rd = (instr[1] >> 3) & 31;
863                          symbol = get_symbol_name(&cpu->machine->symbol_context,                          symbol = get_symbol_name(&cpu->machine->symbol_context,
864                              cpu->cd.mips.gpr[rs], &offset);                              cpu->cd.mips.gpr[rs], &offset);
865                          debug("jalr\t%s", regname(cpu->machine, rd));                          /*  .hb = hazard barrier hint on MIPS32/64 rev 2  */
866                            debug("jalr%s\t%s",
867                                (instr[1] & 0x04) ? ".hb" : "",
868                                regname(cpu->machine, rd));
869                          debug(",%s", regname(cpu->machine, rs));                          debug(",%s", regname(cpu->machine, rs));
870                          if (running && symbol != NULL)                          if (running && symbol != NULL)
871                                  debug("\t<%s>", symbol);                                  debug("\t<%s>", symbol);
# Line 1152  int mips_cpu_disassemble_instr(struct cp Line 1102  int mips_cpu_disassemble_instr(struct cp
1102                  }                  }
1103                  if (hi6 == HI6_SQ_SPECIAL3 &&                  if (hi6 == HI6_SQ_SPECIAL3 &&
1104                      cpu->cd.mips.cpu_type.rev != MIPS_R5900) {                      cpu->cd.mips.cpu_type.rev != MIPS_R5900) {
1105                            int msbd, lsb, sub10;
1106                          special6 = instr[0] & 0x3f;                          special6 = instr[0] & 0x3f;
                         debug("%s", special3_names[special6]);  
1107                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1108                          rt = instr[2] & 31;                          rt = instr[2] & 31;
1109                          rd = (instr[1] >> 3) & 31;                          rd = msbd = (instr[1] >> 3) & 31;
1110                            lsb = ((instr[1] & 7) << 2) | (instr[0] >> 6);
1111                            sub10 = (rs << 5) | lsb;
1112    
1113                          switch (special6) {                          switch (special6) {
1114    
1115                            case SPECIAL3_EXT:
1116                            case SPECIAL3_DEXT:
1117                            case SPECIAL3_DEXTM:
1118                            case SPECIAL3_DEXTU:
1119                                    debug("%s", special3_names[special6]);
1120                                    if (special6 == SPECIAL3_DEXTM)
1121                                            msbd += 32;
1122                                    if (special6 == SPECIAL3_DEXTU)
1123                                            lsb += 32;
1124                                    debug("\t%s", regname(cpu->machine, rt));
1125                                    debug(",%s", regname(cpu->machine, rs));
1126                                    debug(",%i,%i", lsb, msbd + 1);
1127                                    break;
1128    
1129                            case SPECIAL3_INS:
1130                            case SPECIAL3_DINS:
1131                            case SPECIAL3_DINSM:
1132                            case SPECIAL3_DINSU:
1133                                    debug("%s", special3_names[special6]);
1134                                    if (special6 == SPECIAL3_DINSM)
1135                                            msbd += 32;
1136                                    if (special6 == SPECIAL3_DINSU) {
1137                                            lsb += 32;
1138                                            msbd += 32;
1139                                    }
1140                                    msbd -= lsb;
1141                                    debug("\t%s", regname(cpu->machine, rt));
1142                                    debug(",%s", regname(cpu->machine, rs));
1143                                    debug(",%i,%i", lsb, msbd + 1);
1144                                    break;
1145    
1146                            case SPECIAL3_BSHFL:
1147                                    switch (sub10) {
1148                                    case BSHFL_WSBH:
1149                                    case BSHFL_SEB:
1150                                    case BSHFL_SEH:
1151                                            switch (sub10) {
1152                                            case BSHFL_WSBH: debug("wsbh"); break;
1153                                            case BSHFL_SEB:  debug("seb"); break;
1154                                            case BSHFL_SEH:  debug("seh"); break;
1155                                            }
1156                                            debug("\t%s", regname(cpu->machine,rd));
1157                                            debug(",%s", regname(cpu->machine,rt));
1158                                            break;
1159                                    default:debug("%s", special3_names[special6]);
1160                                            debug("\t(UNIMPLEMENTED)");
1161                                    }
1162                                    break;
1163    
1164                            case SPECIAL3_DBSHFL:
1165                                    switch (sub10) {
1166                                    case BSHFL_DSBH:
1167                                    case BSHFL_DSHD:
1168                                            switch (sub10) {
1169                                            case BSHFL_DSBH: debug("dsbh"); break;
1170                                            case BSHFL_DSHD: debug("dshd"); break;
1171                                            }
1172                                            debug("\t%s", regname(cpu->machine,rd));
1173                                            debug(",%s", regname(cpu->machine,rt));
1174                                            break;
1175                                    default:debug("%s", special3_names[special6]);
1176                                            debug("\t(UNIMPLEMENTED)");
1177                                    }
1178                                    break;
1179    
1180                          case SPECIAL3_RDHWR:                          case SPECIAL3_RDHWR:
1181                                    debug("%s", special3_names[special6]);
1182                                  debug("\t%s", regname(cpu->machine, rt));                                  debug("\t%s", regname(cpu->machine, rt));
1183                                  debug(",hwr%i", rd);                                  debug(",hwr%i", rd);
1184                                  break;                                  break;
1185    
1186                          default:                          default:debug("%s", special3_names[special6]);
1187                                  debug("\t(UNIMPLEMENTED)");                                  debug("\t(UNIMPLEMENTED)");
1188                          }                          }
1189                          break;                          break;
# Line 1277  int mips_cpu_disassemble_instr(struct cp Line 1295  int mips_cpu_disassemble_instr(struct cp
1295                  if (cache_op==2)        debug("index store tag"), showtag=1;                  if (cache_op==2)        debug("index store tag"), showtag=1;
1296                  if (cache_op==3)        debug("create dirty exclusive");                  if (cache_op==3)        debug("create dirty exclusive");
1297                  if (cache_op==4)        debug("hit invalidate");                  if (cache_op==4)        debug("hit invalidate");
1298                  if (cache_op==5)        debug("fill OR hit writeback invalidate");                  if (cache_op==5)     debug("fill OR hit writeback invalidate");
1299                  if (cache_op==6)        debug("hit writeback");                  if (cache_op==6)        debug("hit writeback");
1300                  if (cache_op==7)        debug("hit set virtual");                  if (cache_op==7)        debug("hit set virtual");
1301                  if (running)                  if (running)
# Line 1450  int mips_cpu_disassemble_instr(struct cp Line 1468  int mips_cpu_disassemble_instr(struct cp
1468    
1469          case HI6_REGIMM:          case HI6_REGIMM:
1470                  regimm5 = instr[2] & 0x1f;                  regimm5 = instr[2] & 0x1f;
1471                    rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1472                    imm = (instr[1] << 8) + instr[0];
1473                    if (imm >= 32768)              
1474                            imm -= 65536;
1475    
1476                  switch (regimm5) {                  switch (regimm5) {
1477    
1478                  case REGIMM_BLTZ:                  case REGIMM_BLTZ:
1479                  case REGIMM_BGEZ:                  case REGIMM_BGEZ:
1480                  case REGIMM_BLTZL:                  case REGIMM_BLTZL:
# Line 1459  int mips_cpu_disassemble_instr(struct cp Line 1483  int mips_cpu_disassemble_instr(struct cp
1483                  case REGIMM_BLTZALL:                  case REGIMM_BLTZALL:
1484                  case REGIMM_BGEZAL:                  case REGIMM_BGEZAL:
1485                  case REGIMM_BGEZALL:                  case REGIMM_BGEZALL:
                         rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);  
                         imm = (instr[1] << 8) + instr[0];  
                         if (imm >= 32768)                
                                 imm -= 65536;  
   
1486                          debug("%s\t%s,", regimm_names[regimm5],                          debug("%s\t%s,", regimm_names[regimm5],
1487                              regname(cpu->machine, rs));                              regname(cpu->machine, rs));
1488    
# Line 1474  int mips_cpu_disassemble_instr(struct cp Line 1493  int mips_cpu_disassemble_instr(struct cp
1493                          else                          else
1494                                  debug("0x%016"PRIx64, (uint64_t) addr);                                  debug("0x%016"PRIx64, (uint64_t) addr);
1495                          break;                          break;
1496    
1497                    case REGIMM_SYNCI:
1498                            debug("%s\t%i(%s)", regimm_names[regimm5],
1499                                imm, regname(cpu->machine, rs));
1500                            break;
1501    
1502                  default:                  default:
1503                          debug("unimplemented regimm5 = 0x%02x", regimm5);                          debug("unimplemented regimm5 = 0x%02x", regimm5);
1504                  }                  }
# Line 1551  void mips_cpu_register_dump(struct cpu * Line 1576  void mips_cpu_register_dump(struct cpu *
1576                                              "          ");                                              "          ");
1577                                  else                                  else
1578                                          debug(" %3s=%016"PRIx64"%016"PRIx64,                                          debug(" %3s=%016"PRIx64"%016"PRIx64,
1579                                              regname(cpu->machine, r),                                              regname(cpu->machine, r), (uint64_t)
1580                                              (uint64_t)cpu->cd.mips.gpr_quadhi[r],                                              cpu->cd.mips.gpr_quadhi[r],
1581                                              (uint64_t)cpu->cd.mips.gpr[r]);                                              (uint64_t)cpu->cd.mips.gpr[r]);
1582                                  if ((i & 1) == 1)                                  if ((i & 1) == 1)
1583                                          debug("\n");                                          debug("\n");
# Line 1616  void mips_cpu_register_dump(struct cpu * Line 1641  void mips_cpu_register_dump(struct cpu *
1641                                  debug(" c%i,%02i", coprocnr, i);                                  debug(" c%i,%02i", coprocnr, i);
1642    
1643                          if (bits32)                          if (bits32)
1644                                  debug("=%08x", (int)cpu->cd.mips.coproc[coprocnr]->reg[i]);                                  debug("=%08x", (int)cpu->cd.mips.
1645                                        coproc[coprocnr]->reg[i]);
1646                          else {                          else {
1647                                  if (coprocnr == 0 && (i == COP0_COUNT                                  if (coprocnr == 0 && (i == COP0_COUNT
1648                                      || i == COP0_COMPARE || i == COP0_INDEX                                      || i == COP0_COMPARE || i == COP0_INDEX
1649                                      || i == COP0_RANDOM || i == COP0_WIRED))                                      || i == COP0_RANDOM || i == COP0_WIRED))
1650                                          debug(" =         0x%08x", (int)cpu->cd.mips.coproc[coprocnr]->reg[i]);                                          debug(" =         0x%08x",
1651                                                (int) cpu->cd.mips.coproc[
1652                                                coprocnr]->reg[i]);
1653                                  else                                  else
1654                                          debug(" = 0x%016"PRIx64, (uint64_t)                                          debug(" = 0x%016"PRIx64, (uint64_t)
1655                                              cpu->cd.mips.coproc[coprocnr]->reg[i]);                                              cpu->cd.mips.coproc[
1656                                                coprocnr]->reg[i]);
1657                          }                          }
1658    
1659                          if ((i & nm1) == nm1)                          if ((i & nm1) == nm1)
# Line 1676  void mips_cpu_register_dump(struct cpu * Line 1705  void mips_cpu_register_dump(struct cpu *
1705  }  }
1706    
1707    
 static void add_response_word(struct cpu *cpu, char *r, uint64_t value,  
         size_t maxlen, int len)  
 {  
         char *format = (len == 4)? "%08"PRIx64 : "%016"PRIx64;  
         if (len == 4)  
                 value &= 0xffffffffULL;  
         if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {  
                 if (len == 4) {  
                         value = ((value & 0xff) << 24) +  
                                 ((value & 0xff00) << 8) +  
                                 ((value & 0xff0000) >> 8) +  
                                 ((value & 0xff000000) >> 24);  
                 } else {  
                         value = ((value & 0xff) << 56) +  
                                 ((value & 0xff00) << 40) +  
                                 ((value & 0xff0000) << 24) +  
                                 ((value & 0xff000000ULL) << 8) +  
                                 ((value & 0xff00000000ULL) >> 8) +  
                                 ((value & 0xff0000000000ULL) >> 24) +  
                                 ((value & 0xff000000000000ULL) >> 40) +  
                                 ((value & 0xff00000000000000ULL) >> 56);  
                 }  
         }  
         snprintf(r + strlen(r), maxlen - strlen(r), format, (uint64_t)value);  
 }  
   
   
 /*  
  *  mips_cpu_gdb_stub():  
  *  
  *  Execute a "remote GDB" command. Returns 1 on success, 0 on error.  
  */  
 char *mips_cpu_gdb_stub(struct cpu *cpu, char *cmd)  
 {  
         if (strcmp(cmd, "g") == 0) {  
                 /*  76 registers:  gprs, sr, lo, hi, badvaddr, cause, pc,  
                     fprs, fsr, fir, fp.  */  
                 int i;  
                 char *r;  
                 size_t wlen = cpu->is_32bit?  
                     sizeof(uint32_t) : sizeof(uint64_t);  
                 size_t len = 1 + 76 * wlen;  
                 r = malloc(len);  
                 if (r == NULL) {  
                         fprintf(stderr, "out of memory\n");  
                         exit(1);  
                 }  
                 r[0] = '\0';  
                 for (i=0; i<32; i++)  
                         add_response_word(cpu, r, cpu->cd.mips.gpr[i],  
                             len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[0]->reg[COP0_STATUS], len, wlen);  
                 add_response_word(cpu, r, cpu->cd.mips.lo, len, wlen);  
                 add_response_word(cpu, r, cpu->cd.mips.hi, len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[0]->reg[COP0_BADVADDR], len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[0]->reg[COP0_CAUSE], len, wlen);  
                 add_response_word(cpu, r, cpu->pc, len, wlen);  
                 for (i=0; i<32; i++)  
                         add_response_word(cpu, r,  
                             cpu->cd.mips.coproc[1]->reg[i], len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[1]->reg[31] /* fcsr */, len, wlen);  
                 add_response_word(cpu, r,  
                     cpu->cd.mips.coproc[1]->reg[0] /* fcir */, len, wlen);  
   
                 /*  TODO: fp = gpr 30?  */  
                 add_response_word(cpu, r, cpu->cd.mips.gpr[30], len, wlen);  
   
                 return r;  
         }  
   
         if (cmd[0] == 'p') {  
                 int regnr = strtol(cmd + 1, NULL, 16);  
                 size_t wlen = cpu->is_32bit? sizeof(uint32_t):sizeof(uint64_t);  
                 size_t len = 2 * wlen + 1;  
                 char *r = malloc(len);  
                 r[0] = '\0';  
                 if (regnr >= 0 && regnr <= 31) {  
                         add_response_word(cpu, r,  
                             cpu->cd.mips.gpr[regnr], len, wlen);  
                 } else if (regnr == 0x20) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[0]->  
                             reg[COP0_STATUS], len, wlen);  
                 } else if (regnr == 0x21) {  
                         add_response_word(cpu, r, cpu->cd.mips.lo, len, wlen);  
                 } else if (regnr == 0x22) {  
                         add_response_word(cpu, r, cpu->cd.mips.hi, len, wlen);  
                 } else if (regnr == 0x23) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[0]->  
                             reg[COP0_BADVADDR], len, wlen);  
                 } else if (regnr == 0x24) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[0]->  
                             reg[COP0_CAUSE], len, wlen);  
                 } else if (regnr == 0x25) {  
                         add_response_word(cpu, r, cpu->pc, len, wlen);  
                 } else if (regnr >= 0x26 && regnr <= 0x45 &&  
                     cpu->cd.mips.coproc[1] != NULL) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[1]->  
                             reg[regnr - 0x26], len, wlen);  
                 } else if (regnr == 0x46) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[1]->  
                             fcr[MIPS_FPU_FCSR], len, wlen);  
                 } else if (regnr == 0x47) {  
                         add_response_word(cpu, r, cpu->cd.mips.coproc[1]->  
                             fcr[MIPS_FPU_FCIR], len, wlen);  
                 } else {  
                         /*  Unimplemented:  */  
                         add_response_word(cpu, r, 0xcc000 + regnr, len, wlen);  
                 }  
                 return r;  
         }  
   
         fatal("mips_cpu_gdb_stub(): cmd='%s' TODO\n", cmd);  
         return NULL;  
 }  
   
   
1708  /*  /*
1709   *  mips_cpu_interrupt():   *  mips_cpu_interrupt_assert(), mips_cpu_interrupt_deassert():
  *  
  *  Cause an interrupt. If irq_nr is 2..7, then it is a MIPS hardware  
  *  interrupt. 0 and 1 are ignored (software interrupts).  
1710   *   *
1711   *  If irq_nr is >= 8, then this function calls md_interrupt().   *  Assert or deassert a MIPS CPU interrupt by masking in or out bits
1712     *  in the CAUSE register of coprocessor 0.
1713   */   */
1714  int mips_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr)  void mips_cpu_interrupt_assert(struct interrupt *interrupt)
1715  {  {
1716          if (irq_nr >= 8) {          struct cpu *cpu = interrupt->extra;
1717                  if (cpu->machine->md_interrupt != NULL)          cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] |= interrupt->line;
                         cpu->machine->md_interrupt(cpu->machine,  
                             cpu, irq_nr, 1);  
                 else  
                         fatal("mips_cpu_interrupt(): irq_nr = %i, "  
                             "but md_interrupt = NULL ?\n", irq_nr);  
                 return 1;  
         }  
   
         if (irq_nr < 2)  
                 return 0;  
   
         cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] |=  
             ((1 << irq_nr) << STATUS_IM_SHIFT);  
   
         return 1;  
1718  }  }
1719    void mips_cpu_interrupt_deassert(struct interrupt *interrupt)
   
 /*  
  *  mips_cpu_interrupt_ack():  
  *  
  *  Acknowledge an interrupt. If irq_nr is 2..7, then it is a MIPS hardware  
  *  interrupt.  Interrupts 0..1 are ignored (software interrupts).  
  *  
  *  If irq_nr is >= 8, then it is machine dependent, and md_interrupt() is  
  *  called.  
  */  
 int mips_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr)  
1720  {  {
1721          if (irq_nr >= 8) {          struct cpu *cpu = interrupt->extra;
1722                  if (cpu->machine->md_interrupt != NULL)          cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] &= ~interrupt->line;
                         cpu->machine->md_interrupt(cpu->machine, cpu,  
                             irq_nr, 0);  
                 else  
                         fatal("mips_cpu_interrupt_ack(): irq_nr = %i, "  
                             "but md_interrupt = NULL ?\n", irq_nr);  
                 return 1;  
         }  
   
         if (irq_nr < 2)  
                 return 0;  
   
         cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] &=  
             ~((1 << irq_nr) << STATUS_IM_SHIFT);  
   
         return 1;  
1723  }  }
1724    
1725    
# Line 2046  void mips_cpu_exception(struct cpu *cpu, Line 1912  void mips_cpu_exception(struct cpu *cpu,
1912                  /*  debug("[ warning: cpu%i exception while EXL is set,"                  /*  debug("[ warning: cpu%i exception while EXL is set,"
1913                      " not setting EPC ]\n", cpu->cpu_id);  */                      " not setting EPC ]\n", cpu->cpu_id);  */
1914          } else {          } else {
1915                  if (cpu->delay_slot || cpu->cd.mips.nullify_next) {                  if (cpu->delay_slot) {
1916                          reg[COP0_EPC] = cpu->pc - 4;                          reg[COP0_EPC] = cpu->pc - 4;
1917                          reg[COP0_CAUSE] |= CAUSE_BD;                          reg[COP0_CAUSE] |= CAUSE_BD;
   
                         /*  TODO: Should the BD flag actually be set  
                             on nullified slots?  */  
1918                  } else {                  } else {
1919                          reg[COP0_EPC] = cpu->pc;                          reg[COP0_EPC] = cpu->pc;
1920                          reg[COP0_CAUSE] &= ~CAUSE_BD;                          reg[COP0_CAUSE] &= ~CAUSE_BD;
# Line 2063  void mips_cpu_exception(struct cpu *cpu, Line 1926  void mips_cpu_exception(struct cpu *cpu,
1926          else          else
1927                  cpu->delay_slot = NOT_DELAYED;                  cpu->delay_slot = NOT_DELAYED;
1928    
         cpu->cd.mips.nullify_next = 0;  
   
1929          /*  TODO: This is true for MIPS64, but how about others?  */          /*  TODO: This is true for MIPS64, but how about others?  */
1930          if (reg[COP0_STATUS] & STATUS_BEV)          if (reg[COP0_STATUS] & STATUS_BEV)
1931                  base = 0xffffffffbfc00200ULL;                  base = 0xffffffffbfc00200ULL;

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

  ViewVC Help
Powered by ViewVC 1.1.26