/[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 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 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.120 2006/08/12 11:43:12 debug Exp $   *  $Id: cpu_dyntrans.c,v 1.142 2007/02/11 10:47:31 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 230  int DYNTRANS_RUN_INSTR(struct cpu *cpu) Line 236  int DYNTRANS_RUN_INSTR(struct cpu *cpu)
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    
# 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                          }                          }
# Line 339  while (cycles-- > 0) Line 346  while (cycles-- > 0)
346                  }                  }
347          } else {          } else {
348                  /*  Execute multiple instructions:  */                  /*  Execute multiple instructions:  */
349                  int n = 0;                  n_instrs = 0;
350                  for (;;) {                  for (;;) {
351                          struct DYNTRANS_IC *ic;                          struct DYNTRANS_IC *ic;
352    
# Line 351  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 += 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 (n + cpu->n_translated_instrs >=                          I; I; I; I; I;   I; I; I; I; I;
368                              N_SAFE_DYNTRANS_LIMIT)  
369                            cpu->n_translated_instrs += 120;
370                            if (cpu->n_translated_instrs >= N_SAFE_DYNTRANS_LIMIT)
371                                  break;                                  break;
372                  }                  }
                 n_instrs = n;  
373          }          }
374    
375          n_instrs += cpu->n_translated_instrs;          n_instrs += cpu->n_translated_instrs;
# Line 394  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 438  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 463  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 489  void DYNTRANS_FUNCTION_TRACE(struct cpu
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;
492  #if defined(DYNTRANS_X86) || defined(DYNTRANS_TRANSPUTER)  #if defined(DYNTRANS_TRANSPUTER)
493                  d = 0;          /*  TODO  */                  d = 0;          /*  TODO  */
494  #else  #else
495                  /*  Args in registers:  */                  /*  Args in registers:  */
# Line 479  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 505  void DYNTRANS_FUNCTION_TRACE(struct cpu
505                          they go downwards, ie. 22,23 and so on  */                          they go downwards, ie. 22,23 and so on  */
506                      r[24                      r[24
507  #endif  #endif
 #ifdef DYNTRANS_HPPA  
                     r[0         /*  TODO  */  
 #endif  
 #ifdef DYNTRANS_I960  
                     r[0         /*  TODO  */  
 #endif  
 #ifdef DYNTRANS_IA64  
                     r[0         /*  TODO  */  
 #endif  
508  #ifdef DYNTRANS_M68K  #ifdef DYNTRANS_M68K
509                      d[0         /*  TODO  */                      d[0         /*  TODO  */
510  #endif  #endif
# Line 497  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 514  void DYNTRANS_FUNCTION_TRACE(struct cpu
514  #ifdef DYNTRANS_PPC  #ifdef DYNTRANS_PPC
515                      gpr[3                      gpr[3
516  #endif  #endif
517    #ifdef DYNTRANS_RCA180X
518                        r[0         /*  TODO  */
519    #endif
520  #ifdef DYNTRANS_SH  #ifdef DYNTRANS_SH
521                      r[2                      r[4         /*  NetBSD seems to use 4? But 2 seems
522                                            to be used by other code? TODO  */
523  #endif  #endif
524  #ifdef DYNTRANS_SPARC  #ifdef DYNTRANS_SPARC
525                      r[24                      r[8         /*  o0..o5  */
526  #endif  #endif
527                      + x];                      + x];
528  #endif  #endif
# Line 544  static void DYNTRANS_TC_ALLOCATE_DEFAULT Line 565  static void DYNTRANS_TC_ALLOCATE_DEFAULT
565  {  {
566          struct DYNTRANS_TC_PHYSPAGE *ppp;          struct DYNTRANS_TC_PHYSPAGE *ppp;
567    
568            native_commit(cpu);
569    
570          ppp = (struct DYNTRANS_TC_PHYSPAGE *)(cpu->translation_cache          ppp = (struct DYNTRANS_TC_PHYSPAGE *)(cpu->translation_cache
571              + cpu->translation_cache_cur_ofs);              + cpu->translation_cache_cur_ofs);
572    
# Line 655  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 678  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
678                          }                          }
679  #else  #else
680                          x1 = (cached_pc >> (64-DYNTRANS_L1N)) & mask1;                          x1 = (cached_pc >> (64-DYNTRANS_L1N)) & mask1;
681                          x2 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;                          x2 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N))
682                          x3 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N))                              & mask2;
683                              & mask3;                          x3 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N
684                                - DYNTRANS_L3N)) & mask3;
685                          l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];                          l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1];
686                          l3 = l2->l3[x2];                          l3 = l2->l3[x2];
687                          if (l3->host_load[x3] != NULL) {                          if (l3->host_load[x3] != NULL) {
# Line 701  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 725  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
725                  }                  }
726          }          }
727    
728          if (cpu->translation_cache_cur_ofs >= DYNTRANS_CACHE_SIZE) {          if (cpu->translation_cache_cur_ofs >= dyntrans_cache_size) {
729  #ifdef UNSTABLE_DEVEL  #ifdef UNSTABLE_DEVEL
730                  fatal("[ dyntrans: resetting the translation cache ]\n");                  fatal("[ dyntrans: resetting the translation cache ]\n");
731  #endif  #endif
# Line 735  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 759  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
759                  /*  fatal("CREATING page %lli (physaddr 0x%"PRIx64"), table "                  /*  fatal("CREATING page %lli (physaddr 0x%"PRIx64"), table "
760                      "index %i\n", (long long)pagenr, (uint64_t)physaddr,                      "index %i\n", (long long)pagenr, (uint64_t)physaddr,
761                      (int)table_index);  */                      (int)table_index);  */
762                    native_commit(cpu);
763                  *physpage_entryp = physpage_ofs =                  *physpage_entryp = physpage_ofs =
764                      cpu->translation_cache_cur_ofs;                      cpu->translation_cache_cur_ofs;
765    
# Line 1224  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1249  void DYNTRANS_INVALIDATE_TC_CODE(struct
1249                  physpage_entryp = &(((uint32_t *)cpu->                  physpage_entryp = &(((uint32_t *)cpu->
1250                      translation_cache)[table_index]);                      translation_cache)[table_index]);
1251                  physpage_ofs = *physpage_entryp;                  physpage_ofs = *physpage_entryp;
1252    
1253                    /*  Return immediately if there is no code translation
1254                        for this page.  */
1255                    if (physpage_ofs == 0)
1256                            return;
1257    
1258                  prev_ppp = ppp = NULL;                  prev_ppp = ppp = NULL;
1259    
1260                  /*  Traverse the physical page chain:  */                  /*  Traverse the physical page chain:  */
# Line 1241  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1272  void DYNTRANS_INVALIDATE_TC_CODE(struct
1272                          physpage_ofs = ppp->next_ofs;                          physpage_ofs = ppp->next_ofs;
1273                  }                  }
1274    
1275                  if (physpage_ofs == 0)                  /*  If there is no translation, there is no need to go
1276                          ppp = NULL;                      on and try to remove it from the vph_tlb_entry array:  */
1277                    if (ppp == NULL)
1278                            return;
1279    
1280  #if 0  #if 0
1281                  /*                  /*
# Line 1341  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1374  void DYNTRANS_INVALIDATE_TC_CODE(struct
1374  void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page,  void DYNTRANS_UPDATE_TRANSLATION_TABLE(struct cpu *cpu, uint64_t vaddr_page,
1375          unsigned char *host_page, int writeflag, uint64_t paddr_page)          unsigned char *host_page, int writeflag, uint64_t paddr_page)
1376  {  {
1377          int found, r, lowest_index, useraccess = 0;          int found, r, useraccess = 0;
1378    
1379  #ifdef MODE32  #ifdef MODE32
1380          uint32_t index;          uint32_t index;
# Line 1372  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1405  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1405          }          }
1406    
1407          /*  Scan the current TLB entries:  */          /*  Scan the current TLB entries:  */
         lowest_index = 0;  
1408    
1409  #ifdef MODE32  #ifdef MODE32
1410          /*          /*
# Line 1404  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1436  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1436  #endif  #endif
1437    
1438          if (found < 0) {          if (found < 0) {
1439                    /*  Create the new TLB entry, overwriting a "random" entry:  */
1440                  static unsigned int x = 0;                  static unsigned int x = 0;
1441                  lowest_index = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES;                  r = (x++) % DYNTRANS_MAX_VPH_TLB_ENTRIES;
         }  
1442    
         if (found < 0) {  
                 /*  Create the new TLB entry, overwriting the oldest one:  */  
                 r = lowest_index;  
1443                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
1444                          /*  This one has to be invalidated first:  */                          /*  This one has to be invalidated first:  */
1445                          DYNTRANS_INVALIDATE_TLB_ENTRY(cpu,                          DYNTRANS_INVALIDATE_TLB_ENTRY(cpu,

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

  ViewVC Help
Powered by ViewVC 1.1.26