/[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 32 by dpavlin, Mon Oct 8 16:20:58 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.69 2006/09/09 09:04:32 debug Exp $
29   *   *
30   *  ARM instructions.   *  ARM instructions.
31   *   *
# Line 33  Line 33 
33   *  (If no instruction was executed, then it should be decreased. If, say, 4   *  (If no instruction was executed, then it should be decreased. If, say, 4
34   *  instructions were combined into one function and executed, then it should   *  instructions were combined into one function and executed, then it should
35   *  be increased by 3.)   *  be increased by 3.)
36     *
37     *  Note: cpu->pc is prefered over r[ARM_PC]. r[ARM_PC] is only used in a
38     *        few places, and should always be kept in synch with the real
39     *        program counter.
40   */   */
41    
42    
# Line 201  uint8_t condition_gt[16] = { 1,0,1,0, 0, Line 205  uint8_t condition_gt[16] = { 1,0,1,0, 0,
205    
206    
207  /*  /*
  *  nop:  Do nothing.  
208   *  invalid:  Invalid instructions end up here.   *  invalid:  Invalid instructions end up here.
209   */   */
 X(nop) { }  
210  X(invalid) {  X(invalid) {
211          uint32_t low_pc;          uint32_t low_pc;
212          low_pc = ((size_t)ic - (size_t)          low_pc = ((size_t)ic - (size_t)
# Line 213  X(invalid) { Line 215  X(invalid) {
215              << ARM_INSTR_ALIGNMENT_SHIFT);              << ARM_INSTR_ALIGNMENT_SHIFT);
216          cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);          cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
217    
218          fatal("Invalid ARM instruction: pc=0x%08x\n", (int)cpu->pc);          fatal("FATAL ERROR: An internal error occured in the ARM"
219                " dyntrans code. Please contact the author with detailed"
220                " repro steps on how to trigger this bug. pc = 0x%08"PRIx32"\n",
221                (uint32_t)cpu->pc);
222    
         cpu->running = 0;  
         cpu->running_translated = 0;  
         cpu->n_translated_instrs --;  
223          cpu->cd.arm.next_ic = &nothing_call;          cpu->cd.arm.next_ic = &nothing_call;
224  }  }
225    
226    
227  /*  /*
228     *  nop:  Do nothing.
229     */
230    X(nop)
231    {
232    }
233    
234    
235    /*
236   *  b:  Branch (to a different translated page)   *  b:  Branch (to a different translated page)
237   *   *
238   *  arg[0] = relative offset   *  arg[0] = relative offset
# Line 756  X(msr_imm_spsr) Line 766  X(msr_imm_spsr)
766          cpu->pc &= ~((ARM_IC_ENTRIES_PER_PAGE-1) << ARM_INSTR_ALIGNMENT_SHIFT);          cpu->pc &= ~((ARM_IC_ENTRIES_PER_PAGE-1) << ARM_INSTR_ALIGNMENT_SHIFT);
767          cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);          cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
768          old_pc = cpu->pc;          old_pc = cpu->pc;
769          printf("msr_spsr: old pc = 0x%08x\n", old_pc);          printf("msr_spsr: old pc = 0x%08"PRIx32"\n", old_pc);
770  }  }
771                  exit(1);                  exit(1);
772          }          }
# Line 851  X(openfirmware) Line 861  X(openfirmware)
861  X(reboot)  X(reboot)
862  {  {
863          cpu->running = 0;          cpu->running = 0;
         cpu->running_translated = 0;  
864          cpu->n_translated_instrs --;          cpu->n_translated_instrs --;
865          cpu->cd.arm.next_ic = &nothing_call;          cpu->cd.arm.next_ic = &nothing_call;
866  }  }
# Line 875  X(swi_useremul) Line 884  X(swi_useremul)
884          useremul_syscall(cpu, ic->arg[0]);          useremul_syscall(cpu, ic->arg[0]);
885    
886          if (!cpu->running) {          if (!cpu->running) {
                 cpu->running_translated = 0;  
887                  cpu->n_translated_instrs --;                  cpu->n_translated_instrs --;
888                  cpu->cd.arm.next_ic = &nothing_call;                  cpu->cd.arm.next_ic = &nothing_call;
889          } else if (cpu->pc != old_pc) {          } else if (cpu->pc != old_pc) {
# Line 1320  Y(bdt_store) Line 1328  Y(bdt_store)
1328    
1329    
1330  /*  Various load/store multiple instructions:  */  /*  Various load/store multiple instructions:  */
1331  uint32_t *multi_opcode[256];  extern uint32_t *multi_opcode[256];
1332  void (**multi_opcode_f[256])(struct cpu *, struct arm_instr_call *);  extern void (**multi_opcode_f[256])(struct cpu *, struct arm_instr_call *);
1333  X(multi_0x08b15018);  X(multi_0x08b15018);
1334  X(multi_0x08ac000c__ge);  X(multi_0x08ac000c__ge);
1335  X(multi_0x08a05018);  X(multi_0x08a05018);
# Line 2044  void COMBINE(netbsd_memset)(struct cpu * Line 2052  void COMBINE(netbsd_memset)(struct cpu *
2052                      ic[ 0].f == instr(b_samepage__gt) &&                      ic[ 0].f == instr(b_samepage__gt) &&
2053                      ic[ 0].arg[0] == (size_t)&ic[-17]) {                      ic[ 0].arg[0] == (size_t)&ic[-17]) {
2054                          ic[-17].f = instr(netbsd_memset);                          ic[-17].f = instr(netbsd_memset);
                         combined;  
2055                  }                  }
2056          }          }
2057  #endif  #endif
# Line 2074  void COMBINE(netbsd_memcpy)(struct cpu * Line 2081  void COMBINE(netbsd_memcpy)(struct cpu *
2081                      ic[ 0].f == instr(b_samepage__ge) &&                      ic[ 0].f == instr(b_samepage__ge) &&
2082                      ic[ 0].arg[0] == (size_t)&ic[-5]) {                      ic[ 0].arg[0] == (size_t)&ic[-5]) {
2083                          ic[-5].f = instr(netbsd_memcpy);                          ic[-5].f = instr(netbsd_memcpy);
                         combined;  
2084                  }                  }
2085          }          }
2086  #endif  #endif
# Line 2099  void COMBINE(netbsd_cacheclean)(struct c Line 2105  void COMBINE(netbsd_cacheclean)(struct c
2105                      ic[-1].f == instr(b_samepage__ne) &&                      ic[-1].f == instr(b_samepage__ne) &&
2106                      ic[-1].arg[0] == (size_t)&ic[-3]) {                      ic[-1].arg[0] == (size_t)&ic[-3]) {
2107                          ic[-3].f = instr(netbsd_cacheclean);                          ic[-3].f = instr(netbsd_cacheclean);
                         combined;  
2108                  }                  }
2109          }          }
2110  }  }
# Line 2124  void COMBINE(netbsd_cacheclean2)(struct Line 2129  void COMBINE(netbsd_cacheclean2)(struct
2129                      ic[-1].f == instr(subs) &&                      ic[-1].f == instr(subs) &&
2130                      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) {
2131                          ic[-4].f = instr(netbsd_cacheclean2);                          ic[-4].f = instr(netbsd_cacheclean2);
                         combined;  
2132                  }                  }
2133          }          }
2134  }  }
# Line 2151  void COMBINE(netbsd_scanc)(struct cpu *c Line 2155  void COMBINE(netbsd_scanc)(struct cpu *c
2155              ic[-1].arg[1] == (size_t)arm_r_r3_t0_c0 &&              ic[-1].arg[1] == (size_t)arm_r_r3_t0_c0 &&
2156              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[3])) {              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[3])) {
2157                  ic[-2].f = instr(netbsd_scanc);                  ic[-2].f = instr(netbsd_scanc);
                 combined;  
2158          }          }
2159  }  }
2160    
# Line 2175  void COMBINE(strlen)(struct cpu *cpu, Line 2178  void COMBINE(strlen)(struct cpu *cpu,
2178              ic[-1].arg[0] == (size_t)(&cpu->cd.arm.r[3]) &&              ic[-1].arg[0] == (size_t)(&cpu->cd.arm.r[3]) &&
2179              ic[-1].arg[1] == 0) {              ic[-1].arg[1] == 0) {
2180                  ic[-2].f = instr(strlen);                  ic[-2].f = instr(strlen);
                 combined;  
2181          }          }
2182  }  }
2183    
# Line 2201  void COMBINE(xchg)(struct cpu *cpu, Line 2203  void COMBINE(xchg)(struct cpu *cpu,
2203              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 &&
2204              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) {
2205                  ic[-2].f = instr(xchg);                  ic[-2].f = instr(xchg);
                 combined;  
2206          }          }
2207  }  }
2208    
# Line 2232  void COMBINE(netbsd_copyin)(struct cpu * Line 2233  void COMBINE(netbsd_copyin)(struct cpu *
2233              ic[-2].arg[2] == (size_t)(&cpu->cd.arm.r[7]) &&              ic[-2].arg[2] == (size_t)(&cpu->cd.arm.r[7]) &&
2234              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[8])) {              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[8])) {
2235                  ic[-5].f = instr(netbsd_copyin);                  ic[-5].f = instr(netbsd_copyin);
                 combined;  
2236          }          }
2237  #endif  #endif
2238  }  }
# Line 2264  void COMBINE(netbsd_copyout)(struct cpu Line 2264  void COMBINE(netbsd_copyout)(struct cpu
2264              ic[-2].arg[2] == (size_t)(&cpu->cd.arm.r[11]) &&              ic[-2].arg[2] == (size_t)(&cpu->cd.arm.r[11]) &&
2265              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[6])) {              ic[-1].arg[2] == (size_t)(&cpu->cd.arm.r[6])) {
2266                  ic[-5].f = instr(netbsd_copyout);                  ic[-5].f = instr(netbsd_copyout);
                 combined;  
2267          }          }
2268  #endif  #endif
2269  }  }
# Line 2288  void COMBINE(cmps_b)(struct cpu *cpu, Line 2287  void COMBINE(cmps_b)(struct cpu *cpu,
2287                                  ic[-1].f = instr(cmps_neg_beq);                                  ic[-1].f = instr(cmps_neg_beq);
2288                          else                          else
2289                                  ic[-1].f = instr(cmps_pos_beq);                                  ic[-1].f = instr(cmps_pos_beq);
                         combined;  
2290                  }                  }
2291                  return;                  return;
2292          }          }
# Line 2298  void COMBINE(cmps_b)(struct cpu *cpu, Line 2296  void COMBINE(cmps_b)(struct cpu *cpu,
2296                                  ic[-1].f = instr(cmps0_beq_samepage);                                  ic[-1].f = instr(cmps0_beq_samepage);
2297                          else                          else
2298                                  ic[-1].f = instr(cmps_beq_samepage);                                  ic[-1].f = instr(cmps_beq_samepage);
                         combined;  
2299                  }                  }
2300                  if (ic[-1].f == instr(tsts) &&                  if (ic[-1].f == instr(tsts) &&
2301                      !(ic[-1].arg[1] & 0x80000000)) {                      !(ic[-1].arg[1] & 0x80000000)) {
2302                          ic[-1].f = instr(tsts_lo_beq_samepage);                          ic[-1].f = instr(tsts_lo_beq_samepage);
                         combined;  
2303                  }                  }
2304                  if (ic[-1].f == instr(teqs)) {                  if (ic[-1].f == instr(teqs)) {
2305                          ic[-1].f = instr(teqs_beq_samepage);                          ic[-1].f = instr(teqs_beq_samepage);
                         combined;  
2306                  }                  }
2307                  return;                  return;
2308          }          }
# Line 2317  void COMBINE(cmps_b)(struct cpu *cpu, Line 2312  void COMBINE(cmps_b)(struct cpu *cpu,
2312                                  ic[-1].f = instr(cmps0_bne_samepage);                                  ic[-1].f = instr(cmps0_bne_samepage);
2313                          else                          else
2314                                  ic[-1].f = instr(cmps_bne_samepage);                                  ic[-1].f = instr(cmps_bne_samepage);
                         combined;  
2315                  }                  }
2316                  if (ic[-1].f == instr(tsts) &&                  if (ic[-1].f == instr(tsts) &&
2317                      !(ic[-1].arg[1] & 0x80000000)) {                      !(ic[-1].arg[1] & 0x80000000)) {
2318                          ic[-1].f = instr(tsts_lo_bne_samepage);                          ic[-1].f = instr(tsts_lo_bne_samepage);
                         combined;  
2319                  }                  }
2320                  if (ic[-1].f == instr(teqs)) {                  if (ic[-1].f == instr(teqs)) {
2321                          ic[-1].f = instr(teqs_bne_samepage);                          ic[-1].f = instr(teqs_bne_samepage);
                         combined;  
2322                  }                  }
2323                  return;                  return;
2324          }          }
2325          if (ic[0].f == instr(b_samepage__cc)) {          if (ic[0].f == instr(b_samepage__cc)) {
2326                  if (ic[-1].f == instr(cmps)) {                  if (ic[-1].f == instr(cmps)) {
2327                          ic[-1].f = instr(cmps_bcc_samepage);                          ic[-1].f = instr(cmps_bcc_samepage);
                         combined;  
2328                  }                  }
2329                  if (ic[-1].f == instr(cmps_regshort)) {                  if (ic[-1].f == instr(cmps_regshort)) {
2330                          ic[-1].f = instr(cmps_reg_bcc_samepage);                          ic[-1].f = instr(cmps_reg_bcc_samepage);
                         combined;  
2331                  }                  }
2332                  return;                  return;
2333          }          }
2334          if (ic[0].f == instr(b_samepage__hi)) {          if (ic[0].f == instr(b_samepage__hi)) {
2335                  if (ic[-1].f == instr(cmps)) {                  if (ic[-1].f == instr(cmps)) {
2336                          ic[-1].f = instr(cmps_bhi_samepage);                          ic[-1].f = instr(cmps_bhi_samepage);
                         combined;  
2337                  }                  }
2338                  if (ic[-1].f == instr(cmps_regshort)) {                  if (ic[-1].f == instr(cmps_regshort)) {
2339                          ic[-1].f = instr(cmps_reg_bhi_samepage);                          ic[-1].f = instr(cmps_reg_bhi_samepage);
                         combined;  
2340                  }                  }
2341                  return;                  return;
2342          }          }
2343          if (ic[0].f == instr(b_samepage__gt)) {          if (ic[0].f == instr(b_samepage__gt)) {
2344                  if (ic[-1].f == instr(cmps)) {                  if (ic[-1].f == instr(cmps)) {
2345                          ic[-1].f = instr(cmps_bgt_samepage);                          ic[-1].f = instr(cmps_bgt_samepage);
                         combined;  
2346                  }                  }
2347                  return;                  return;
2348          }          }
2349          if (ic[0].f == instr(b_samepage__le)) {          if (ic[0].f == instr(b_samepage__le)) {
2350                  if (ic[-1].f == instr(cmps)) {                  if (ic[-1].f == instr(cmps)) {
2351                          ic[-1].f = instr(cmps_ble_samepage);                          ic[-1].f = instr(cmps_ble_samepage);
                         combined;  
2352                  }                  }
2353                  return;                  return;
2354          }          }
# Line 2455  static void arm_switch_add1(struct arm_i Line 2441  static void arm_switch_add1(struct arm_i
2441  X(to_be_translated)  X(to_be_translated)
2442  {  {
2443          uint32_t addr, low_pc, iword, imm = 0;          uint32_t addr, low_pc, iword, imm = 0;
 #ifdef DYNTRANS_BACKEND  
         int simple = 0;  
 #endif  
2444          unsigned char *page;          unsigned char *page;
2445          unsigned char ib[4];          unsigned char ib[4];
2446          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 2621  X(to_be_translated)
2621                      (iword & 0x0fb0f000) == 0x0320f000) {                      (iword & 0x0fb0f000) == 0x0320f000) {
2622                          /*  msr: move to [S|C]PSR from a register or                          /*  msr: move to [S|C]PSR from a register or
2623                              immediate value  */                              immediate value  */
                         if (rm == ARM_PC) {  
                                 fatal("msr PC?\n");  
                                 goto bad;  
                         }  
2624                          if (iword & 0x02000000) {                          if (iword & 0x02000000) {
2625                                  if (iword & 0x00400000)                                  if (iword & 0x00400000)
2626                                          ic->f = cond_instr(msr_imm_spsr);                                          ic->f = cond_instr(msr_imm_spsr);
2627                                  else                                  else
2628                                          ic->f = cond_instr(msr_imm);                                          ic->f = cond_instr(msr_imm);
2629                          } else {                          } else {
2630                                    if (rm == ARM_PC) {
2631                                            fatal("msr PC?\n");
2632                                            goto bad;
2633                                    }
2634                                  if (iword & 0x00400000)                                  if (iword & 0x00400000)
2635                                          ic->f = cond_instr(msr_spsr);                                          ic->f = cond_instr(msr_spsr);
2636                                  else                                  else
# Line 2745  X(to_be_translated) Line 2728  X(to_be_translated)
2728                  /*  "mov reg,#0":  */                  /*  "mov reg,#0":  */
2729                  if ((iword & 0x0fff0fff) == 0x03a00000 && rd != ARM_PC) {                  if ((iword & 0x0fff0fff) == 0x03a00000 && rd != ARM_PC) {
2730                          arm_switch_clear(ic, rd, condition_code);                          arm_switch_clear(ic, rd, condition_code);
 #ifdef DYNTRANS_BACKEND  
 simple = 1;  
 #endif  
2731                          break;                          break;
2732                  }                  }
2733    
2734                  /*  "mov reg,#1":  */                  /*  "mov reg,#1":  */
2735                  if ((iword & 0x0fff0fff) == 0x03a00001 && rd != ARM_PC) {                  if ((iword & 0x0fff0fff) == 0x03a00001 && rd != ARM_PC) {
2736                          arm_switch_mov1(ic, rd, condition_code);                          arm_switch_mov1(ic, rd, condition_code);
 #ifdef DYNTRANS_BACKEND  
 simple = 1;  
 #endif  
2737                          break;                          break;
2738                  }                  }
2739    
# Line 2764  simple = 1; Line 2741  simple = 1;
2741                  if ((iword & 0x0ff00fff) == 0x02800001 && rd != ARM_PC                  if ((iword & 0x0ff00fff) == 0x02800001 && rd != ARM_PC
2742                      && rn == rd) {                      && rn == rd) {
2743                          arm_switch_add1(ic, rd, condition_code);                          arm_switch_add1(ic, rd, condition_code);
 #ifdef DYNTRANS_BACKEND  
 simple = 1;  
 #endif  
2744                          break;                          break;
2745                  }                  }
2746    

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

  ViewVC Help
Powered by ViewVC 1.1.26