/[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 4 by dpavlin, Mon Oct 8 16:18:00 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.165 2005/04/27 16:37:34 debug Exp $
29   *   *
30   *  Dynamic binary translation.   *  Dynamic binary translation.
31   *   *
# Line 123  Line 123 
123  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; }
124  void bintrans_invalidate(struct cpu *cpu, uint64_t paddr) { }  void bintrans_invalidate(struct cpu *cpu, uint64_t paddr) { }
125  int bintrans_attempt_translate(struct cpu *cpu, uint64_t paddr) { return 0; }  int bintrans_attempt_translate(struct cpu *cpu, uint64_t paddr) { return 0; }
126    void bintrans_restart(struct cpu *cpu) { }
127  void bintrans_init_cpu(struct cpu *cpu) { }  void bintrans_init_cpu(struct cpu *cpu) { }
128  void bintrans_init(struct machine *machine, struct memory *mem)  void bintrans_init(struct machine *machine, struct memory *mem)
129  {  {
# Line 278  void bintrans_invalidate(struct cpu *cpu Line 279  void bintrans_invalidate(struct cpu *cpu
279    
280    
281  /*  /*
282     *  bintrans_restart():
283     *
284     *  Starts over by throwing away the bintrans cache contents.
285     */
286    void bintrans_restart(struct cpu *cpu)
287    {
288            int i, n = 1 << BINTRANS_CACHE_N_INDEX_BITS;
289    
290            for (i=0; i<n; i++)
291                    cpu->mem->translation_page_entry_array[i] = NULL;
292    
293            cpu->mem->translation_code_chunk_space_head = 0;
294            cpu->mem->n_quick_jumps = 0;
295    
296            /*  debug("bintrans: Starting over!\n");  */
297            clear_all_chunks_from_all_tables(cpu);
298    }
299    
300    
301    /*
302   *  enter_chunks_into_tables():   *  enter_chunks_into_tables():
303   */   */
304  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 337  int old_bintrans_attempt_translate(struc Line 358  int old_bintrans_attempt_translate(struc
358              (paddr & 3) != 0)              (paddr & 3) != 0)
359                  return cpu->cd.mips.bintrans_instructions_executed;                  return cpu->cd.mips.bintrans_instructions_executed;
360    
         cpu->mem->bintrans_32bit_only = (cpu->cd.mips.cpu_type.isa_level <= 2  
             || cpu->cd.mips.cpu_type.isa_level == 32);  
361          byte_order_cached_bigendian = (cpu->byte_order == EMUL_BIG_ENDIAN);          byte_order_cached_bigendian = (cpu->byte_order == EMUL_BIG_ENDIAN);
362    
363          /*  Is this a part of something that is already translated?  */          /*  Is this a part of something that is already translated?  */
364          paddr_page = paddr & ~0xfff;          paddr_page = paddr & ~0xfff;
365          offset_within_page = (paddr & 0xfff) / 4;          offset_within_page = (paddr & 0xfff) >> 2;
366          entry_index = PADDR_TO_INDEX(paddr);          entry_index = PADDR_TO_INDEX(paddr);
367          tep = cpu->mem->translation_page_entry_array[entry_index];          tep = cpu->mem->translation_page_entry_array[entry_index];
368          while (tep != NULL) {          while (tep != NULL) {
369                  if (tep->paddr == paddr_page) {                  if (tep->paddr == paddr_page) {
370                          int mask = 1 << (offset_within_page & 7);                          int mask;
371    
372                          if (tep->chunk[offset_within_page] != 0) {                          if (tep->chunk[offset_within_page] != 0) {
373                                  f = (size_t)tep->chunk[offset_within_page] +                                  f = (size_t)tep->chunk[offset_within_page] +
374                                      cpu->mem->translation_code_chunk_space;                                      cpu->mem->translation_code_chunk_space;
375                                  goto run_it;    /*  see further down  */                                  goto run_it;    /*  see further down  */
376                          }                          }
377    
378                            mask = 1 << (offset_within_page & 7);
379                          if (tep->flags[offset_within_page >> 3] & mask)                          if (tep->flags[offset_within_page >> 3] & mask)
380                                  return cpu->cd.mips.                                  return cpu->cd.mips.
381                                      bintrans_instructions_executed;                                      bintrans_instructions_executed;
# Line 380  cpu->cd.mips.pc_last_host_4k_page,(long Line 401  cpu->cd.mips.pc_last_host_4k_page,(long
401           */           */
402          if (cpu->mem->translation_code_chunk_space_head >=          if (cpu->mem->translation_code_chunk_space_head >=
403              cpu->machine->bintrans_size) {              cpu->machine->bintrans_size) {
404                  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;  
405                  tep = NULL;                  tep = NULL;
                 debug("bintrans: Starting over!\n");  
                 clear_all_chunks_from_all_tables(cpu);  
406          }          }
407    
408    
# Line 434  cpu->cd.mips.pc_last_host_4k_page,(long Line 449  cpu->cd.mips.pc_last_host_4k_page,(long
449           *  Try to translate a chunk of code:           *  Try to translate a chunk of code:
450           */           */
451          p = paddr & 0xfff;          p = paddr & 0xfff;
452            prev_p = p >> 2;
453          try_to_translate = 1;          try_to_translate = 1;
454          n_translated = 0;          n_translated = 0;
455          res = 0;          res = 0;
# Line 445  cpu->cd.mips.pc_last_host_4k_page,(long Line 461  cpu->cd.mips.pc_last_host_4k_page,(long
461    
462          while (try_to_translate) {          while (try_to_translate) {
463                  ca_justdid = ca;                  ca_justdid = ca;
                 prev_p = p/4;  
464                  translated = 0;                  translated = 0;
465    
466                  /*  Read an instruction word from host memory:  */                  /*  Read an instruction word from host memory:  */
# Line 621  cpu->cd.mips.pc_last_host_4k_page,(long Line 636  cpu->cd.mips.pc_last_host_4k_page,(long
636                  case HI6_XORI:                  case HI6_XORI:
637                  case HI6_DADDI:                  case HI6_DADDI:
638                  case HI6_DADDIU:                  case HI6_DADDIU:
639                          rs = ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7);                          translated = try_to_translate =
640                          rt = instr[2] & 31;                              bintrans_write_instruction__addiu_etc(&ca,
641                          imm = (instr[1] << 8) + instr[0];                              instr[2] & 31,
642                          translated = try_to_translate = bintrans_write_instruction__addiu_etc(&ca, rt, rs, imm, hi6);                              ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7),
643                                (instr[1] << 8) + instr[0], hi6);
644                          n_translated += translated;                          n_translated += translated;
645                          break;                          break;
646    
647                  case HI6_LUI:                  case HI6_LUI:
648                          rt = instr[2] & 31;                          translated = try_to_translate =
649                          imm = (instr[1] << 8) + instr[0];                              bintrans_write_instruction__lui(&ca,
650                          translated = try_to_translate = bintrans_write_instruction__lui(&ca, rt, imm);                              instr[2] & 31, (instr[1] << 8) + instr[0]);
651                          n_translated += translated;                          n_translated += translated;
652                          break;                          break;
653    
# Line 664  cpu->cd.mips.pc_last_host_4k_page,(long Line 680  cpu->cd.mips.pc_last_host_4k_page,(long
680                                                  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);
681                                                  n_translated += translated;                                                  n_translated += translated;
682                                          }                                          }
683                                  }                                  } else
684                                            try_to_translate = 0;
685                                  break;                                  break;
686                          case 0x42:                          case 0x42:
687                                  if (instr[2] == 0x00 && instr[1] == 0x00 && instr[0] == 0x10) {                                  if (instr[2] == 0x00 && instr[1] == 0x00 && instr[0] == 0x10) {
# Line 697  cpu->cd.mips.pc_last_host_4k_page,(long Line 714  cpu->cd.mips.pc_last_host_4k_page,(long
714                                          /*  standby and suspend on VR41xx etc ==> NOP  */                                          /*  standby and suspend on VR41xx etc ==> NOP  */
715                                          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(&ca, 0, 0, 0, 0, SPECIAL_SLL);
716                                          n_translated += translated;                                          n_translated += translated;
717                                  }                                  } else
718                                            try_to_translate = 0;
719                                  break;                                  break;
720                          default:                          default:
721                                  try_to_translate = 0;                                  try_to_translate = 0;
# Line 773  cpu->cd.mips.pc_last_host_4k_page,(long Line 791  cpu->cd.mips.pc_last_host_4k_page,(long
791                                      cpu->mem, &ca,                                      cpu->mem, &ca,
792                                      potential_chunk_p, &tep->chunk[0], 0,                                      potential_chunk_p, &tep->chunk[0], 0,
793                                      delayed_branch_new_p & 0xfff, forward);                                      delayed_branch_new_p & 0xfff, forward);
794    #if 0
795                                  if (stop_after_delayed_branch)                                  if (stop_after_delayed_branch)
796                                          try_to_translate = 0;                                          try_to_translate = 0;
797    #endif
798                          }                          }
799                  }                  }
800    
# Line 796  cpu->cd.mips.pc_last_host_4k_page,(long Line 815  cpu->cd.mips.pc_last_host_4k_page,(long
815                                              tep->chunk[prev_p]);                                              tep->chunk[prev_p]);
816                  }                  }
817    
818                  /*  Glue together with previously translated code, if any:  */                  if (translated && try_to_translate && prev_p < 1023) {
819                  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;  
                 }  
820    
821                  if (translated && try_to_translate && n_translated > 80                          if (tep->flags[(prev_p+1) >> 3] & mask
822                      && prev_p < 1023 && !delayed_branch) {                              && !delayed_branch) {
823                          bintrans_write_instruction__delayedbranch(cpu->mem,                                  bintrans_write_chunkreturn_fail(&ca);
824                              &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);                                  /*  try_to_translate = 0;  */
825                          try_to_translate = 0;                                  break;
826                  }                          }
827    
828  {                          /*  Glue together with previously translated code,
829          int mask = 1 << ((prev_p+1) & 7);                              if any:  */
830                            if (tep->chunk[prev_p+1] != 0 && !delayed_branch) {
831                                    bintrans_write_instruction__delayedbranch(cpu->mem,
832                                        &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);
833                                    /*  try_to_translate = 0;  */
834                                    break;
835                            }
836    
837                  if (translated && try_to_translate &&                          if (n_translated > 80 && !delayed_branch) {
838                      tep->flags[(prev_p+1) >> 3] & mask                                  bintrans_write_instruction__delayedbranch(cpu->mem,
839                      && prev_p < 1023 && !delayed_branch) {                                      &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);
840                          bintrans_write_chunkreturn_fail(&ca);                                  /*  try_to_translate = 0;  */
841                                    break;
842                            }
843                  }                  }
 }  
844    
845                  p += sizeof(instr);                  p += sizeof(instr);
846                    prev_p ++;
847    
848                  /*  If we have reached a different (MIPS) page, then stop translating.  */                  /*  If we have reached a different (MIPS) page, then stop translating.  */
849                  if (p == 0x1000)                  if (p == 0x1000)
# Line 921  run_it: Line 942  run_it:
942    
943                  if (ok) {                  if (ok) {
944                          paddr_page = paddr & ~0xfff;                          paddr_page = paddr & ~0xfff;
945                          offset_within_page = (paddr & 0xfff) / 4;                          offset_within_page = (paddr & 0xfff) >> 2;
946                          entry_index = PADDR_TO_INDEX(paddr);                          entry_index = PADDR_TO_INDEX(paddr);
947                          tep = cpu->mem->translation_page_entry_array[entry_index];                          tep = cpu->mem->translation_page_entry_array[entry_index];
948                          while (tep != NULL) {                          while (tep != NULL) {
949                                  if (tep->paddr == paddr_page) {                                  if (tep->paddr == paddr_page) {
950                                          int mask = 1 << (offset_within_page & 7);                                          int mask;
951                                          if (tep->chunk[offset_within_page] != 0) {                                          if (tep->chunk[offset_within_page] != 0) {
952                                                  f = (size_t)tep->chunk[offset_within_page] +                                                  f = (size_t)tep->chunk[offset_within_page] +
953                                                      cpu->mem->translation_code_chunk_space;                                                      cpu->mem->translation_code_chunk_space;
954                                                  goto run_it;                                                  goto run_it;
955                                          }                                          }
956                                            mask = 1 << (offset_within_page & 7);
957                                          if (tep->flags[offset_within_page >> 3] & mask)                                          if (tep->flags[offset_within_page >> 3] & mask)
958                                                  return cpu->cd.mips.bintrans_instructions_executed;                                                  return cpu->cd.mips.bintrans_instructions_executed;
959                                          break;                                          break;
# Line 1071  void old_bintrans_init_cpu(struct cpu *c Line 1093  void old_bintrans_init_cpu(struct cpu *c
1093          }          }
1094    
1095          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;
1096    
1097            cpu->mem->bintrans_32bit_only = (cpu->cd.mips.cpu_type.isa_level <= 2
1098                || cpu->cd.mips.cpu_type.isa_level == 32);
1099  }  }
1100    
1101    

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

  ViewVC Help
Powered by ViewVC 1.1.26