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

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

revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_arm_instr.c,v 1.60 2006/02/09 22:40:27 debug Exp $   *  $Id: cpu_arm_instr.c,v 1.68 2006/08/11 17:43:30 debug Exp $
29   *   *
30   *  ARM instructions.   *  ARM instructions.
31   *   *
# Line 201  uint8_t condition_gt[16] = { 1,0,1,0, 0, Line 201  uint8_t condition_gt[16] = { 1,0,1,0, 0,
201    
202    
203  /*  /*
  *  nop:  Do nothing.  
204   *  invalid:  Invalid instructions end up here.   *  invalid:  Invalid instructions end up here.
205   */   */
 X(nop) { }  
206  X(invalid) {  X(invalid) {
207          uint32_t low_pc;          uint32_t low_pc;
208          low_pc = ((size_t)ic - (size_t)          low_pc = ((size_t)ic - (size_t)
# Line 213  X(invalid) { Line 211  X(invalid) {
211              << ARM_INSTR_ALIGNMENT_SHIFT);              << ARM_INSTR_ALIGNMENT_SHIFT);
212          cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);          cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
213    
214          fatal("Invalid ARM instruction: pc=0x%08x\n", (int)cpu->pc);          fatal("FATAL ERROR: An internal error occured in the ARM"
215                " dyntrans code. Please contact the author with detailed"
216                " repro steps on how to trigger this bug. pc = 0x%08"PRIx32"\n",
217                (uint32_t)cpu->pc);
218    
         cpu->running = 0;  
         cpu->running_translated = 0;  
         cpu->n_translated_instrs --;  
219          cpu->cd.arm.next_ic = &nothing_call;          cpu->cd.arm.next_ic = &nothing_call;
220  }  }
221    
222    
223  /*  /*
224     *  nop:  Do nothing.
225     */
226    X(nop)
227    {
228    }
229    
230    
231    /*
232   *  b:  Branch (to a different translated page)   *  b:  Branch (to a different translated page)
233   *   *
234   *  arg[0] = relative offset   *  arg[0] = relative offset
# Line 756  X(msr_imm_spsr) Line 762  X(msr_imm_spsr)
762          cpu->pc &= ~((ARM_IC_ENTRIES_PER_PAGE-1) << ARM_INSTR_ALIGNMENT_SHIFT);          cpu->pc &= ~((ARM_IC_ENTRIES_PER_PAGE-1) << ARM_INSTR_ALIGNMENT_SHIFT);
763          cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);          cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
764          old_pc = cpu->pc;          old_pc = cpu->pc;
765          printf("msr_spsr: old pc = 0x%08x\n", old_pc);          printf("msr_spsr: old pc = 0x%08"PRIx32"\n", old_pc);
766  }  }
767                  exit(1);                  exit(1);
768          }          }
# Line 851  X(openfirmware) Line 857  X(openfirmware)
857  X(reboot)  X(reboot)
858  {  {
859          cpu->running = 0;          cpu->running = 0;
         cpu->running_translated = 0;  
860          cpu->n_translated_instrs --;          cpu->n_translated_instrs --;
861          cpu->cd.arm.next_ic = &nothing_call;          cpu->cd.arm.next_ic = &nothing_call;
862  }  }
# Line 875  X(swi_useremul) Line 880  X(swi_useremul)
880          useremul_syscall(cpu, ic->arg[0]);          useremul_syscall(cpu, ic->arg[0]);
881    
882          if (!cpu->running) {          if (!cpu->running) {
                 cpu->running_translated = 0;  
883                  cpu->n_translated_instrs --;                  cpu->n_translated_instrs --;
884                  cpu->cd.arm.next_ic = &nothing_call;                  cpu->cd.arm.next_ic = &nothing_call;
885          } else if (cpu->pc != old_pc) {          } else if (cpu->pc != old_pc) {
# Line 1320  Y(bdt_store) Line 1324  Y(bdt_store)
1324    
1325    
1326  /*  Various load/store multiple instructions:  */  /*  Various load/store multiple instructions:  */
1327  uint32_t *multi_opcode[256];  extern uint32_t *multi_opcode[256];
1328  void (**multi_opcode_f[256])(struct cpu *, struct arm_instr_call *);  extern void (**multi_opcode_f[256])(struct cpu *, struct arm_instr_call *);
1329  X(multi_0x08b15018);  X(multi_0x08b15018);
1330  X(multi_0x08ac000c__ge);  X(multi_0x08ac000c__ge);
1331  X(multi_0x08a05018);  X(multi_0x08a05018);
# Line 2044  void COMBINE(netbsd_memset)(struct cpu * Line 2048  void COMBINE(netbsd_memset)(struct cpu *
2048                      ic[ 0].f == instr(b_samepage__gt) &&                      ic[ 0].f == instr(b_samepage__gt) &&
2049                      ic[ 0].arg[0] == (size_t)&ic[-17]) {                      ic[ 0].arg[0] == (size_t)&ic[-17]) {
2050                          ic[-17].f = instr(netbsd_memset);                          ic[-17].f = instr(netbsd_memset);
                         combined;  
2051                  }                  }
2052          }          }
2053  #endif  #endif
# Line 2074  void COMBINE(netbsd_memcpy)(struct cpu * Line 2077  void COMBINE(netbsd_memcpy)(struct cpu *
2077                      ic[ 0].f == instr(b_samepage__ge) &&                      ic[ 0].f == instr(b_samepage__ge) &&
2078                      ic[ 0].arg[0] == (size_t)&ic[-5]) {                      ic[ 0].arg[0] == (size_t)&ic[-5]) {
2079                          ic[-5].f = instr(netbsd_memcpy);                          ic[-5].f = instr(netbsd_memcpy);
                         combined;  
2080                  }                  }
2081          }          }
2082  #endif  #endif
# Line 2099  void COMBINE(netbsd_cacheclean)(struct c Line 2101  void COMBINE(netbsd_cacheclean)(struct c
2101                      ic[-1].f == instr(b_samepage__ne) &&                      ic[-1].f == instr(b_samepage__ne) &&
2102                      ic[-1].arg[0] == (size_t)&ic[-3]) {                      ic[-1].arg[0] == (size_t)&ic[-3]) {
2103                          ic[-3].f = instr(netbsd_cacheclean);                          ic[-3].f = instr(netbsd_cacheclean);
                         combined;  
2104                  }                  }
2105          }          }
2106  }  }
# Line 2124  void COMBINE(netbsd_cacheclean2)(struct Line 2125  void COMBINE(netbsd_cacheclean2)(struct
2125                      ic[-1].f == instr(subs) &&                      ic[-1].f == instr(subs) &&
2126                      ic[-1].arg[0]==ic[-1].arg[2] && ic[-1].arg[1] == 0x20) {                      ic[-1].arg[0]==ic[-1].arg[2] && ic[-1].arg[1] == 0x20) {
2127                          ic[-4].f = instr(netbsd_cacheclean2);                          ic[-4].f = instr(netbsd_cacheclean2);
                         combined;  
2128                  }                  }
2129          }          }
2130  }  }
# Line 2151  void COMBINE(netbsd_scanc)(struct cpu *c Line 2151  void COMBINE(netbsd_scanc)(struct cpu *c
2151              ic[-1].arg[1] == (size_t)arm_r_r3_t0_c0 &&              ic[-1].arg[1] == (size_t)arm_r_r3_t0_c0 &&
2152              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[3])) {              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[3])) {
2153                  ic[-2].f = instr(netbsd_scanc);                  ic[-2].f = instr(netbsd_scanc);
                 combined;  
2154          }          }
2155  }  }
2156    
# Line 2175  void COMBINE(strlen)(struct cpu *cpu, Line 2174  void COMBINE(strlen)(struct cpu *cpu,
2174              ic[-1].arg[0] == (size_t)(&cpu->cd.arm.r[3]) &&              ic[-1].arg[0] == (size_t)(&cpu->cd.arm.r[3]) &&
2175              ic[-1].arg[1] == 0) {              ic[-1].arg[1] == 0) {
2176                  ic[-2].f = instr(strlen);                  ic[-2].f = instr(strlen);
                 combined;  
2177          }          }
2178  }  }
2179    
# Line 2201  void COMBINE(xchg)(struct cpu *cpu, Line 2199  void COMBINE(xchg)(struct cpu *cpu,
2199              ic[-1].arg[0] == b && ic[-1].arg[1] == a && ic[-1].arg[2] == a &&              ic[-1].arg[0] == b && ic[-1].arg[1] == a && ic[-1].arg[2] == a &&
2200              ic[ 0].arg[0] == a && ic[ 0].arg[1] == b && ic[ 0].arg[2] == b) {              ic[ 0].arg[0] == a && ic[ 0].arg[1] == b && ic[ 0].arg[2] == b) {
2201                  ic[-2].f = instr(xchg);                  ic[-2].f = instr(xchg);
                 combined;  
2202          }          }
2203  }  }
2204    
# Line 2232  void COMBINE(netbsd_copyin)(struct cpu * Line 2229  void COMBINE(netbsd_copyin)(struct cpu *
2229              ic[-2].arg[2] == (size_t)(&cpu->cd.arm.r[7]) &&              ic[-2].arg[2] == (size_t)(&cpu->cd.arm.r[7]) &&
2230              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[8])) {              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[8])) {
2231                  ic[-5].f = instr(netbsd_copyin);                  ic[-5].f = instr(netbsd_copyin);
                 combined;  
2232          }          }
2233  #endif  #endif
2234  }  }
# Line 2264  void COMBINE(netbsd_copyout)(struct cpu Line 2260  void COMBINE(netbsd_copyout)(struct cpu
2260              ic[-2].arg[2] == (size_t)(&cpu->cd.arm.r[11]) &&              ic[-2].arg[2] == (size_t)(&cpu->cd.arm.r[11]) &&
2261              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[6])) {              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[6])) {
2262                  ic[-5].f = instr(netbsd_copyout);                  ic[-5].f = instr(netbsd_copyout);
                 combined;  
2263          }          }
2264  #endif  #endif
2265  }  }
# Line 2288  void COMBINE(cmps_b)(struct cpu *cpu, Line 2283  void COMBINE(cmps_b)(struct cpu *cpu,
2283                                  ic[-1].f = instr(cmps_neg_beq);                                  ic[-1].f = instr(cmps_neg_beq);
2284                          else                          else
2285                                  ic[-1].f = instr(cmps_pos_beq);                                  ic[-1].f = instr(cmps_pos_beq);
                         combined;  
2286                  }                  }
2287                  return;                  return;
2288          }          }
# Line 2298  void COMBINE(cmps_b)(struct cpu *cpu, Line 2292  void COMBINE(cmps_b)(struct cpu *cpu,
2292                                  ic[-1].f = instr(cmps0_beq_samepage);                                  ic[-1].f = instr(cmps0_beq_samepage);
2293                          else                          else
2294                                  ic[-1].f = instr(cmps_beq_samepage);                                  ic[-1].f = instr(cmps_beq_samepage);
                         combined;  
2295                  }                  }
2296                  if (ic[-1].f == instr(tsts) &&                  if (ic[-1].f == instr(tsts) &&
2297                      !(ic[-1].arg[1] & 0x80000000)) {                      !(ic[-1].arg[1] & 0x80000000)) {
2298                          ic[-1].f = instr(tsts_lo_beq_samepage);                          ic[-1].f = instr(tsts_lo_beq_samepage);
                         combined;  
2299                  }                  }
2300                  if (ic[-1].f == instr(teqs)) {                  if (ic[-1].f == instr(teqs)) {
2301                          ic[-1].f = instr(teqs_beq_samepage);                          ic[-1].f = instr(teqs_beq_samepage);
                         combined;  
2302                  }                  }
2303                  return;                  return;
2304          }          }
# Line 2317  void COMBINE(cmps_b)(struct cpu *cpu, Line 2308  void COMBINE(cmps_b)(struct cpu *cpu,
2308                                  ic[-1].f = instr(cmps0_bne_samepage);                                  ic[-1].f = instr(cmps0_bne_samepage);
2309                          else                          else
2310                                  ic[-1].f = instr(cmps_bne_samepage);                                  ic[-1].f = instr(cmps_bne_samepage);
                         combined;  
2311                  }                  }
2312                  if (ic[-1].f == instr(tsts) &&                  if (ic[-1].f == instr(tsts) &&
2313                      !(ic[-1].arg[1] & 0x80000000)) {                      !(ic[-1].arg[1] & 0x80000000)) {
2314                          ic[-1].f = instr(tsts_lo_bne_samepage);                          ic[-1].f = instr(tsts_lo_bne_samepage);
                         combined;  
2315                  }                  }
2316                  if (ic[-1].f == instr(teqs)) {                  if (ic[-1].f == instr(teqs)) {
2317                          ic[-1].f = instr(teqs_bne_samepage);                          ic[-1].f = instr(teqs_bne_samepage);
                         combined;  
2318                  }                  }
2319                  return;                  return;
2320          }          }
2321          if (ic[0].f == instr(b_samepage__cc)) {          if (ic[0].f == instr(b_samepage__cc)) {
2322                  if (ic[-1].f == instr(cmps)) {                  if (ic[-1].f == instr(cmps)) {
2323                          ic[-1].f = instr(cmps_bcc_samepage);                          ic[-1].f = instr(cmps_bcc_samepage);
                         combined;  
2324                  }                  }
2325                  if (ic[-1].f == instr(cmps_regshort)) {                  if (ic[-1].f == instr(cmps_regshort)) {
2326                          ic[-1].f = instr(cmps_reg_bcc_samepage);                          ic[-1].f = instr(cmps_reg_bcc_samepage);
                         combined;  
2327                  }                  }
2328                  return;                  return;
2329          }          }
2330          if (ic[0].f == instr(b_samepage__hi)) {          if (ic[0].f == instr(b_samepage__hi)) {
2331                  if (ic[-1].f == instr(cmps)) {                  if (ic[-1].f == instr(cmps)) {
2332                          ic[-1].f = instr(cmps_bhi_samepage);                          ic[-1].f = instr(cmps_bhi_samepage);
                         combined;  
2333                  }                  }
2334                  if (ic[-1].f == instr(cmps_regshort)) {                  if (ic[-1].f == instr(cmps_regshort)) {
2335                          ic[-1].f = instr(cmps_reg_bhi_samepage);                          ic[-1].f = instr(cmps_reg_bhi_samepage);
                         combined;  
2336                  }                  }
2337                  return;                  return;
2338          }          }
2339          if (ic[0].f == instr(b_samepage__gt)) {          if (ic[0].f == instr(b_samepage__gt)) {
2340                  if (ic[-1].f == instr(cmps)) {                  if (ic[-1].f == instr(cmps)) {
2341                          ic[-1].f = instr(cmps_bgt_samepage);                          ic[-1].f = instr(cmps_bgt_samepage);
                         combined;  
2342                  }                  }
2343                  return;                  return;
2344          }          }
2345          if (ic[0].f == instr(b_samepage__le)) {          if (ic[0].f == instr(b_samepage__le)) {
2346                  if (ic[-1].f == instr(cmps)) {                  if (ic[-1].f == instr(cmps)) {
2347                          ic[-1].f = instr(cmps_ble_samepage);                          ic[-1].f = instr(cmps_ble_samepage);
                         combined;  
2348                  }                  }
2349                  return;                  return;
2350          }          }
# Line 2455  static void arm_switch_add1(struct arm_i Line 2437  static void arm_switch_add1(struct arm_i
2437  X(to_be_translated)  X(to_be_translated)
2438  {  {
2439          uint32_t addr, low_pc, iword, imm = 0;          uint32_t addr, low_pc, iword, imm = 0;
 #ifdef DYNTRANS_BACKEND  
         int simple = 0;  
 #endif  
2440          unsigned char *page;          unsigned char *page;
2441          unsigned char ib[4];          unsigned char ib[4];
2442          int condition_code, main_opcode, secondary_opcode, s_bit, rn, rd, r8;          int condition_code, main_opcode, secondary_opcode, s_bit, rn, rd, r8;
# Line 2638  X(to_be_translated) Line 2617  X(to_be_translated)
2617                      (iword & 0x0fb0f000) == 0x0320f000) {                      (iword & 0x0fb0f000) == 0x0320f000) {
2618                          /*  msr: move to [S|C]PSR from a register or                          /*  msr: move to [S|C]PSR from a register or
2619                              immediate value  */                              immediate value  */
                         if (rm == ARM_PC) {  
                                 fatal("msr PC?\n");  
                                 goto bad;  
                         }  
2620                          if (iword & 0x02000000) {                          if (iword & 0x02000000) {
2621                                  if (iword & 0x00400000)                                  if (iword & 0x00400000)
2622                                          ic->f = cond_instr(msr_imm_spsr);                                          ic->f = cond_instr(msr_imm_spsr);
2623                                  else                                  else
2624                                          ic->f = cond_instr(msr_imm);                                          ic->f = cond_instr(msr_imm);
2625                          } else {                          } else {
2626                                    if (rm == ARM_PC) {
2627                                            fatal("msr PC?\n");
2628                                            goto bad;
2629                                    }
2630                                  if (iword & 0x00400000)                                  if (iword & 0x00400000)
2631                                          ic->f = cond_instr(msr_spsr);                                          ic->f = cond_instr(msr_spsr);
2632                                  else                                  else
# Line 2745  X(to_be_translated) Line 2724  X(to_be_translated)
2724                  /*  "mov reg,#0":  */                  /*  "mov reg,#0":  */
2725                  if ((iword & 0x0fff0fff) == 0x03a00000 && rd != ARM_PC) {                  if ((iword & 0x0fff0fff) == 0x03a00000 && rd != ARM_PC) {
2726                          arm_switch_clear(ic, rd, condition_code);                          arm_switch_clear(ic, rd, condition_code);
 #ifdef DYNTRANS_BACKEND  
 simple = 1;  
 #endif  
2727                          break;                          break;
2728                  }                  }
2729    
2730                  /*  "mov reg,#1":  */                  /*  "mov reg,#1":  */
2731                  if ((iword & 0x0fff0fff) == 0x03a00001 && rd != ARM_PC) {                  if ((iword & 0x0fff0fff) == 0x03a00001 && rd != ARM_PC) {
2732                          arm_switch_mov1(ic, rd, condition_code);                          arm_switch_mov1(ic, rd, condition_code);
 #ifdef DYNTRANS_BACKEND  
 simple = 1;  
 #endif  
2733                          break;                          break;
2734                  }                  }
2735    
# Line 2764  simple = 1; Line 2737  simple = 1;
2737                  if ((iword & 0x0ff00fff) == 0x02800001 && rd != ARM_PC                  if ((iword & 0x0ff00fff) == 0x02800001 && rd != ARM_PC
2738                      && rn == rd) {                      && rn == rd) {
2739                          arm_switch_add1(ic, rd, condition_code);                          arm_switch_add1(ic, rd, condition_code);
 #ifdef DYNTRANS_BACKEND  
 simple = 1;  
 #endif  
2740                          break;                          break;
2741                  }                  }
2742    

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

  ViewVC Help
Powered by ViewVC 1.1.26