/[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 41 by dpavlin, Mon Oct 8 16:22:11 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_arm_instr.c,v 1.71 2007/04/20 13:47:53 debug Exp $   *  $Id: cpu_arm_instr.c,v 1.74 2007/06/14 04:53:46 debug Exp $
29   *   *
30   *  ARM instructions.   *  ARM instructions.
31   *   *
# Line 989  X(store_w1_word_u1_p0_imm); Line 989  X(store_w1_word_u1_p0_imm);
989  X(store_w0_byte_u1_p0_imm);  X(store_w0_byte_u1_p0_imm);
990  X(store_w0_word_u1_p0_imm);  X(store_w0_word_u1_p0_imm);
991  X(store_w0_word_u1_p1_imm);  X(store_w0_word_u1_p1_imm);
 X(load_w1_word_u1_p0_imm);  
992  X(load_w0_word_u1_p0_imm);  X(load_w0_word_u1_p0_imm);
993    X(load_w0_word_u1_p1_imm);
994    X(load_w1_word_u1_p0_imm);
995  X(load_w0_byte_u1_p1_imm);  X(load_w0_byte_u1_p1_imm);
996  X(load_w0_byte_u1_p1_reg);  X(load_w0_byte_u1_p1_reg);
997  X(load_w1_byte_u1_p1_imm);  X(load_w1_byte_u1_p1_imm);
# Line 1534  X(netbsd_scanc) Line 1535  X(netbsd_scanc)
1535    
1536    
1537  /*  /*
1538     *  netbsd_idle:
1539     *
1540     *  L:  ldr     rX,[rY]
1541     *      teqs    rX,#0
1542     *      bne     X (samepage)
1543     *      teqs    rZ,#0
1544     *      beq     L (samepage)
1545     *      ....
1546     *      X:  somewhere else on the same page
1547     */
1548    X(netbsd_idle)
1549    {
1550            uint32_t rY = reg(ic[0].arg[0]);
1551            uint32_t rZ = reg(ic[3].arg[0]);
1552            uint32_t *p;
1553            uint32_t rX;
1554    
1555            p = (uint32_t *) cpu->cd.arm.host_load[rY >> 12];
1556            if (p == NULL) {
1557                    instr(load_w0_word_u1_p1_imm)(cpu, ic);
1558                    return;
1559            }
1560    
1561            rX = p[(rY & 0xfff) >> 2];
1562            /*  No need to convert endianness, since it's only a 0-test.  */
1563    
1564            /*  This makes execution continue on the first teqs instruction,
1565                which is fine.  */
1566            if (rX != 0) {
1567                    instr(load_w0_word_u1_p1_imm)(cpu, ic);
1568                    return;
1569            }
1570    
1571            if (rZ == 0) {
1572                    /*  Synch the program counter.  */
1573                    uint32_t low_pc = ((size_t)ic - (size_t)
1574                        cpu->cd.arm.cur_ic_page) / sizeof(struct arm_instr_call);
1575                    cpu->pc &= ~((ARM_IC_ENTRIES_PER_PAGE-1)
1576                        << ARM_INSTR_ALIGNMENT_SHIFT);
1577                    cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
1578    
1579                    /*  Quasi-idle for a while:  */
1580                    cpu->has_been_idling = 1;
1581                    if (cpu->machine->ncpus == 1)
1582                            usleep(50);
1583                    cpu->n_translated_instrs += N_SAFE_DYNTRANS_LIMIT;
1584    
1585                    cpu->cd.arm.next_ic = &nothing_call;
1586                    return;
1587            }
1588    
1589            cpu->cd.arm.next_ic = &ic[5];
1590    }
1591    
1592    
1593    /*
1594   *  strlen:   *  strlen:
1595   *   *
1596   *  S: e5f03001   ldrb  rY,[rX,#1]!   *  S: e5f03001   ldrb  rY,[rX,#1]!
# Line 2270  void COMBINE(netbsd_copyout)(struct cpu Line 2327  void COMBINE(netbsd_copyout)(struct cpu
2327    
2328    
2329  /*  /*
2330   *  Combine: cmps_b():   *  Combine: cmps + beq, etc:
2331   */   */
2332  void COMBINE(cmps_b)(struct cpu *cpu,  void COMBINE(beq_etc)(struct cpu *cpu,
2333          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2334  {  {
2335          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)
# Line 2301  void COMBINE(cmps_b)(struct cpu *cpu, Line 2358  void COMBINE(cmps_b)(struct cpu *cpu,
2358                      !(ic[-1].arg[1] & 0x80000000)) {                      !(ic[-1].arg[1] & 0x80000000)) {
2359                          ic[-1].f = instr(tsts_lo_beq_samepage);                          ic[-1].f = instr(tsts_lo_beq_samepage);
2360                  }                  }
2361                    if (n_back >= 4 &&
2362                        ic[-4].f == instr(load_w0_word_u1_p1_imm) &&
2363                        ic[-4].arg[0] != ic[-4].arg[2] &&
2364                        ic[-4].arg[1] == 0 &&
2365                        ic[-4].arg[2] == ic[-3].arg[0] &&
2366                        /*  Note: The teqs+bne is already combined!  */
2367                        ic[-3].f == instr(teqs_bne_samepage) &&
2368                        ic[-3].arg[1] == 0 &&
2369                        ic[-2].f == instr(b_samepage__ne) &&
2370                        ic[-1].f == instr(teqs) &&
2371                        ic[-1].arg[0] != ic[-4].arg[0] &&
2372                        ic[-1].arg[1] == 0) {
2373                            ic[-4].f = instr(netbsd_idle);
2374                    }
2375                  if (ic[-1].f == instr(teqs)) {                  if (ic[-1].f == instr(teqs)) {
2376                          ic[-1].f = instr(teqs_beq_samepage);                          ic[-1].f = instr(teqs_beq_samepage);
2377                  }                  }
# Line 2504  X(to_be_translated) Line 2575  X(to_be_translated)
2575                          goto okay;                          goto okay;
2576                  }                  }
2577    
2578                  fatal("TODO: ARM condition code 0x%x\n",                  if (!cpu->translation_readahead)
2579                      condition_code);                          fatal("TODO: ARM condition code 0x%x\n",
2580                                condition_code);
2581                  goto bad;                  goto bad;
2582          }          }
2583    
# Line 2547  X(to_be_translated) Line 2619  X(to_be_translated)
2619                  if ((iword & 0x0f8000f0) == 0x00800090) {                  if ((iword & 0x0f8000f0) == 0x00800090) {
2620                          /*  Long multiplication:  */                          /*  Long multiplication:  */
2621                          if (s_bit) {                          if (s_bit) {
2622                                  fatal("TODO: sbit mull\n");                                  if (!cpu->translation_readahead)
2623                                            fatal("TODO: sbit mull\n");
2624                                  goto bad;                                  goto bad;
2625                          }                          }
2626                          ic->f = cond_instr(mull);                          ic->f = cond_instr(mull);
# Line 2555  X(to_be_translated) Line 2628  X(to_be_translated)
2628                          break;                          break;
2629                  }                  }
2630                  if ((iword & 0x0f900ff0) == 0x01000050) {                  if ((iword & 0x0f900ff0) == 0x01000050) {
2631                          fatal("TODO: q{,d}{add,sub}\n");                          if (!cpu->translation_readahead)
2632                                    fatal("TODO: q{,d}{add,sub}\n");
2633                          goto bad;                          goto bad;
2634                  }                  }
2635                  if ((iword & 0x0ff000d0) == 0x01200010) {                  if ((iword & 0x0ff000d0) == 0x01200010) {
# Line 2628  X(to_be_translated) Line 2702  X(to_be_translated)
2702                                          ic->f = cond_instr(msr_imm);                                          ic->f = cond_instr(msr_imm);
2703                          } else {                          } else {
2704                                  if (rm == ARM_PC) {                                  if (rm == ARM_PC) {
2705                                          fatal("msr PC?\n");                                          if (!cpu->translation_readahead)
2706                                                    fatal("msr PC?\n");
2707                                          goto bad;                                          goto bad;
2708                                  }                                  }
2709                                  if (iword & 0x00400000)                                  if (iword & 0x00400000)
# Line 2645  X(to_be_translated) Line 2720  X(to_be_translated)
2720                          case 1: ic->arg[1] = 0x000000ff; break;                          case 1: ic->arg[1] = 0x000000ff; break;
2721                          case 8: ic->arg[1] = 0xff000000; break;                          case 8: ic->arg[1] = 0xff000000; break;
2722                          case 9: ic->arg[1] = 0xff0000ff; break;                          case 9: ic->arg[1] = 0xff0000ff; break;
2723                          default:fatal("unimpl a: msr regform\n");                          default:if (!cpu->translation_readahead)
2724                                            fatal("unimpl a: msr regform\n");
2725                                  goto bad;                                  goto bad;
2726                          }                          }
2727                          break;                          break;
# Line 2653  X(to_be_translated) Line 2729  X(to_be_translated)
2729                  if ((iword & 0x0fbf0fff) == 0x010f0000) {                  if ((iword & 0x0fbf0fff) == 0x010f0000) {
2730                          /*  mrs: move from CPSR/SPSR to a register:  */                          /*  mrs: move from CPSR/SPSR to a register:  */
2731                          if (rd == ARM_PC) {                          if (rd == ARM_PC) {
2732                                  fatal("mrs PC?\n");                                  if (!cpu->translation_readahead)
2733                                            fatal("mrs PC?\n");
2734                                  goto bad;                                  goto bad;
2735                          }                          }
2736                          if (iword & 0x00400000)                          if (iword & 0x00400000)
# Line 2699  X(to_be_translated) Line 2776  X(to_be_translated)
2776                  }                  }
2777    
2778                  if (iword & 0x80 && !(main_opcode & 2) && iword & 0x10) {                  if (iword & 0x80 && !(main_opcode & 2) && iword & 0x10) {
2779                          fatal("reg form blah blah\n");                          if (!cpu->translation_readahead)
2780                                    fatal("reg form blah blah\n");
2781                          goto bad;                          goto bad;
2782                  }                  }
2783    
# Line 2821  X(to_be_translated) Line 2899  X(to_be_translated)
2899                  else                  else
2900                          ic->arg[1] = (size_t)(void *)arm_r[iword & 0xfff];                          ic->arg[1] = (size_t)(void *)arm_r[iword & 0xfff];
2901                  if ((iword & 0x0e000010) == 0x06000010) {                  if ((iword & 0x0e000010) == 0x06000010) {
2902                          fatal("Not a Load/store TODO\n");                          if (!cpu->translation_readahead)
2903                                    fatal("Not a Load/store TODO\n");
2904                          goto bad;                          goto bad;
2905                  }                  }
2906                  /*  Special case: pc-relative load within the same page:  */                  /*  Special case: pc-relative load within the same page:  */
# Line 2850  X(to_be_translated) Line 2929  X(to_be_translated)
2929                                  } else {                                  } else {
2930                                          if (!cpu->memory_rw(cpu, cpu->mem, a,                                          if (!cpu->memory_rw(cpu, cpu->mem, a,
2931                                              c, len, MEM_READ, CACHE_DATA)) {                                              c, len, MEM_READ, CACHE_DATA)) {
2932                                                  fatal("to_be_translated(): "                                                  if (!cpu->translation_readahead)
2933                                                      "read failed X: TODO\n");                                                          fatal("read failed X:"
2934                                                                " TODO\n");
2935                                                  goto bad;                                                  goto bad;
2936                                          }                                          }
2937                                  }                                  }
# Line 2910  X(to_be_translated) Line 2990  X(to_be_translated)
2990                  }                  }
2991  #endif  #endif
2992                  if (rn == ARM_PC) {                  if (rn == ARM_PC) {
2993                          fatal("TODO: bdt with PC as base\n");                          if (!cpu->translation_readahead)
2994                                    fatal("TODO: bdt with PC as base\n");
2995                          goto bad;                          goto bad;
2996                  }                  }
2997                  break;                  break;
# Line 2920  X(to_be_translated) Line 3001  X(to_be_translated)
3001                  if (main_opcode == 0x0a) {                  if (main_opcode == 0x0a) {
3002                          ic->f = cond_instr(b);                          ic->f = cond_instr(b);
3003                          samepage_function = cond_instr(b_samepage);                          samepage_function = cond_instr(b_samepage);
3004    
3005                            /*  Abort read-ahead on unconditional branches:  */
3006                            if (condition_code == 0xe &&
3007                                cpu->translation_readahead > 1)
3008                                    cpu->translation_readahead = 1;
3009    
3010                          if (iword == 0xcaffffed)                          if (iword == 0xcaffffed)
3011                                  cpu->cd.arm.combination_check =                                  cpu->cd.arm.combination_check =
3012                                      COMBINE(netbsd_memset);                                      COMBINE(netbsd_memset);
# Line 2984  X(to_be_translated) Line 3071  X(to_be_translated)
3071                  if (main_opcode == 0xa && (condition_code <= 1                  if (main_opcode == 0xa && (condition_code <= 1
3072                      || condition_code == 3 || condition_code == 8                      || condition_code == 3 || condition_code == 8
3073                      || condition_code == 12 || condition_code == 13))                      || condition_code == 12 || condition_code == 13))
3074                          cpu->cd.arm.combination_check = COMBINE(cmps_b);                          cpu->cd.arm.combination_check = COMBINE(beq_etc);
3075    
3076                  if (iword == 0x1afffffc)                  if (iword == 0x1afffffc)
3077                          cpu->cd.arm.combination_check = COMBINE(strlen);                          cpu->cd.arm.combination_check = COMBINE(strlen);
# Line 3003  X(to_be_translated) Line 3090  X(to_be_translated)
3090                   */                   */
3091                  if ((iword & 0x0fe00fff) == 0x0c400000) {                  if ((iword & 0x0fe00fff) == 0x0c400000) {
3092                          /*  Special case: mar/mra DSP instructions  */                          /*  Special case: mar/mra DSP instructions  */
3093                          fatal("TODO: mar/mra DSP instructions!\n");                          if (!cpu->translation_readahead)
3094                                    fatal("TODO: mar/mra DSP instructions!\n");
3095                          /*  Perhaps these are actually identical to MCRR/MRRC */                          /*  Perhaps these are actually identical to MCRR/MRRC */
3096                          goto bad;                          goto bad;
3097                  }                  }
3098    
3099                  if ((iword & 0x0fe00000) == 0x0c400000) {                  if ((iword & 0x0fe00000) == 0x0c400000) {
3100                          fatal("MCRR/MRRC: TODO\n");                          if (!cpu->translation_readahead)
3101                                    fatal("MCRR/MRRC: TODO\n");
3102                          goto bad;                          goto bad;
3103                  }                  }
3104    
# Line 3023  X(to_be_translated) Line 3112  X(to_be_translated)
3112                  ic->f = cond_instr(und);                  ic->f = cond_instr(und);
3113                  ic->arg[0] = addr & 0xfff;                  ic->arg[0] = addr & 0xfff;
3114  #else  #else
3115                  fatal("LDC/STC: TODO\n");                  if (!cpu->translation_readahead)
3116                            fatal("LDC/STC: TODO\n");
3117                  goto bad;                  goto bad;
3118  #endif  #endif
3119                  break;                  break;
# Line 3032  X(to_be_translated) Line 3122  X(to_be_translated)
3122                  if ((iword & 0x0ff00ff0) == 0x0e200010) {                  if ((iword & 0x0ff00ff0) == 0x0e200010) {
3123                          /*  Special case: mia* DSP instructions  */                          /*  Special case: mia* DSP instructions  */
3124                          /*  See Intel's 27343601.pdf, page 16-20  */                          /*  See Intel's 27343601.pdf, page 16-20  */
3125                          fatal("TODO: mia* DSP instructions!\n");                          if (!cpu->translation_readahead)
3126                                    fatal("TODO: mia* DSP instructions!\n");
3127                          goto bad;                          goto bad;
3128                  }                  }
3129                  if (iword & 0x10) {                  if (iword & 0x10) {
# Line 3065  X(to_be_translated) Line 3156  X(to_be_translated)
3156                                  ic->arg[0] = iword & 0x00ffffff;                                  ic->arg[0] = iword & 0x00ffffff;
3157                                  ic->f = cond_instr(swi_useremul);                                  ic->f = cond_instr(swi_useremul);
3158                          } else {                          } else {
3159                                  fatal("Bad userland SWI?\n");                                  if (!cpu->translation_readahead)
3160                                            fatal("Bad userland SWI?\n");
3161                                  goto bad;                                  goto bad;
3162                          }                          }
3163                  }                  }

Legend:
Removed from v.41  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26