/[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 18 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_dyntrans.c,v 1.27 2005/10/27 14:01:13 debug Exp $   *  $Id: cpu_dyntrans.c,v 1.41 2005/11/23 22:03:31 debug Exp $
29   *   *
30   *  Common dyntrans routines. Included from cpu_*.c.   *  Common dyntrans routines. Included from cpu_*.c.
31   */   */
# Line 40  static void gather_statistics(struct cpu Line 40  static void gather_statistics(struct cpu
40          if (low_pc < 0 || low_pc >= DYNTRANS_IC_ENTRIES_PER_PAGE)          if (low_pc < 0 || low_pc >= DYNTRANS_IC_ENTRIES_PER_PAGE)
41                  return;                  return;
42    
43  #if 1  #if 0
44          /*  Use the physical address:  */          /*  Use the physical address:  */
45          cpu->cd.DYNTRANS_ARCH.cur_physpage = (void *)          cpu->cd.DYNTRANS_ARCH.cur_physpage = (void *)
46              cpu->cd.DYNTRANS_ARCH.cur_ic_page;              cpu->cd.DYNTRANS_ARCH.cur_ic_page;
# Line 94  a &= 0x03ffffff; Line 94  a &= 0x03ffffff;
94  #define S               gather_statistics(cpu)  #define S               gather_statistics(cpu)
95    
96  #ifdef DYNTRANS_VARIABLE_INSTRUCTION_LENGTH  #ifdef DYNTRANS_VARIABLE_INSTRUCTION_LENGTH
97  #define I               ic = cpu->cd.DYNTRANS_ARCH.next_ic; ic->f(cpu, ic);  #define I               ic = cpu->cd.DYNTRANS_ARCH.next_ic;             \
98                            cpu->cd.DYNTRANS_ARCH.next_ic += ic->len;       \
99                            ic->f(cpu, ic);
100  #else  #else
101  #define I               ic = cpu->cd.DYNTRANS_ARCH.next_ic ++; ic->f(cpu, ic);  #define I               ic = cpu->cd.DYNTRANS_ARCH.next_ic ++; ic->f(cpu, ic);
102  #endif  #endif
# Line 134  int DYNTRANS_CPU_RUN_INSTR(struct emul * Line 136  int DYNTRANS_CPU_RUN_INSTR(struct emul *
136          if (cpu->cd.arm.irq_asserted && !(cpu->cd.arm.cpsr & ARM_FLAG_I))          if (cpu->cd.arm.irq_asserted && !(cpu->cd.arm.cpsr & ARM_FLAG_I))
137                  arm_exception(cpu, ARM_EXCEPTION_IRQ);                  arm_exception(cpu, ARM_EXCEPTION_IRQ);
138  #endif  #endif
139    #ifdef DYNTRANS_PPC
140            if (cpu->cd.ppc.dec_intr_pending && cpu->cd.ppc.msr & PPC_MSR_EE) {
141                    ppc_exception(cpu, PPC_EXCEPTION_DEC);
142                    cpu->cd.ppc.dec_intr_pending = 0;
143            }
144            if (cpu->cd.ppc.irq_asserted && cpu->cd.ppc.msr & PPC_MSR_EE)
145                    ppc_exception(cpu, PPC_EXCEPTION_EI);
146    #endif
147    
148          cached_pc = cpu->pc;          cached_pc = cpu->pc;
149    
# Line 238  int DYNTRANS_CPU_RUN_INSTR(struct emul * Line 248  int DYNTRANS_CPU_RUN_INSTR(struct emul *
248                  }                  }
249          }          }
250    
251            n_instrs += cpu->n_translated_instrs;
252    
253          /*          /*  Synchronize the program counter:  */
          *  Update the program counter and return the correct number of  
          *  executed instructions:  
          */  
254          low_pc = ((size_t)cpu->cd.DYNTRANS_ARCH.next_ic - (size_t)          low_pc = ((size_t)cpu->cd.DYNTRANS_ARCH.next_ic - (size_t)
255              cpu->cd.DYNTRANS_ARCH.cur_ic_page) / sizeof(struct DYNTRANS_IC);              cpu->cd.DYNTRANS_ARCH.cur_ic_page) / sizeof(struct DYNTRANS_IC);
   
256          if (low_pc >= 0 && low_pc < DYNTRANS_IC_ENTRIES_PER_PAGE) {          if (low_pc >= 0 && low_pc < DYNTRANS_IC_ENTRIES_PER_PAGE) {
 #ifdef DYNTRANS_ARM  
                 cpu->cd.arm.r[ARM_PC] &= ~((DYNTRANS_IC_ENTRIES_PER_PAGE-1)<<2);  
                 cpu->cd.arm.r[ARM_PC] += (low_pc << 2);  
                 cpu->pc = cpu->cd.arm.r[ARM_PC];  
 #else  
257                  cpu->pc &= ~((DYNTRANS_IC_ENTRIES_PER_PAGE-1) <<                  cpu->pc &= ~((DYNTRANS_IC_ENTRIES_PER_PAGE-1) <<
258                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);
259                  cpu->pc += (low_pc << DYNTRANS_INSTR_ALIGNMENT_SHIFT);                  cpu->pc += (low_pc << DYNTRANS_INSTR_ALIGNMENT_SHIFT);
 #endif  
260          } else if (low_pc == DYNTRANS_IC_ENTRIES_PER_PAGE) {          } else if (low_pc == DYNTRANS_IC_ENTRIES_PER_PAGE) {
261                  /*  Switch to next page:  */                  /*  Switch to next page:  */
 #ifdef DYNTRANS_ARM  
                 cpu->cd.arm.r[ARM_PC] &= ~((ARM_IC_ENTRIES_PER_PAGE-1) << 2);  
                 cpu->cd.arm.r[ARM_PC] += (ARM_IC_ENTRIES_PER_PAGE << 2);  
                 cpu->pc = cpu->cd.arm.r[ARM_PC];  
 #else  
262                  cpu->pc &= ~((DYNTRANS_IC_ENTRIES_PER_PAGE-1) <<                  cpu->pc &= ~((DYNTRANS_IC_ENTRIES_PER_PAGE-1) <<
263                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);
264                  cpu->pc += (DYNTRANS_IC_ENTRIES_PER_PAGE <<                  cpu->pc += (DYNTRANS_IC_ENTRIES_PER_PAGE <<
265                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);
 #endif  
         } else {  
                 /*  debug("debug: Outside a page (This is actually ok)\n");  */  
266          }          }
267    
268          return n_instrs + cpu->n_translated_instrs;  #ifdef DYNTRANS_PPC
269            /*  Update the Decrementer and Time base registers:  */
270            {
271                    uint32_t old = cpu->cd.ppc.spr[SPR_DEC];
272                    cpu->cd.ppc.spr[SPR_DEC] = (uint32_t) (old - n_instrs);
273                    if ((old >> 31) == 0 && (cpu->cd.ppc.spr[SPR_DEC] >> 31) == 1)
274                            cpu->cd.ppc.dec_intr_pending = 1;
275    
276                    old = cpu->cd.ppc.spr[SPR_TBL];
277                    cpu->cd.ppc.spr[SPR_TBL] += n_instrs;
278                    if ((old >> 31) == 1 && (cpu->cd.ppc.spr[SPR_TBL] >> 31) == 0)
279                            cpu->cd.ppc.spr[SPR_TBU] ++;
280            }
281    #endif
282    
283            /*  Return the nr of instructions executed:  */
284            return n_instrs;
285  }  }
286  #endif  /*  DYNTRANS_CPU_RUN_INSTR  */  #endif  /*  DYNTRANS_CPU_RUN_INSTR  */
287    
# Line 352  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 361  void DYNTRANS_FUNCTION_TRACE(struct cpu
361  #ifdef DYNTRANS_MIPS  #ifdef DYNTRANS_MIPS
362                      gpr[MIPS_GPR_A0                      gpr[MIPS_GPR_A0
363  #endif  #endif
364    #ifdef DYNTRANS_NEWMIPS
365                        r[0         /*  TODO  */
366    #endif
367  #ifdef DYNTRANS_PPC  #ifdef DYNTRANS_PPC
368                      gpr[3                      gpr[3
369  #endif  #endif
# Line 453  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 465  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
465  #else  #else
466          uint64_t          uint64_t
467  #endif  #endif
468              cached_pc, physaddr;              cached_pc, physaddr = 0;
469          uint32_t physpage_ofs;          uint32_t physpage_ofs;
470          int ok, pagenr, table_index;          int ok, pagenr, table_index;
471          uint32_t *physpage_entryp;          uint32_t *physpage_entryp;
# Line 519  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 531  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
531                          ok = 1;                          ok = 1;
532                  }                  }
533                  if (!ok) {                  if (!ok) {
534  /*                          /*  fatal("TODO: instruction vaddr=>paddr translation"
                         fatal("TODO: instruction vaddr=>paddr translation"  
535                              " failed. vaddr=0x%llx\n", (long long)cached_pc);                              " failed. vaddr=0x%llx\n", (long long)cached_pc);
536  fatal("!! cpu->pc=0x%llx arm_pc=0x%x\n", (long long)cpu->pc,                          fatal("!! cpu->pc=0x%llx\n", (long long)cpu->pc);  */
537  cpu->cd.arm.r[ARM_PC]);  
 */  
538                          ok = cpu->translate_address(cpu, cpu->pc, &paddr,                          ok = cpu->translate_address(cpu, cpu->pc, &paddr,
539                              FLAG_INSTR);                              FLAG_INSTR);
540  /*  
541  printf("EXCEPTION HANDLER: vaddr = 0x%x ==> paddr = 0x%x\n",                          /*  printf("EXCEPTION HANDLER: vaddr = 0x%x ==> "
542          (int)cpu->pc, (int)paddr);                              "paddr = 0x%x\n", (int)cpu->pc, (int)paddr);
543  fatal("!? cpu->pc=0x%llx arm_pc=0x%x\n", (long long)cpu->pc,                          fatal("!? cpu->pc=0x%llx\n", (long long)cpu->pc);  */
544  cpu->cd.arm.r[ARM_PC]);  
 */  
545                          if (!ok) {                          if (!ok) {
546                                  fatal("FATAL: could not find physical"                                  fatal("FATAL: could not find physical"
547                                      " address of the exception handler?");                                      " address of the exception handler?");
# Line 561  cpu->cd.arm.r[ARM_PC]); Line 570  cpu->cd.arm.r[ARM_PC]);
570  #endif  #endif
571    
572          if (cpu->translation_cache_cur_ofs >= DYNTRANS_CACHE_SIZE) {          if (cpu->translation_cache_cur_ofs >= DYNTRANS_CACHE_SIZE) {
573                  fatal("[ dyntrans: resetting the translation cache ]\n");                  debug("[ dyntrans: resetting the translation cache ]\n");
574                  cpu_create_or_reset_tc(cpu);                  cpu_create_or_reset_tc(cpu);
575          }          }
576    
# Line 610  cpu->cd.arm.r[ARM_PC]); Line 619  cpu->cd.arm.r[ARM_PC]);
619                  vph_p->phys_page[b] = ppp;                  vph_p->phys_page[b] = ppp;
620  #endif  #endif
621    
622    #ifdef MODE32
623            /*  Small optimization: only mark the physical page as non-writable
624                if it did not contain translations. (Because if it does contain
625                translations, it is already non-writable.)  */
626            if (!cpu->cd.DYNTRANS_ARCH.phystranslation[pagenr >> 5] &
627                (1 << (pagenr & 31)))
628    #endif
629          cpu->invalidate_translation_caches(cpu, physaddr,          cpu->invalidate_translation_caches(cpu, physaddr,
630              JUST_MARK_AS_NON_WRITABLE | INVALIDATE_PADDR);              JUST_MARK_AS_NON_WRITABLE | INVALIDATE_PADDR);
631    
 /*      cpu->cd.DYNTRANS_ARCH.cur_physpage = ppp;  */  
632          cpu->cd.DYNTRANS_ARCH.cur_ic_page = &ppp->ics[0];          cpu->cd.DYNTRANS_ARCH.cur_ic_page = &ppp->ics[0];
633    
634          cpu->cd.DYNTRANS_ARCH.next_ic = cpu->cd.DYNTRANS_ARCH.cur_ic_page +          cpu->cd.DYNTRANS_ARCH.next_ic = cpu->cd.DYNTRANS_ARCH.cur_ic_page +
# Line 674  void DYNTRANS_PC_TO_POINTERS_FUNC(struct Line 689  void DYNTRANS_PC_TO_POINTERS_FUNC(struct
689                          goto have_it;                          goto have_it;
690          }          }
691  #else  #else
692            /*  Temporary, to avoid a compiler warning:  */
693            cached_pc = 0;
694            ppp = NULL;
695  #ifdef DYNTRANS_IA64  #ifdef DYNTRANS_IA64
696          fatal("IA64 todo\n");          fatal("IA64 todo\n");
697  #else  #else
698          fatal("Neither alpha, ia64, nor 32-bit? 1\n");          fatal("Neither alpha, ia64, nor 32-bit? 1\n");
         { char *p = (char *) 0; *p = 0; }  
699          exit(1);          exit(1);
700  #endif  #endif
701  #endif  #endif
# Line 688  void DYNTRANS_PC_TO_POINTERS_FUNC(struct Line 705  void DYNTRANS_PC_TO_POINTERS_FUNC(struct
705          return;          return;
706    
707          /*  Quick return path:  */          /*  Quick return path:  */
708    #if defined(MODE32) || defined(DYNTRANS_ALPHA)
709  have_it:  have_it:
 /*      cpu->cd.DYNTRANS_ARCH.cur_physpage = ppp;  */  
710          cpu->cd.DYNTRANS_ARCH.cur_ic_page = &ppp->ics[0];          cpu->cd.DYNTRANS_ARCH.cur_ic_page = &ppp->ics[0];
711          cpu->cd.DYNTRANS_ARCH.next_ic = cpu->cd.DYNTRANS_ARCH.cur_ic_page +          cpu->cd.DYNTRANS_ARCH.next_ic = cpu->cd.DYNTRANS_ARCH.cur_ic_page +
712              DYNTRANS_PC_TO_IC_ENTRY(cached_pc);              DYNTRANS_PC_TO_IC_ENTRY(cached_pc);
# Line 697  have_it: Line 714  have_it:
714          /*  printf("cached_pc=0x%016llx  pagenr=%lli  table_index=%lli, "          /*  printf("cached_pc=0x%016llx  pagenr=%lli  table_index=%lli, "
715              "physpage_ofs=0x%016llx\n", (long long)cached_pc, (long long)pagenr,              "physpage_ofs=0x%016llx\n", (long long)cached_pc, (long long)pagenr,
716              (long long)table_index, (long long)physpage_ofs);  */              (long long)table_index, (long long)physpage_ofs);  */
717    #endif
718  }  }
719  #endif  /*  DYNTRANS_PC_TO_POINTERS_FUNC  */  #endif  /*  DYNTRANS_PC_TO_POINTERS_FUNC  */
720    
# Line 724  static void DYNTRANS_INVALIDATE_TLB_ENTR Line 742  static void DYNTRANS_INVALIDATE_TLB_ENTR
742          uint32_t index = DYNTRANS_ADDR_TO_PAGENR(vaddr_page);          uint32_t index = DYNTRANS_ADDR_TO_PAGENR(vaddr_page);
743    
744  #ifdef DYNTRANS_ARM  #ifdef DYNTRANS_ARM
745          cpu->cd.DYNTRANS_ARCH.is_userpage[index >> 3] &= ~(1 << (index & 7));          cpu->cd.DYNTRANS_ARCH.is_userpage[index >> 5] &= ~(1 << (index & 31));
746  #endif  #endif
747    
748          if (flags & JUST_MARK_AS_NON_WRITABLE) {          if (flags & JUST_MARK_AS_NON_WRITABLE) {
# Line 820  void DYNTRANS_INVALIDATE_TC(struct cpu * Line 838  void DYNTRANS_INVALIDATE_TC(struct cpu *
838  #endif  #endif
839              addr_page = paddr & ~(DYNTRANS_PAGESIZE - 1);              addr_page = paddr & ~(DYNTRANS_PAGESIZE - 1);
840    
841            /*  fatal("invalidate(): ");  */
842    
843          /*  Quick case for virtual addresses: see note above.  */          /*  Quick case for virtual addresses: see note above.  */
844          if (flags & INVALIDATE_VADDR) {          if (flags & INVALIDATE_VADDR) {
845                    /*  fatal("vaddr 0x%08x\n", (int)addr_page);  */
846                  DYNTRANS_INVALIDATE_TLB_ENTRY(cpu, addr_page, flags);                  DYNTRANS_INVALIDATE_TLB_ENTRY(cpu, addr_page, flags);
847                  return;                  return;
848          }          }
849    
850            if (flags & INVALIDATE_ALL) {
851                    /*  fatal("all\n");  */
852                    for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {
853                            if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
854                                    DYNTRANS_INVALIDATE_TLB_ENTRY(cpu, cpu->cd.
855                                        DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page,
856                                        0);
857                                    cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid=0;
858                            }
859                    }
860                    return;
861            }
862    
863            /*  fatal("paddr 0x%08x\n", (int)addr_page);  */
864    
865          for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {          for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {
866                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid && (                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid && (
867                      (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page ==                      (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page ==
# Line 1011  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1047  void DYNTRANS_INVALIDATE_TC_CODE(struct
1047  void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page,  void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page,
1048          unsigned char *host_page, int writeflag, uint64_t paddr_page)          unsigned char *host_page, int writeflag, uint64_t paddr_page)
1049  {  {
1050    #ifndef MODE32
1051          int64_t lowest, highest = -1;          int64_t lowest, highest = -1;
1052    #endif
1053          int found, r, lowest_index, start, end, useraccess = 0;          int found, r, lowest_index, start, end, useraccess = 0;
1054    
1055  #ifdef DYNTRANS_ALPHA  #ifdef DYNTRANS_ALPHA
# Line 1057  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1095  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1095  #endif  #endif
1096    
1097          /*  Scan the current TLB entries:  */          /*  Scan the current TLB entries:  */
1098          found = -1; lowest_index = start;          lowest_index = start;
         lowest = cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[0].timestamp;  
1099    
1100  #ifdef MODE32  #ifdef MODE32
1101          /*  NOTE: vaddr_to_tlbindex is one more than the index, so that          /*
1102              0 becomes -1, which means a miss.  */           *  NOTE 1: vaddr_to_tlbindex is one more than the index, so that
1103          found = cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[           *          0 becomes -1, which means a miss.
1104             *
1105             *  NOTE 2: When a miss occurs, instead of scanning the entire tlb
1106             *          for the entry with the lowest time stamp, just choosing
1107             *          one at random will work as well.
1108             */
1109            found = (int)cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[
1110              DYNTRANS_ADDR_TO_PAGENR(vaddr_page)] - 1;              DYNTRANS_ADDR_TO_PAGENR(vaddr_page)] - 1;
1111          if (found < 0)          if (found < 0) {
1112                  lowest_index = (random() % (end-start)) + start;                  static unsigned int x = 0;
1113          if (0)                  lowest_index = (x % (end-start)) + start;
1114  #endif                  x ++;
1115            }
1116    #else
1117            lowest = cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[0].timestamp;
1118            found = -1;
1119          for (r=start; r<end; r++) {          for (r=start; r<end; r++) {
1120                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp < lowest) {                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp < lowest) {
1121                          lowest = cpu->cd.DYNTRANS_ARCH.                          lowest = cpu->cd.DYNTRANS_ARCH.
# Line 1086  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1132  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1132                          break;                          break;
1133                  }                  }
1134          }          }
1135    #endif
1136    
1137          if (found < 0) {          if (found < 0) {
1138                  /*  Create the new TLB entry, overwriting the oldest one:  */                  /*  Create the new TLB entry, overwriting the oldest one:  */
# Line 1101  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1148  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1148                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].host_page = host_page;                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].host_page = host_page;
1149                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page = paddr_page;                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page = paddr_page;
1150                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page;                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page;
1151                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = writeflag;                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag =
1152                        writeflag & MEM_WRITE;
1153    #ifndef MODE32
1154                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1;                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1;
1155    #endif
1156    
1157                  /*  Add the new translation to the table:  */                  /*  Add the new translation to the table:  */
1158  #ifdef DYNTRANS_ALPHA  #ifdef DYNTRANS_ALPHA
# Line 1151  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1201  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1201                  cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[index] = r + 1;                  cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[index] = r + 1;
1202  #ifdef DYNTRANS_ARM  #ifdef DYNTRANS_ARM
1203                  if (useraccess)                  if (useraccess)
1204                          cpu->cd.DYNTRANS_ARCH.is_userpage[index >> 3]                          cpu->cd.DYNTRANS_ARCH.is_userpage[index >> 5]
1205                              |= 1 << (index & 7);                              |= 1 << (index & 31);
1206  #endif  #endif
1207  #endif  /*  32  */  #endif  /*  32  */
1208  #endif  /*  !ALPHA  */  #endif  /*  !ALPHA  */
# Line 1161  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1211  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1211                   *  The translation was already in the TLB.                   *  The translation was already in the TLB.
1212                   *      Writeflag = 0:  Do nothing.                   *      Writeflag = 0:  Do nothing.
1213                   *      Writeflag = 1:  Make sure the page is writable.                   *      Writeflag = 1:  Make sure the page is writable.
1214                   *      Writeflag = -1: Downgrade to readonly.                   *      Writeflag = MEM_DOWNGRADE: Downgrade to readonly.
1215                   */                   */
1216                  r = found;                  r = found;
1217    #ifndef MODE32
1218                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1;                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1;
1219                  if (writeflag == 1)  #endif
1220                    if (writeflag & MEM_WRITE)
1221                          cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1;                          cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1;
1222                  if (writeflag == -1)                  if (writeflag & MEM_DOWNGRADE)
1223                          cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 0;                          cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 0;
1224  #ifdef DYNTRANS_ALPHA  #ifdef DYNTRANS_ALPHA
1225                  a = (vaddr_page >> ALPHA_LEVEL0_SHIFT) & (ALPHA_LEVEL0 - 1);                  a = (vaddr_page >> ALPHA_LEVEL0_SHIFT) & (ALPHA_LEVEL0 - 1);
# Line 1179  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1231  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1231                          vph_p = cpu->cd.alpha.vph_table0[a];                          vph_p = cpu->cd.alpha.vph_table0[a];
1232                  vph_p->phys_page[b] = NULL;                  vph_p->phys_page[b] = NULL;
1233                  if (vph_p->phys_addr[b] == paddr_page) {                  if (vph_p->phys_addr[b] == paddr_page) {
1234                          if (writeflag == 1)                          if (writeflag & MEM_WRITE)
1235                                  vph_p->host_store[b] = host_page;                                  vph_p->host_store[b] = host_page;
1236                          if (writeflag == -1)                          if (writeflag & MEM_DOWNGRADE)
1237                                  vph_p->host_store[b] = NULL;                                  vph_p->host_store[b] = NULL;
1238                  } else {                  } else {
1239                          /*  Change the entire physical/host mapping:  */                          /*  Change the entire physical/host mapping:  */
# Line 1194  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1246  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1246                  index = DYNTRANS_ADDR_TO_PAGENR(vaddr_page);                  index = DYNTRANS_ADDR_TO_PAGENR(vaddr_page);
1247                  cpu->cd.DYNTRANS_ARCH.phys_page[index] = NULL;                  cpu->cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1248  #ifdef DYNTRANS_ARM  #ifdef DYNTRANS_ARM
1249                  cpu->cd.DYNTRANS_ARCH.is_userpage[index >> 3]&=~(1<<(index&7));                  cpu->cd.DYNTRANS_ARCH.is_userpage[index>>5] &= ~(1<<(index&31));
1250                  if (useraccess)                  if (useraccess)
1251                          cpu->cd.DYNTRANS_ARCH.is_userpage[index >> 3]                          cpu->cd.DYNTRANS_ARCH.is_userpage[index >> 5]
1252                              |= 1 << (index & 7);                              |= 1 << (index & 31);
1253  #endif  #endif
1254                  if (cpu->cd.DYNTRANS_ARCH.phys_addr[index] == paddr_page) {                  if (cpu->cd.DYNTRANS_ARCH.phys_addr[index] == paddr_page) {
1255                          if (writeflag == 1)                          if (writeflag & MEM_WRITE)
1256                                  cpu->cd.DYNTRANS_ARCH.host_store[index] =                                  cpu->cd.DYNTRANS_ARCH.host_store[index] =
1257                                      host_page;                                      host_page;
1258                          if (writeflag == -1)                          if (writeflag & MEM_DOWNGRADE)
1259                                  cpu->cd.DYNTRANS_ARCH.host_store[index] = NULL;                                  cpu->cd.DYNTRANS_ARCH.host_store[index] = NULL;
1260                  } else {                  } else {
1261                          /*  Change the entire physical/host mapping:  */                          /*  Change the entire physical/host mapping:  */
# Line 1285  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1337  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1337           *  instruction combination.           *  instruction combination.
1338           */           */
1339          if (!single_step && !cpu->machine->instruction_trace) {          if (!single_step && !cpu->machine->instruction_trace) {
1340                  if (cpu->combination_check != NULL &&                  if (cpu->cd.DYNTRANS_ARCH.combination_check != NULL &&
1341                      cpu->machine->speed_tricks)                      cpu->machine->speed_tricks)
1342                          cpu->combination_check(cpu, ic,                          cpu->cd.DYNTRANS_ARCH.combination_check(cpu, ic,
1343                              addr & (DYNTRANS_PAGESIZE - 1));                              addr & (DYNTRANS_PAGESIZE - 1));
1344                  cpu->combination_check = NULL;                  cpu->cd.DYNTRANS_ARCH.combination_check = NULL;
1345          }          }
1346    
1347          /*  ... and finally execute the translated instruction:  */          /*  ... and finally execute the translated instruction:  */

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

  ViewVC Help
Powered by ViewVC 1.1.26