/[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 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  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.54 2005/11/19 18:53:07 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 36  Line 36 
36   */   */
37    
38    
 #include "arm_quick_pc_to_pointers.h"  
   
39  /*  #define GATHER_BDT_STATISTICS  */  /*  #define GATHER_BDT_STATISTICS  */
40    
41    
# Line 203  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 215  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 587  Y(mull) Line 591  Y(mull)
591    
592    
593  /*  /*
594     *  smulXY:  16-bit * 16-bit multiplication (32-bit result)
595     *
596     *  arg[0] = ptr to rm
597     *  arg[1] = ptr to rs
598     *  arg[2] = ptr to rd
599     */
600    X(smulbb)
601    {
602            reg(ic->arg[2]) = (int32_t)(int16_t)reg(ic->arg[0]) *
603                (int32_t)(int16_t)reg(ic->arg[1]);
604    }
605    Y(smulbb)
606    X(smultb)
607    {
608            reg(ic->arg[2]) = (int32_t)(int16_t)(reg(ic->arg[0]) >> 16) *
609                (int32_t)(int16_t)reg(ic->arg[1]);
610    }
611    Y(smultb)
612    X(smulbt)
613    {
614            reg(ic->arg[2]) = (int32_t)(int16_t)reg(ic->arg[0]) *
615                (int32_t)(int16_t)(reg(ic->arg[1]) >> 16);
616    }
617    Y(smulbt)
618    X(smultt)
619    {
620            reg(ic->arg[2]) = (int32_t)(int16_t)(reg(ic->arg[0]) >> 16) *
621                (int32_t)(int16_t)(reg(ic->arg[1]) >> 16);
622    }
623    Y(smultt)
624    
625    
626    /*
627   *  mov_reg_reg:  Move a register to another.   *  mov_reg_reg:  Move a register to another.
628   *   *
629   *  arg[0] = ptr to source register   *  arg[0] = ptr to source register
# Line 725  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 820  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 844  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 1289  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 1991  X(end_of_page) Line 2026  X(end_of_page)
2026    
2027    
2028  /*  /*
2029   *  arm_combine_netbsd_memset():   *  Combine: netbsd_memset():
2030   *   *
2031   *  Check for the core of a NetBSD/arm memset; large memsets use a sequence   *  Check for the core of a NetBSD/arm memset; large memsets use a sequence
2032   *  of 16 store-multiple instructions, each storing 2 registers at a time.   *  of 16 store-multiple instructions, each storing 2 registers at a time.
2033   */   */
2034  void arm_combine_netbsd_memset(struct cpu *cpu,  void COMBINE(netbsd_memset)(struct cpu *cpu,
2035          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2036  {  {
2037  #ifdef HOST_LITTLE_ENDIAN  #ifdef HOST_LITTLE_ENDIAN
# Line 2013  void arm_combine_netbsd_memset(struct cp Line 2048  void arm_combine_netbsd_memset(struct cp
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 2021  void arm_combine_netbsd_memset(struct cp Line 2055  void arm_combine_netbsd_memset(struct cp
2055    
2056    
2057  /*  /*
2058   *  arm_combine_netbsd_memcpy():   *  Combine: netbsd_memcpy():
2059   *   *
2060   *  Check for the core of a NetBSD/arm memcpy; large memcpys use a   *  Check for the core of a NetBSD/arm memcpy; large memcpys use a
2061   *  sequence of ldmia instructions.   *  sequence of ldmia instructions.
2062   */   */
2063  void arm_combine_netbsd_memcpy(struct cpu *cpu,  void COMBINE(netbsd_memcpy)(struct cpu *cpu, struct arm_instr_call *ic,
2064          struct arm_instr_call *ic, int low_addr)          int low_addr)
2065  {  {
2066  #ifdef HOST_LITTLE_ENDIAN  #ifdef HOST_LITTLE_ENDIAN
2067          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)
# Line 2043  void arm_combine_netbsd_memcpy(struct cp Line 2077  void arm_combine_netbsd_memcpy(struct cp
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 2051  void arm_combine_netbsd_memcpy(struct cp Line 2084  void arm_combine_netbsd_memcpy(struct cp
2084    
2085    
2086  /*  /*
2087   *  arm_combine_netbsd_cacheclean():   *  Combine: netbsd_cacheclean():
2088   *   *
2089   *  Check for the core of a NetBSD/arm cache clean. (There are two variants.)   *  Check for the core of a NetBSD/arm cache clean. (There are two variants.)
2090   */   */
2091  void arm_combine_netbsd_cacheclean(struct cpu *cpu,  void COMBINE(netbsd_cacheclean)(struct cpu *cpu,
2092          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2093  {  {
2094          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)
# Line 2068  void arm_combine_netbsd_cacheclean(struc Line 2101  void arm_combine_netbsd_cacheclean(struc
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  }  }
2107    
2108    
2109  /*  /*
2110   *  arm_combine_netbsd_cacheclean2():   *  Combine: netbsd_cacheclean2():
2111   *   *
2112   *  Check for the core of a NetBSD/arm cache clean. (Second variant.)   *  Check for the core of a NetBSD/arm cache clean. (Second variant.)
2113   */   */
2114  void arm_combine_netbsd_cacheclean2(struct cpu *cpu,  void COMBINE(netbsd_cacheclean2)(struct cpu *cpu,
2115          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2116  {  {
2117          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)
# Line 2093  void arm_combine_netbsd_cacheclean2(stru Line 2125  void arm_combine_netbsd_cacheclean2(stru
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  }  }
2131    
2132    
2133  /*  /*
2134   *  arm_combine_netbsd_scanc():   *  Combine: netbsd_scanc():
2135   */   */
2136  void arm_combine_netbsd_scanc(struct cpu *cpu,  void COMBINE(netbsd_scanc)(struct cpu *cpu,
2137          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2138  {  {
2139          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)
# Line 2120  void arm_combine_netbsd_scanc(struct cpu Line 2151  void arm_combine_netbsd_scanc(struct cpu
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    
2157    
2158  /*  /*
2159   *  arm_combine_strlen():   *  Combine: strlen():
2160   */   */
2161  void arm_combine_strlen(struct cpu *cpu,  void COMBINE(strlen)(struct cpu *cpu,
2162          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2163  {  {
2164          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)
# Line 2144  void arm_combine_strlen(struct cpu *cpu, Line 2174  void arm_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    
2180    
2181  /*  /*
2182   *  arm_combine_xchg():   *  Combine: xchg():
2183   */   */
2184  void arm_combine_xchg(struct cpu *cpu,  void COMBINE(xchg)(struct cpu *cpu,
2185          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2186  {  {
2187          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)
# Line 2170  void arm_combine_xchg(struct cpu *cpu, Line 2199  void arm_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    
2205    
2206  /*  /*
2207   *  arm_combine_netbsd_copyin():   *  Combine: netbsd_copyin():
2208   */   */
2209  void arm_combine_netbsd_copyin(struct cpu *cpu,  void COMBINE(netbsd_copyin)(struct cpu *cpu,
2210          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2211  {  {
2212  #ifdef HOST_LITTLE_ENDIAN  #ifdef HOST_LITTLE_ENDIAN
# Line 2201  void arm_combine_netbsd_copyin(struct cp Line 2229  void arm_combine_netbsd_copyin(struct cp
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  }  }
2235    
2236    
2237  /*  /*
2238   *  arm_combine_netbsd_copyout():   *  Combine: netbsd_copyout():
2239   */   */
2240  void arm_combine_netbsd_copyout(struct cpu *cpu,  void COMBINE(netbsd_copyout)(struct cpu *cpu,
2241          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2242  {  {
2243  #ifdef HOST_LITTLE_ENDIAN  #ifdef HOST_LITTLE_ENDIAN
# Line 2233  void arm_combine_netbsd_copyout(struct c Line 2260  void arm_combine_netbsd_copyout(struct c
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  }  }
2266    
2267    
2268  /*  /*
2269   *  arm_combine_cmps_b():   *  Combine: cmps_b():
2270   */   */
2271  void arm_combine_cmps_b(struct cpu *cpu,  void COMBINE(cmps_b)(struct cpu *cpu,
2272          struct arm_instr_call *ic, int low_addr)          struct arm_instr_call *ic, int low_addr)
2273  {  {
2274          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)          int n_back = (low_addr >> ARM_INSTR_ALIGNMENT_SHIFT)
# Line 2257  void arm_combine_cmps_b(struct cpu *cpu, Line 2283  void arm_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 2267  void arm_combine_cmps_b(struct cpu *cpu, Line 2292  void arm_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 2286  void arm_combine_cmps_b(struct cpu *cpu, Line 2308  void arm_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 2584  X(to_be_translated) Line 2597  X(to_be_translated)
2597                          goto bad;                          goto bad;
2598                  }                  }
2599                  if ((iword & 0x0ff0f090) == 0x01600080) {                  if ((iword & 0x0ff0f090) == 0x01600080) {
2600                          /*  TODO: smulXY  */                          /*  smulXY (16-bit * 16-bit => 32-bit)  */
2601                          goto bad;                          switch (iword & 0x60) {
2602                            case 0x00: ic->f = cond_instr(smulbb); break;
2603                            case 0x20: ic->f = cond_instr(smultb); break;
2604                            case 0x40: ic->f = cond_instr(smulbt); break;
2605                            default:   ic->f = cond_instr(smultt); break;
2606                            }
2607                            ic->arg[0] = (size_t)(&cpu->cd.arm.r[rm]);
2608                            ic->arg[1] = (size_t)(&cpu->cd.arm.r[r8]);
2609                            ic->arg[2] = (size_t)(&cpu->cd.arm.r[rn]); /*  Rd  */
2610                            break;
2611                  }                  }
2612                  if ((iword & 0x0ff0f0b0) == 0x012000a0) {                  if ((iword & 0x0ff0f0b0) == 0x012000a0) {
2613                          /*  TODO: smulwY  */                          /*  TODO: smulwY  */
# Line 2595  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 2767  X(to_be_translated) Line 2789  X(to_be_translated)
2789                              (any_pc_reg? 512 : 0) + (regform? 1024 : 0)];                              (any_pc_reg? 512 : 0) + (regform? 1024 : 0)];
2790    
2791                  if (ic->f == instr(eor_regshort))                  if (ic->f == instr(eor_regshort))
2792                          cpu->cd.arm.combination_check = arm_combine_xchg;                          cpu->cd.arm.combination_check = COMBINE(xchg);
2793                  if (iword == 0xe113000c)                  if (iword == 0xe113000c)
2794                          cpu->cd.arm.combination_check =                          cpu->cd.arm.combination_check = COMBINE(netbsd_scanc);
                             arm_combine_netbsd_scanc;  
2795                  break;                  break;
2796    
2797          case 0x4:       /*  Load and store...  */          case 0x4:       /*  Load and store...  */
# Line 2842  X(to_be_translated) Line 2863  X(to_be_translated)
2863                          }                          }
2864                  }                  }
2865                  if (iword == 0xe4b09004)                  if (iword == 0xe4b09004)
2866                          cpu->cd.arm.combination_check =                          cpu->cd.arm.combination_check = COMBINE(netbsd_copyin);
                             arm_combine_netbsd_copyin;  
2867                  if (iword == 0xe4a17004)                  if (iword == 0xe4a17004)
2868                          cpu->cd.arm.combination_check =                          cpu->cd.arm.combination_check = COMBINE(netbsd_copyout);
                             arm_combine_netbsd_copyout;  
2869                  break;                  break;
2870    
2871          case 0x8:       /*  Multiple load/store...  (Block data transfer)  */          case 0x8:       /*  Multiple load/store...  (Block data transfer)  */
# Line 2899  X(to_be_translated) Line 2918  X(to_be_translated)
2918                          samepage_function = cond_instr(b_samepage);                          samepage_function = cond_instr(b_samepage);
2919                          if (iword == 0xcaffffed)                          if (iword == 0xcaffffed)
2920                                  cpu->cd.arm.combination_check =                                  cpu->cd.arm.combination_check =
2921                                      arm_combine_netbsd_memset;                                      COMBINE(netbsd_memset);
2922                          if (iword == 0xaafffff9)                          if (iword == 0xaafffff9)
2923                                  cpu->cd.arm.combination_check =                                  cpu->cd.arm.combination_check =
2924                                      arm_combine_netbsd_memcpy;                                      COMBINE(netbsd_memcpy);
2925                  } else {                  } else {
2926                          if (cpu->machine->show_trace_tree) {                          if (cpu->machine->show_trace_tree) {
2927                                  ic->f = cond_instr(bl_trace);                                  ic->f = cond_instr(bl_trace);
# Line 2961  X(to_be_translated) Line 2980  X(to_be_translated)
2980                  if (main_opcode == 0xa && (condition_code <= 1                  if (main_opcode == 0xa && (condition_code <= 1
2981                      || condition_code == 3 || condition_code == 8                      || condition_code == 3 || condition_code == 8
2982                      || condition_code == 12 || condition_code == 13))                      || condition_code == 12 || condition_code == 13))
2983                          cpu->cd.arm.combination_check = arm_combine_cmps_b;                          cpu->cd.arm.combination_check = COMBINE(cmps_b);
2984    
2985                  if (iword == 0x1afffffc)                  if (iword == 0x1afffffc)
2986                          cpu->cd.arm.combination_check = arm_combine_strlen;                          cpu->cd.arm.combination_check = COMBINE(strlen);
2987    
2988                  /*  Hm. Does this really increase performance?  */                  /*  Hm. Does this really increase performance?  */
2989                  if (iword == 0x8afffffa)                  if (iword == 0x8afffffa)
2990                          cpu->cd.arm.combination_check =                          cpu->cd.arm.combination_check =
2991                              arm_combine_netbsd_cacheclean2;                              COMBINE(netbsd_cacheclean2);
2992                  break;                  break;
2993    
2994          case 0xc:          case 0xc:
# Line 2978  X(to_be_translated) Line 2997  X(to_be_translated)
2997                   *  xxxx1100 0100nnnn ddddcccc oooommmm    MCRR c,op,Rd,Rn,CRm                   *  xxxx1100 0100nnnn ddddcccc oooommmm    MCRR c,op,Rd,Rn,CRm
2998                   *  xxxx1100 0101nnnn ddddcccc oooommmm    MRRC c,op,Rd,Rn,CRm                   *  xxxx1100 0101nnnn ddddcccc oooommmm    MRRC c,op,Rd,Rn,CRm
2999                   */                   */
3000                    if ((iword & 0x0fe00fff) == 0x0c400000) {
3001                            /*  Special case: mar/mra DSP instructions  */
3002                            fatal("TODO: mar/mra DSP instructions!\n");
3003                            /*  Perhaps these are actually identical to MCRR/MRRC */
3004                            goto bad;
3005                    }
3006    
3007                  if ((iword & 0x0fe00000) == 0x0c400000) {                  if ((iword & 0x0fe00000) == 0x0c400000) {
3008                          fatal("MCRR/MRRC: TODO\n");                          fatal("MCRR/MRRC: TODO\n");
3009                          goto bad;                          goto bad;
# Line 2989  X(to_be_translated) Line 3015  X(to_be_translated)
3015                   *  For now, treat as Undefined instructions. This causes e.g.                   *  For now, treat as Undefined instructions. This causes e.g.
3016                   *  Linux/ARM to emulate these instructions (floating point).                   *  Linux/ARM to emulate these instructions (floating point).
3017                   */                   */
3018    #if 0
3019                  ic->f = cond_instr(und);                  ic->f = cond_instr(und);
3020                  ic->arg[0] = addr & 0xfff;                  ic->arg[0] = addr & 0xfff;
3021    #else
3022                    fatal("LDC/STC: TODO\n");
3023                    goto bad;
3024    #endif
3025                  break;                  break;
3026    
3027          case 0xe:          case 0xe:
3028                    if ((iword & 0x0ff00ff0) == 0x0e200010) {
3029                            /*  Special case: mia* DSP instructions  */
3030                            /*  See Intel's 27343601.pdf, page 16-20  */
3031                            fatal("TODO: mia* DSP instructions!\n");
3032                            goto bad;
3033                    }
3034                  if (iword & 0x10) {                  if (iword & 0x10) {
3035                          /*  xxxx1110 oooLNNNN ddddpppp qqq1MMMM  MCR/MRC  */                          /*  xxxx1110 oooLNNNN ddddpppp qqq1MMMM  MCR/MRC  */
3036                          ic->arg[0] = iword;                          ic->arg[0] = iword;
# Line 3005  X(to_be_translated) Line 3042  X(to_be_translated)
3042                  }                  }
3043                  if (iword == 0xee070f9a)                  if (iword == 0xee070f9a)
3044                          cpu->cd.arm.combination_check =                          cpu->cd.arm.combination_check =
3045                              arm_combine_netbsd_cacheclean;                              COMBINE(netbsd_cacheclean);
3046                  break;                  break;
3047    
3048          case 0xf:          case 0xf:

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

  ViewVC Help
Powered by ViewVC 1.1.26