/[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 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC revision 40 by dpavlin, Mon Oct 8 16:22:11 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.132 2006/10/27 13:12:20 debug Exp $   *  $Id: cpu_dyntrans.c,v 1.147 2007/04/19 15:18:16 debug Exp $
29   *   *
30   *  Common dyntrans routines. Included from cpu_*.c.   *  Common dyntrans routines. Included from cpu_*.c.
31   */   */
# Line 265  int DYNTRANS_RUN_INSTR(struct cpu *cpu) Line 265  int DYNTRANS_RUN_INSTR(struct cpu *cpu)
265                              any instruction for any ISA:  */                              any instruction for any ISA:  */
266                          unsigned char instr[1 <<                          unsigned char instr[1 <<
267                              DYNTRANS_INSTR_ALIGNMENT_SHIFT];                              DYNTRANS_INSTR_ALIGNMENT_SHIFT];
 #ifdef DYNTRANS_X86  
                         cpu->cd.x86.cursegment = X86_S_CS;  
                         cpu->cd.x86.seg_override = 0;  
 #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 "
# Line 350  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 362  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 411  while (cycles-- > 0) Line 412  while (cycles-- > 0)
412  /*  Not yet.  TODO  */  /*  Not yet.  TODO  */
413                          if (cpu->machine->emulated_hz > 0) {                          if (cpu->machine->emulated_hz > 0) {
414                                  if (cpu->cd.mips.compare_interrupts_pending > 0)                                  if (cpu->cd.mips.compare_interrupts_pending > 0)
415                                          cpu_interrupt(cpu, 7);                                          INTERRUPT_ASSERT(
416                                                cpu->cd.mips.irq_compare);
417                          } else                          } else
418  #endif  #endif
419                          {                          {
420                                  if (diff1 > 0 && diff2 <= 0)                                  if (diff1 > 0 && diff2 <= 0)
421                                          cpu_interrupt(cpu, 7);                                          INTERRUPT_ASSERT(
422                                                cpu->cd.mips.irq_compare);
423                          }                          }
424                  }                  }
425          }          }
# Line 460  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 463  void DYNTRANS_FUNCTION_TRACE(struct cpu
463  #if defined(DYNTRANS_ALPHA) || defined(DYNTRANS_SPARC)  #if defined(DYNTRANS_ALPHA) || defined(DYNTRANS_SPARC)
464              6              6
465  #else  #else
466  #ifdef DYNTRANS_SH  #if defined(DYNTRANS_SH) || defined(DYNTRANS_M88K)
467              8   /*  Both for 32-bit and 64-bit SuperH  */              8   /*  Both for 32-bit and 64-bit SuperH, and M88K  */
468  #else  #else
469              4   /*  Default value for most archs  */              4   /*  Default value for most archs  */
470  #endif  #endif
# Line 485  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 502  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_AVR32  
                     r[0         /*  TODO  */  
 #endif  
 #ifdef DYNTRANS_HPPA  
                     r[0         /*  TODO  */  
 #endif  
 #ifdef DYNTRANS_I960  
                     r[0         /*  TODO  */  
 #endif  
 #ifdef DYNTRANS_IA64  
                     r[0         /*  TODO  */  
 #endif  
 #ifdef DYNTRANS_M68K  
                     d[0         /*  TODO  */  
 #endif  
503  #ifdef DYNTRANS_MIPS  #ifdef DYNTRANS_MIPS
504                      gpr[MIPS_GPR_A0                      gpr[MIPS_GPR_A0
505  #endif  #endif
506    #ifdef DYNTRANS_M88K
507                        r[2         /*  r2..r9  */
508    #endif
509  #ifdef DYNTRANS_PPC  #ifdef DYNTRANS_PPC
510                      gpr[3                      gpr[3
511  #endif  #endif
 #ifdef DYNTRANS_RCA180X  
                     r[0         /*  TODO  */  
 #endif  
512  #ifdef DYNTRANS_SH  #ifdef DYNTRANS_SH
513                      r[4         /*  NetBSD seems to use 4? But 2 seems                      r[4         /*  NetBSD seems to use 4? But 2 seems
514                                          to be used by other code? TODO  */                                          to be used by other code? TODO  */
# Line 534  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 517  void DYNTRANS_FUNCTION_TRACE(struct cpu
517                      r[8         /*  o0..o5  */                      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 685  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 731  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 758  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 773  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 1254  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 1271  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                  /*                  /*

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

  ViewVC Help
Powered by ViewVC 1.1.26