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

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

revision 34 by dpavlin, Mon Oct 8 16:21:17 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_sh_instr.c,v 1.49 2007/01/28 16:59:06 debug Exp $   *  $Id: cpu_sh_instr.c,v 1.61 2007/06/04 06:32:25 debug Exp $
29   *   *
30   *  SH instructions.   *  SH instructions.
31   *   *
# Line 173  X(exts_b_rm_rn) { reg(ic->arg[1]) = (int Line 173  X(exts_b_rm_rn) { reg(ic->arg[1]) = (int
173  X(extu_b_rm_rn) { reg(ic->arg[1]) = (uint8_t)reg(ic->arg[0]); }  X(extu_b_rm_rn) { reg(ic->arg[1]) = (uint8_t)reg(ic->arg[0]); }
174  X(exts_w_rm_rn) { reg(ic->arg[1]) = (int16_t)reg(ic->arg[0]); }  X(exts_w_rm_rn) { reg(ic->arg[1]) = (int16_t)reg(ic->arg[0]); }
175  X(extu_w_rm_rn) { reg(ic->arg[1]) = (uint16_t)reg(ic->arg[0]); }  X(extu_w_rm_rn) { reg(ic->arg[1]) = (uint16_t)reg(ic->arg[0]); }
176    /*  Note: rm and rn are the same on these:  */
177    X(extu_b_rm)    { reg(ic->arg[1]) = (uint8_t)reg(ic->arg[1]); }
178    X(extu_w_rm)    { reg(ic->arg[1]) = (uint16_t)reg(ic->arg[1]); }
179    
180    
181  /*  /*
# Line 280  X(and_b_imm_r0_gbr) Line 283  X(and_b_imm_r0_gbr)
283   *  arg[0] = int8_t imm, extended to at least int32_t   *  arg[0] = int8_t imm, extended to at least int32_t
284   *  arg[1] = ptr to rn   *  arg[1] = ptr to rn
285   */   */
286  X(mov_imm_rn) { reg(ic->arg[1]) = (int32_t)ic->arg[0]; }  X(mov_imm_rn) { reg(ic->arg[1]) = ic->arg[0]; }
287  X(add_imm_rn) { reg(ic->arg[1]) += (int32_t)ic->arg[0]; }  X(mov_0_rn)   { reg(ic->arg[1]) = 0; }
288    X(add_imm_rn) { reg(ic->arg[1]) += ic->arg[0]; }
289    X(inc_rn)     { reg(ic->arg[1]) ++; }
290    X(add_4_rn)   { reg(ic->arg[1]) += 4; }
291    X(sub_4_rn)   { reg(ic->arg[1]) -= 4; }
292    X(dec_rn)     { reg(ic->arg[1]) --; }
293    
294    
295  /*  /*
296   *  mov_b_rm_predec_rn:  mov.b reg,@-Rn   *  mov_b_rm_predec_rn:     mov.b reg,@-Rn
297   *  mov_w_rm_predec_rn:  mov.w reg,@-Rn   *  mov_w_rm_predec_rn:     mov.w reg,@-Rn
298   *  mov_l_rm_predec_rn:  mov.l reg,@-Rn   *  mov_l_rm_predec_rn:     mov.l reg,@-Rn
299   *  stc_l_rm_predec_rn:  mov.l reg,@-Rn, with MD status bit check   *  stc_l_rm_predec_rn_md:  mov.l reg,@-Rn, with MD status bit check
300   *   *
301   *  arg[0] = ptr to rm  (or other register)   *  arg[0] = ptr to rm  (or other register)
302   *  arg[1] = ptr to rn   *  arg[1] = ptr to rn
# Line 362  X(mov_l_rm_predec_rn) Line 370  X(mov_l_rm_predec_rn)
370                  reg(ic->arg[1]) = addr;                  reg(ic->arg[1]) = addr;
371          }          }
372  }  }
373  X(stc_l_rm_predec_rn)  X(stc_l_rm_predec_rn_md)
374  {  {
375          uint32_t addr = reg(ic->arg[1]) - sizeof(uint32_t);          uint32_t addr = reg(ic->arg[1]) - sizeof(uint32_t);
376          uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];          uint32_t *p = (uint32_t *) cpu->cd.sh.host_store[addr >> 12];
# Line 818  X(mov_l_arg1_postinc_to_arg0_md) Line 826  X(mov_l_arg1_postinc_to_arg0_md)
826          else          else
827                  data = BE32_TO_HOST(data);                  data = BE32_TO_HOST(data);
828          reg(ic->arg[1]) = addr + sizeof(data);          reg(ic->arg[1]) = addr + sizeof(data);
829          reg(ic->arg[0]) = data;  
830            /*  Special case when loading into the SR register:  */
831            if (ic->arg[0] == (size_t)&cpu->cd.sh.sr)
832                    sh_update_sr(cpu, data);
833            else
834                    reg(ic->arg[0]) = data;
835  }  }
836  X(mov_l_arg1_postinc_to_arg0_fp)  X(mov_l_arg1_postinc_to_arg0_fp)
837  {  {
# Line 845  X(mov_l_arg1_postinc_to_arg0_fp) Line 858  X(mov_l_arg1_postinc_to_arg0_fp)
858                  data = BE32_TO_HOST(data);                  data = BE32_TO_HOST(data);
859          reg(ic->arg[1]) = addr + sizeof(data);          reg(ic->arg[1]) = addr + sizeof(data);
860    
861          if (ic->arg[0] == (size_t)cpu->cd.sh.fpscr)          /*  Ugly special case for FPSCR:  */
862            if (ic->arg[0] == (size_t)&cpu->cd.sh.fpscr)
863                  sh_update_fpscr(cpu, data);                  sh_update_fpscr(cpu, data);
864          else          else
865                  reg(ic->arg[0]) = data;                  reg(ic->arg[0]) = data;
# Line 1365  X(mov_w_r0_disp_rn) Line 1379  X(mov_w_r0_disp_rn)
1379   *  sub_rm_rn:  rn = rn - rm   *  sub_rm_rn:  rn = rn - rm
1380   *  subc_rm_rn: rn = rn - rm - t; t = borrow   *  subc_rm_rn: rn = rn - rm - t; t = borrow
1381   *  tst_rm_rn:  t = ((rm & rn) == 0)   *  tst_rm_rn:  t = ((rm & rn) == 0)
1382     *  tst_rm:     t = (rm == 0)
1383   *  xtrct_rm_rn:  rn = (rn >> 16) | (rm << 16)   *  xtrct_rm_rn:  rn = (rn >> 16) | (rm << 16)
1384   *   *
1385   *  arg[0] = ptr to rm   *  arg[0] = ptr to rm
# Line 1406  X(tst_rm_rn) Line 1421  X(tst_rm_rn)
1421          else          else
1422                  cpu->cd.sh.sr |= SH_SR_T;                  cpu->cd.sh.sr |= SH_SR_T;
1423  }  }
1424    X(tst_rm)
1425    {
1426            if (reg(ic->arg[0]))
1427                    cpu->cd.sh.sr &= ~SH_SR_T;
1428            else
1429                    cpu->cd.sh.sr |= SH_SR_T;
1430    }
1431  X(xtrct_rm_rn)  X(xtrct_rm_rn)
1432  {  {
1433          uint32_t rn = reg(ic->arg[1]), rm = reg(ic->arg[0]);          uint32_t rn = reg(ic->arg[1]), rm = reg(ic->arg[0]);
# Line 1427  X(div0u) Line 1449  X(div0u)
1449  }  }
1450  X(div0s_rm_rn)  X(div0s_rm_rn)
1451  {  {
1452          int q = reg(ic->arg[1]) >> 31, m = reg(ic->arg[0]) >> 31;          int q = reg(ic->arg[1]) & 0x80000000;
1453          cpu->cd.sh.sr &= ~(SH_SR_Q | SH_SR_M | SH_SR_T);          int m = reg(ic->arg[0]) & 0x80000000;
1454            uint32_t new_sr = cpu->cd.sh.sr & ~(SH_SR_Q | SH_SR_M | SH_SR_T);
1455          if (q)          if (q)
1456                  cpu->cd.sh.sr |= SH_SR_Q;                  new_sr |= SH_SR_Q;
1457          if (m)          if (m)
1458                  cpu->cd.sh.sr |= SH_SR_M;                  new_sr |= SH_SR_M;
1459          if (m ^ q)          if (m ^ q)
1460                  cpu->cd.sh.sr |= SH_SR_T;                  new_sr |= SH_SR_T;
1461            cpu->cd.sh.sr = new_sr;
1462  }  }
1463  X(div1_rm_rn)  X(div1_rm_rn)
1464  {  {
# Line 1607  X(cmp_str_rm_rn) Line 1631  X(cmp_str_rm_rn)
1631  X(shll_rn)  X(shll_rn)
1632  {  {
1633          uint32_t rn = reg(ic->arg[1]);          uint32_t rn = reg(ic->arg[1]);
1634          if (rn >> 31)          if (rn & 0x80000000)
1635                  cpu->cd.sh.sr |= SH_SR_T;                  cpu->cd.sh.sr |= SH_SR_T;
1636          else          else
1637                  cpu->cd.sh.sr &= ~SH_SR_T;                  cpu->cd.sh.sr &= ~SH_SR_T;
# Line 1624  X(shlr_rn) Line 1648  X(shlr_rn)
1648  }  }
1649  X(rotl_rn)  X(rotl_rn)
1650  {  {
1651          uint32_t rn = reg(ic->arg[1]);          uint32_t rn = reg(ic->arg[1]), x;
1652          if (rn >> 31)          if (rn & 0x80000000) {
1653                    x = 1;
1654                  cpu->cd.sh.sr |= SH_SR_T;                  cpu->cd.sh.sr |= SH_SR_T;
1655          else          } else {
1656                    x = 0;
1657                  cpu->cd.sh.sr &= ~SH_SR_T;                  cpu->cd.sh.sr &= ~SH_SR_T;
1658          reg(ic->arg[1]) = (rn << 1) | (rn >> 31);          }
1659            reg(ic->arg[1]) = (rn << 1) | x;
1660  }  }
1661  X(rotr_rn)  X(rotr_rn)
1662  {  {
# Line 1739  X(shld) Line 1766  X(shld)
1766   *  braf:  Like bra, but using a register instead of an immediate   *  braf:  Like bra, but using a register instead of an immediate
1767   *  bsrf:  Like braf, but also sets PR to the return address   *  bsrf:  Like braf, but also sets PR to the return address
1768   *   *
1769   *  arg[0] = immediate offset relative to start of page   *  arg[0] = immediate offset relative to start of page,
1770     *           or ptr to target instruction, for samepage branches
1771   *  arg[1] = ptr to Rn  (for braf/bsrf)   *  arg[1] = ptr to Rn  (for braf/bsrf)
1772   */   */
1773  X(bra)  X(bra)
# Line 1757  X(bra) Line 1785  X(bra)
1785          } else          } else
1786                  cpu->delay_slot = NOT_DELAYED;                  cpu->delay_slot = NOT_DELAYED;
1787  }  }
1788    X(bra_samepage)
1789    {
1790            cpu->delay_slot = TO_BE_DELAYED;
1791            ic[1].f(cpu, ic+1);
1792            cpu->n_translated_instrs ++;
1793            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))
1794                    cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[0];
1795            cpu->delay_slot = NOT_DELAYED;
1796    }
1797  X(bsr)  X(bsr)
1798  {  {
1799          MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<          MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
# Line 1776  X(bsr) Line 1813  X(bsr)
1813          } else          } else
1814                  cpu->delay_slot = NOT_DELAYED;                  cpu->delay_slot = NOT_DELAYED;
1815  }  }
1816    X(bsr_samepage)
1817    {
1818            uint32_t old_pc;
1819            SYNCH_PC;
1820            old_pc = cpu->pc;
1821            cpu->delay_slot = TO_BE_DELAYED;
1822            ic[1].f(cpu, ic+1);
1823            cpu->n_translated_instrs ++;
1824            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1825                    cpu->cd.sh.pr = old_pc + 4;
1826                    cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[0];
1827            }
1828            cpu->delay_slot = NOT_DELAYED;
1829    }
1830  X(braf_rn)  X(braf_rn)
1831  {  {
1832          MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<          MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
# Line 1819  X(bsrf_rn) Line 1870  X(bsrf_rn)
1870   *  bf/s: Branch if false (with delay-slot)   *  bf/s: Branch if false (with delay-slot)
1871   *   *
1872   *  arg[0] = immediate offset relative to start of page   *  arg[0] = immediate offset relative to start of page
1873     *  arg[1] = for samepage functions, the new instruction pointer
1874   */   */
1875  X(bt)  X(bt)
1876  {  {
# Line 1838  X(bf) Line 1890  X(bf)
1890                  quick_pc_to_pointers(cpu);                  quick_pc_to_pointers(cpu);
1891          }          }
1892  }  }
1893    X(bt_samepage)
1894    {
1895            if (cpu->cd.sh.sr & SH_SR_T)
1896                    cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[1];
1897    }
1898    X(bf_samepage)
1899    {
1900            if (!(cpu->cd.sh.sr & SH_SR_T))
1901                    cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[1];
1902    }
1903  X(bt_s)  X(bt_s)
1904  {  {
1905          MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<          MODE_int_t target = cpu->pc & ~((SH_IC_ENTRIES_PER_PAGE-1) <<
# Line 1876  X(bf_s) Line 1938  X(bf_s)
1938          } else          } else
1939                  cpu->delay_slot = NOT_DELAYED;                  cpu->delay_slot = NOT_DELAYED;
1940  }  }
1941    X(bt_s_samepage)
1942    {
1943            int cond = cpu->cd.sh.sr & SH_SR_T;
1944            cpu->delay_slot = TO_BE_DELAYED;
1945            ic[1].f(cpu, ic+1);
1946            cpu->n_translated_instrs ++;
1947            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1948                    cpu->delay_slot = NOT_DELAYED;
1949                    if (cond)
1950                            cpu->cd.sh.next_ic =
1951                                (struct sh_instr_call *) ic->arg[1];
1952                    else
1953                            cpu->cd.sh.next_ic ++;
1954            } else
1955                    cpu->delay_slot = NOT_DELAYED;
1956    }
1957    X(bf_s_samepage)
1958    {
1959            int cond = !(cpu->cd.sh.sr & SH_SR_T);
1960            cpu->delay_slot = TO_BE_DELAYED;
1961            ic[1].f(cpu, ic+1);
1962            cpu->n_translated_instrs ++;
1963            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1964                    cpu->delay_slot = NOT_DELAYED;
1965                    if (cond)
1966                            cpu->cd.sh.next_ic =
1967                                (struct sh_instr_call *) ic->arg[1];
1968                    else
1969                            cpu->cd.sh.next_ic ++;
1970            } else
1971                    cpu->delay_slot = NOT_DELAYED;
1972    }
1973    
1974    
1975  /*  /*
# Line 1984  X(rts_trace) Line 2078  X(rts_trace)
2078    
2079    
2080  /*  /*
  *  sts_mach_rn: Store MACH into Rn  
  *  sts_macl_rn: Store MACL into Rn  
  *  sts_pr_rn:   Store PR into Rn  
  *  
  *  arg[1] = ptr to rn  
  */  
 X(sts_mach_rn) { reg(ic->arg[1]) = cpu->cd.sh.mach; }  
 X(sts_macl_rn) { reg(ic->arg[1]) = cpu->cd.sh.macl; }  
 X(sts_pr_rn)   { reg(ic->arg[1]) = cpu->cd.sh.pr; }  
   
   
 /*  
2081   *  rte:  Return from exception.   *  rte:  Return from exception.
2082   */   */
2083  X(rte)  X(rte)
# Line 2040  X(ldtlb) Line 2122  X(ldtlb)
2122                              old_hi & 0xfffff000, INVALIDATE_VADDR);                              old_hi & 0xfffff000, INVALIDATE_VADDR);
2123                  else                  else
2124                          cpu->invalidate_translation_caches(cpu,                          cpu->invalidate_translation_caches(cpu,
2125                              old_hi & 0xfffff000, INVALIDATE_ALL);                              0, INVALIDATE_ALL);
2126          }          }
2127  }  }
2128    
# Line 2068  X(ldc_rm_sr) Line 2150  X(ldc_rm_sr)
2150  {  {
2151          RES_INST_IF_NOT_MD;          RES_INST_IF_NOT_MD;
2152          sh_update_sr(cpu, reg(ic->arg[1]));          sh_update_sr(cpu, reg(ic->arg[1]));
2153    
2154    #if 0
2155    /*  NOTE: This code causes NetBSD/landisk to get past a point where it
2156        otherwise hangs, but it causes Linux/Dreamcast to bug out instead. :/  */
2157    
2158            if (!(cpu->cd.sh.sr & SH_SR_BL) && cpu->cd.sh.int_to_assert > 0 &&
2159                ( (cpu->cd.sh.sr & SH_SR_IMASK) >> SH_SR_IMASK_SHIFT)
2160                < cpu->cd.sh.int_level) {
2161                    /*  Cause interrupt immediately, by dropping out of the
2162                        main dyntrans loop:  */
2163                    cpu->cd.sh.next_ic = &nothing_call;
2164            }
2165    #endif
2166  }  }
2167    
2168    
# Line 2192  X(ftrc_frm_fpul) Line 2287  X(ftrc_frm_fpul)
2287    
2288    
2289  /*  /*
2290     *  fcnvsd_fpul_drn:  Convert single-precision to double-precision.
2291     *  fcnvds_drm_fpul:  Convert double-precision to single-precision.
2292     *
2293     *  arg[0] = ptr to destination (double- or single-precision float)
2294     */
2295    X(fcnvsd_fpul_drn)
2296    {
2297            struct ieee_float_value op1;
2298            int64_t ieee;
2299    
2300            FLOATING_POINT_AVAILABLE_CHECK;
2301    
2302            ieee_interpret_float_value(cpu->cd.sh.fpul, &op1, IEEE_FMT_S);
2303            cpu->cd.sh.fpul = (int32_t) op1.f;
2304    
2305            /*  Store double-precision result:  */
2306            ieee = ieee_store_float_value(op1.f, IEEE_FMT_D, 0);
2307            reg(ic->arg[0]) = (uint32_t) (ieee >> 32);
2308            reg(ic->arg[0] + sizeof(uint32_t)) = (uint32_t) ieee;
2309    }
2310    X(fcnvds_drm_fpul)
2311    {
2312            struct ieee_float_value op1;
2313            int64_t r1;
2314    
2315            FLOATING_POINT_AVAILABLE_CHECK;
2316    
2317            r1 = reg(ic->arg[0] + sizeof(uint32_t)) +
2318                ((uint64_t)reg(ic->arg[0]) << 32);
2319            ieee_interpret_float_value(r1, &op1, IEEE_FMT_D);
2320    
2321            cpu->cd.sh.fpul = ieee_store_float_value(op1.f, IEEE_FMT_S, 0);
2322    }
2323    
2324    
2325    /*
2326   *  fsca_fpul_drn:  Sinus/cosinus approximation.   *  fsca_fpul_drn:  Sinus/cosinus approximation.
2327   *   *
2328   *  Note: This is an interesting instruction. It is not included in the SH4   *  Note: This is an interesting instruction. It is not included in the SH4
# Line 2632  X(tas_b_rn) Line 2763  X(tas_b_rn)
2763    
2764    
2765  /*  /*
2766   *  prom_emul_dreamcast:   *  prom_emul:
2767   */   */
2768  X(prom_emul_dreamcast)  X(prom_emul)
2769  {  {
2770          uint32_t old_pc;          uint32_t old_pc;
2771          SYNCH_PC;          SYNCH_PC;
2772          old_pc = cpu->pc;          old_pc = cpu->pc;
2773    
2774          dreamcast_emul(cpu);          switch (cpu->machine->machine_type) {
2775            case MACHINE_DREAMCAST:
2776                    dreamcast_emul(cpu);
2777                    break;
2778            case MACHINE_LANDISK:
2779                    sh_ipl_g_emul(cpu);
2780                    break;
2781            default:
2782                    fatal("SH prom_emul: unimplemented machine type.\n");
2783                    exit(1);
2784            }
2785    
2786          if (!cpu->running) {          if (!cpu->running) {
2787                  cpu->n_translated_instrs --;                  cpu->n_translated_instrs --;
# Line 2742  X(to_be_translated) Line 2883  X(to_be_translated)
2883          uint64_t addr, low_pc;          uint64_t addr, low_pc;
2884          uint32_t iword;          uint32_t iword;
2885          unsigned char *page;          unsigned char *page;
2886          unsigned char ib[4];          unsigned char ib[2];
2887          int main_opcode, isize = cpu->cd.sh.compact? 2 : sizeof(ib);          int main_opcode, isize = sizeof(ib);
2888          int in_crosspage_delayslot = 0, r8, r4, lo4, lo8;          int in_crosspage_delayslot = 0, r8, r4, lo4, lo8;
2889          /*  void (*samepage_function)(struct cpu *, struct sh_instr_call *);  */          void (*samepage_function)(struct cpu *, struct sh_instr_call *);
2890    
2891          /*  Figure out the (virtual) address of the instruction:  */          /*  Figure out the (virtual) address of the instruction:  */
2892          low_pc = ((size_t)ic - (size_t)cpu->cd.sh.cur_ic_page)          low_pc = ((size_t)ic - (size_t)cpu->cd.sh.cur_ic_page)
# Line 2794  X(to_be_translated) Line 2935  X(to_be_translated)
2935                  }                  }
2936          }          }
2937    
2938          if (cpu->cd.sh.compact) {          iword = *((uint16_t *)&ib[0]);
2939                  iword = *((uint16_t *)&ib[0]);          if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
2940                  if (cpu->byte_order == EMUL_LITTLE_ENDIAN)                  iword = LE16_TO_HOST(iword);
2941                          iword = LE16_TO_HOST(iword);          else
2942                  else                  iword = BE16_TO_HOST(iword);
2943                          iword = BE16_TO_HOST(iword);          main_opcode = iword >> 12;
2944                  main_opcode = iword >> 12;          r8 = (iword >> 8) & 0xf;
2945                  r8 = (iword >> 8) & 0xf;          r4 = (iword >> 4) & 0xf;
2946                  r4 = (iword >> 4) & 0xf;          lo8 = iword & 0xff;
2947                  lo8 = iword & 0xff;          lo4 = iword & 0xf;
                 lo4 = iword & 0xf;  
         } else {  
                 iword = *((uint32_t *)&ib[0]);  
                 if (cpu->byte_order == EMUL_LITTLE_ENDIAN)  
                         iword = LE32_TO_HOST(iword);  
                 else  
                         iword = BE32_TO_HOST(iword);  
                 main_opcode = -1;       /*  TODO  */  
                 fatal("SH5/SH64 isn't implemented yet. Sorry.\n");  
                 goto bad;  
         }  
2948    
2949    
2950  #define DYNTRANS_TO_BE_TRANSLATED_HEAD  #define DYNTRANS_TO_BE_TRANSLATED_HEAD
# Line 2891  X(to_be_translated) Line 3021  X(to_be_translated)
3021                          ic->f = instr(copy_privileged_register);                          ic->f = instr(copy_privileged_register);
3022                          ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[(lo8 >> 4) & 7];                          ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[(lo8 >> 4) & 7];
3023                  } else if (iword == SH_INVALID_INSTR) {                  } else if (iword == SH_INVALID_INSTR) {
3024                          /*  PROM emulation specifically for Dreamcast  */                          /*  PROM emulation (GXemul specific)  */
3025                          ic->f = instr(prom_emul_dreamcast);                          ic->f = instr(prom_emul);
3026                  } else {                  } else {
3027                          switch (lo8) {                          switch (lo8) {
3028                          case 0x02:      /*  STC SR,Rn  */                          case 0x02:      /*  STC SR,Rn  */
# Line 2909  X(to_be_translated) Line 3039  X(to_be_translated)
3039                          case 0x09:      /*  NOP  */                          case 0x09:      /*  NOP  */
3040                                  ic->f = instr(nop);                                  ic->f = instr(nop);
3041                                  if (iword & 0x0f00) {                                  if (iword & 0x0f00) {
3042                                          fatal("Unimplemented NOP variant?\n");                                          if (!cpu->translation_readahead)
3043                                                    fatal("Unimplemented NOP"
3044                                                        " variant?\n");
3045                                          goto bad;                                          goto bad;
3046                                  }                                  }
3047                                  break;                                  break;
3048                          case 0x0a:      /*  STS MACH,Rn  */                          case 0x0a:      /*  STS MACH,Rn  */
3049                                  ic->f = instr(sts_mach_rn);                                  ic->f = instr(mov_rm_rn);
3050                                    ic->arg[0] = (size_t)&cpu->cd.sh.mach;
3051                                  break;                                  break;
3052                          case 0x12:      /*  STC GBR,Rn  */                          case 0x12:      /*  STC GBR,Rn  */
3053                                  ic->f = instr(mov_rm_rn);                                  ic->f = instr(mov_rm_rn);
3054                                  ic->arg[0] = (size_t)&cpu->cd.sh.gbr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.gbr;
3055                                  break;                                  break;
3056                          case 0x1a:      /*  STS MACL,Rn  */                          case 0x1a:      /*  STS MACL,Rn  */
3057                                  ic->f = instr(sts_macl_rn);                                  ic->f = instr(mov_rm_rn);
3058                                    ic->arg[0] = (size_t)&cpu->cd.sh.macl;
3059                                  break;                                  break;
3060                          case 0x22:      /*  STC VBR,Rn  */                          case 0x22:      /*  STC VBR,Rn  */
3061                                  ic->f = instr(copy_privileged_register);                                  ic->f = instr(copy_privileged_register);
# Line 2938  X(to_be_translated) Line 3072  X(to_be_translated)
3072                                  ic->f = instr(movt_rn);                                  ic->f = instr(movt_rn);
3073                                  break;                                  break;
3074                          case 0x2a:      /*  STS PR,Rn  */                          case 0x2a:      /*  STS PR,Rn  */
3075                                  ic->f = instr(sts_pr_rn);                                  ic->f = instr(mov_rm_rn);
3076                                    ic->arg[0] = (size_t)&cpu->cd.sh.pr;
3077                                  break;                                  break;
3078                          case 0x32:      /*  STC SSR,Rn  */                          case 0x32:      /*  STC SSR,Rn  */
3079                                  ic->f = instr(copy_privileged_register);                                  ic->f = instr(copy_privileged_register);
# Line 2986  X(to_be_translated) Line 3121  X(to_be_translated)
3121                                  ic->arg[0] = (size_t)&cpu->cd.sh.dbr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.dbr;
3122                                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];                                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];
3123                                  break;                                  break;
3124                          default:fatal("Unimplemented opcode 0x%x,0x%03x\n",                          default:if (!cpu->translation_readahead)
3125                                      main_opcode, iword & 0xfff);                                          fatal("Unimplemented opcode 0x%x,"
3126                                                "0x%03x\n", main_opcode,
3127                                                iword & 0xfff);
3128                                  goto bad;                                  goto bad;
3129                          }                          }
3130                  }                  }
# Line 3023  X(to_be_translated) Line 3160  X(to_be_translated)
3160                          break;                          break;
3161                  case 0x8:       /*  TST Rm,Rn  */                  case 0x8:       /*  TST Rm,Rn  */
3162                          ic->f = instr(tst_rm_rn);                          ic->f = instr(tst_rm_rn);
3163                            if (r8 == r4)
3164                                    ic->f = instr(tst_rm);
3165                          break;                          break;
3166                  case 0x9:       /*  AND Rm,Rn  */                  case 0x9:       /*  AND Rm,Rn  */
3167                          ic->f = instr(and_rm_rn);                          ic->f = instr(and_rm_rn);
# Line 3045  X(to_be_translated) Line 3184  X(to_be_translated)
3184                  case 0xf:       /*  MULS.W Rm,Rn  */                  case 0xf:       /*  MULS.W Rm,Rn  */
3185                          ic->f = instr(muls_w_rm_rn);                          ic->f = instr(muls_w_rm_rn);
3186                          break;                          break;
3187                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3188                              main_opcode, lo4);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3189                                        main_opcode, lo4);
3190                          goto bad;                          goto bad;
3191                  }                  }
3192                  break;                  break;
# Line 3089  X(to_be_translated) Line 3229  X(to_be_translated)
3229                  case 0xe:       /*  ADDC Rm,Rn  */                  case 0xe:       /*  ADDC Rm,Rn  */
3230                          ic->f = instr(addc_rm_rn);                          ic->f = instr(addc_rm_rn);
3231                          break;                          break;
3232                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3233                              main_opcode, lo4);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3234                                        main_opcode, lo4);
3235                          goto bad;                          goto bad;
3236                  }                  }
3237                  break;                  break;
# Line 3102  X(to_be_translated) Line 3243  X(to_be_translated)
3243                          ic->f = instr(shld);                          ic->f = instr(shld);
3244                  } else if ((lo8 & 0x8f) == 0x83) {                  } else if ((lo8 & 0x8f) == 0x83) {
3245                          /*  STC.L Rm_BANK,@-Rn  */                          /*  STC.L Rm_BANK,@-Rn  */
3246                          ic->f = instr(stc_l_rm_predec_rn);                          ic->f = instr(stc_l_rm_predec_rn_md);
3247                          ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[                          ic->arg[0] = (size_t)&cpu->cd.sh.r_bank[
3248                              (lo8 >> 4) & 7];    /* m */                              (lo8 >> 4) & 7];    /* m */
3249                  } else if ((lo8 & 0x8f) == 0x87) {                  } else if ((lo8 & 0x8f) == 0x87) {
# Line 3127  X(to_be_translated) Line 3268  X(to_be_translated)
3268                                  ic->arg[0] = (size_t)&cpu->cd.sh.mach;                                  ic->arg[0] = (size_t)&cpu->cd.sh.mach;
3269                                  break;                                  break;
3270                          case 0x03:      /*  STC.L SR,@-Rn  */                          case 0x03:      /*  STC.L SR,@-Rn  */
3271                                  ic->f = instr(stc_l_rm_predec_rn);                                  ic->f = instr(stc_l_rm_predec_rn_md);
3272                                  ic->arg[0] = (size_t)&cpu->cd.sh.sr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.sr;
3273                                  break;                                  break;
3274                          case 0x04:      /*  ROTL Rn  */                          case 0x04:      /*  ROTL Rn  */
# Line 3172  X(to_be_translated) Line 3313  X(to_be_translated)
3313                                  ic->arg[0] = (size_t)&cpu->cd.sh.macl;                                  ic->arg[0] = (size_t)&cpu->cd.sh.macl;
3314                                  break;                                  break;
3315                          case 0x13:      /*  STC.L GBR,@-Rn  */                          case 0x13:      /*  STC.L GBR,@-Rn  */
3316                                  ic->f = instr(stc_l_rm_predec_rn);                                  ic->f = instr(mov_l_rm_predec_rn);
3317                                  ic->arg[0] = (size_t)&cpu->cd.sh.gbr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.gbr;
3318                                  break;                                  break;
3319                          case 0x15:      /*  CMP/PL Rn  */                          case 0x15:      /*  CMP/PL Rn  */
# Line 3183  X(to_be_translated) Line 3324  X(to_be_translated)
3324                                  ic->arg[0] = (size_t)&cpu->cd.sh.macl;                                  ic->arg[0] = (size_t)&cpu->cd.sh.macl;
3325                                  break;                                  break;
3326                          case 0x17:      /*  LDC.L @Rm+,GBR  */                          case 0x17:      /*  LDC.L @Rm+,GBR  */
3327                                  ic->f = instr(mov_l_arg1_postinc_to_arg0_md);                                  ic->f = instr(mov_l_arg1_postinc_to_arg0);
3328                                  ic->arg[0] = (size_t)&cpu->cd.sh.gbr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.gbr;
3329                                  break;                                  break;
3330                          case 0x18:      /*  SHLL8 Rn  */                          case 0x18:      /*  SHLL8 Rn  */
# Line 3212  X(to_be_translated) Line 3353  X(to_be_translated)
3353                                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */                                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */
3354                                  break;                                  break;
3355                          case 0x23:      /*  STC.L VBR,@-Rn  */                          case 0x23:      /*  STC.L VBR,@-Rn  */
3356                                  ic->f = instr(stc_l_rm_predec_rn);                                  ic->f = instr(stc_l_rm_predec_rn_md);
3357                                  ic->arg[0] = (size_t)&cpu->cd.sh.vbr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.vbr;
3358                                  break;                                  break;
3359                          case 0x24:      /*  ROTCL Rn  */                          case 0x24:      /*  ROTCL Rn  */
# Line 3254  X(to_be_translated) Line 3395  X(to_be_translated)
3395                                  ic->arg[1] = (size_t)&cpu->cd.sh.vbr;                                  ic->arg[1] = (size_t)&cpu->cd.sh.vbr;
3396                                  break;                                  break;
3397                          case 0x33:      /*  STC.L SSR,@-Rn  */                          case 0x33:      /*  STC.L SSR,@-Rn  */
3398                                  ic->f = instr(stc_l_rm_predec_rn);                                  ic->f = instr(stc_l_rm_predec_rn_md);
3399                                  ic->arg[0] = (size_t)&cpu->cd.sh.ssr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.ssr;
3400                                  break;                                  break;
3401                          case 0x37:      /*  LDC.L @Rm+,SSR  */                          case 0x37:      /*  LDC.L @Rm+,SSR  */
# Line 3267  X(to_be_translated) Line 3408  X(to_be_translated)
3408                                  ic->arg[1] = (size_t)&cpu->cd.sh.ssr;                                  ic->arg[1] = (size_t)&cpu->cd.sh.ssr;
3409                                  break;                                  break;
3410                          case 0x43:      /*  STC.L SPC,@-Rn  */                          case 0x43:      /*  STC.L SPC,@-Rn  */
3411                                  ic->f = instr(stc_l_rm_predec_rn);                                  ic->f = instr(stc_l_rm_predec_rn_md);
3412                                  ic->arg[0] = (size_t)&cpu->cd.sh.spc;                                  ic->arg[0] = (size_t)&cpu->cd.sh.spc;
3413                                  break;                                  break;
3414                          case 0x47:      /*  LDC.L @Rm+,SPC  */                          case 0x47:      /*  LDC.L @Rm+,SPC  */
# Line 3299  X(to_be_translated) Line 3440  X(to_be_translated)
3440                                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */                                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */
3441                                  break;                                  break;
3442                          case 0x66:      /*  LDS.L @Rm+,FPSCR  */                          case 0x66:      /*  LDS.L @Rm+,FPSCR  */
3443                                    /*  Note: Loading into FPSCR is a specia
3444                                        case (need to call sh_update_fpsrc()).  */
3445                                  ic->f = instr(mov_l_arg1_postinc_to_arg0_fp);                                  ic->f = instr(mov_l_arg1_postinc_to_arg0_fp);
3446                                  ic->arg[0] = (size_t)&cpu->cd.sh.fpscr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.fpscr;
3447                                  break;                                  break;
# Line 3311  X(to_be_translated) Line 3454  X(to_be_translated)
3454                                  ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];                                  ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];
3455                                  ic->arg[1] = (size_t)&cpu->cd.sh.dbr;                                  ic->arg[1] = (size_t)&cpu->cd.sh.dbr;
3456                                  break;                                  break;
3457                          default:fatal("Unimplemented opcode 0x%x,0x%02x\n",                          default:if (!cpu->translation_readahead)
3458                                      main_opcode, lo8);                                          fatal("Unimplemented opcode 0x%x,"
3459                                                "0x%02x\n", main_opcode, lo8);
3460                                  goto bad;                                  goto bad;
3461                          }                          }
3462                  }                  }
# Line 3372  X(to_be_translated) Line 3516  X(to_be_translated)
3516                          break;                          break;
3517                  case 0xc:       /*  EXTU.B Rm,Rn  */                  case 0xc:       /*  EXTU.B Rm,Rn  */
3518                          ic->f = instr(extu_b_rm_rn);                          ic->f = instr(extu_b_rm_rn);
3519                            if (r8 == r4)
3520                                    ic->f = instr(extu_b_rm);
3521                          break;                          break;
3522                  case 0xd:       /*  EXTU.W Rm,Rn  */                  case 0xd:       /*  EXTU.W Rm,Rn  */
3523                          ic->f = instr(extu_w_rm_rn);                          ic->f = instr(extu_w_rm_rn);
3524                            if (r8 == r4)
3525                                    ic->f = instr(extu_w_rm);
3526                          break;                          break;
3527                  case 0xe:       /*  EXTS.B Rm,Rn  */                  case 0xe:       /*  EXTS.B Rm,Rn  */
3528                          ic->f = instr(exts_b_rm_rn);                          ic->f = instr(exts_b_rm_rn);
# Line 3382  X(to_be_translated) Line 3530  X(to_be_translated)
3530                  case 0xf:       /*  EXTS.W Rm,Rn  */                  case 0xf:       /*  EXTS.W Rm,Rn  */
3531                          ic->f = instr(exts_w_rm_rn);                          ic->f = instr(exts_w_rm_rn);
3532                          break;                          break;
3533                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3534                              main_opcode, lo4);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3535                                        main_opcode, lo4);
3536                          goto bad;                          goto bad;
3537                  }                  }
3538                  break;                  break;
# Line 3391  X(to_be_translated) Line 3540  X(to_be_translated)
3540          case 0x7:       /*  ADD #imm,Rn  */          case 0x7:       /*  ADD #imm,Rn  */
3541                  ic->f = instr(add_imm_rn);                  ic->f = instr(add_imm_rn);
3542                  ic->arg[0] = (int8_t)lo8;                  ic->arg[0] = (int8_t)lo8;
3543                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];         /* n */
3544                    if (lo8 == 1)
3545                            ic->f = instr(inc_rn);
3546                    if (lo8 == 4)
3547                            ic->f = instr(add_4_rn);
3548                    if (lo8 == 0xfc)
3549                            ic->f = instr(sub_4_rn);
3550                    if (lo8 == 0xff)
3551                            ic->f = instr(dec_rn);
3552                  break;                  break;
3553    
3554          case 0x8:          case 0x8:
# Line 3399  X(to_be_translated) Line 3556  X(to_be_translated)
3556                  ic->arg[0] = (int8_t)lo8 * 2 +                  ic->arg[0] = (int8_t)lo8 * 2 +
3557                      (addr & ((SH_IC_ENTRIES_PER_PAGE-1)                      (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3558                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;
3559                    samepage_function = NULL;
3560    
3561                  switch (r8) {                  switch (r8) {
3562                  case 0x0:       /*  MOV.B R0,@(disp,Rn)  */                  case 0x0:       /*  MOV.B R0,@(disp,Rn)  */
3563                          ic->f = instr(mov_b_r0_disp_rn);                          ic->f = instr(mov_b_r0_disp_rn);
# Line 3426  X(to_be_translated) Line 3585  X(to_be_translated)
3585                          break;                          break;
3586                  case 0x9:       /*  BT (disp,PC)  */                  case 0x9:       /*  BT (disp,PC)  */
3587                          ic->f = instr(bt);                          ic->f = instr(bt);
3588                            samepage_function = instr(bt_samepage);
3589                          break;                          break;
3590                  case 0xb:       /*  BF (disp,PC)  */                  case 0xb:       /*  BF (disp,PC)  */
3591                          ic->f = instr(bf);                          ic->f = instr(bf);
3592                            samepage_function = instr(bf_samepage);
3593                          break;                          break;
3594                  case 0xd:       /*  BT/S (disp,PC)  */                  case 0xd:       /*  BT/S (disp,PC)  */
3595                          ic->f = instr(bt_s);                          ic->f = instr(bt_s);
3596                            samepage_function = instr(bt_s_samepage);
3597                          break;                          break;
3598                  case 0xf:       /*  BF/S (disp,PC)  */                  case 0xf:       /*  BF/S (disp,PC)  */
3599                          ic->f = instr(bf_s);                          ic->f = instr(bf_s);
3600                            samepage_function = instr(bf_s_samepage);
3601                          break;                          break;
3602                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3603                              main_opcode, r8);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3604                                        main_opcode, r8);
3605                          goto bad;                          goto bad;
3606                  }                  }
3607    
3608                    /*  samepage branches:  */
3609                    if (samepage_function != NULL && ic->arg[0] < 0x1000 &&
3610                        (addr & 0xfff) < 0xffe) {
3611                            ic->arg[1] = (size_t) (cpu->cd.sh.cur_ic_page +
3612                                (ic->arg[0] >> SH_INSTR_ALIGNMENT_SHIFT));
3613                            ic->f = samepage_function;
3614                    }
3615    
3616                  break;                  break;
3617    
3618          case 0x9:       /*  MOV.W @(disp,PC),Rn  */          case 0x9:       /*  MOV.W @(disp,PC),Rn  */
3619                  ic->f = instr(mov_w_disp_pc_rn);                  ic->f = instr(mov_w_disp_pc_rn);
3620                  ic->arg[0] = lo8 * 2 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)                  ic->arg[0] = lo8 * 2 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3621                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;
3622                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */  
3623                    /*  If the word is reachable from the same page as the
3624                        current address, then optimize it as a mov_imm_rn:  */
3625                    if (ic->arg[0] < 0x1000 && page != NULL) {
3626                            uint16_t *p = (uint16_t *) page;
3627                            uint16_t data = p[ic->arg[0] >> 1];
3628                            if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3629                                    data = LE16_TO_HOST(data);
3630                            else
3631                                    data = BE16_TO_HOST(data);
3632                            ic->f = instr(mov_imm_rn);
3633                            ic->arg[0] = (int16_t) data;
3634                    }
3635                  break;                  break;
3636    
3637          case 0xa:       /*  BRA disp  */          case 0xa:       /*  BRA disp  */
3638          case 0xb:       /*  BSR disp  */          case 0xb:       /*  BSR disp  */
3639                  ic->f = main_opcode == 0xa? instr(bra) : instr(bsr);                  samepage_function = NULL;
3640    
3641                    switch (main_opcode) {
3642                    case 0xa:
3643                            ic->f = instr(bra);
3644                            samepage_function = instr(bra_samepage);
3645                            break;
3646                    case 0xb:
3647                            ic->f = instr(bsr);
3648                            samepage_function = instr(bsr_samepage);
3649                            break;
3650                    }
3651    
3652                  ic->arg[0] = (int32_t) ( (addr & ((SH_IC_ENTRIES_PER_PAGE-1)                  ic->arg[0] = (int32_t) ( (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3653                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4 +                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4 +
3654                      (((int32_t)(int16_t)((iword & 0xfff) << 4)) >> 3) );                      (((int32_t)(int16_t)((iword & 0xfff) << 4)) >> 3) );
3655    
3656                    /*  samepage branches:  */
3657                    if (samepage_function != NULL && ic->arg[0] < 0x1000 &&
3658                        (addr & 0xfff) < 0xffe) {
3659                            ic->arg[0] = (size_t) (cpu->cd.sh.cur_ic_page +
3660                                (ic->arg[0] >> SH_INSTR_ALIGNMENT_SHIFT));
3661                            ic->f = samepage_function;
3662                    }
3663                  break;                  break;
3664    
3665          case 0xc:          case 0xc:
# Line 3521  X(to_be_translated) Line 3726  X(to_be_translated)
3726                          ic->f = instr(or_b_imm_r0_gbr);                          ic->f = instr(or_b_imm_r0_gbr);
3727                          ic->arg[0] = lo8;                          ic->arg[0] = lo8;
3728                          break;                          break;
3729                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3730                              main_opcode, r8);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3731                                        main_opcode, r8);
3732                          goto bad;                          goto bad;
3733                  }                  }
3734                  break;                  break;
# Line 3531  X(to_be_translated) Line 3737  X(to_be_translated)
3737                  ic->f = instr(mov_l_disp_pc_rn);                  ic->f = instr(mov_l_disp_pc_rn);
3738                  ic->arg[0] = lo8 * 4 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)                  ic->arg[0] = lo8 * 4 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3739                      << SH_INSTR_ALIGNMENT_SHIFT) & ~3) + 4;                      << SH_INSTR_ALIGNMENT_SHIFT) & ~3) + 4;
3740    
3741                    /*  If the word is reachable from the same page as the
3742                        current address, then optimize it as a mov_imm_rn:  */
3743                    if (ic->arg[0] < 0x1000 && page != NULL) {
3744                            uint32_t *p = (uint32_t *) page;
3745                            uint32_t data = p[ic->arg[0] >> 2];
3746                            if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3747                                    data = LE32_TO_HOST(data);
3748                            else
3749                                    data = BE32_TO_HOST(data);
3750                            ic->f = instr(mov_imm_rn);
3751                            ic->arg[0] = data;
3752                    }
3753                  break;                  break;
3754    
3755          case 0xe:       /*  MOV #imm,Rn  */          case 0xe:       /*  MOV #imm,Rn  */
3756                  ic->f = instr(mov_imm_rn);                  ic->f = instr(mov_imm_rn);
3757                  ic->arg[0] = (int8_t)lo8;                  ic->arg[0] = (int8_t)lo8;
3758                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */
3759                    if (lo8 == 0)
3760                            ic->f = instr(mov_0_rn);
3761                  break;                  break;
3762    
3763          case 0xf:          case 0xf:
# Line 3645  X(to_be_translated) Line 3866  X(to_be_translated)
3866                          ic->f = instr(fldi_frn);                          ic->f = instr(fldi_frn);
3867                          ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];                          ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
3868                          ic->arg[1] = 0x3f800000;                          ic->arg[1] = 0x3f800000;
3869                    } else if ((iword & 0x01ff) == 0x00ad) {
3870                            /*  FCNVSD FPUL,DRn  */
3871                            ic->f = instr(fcnvsd_fpul_drn);
3872                            ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
3873                    } else if ((iword & 0x01ff) == 0x00bd) {
3874                            /*  FCNVDS DRm,FPUL  */
3875                            ic->f = instr(fcnvds_drm_fpul);
3876                            ic->arg[0] = (size_t)&cpu->cd.sh.fr[r8];
3877                  } else if ((iword & 0x01ff) == 0x00fd) {                  } else if ((iword & 0x01ff) == 0x00fd) {
3878                          /*  FSCA FPUL,DRn  */                          /*  FSCA FPUL,DRn  */
3879                          ic->f = instr(fsca_fpul_drn);                          ic->f = instr(fsca_fpul_drn);
# Line 3665  X(to_be_translated) Line 3894  X(to_be_translated)
3894                          ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];                          ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
3895                          ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];                          ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
3896                  } else {                  } else {
3897                          fatal("Unimplemented opcode 0x%x,0x%02x\n",                          if (!cpu->translation_readahead)
3898                              main_opcode, lo8);                                  fatal("Unimplemented opcode 0x%x,0x%02x\n",
3899                                        main_opcode, lo8);
3900                          goto bad;                          goto bad;
3901                  }                  }
3902                  break;                  break;
3903    
3904          default:fatal("Unimplemented main opcode 0x%x\n", main_opcode);          default:if (!cpu->translation_readahead)
3905                            fatal("Unimplemented main opcode 0x%x\n", main_opcode);
3906                  goto bad;                  goto bad;
3907          }          }
3908    

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

  ViewVC Help
Powered by ViewVC 1.1.26