/[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 41 by dpavlin, Mon Oct 8 16:22:11 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_sh_instr.c,v 1.56 2007/04/19 15:49:39 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  /*  /*
# Line 1371  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 1412  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 1433  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 1613  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 1630  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 1745  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 1763  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 1782  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 1825  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 1844  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 1882  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 2795  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 2847  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 2962  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;
# Line 3042  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 3079  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 3101  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 3145  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 3369  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 3430  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 3440  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 3449  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 3457  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 3484  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 3579  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 3589  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 3731  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.41  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26