/[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 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC
# 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.120 2006/08/12 11:43:12 debug Exp $
29   *   *
30   *  Common dyntrans routines. Included from cpu_*.c.   *  Common dyntrans routines. Included from cpu_*.c.
31   */   */
# Line 223  int DYNTRANS_RUN_INSTR(struct cpu *cpu) Line 223  int DYNTRANS_RUN_INSTR(struct cpu *cpu)
223  #endif  #endif
224  #ifdef DYNTRANS_PPC  #ifdef DYNTRANS_PPC
225          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) {
226                  ppc_exception(cpu, PPC_EXCEPTION_DEC);                  if (!(cpu->cd.ppc.cpu_type.flags & PPC_NO_DEC))
227                            ppc_exception(cpu, PPC_EXCEPTION_DEC);
228                  cpu->cd.ppc.dec_intr_pending = 0;                  cpu->cd.ppc.dec_intr_pending = 0;
229          }          }
230          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)
# Line 233  int DYNTRANS_RUN_INSTR(struct cpu *cpu) Line 234  int DYNTRANS_RUN_INSTR(struct cpu *cpu)
234          cached_pc = cpu->pc;          cached_pc = cpu->pc;
235    
236          cpu->n_translated_instrs = 0;          cpu->n_translated_instrs = 0;
         cpu->running_translated = 1;  
237    
238          cpu->cd.DYNTRANS_ARCH.cur_physpage = (void *)          cpu->cd.DYNTRANS_ARCH.cur_physpage = (void *)
239              cpu->cd.DYNTRANS_ARCH.cur_ic_page;              cpu->cd.DYNTRANS_ARCH.cur_ic_page;
# Line 292  int DYNTRANS_RUN_INSTR(struct cpu *cpu) Line 292  int DYNTRANS_RUN_INSTR(struct cpu *cpu)
292                          }                          }
293                  }                  }
294    
                 /*  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;  
                 }  
   
295                  if (cpu->machine->statistics_enabled)                  if (cpu->machine->statistics_enabled)
296                          S;                          S;
297    
# Line 344  while (cycles-- > 0) Line 316  while (cycles-- > 0)
316          cpu->machine->tick_func[1](cpu, cpu->machine->tick_extra[1]);          cpu->machine->tick_func[1](cpu, cpu->machine->tick_extra[1]);
317  /* printf("B\n"); */  /* printf("B\n"); */
318    
319                          if (!cpu->running_translated ||                          if (n_instrs + cpu->n_translated_instrs >=
                             n_instrs + cpu->n_translated_instrs >=  
320                              N_SAFE_DYNTRANS_LIMIT)                              N_SAFE_DYNTRANS_LIMIT)
321                                  break;                                  break;
322                  }                  }
# Line 362  while (cycles-- > 0) Line 333  while (cycles-- > 0)
333    
334                          n_instrs += 24;                          n_instrs += 24;
335    
336                          if (!cpu->running_translated ||                          if (n_instrs + cpu->n_translated_instrs >=
                             n_instrs + cpu->n_translated_instrs >=  
337                              N_SAFE_DYNTRANS_LIMIT)                              N_SAFE_DYNTRANS_LIMIT)
338                                  break;                                  break;
339                  }                  }
340          } else {          } else {
341                  /*  Execute multiple instructions:  */                  /*  Execute multiple instructions:  */
342                  n_instrs = 0;                  int n = 0;
343                  for (;;) {                  for (;;) {
344                          struct DYNTRANS_IC *ic;                          struct DYNTRANS_IC *ic;
345    
# Line 381  while (cycles-- > 0) Line 351  while (cycles-- > 0)
351    
352                          I; I; I; I; I;   I; I; I; I; I;                          I; I; I; I; I;   I; I; I; I; I;
353    
354                          n_instrs += 60;                          n += 60;
355    
356                          if (!cpu->running_translated ||                          if (n + cpu->n_translated_instrs >=
                             n_instrs + cpu->n_translated_instrs >=  
357                              N_SAFE_DYNTRANS_LIMIT)                              N_SAFE_DYNTRANS_LIMIT)
358                                  break;                                  break;
359                  }                  }
360                    n_instrs = n;
361          }          }
362    
363          n_instrs += cpu->n_translated_instrs;          n_instrs += cpu->n_translated_instrs;
# Line 650  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 620  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
620          if (!ok) {          if (!ok) {
621                  uint64_t paddr;                  uint64_t paddr;
622                  if (cpu->translate_v2p != NULL) {                  if (cpu->translate_v2p != NULL) {
623                            uint64_t vaddr =
624    #if defined(MODE32) && defined(DYNTRANS_MIPS)
625                            /*  32-bit MIPS is _sign_ extend, not zero.  */
626                                (int32_t)
627    #endif
628                                cached_pc;
629                          ok = cpu->translate_v2p(                          ok = cpu->translate_v2p(
630                              cpu, cached_pc, &paddr, FLAG_INSTR);                              cpu, vaddr, &paddr, FLAG_INSTR);
631                  } else {                  } else {
632                          paddr = cached_pc;                          paddr = cached_pc;
633                          ok = 1;                          ok = 1;
# Line 902  void DYNTRANS_INIT_TABLES(struct cpu *cp Line 878  void DYNTRANS_INIT_TABLES(struct cpu *cp
878          }          }
879    
880          ppp->next_ofs = 0;          ppp->next_ofs = 0;
         ppp->flags = 0;  
881          ppp->translations = 0;          ppp->translations = 0;
882          /*  ppp->physaddr is filled in by the page allocator  */          /*  ppp->physaddr is filled in by the page allocator  */
883    
# Line 1312  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1287  void DYNTRANS_INVALIDATE_TC_CODE(struct
1287                                  x >>= 1;                                  x >>= 1;
1288                          }                          }
1289    
                         ppp->flags &= ~COMBINATIONS;  
1290                          ppp->translations = 0;                          ppp->translations = 0;
1291                  }                  }
1292  #endif  #endif
# Line 1367  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1341  void DYNTRANS_INVALIDATE_TC_CODE(struct
1341  void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page,  void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page,
1342          unsigned char *host_page, int writeflag, uint64_t paddr_page)          unsigned char *host_page, int writeflag, uint64_t paddr_page)
1343  {  {
 #ifndef MODE32  
         int64_t lowest, highest = -1;  
 #endif  
1344          int found, r, lowest_index, useraccess = 0;          int found, r, lowest_index, useraccess = 0;
1345    
1346  #ifdef MODE32  #ifdef MODE32
# Line 1414  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1385  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1385           */           */
1386          found = (int)cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[          found = (int)cpu->cd.DYNTRANS_ARCH.vaddr_to_tlbindex[
1387              DYNTRANS_ADDR_TO_PAGENR(vaddr_page)] - 1;              DYNTRANS_ADDR_TO_PAGENR(vaddr_page)] - 1;
1388    #else
1389            x1 = (vaddr_page >> (64-DYNTRANS_L1N)) & mask1;
1390            x2 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
1391            x3 = (vaddr_page >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N))
1392                & mask3;
1393    
1394            l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];
1395            if (l2 == cpu->cd.DYNTRANS_ARCH.l2_64_dummy)
1396                    found = -1;
1397            else {
1398                    l3 = l2->l3[x2];
1399                    if (l3 == cpu->cd.DYNTRANS_ARCH.l3_64_dummy)
1400                            found = -1;
1401                    else
1402                            found = (int)l3->vaddr_to_tlbindex[x3] - 1;
1403            }
1404    #endif
1405    
1406          if (found < 0) {          if (found < 0) {
1407                  static unsigned int x = 0;                  static unsigned int x = 0;
1408                  lowest_index = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES;                  lowest_index = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES;
1409          }          }
 #else  
         lowest = cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[0].timestamp;  
         found = -1;  
         for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {  
                 if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp < lowest) {  
                         lowest = cpu->cd.DYNTRANS_ARCH.  
                             vph_tlb_entry[r].timestamp;  
                         lowest_index = r;  
                 }  
                 if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp > highest)  
                         highest = cpu->cd.DYNTRANS_ARCH.  
                             vph_tlb_entry[r].timestamp;  
                 if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid &&  
                     cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page ==  
                     vaddr_page) {  
                         found = r;  
                         break;  
                 }  
         }  
 #endif  
1410    
1411          if (found < 0) {          if (found < 0) {
1412                  /*  Create the new TLB entry, overwriting the oldest one:  */                  /*  Create the new TLB entry, overwriting the oldest one:  */
# Line 1455  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1424  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1424                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page;                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page;
1425                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag =                  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag =
1426                      writeflag & MEM_WRITE;                      writeflag & MEM_WRITE;
 #ifndef MODE32  
                 cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1;  
 #endif  
1427    
1428                  /*  Add the new translation to the table:  */                  /*  Add the new translation to the table:  */
1429  #ifdef MODE32  #ifdef MODE32
# Line 1474  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1440  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1440                              |= 1 << (index & 31);                              |= 1 << (index & 31);
1441  #endif  #endif
1442  #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;  
   
1443                  l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];                  l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];
1444                  if (l2 == cpu->cd.DYNTRANS_ARCH.l2_64_dummy) {                  if (l2 == cpu->cd.DYNTRANS_ARCH.l2_64_dummy) {
1445                          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 1524  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1524                   *      Writeflag = MEM_DOWNGRADE: Downgrade to readonly.                   *      Writeflag = MEM_DOWNGRADE: Downgrade to readonly.
1525                   */                   */
1526                  r = found;                  r = found;
 #ifndef MODE32  
                 cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].timestamp = highest + 1;  
 #endif  
1527                  if (writeflag & MEM_WRITE)                  if (writeflag & MEM_WRITE)
1528                          cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1;                          cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1;
1529                  if (writeflag & MEM_DOWNGRADE)                  if (writeflag & MEM_DOWNGRADE)
# Line 1714  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].v Line 1672  cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].v
1672  #ifdef DYNTRANS_DELAYSLOT  #ifdef DYNTRANS_DELAYSLOT
1673              && !in_crosspage_delayslot              && !in_crosspage_delayslot
1674  #endif  #endif
1675              ) {              && cpu->cd.DYNTRANS_ARCH.combination_check != NULL
1676                  if (cpu->cd.DYNTRANS_ARCH.combination_check != NULL &&              && cpu->machine->allow_instruction_combinations) {
1677                      cpu->machine->allow_instruction_combinations)                  cpu->cd.DYNTRANS_ARCH.combination_check(cpu, ic,
1678                          cpu->cd.DYNTRANS_ARCH.combination_check(cpu, ic,                      addr & (DYNTRANS_PAGESIZE - 1));
                             addr & (DYNTRANS_PAGESIZE - 1));  
1679          }          }
1680    
1681          cpu->cd.DYNTRANS_ARCH.combination_check = NULL;          cpu->cd.DYNTRANS_ARCH.combination_check = NULL;
# Line 1798  bad:   /* Line 1755  bad:   /*
1755          }          }
1756    
1757          cpu->running = 0;          cpu->running = 0;
1758          cpu->dead = 1;  
1759            /*  Note: Single-stepping can jump here.  */
1760  stop_running_translated:  stop_running_translated:
1761    
1762          debugger_n_steps_left_before_interaction = 0;          debugger_n_steps_left_before_interaction = 0;
1763          cpu->running_translated = 0;  
1764          ic = cpu->cd.DYNTRANS_ARCH.next_ic = &nothing_call;          ic = cpu->cd.DYNTRANS_ARCH.next_ic = &nothing_call;
1765          cpu->cd.DYNTRANS_ARCH.next_ic ++;          cpu->cd.DYNTRANS_ARCH.next_ic ++;
1766    
1767          /*  Execute the "nothing" instruction:  */          /*  Execute the "nothing" instruction:  */
1768          ic->f(cpu, ic);          ic->f(cpu, ic);
1769    
1770  #endif  /*  DYNTRANS_TO_BE_TRANSLATED_TAIL  */  #endif  /*  DYNTRANS_TO_BE_TRANSLATED_TAIL  */
1771    

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

  ViewVC Help
Powered by ViewVC 1.1.26