/[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 11 by dpavlin, Mon Oct 8 16:18:27 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.169 2005/06/22 10:12:25 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 142  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 157  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 202  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 287  void bintrans_restart(struct cpu *cpu) Line 276  void bintrans_restart(struct cpu *cpu)
276  {  {
277          int i, n = 1 << BINTRANS_CACHE_N_INDEX_BITS;          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++)          for (i=0; i<n; i++)
283                  cpu->mem->translation_page_entry_array[i] = NULL;                  cpu->mem->translation_page_entry_array[i] = NULL;
284    
285          cpu->mem->translation_code_chunk_space_head = 0;          cpu->mem->translation_code_chunk_space_head = 0;
286          cpu->mem->n_quick_jumps = 0;          cpu->mem->n_quick_jumps = 0;
287    
288          /*  debug("bintrans: Starting over!\n");  */          debug("[ bintrans: Starting over! ]\n");
289          clear_all_chunks_from_all_tables(cpu);          clear_all_chunks_from_all_tables(cpu);
290  }  }
291    
# Line 348  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 420  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 453  cpu->cd.mips.pc_last_host_4k_page,(long Line 444  cpu->cd.mips.pc_last_host_4k_page,(long
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 503  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 544  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 566  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 584  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 593  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 637  cpu->cd.mips.pc_last_host_4k_page,(long Line 631  cpu->cd.mips.pc_last_host_4k_page,(long
631                  case HI6_DADDI:                  case HI6_DADDI:
632                  case HI6_DADDIU:                  case HI6_DADDIU:
633                          translated = try_to_translate =                          translated = try_to_translate =
634                              bintrans_write_instruction__addiu_etc(&ca,                              bintrans_write_instruction__addiu_etc(cpu->mem,
635                              instr[2] & 31,                              &ca, instr[2] & 31,
636                              ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7),                              ((instr[3] & 3) << 3) + ((instr[2] >> 5) & 7),
637                              (instr[1] << 8) + instr[0], hi6);                              (instr[1] << 8) + instr[0], hi6);
638                          n_translated += translated;                          n_translated += translated;
# Line 680  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                                  } 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;                                          try_to_translate = 0;
686                                            return_code_written = 1;
687                                    }
688                                  break;                                  break;
689                          case 0x42:                          case 0x42:
690                                  if (instr[2] == 0x00 && instr[1] == 0x00 && instr[0] == 0x10) {                                  if (instr[2] == 0x00 && instr[1] == 0x00 && instr[0] == 0x10) {
# Line 712  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                                  } 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;                                          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 748  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 766  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 791  cpu->cd.mips.pc_last_host_4k_page,(long Line 813  cpu->cd.mips.pc_last_host_4k_page,(long
813                                      cpu->mem, &ca,                                      cpu->mem, &ca,
814                                      potential_chunk_p, &tep->chunk[0], 0,                                      potential_chunk_p, &tep->chunk[0], 0,
815                                      delayed_branch_new_p & 0xfff, forward);                                      delayed_branch_new_p & 0xfff, forward);
816  #if 0  
817                                  if (stop_after_delayed_branch)                                  if (stop_after_delayed_branch)
818                                          try_to_translate = 0;                                          try_to_translate = 0;
 #endif  
819                          }                          }
820                  }                  }
821    
# Line 821  cpu->cd.mips.pc_last_host_4k_page,(long Line 842  cpu->cd.mips.pc_last_host_4k_page,(long
842                          if (tep->flags[(prev_p+1) >> 3] & mask                          if (tep->flags[(prev_p+1) >> 3] & mask
843                              && !delayed_branch) {                              && !delayed_branch) {
844                                  bintrans_write_chunkreturn_fail(&ca);                                  bintrans_write_chunkreturn_fail(&ca);
845                                  /*  try_to_translate = 0;  */                                  try_to_translate = 0;
846                                    return_code_written = 1;
847                                  break;                                  break;
848                          }                          }
849    
# Line 830  cpu->cd.mips.pc_last_host_4k_page,(long Line 852  cpu->cd.mips.pc_last_host_4k_page,(long
852                          if (tep->chunk[prev_p+1] != 0 && !delayed_branch) {                          if (tep->chunk[prev_p+1] != 0 && !delayed_branch) {
853                                  bintrans_write_instruction__delayedbranch(cpu->mem,                                  bintrans_write_instruction__delayedbranch(cpu->mem,
854                                      &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);                                      &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;  */                                  /*  try_to_translate = 0;  */
858                                  break;                                  break;
859                          }                          }
860    
861                          if (n_translated > 80 && !delayed_branch) {                          if (n_translated > 120 && !delayed_branch) {
862                                  bintrans_write_instruction__delayedbranch(cpu->mem,                                  bintrans_write_instruction__delayedbranch(cpu->mem,
863                                      &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);                                      &ca, &tep->chunk[prev_p+1], NULL, 1, p+4, 1);
864                                  /*  try_to_translate = 0;  */                                  try_to_translate = 0;
865                                    return_code_written = 1;
866                                  break;                                  break;
867                          }                          }
868                  }                  }
# Line 864  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 876  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 1067  void old_bintrans_init_cpu(struct cpu *c Line 1093  void old_bintrans_init_cpu(struct cpu *c
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 =

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

  ViewVC Help
Powered by ViewVC 1.1.26