/[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 31 by dpavlin, Mon Oct 8 16:20:40 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# 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.69 2006/10/07 02:05:21 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 323  int mips_cpu_new(struct cpu *cpu, struct Line 325  int mips_cpu_new(struct cpu *cpu, struct
325                          cpu->translate_v2p = translate_v2p_generic;                          cpu->translate_v2p = translate_v2p_generic;
326          }          }
327    
328            if (cpu->machine->prom_emulation) {
329                    /*
330                     *  Default behaviour of jumping to 0xbfc00000 should be
331                     *  a reboot, unless machine-specific initialization code
332                     *  overrides this.
333                     *
334                     *  Note: Specifically big-endian machines should override
335                     *  this, since the default MIPS CPU is little-endian!
336                     */
337                    store_32bit_word(cpu, 0xffffffff9fc00000ULL, 0x00c0de0d);
338            }
339    
340            /*  Add all register names to the settings:  */
341            CPU_SETTINGS_ADD_REGISTER64("pc", cpu->pc);
342            CPU_SETTINGS_ADD_REGISTER64("hi", cpu->cd.mips.hi);
343            CPU_SETTINGS_ADD_REGISTER64("lo", cpu->cd.mips.lo);
344            for (i=0; i<N_MIPS_GPRS; i++)
345                    CPU_SETTINGS_ADD_REGISTER64(regnames[i], cpu->cd.mips.gpr[i]);
346            /*  TODO: Write via special handler function!  */
347            for (i=0; i<N_MIPS_COPROC_REGS; i++)
348                    CPU_SETTINGS_ADD_REGISTER64(cop0_names[i],
349                        cpu->cd.mips.coproc[0]->reg[i]);
350    
351          return 1;          return 1;
352  }  }
353    
# Line 606  void mips_cpu_tlbdump(struct machine *m, Line 631  void mips_cpu_tlbdump(struct machine *m,
631                                  printf("\n");                                  printf("\n");
632                                  break;                                  break;
633                          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;  
634                                  case MMU32:                                  case MMU32:
635                                          printf("vaddr=0x%08"PRIx32" ",                                          printf("vaddr=0x%08"PRIx32" ",
636                                              (uint32_t)(hi&ENTRYHI_VPN2_MASK));                                              (uint32_t) hi);
637                                          break;                                          break;
638                                    case MMU10K:
639                                  default:/*  R4000 etc.  */                                  default:/*  R4000 etc.  */
640                                          printf("vaddr=0x%1x..%010"PRIx64" ",                                          printf("vaddr=%016"PRIx64" ",
641                                              (int) (hi >> 60),                                              (uint64_t) hi);
                                             (uint64_t) (hi&ENTRYHI_VPN2_MASK));  
642                                  }                                  }
643                                  if (hi & TLB_G)                                  if (hi & TLB_G)
644                                          printf("(global): ");                                          printf("(global): ");
# Line 664  void mips_cpu_tlbdump(struct machine *m, Line 684  void mips_cpu_tlbdump(struct machine *m,
684    
685    
686  /*  /*
  *  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 "";  
         }  
 }  
   
   
 /*  
687   *  mips_cpu_disassemble_instr():   *  mips_cpu_disassemble_instr():
688   *   *
689   *  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 700  static const char *cpu_flags(struct cpu
700  int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr,  int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *originstr,
701          int running, uint64_t dumpaddr)          int running, uint64_t dumpaddr)
702  {  {
703          int hi6, special6, regimm5;          int hi6, special6, regimm5, sub;
704          int rt, rd, rs, sa, imm, copz, cache_op, which_cache, showtag;          int rt, rd, rs, sa, imm, copz, cache_op, which_cache, showtag;
705          uint64_t addr, offset;          uint64_t addr, offset;
706          uint32_t instrword;          uint32_t instrword;
# Line 839  int mips_cpu_disassemble_instr(struct cp Line 742  int mips_cpu_disassemble_instr(struct cp
742          debug(": %02x%02x%02x%02x",          debug(": %02x%02x%02x%02x",
743              instr[3], instr[2], instr[1], instr[0]);              instr[3], instr[2], instr[1], instr[0]);
744    
745          if (running)          if (running && cpu->delay_slot)
746                  debug("%s", cpu_flags(cpu));                  debug(" (d)");
747    
748          debug("\t");          debug("\t");
749    
# Line 848  int mips_cpu_disassemble_instr(struct cp Line 751  int mips_cpu_disassemble_instr(struct cp
751           *  Decode the instruction:           *  Decode the instruction:
752           */           */
753    
         if (cpu->cd.mips.nullify_next && running) {  
                 debug("(nullified)");  
                 goto disasm_ret;  
         }  
   
754          hi6 = (instr[3] >> 2) & 0x3f;          hi6 = (instr[3] >> 2) & 0x3f;
755    
756          switch (hi6) {          switch (hi6) {
# Line 868  int mips_cpu_disassemble_instr(struct cp Line 766  int mips_cpu_disassemble_instr(struct cp
766                  case SPECIAL_DSLL32:                  case SPECIAL_DSLL32:
767                  case SPECIAL_DSRL32:                  case SPECIAL_DSRL32:
768                  case SPECIAL_DSRA32:                  case SPECIAL_DSRA32:
769                            sub = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
770                          rt = instr[2] & 31;                          rt = instr[2] & 31;
771                          rd = (instr[1] >> 3) & 31;                          rd = (instr[1] >> 3) & 31;
772                          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 780  int mips_cpu_disassemble_instr(struct cp
780                                          debug("ehb");                                          debug("ehb");
781                                  else                                  else
782                                          debug("nop (weird, sa=%i)", sa);                                          debug("nop (weird, sa=%i)", sa);
783                                  goto disasm_ret;                                  break;
784                          } else                          }
785    
786                            switch (sub) {
787                            case 0x00:
788                                  debug("%s\t%s,",                                  debug("%s\t%s,",
789                                      special_names[special6],                                      special_names[special6],
790                                      regname(cpu->machine, rd));                                      regname(cpu->machine, rd));
791                                  debug("%s,%i", regname(cpu->machine, rt), sa);                                  debug("%s,%i", regname(cpu->machine, rt), sa);
792                                    break;
793                            case 0x01:
794                                    debug("%s\t%s,",
795                                        special_rot_names[special6],
796                                        regname(cpu->machine, rd));
797                                    debug("%s,%i", regname(cpu->machine, rt), sa);
798                                    break;
799                            default:debug("UNIMPLEMENTED special, sub=0x%02x\n",
800                                        sub);
801                            }
802                          break;                          break;
803                  case SPECIAL_DSRLV:                  case SPECIAL_DSRLV:
804                  case SPECIAL_DSRAV:                  case SPECIAL_DSRAV:
# Line 897  int mips_cpu_disassemble_instr(struct cp Line 809  int mips_cpu_disassemble_instr(struct cp
809                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
810                          rt = instr[2] & 31;                          rt = instr[2] & 31;
811                          rd = (instr[1] >> 3) & 31;                          rd = (instr[1] >> 3) & 31;
812                          debug("%s\t%s",                          sub = ((instr[1] & 7) << 2) + ((instr[0] >> 6) & 3);
813                              special_names[special6], regname(cpu->machine, rd));  
814                          debug(",%s", regname(cpu->machine, rt));                          switch (sub) {
815                          debug(",%s", regname(cpu->machine, rs));                          case 0x00:
816                                    debug("%s\t%s", special_names[special6],
817                                        regname(cpu->machine, rd));
818                                    debug(",%s", regname(cpu->machine, rt));
819                                    debug(",%s", regname(cpu->machine, rs));
820                                    break;
821                            case 0x01:
822                                    debug("%s\t%s", special_rot_names[special6],
823                                        regname(cpu->machine, rd));
824                                    debug(",%s", regname(cpu->machine, rt));
825                                    debug(",%s", regname(cpu->machine, rs));
826                                    break;
827                            default:debug("UNIMPLEMENTED special, sub=0x%02x\n",
828                                        sub);
829                            }
830                          break;                          break;
831                  case SPECIAL_JR:                  case SPECIAL_JR:
832                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
833                          symbol = get_symbol_name(&cpu->machine->symbol_context,                          symbol = get_symbol_name(&cpu->machine->symbol_context,
834                              cpu->cd.mips.gpr[rs], &offset);                              cpu->cd.mips.gpr[rs], &offset);
835                          debug("jr\t%s", regname(cpu->machine, rs));                          /*  .hb = hazard barrier hint on MIPS32/64 rev 2  */
836                            debug("jr%s\t%s",
837                                (instr[1] & 0x04) ? ".hb" : "",
838                                regname(cpu->machine, rs));
839                          if (running && symbol != NULL)                          if (running && symbol != NULL)
840                                  debug("\t<%s>", symbol);                                  debug("\t<%s>", symbol);
841                          break;                          break;
# Line 915  int mips_cpu_disassemble_instr(struct cp Line 844  int mips_cpu_disassemble_instr(struct cp
844                          rd = (instr[1] >> 3) & 31;                          rd = (instr[1] >> 3) & 31;
845                          symbol = get_symbol_name(&cpu->machine->symbol_context,                          symbol = get_symbol_name(&cpu->machine->symbol_context,
846                              cpu->cd.mips.gpr[rs], &offset);                              cpu->cd.mips.gpr[rs], &offset);
847                          debug("jalr\t%s", regname(cpu->machine, rd));                          /*  .hb = hazard barrier hint on MIPS32/64 rev 2  */
848                            debug("jalr%s\t%s",
849                                (instr[1] & 0x04) ? ".hb" : "",
850                                regname(cpu->machine, rd));
851                          debug(",%s", regname(cpu->machine, rs));                          debug(",%s", regname(cpu->machine, rs));
852                          if (running && symbol != NULL)                          if (running && symbol != NULL)
853                                  debug("\t<%s>", symbol);                                  debug("\t<%s>", symbol);
# Line 1152  int mips_cpu_disassemble_instr(struct cp Line 1084  int mips_cpu_disassemble_instr(struct cp
1084                  }                  }
1085                  if (hi6 == HI6_SQ_SPECIAL3 &&                  if (hi6 == HI6_SQ_SPECIAL3 &&
1086                      cpu->cd.mips.cpu_type.rev != MIPS_R5900) {                      cpu->cd.mips.cpu_type.rev != MIPS_R5900) {
1087                            int msbd, lsb, sub10;
1088                          special6 = instr[0] & 0x3f;                          special6 = instr[0] & 0x3f;
                         debug("%s", special3_names[special6]);  
1089                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1090                          rt = instr[2] & 31;                          rt = instr[2] & 31;
1091                          rd = (instr[1] >> 3) & 31;                          rd = msbd = (instr[1] >> 3) & 31;
1092                            lsb = ((instr[1] & 7) << 2) | (instr[0] >> 6);
1093                            sub10 = (rs << 5) | lsb;
1094    
1095                          switch (special6) {                          switch (special6) {
1096    
1097                            case SPECIAL3_EXT:
1098                            case SPECIAL3_DEXT:
1099                            case SPECIAL3_DEXTM:
1100                            case SPECIAL3_DEXTU:
1101                                    debug("%s", special3_names[special6]);
1102                                    if (special6 == SPECIAL3_DEXTM)
1103                                            msbd += 32;
1104                                    if (special6 == SPECIAL3_DEXTU)
1105                                            lsb += 32;
1106                                    debug("\t%s", regname(cpu->machine, rt));
1107                                    debug(",%s", regname(cpu->machine, rs));
1108                                    debug(",%i,%i", lsb, msbd + 1);
1109                                    break;
1110    
1111                            case SPECIAL3_INS:
1112                            case SPECIAL3_DINS:
1113                            case SPECIAL3_DINSM:
1114                            case SPECIAL3_DINSU:
1115                                    debug("%s", special3_names[special6]);
1116                                    if (special6 == SPECIAL3_DINSM)
1117                                            msbd += 32;
1118                                    if (special6 == SPECIAL3_DINSU) {
1119                                            lsb += 32;
1120                                            msbd += 32;
1121                                    }
1122                                    msbd -= lsb;
1123                                    debug("\t%s", regname(cpu->machine, rt));
1124                                    debug(",%s", regname(cpu->machine, rs));
1125                                    debug(",%i,%i", lsb, msbd + 1);
1126                                    break;
1127    
1128                            case SPECIAL3_BSHFL:
1129                                    switch (sub10) {
1130                                    case BSHFL_WSBH:
1131                                    case BSHFL_SEB:
1132                                    case BSHFL_SEH:
1133                                            switch (sub10) {
1134                                            case BSHFL_WSBH: debug("wsbh"); break;
1135                                            case BSHFL_SEB:  debug("seb"); break;
1136                                            case BSHFL_SEH:  debug("seh"); break;
1137                                            }
1138                                            debug("\t%s", regname(cpu->machine,rd));
1139                                            debug(",%s", regname(cpu->machine,rt));
1140                                            break;
1141                                    default:debug("%s", special3_names[special6]);
1142                                            debug("\t(UNIMPLEMENTED)");
1143                                    }
1144                                    break;
1145    
1146                            case SPECIAL3_DBSHFL:
1147                                    switch (sub10) {
1148                                    case BSHFL_DSBH:
1149                                    case BSHFL_DSHD:
1150                                            switch (sub10) {
1151                                            case BSHFL_DSBH: debug("dsbh"); break;
1152                                            case BSHFL_DSHD: debug("dshd"); break;
1153                                            }
1154                                            debug("\t%s", regname(cpu->machine,rd));
1155                                            debug(",%s", regname(cpu->machine,rt));
1156                                            break;
1157                                    default:debug("%s", special3_names[special6]);
1158                                            debug("\t(UNIMPLEMENTED)");
1159                                    }
1160                                    break;
1161    
1162                          case SPECIAL3_RDHWR:                          case SPECIAL3_RDHWR:
1163                                    debug("%s", special3_names[special6]);
1164                                  debug("\t%s", regname(cpu->machine, rt));                                  debug("\t%s", regname(cpu->machine, rt));
1165                                  debug(",hwr%i", rd);                                  debug(",hwr%i", rd);
1166                                  break;                                  break;
1167    
1168                          default:                          default:debug("%s", special3_names[special6]);
1169                                  debug("\t(UNIMPLEMENTED)");                                  debug("\t(UNIMPLEMENTED)");
1170                          }                          }
1171                          break;                          break;
# Line 1450  int mips_cpu_disassemble_instr(struct cp Line 1450  int mips_cpu_disassemble_instr(struct cp
1450    
1451          case HI6_REGIMM:          case HI6_REGIMM:
1452                  regimm5 = instr[2] & 0x1f;                  regimm5 = instr[2] & 0x1f;
1453                    rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);
1454                    imm = (instr[1] << 8) + instr[0];
1455                    if (imm >= 32768)              
1456                            imm -= 65536;
1457    
1458                  switch (regimm5) {                  switch (regimm5) {
1459    
1460                  case REGIMM_BLTZ:                  case REGIMM_BLTZ:
1461                  case REGIMM_BGEZ:                  case REGIMM_BGEZ:
1462                  case REGIMM_BLTZL:                  case REGIMM_BLTZL:
# Line 1459  int mips_cpu_disassemble_instr(struct cp Line 1465  int mips_cpu_disassemble_instr(struct cp
1465                  case REGIMM_BLTZALL:                  case REGIMM_BLTZALL:
1466                  case REGIMM_BGEZAL:                  case REGIMM_BGEZAL:
1467                  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;  
   
1468                          debug("%s\t%s,", regimm_names[regimm5],                          debug("%s\t%s,", regimm_names[regimm5],
1469                              regname(cpu->machine, rs));                              regname(cpu->machine, rs));
1470    
# Line 1474  int mips_cpu_disassemble_instr(struct cp Line 1475  int mips_cpu_disassemble_instr(struct cp
1475                          else                          else
1476                                  debug("0x%016"PRIx64, (uint64_t) addr);                                  debug("0x%016"PRIx64, (uint64_t) addr);
1477                          break;                          break;
1478    
1479                    case REGIMM_SYNCI:
1480                            debug("%s\t%i(%s)", regimm_names[regimm5],
1481                                imm, regname(cpu->machine, rs));
1482                            break;
1483    
1484                  default:                  default:
1485                          debug("unimplemented regimm5 = 0x%02x", regimm5);                          debug("unimplemented regimm5 = 0x%02x", regimm5);
1486                  }                  }
# Line 2046  void mips_cpu_exception(struct cpu *cpu, Line 2053  void mips_cpu_exception(struct cpu *cpu,
2053                  /*  debug("[ warning: cpu%i exception while EXL is set,"                  /*  debug("[ warning: cpu%i exception while EXL is set,"
2054                      " not setting EPC ]\n", cpu->cpu_id);  */                      " not setting EPC ]\n", cpu->cpu_id);  */
2055          } else {          } else {
2056                  if (cpu->delay_slot || cpu->cd.mips.nullify_next) {                  if (cpu->delay_slot) {
2057                          reg[COP0_EPC] = cpu->pc - 4;                          reg[COP0_EPC] = cpu->pc - 4;
2058                          reg[COP0_CAUSE] |= CAUSE_BD;                          reg[COP0_CAUSE] |= CAUSE_BD;
   
                         /*  TODO: Should the BD flag actually be set  
                             on nullified slots?  */  
2059                  } else {                  } else {
2060                          reg[COP0_EPC] = cpu->pc;                          reg[COP0_EPC] = cpu->pc;
2061                          reg[COP0_CAUSE] &= ~CAUSE_BD;                          reg[COP0_CAUSE] &= ~CAUSE_BD;
# Line 2063  void mips_cpu_exception(struct cpu *cpu, Line 2067  void mips_cpu_exception(struct cpu *cpu,
2067          else          else
2068                  cpu->delay_slot = NOT_DELAYED;                  cpu->delay_slot = NOT_DELAYED;
2069    
         cpu->cd.mips.nullify_next = 0;  
   
2070          /*  TODO: This is true for MIPS64, but how about others?  */          /*  TODO: This is true for MIPS64, but how about others?  */
2071          if (reg[COP0_STATUS] & STATUS_BEV)          if (reg[COP0_STATUS] & STATUS_BEV)
2072                  base = 0xffffffffbfc00200ULL;                  base = 0xffffffffbfc00200ULL;

Legend:
Removed from v.31  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26