/[gxemul]/trunk/src/bintrans.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/bintrans.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: bintrans.c,v 1.160 2005/04/06 21:16:45 debug Exp $   *  $Id: bintrans.c,v 1.177 2005/08/14 15:47:36 debug Exp $
29   *   *
30   *  Dynamic binary translation.   *  Dynamic binary translation.
31   *   *
# Line 81  Line 81 
81   *   *
82   *      o)  Load/stores: TODO: Comment.   *      o)  Load/stores: TODO: Comment.
83   *   *
  *  Testing:  Running regression tests with and without the binary translator  
  *  enabled should obviously result in the exact same results, or something is  
  *  wrong.  
84   *   *
85   *  The general idea is something like this:   *  The general idea is something like this:
86   *   *
# Line 123  Line 120 
120  int bintrans_pc_is_in_cache(struct cpu *cpu, uint64_t pc) { return 0; }  int bintrans_pc_is_in_cache(struct cpu *cpu, uint64_t pc) { return 0; }
121  void bintrans_invalidate(struct cpu *cpu, uint64_t paddr) { }  void bintrans_invalidate(struct cpu *cpu, uint64_t paddr) { }
122  int bintrans_attempt_translate(struct cpu *cpu, uint64_t paddr) { return 0; }  int bintrans_attempt_translate(struct cpu *cpu, uint64_t paddr) { return 0; }
123    void bintrans_restart(struct cpu *cpu) { }
124  void bintrans_init_cpu(struct cpu *cpu) { }  void bintrans_init_cpu(struct cpu *cpu) { }
125  void bintrans_init(struct machine *machine, struct memory *mem)  void bintrans_init(struct machine *machine, struct memory *mem)
126  {  {
# Line 141  static void bintrans_write_chunkreturn_f Line 139  static void bintrans_write_chunkreturn_f
139  static void bintrans_write_pc_inc(unsigned char **addrp);  static void bintrans_write_pc_inc(unsigned char **addrp);
140  static void bintrans_write_quickjump(struct memory *mem,  static void bintrans_write_quickjump(struct memory *mem,
141          unsigned char *quickjump_code, uint32_t chunkoffset);          unsigned char *quickjump_code, uint32_t chunkoffset);
142  static int bintrans_write_instruction__addiu_etc(unsigned char **addrp, int rt,  static int bintrans_write_instruction__addiu_etc(struct memory *mem,
143          int rs, int imm, int instruction_type);          unsigned char **addrp, int rt, int rs, int imm,
144  static int bintrans_write_instruction__addu_etc(unsigned char **addrp, int rd,          int instruction_type);
145          int rs, int rt, int sa, int instruction_type);  static int bintrans_write_instruction__addu_etc(struct memory *mem,
146            unsigned char **addrp, int rd, int rs, int rt, int sa,
147            int instruction_type);
148  static int bintrans_write_instruction__branch(unsigned char **addrp,  static int bintrans_write_instruction__branch(unsigned char **addrp,
149          int instruction_type, int regimm_type, int rt, int rs, int imm);          int instruction_type, int regimm_type, int rt, int rs, int imm);
150  static int bintrans_write_instruction__jr(unsigned char **addrp, int rs,  static int bintrans_write_instruction__jr(unsigned char **addrp, int rs,
# Line 156  static int bintrans_write_instruction__d Line 156  static int bintrans_write_instruction__d
156          int only_care_about_chunk_p, int p, int forward);          int only_care_about_chunk_p, int p, int forward);
157  static int bintrans_write_instruction__loadstore(struct memory *mem,  static int bintrans_write_instruction__loadstore(struct memory *mem,
158          unsigned char **addrp, int rt, int imm, int rs, int instruction_type,          unsigned char **addrp, int rt, int imm, int rs, int instruction_type,
159          int bigendian);          int bigendian, int do_alignment_check);
160  static int bintrans_write_instruction__lui(unsigned char **addrp, int rt,  static int bintrans_write_instruction__lui(unsigned char **addrp, int rt,
161          int imm);          int imm);
162  static int bintrans_write_instruction__mfmthilo(unsigned char **addrp, int rd,  static int bintrans_write_instruction__mfmthilo(unsigned char **addrp, int rd,
# Line 201  static void bintrans_register_potential_ Line 201  static void bintrans_register_potential_
201  #define BACKEND_NAME "i386"  #define BACKEND_NAME "i386"
202  #include "bintrans_i386.c"  #include "bintrans_i386.c"
203  #else  #else
 #ifdef MIPS  
 #define BACKEND_NAME "MIPS"  
 #include "bintrans_mips.c"  
 #else  
 #ifdef SPARCV9  
 #define BACKEND_NAME "UltraSPARC"  
 #include "bintrans_sparcv9.c"  
 #else  
204  #error Unsupported host architecture for bintrans.  #error Unsupported host architecture for bintrans.
 #endif  /*  SPARCV9  */  
 #endif  /*  MIPS  */  
205  #endif  /*  I386  */  #endif  /*  I386  */
206  #endif  /*  ALPHA  */  #endif  /*  ALPHA  */
207    
# Line 278  void bintrans_invalidate(struct cpu *cpu Line 268  void bintrans_invalidate(struct cpu *cpu
268    
269    
270  /*  /*
271     *  bintrans_restart():
272     *
273     *  Starts over by throwing away the bintrans cache contents.
274     */
275    void bintrans_restart(struct cpu *cpu)
276    {
277            int i, n = 1 << BINTRANS_CACHE_N_INDEX_BITS;
278    
279            if (cpu->machine->arch != ARCH_MIPS)
280                    return;
281    
282            for (i=0; i<n; i++)
283                    cpu->mem->translation_page_entry_array[i] = NULL;
284    
285            cpu->mem->translation_code_chunk_space_head = 0;
286            cpu->mem->n_quick_jumps = 0;
287    
288            debug("[ bintrans: Starting over! ]\n");
289            clear_all_chunks_from_all_tables(cpu);
290    }
291    
292    
293    /*
294   *  enter_chunks_into_tables():   *  enter_chunks_into_tables():
295   */   */
296  static void enter_chunks_into_tables(struct cpu *cpu, uint64_t vaddr,  static void enter_chunks_into_tables(struct cpu *cpu, uint64_t vaddr,
# Line 291  static void enter_chunks_into_tables(str Line 304  static void enter_chunks_into_tables(str
304                  a = (vaddr >> 22) & 0x3ff;                  a = (vaddr >> 22) & 0x3ff;
305                  b = (vaddr >> 12) & 0x3ff;                  b = (vaddr >> 12) & 0x3ff;
306                  tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];                  tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];
307                  if (tbl1->haddr_entry[b] != NULL)                  if (tbl1->haddr_entry[b*2] != NULL)
308                          tbl1->bintrans_chunks[b] = chunk0;                          tbl1->bintrans_chunks[b] = chunk0;
309                  break;                  break;
310          default:          default:
# Line 327  int old_bintrans_attempt_translate(struc Line 340  int old_bintrans_attempt_translate(struc
340          int rs,rt,rd,sa,imm;          int rs,rt,rd,sa,imm;
341          uint32_t *potential_chunk_p;    /*  for branches  */          uint32_t *potential_chunk_p;    /*  for branches  */
342          int byte_order_cached_bigendian;          int byte_order_cached_bigendian;
343          int delayed_branch, stop_after_delayed_branch;          int delayed_branch, stop_after_delayed_branch, return_code_written;
344          uint64_t delayed_branch_new_p;          uint64_t delayed_branch_new_p;
345          int prev_p;          int prev_p;
346    
# Line 337  int old_bintrans_attempt_translate(struc Line 350  int old_bintrans_attempt_translate(struc
350              (paddr & 3) != 0)              (paddr & 3) != 0)
351                  return cpu->cd.mips.bintrans_instructions_executed;                  return cpu->cd.mips.bintrans_instructions_executed;
352    
         cpu->mem->bintrans_32bit_only = (cpu->cd.mips.cpu_type.isa_level <= 2  
             || cpu->cd.mips.cpu_type.isa_level == 32);  
353          byte_order_cached_bigendian = (cpu->byte_order == EMUL_BIG_ENDIAN);          byte_order_cached_bigendian = (cpu->byte_order == EMUL_BIG_ENDIAN);
354    
355          /*  Is this a part of something that is already translated?  */          /*  Is this a part of something that is already translated?  */
356          paddr_page = paddr & ~0xfff;          paddr_page = paddr & ~0xfff;
357          offset_within_page = (paddr & 0xfff) / 4;          offset_within_page = (paddr & 0xfff) >> 2;
358          entry_index = PADDR_TO_INDEX(paddr);          entry_index = PADDR_TO_INDEX(paddr);
359          tep = cpu->mem->translation_page_entry_array[entry_index];          tep = cpu->mem->translation_page_entry_array[entry_index];
360          while (tep != NULL) {          while (tep != NULL) {
361                  if (tep->paddr == paddr_page) {                  if (tep->paddr == paddr_page) {
362                          int mask = 1 << (offset_within_page & 7);                          int mask;
363    
364                          if (tep->chunk[offset_within_page] != 0) {                          if (tep->chunk[offset_within_page] != 0) {
365                                  f = (size_t)tep->chunk[offset_within_page] +                                  f = (size_t)tep->chunk[offset_within_page] +
366                                      cpu->mem->translation_code_chunk_space;                                      cpu->mem->translation_code_chunk_space;
367                                  goto run_it;    /*  see further down  */                                  goto run_it;    /*  see further down  */
368                          }                          }
369    
370                            mask = 1 << (offset_within_page & 7);
371                          if (tep->flags[offset_within_page >> 3] & mask)                          if (tep->flags[offset_within_page >> 3] & mask)
372                                  return cpu->cd.mips.                                  return cpu->cd.mips.
373                                      bintrans_instructions_executed;                                      bintrans_instructions_executed;
# Line 380  cpu->cd.mips.pc_last_host_4k_page,(long Line 393  cpu->cd.mips.pc_last_host_4k_page,(long
393           */           */
394          if (cpu->mem->translation_code_chunk_space_head >=          if (cpu->mem->translation_code_chunk_space_head >=
395              cpu->machine->bintrans_size) {              cpu->machine->bintrans_size) {
396                  int i, n = 1 << BINTRANS_CACHE_N_INDEX_BITS;                  bintrans_restart(cpu);
                 for (i=0; i<n; i++)  
                         cpu->mem->translation_page_entry_array[i] = NULL;  
                 cpu->mem->translation_code_chunk_space_head = 0;  
                 cpu->mem->n_quick_jumps = 0;  
397                  tep = NULL;                  tep = NULL;
                 debug("bintrans: Starting over!\n");  
                 clear_all_chunks_from_all_tables(cpu);  
398          }          }
399    
400    
# Line 405  cpu->cd.mips.pc_last_host_4k_page,(long Line 412  cpu->cd.mips.pc_last_host_4k_page,(long
412    
413                  /*  ... and align again:  */                  /*  ... and align again:  */
414                  cpu->mem->translation_code_chunk_space_head =                  cpu->mem->translation_code_chunk_space_head =
415                      ((cpu->mem->translation_code_chunk_space_head - 1) | 63)                      ((cpu->mem->translation_code_chunk_space_head - 1) | 31)+1;
                     + 1;  
416    
417                  /*  Add the entry to the array:  */                  /*  Add the entry to the array:  */
418                  memset(tep, 0, sizeof(struct translation_page_entry));                  memset(tep, 0, sizeof(struct translation_page_entry));
# Line 434  cpu->cd.mips.pc_last_host_4k_page,(long Line 440  cpu->cd.mips.pc_last_host_4k_page,(long
440           *  Try to translate a chunk of code:           *  Try to translate a chunk of code:
441           */           */
442          p = paddr & 0xfff;          p = paddr & 0xfff;
443            prev_p = p >> 2;
444          try_to_translate = 1;          try_to_translate = 1;
445          n_translated = 0;          n_translated = 0;
446          res = 0;          res = 0;
447            return_code_written = 0;
448          delayed_branch = 0;          delayed_branch = 0;
449          stop_after_delayed_branch = 0;          stop_after_delayed_branch = 0;
450          delayed_branch_new_p = 0;          delayed_branch_new_p = 0;
# Line 445  cpu->cd.mips.pc_last_host_4k_page,(long Line 453  cpu->cd.mips.pc_last_host_4k_page,(long
453    
454          while (try_to_translate) {          while (try_to_translate) {
455                  ca_justdid = ca;                  ca_justdid = ca;
                 prev_p = p/4;  
456                  translated = 0;                  translated = 0;
457    
458                  /*  Read an instruction word from host memory:  */                  /*  Read an instruction word from host memory:  */
# Line 488  cpu->cd.mips.pc_last_host_4k_page,(long Line 495  cpu->cd.mips.pc_last_host_4k_page,(long
495                                          bintrans_write_chunkreturn_fail(&ca);                                          bintrans_write_chunkreturn_fail(&ca);
496                                          tep->flags[prev_p >> 3] |= mask;                                          tep->flags[prev_p >> 3] |= mask;
497                                          try_to_translate = 0;                                          try_to_translate = 0;
498                                            return_code_written = 1;
499                                  } else {                                  } else {
500                                          translated = bintrans_write_instruction__tlb_rfe_etc(&ca,                                          translated = bintrans_write_instruction__tlb_rfe_etc(&ca,
501                                              special6 == SPECIAL_BREAK? CALL_BREAK : CALL_SYSCALL);                                              special6 == SPECIAL_BREAK? CALL_BREAK : CALL_SYSCALL);
# Line 529  cpu->cd.mips.pc_last_host_4k_page,(long Line 537  cpu->cd.mips.pc_last_host_4k_page,(long
537                                          rd = rt = rs = sa = 0;                                          rd = rt = rs = sa = 0;
538                                          special6 = SPECIAL_SLL;                                          special6 = SPECIAL_SLL;
539                                  }                                  }
540                                  translated = try_to_translate = bintrans_write_instruction__addu_etc(&ca, rd, rs, rt, sa, special6);                                  translated = try_to_translate = bintrans_write_instruction__addu_etc(cpu->mem, &ca, rd, rs, rt, sa, special6);
541                                  n_translated += translated;                                  n_translated += translated;
542                                  break;                                  break;
543                          case SPECIAL_MFHI:                          case SPECIAL_MFHI:
# Line 551  cpu->cd.mips.pc_last_host_4k_page,(long Line 559  cpu->cd.mips.pc_last_host_4k_page,(long
559                                          tep->flags[prev_p >> 3] |= mask;                                          tep->flags[prev_p >> 3] |= mask;
560                                  }                                  }
561                                  try_to_translate = 0;                                  try_to_translate = 0;
562                                    return_code_written = 1;
563                          }                          }
564                          break;                          break;
565    
# Line 569  cpu->cd.mips.pc_last_host_4k_page,(long Line 578  cpu->cd.mips.pc_last_host_4k_page,(long
578                                  delayed_branch_new_p = p + 4 + 4*imm;                                  delayed_branch_new_p = p + 4 + 4*imm;
579                                  break;                                  break;
580                          default:                          default:
                                 try_to_translate = 0;  
581                                  /*  Untranslatable:  */                                  /*  Untranslatable:  */
582                                  /*  TODO: this code should only be in one place  */                                  /*  TODO: this code should only be in one place  */
583                                  bintrans_write_chunkreturn_fail(&ca);                                  bintrans_write_chunkreturn_fail(&ca);
# Line 578  cpu->cd.mips.pc_last_host_4k_page,(long Line 586  cpu->cd.mips.pc_last_host_4k_page,(long
586                                          tep->flags[prev_p >> 3] |= mask;                                          tep->flags[prev_p >> 3] |= mask;
587                                  }                                  }
588                                  try_to_translate = 0;                                  try_to_translate = 0;
589                                    return_code_written = 1;
590                          }                          }
591                          break;                          break;
592    
# Line 621  cpu->cd.mips.pc_last_host_4k_page,(long Line 630  cpu->cd.mips.pc_last_host_4k_page,(long
630                  case HI6_XORI:                  case HI6_XORI:
631                  case HI6_DADDI:                  case HI6_DADDI:
632                  case HI6_DADDIU:                  case HI6_DADDIU:
633                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);                          translated = try_to_translate =
634                          rt = instr[2] & 31;                              bintrans_write_instruction__addiu_etc(cpu->mem,
635                          imm = (instr[1] << 8) + instr[0];                              &ca, instr[2] & 31,
636                          translated = try_to_translate = bintrans_write_instruction__addiu_etc(&ca, rt, rs, imm, hi6);                              ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7),
637                                (instr[1] << 8) + instr[0], hi6);
638                          n_translated += translated;                          n_translated += translated;
639                          break;                          break;
640    
641                  case HI6_LUI:                  case HI6_LUI:
642                          rt = instr[2] & 31;                          translated = try_to_translate =
643                          imm = (instr[1] << 8) + instr[0];                              bintrans_write_instruction__lui(&ca,
644                          translated = try_to_translate = bintrans_write_instruction__lui(&ca, rt, imm);                              instr[2] & 31, (instr[1] << 8) + instr[0]);
645                          n_translated += translated;                          n_translated += translated;
646                          break;                          break;
647    
# Line 664  cpu->cd.mips.pc_last_host_4k_page,(long Line 674  cpu->cd.mips.pc_last_host_4k_page,(long
674                                                  translated = try_to_translate = bintrans_write_instruction__mfc_mtc(cpu->mem, &ca, 0, 1, rt, rd, 1);                                                  translated = try_to_translate = bintrans_write_instruction__mfc_mtc(cpu->mem, &ca, 0, 1, rt, rd, 1);
675                                                  n_translated += translated;                                                  n_translated += translated;
676                                          }                                          }
677                                    } else {
678                                            /*  Untranslatable:  */
679                                            /*  TODO: this code should only be in one place  */
680                                            bintrans_write_chunkreturn_fail(&ca);
681                                            {
682                                                    int mask = 1 << (prev_p & 7);
683                                                    tep->flags[prev_p >> 3] |= mask;
684                                            }
685                                            try_to_translate = 0;
686                                            return_code_written = 1;
687                                  }                                  }
688                                  break;                                  break;
689                          case 0x42:                          case 0x42:
# Line 695  cpu->cd.mips.pc_last_host_4k_page,(long Line 715  cpu->cd.mips.pc_last_host_4k_page,(long
715                                          n_translated += translated;                                          n_translated += translated;
716                                  } else if (instr[2] == 0 && instr[1] == 0 && (instr[0] == 0x21 || instr[0] == 0x22)) {                                  } else if (instr[2] == 0 && instr[1] == 0 && (instr[0] == 0x21 || instr[0] == 0x22)) {
717                                          /*  standby and suspend on VR41xx etc ==> NOP  */                                          /*  standby and suspend on VR41xx etc ==> NOP  */
718                                          translated = try_to_translate = bintrans_write_instruction__addu_etc(&ca, 0, 0, 0, 0, SPECIAL_SLL);                                          translated = try_to_translate = bintrans_write_instruction__addu_etc(cpu->mem, &ca, 0, 0, 0, 0, SPECIAL_SLL);
719                                          n_translated += translated;                                          n_translated += translated;
720                                    } else {
721                                            /*  Untranslatable:  */
722                                            /*  TODO: this code should only be in one place  */
723                                            bintrans_write_chunkreturn_fail(&ca);
724                                            {
725                                                    int mask = 1 << (prev_p & 7);
726                                                    tep->flags[prev_p >> 3] |= mask;
727                                            }
728                                            try_to_translate = 0;
729                                            return_code_written = 1;
730                                  }                                  }
731                                  break;                                  break;
732                          default:                          default:
733                                    /*  Untranslatable:  */
734                                    /*  TODO: this code should only be in one place  */
735                                    bintrans_write_chunkreturn_fail(&ca);
736                                    {
737                                            int mask = 1 << (prev_p & 7);
738                                            tep->flags[prev_p >> 3] |= mask;
739                                    }
740                                  try_to_translate = 0;                                  try_to_translate = 0;
741                                    return_code_written = 1;
742                          }                          }
743                          break;                          break;
   
744  #if 0  #if 0
745                  case HI6_LQ_MDMX:                  case HI6_LQ_MDMX:
746  #endif  #endif
# Line 730  cpu->cd.mips.pc_last_host_4k_page,(long Line 767  cpu->cd.mips.pc_last_host_4k_page,(long
767                          imm = (instr[1] << 8) + instr[0];                          imm = (instr[1] << 8) + instr[0];
768                          if (imm >= 32768)                          if (imm >= 32768)
769                                  imm -= 65536;                                  imm -= 65536;
770                          translated = try_to_translate = bintrans_write_instruction__loadstore(cpu->mem, &ca, rt, imm, rs, hi6, byte_order_cached_bigendian);                          translated = try_to_translate = bintrans_write_instruction__loadstore(cpu->mem, &ca, rt, imm, rs, hi6,
771                                byte_order_cached_bigendian,
772                                cpu->machine->dyntrans_alignment_check);
773                          n_translated += translated;                          n_translated += translated;
774                          break;                          break;
775    
776                  case HI6_CACHE:                  case HI6_CACHE:
777                          translated = try_to_translate = bintrans_write_instruction__addu_etc(&ca, 0, 0, 0, 0, SPECIAL_SLL);                          translated = try_to_translate = bintrans_write_instruction__addu_etc(cpu->mem, &ca, 0, 0, 0, 0, SPECIAL_SLL);
778                          n_translated += translated;                          n_translated += translated;
779                          break;                          break;
780    
# Line 748  cpu->cd.mips.pc_last_host_4k_page,(long Line 787  cpu->cd.mips.pc_last_host_4k_page,(long
787                                  tep->flags[prev_p >> 3] |= mask;                                  tep->flags[prev_p >> 3] |= mask;
788                          }                          }
789                          try_to_translate = 0;                          try_to_translate = 0;
790                            return_code_written = 1;
791                  }                  }
792    
793                  if (translated && delayed_branch) {                  if (translated && delayed_branch) {
# Line 796  cpu->cd.mips.pc_last_host_4k_page,(long Line 836  cpu->cd.mips.pc_last_host_4k_page,(long
836                                              tep->chunk[prev_p]);                                              tep->chunk[prev_p]);
837                  }                  }
838    
839                  /*  Glue together with previously translated code, if any:  */                  if (translated && try_to_translate && prev_p < 1023) {
840                  if (translated && try_to_translate &&                          int mask = 1 << ((prev_p+1) & 7);
                     prev_p < 1023 && tep->chunk[prev_p+1] != 0  
                     && !delayed_branch) {  
                         bintrans_write_instruction__delayedbranch(cpu->mem,  
                             &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);  
                         try_to_translate = 0;  
                 }  
841    
842                  if (translated && try_to_translate && n_translated > 80                          if (tep->flags[(prev_p+1) >> 3] & mask
843                      && prev_p < 1023 && !delayed_branch) {                              && !delayed_branch) {
844                          bintrans_write_instruction__delayedbranch(cpu->mem,                                  bintrans_write_chunkreturn_fail(&ca);
845                              &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);                                  try_to_translate = 0;
846                          try_to_translate = 0;                                  return_code_written = 1;
847                  }                                  break;
848                            }
849    
850  {                          /*  Glue together with previously translated code,
851          int mask = 1 << ((prev_p+1) & 7);                              if any:  */
852                            if (tep->chunk[prev_p+1] != 0 && !delayed_branch) {
853                                    bintrans_write_instruction__delayedbranch(cpu->mem,
854                                        &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);
855                                    try_to_translate = 0;
856                                    return_code_written = 1;
857                                    /*  try_to_translate = 0;  */
858                                    break;
859                            }
860    
861                  if (translated && try_to_translate &&                          if (n_translated > 120 && !delayed_branch) {
862                      tep->flags[(prev_p+1) >> 3] & mask                                  bintrans_write_instruction__delayedbranch(cpu->mem,
863                      && prev_p < 1023 && !delayed_branch) {                                      &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);
864                          bintrans_write_chunkreturn_fail(&ca);                                  try_to_translate = 0;
865                                    return_code_written = 1;
866                                    break;
867                            }
868                  }                  }
 }  
869    
870                  p += sizeof(instr);                  p += sizeof(instr);
871                    prev_p ++;
872    
873                  /*  If we have reached a different (MIPS) page, then stop translating.  */                  /*  If we have reached a different (MIPS) page, then stop translating.  */
874                  if (p == 0x1000)                  if (p == 0x1000)
# Line 843  cpu->cd.mips.pc_last_host_4k_page,(long Line 889  cpu->cd.mips.pc_last_host_4k_page,(long
889              cpu->mem->translation_code_chunk_space_head;              cpu->mem->translation_code_chunk_space_head;
890    
891          /*  Add return code:  */          /*  Add return code:  */
892          bintrans_write_chunkreturn(&ca);          if (!return_code_written)
893                    bintrans_write_chunkreturn(&ca);
894    
895          /*  chunk_len = nr of bytes occupied by the new code chunk  */          /*  chunk_len = nr of bytes occupied by the new code chunk  */
896          chunk_len = (size_t)ca - (size_t)ca2;          chunk_len = (size_t)ca - (size_t)ca2;
# Line 855  cpu->cd.mips.pc_last_host_4k_page,(long Line 902  cpu->cd.mips.pc_last_host_4k_page,(long
902    
903          /*  Align the code chunk space:  */          /*  Align the code chunk space:  */
904          cpu->mem->translation_code_chunk_space_head =          cpu->mem->translation_code_chunk_space_head =
905              ((cpu->mem->translation_code_chunk_space_head - 1) | 63) + 1;              ((cpu->mem->translation_code_chunk_space_head - 1) | 31) + 1;
906    
907    
908          /*  RUN the code chunk:  */          /*  RUN the code chunk:  */
# Line 897  run_it: Line 944  run_it:
944                          /*  tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];  */                          /*  tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];  */
945    
946                          tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0[a];                          tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0[a];
947                          if (tbl1->haddr_entry[b] != NULL) {                          if (tbl1->haddr_entry[b*2] != NULL) {
948                                  paddr = tbl1->paddr_entry[b] | (cpu->pc & 0xfff);                                  paddr = tbl1->paddr_entry[b] | (cpu->pc & 0xfff);
949                                  ok = 1;                                  ok = 1;
950                          }                          }
# Line 921  run_it: Line 968  run_it:
968    
969                  if (ok) {                  if (ok) {
970                          paddr_page = paddr & ~0xfff;                          paddr_page = paddr & ~0xfff;
971                          offset_within_page = (paddr & 0xfff) / 4;                          offset_within_page = (paddr & 0xfff) >> 2;
972                          entry_index = PADDR_TO_INDEX(paddr);                          entry_index = PADDR_TO_INDEX(paddr);
973                          tep = cpu->mem->translation_page_entry_array[entry_index];                          tep = cpu->mem->translation_page_entry_array[entry_index];
974                          while (tep != NULL) {                          while (tep != NULL) {
975                                  if (tep->paddr == paddr_page) {                                  if (tep->paddr == paddr_page) {
976                                          int mask = 1 << (offset_within_page & 7);                                          int mask;
977                                          if (tep->chunk[offset_within_page] != 0) {                                          if (tep->chunk[offset_within_page] != 0) {
978                                                  f = (size_t)tep->chunk[offset_within_page] +                                                  f = (size_t)tep->chunk[offset_within_page] +
979                                                      cpu->mem->translation_code_chunk_space;                                                      cpu->mem->translation_code_chunk_space;
980                                                  goto run_it;                                                  goto run_it;
981                                          }                                          }
982                                            mask = 1 << (offset_within_page & 7);
983                                          if (tep->flags[offset_within_page >> 3] & mask)                                          if (tep->flags[offset_within_page >> 3] & mask)
984                                                  return cpu->cd.mips.bintrans_instructions_executed;                                                  return cpu->cd.mips.bintrans_instructions_executed;
985                                          break;                                          break;
# Line 941  run_it: Line 989  run_it:
989    
990  #if 1  #if 1
991                          /*  We have no translation.  */                          /*  We have no translation.  */
992                          if ((cpu->pc & 0xfff00000) == 0xbfc00000 &&                          if ((cpu->pc & 0xdff00000) == 0x9fc00000 &&
993                              cpu->machine->prom_emulation)                              cpu->machine->prom_emulation)
994                                  return cpu->cd.mips.bintrans_instructions_executed;                                  return cpu->cd.mips.bintrans_instructions_executed;
995    
# Line 959  run_it: Line 1007  run_it:
1007                                      cpu->cd.mips.vaddr_to_hostaddr_table0_kernel)                                      cpu->cd.mips.vaddr_to_hostaddr_table0_kernel)
1008                                          ok = 0;                                          ok = 0;
1009                                  tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];                                  tbl1 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel[a];
1010                                  if (ok && tbl1->haddr_entry[b] != NULL) {                                  if (ok && tbl1->haddr_entry[b*2] != NULL) {
1011                                          cpu->cd.mips.pc_last_virtual_page = cpu->pc & ~0xfff;                                          cpu->cd.mips.pc_last_virtual_page = cpu->pc & ~0xfff;
1012                                          cpu->cd.mips.pc_last_physical_page = paddr & ~0xfff;                                          cpu->cd.mips.pc_last_physical_page = paddr & ~0xfff;
1013                                          cpu->cd.mips.pc_last_host_4k_page = (unsigned char *)                                          cpu->cd.mips.pc_last_host_4k_page = (unsigned char *)tbl1->haddr_entry[b*2];
                                             (((size_t)tbl1->haddr_entry[b]) & ~1);  
1014                                          cpu->cd.mips.pc_bintrans_host_4kpage = cpu->cd.mips.pc_last_host_4k_page;                                          cpu->cd.mips.pc_bintrans_host_4kpage = cpu->cd.mips.pc_last_host_4k_page;
1015                                          cpu->cd.mips.pc_bintrans_paddr = paddr;                                          cpu->cd.mips.pc_bintrans_paddr = paddr;
1016    
# Line 1019  void old_bintrans_init_cpu(struct cpu *c Line 1066  void old_bintrans_init_cpu(struct cpu *c
1066          int i, offset;          int i, offset;
1067    
1068          cpu->cd.mips.chunk_base_address        = cpu->mem->translation_code_chunk_space;          cpu->cd.mips.chunk_base_address        = cpu->mem->translation_code_chunk_space;
1069          cpu->cd.mips.bintrans_loadstore_32bit  = bintrans_loadstore_32bit;          cpu->cd.mips.bintrans_load_32bit       = bintrans_load_32bit;
1070            cpu->cd.mips.bintrans_store_32bit      = bintrans_store_32bit;
1071          cpu->cd.mips.bintrans_jump_to_32bit_pc = bintrans_jump_to_32bit_pc;          cpu->cd.mips.bintrans_jump_to_32bit_pc = bintrans_jump_to_32bit_pc;
1072          cpu->cd.mips.bintrans_fast_tlbwri      = coproc_tlbwri;          cpu->cd.mips.bintrans_fast_tlbwri      = coproc_tlbwri;
1073          cpu->cd.mips.bintrans_fast_tlbpr       = coproc_tlbpr;          cpu->cd.mips.bintrans_fast_tlbpr       = coproc_tlbpr;
# Line 1037  void old_bintrans_init_cpu(struct cpu *c Line 1085  void old_bintrans_init_cpu(struct cpu *c
1085          cpu->cd.mips.vaddr_to_hostaddr_r2k3k_dcachetable =          cpu->cd.mips.vaddr_to_hostaddr_r2k3k_dcachetable =
1086              zeroed_alloc(sizeof(struct vth32_table));              zeroed_alloc(sizeof(struct vth32_table));
1087          for (i=0; i<1024; i++) {          for (i=0; i<1024; i++) {
1088                  cpu->cd.mips.vaddr_to_hostaddr_r2k3k_dcachetable->haddr_entry[i] =                  cpu->cd.mips.vaddr_to_hostaddr_r2k3k_dcachetable->
1089                      (void *)(((size_t)cpu->cd.mips.cache[0]+offset) | 1);                      haddr_entry[i*2] = (void *)((size_t)cpu->cd.mips.cache[0]+offset);
1090                    cpu->cd.mips.vaddr_to_hostaddr_r2k3k_dcachetable->
1091                        haddr_entry[i*2+1] = (void *)((size_t)cpu->cd.mips.cache[0]+offset);
1092                  offset = (offset + 4096) % cpu->cd.mips.cache_size[0];                  offset = (offset + 4096) % cpu->cd.mips.cache_size[0];
1093          }          }
1094          cpu->cd.mips.vaddr_to_hostaddr_r2k3k_dcachetable->refcount = 1024;          cpu->cd.mips.vaddr_to_hostaddr_r2k3k_dcachetable->refcount = 1024;
1095    
1096            /*  1M entry cache stuff for R2K/3K:  */
1097            if (cpu->cd.mips.cpu_type.isa_level == 1) {
1098                    cpu->cd.mips.huge_r2k3k_cache_table =
1099                        zeroed_alloc(1048576 * sizeof(unsigned char *));
1100    #if 1
1101                    for (i=0; i<1048576; i++) {
1102                            unsigned char *ptr = NULL;
1103                            if (i < (0xa0000000ULL >> 12) ||
1104                                i >= (0xc0000000ULL >> 12))
1105                                    ptr = cpu->cd.mips.
1106                                        vaddr_to_hostaddr_r2k3k_dcachetable
1107                                        ->haddr_entry[(i & 1023) * 2];
1108                            cpu->cd.mips.huge_r2k3k_cache_table[i] = ptr;
1109                    }
1110    #endif
1111            }
1112    
1113          /*  Instruction cache:  */          /*  Instruction cache:  */
1114          offset = 0;          offset = 0;
1115          cpu->cd.mips.vaddr_to_hostaddr_r2k3k_icachetable =          cpu->cd.mips.vaddr_to_hostaddr_r2k3k_icachetable =
1116              zeroed_alloc(sizeof(struct vth32_table));              zeroed_alloc(sizeof(struct vth32_table));
1117          for (i=0; i<1024; i++) {          for (i=0; i<1024; i++) {
1118                  cpu->cd.mips.vaddr_to_hostaddr_r2k3k_icachetable->haddr_entry[i] =                  cpu->cd.mips.vaddr_to_hostaddr_r2k3k_icachetable->
1119                      (void *)(((size_t)cpu->cd.mips.cache[1]+offset) | 1);                      haddr_entry[i*2] =
1120                        (void *)((size_t)cpu->cd.mips.cache[1]+offset);
1121                    cpu->cd.mips.vaddr_to_hostaddr_r2k3k_icachetable->
1122                        haddr_entry[i*2+1] =
1123                        (void *)((size_t)cpu->cd.mips.cache[1]+offset);
1124                  offset = (offset + 4096) % cpu->cd.mips.cache_size[1];                  offset = (offset + 4096) % cpu->cd.mips.cache_size[1];
1125          }          }
1126          cpu->cd.mips.vaddr_to_hostaddr_r2k3k_icachetable->refcount = 1024;          cpu->cd.mips.vaddr_to_hostaddr_r2k3k_icachetable->refcount = 1024;
# Line 1071  void old_bintrans_init_cpu(struct cpu *c Line 1142  void old_bintrans_init_cpu(struct cpu *c
1142          }          }
1143    
1144          cpu->cd.mips.vaddr_to_hostaddr_table0 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel;          cpu->cd.mips.vaddr_to_hostaddr_table0 = cpu->cd.mips.vaddr_to_hostaddr_table0_kernel;
1145    
1146            cpu->mem->bintrans_32bit_only = (cpu->cd.mips.cpu_type.isa_level <= 2
1147                || cpu->cd.mips.cpu_type.isa_level == 32);
1148  }  }
1149    
1150    

Legend:
Removed from v.2  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26