/[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 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC revision 44 by dpavlin, Mon Oct 8 16:22:56 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_arm_instr.c,v 1.69 2006/09/09 09:04:32 debug Exp $   *  $Id: cpu_arm_instr.c,v 1.77 2007/06/28 13:36:46 debug Exp $
29   *   *
30   *  ARM instructions.   *  ARM instructions.
31   *   *
# Line 235  X(nop) Line 235  X(nop)
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 from start of page
239   */   */
240  X(b)  X(b)
241  {  {
# 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                    static int x = 0;
1573    
1574                    /*  Synch the program counter.  */
1575                    uint32_t low_pc = ((size_t)ic - (size_t)
1576                        cpu->cd.arm.cur_ic_page) / sizeof(struct arm_instr_call);
1577                    cpu->pc &= ~((ARM_IC_ENTRIES_PER_PAGE-1)
1578                        << ARM_INSTR_ALIGNMENT_SHIFT);
1579                    cpu->pc += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT);
1580    
1581                    /*  Quasi-idle for a while:  */
1582                    cpu->has_been_idling = 1;
1583                    if (cpu->machine->ncpus == 1 && (++x) == 100) {
1584                            usleep(50);
1585                            x = 0;
1586                    }
1587    
1588                    cpu->n_translated_instrs += N_SAFE_DYNTRANS_LIMIT / 6;
1589                    cpu->cd.arm.next_ic = &nothing_call;
1590                    return;
1591            }
1592    
1593            cpu->cd.arm.next_ic = &ic[5];
1594    }
1595    
1596    
1597    /*
1598   *  strlen:   *  strlen:
1599   *   *
1600   *  S: e5f03001   ldrb  rY,[rX,#1]!   *  S: e5f03001   ldrb  rY,[rX,#1]!
# Line 2270  void COMBINE(netbsd_copyout)(struct cpu Line 2331  void COMBINE(netbsd_copyout)(struct cpu
2331    
2332    
2333  /*  /*
2334   *  Combine: cmps_b():   *  Combine: cmps + beq, etc:
2335   */   */
2336  void COMBINE(cmps_b)(struct cpu *cpu,  void COMBINE(beq_etc)(struct cpu *cpu,
2337          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2338  {  {
2339          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 2362  void COMBINE(cmps_b)(struct cpu *cpu,
2362                      !(ic[-1].arg[1] & 0x80000000)) {                      !(ic[-1].arg[1] & 0x80000000)) {
2363                          ic[-1].f = instr(tsts_lo_beq_samepage);                          ic[-1].f = instr(tsts_lo_beq_samepage);
2364                  }                  }
2365                    if (n_back >= 4 &&
2366                        ic[-4].f == instr(load_w0_word_u1_p1_imm) &&
2367                        ic[-4].arg[0] != ic[-4].arg[2] &&
2368                        ic[-4].arg[1] == 0 &&
2369                        ic[-4].arg[2] == ic[-3].arg[0] &&
2370                        /*  Note: The teqs+bne is already combined!  */
2371                        ic[-3].f == instr(teqs_bne_samepage) &&
2372                        ic[-3].arg[1] == 0 &&
2373                        ic[-2].f == instr(b_samepage__ne) &&
2374                        ic[-1].f == instr(teqs) &&
2375                        ic[-1].arg[0] != ic[-4].arg[0] &&
2376                        ic[-1].arg[1] == 0) {
2377                            ic[-4].f = instr(netbsd_idle);
2378                    }
2379                  if (ic[-1].f == instr(teqs)) {                  if (ic[-1].f == instr(teqs)) {
2380                          ic[-1].f = instr(teqs_beq_samepage);                          ic[-1].f = instr(teqs_beq_samepage);
2381                  }                  }
# Line 2458  X(to_be_translated) Line 2533  X(to_be_translated)
2533    
2534          /*  Read the instruction word from memory:  */          /*  Read the instruction word from memory:  */
2535          page = cpu->cd.arm.host_load[addr >> 12];          page = cpu->cd.arm.host_load[addr >> 12];
2536    
2537          if (page != NULL) {          if (page != NULL) {
2538                  /*  fatal("TRANSLATION HIT! 0x%08x\n", addr);  */                  /*  fatal("TRANSLATION HIT! 0x%08x\n", addr);  */
2539                  memcpy(ib, page + (addr & 0xfff), sizeof(ib));                  memcpy(ib, page + (addr & 0xfff), sizeof(ib));
# Line 2504  X(to_be_translated) Line 2580  X(to_be_translated)
2580                          goto okay;                          goto okay;
2581                  }                  }
2582    
2583                  fatal("TODO: ARM condition code 0x%x\n",                  if (!cpu->translation_readahead)
2584                      condition_code);                          fatal("TODO: ARM condition code 0x%x\n",
2585                                condition_code);
2586                  goto bad;                  goto bad;
2587          }          }
2588    
# Line 2547  X(to_be_translated) Line 2624  X(to_be_translated)
2624                  if ((iword & 0x0f8000f0) == 0x00800090) {                  if ((iword & 0x0f8000f0) == 0x00800090) {
2625                          /*  Long multiplication:  */                          /*  Long multiplication:  */
2626                          if (s_bit) {                          if (s_bit) {
2627                                  fatal("TODO: sbit mull\n");                                  if (!cpu->translation_readahead)
2628                                            fatal("TODO: sbit mull\n");
2629                                  goto bad;                                  goto bad;
2630                          }                          }
2631                          ic->f = cond_instr(mull);                          ic->f = cond_instr(mull);
# Line 2555  X(to_be_translated) Line 2633  X(to_be_translated)
2633                          break;                          break;
2634                  }                  }
2635                  if ((iword & 0x0f900ff0) == 0x01000050) {                  if ((iword & 0x0f900ff0) == 0x01000050) {
2636                          fatal("TODO: q{,d}{add,sub}\n");                          if (!cpu->translation_readahead)
2637                                    fatal("TODO: q{,d}{add,sub}\n");
2638                          goto bad;                          goto bad;
2639                  }                  }
2640                  if ((iword & 0x0ff000d0) == 0x01200010) {                  if ((iword & 0x0ff000d0) == 0x01200010) {
# Line 2628  X(to_be_translated) Line 2707  X(to_be_translated)
2707                                          ic->f = cond_instr(msr_imm);                                          ic->f = cond_instr(msr_imm);
2708                          } else {                          } else {
2709                                  if (rm == ARM_PC) {                                  if (rm == ARM_PC) {
2710                                          fatal("msr PC?\n");                                          if (!cpu->translation_readahead)
2711                                                    fatal("msr PC?\n");
2712                                          goto bad;                                          goto bad;
2713                                  }                                  }
2714                                  if (iword & 0x00400000)                                  if (iword & 0x00400000)
# Line 2645  X(to_be_translated) Line 2725  X(to_be_translated)
2725                          case 1: ic->arg[1] = 0x000000ff; break;                          case 1: ic->arg[1] = 0x000000ff; break;
2726                          case 8: ic->arg[1] = 0xff000000; break;                          case 8: ic->arg[1] = 0xff000000; break;
2727                          case 9: ic->arg[1] = 0xff0000ff; break;                          case 9: ic->arg[1] = 0xff0000ff; break;
2728                          default:fatal("unimpl a: msr regform\n");                          default:if (!cpu->translation_readahead)
2729                                            fatal("unimpl a: msr regform\n");
2730                                  goto bad;                                  goto bad;
2731                          }                          }
2732                          break;                          break;
# Line 2653  X(to_be_translated) Line 2734  X(to_be_translated)
2734                  if ((iword & 0x0fbf0fff) == 0x010f0000) {                  if ((iword & 0x0fbf0fff) == 0x010f0000) {
2735                          /*  mrs: move from CPSR/SPSR to a register:  */                          /*  mrs: move from CPSR/SPSR to a register:  */
2736                          if (rd == ARM_PC) {                          if (rd == ARM_PC) {
2737                                  fatal("mrs PC?\n");                                  if (!cpu->translation_readahead)
2738                                            fatal("mrs PC?\n");
2739                                  goto bad;                                  goto bad;
2740                          }                          }
2741                          if (iword & 0x00400000)                          if (iword & 0x00400000)
# Line 2699  X(to_be_translated) Line 2781  X(to_be_translated)
2781                  }                  }
2782    
2783                  if (iword & 0x80 && !(main_opcode & 2) && iword & 0x10) {                  if (iword & 0x80 && !(main_opcode & 2) && iword & 0x10) {
2784                          fatal("reg form blah blah\n");                          if (!cpu->translation_readahead)
2785                                    fatal("reg form blah blah\n");
2786                          goto bad;                          goto bad;
2787                  }                  }
2788    
# Line 2821  X(to_be_translated) Line 2904  X(to_be_translated)
2904                  else                  else
2905                          ic->arg[1] = (size_t)(void *)arm_r[iword & 0xfff];                          ic->arg[1] = (size_t)(void *)arm_r[iword & 0xfff];
2906                  if ((iword & 0x0e000010) == 0x06000010) {                  if ((iword & 0x0e000010) == 0x06000010) {
2907                          fatal("Not a Load/store TODO\n");                          if (!cpu->translation_readahead)
2908                                    fatal("Not a Load/store TODO\n");
2909                          goto bad;                          goto bad;
2910                  }                  }
2911                  /*  Special case: pc-relative load within the same page:  */                  /*  Special case: pc-relative load within the same page:  */
# Line 2844  X(to_be_translated) Line 2928  X(to_be_translated)
2928                                  /*  ic->f = cond_instr(mov);  */                                  /*  ic->f = cond_instr(mov);  */
2929                                  ic->f = arm_dpi_instr[condition_code + 16*0xd];                                  ic->f = arm_dpi_instr[condition_code + 16*0xd];
2930                                  ic->arg[2] = (size_t)(&cpu->cd.arm.r[rd]);                                  ic->arg[2] = (size_t)(&cpu->cd.arm.r[rd]);
2931                                  p = cpu->cd.arm.host_load[a >> 12];                                  p = page;
2932                                  if (p != NULL) {                                  if (p != NULL) {
2933                                          memcpy(c, p + (a & 0xfff), len);                                          memcpy(c, p + (a & 0xfff), len);
2934                                  } else {                                  } else {
2935                                          if (!cpu->memory_rw(cpu, cpu->mem, a,                                          fatal("Hm? Internal error in "
2936                                              c, len, MEM_READ, CACHE_DATA)) {                                              "cpu_arm_instr.c!\n");
2937                                                  fatal("to_be_translated(): "                                          goto bad;
                                                     "read failed X: TODO\n");  
                                                 goto bad;  
                                         }  
2938                                  }                                  }
2939                                  if (cpu->byte_order == EMUL_LITTLE_ENDIAN)                                  if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
2940                                          x = c[0] + (c[1]<<8) +                                          x = c[0] + (c[1]<<8) +
# Line 2910  X(to_be_translated) Line 2991  X(to_be_translated)
2991                  }                  }
2992  #endif  #endif
2993                  if (rn == ARM_PC) {                  if (rn == ARM_PC) {
2994                          fatal("TODO: bdt with PC as base\n");                          if (!cpu->translation_readahead)
2995                                    fatal("TODO: bdt with PC as base\n");
2996                          goto bad;                          goto bad;
2997                  }                  }
2998                  break;                  break;
# Line 2920  X(to_be_translated) Line 3002  X(to_be_translated)
3002                  if (main_opcode == 0x0a) {                  if (main_opcode == 0x0a) {
3003                          ic->f = cond_instr(b);                          ic->f = cond_instr(b);
3004                          samepage_function = cond_instr(b_samepage);                          samepage_function = cond_instr(b_samepage);
3005    
3006                            /*  Abort read-ahead on unconditional branches:  */
3007                            if (condition_code == 0xe &&
3008                                cpu->translation_readahead > 1)
3009                                    cpu->translation_readahead = 1;
3010    
3011                          if (iword == 0xcaffffed)                          if (iword == 0xcaffffed)
3012                                  cpu->cd.arm.combination_check =                                  cpu->cd.arm.combination_check =
3013                                      COMBINE(netbsd_memset);                                      COMBINE(netbsd_memset);
# Line 2984  X(to_be_translated) Line 3072  X(to_be_translated)
3072                  if (main_opcode == 0xa && (condition_code <= 1                  if (main_opcode == 0xa && (condition_code <= 1
3073                      || condition_code == 3 || condition_code == 8                      || condition_code == 3 || condition_code == 8
3074                      || condition_code == 12 || condition_code == 13))                      || condition_code == 12 || condition_code == 13))
3075                          cpu->cd.arm.combination_check = COMBINE(cmps_b);                          cpu->cd.arm.combination_check = COMBINE(beq_etc);
3076    
3077                  if (iword == 0x1afffffc)                  if (iword == 0x1afffffc)
3078                          cpu->cd.arm.combination_check = COMBINE(strlen);                          cpu->cd.arm.combination_check = COMBINE(strlen);
# Line 3003  X(to_be_translated) Line 3091  X(to_be_translated)
3091                   */                   */
3092                  if ((iword & 0x0fe00fff) == 0x0c400000) {                  if ((iword & 0x0fe00fff) == 0x0c400000) {
3093                          /*  Special case: mar/mra DSP instructions  */                          /*  Special case: mar/mra DSP instructions  */
3094                          fatal("TODO: mar/mra DSP instructions!\n");                          if (!cpu->translation_readahead)
3095                                    fatal("TODO: mar/mra DSP instructions!\n");
3096                          /*  Perhaps these are actually identical to MCRR/MRRC */                          /*  Perhaps these are actually identical to MCRR/MRRC */
3097                          goto bad;                          goto bad;
3098                  }                  }
3099    
3100                  if ((iword & 0x0fe00000) == 0x0c400000) {                  if ((iword & 0x0fe00000) == 0x0c400000) {
3101                          fatal("MCRR/MRRC: TODO\n");                          if (!cpu->translation_readahead)
3102                                    fatal("MCRR/MRRC: TODO\n");
3103                          goto bad;                          goto bad;
3104                  }                  }
3105    
# Line 3023  X(to_be_translated) Line 3113  X(to_be_translated)
3113                  ic->f = cond_instr(und);                  ic->f = cond_instr(und);
3114                  ic->arg[0] = addr & 0xfff;                  ic->arg[0] = addr & 0xfff;
3115  #else  #else
3116                  fatal("LDC/STC: TODO\n");                  if (!cpu->translation_readahead)
3117                            fatal("LDC/STC: TODO\n");
3118                  goto bad;                  goto bad;
3119  #endif  #endif
3120                  break;                  break;
# Line 3032  X(to_be_translated) Line 3123  X(to_be_translated)
3123                  if ((iword & 0x0ff00ff0) == 0x0e200010) {                  if ((iword & 0x0ff00ff0) == 0x0e200010) {
3124                          /*  Special case: mia* DSP instructions  */                          /*  Special case: mia* DSP instructions  */
3125                          /*  See Intel's 27343601.pdf, page 16-20  */                          /*  See Intel's 27343601.pdf, page 16-20  */
3126                          fatal("TODO: mia* DSP instructions!\n");                          if (!cpu->translation_readahead)
3127                                    fatal("TODO: mia* DSP instructions!\n");
3128                          goto bad;                          goto bad;
3129                  }                  }
3130                  if (iword & 0x10) {                  if (iword & 0x10) {
# Line 3065  X(to_be_translated) Line 3157  X(to_be_translated)
3157                                  ic->arg[0] = iword & 0x00ffffff;                                  ic->arg[0] = iword & 0x00ffffff;
3158                                  ic->f = cond_instr(swi_useremul);                                  ic->f = cond_instr(swi_useremul);
3159                          } else {                          } else {
3160                                  fatal("Bad userland SWI?\n");                                  if (!cpu->translation_readahead)
3161                                            fatal("Bad userland SWI?\n");
3162                                  goto bad;                                  goto bad;
3163                          }                          }
3164                  }                  }

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

  ViewVC Help
Powered by ViewVC 1.1.26