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

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

revision 28 by dpavlin, Mon Oct 8 16:20:26 2007 UTC revision 38 by dpavlin, Mon Oct 8 16:21:53 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005-2006  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_dyntrans.c,v 1.113 2006/07/21 20:09:15 debug Exp $   *  $Id: cpu_dyntrans.c,v 1.145 2007/04/10 17:26:20 debug Exp $
29   *   *
30   *  Common dyntrans routines. Included from cpu_*.c.   *  Common dyntrans routines. Included from cpu_*.c.
31   */   */
# Line 45  static void gather_statistics(struct cpu Line 45  static void gather_statistics(struct cpu
45          int low_pc = ((size_t)cpu->cd.DYNTRANS_ARCH.next_ic - (size_t)          int low_pc = ((size_t)cpu->cd.DYNTRANS_ARCH.next_ic - (size_t)
46              cpu->cd.DYNTRANS_ARCH.cur_ic_page) / sizeof(struct DYNTRANS_IC);              cpu->cd.DYNTRANS_ARCH.cur_ic_page) / sizeof(struct DYNTRANS_IC);
47    
48            if (cpu->machine->statistics_file == NULL) {
49                    fatal("statistics gathering with no filename set is"
50                        " meaningless\n");
51                    return;
52            }
53    
54          buf[0] = '\0';          buf[0] = '\0';
55    
56          while ((ch = cpu->machine->statistics_fields[i]) != '\0') {          while ((ch = cpu->machine->statistics_fields[i]) != '\0') {
# Line 223  int DYNTRANS_RUN_INSTR(struct cpu *cpu) Line 229  int DYNTRANS_RUN_INSTR(struct cpu *cpu)
229  #endif  #endif
230  #ifdef DYNTRANS_PPC  #ifdef DYNTRANS_PPC
231          if (cpu->cd.ppc.dec_intr_pending && cpu->cd.ppc.msr & PPC_MSR_EE) {          if (cpu->cd.ppc.dec_intr_pending && cpu->cd.ppc.msr & PPC_MSR_EE) {
232                  ppc_exception(cpu, PPC_EXCEPTION_DEC);                  if (!(cpu->cd.ppc.cpu_type.flags & PPC_NO_DEC))
233                            ppc_exception(cpu, PPC_EXCEPTION_DEC);
234                  cpu->cd.ppc.dec_intr_pending = 0;                  cpu->cd.ppc.dec_intr_pending = 0;
235          }          }
236          if (cpu->cd.ppc.irq_asserted && cpu->cd.ppc.msr & PPC_MSR_EE)          if (cpu->cd.ppc.irq_asserted && cpu->cd.ppc.msr & PPC_MSR_EE)
237                  ppc_exception(cpu, PPC_EXCEPTION_EI);                  ppc_exception(cpu, PPC_EXCEPTION_EI);
238  #endif  #endif
239    #ifdef DYNTRANS_SH
240            if (cpu->cd.sh.int_to_assert > 0 && !(cpu->cd.sh.sr & SH_SR_BL)
241                && ((cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT)
242                < cpu->cd.sh.int_level)
243                    sh_exception(cpu, 0, cpu->cd.sh.int_to_assert, 0);
244    #endif
245    
246          cached_pc = cpu->pc;          cached_pc = cpu->pc;
247    
248          cpu->n_translated_instrs = 0;          cpu->n_translated_instrs = 0;
         cpu->running_translated = 1;  
249    
250          cpu->cd.DYNTRANS_ARCH.cur_physpage = (void *)          cpu->cd.DYNTRANS_ARCH.cur_physpage = (void *)
251              cpu->cd.DYNTRANS_ARCH.cur_ic_page;              cpu->cd.DYNTRANS_ARCH.cur_ic_page;
# Line 249  int DYNTRANS_RUN_INSTR(struct cpu *cpu) Line 261  int DYNTRANS_RUN_INSTR(struct cpu *cpu)
261                          cpu_register_dump(cpu->machine, cpu, 1, 0x1);                          cpu_register_dump(cpu->machine, cpu, 1, 0x1);
262                  }                  }
263                  if (cpu->machine->instruction_trace) {                  if (cpu->machine->instruction_trace) {
264  #ifdef DYNTRANS_X86                          /*  TODO/Note: This must be large enough to hold
265                          unsigned char instr[17];                              any instruction for any ISA:  */
266                          cpu->cd.x86.cursegment = X86_S_CS;                          unsigned char instr[1 <<
267                          cpu->cd.x86.seg_override = 0;                              DYNTRANS_INSTR_ALIGNMENT_SHIFT];
 #else  
 #ifdef DYNTRANS_M68K  
                         unsigned char instr[16];        /*  TODO: 16?  */  
 #else  
                         unsigned char instr[4];         /*  General case...  */  
 #endif  
 #endif  
   
268                          if (!cpu->memory_rw(cpu, cpu->mem, cached_pc, &instr[0],                          if (!cpu->memory_rw(cpu, cpu->mem, cached_pc, &instr[0],
269                              sizeof(instr), MEM_READ, CACHE_INSTRUCTION)) {                              sizeof(instr), MEM_READ, CACHE_INSTRUCTION)) {
270                                  fatal("XXX_run_instr(): could not read "                                  fatal("XXX_run_instr(): could not read "
271                                      "the instruction\n");                                      "the instruction\n");
272                          } else {                          } else {
273                                  cpu_disassemble_instr(cpu->machine, cpu,  #ifdef DYNTRANS_DELAYSLOT
274                                      instr, 1, 0);                                  int len =
275    #endif
276                                        cpu_disassemble_instr(
277                                        cpu->machine, cpu, instr, 1, 0);
278  #ifdef DYNTRANS_DELAYSLOT  #ifdef DYNTRANS_DELAYSLOT
279                                  /*  Show the instruction in the delay slot,                                  /*  Show the instruction in the delay slot,
280                                      if any:  */                                      if any:  */
# Line 278  int DYNTRANS_RUN_INSTR(struct cpu *cpu) Line 285  int DYNTRANS_RUN_INSTR(struct cpu *cpu)
285                                      instr)) {                                      instr)) {
286                                          int saved_delayslot = cpu->delay_slot;                                          int saved_delayslot = cpu->delay_slot;
287                                          cpu->memory_rw(cpu, cpu->mem, cached_pc                                          cpu->memory_rw(cpu, cpu->mem, cached_pc
288                                              + sizeof(instr), &instr[0],                                              + len, &instr[0],
289                                              sizeof(instr), MEM_READ,                                              sizeof(instr), MEM_READ,
290                                              CACHE_INSTRUCTION);                                              CACHE_INSTRUCTION);
291                                          cpu->delay_slot = DELAYED;                                          cpu->delay_slot = DELAYED;
292                                          cpu->pc += sizeof(instr);                                          cpu->pc += len;
293                                          cpu_disassemble_instr(cpu->machine,                                          cpu_disassemble_instr(cpu->machine,
294                                              cpu, instr, 1, 0);                                              cpu, instr, 1, 0);
295                                          cpu->delay_slot = saved_delayslot;                                          cpu->delay_slot = saved_delayslot;
296                                          cpu->pc -= sizeof(instr);                                          cpu->pc -= len;
297                                  }                                  }
298  #endif  #endif
299                          }                          }
300                  }                  }
301    
                 /*  When single-stepping, multiple instruction calls cannot  
                     be combined into one. This clears all translations:  */  
                 if (cpu->cd.DYNTRANS_ARCH.cur_physpage->flags & COMBINATIONS) {  
                         int i;  
                         for (i=0; i<DYNTRANS_IC_ENTRIES_PER_PAGE; i++) {  
                                 cpu->cd.DYNTRANS_ARCH.cur_physpage->ics[i].f =  
 #ifdef DYNTRANS_DUALMODE_32  
                                     cpu->is_32bit?  
                                         instr32(to_be_translated) :  
 #endif  
                                         instr(to_be_translated);  
 #ifdef DYNTRANS_VARIABLE_INSTRUCTION_LENGTH  
                                 cpu->cd.DYNTRANS_ARCH.cur_physpage->ics[i].  
                                     arg[0] = 0;  
 #endif  
                         }  
   
                         fatal("[ Note: The translation of physical page 0x%"  
                             PRIx64" contained combinations of instructions; "  
                             "these are now flushed because we are single-"  
                             "stepping. ]\n", (long long)cpu->cd.DYNTRANS_ARCH.  
                             cur_physpage->physaddr);  
   
                         cpu->cd.DYNTRANS_ARCH.cur_physpage->flags &=  
                             ~COMBINATIONS;  
                         cpu->cd.DYNTRANS_ARCH.cur_physpage->translations = 0;  
                 }  
   
302                  if (cpu->machine->statistics_enabled)                  if (cpu->machine->statistics_enabled)
303                          S;                          S;
304    
# Line 344  while (cycles-- > 0) Line 323  while (cycles-- > 0)
323          cpu->machine->tick_func[1](cpu, cpu->machine->tick_extra[1]);          cpu->machine->tick_func[1](cpu, cpu->machine->tick_extra[1]);
324  /* printf("B\n"); */  /* printf("B\n"); */
325    
326                          if (!cpu->running_translated ||                          if (n_instrs + cpu->n_translated_instrs >=
                             n_instrs + cpu->n_translated_instrs >=  
327                              N_SAFE_DYNTRANS_LIMIT)                              N_SAFE_DYNTRANS_LIMIT)
328                                  break;                                  break;
329                  }                  }
# Line 362  while (cycles-- > 0) Line 340  while (cycles-- > 0)
340    
341                          n_instrs += 24;                          n_instrs += 24;
342    
343                          if (!cpu->running_translated ||                          if (n_instrs + cpu->n_translated_instrs >=
                             n_instrs + cpu->n_translated_instrs >=  
344                              N_SAFE_DYNTRANS_LIMIT)                              N_SAFE_DYNTRANS_LIMIT)
345                                  break;                                  break;
346                  }                  }
# Line 381  while (cycles-- > 0) Line 358  while (cycles-- > 0)
358    
359                          I; I; I; I; I;   I; I; I; I; I;                          I; I; I; I; I;   I; I; I; I; I;
360    
361                          n_instrs += 60;                          I; I; I; I; I;   I; I; I; I; I;
362                            I; I; I; I; I;   I; I; I; I; I;
363                            I; I; I; I; I;   I; I; I; I; I;
364                            I; I; I; I; I;   I; I; I; I; I;
365                            I; I; I; I; I;   I; I; I; I; I;
366    
367                          if (!cpu->running_translated ||                          I; I; I; I; I;   I; I; I; I; I;
368                              n_instrs + cpu->n_translated_instrs >=  
369                              N_SAFE_DYNTRANS_LIMIT)                          cpu->n_translated_instrs += 120;
370                            if (cpu->n_translated_instrs >= N_SAFE_DYNTRANS_LIMIT)
371                                  break;                                  break;
372                  }                  }
373          }          }
# Line 424  while (cycles-- > 0) Line 406  while (cycles-- > 0)
406                      (int32_t) (old + n_instrs);                      (int32_t) (old + n_instrs);
407                  diff2 = cpu->cd.mips.coproc[0]->reg[COP0_COMPARE] -                  diff2 = cpu->cd.mips.coproc[0]->reg[COP0_COMPARE] -
408                      cpu->cd.mips.coproc[0]->reg[COP0_COUNT];                      cpu->cd.mips.coproc[0]->reg[COP0_COUNT];
409                  if (cpu->cd.mips.compare_register_set && diff1>0 && diff2<=0)  
410                          cpu_interrupt(cpu, 7);                  if (cpu->cd.mips.compare_register_set) {
411    #if 1
412    /*  Not yet.  TODO  */
413                            if (cpu->machine->emulated_hz > 0) {
414                                    if (cpu->cd.mips.compare_interrupts_pending > 0)
415                                            INTERRUPT_ASSERT(
416                                                cpu->cd.mips.irq_compare);
417                            } else
418    #endif
419                            {
420                                    if (diff1 > 0 && diff2 <= 0)
421                                            INTERRUPT_ASSERT(
422                                                cpu->cd.mips.irq_compare);
423                            }
424                    }
425          }          }
426  #endif  #endif
427  #ifdef DYNTRANS_PPC  #ifdef DYNTRANS_PPC
# Line 468  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 464  void DYNTRANS_FUNCTION_TRACE(struct cpu
464              6              6
465  #else  #else
466  #ifdef DYNTRANS_SH  #ifdef DYNTRANS_SH
467              8              8   /*  Both for 32-bit and 64-bit SuperH  */
468  #else  #else
469              4   /*  Default value for most archs  */              4   /*  Default value for most archs  */
470  #endif  #endif
# Line 492  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 488  void DYNTRANS_FUNCTION_TRACE(struct cpu
488           *  than were passed in register.           *  than were passed in register.
489           */           */
490          for (x=0; x<n_args_to_print; x++) {          for (x=0; x<n_args_to_print; x++) {
491                  int64_t d;                  int64_t d = cpu->cd.DYNTRANS_ARCH.
 #if defined(DYNTRANS_X86) || defined(DYNTRANS_TRANSPUTER)  
                 d = 0;          /*  TODO  */  
 #else  
                 /*  Args in registers:  */  
                 d = cpu->cd.DYNTRANS_ARCH.  
492  #ifdef DYNTRANS_ALPHA  #ifdef DYNTRANS_ALPHA
493                      r[ALPHA_A0                      r[ALPHA_A0
494  #endif  #endif
# Line 509  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 500  void DYNTRANS_FUNCTION_TRACE(struct cpu
500                          they go downwards, ie. 22,23 and so on  */                          they go downwards, ie. 22,23 and so on  */
501                      r[24                      r[24
502  #endif  #endif
 #ifdef DYNTRANS_HPPA  
                     r[0         /*  TODO  */  
 #endif  
 #ifdef DYNTRANS_I960  
                     r[0         /*  TODO  */  
 #endif  
 #ifdef DYNTRANS_IA64  
                     r[0         /*  TODO  */  
 #endif  
503  #ifdef DYNTRANS_M68K  #ifdef DYNTRANS_M68K
504                      d[0         /*  TODO  */                      d[0         /*  TODO  */
505  #endif  #endif
# Line 528  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 510  void DYNTRANS_FUNCTION_TRACE(struct cpu
510                      gpr[3                      gpr[3
511  #endif  #endif
512  #ifdef DYNTRANS_SH  #ifdef DYNTRANS_SH
513                      r[2                      r[4         /*  NetBSD seems to use 4? But 2 seems
514                                            to be used by other code? TODO  */
515  #endif  #endif
516  #ifdef DYNTRANS_SPARC  #ifdef DYNTRANS_SPARC
517                      r[24                      r[8         /*  o0..o5  */
518  #endif  #endif
519                      + x];                      + x];
520  #endif  
521                  symbol = get_symbol_name(&cpu->machine->symbol_context, d, &ot);                  symbol = get_symbol_name(&cpu->machine->symbol_context, d, &ot);
522    
523                  if (d > -256 && d < 256)                  if (d > -256 && d < 256)
# Line 650  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 633  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
633          if (!ok) {          if (!ok) {
634                  uint64_t paddr;                  uint64_t paddr;
635                  if (cpu->translate_v2p != NULL) {                  if (cpu->translate_v2p != NULL) {
636                            uint64_t vaddr =
637    #if defined(MODE32) && defined(DYNTRANS_MIPS)
638                            /*  32-bit MIPS is _sign_ extend, not zero.  */
639                                (int32_t)
640    #endif
641                                cached_pc;
642                          ok = cpu->translate_v2p(                          ok = cpu->translate_v2p(
643                              cpu, cached_pc, &paddr, FLAG_INSTR);                              cpu, vaddr, &paddr, FLAG_INSTR);
644                  } else {                  } else {
645                          paddr = cached_pc;                          paddr = cached_pc;
646                          ok = 1;                          ok = 1;
# Line 679  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 668  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
668                          }                          }
669  #else  #else
670                          x1 = (cached_pc >> (64-DYNTRANS_L1N)) & mask1;                          x1 = (cached_pc >> (64-DYNTRANS_L1N)) & mask1;
671                          x2 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;                          x2 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N))
672                          x3 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N))                              & mask2;
673                              & mask3;                          x3 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N
674                                - DYNTRANS_L3N)) & mask3;
675                          l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];                          l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];
676                          l3 = l2->l3[x2];                          l3 = l2->l3[x2];
677                          if (l3->host_load[x3] != NULL) {                          if (l3->host_load[x3] != NULL) {
# Line 725  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 715  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
715                  }                  }
716          }          }
717    
718          if (cpu->translation_cache_cur_ofs >= DYNTRANS_CACHE_SIZE) {          if (cpu->translation_cache_cur_ofs >= dyntrans_cache_size) {
719  #ifdef UNSTABLE_DEVEL  #ifdef UNSTABLE_DEVEL
720                  fatal("[ dyntrans: resetting the translation cache ]\n");                  fatal("[ dyntrans: resetting the translation cache ]\n");
721  #endif  #endif
# Line 752  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 742  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
742                  physpage_ofs = ppp->next_ofs;                  physpage_ofs = ppp->next_ofs;
743          }          }
744    
745          /*  If the offset is 0 (or ppp is NULL), then we need to create a          /*
746              new "default" empty translation page.  */           *  If the offset is 0, then no translation exists yet for this
747             *  physical address. Let's create a new page, and add it first in
748             *  the chain.
749             */
750            if (physpage_ofs == 0) {
751                    uint32_t previous_first_page_in_chain;
752    
         if (ppp == NULL) {  
753                  /*  fatal("CREATING page %lli (physaddr 0x%"PRIx64"), table "                  /*  fatal("CREATING page %lli (physaddr 0x%"PRIx64"), table "
754                      "index %i\n", (long long)pagenr, (uint64_t)physaddr,                      "index %i\n", (long long)pagenr, (uint64_t)physaddr,
755                      (int)table_index);  */                      (int)table_index);  */
756    
757                    previous_first_page_in_chain = *physpage_entryp;
758    
759                    /*  Insert the new page first in the chain:  */
760                  *physpage_entryp = physpage_ofs =                  *physpage_entryp = physpage_ofs =
761                      cpu->translation_cache_cur_ofs;                      cpu->translation_cache_cur_ofs;
762    
# Line 767  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 765  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
765    
766                  ppp = (struct DYNTRANS_TC_PHYSPAGE *)(cpu->translation_cache                  ppp = (struct DYNTRANS_TC_PHYSPAGE *)(cpu->translation_cache
767                      + physpage_ofs);                      + physpage_ofs);
768    
769                    /*  Point to the other pages in the same chain:  */
770                    ppp->next_ofs = previous_first_page_in_chain;
771          }          }
772    
773            /*  Here, ppp points to a valid physical page struct.  */
774    
775  #ifdef MODE32  #ifdef MODE32
776          if (cpu->cd.DYNTRANS_ARCH.host_load[index] != NULL)          if (cpu->cd.DYNTRANS_ARCH.host_load[index] != NULL)
777                  cpu->cd.DYNTRANS_ARCH.phys_page[index] = ppp;                  cpu->cd.DYNTRANS_ARCH.phys_page[index] = ppp;
# Line 902  void DYNTRANS_INIT_TABLES(struct cpu *cp Line 905  void DYNTRANS_INIT_TABLES(struct cpu *cp
905          }          }
906    
907          ppp->next_ofs = 0;          ppp->next_ofs = 0;
         ppp->flags = 0;  
908          ppp->translations = 0;          ppp->translations = 0;
909          /*  ppp->physaddr is filled in by the page allocator  */          /*  ppp->physaddr is filled in by the page allocator  */
910    
# Line 1249  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1251  void DYNTRANS_INVALIDATE_TC_CODE(struct
1251                  physpage_entryp = &(((uint32_t *)cpu->                  physpage_entryp = &(((uint32_t *)cpu->
1252                      translation_cache)[table_index]);                      translation_cache)[table_index]);
1253                  physpage_ofs = *physpage_entryp;                  physpage_ofs = *physpage_entryp;
1254    
1255                    /*  Return immediately if there is no code translation
1256                        for this page.  */
1257                    if (physpage_ofs == 0)
1258                            return;
1259    
1260                  prev_ppp = ppp = NULL;                  prev_ppp = ppp = NULL;
1261    
1262                  /*  Traverse the physical page chain:  */                  /*  Traverse the physical page chain:  */
# Line 1266  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1274  void DYNTRANS_INVALIDATE_TC_CODE(struct
1274                          physpage_ofs = ppp->next_ofs;                          physpage_ofs = ppp->next_ofs;
1275                  }                  }
1276    
1277                    /*  If there is no translation, there is no need to go
1278                        on and try to remove it from the vph_tlb_entry array:  */
1279                  if (physpage_ofs == 0)                  if (physpage_ofs == 0)
1280                          ppp = NULL;                          return;
1281    
1282  #if 0  #if 0
1283                  /*                  /*
# Line 1312  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1322  void DYNTRANS_INVALIDATE_TC_CODE(struct
1322                                  x >>= 1;                                  x >>= 1;
1323                          }                          }
1324    
                         ppp->flags &= ~COMBINATIONS;  
1325                          ppp->translations = 0;                          ppp->translations = 0;
1326                  }                  }
1327  #endif  #endif
# Line 1367  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1376  void DYNTRANS_INVALIDATE_TC_CODE(struct
1376  void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page,  void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page,
1377          unsigned char *host_page, int writeflag, uint64_t paddr_page)          unsigned char *host_page, int writeflag, uint64_t paddr_page)
1378  {  {
1379  #ifndef MODE32          int found, r, useraccess = 0;
         int64_t lowest, highest = -1;  
 #endif  
         int found, r, lowest_index, useraccess = 0;  
1380    
1381  #ifdef MODE32  #ifdef MODE32
1382          uint32_t index;          uint32_t index;
# Line 1401  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1407  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1407          }          }
1408    
1409          /*  Scan the current TLB entries:  */          /*  Scan the current TLB entries:  */
         lowest_index = 0;  
1410    
1411  #ifdef MODE32  #ifdef MODE32
1412          /*          /*
# Line 1414  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1419  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1419           */           */
1420          found = (int)cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[          found = (int)cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[
1421              DYNTRANS_ADDR_TO_PAGENR(vaddr_page)] - 1;              DYNTRANS_ADDR_TO_PAGENR(vaddr_page)] - 1;
         if (found < 0) {  
                 static unsigned int x = 0;  
                 lowest_index = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES;  
         }  
1422  #else  #else
1423          lowest = cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[0].timestamp;          x1 = (vaddr_page >> (64-DYNTRANS_L1N)) & mask1;
1424          found = -1;          x2 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
1425          for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {          x3 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N))
1426                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp < lowest) {              & mask3;
1427                          lowest = cpu->cd.DYNTRANS_ARCH.  
1428                              vph_tlb_entry[r].timestamp;          l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];
1429                          lowest_index = r;          if (l2 == cpu->cd.DYNTRANS_ARCH.l2_64_dummy)
1430                  }                  found = -1;
1431                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp > highest)          else {
1432                          highest = cpu->cd.DYNTRANS_ARCH.                  l3 = l2->l3[x2];
1433                              vph_tlb_entry[r].timestamp;                  if (l3 == cpu->cd.DYNTRANS_ARCH.l3_64_dummy)
1434                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid &&                          found = -1;
1435                      cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page ==                  else
1436                      vaddr_page) {                          found = (int)l3->vaddr_to_tlbindex[x3] - 1;
                         found = r;  
                         break;  
                 }  
1437          }          }
1438  #endif  #endif
1439    
1440          if (found < 0) {          if (found < 0) {
1441                  /*  Create the new TLB entry, overwriting the oldest one:  */                  /*  Create the new TLB entry, overwriting a "random" entry:  */
1442                  r = lowest_index;                  static unsigned int x = 0;
1443                    r = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES;
1444    
1445                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
1446                          /*  This one has to be invalidated first:  */                          /*  This one has to be invalidated first:  */
1447                          DYNTRANS_INVALIDATE_TLB_ENTRY(cpu,                          DYNTRANS_INVALIDATE_TLB_ENTRY(cpu,
# Line 1455  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1455  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1455                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page;                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page;
1456                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag =                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag =
1457                      writeflag & MEM_WRITE;                      writeflag & MEM_WRITE;
 #ifndef MODE32  
                 cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1;  
 #endif  
1458    
1459                  /*  Add the new translation to the table:  */                  /*  Add the new translation to the table:  */
1460  #ifdef MODE32  #ifdef MODE32
# Line 1474  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1471  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1471                              |= 1 << (index & 31);                              |= 1 << (index & 31);
1472  #endif  #endif
1473  #else   /* !MODE32  */  #else   /* !MODE32  */
                 x1 = (vaddr_page >> (64-DYNTRANS_L1N)) & mask1;  
                 x2 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;  
                 x3 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N))  
                     & mask3;  
   
1474                  l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];                  l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];
1475                  if (l2 == cpu->cd.DYNTRANS_ARCH.l2_64_dummy) {                  if (l2 == cpu->cd.DYNTRANS_ARCH.l2_64_dummy) {
1476                          if (cpu->cd.DYNTRANS_ARCH.next_free_l2 != NULL) {                          if (cpu->cd.DYNTRANS_ARCH.next_free_l2 != NULL) {
# Line 1563  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1555  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1555                   *      Writeflag = MEM_DOWNGRADE: Downgrade to readonly.                   *      Writeflag = MEM_DOWNGRADE: Downgrade to readonly.
1556                   */                   */
1557                  r = found;                  r = found;
 #ifndef MODE32  
                 cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1;  
 #endif  
1558                  if (writeflag & MEM_WRITE)                  if (writeflag & MEM_WRITE)
1559                          cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1;                          cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1;
1560                  if (writeflag & MEM_DOWNGRADE)                  if (writeflag & MEM_DOWNGRADE)
# Line 1714  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].v Line 1703  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].v
1703  #ifdef DYNTRANS_DELAYSLOT  #ifdef DYNTRANS_DELAYSLOT
1704              && !in_crosspage_delayslot              && !in_crosspage_delayslot
1705  #endif  #endif
1706              ) {              && cpu->cd.DYNTRANS_ARCH.combination_check != NULL
1707                  if (cpu->cd.DYNTRANS_ARCH.combination_check != NULL &&              && cpu->machine->allow_instruction_combinations) {
1708                      cpu->machine->allow_instruction_combinations)                  cpu->cd.DYNTRANS_ARCH.combination_check(cpu, ic,
1709                          cpu->cd.DYNTRANS_ARCH.combination_check(cpu, ic,                      addr & (DYNTRANS_PAGESIZE - 1));
                             addr & (DYNTRANS_PAGESIZE - 1));  
1710          }          }
1711    
1712          cpu->cd.DYNTRANS_ARCH.combination_check = NULL;          cpu->cd.DYNTRANS_ARCH.combination_check = NULL;
# Line 1798  bad:   /* Line 1786  bad:   /*
1786          }          }
1787    
1788          cpu->running = 0;          cpu->running = 0;
1789          cpu->dead = 1;  
1790            /*  Note: Single-stepping can jump here.  */
1791  stop_running_translated:  stop_running_translated:
1792    
1793          debugger_n_steps_left_before_interaction = 0;          debugger_n_steps_left_before_interaction = 0;
1794          cpu->running_translated = 0;  
1795          ic = cpu->cd.DYNTRANS_ARCH.next_ic = &nothing_call;          ic = cpu->cd.DYNTRANS_ARCH.next_ic = &nothing_call;
1796          cpu->cd.DYNTRANS_ARCH.next_ic ++;          cpu->cd.DYNTRANS_ARCH.next_ic ++;
1797    
1798          /*  Execute the "nothing" instruction:  */          /*  Execute the "nothing" instruction:  */
1799          ic->f(cpu, ic);          ic->f(cpu, ic);
1800    
1801  #endif  /*  DYNTRANS_TO_BE_TRANSLATED_TAIL  */  #endif  /*  DYNTRANS_TO_BE_TRANSLATED_TAIL  */
1802    

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

  ViewVC Help
Powered by ViewVC 1.1.26