/[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 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  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.41 2005/11/23 22:03:31 debug Exp $   *  $Id: cpu_dyntrans.c,v 1.54 2006/02/09 22:55:20 debug Exp $
29   *   *
30   *  Common dyntrans routines. Included from cpu_*.c.   *  Common dyntrans routines. Included from cpu_*.c.
31   */   */
32    
33    
34  #ifdef  DYNTRANS_CPU_RUN_INSTR  #ifdef  DYNTRANS_CPU_RUN_INSTR
35    #if 1   /*  IC statistics:  */
36    static void gather_statistics(struct cpu *cpu)
37    {
38            struct DYNTRANS_IC *ic = cpu->cd.DYNTRANS_ARCH.next_ic;
39            static long long n = 0;
40            static FILE *f = NULL;
41    
42            n++;
43            if (n < 100000000)
44                    return;
45    
46            if (f == NULL) {
47                    f = fopen("instruction_call_statistics.raw", "w");
48                    if (f == NULL) {
49                            fatal("Unable to open statistics file for output.\n");
50                            exit(1);
51                    }
52            }
53            fwrite(&ic->f, 1, sizeof(void *), f);
54    }
55    #else   /*  PC statistics:  */
56  static void gather_statistics(struct cpu *cpu)  static void gather_statistics(struct cpu *cpu)
57  {  {
58          uint64_t a;          uint64_t a;
# Line 89  a &= 0x03ffffff; Line 110  a &= 0x03ffffff;
110          }          }
111  }  }
112  }  }
113    #endif  /*  PC statistics  */
114    
115  #define S               gather_statistics(cpu)  #define S               gather_statistics(cpu)
116    
117  #ifdef DYNTRANS_VARIABLE_INSTRUCTION_LENGTH  #ifdef DYNTRANS_VARIABLE_INSTRUCTION_LENGTH
118  #define I               ic = cpu->cd.DYNTRANS_ARCH.next_ic;             \  #define I               ic = cpu->cd.DYNTRANS_ARCH.next_ic;             \
119                          cpu->cd.DYNTRANS_ARCH.next_ic += ic->len;       \                          cpu->cd.DYNTRANS_ARCH.next_ic += ic->arg[0];    \
120                          ic->f(cpu, ic);                          ic->f(cpu, ic);
121  #else  #else
122  #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);
# Line 178  int DYNTRANS_CPU_RUN_INSTR(struct emul * Line 199  int DYNTRANS_CPU_RUN_INSTR(struct emul *
199                              sizeof(instr), MEM_READ, CACHE_INSTRUCTION)) {                              sizeof(instr), MEM_READ, CACHE_INSTRUCTION)) {
200                                  fatal("XXX_cpu_run_instr(): could not read "                                  fatal("XXX_cpu_run_instr(): could not read "
201                                      "the instruction\n");                                      "the instruction\n");
202                          } else                          } else {
203                                  cpu_disassemble_instr(cpu->machine, cpu,                                  cpu_disassemble_instr(cpu->machine, cpu,
204                                      instr, 1, 0, 0);                                      instr, 1, 0, 0);
205    #ifdef DYNTRANS_MIPS
206    /*  TODO: generalize, not just MIPS  */
207                                    /*  Show the instruction in the delay slot,
208                                        if any:  */
209                                    fatal("TODO: check for delay slot!\n");
210    #endif
211                            }
212                  }                  }
213    
214                  /*  When single-stepping, multiple instruction calls cannot                  /*  When single-stepping, multiple instruction calls cannot
# Line 263  int DYNTRANS_CPU_RUN_INSTR(struct emul * Line 291  int DYNTRANS_CPU_RUN_INSTR(struct emul *
291                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);
292                  cpu->pc += (DYNTRANS_IC_ENTRIES_PER_PAGE <<                  cpu->pc += (DYNTRANS_IC_ENTRIES_PER_PAGE <<
293                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);                      DYNTRANS_INSTR_ALIGNMENT_SHIFT);
294            } else if (low_pc == DYNTRANS_IC_ENTRIES_PER_PAGE + 1) {
295                    /*  Switch to next page and skip an instruction which was
296                        already executed (in a delay slot):  */
297                    cpu->pc &= ~((DYNTRANS_IC_ENTRIES_PER_PAGE-1) <<
298                        DYNTRANS_INSTR_ALIGNMENT_SHIFT);
299                    cpu->pc += ((DYNTRANS_IC_ENTRIES_PER_PAGE + 1) <<
300                        DYNTRANS_INSTR_ALIGNMENT_SHIFT);
301          }          }
302    
303  #ifdef DYNTRANS_PPC  #ifdef DYNTRANS_PPC
# Line 270  int DYNTRANS_CPU_RUN_INSTR(struct emul * Line 305  int DYNTRANS_CPU_RUN_INSTR(struct emul *
305          {          {
306                  uint32_t old = cpu->cd.ppc.spr[SPR_DEC];                  uint32_t old = cpu->cd.ppc.spr[SPR_DEC];
307                  cpu->cd.ppc.spr[SPR_DEC] = (uint32_t) (old - n_instrs);                  cpu->cd.ppc.spr[SPR_DEC] = (uint32_t) (old - n_instrs);
308                  if ((old >> 31) == 0 && (cpu->cd.ppc.spr[SPR_DEC] >> 31) == 1)                  if ((old >> 31) == 0 && (cpu->cd.ppc.spr[SPR_DEC] >> 31) == 1
309                        && !(cpu->cd.ppc.cpu_type.flags & PPC_NO_DEC))
310                          cpu->cd.ppc.dec_intr_pending = 1;                          cpu->cd.ppc.dec_intr_pending = 1;
   
311                  old = cpu->cd.ppc.spr[SPR_TBL];                  old = cpu->cd.ppc.spr[SPR_TBL];
312                  cpu->cd.ppc.spr[SPR_TBL] += n_instrs;                  cpu->cd.ppc.spr[SPR_TBL] += n_instrs;
313                  if ((old >> 31) == 1 && (cpu->cd.ppc.spr[SPR_TBL] >> 31) == 0)                  if ((old >> 31) == 1 && (cpu->cd.ppc.spr[SPR_TBL] >> 31) == 0)
# Line 361  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 396  void DYNTRANS_FUNCTION_TRACE(struct cpu
396  #ifdef DYNTRANS_MIPS  #ifdef DYNTRANS_MIPS
397                      gpr[MIPS_GPR_A0                      gpr[MIPS_GPR_A0
398  #endif  #endif
 #ifdef DYNTRANS_NEWMIPS  
                     r[0         /*  TODO  */  
 #endif  
399  #ifdef DYNTRANS_PPC  #ifdef DYNTRANS_PPC
400                      gpr[3                      gpr[3
401  #endif  #endif
# Line 371  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 403  void DYNTRANS_FUNCTION_TRACE(struct cpu
403                      r[2                      r[2
404  #endif  #endif
405  #ifdef DYNTRANS_SPARC  #ifdef DYNTRANS_SPARC
406                      r_i[0                      r[24
407  #endif  #endif
408                      + x];                      + x];
409  #endif  #endif
# Line 403  void DYNTRANS_FUNCTION_TRACE(struct cpu Line 435  void DYNTRANS_FUNCTION_TRACE(struct cpu
435    
436    
437  #ifdef DYNTRANS_TC_ALLOCATE_DEFAULT_PAGE  #ifdef DYNTRANS_TC_ALLOCATE_DEFAULT_PAGE
438    
439  /*  forward declaration of to_be_translated and end_of_page:  */  /*  forward declaration of to_be_translated and end_of_page:  */
440  static void instr(to_be_translated)(struct cpu *, struct DYNTRANS_IC *);  static void instr(to_be_translated)(struct cpu *, struct DYNTRANS_IC *);
441  static void instr(end_of_page)(struct cpu *,struct DYNTRANS_IC *);  static void instr(end_of_page)(struct cpu *,struct DYNTRANS_IC *);
# Line 410  static void instr(end_of_page)(struct cp Line 443  static void instr(end_of_page)(struct cp
443  static void instr32(to_be_translated)(struct cpu *, struct DYNTRANS_IC *);  static void instr32(to_be_translated)(struct cpu *, struct DYNTRANS_IC *);
444  static void instr32(end_of_page)(struct cpu *,struct DYNTRANS_IC *);  static void instr32(end_of_page)(struct cpu *,struct DYNTRANS_IC *);
445  #endif  #endif
446    
447    #ifdef DYNTRANS_DELAYSLOT
448    static void instr(end_of_page2)(struct cpu *,struct DYNTRANS_IC *);
449    #ifdef DYNTRANS_DUALMODE_32
450    static void instr32(end_of_page2)(struct cpu *,struct DYNTRANS_IC *);
451    #endif
452    #endif
453    
454  /*  /*
455   *  XXX_tc_allocate_default_page():   *  XXX_tc_allocate_default_page():
456   *   *
# Line 436  static void DYNTRANS_TC_ALLOCATE_DEFAULT Line 477  static void DYNTRANS_TC_ALLOCATE_DEFAULT
477  #endif  #endif
478                      instr(to_be_translated);                      instr(to_be_translated);
479    
480          ppp->ics[DYNTRANS_IC_ENTRIES_PER_PAGE].f =          ppp->ics[DYNTRANS_IC_ENTRIES_PER_PAGE + 0].f =
481  #ifdef DYNTRANS_DUALMODE_32  #ifdef DYNTRANS_DUALMODE_32
482              cpu->is_32bit? instr32(end_of_page) :              cpu->is_32bit? instr32(end_of_page) :
483  #endif  #endif
484              instr(end_of_page);              instr(end_of_page);
485    
486    #ifdef DYNTRANS_DELAYSLOT
487            ppp->ics[DYNTRANS_IC_ENTRIES_PER_PAGE + 1].f =
488    #ifdef DYNTRANS_DUALMODE_32
489                cpu->is_32bit? instr32(end_of_page2) :
490    #endif
491                instr(end_of_page2);
492    #endif
493    
494          cpu->translation_cache_cur_ofs += sizeof(struct DYNTRANS_TC_PHYSPAGE);          cpu->translation_cache_cur_ofs += sizeof(struct DYNTRANS_TC_PHYSPAGE);
495    
496          cpu->translation_cache_cur_ofs --;          cpu->translation_cache_cur_ofs --;
# Line 489  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 538  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
538          } else          } else
539                  vph_p = cpu->cd.alpha.vph_table0[a];                  vph_p = cpu->cd.alpha.vph_table0[a];
540  #else  #else
541  #ifdef DYNTRANS_IA64          fatal("Neither alpha nor 32-bit? 3\n");
         fatal("IA64 todo\n");  
 #else  
         fatal("Neither alpha, ia64, nor 32-bit? 3\n");  
542          exit(1);          exit(1);
543  #endif  #endif
544  #endif  #endif
 #endif  
545    
546          /*  Virtual to physical address translation:  */          /*  Virtual to physical address translation:  */
547          ok = 0;          ok = 0;
# Line 512  void DYNTRANS_PC_TO_POINTERS_GENERIC(str Line 557  void DYNTRANS_PC_TO_POINTERS_GENERIC(str
557                  ok = 1;                  ok = 1;
558          }          }
559  #else  #else
560  #ifdef DYNTRANS_IA64          fatal("Neither alpha nor 32-bit? 4\n");
         fatal("IA64 todo\n");  
 #else  
         fatal("Neither alpha, ia64, nor 32-bit? 4\n");  
561          exit(1);          exit(1);
562  #endif  #endif
563  #endif  #endif
 #endif  
564    
565          if (!ok) {          if (!ok) {
566                  uint64_t paddr;                  uint64_t paddr;
# Line 660  void DYNTRANS_PC_TO_POINTERS_FUNC(struct Line 701  void DYNTRANS_PC_TO_POINTERS_FUNC(struct
701  #else  #else
702          uint64_t          uint64_t
703  #endif  #endif
704              cached_pc;              cached_pc = cpu->pc;
705          struct DYNTRANS_TC_PHYSPAGE *ppp;          struct DYNTRANS_TC_PHYSPAGE *ppp;
706    
707  #ifdef MODE32  #ifdef MODE32
708          int index;          int index;
         cached_pc = cpu->pc;  
709          index = DYNTRANS_ADDR_TO_PAGENR(cached_pc);          index = DYNTRANS_ADDR_TO_PAGENR(cached_pc);
710          ppp = cpu->cd.DYNTRANS_ARCH.phys_page[index];          ppp = cpu->cd.DYNTRANS_ARCH.phys_page[index];
711          if (ppp != NULL)          if (ppp != NULL)
# Line 675  void DYNTRANS_PC_TO_POINTERS_FUNC(struct Line 715  void DYNTRANS_PC_TO_POINTERS_FUNC(struct
715          uint32_t a, b;          uint32_t a, b;
716          int kernel = 0;          int kernel = 0;
717          struct alpha_vph_page *vph_p;          struct alpha_vph_page *vph_p;
         cached_pc = cpu->pc;  
718          a = (cached_pc >> ALPHA_LEVEL0_SHIFT) & (ALPHA_LEVEL0 - 1);          a = (cached_pc >> ALPHA_LEVEL0_SHIFT) & (ALPHA_LEVEL0 - 1);
719          b = (cached_pc >> ALPHA_LEVEL1_SHIFT) & (ALPHA_LEVEL1 - 1);          b = (cached_pc >> ALPHA_LEVEL1_SHIFT) & (ALPHA_LEVEL1 - 1);
720          if ((cached_pc >> ALPHA_TOPSHIFT) == ALPHA_TOP_KERNEL) {          if ((cached_pc >> ALPHA_TOPSHIFT) == ALPHA_TOP_KERNEL) {
# Line 689  void DYNTRANS_PC_TO_POINTERS_FUNC(struct Line 728  void DYNTRANS_PC_TO_POINTERS_FUNC(struct
728                          goto have_it;                          goto have_it;
729          }          }
730  #else  #else
731            fatal("X1: cached_pc=%016llx\n", (long long)cached_pc);
732          /*  Temporary, to avoid a compiler warning:  */          /*  Temporary, to avoid a compiler warning:  */
         cached_pc = 0;  
733          ppp = NULL;          ppp = NULL;
734  #ifdef DYNTRANS_IA64          fatal("Neither alpha nor 32-bit? 1\n");
         fatal("IA64 todo\n");  
 #else  
         fatal("Neither alpha, ia64, nor 32-bit? 1\n");  
735          exit(1);          exit(1);
736  #endif  #endif
737  #endif  #endif
 #endif  
738    
739          DYNTRANS_PC_TO_POINTERS_GENERIC(cpu);          DYNTRANS_PC_TO_POINTERS_GENERIC(cpu);
740          return;          return;
# Line 800  static void DYNTRANS_INVALIDATE_TLB_ENTR Line 835  static void DYNTRANS_INVALIDATE_TLB_ENTR
835                              cpu->cd.alpha.vph_default_page;                              cpu->cd.alpha.vph_default_page;
836          }          }
837  #else   /*  !DYNTRANS_ALPHA  */  #else   /*  !DYNTRANS_ALPHA  */
838  #ifdef DYNTRANS_IA64          fatal("Not yet for non-1-level, non-Alpha\n");
         fatal("IA64: blah blah TODO\n");  
 #else  
         fatal("Not yet for non-1-level, non-Alpha, non-ia64\n");  
 #endif  /*  !DYNTRANS_IA64  */  
839  #endif  /*  !DYNTRANS_ALPHA  */  #endif  /*  !DYNTRANS_ALPHA  */
840  #endif  #endif
841  }  }
# Line 821  static void DYNTRANS_INVALIDATE_TLB_ENTR Line 852  static void DYNTRANS_INVALIDATE_TLB_ENTR
852   *  flags should be one of   *  flags should be one of
853   *      INVALIDATE_PADDR  INVALIDATE_VADDR  or  INVALIDATE_ALL   *      INVALIDATE_PADDR  INVALIDATE_VADDR  or  INVALIDATE_ALL
854   *   *
855     *  In addition, for INVALIDATE_ALL, INVALIDATE_VADDR_UPPER4 may be set and
856     *  bit 31..28 of addr are used to select the virtual addresses to invalidate.
857     *  (This is useful for PowerPC emulation, when segment registers are updated.)
858     *
859   *  In the case when all translations are invalidated, paddr doesn't need   *  In the case when all translations are invalidated, paddr doesn't need
860   *  to be supplied.   *  to be supplied.
861   *   *
# Line 828  static void DYNTRANS_INVALIDATE_TLB_ENTR Line 863  static void DYNTRANS_INVALIDATE_TLB_ENTR
863   *             the quick translation array, not from the linear   *             the quick translation array, not from the linear
864   *             vph_tlb_entry[] array.  Hopefully this is enough anyway.   *             vph_tlb_entry[] array.  Hopefully this is enough anyway.
865   */   */
866  void DYNTRANS_INVALIDATE_TC(struct cpu *cpu, uint64_t paddr, int flags)  void DYNTRANS_INVALIDATE_TC(struct cpu *cpu, uint64_t addr, int flags)
867  {  {
868          int r;          int r;
869  #ifdef MODE32  #ifdef MODE32
# Line 836  void DYNTRANS_INVALIDATE_TC(struct cpu * Line 871  void DYNTRANS_INVALIDATE_TC(struct cpu *
871  #else  #else
872          uint64_t          uint64_t
873  #endif  #endif
874              addr_page = paddr & ~(DYNTRANS_PAGESIZE - 1);              addr_page = addr & ~(DYNTRANS_PAGESIZE - 1);
875    
876          /*  fatal("invalidate(): ");  */          /*  fatal("invalidate(): ");  */
877    
878          /*  Quick case for virtual addresses: see note above.  */          /*  Quick case for _one_ virtual addresses: see note above.  */
879          if (flags & INVALIDATE_VADDR) {          if (flags & INVALIDATE_VADDR) {
880                  /*  fatal("vaddr 0x%08x\n", (int)addr_page);  */                  /*  fatal("vaddr 0x%08x\n", (int)addr_page);  */
881                  DYNTRANS_INVALIDATE_TLB_ENTRY(cpu, addr_page, flags);                  DYNTRANS_INVALIDATE_TLB_ENTRY(cpu, addr_page, flags);
882                  return;                  return;
883          }          }
884    
885            /*  Invalidate everything:  */
886    #ifdef DYNTRANS_PPC
887            if (flags & INVALIDATE_ALL && flags & INVALIDATE_VADDR_UPPER4) {
888                    /*  fatal("all, upper4 (PowerPC segment)\n");  */
889                    for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {
890                            if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid &&
891                                (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page
892                                & 0xf0000000) == addr_page) {
893                                    DYNTRANS_INVALIDATE_TLB_ENTRY(cpu, cpu->cd.
894                                        DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page,
895                                        0);
896                                    cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid=0;
897                            }
898                    }
899                    return;
900            }
901    #endif
902          if (flags & INVALIDATE_ALL) {          if (flags & INVALIDATE_ALL) {
903                  /*  fatal("all\n");  */                  /*  fatal("all\n");  */
904                  for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {                  for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {
# Line 860  void DYNTRANS_INVALIDATE_TC(struct cpu * Line 912  void DYNTRANS_INVALIDATE_TC(struct cpu *
912                  return;                  return;
913          }          }
914    
915          /*  fatal("paddr 0x%08x\n", (int)addr_page);  */          /*  Invalidate a physical page:  */
916    
917            if (!(flags & INVALIDATE_PADDR))
918                    fatal("HUH? Invalidate: Not vaddr, all, or paddr?\n");
919    
920            /*  fatal("addr 0x%08x\n", (int)addr_page);  */
921    
922          for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {          for (r=0; r<DYNTRANS_MAX_VPH_TLB_ENTRIES; r++) {
923                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid && (                  if (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid && addr_page
924                      (cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page ==                      == cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page) {
                     addr_page && flags & INVALIDATE_PADDR) ||  
                     flags & INVALIDATE_ALL) ) {  
925                          DYNTRANS_INVALIDATE_TLB_ENTRY(cpu,                          DYNTRANS_INVALIDATE_TLB_ENTRY(cpu,
926                              cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page,                              cpu->cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page,
927                              flags);                              flags);
# Line 1022  void DYNTRANS_INVALIDATE_TC_CODE(struct Line 1077  void DYNTRANS_INVALIDATE_TC_CODE(struct
1077                                          vph_p = cpu->cd.alpha.vph_table0[a];                                          vph_p = cpu->cd.alpha.vph_table0[a];
1078                                  vph_p->phys_page[b] = NULL;                                  vph_p->phys_page[b] = NULL;
1079  #else   /*  !DYNTRANS_ALPHA  */  #else   /*  !DYNTRANS_ALPHA  */
1080  #ifdef DYNTRANS_IA64                                  fatal("Not yet for non-1-level, non-Alpha\n");
                                 fatal("IA64: blah yo yo TODO\n");  
 #else  
                                 fatal("Not yet for non-1-level, non-Alpha, "  
                                     "non-ia64\n");  
 #endif  /*  !DYNTRANS_IA64  */  
1081  #endif  /*  !DYNTRANS_ALPHA  */  #endif  /*  !DYNTRANS_ALPHA  */
1082  #endif  #endif
1083                          }                          }
# Line 1068  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1118  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1118              " p=0x%x\n", (int)vaddr_page, host_page, writeflag,              " p=0x%x\n", (int)vaddr_page, host_page, writeflag,
1119              (int)paddr_page);  */              (int)paddr_page);  */
1120  #else   /*  !MODE32  */  #else   /*  !MODE32  */
1121  #ifdef DYNTRANS_IA64          fatal("Neither 32-bit nor Alpha? 2\n");
         fatal("IA64 update todo\n");  
 #else  
         fatal("Neither 32-bit, IA64, nor Alpha? 2\n");  
1122          exit(1);          exit(1);
1123  #endif  #endif
1124  #endif  #endif
 #endif  
1125    
1126          if (writeflag & MEMORY_USER_ACCESS) {          if (writeflag & MEMORY_USER_ACCESS) {
1127                  writeflag &= ~MEMORY_USER_ACCESS;                  writeflag &= ~MEMORY_USER_ACCESS;
# Line 1300  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1346  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1346                                  fatal("BREAKPOINT: pc = 0x%llx\n(The "                                  fatal("BREAKPOINT: pc = 0x%llx\n(The "
1347                                      "instruction has not yet executed.)\n",                                      "instruction has not yet executed.)\n",
1348                                      (long long)cpu->pc);                                      (long long)cpu->pc);
1349    #ifdef DYNTRANS_DELAYSLOT
1350                                    if (cpu->cd.DYNTRANS_ARCH.delay_slot !=
1351                                        NOT_DELAYED)
1352                                            fatal("ERROR! Breakpoint in a delay"
1353                                                " slot! Not yet supported.\n");
1354    #endif
1355                                  single_step_breakpoint = 1;                                  single_step_breakpoint = 1;
1356                                  single_step = 1;                                  single_step = 1;
1357                                  goto stop_running_translated;                                  goto stop_running_translated;
# Line 1321  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1373  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1373           */           */
1374  #ifdef MODE32  #ifdef MODE32
1375          if (!(cpu->cd.DYNTRANS_ARCH.cur_physpage->flags & TRANSLATIONS)) {          if (!(cpu->cd.DYNTRANS_ARCH.cur_physpage->flags & TRANSLATIONS)) {
1376                  uint32_t index = DYNTRANS_ADDR_TO_PAGENR(addr);                  uint32_t index = DYNTRANS_ADDR_TO_PAGENR((uint32_t)addr);
1377                  cpu->cd.DYNTRANS_ARCH.phystranslation[index >> 5] |=                  cpu->cd.DYNTRANS_ARCH.phystranslation[index >> 5] |=
1378                      (1 << (index & 31));                      (1 << (index & 31));
1379          }          }
# Line 1329  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s Line 1381  void DYNTRANS_UPDATE_TRANSLATION_TABLE(s
1381          cpu->cd.DYNTRANS_ARCH.cur_physpage->flags |= TRANSLATIONS;          cpu->cd.DYNTRANS_ARCH.cur_physpage->flags |= TRANSLATIONS;
1382    
1383    
1384    #ifdef DYNTRANS_BACKEND
1385            /*
1386             *  "Empty"/simple native dyntrans backend stuff:
1387             *
1388             *  1) If no translation is currently being done, but the translated
1389             *     instruction was simple enough, then let's start making a new
1390             *     native translation block.
1391             *
1392             *  2) If a native translation block is currently being constructed,
1393             *     but this instruction wasn't simple enough, then end the block
1394             *     (without including this instruction).
1395             *
1396             *  3) If a native translation block is currently being constructed,
1397             *     and this is a simple instruction, then add it.
1398             */
1399            if (simple && cpu->translation_context.p == NULL &&
1400                dyntrans_backend_enable) {
1401                    size_t s = 0;
1402    
1403                    if (cpu->translation_context.translation_buffer == NULL) {
1404                            cpu->translation_context.translation_buffer =
1405                                zeroed_alloc(DTB_TRANSLATION_SIZE_MAX +
1406                                DTB_TRANSLATION_SIZE_MARGIN);
1407                    }
1408    
1409                    cpu->translation_context.p =
1410                        cpu->translation_context.translation_buffer;
1411    
1412                    cpu->translation_context.ic_page =
1413                        cpu->cd.DYNTRANS_ARCH.cur_ic_page;
1414                    cpu->translation_context.start_instr_call_index =
1415                        ((size_t)ic - (size_t)cpu->cd.DYNTRANS_ARCH.cur_ic_page)
1416                        / (sizeof(*ic));
1417    
1418                    dtb_function_prologue(&cpu->translation_context, &s);
1419                    cpu->translation_context.p += s;
1420                    cpu->translation_context.n_simple = 0;
1421            }
1422    
1423            /*  If this is not a continuation of a simple translation, then
1424                stop now!  */
1425            if (cpu->translation_context.ic_page != cpu->cd.DYNTRANS_ARCH.
1426                cur_ic_page || ic != &cpu->cd.DYNTRANS_ARCH.cur_ic_page[
1427                cpu->translation_context.start_instr_call_index +
1428                cpu->translation_context.n_simple])
1429                    simple = 0;
1430    
1431            if (cpu->translation_context.p != NULL && !simple) {
1432                    size_t s = 0, total;
1433    
1434                    if (cpu->translation_context.n_simple > 1) {
1435                            dtb_generate_ptr_inc(cpu, &cpu->translation_context,
1436                                &s, &cpu->cd.DYNTRANS_ARCH.next_ic,
1437                                (cpu->translation_context.n_simple - 1) *
1438                                sizeof(*(cpu->cd.DYNTRANS_ARCH.next_ic)));
1439                            cpu->translation_context.p += s;
1440                    }
1441    
1442                    dtb_function_epilogue(&cpu->translation_context, &s);
1443                    cpu->translation_context.p += s;
1444    
1445                    cpu_dtb_do_fixups(cpu);
1446    #if 0
1447    {
1448    int i;
1449    unsigned char *addr = cpu->translation_context.translation_buffer;
1450    printf("index = %i\n", cpu->translation_context.start_instr_call_index);
1451    quiet_mode = 0;
1452    for (i=0; i<4*32; i+=4)
1453            alpha_cpu_disassemble_instr(cpu, (unsigned char *)addr + i,
1454            0, i, 0);
1455    }
1456    #endif
1457                    total = (size_t)cpu->translation_context.p -
1458                        (size_t)cpu->translation_context.translation_buffer;
1459    
1460                    /*  Copy the translated block to the translation cache:  */
1461                    /*  Align first:  */
1462                    cpu->translation_cache_cur_ofs --;
1463                    cpu->translation_cache_cur_ofs |= 31;
1464                    cpu->translation_cache_cur_ofs ++;
1465    
1466                    memcpy(cpu->translation_cache + cpu->translation_cache_cur_ofs,
1467                        cpu->translation_context.translation_buffer, total);
1468    
1469                    /*  Set the ic pointer:  */
1470                    ((struct DYNTRANS_IC *)cpu->translation_context.ic_page)
1471                        [cpu->translation_context.start_instr_call_index].f =
1472                        (void *)
1473                        (cpu->translation_cache + cpu->translation_cache_cur_ofs);
1474    
1475                    /*  Align cur_ofs afterwards as well, just to be safe.  */
1476                    cpu->translation_cache_cur_ofs += total;
1477                    cpu->translation_cache_cur_ofs --;
1478                    cpu->translation_cache_cur_ofs |= 31;
1479                    cpu->translation_cache_cur_ofs ++;
1480    
1481                    /*  Set the "combined instruction" flag for this page:  */
1482                    cpu->cd.DYNTRANS_ARCH.cur_physpage = (void *)
1483                        cpu->cd.DYNTRANS_ARCH.cur_ic_page;
1484                    cpu->cd.DYNTRANS_ARCH.cur_physpage->flags |= COMBINATIONS;
1485    
1486                    dtb_host_cacheinvalidate(0,0); /* p , size ... ); */
1487    
1488                    cpu->translation_context.p = NULL;
1489            }
1490            if (cpu->translation_context.p != NULL) {
1491                    size_t s = 0;
1492                    dtb_generate_fcall(cpu, &cpu->translation_context,
1493                        &s, (size_t)ic->f, (size_t)ic);
1494                    cpu->translation_context.p += s;
1495                    cpu->translation_context.n_simple ++;
1496            }
1497    #endif  /*  DYNTRANS_BACKEND  */
1498    
1499    
1500          /*          /*
1501           *  Now it is time to check for combinations of instructions that can           *  Now it is time to check for combinations of instructions that can
1502           *  be converted into a single function call.           *  be converted into a single function call.

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

  ViewVC Help
Powered by ViewVC 1.1.26