/[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 40 by dpavlin, Mon Oct 8 16:22:11 2007 UTC revision 44 by dpavlin, Mon Oct 8 16:22:56 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.64 2007/06/28 13:36:47 debug Exp $
29   *   *
30   *  SH instructions.   *  SH instructions.
31   *   *
# Line 102  X(sleep) Line 102  X(sleep)
102    
103          if (cpu->machine->ncpus == 1) {          if (cpu->machine->ncpus == 1) {
104                  static int x = 0;                  static int x = 0;
105    
106                  if ((++x) == 600) {                  if ((++x) == 600) {
107                          usleep(10);                          usleep(10);
108                          x = 0;                          x = 0;
109                  }                  }
110    
111                  cpu->n_translated_instrs += N_SAFE_DYNTRANS_LIMIT / 6;                  cpu->n_translated_instrs += N_SAFE_DYNTRANS_LIMIT / 6;
112          }          }
113  }  }
# Line 173  X(exts_b_rm_rn) { reg(ic->arg[1]) = (int Line 175  X(exts_b_rm_rn) { reg(ic->arg[1]) = (int
175  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]); }
176  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]); }
177  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]); }
178    /*  Note: rm and rn are the same on these:  */
179    X(extu_b_rm)    { reg(ic->arg[1]) = (uint8_t)reg(ic->arg[1]); }
180    X(extu_w_rm)    { reg(ic->arg[1]) = (uint16_t)reg(ic->arg[1]); }
181    
182    
183  /*  /*
# Line 280  X(and_b_imm_r0_gbr) Line 285  X(and_b_imm_r0_gbr)
285   *  arg[0] = int8_t imm, extended to at least int32_t   *  arg[0] = int8_t imm, extended to at least int32_t
286   *  arg[1] = ptr to rn   *  arg[1] = ptr to rn
287   */   */
288  X(mov_imm_rn) { reg(ic->arg[1]) = (int32_t)ic->arg[0]; }  X(mov_imm_rn) { reg(ic->arg[1]) = ic->arg[0]; }
289  X(add_imm_rn) { reg(ic->arg[1]) += (int32_t)ic->arg[0]; }  X(mov_0_rn)   { reg(ic->arg[1]) = 0; }
290    X(add_imm_rn) { reg(ic->arg[1]) += ic->arg[0]; }
291    X(inc_rn)     { reg(ic->arg[1]) ++; }
292    X(add_4_rn)   { reg(ic->arg[1]) += 4; }
293    X(sub_4_rn)   { reg(ic->arg[1]) -= 4; }
294    X(dec_rn)     { reg(ic->arg[1]) --; }
295    
296    
297  /*  /*
# Line 1371  X(mov_w_r0_disp_rn) Line 1381  X(mov_w_r0_disp_rn)
1381   *  sub_rm_rn:  rn = rn - rm   *  sub_rm_rn:  rn = rn - rm
1382   *  subc_rm_rn: rn = rn - rm - t; t = borrow   *  subc_rm_rn: rn = rn - rm - t; t = borrow
1383   *  tst_rm_rn:  t = ((rm & rn) == 0)   *  tst_rm_rn:  t = ((rm & rn) == 0)
1384     *  tst_rm:     t = (rm == 0)
1385   *  xtrct_rm_rn:  rn = (rn >> 16) | (rm << 16)   *  xtrct_rm_rn:  rn = (rn >> 16) | (rm << 16)
1386   *   *
1387   *  arg[0] = ptr to rm   *  arg[0] = ptr to rm
# Line 1412  X(tst_rm_rn) Line 1423  X(tst_rm_rn)
1423          else          else
1424                  cpu->cd.sh.sr |= SH_SR_T;                  cpu->cd.sh.sr |= SH_SR_T;
1425  }  }
1426    X(tst_rm)
1427    {
1428            if (reg(ic->arg[0]))
1429                    cpu->cd.sh.sr &= ~SH_SR_T;
1430            else
1431                    cpu->cd.sh.sr |= SH_SR_T;
1432    }
1433  X(xtrct_rm_rn)  X(xtrct_rm_rn)
1434  {  {
1435          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 1451  X(div0u)
1451  }  }
1452  X(div0s_rm_rn)  X(div0s_rm_rn)
1453  {  {
1454          int q = reg(ic->arg[1]) >> 31, m = reg(ic->arg[0]) >> 31;          int q = reg(ic->arg[1]) & 0x80000000;
1455          cpu->cd.sh.sr &= ~(SH_SR_Q | SH_SR_M | SH_SR_T);          int m = reg(ic->arg[0]) & 0x80000000;
1456            uint32_t new_sr = cpu->cd.sh.sr & ~(SH_SR_Q | SH_SR_M | SH_SR_T);
1457          if (q)          if (q)
1458                  cpu->cd.sh.sr |= SH_SR_Q;                  new_sr |= SH_SR_Q;
1459          if (m)          if (m)
1460                  cpu->cd.sh.sr |= SH_SR_M;                  new_sr |= SH_SR_M;
1461          if (m ^ q)          if (m ^ q)
1462                  cpu->cd.sh.sr |= SH_SR_T;                  new_sr |= SH_SR_T;
1463            cpu->cd.sh.sr = new_sr;
1464  }  }
1465  X(div1_rm_rn)  X(div1_rm_rn)
1466  {  {
# Line 1613  X(cmp_str_rm_rn) Line 1633  X(cmp_str_rm_rn)
1633  X(shll_rn)  X(shll_rn)
1634  {  {
1635          uint32_t rn = reg(ic->arg[1]);          uint32_t rn = reg(ic->arg[1]);
1636          if (rn >> 31)          if (rn & 0x80000000)
1637                  cpu->cd.sh.sr |= SH_SR_T;                  cpu->cd.sh.sr |= SH_SR_T;
1638          else          else
1639                  cpu->cd.sh.sr &= ~SH_SR_T;                  cpu->cd.sh.sr &= ~SH_SR_T;
# Line 1630  X(shlr_rn) Line 1650  X(shlr_rn)
1650  }  }
1651  X(rotl_rn)  X(rotl_rn)
1652  {  {
1653          uint32_t rn = reg(ic->arg[1]);          uint32_t rn = reg(ic->arg[1]), x;
1654          if (rn >> 31)          if (rn & 0x80000000) {
1655                    x = 1;
1656                  cpu->cd.sh.sr |= SH_SR_T;                  cpu->cd.sh.sr |= SH_SR_T;
1657          else          } else {
1658                    x = 0;
1659                  cpu->cd.sh.sr &= ~SH_SR_T;                  cpu->cd.sh.sr &= ~SH_SR_T;
1660          reg(ic->arg[1]) = (rn << 1) | (rn >> 31);          }
1661            reg(ic->arg[1]) = (rn << 1) | x;
1662  }  }
1663  X(rotr_rn)  X(rotr_rn)
1664  {  {
# Line 1745  X(shld) Line 1768  X(shld)
1768   *  braf:  Like bra, but using a register instead of an immediate   *  braf:  Like bra, but using a register instead of an immediate
1769   *  bsrf:  Like braf, but also sets PR to the return address   *  bsrf:  Like braf, but also sets PR to the return address
1770   *   *
1771   *  arg[0] = immediate offset relative to start of page   *  arg[0] = immediate offset relative to start of page,
1772     *           or ptr to target instruction, for samepage branches
1773   *  arg[1] = ptr to Rn  (for braf/bsrf)   *  arg[1] = ptr to Rn  (for braf/bsrf)
1774   */   */
1775  X(bra)  X(bra)
# Line 1763  X(bra) Line 1787  X(bra)
1787          } else          } else
1788                  cpu->delay_slot = NOT_DELAYED;                  cpu->delay_slot = NOT_DELAYED;
1789  }  }
1790    X(bra_samepage)
1791    {
1792            cpu->delay_slot = TO_BE_DELAYED;
1793            ic[1].f(cpu, ic+1);
1794            cpu->n_translated_instrs ++;
1795            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT))
1796                    cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[0];
1797            cpu->delay_slot = NOT_DELAYED;
1798    }
1799  X(bsr)  X(bsr)
1800  {  {
1801          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 1815  X(bsr)
1815          } else          } else
1816                  cpu->delay_slot = NOT_DELAYED;                  cpu->delay_slot = NOT_DELAYED;
1817  }  }
1818    X(bsr_samepage)
1819    {
1820            uint32_t old_pc;
1821            SYNCH_PC;
1822            old_pc = cpu->pc;
1823            cpu->delay_slot = TO_BE_DELAYED;
1824            ic[1].f(cpu, ic+1);
1825            cpu->n_translated_instrs ++;
1826            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1827                    cpu->cd.sh.pr = old_pc + 4;
1828                    cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[0];
1829            }
1830            cpu->delay_slot = NOT_DELAYED;
1831    }
1832  X(braf_rn)  X(braf_rn)
1833  {  {
1834          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 1872  X(bsrf_rn)
1872   *  bf/s: Branch if false (with delay-slot)   *  bf/s: Branch if false (with delay-slot)
1873   *   *
1874   *  arg[0] = immediate offset relative to start of page   *  arg[0] = immediate offset relative to start of page
1875     *  arg[1] = for samepage functions, the new instruction pointer
1876   */   */
1877  X(bt)  X(bt)
1878  {  {
# Line 1844  X(bf) Line 1892  X(bf)
1892                  quick_pc_to_pointers(cpu);                  quick_pc_to_pointers(cpu);
1893          }          }
1894  }  }
1895    X(bt_samepage)
1896    {
1897            if (cpu->cd.sh.sr & SH_SR_T)
1898                    cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[1];
1899    }
1900    X(bf_samepage)
1901    {
1902            if (!(cpu->cd.sh.sr & SH_SR_T))
1903                    cpu->cd.sh.next_ic = (struct sh_instr_call *) ic->arg[1];
1904    }
1905  X(bt_s)  X(bt_s)
1906  {  {
1907          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 1940  X(bf_s)
1940          } else          } else
1941                  cpu->delay_slot = NOT_DELAYED;                  cpu->delay_slot = NOT_DELAYED;
1942  }  }
1943    X(bt_s_samepage)
1944    {
1945            int cond = cpu->cd.sh.sr & SH_SR_T;
1946            cpu->delay_slot = TO_BE_DELAYED;
1947            ic[1].f(cpu, ic+1);
1948            cpu->n_translated_instrs ++;
1949            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1950                    cpu->delay_slot = NOT_DELAYED;
1951                    if (cond)
1952                            cpu->cd.sh.next_ic =
1953                                (struct sh_instr_call *) ic->arg[1];
1954                    else
1955                            cpu->cd.sh.next_ic ++;
1956            } else
1957                    cpu->delay_slot = NOT_DELAYED;
1958    }
1959    X(bf_s_samepage)
1960    {
1961            int cond = !(cpu->cd.sh.sr & SH_SR_T);
1962            cpu->delay_slot = TO_BE_DELAYED;
1963            ic[1].f(cpu, ic+1);
1964            cpu->n_translated_instrs ++;
1965            if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
1966                    cpu->delay_slot = NOT_DELAYED;
1967                    if (cond)
1968                            cpu->cd.sh.next_ic =
1969                                (struct sh_instr_call *) ic->arg[1];
1970                    else
1971                            cpu->cd.sh.next_ic ++;
1972            } else
1973                    cpu->delay_slot = NOT_DELAYED;
1974    }
1975    
1976    
1977  /*  /*
# Line 2792  X(end_of_page2) Line 2882  X(end_of_page2)
2882   */   */
2883  X(to_be_translated)  X(to_be_translated)
2884  {  {
2885          uint64_t addr, low_pc;          uint32_t addr, low_pc, iword;
         uint32_t iword;  
2886          unsigned char *page;          unsigned char *page;
2887          unsigned char ib[4];          unsigned char ib[2];
2888          int main_opcode, isize = cpu->cd.sh.compact? 2 : sizeof(ib);          int main_opcode, isize = sizeof(ib);
2889          int in_crosspage_delayslot = 0, r8, r4, lo4, lo8;          int in_crosspage_delayslot = 0, r8, r4, lo4, lo8;
2890          /*  void (*samepage_function)(struct cpu *, struct sh_instr_call *);  */          void (*samepage_function)(struct cpu *, struct sh_instr_call *);
2891    
2892          /*  Figure out the (virtual) address of the instruction:  */          /*  Figure out the (virtual) address of the instruction:  */
2893          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 2818  X(to_be_translated) Line 2907  X(to_be_translated)
2907          addr &= ~((1 << SH_INSTR_ALIGNMENT_SHIFT) - 1);          addr &= ~((1 << SH_INSTR_ALIGNMENT_SHIFT) - 1);
2908    
2909          /*  Read the instruction word from memory:  */          /*  Read the instruction word from memory:  */
 #ifdef MODE32  
2910          page = cpu->cd.sh.host_load[(uint32_t)addr >> 12];          page = cpu->cd.sh.host_load[(uint32_t)addr >> 12];
 #else  
         {  
                 const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;  
                 const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;  
                 const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;  
                 uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;  
                 uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;  
                 uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-  
                     DYNTRANS_L3N)) & mask3;  
                 struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.sh.l1_64[x1];  
                 struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];  
                 page = l3->host_load[x3];  
         }  
 #endif  
2911    
2912          if (page != NULL) {          if (page != NULL) {
2913                  /*  fatal("TRANSLATION HIT!\n");  */                  /*  fatal("TRANSLATION HIT!\n");  */
# Line 2847  X(to_be_translated) Line 2921  X(to_be_translated)
2921                  }                  }
2922          }          }
2923    
2924          if (cpu->cd.sh.compact) {          iword = *((uint16_t *)&ib[0]);
2925                  iword = *((uint16_t *)&ib[0]);          if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
2926                  if (cpu->byte_order == EMUL_LITTLE_ENDIAN)                  iword = LE16_TO_HOST(iword);
2927                          iword = LE16_TO_HOST(iword);          else
2928                  else                  iword = BE16_TO_HOST(iword);
2929                          iword = BE16_TO_HOST(iword);          main_opcode = iword >> 12;
2930                  main_opcode = iword >> 12;          r8 = (iword >> 8) & 0xf;
2931                  r8 = (iword >> 8) & 0xf;          r4 = (iword >> 4) & 0xf;
2932                  r4 = (iword >> 4) & 0xf;          lo8 = iword & 0xff;
2933                  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;  
         }  
2934    
2935    
2936  #define DYNTRANS_TO_BE_TRANSLATED_HEAD  #define DYNTRANS_TO_BE_TRANSLATED_HEAD
# Line 2962  X(to_be_translated) Line 3025  X(to_be_translated)
3025                          case 0x09:      /*  NOP  */                          case 0x09:      /*  NOP  */
3026                                  ic->f = instr(nop);                                  ic->f = instr(nop);
3027                                  if (iword & 0x0f00) {                                  if (iword & 0x0f00) {
3028                                          fatal("Unimplemented NOP variant?\n");                                          if (!cpu->translation_readahead)
3029                                                    fatal("Unimplemented NOP"
3030                                                        " variant?\n");
3031                                          goto bad;                                          goto bad;
3032                                  }                                  }
3033                                  break;                                  break;
# Line 3042  X(to_be_translated) Line 3107  X(to_be_translated)
3107                                  ic->arg[0] = (size_t)&cpu->cd.sh.dbr;                                  ic->arg[0] = (size_t)&cpu->cd.sh.dbr;
3108                                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];                                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];
3109                                  break;                                  break;
3110                          default:fatal("Unimplemented opcode 0x%x,0x%03x\n",                          default:if (!cpu->translation_readahead)
3111                                      main_opcode, iword & 0xfff);                                          fatal("Unimplemented opcode 0x%x,"
3112                                                "0x%03x\n", main_opcode,
3113                                                iword & 0xfff);
3114                                  goto bad;                                  goto bad;
3115                          }                          }
3116                  }                  }
# Line 3079  X(to_be_translated) Line 3146  X(to_be_translated)
3146                          break;                          break;
3147                  case 0x8:       /*  TST Rm,Rn  */                  case 0x8:       /*  TST Rm,Rn  */
3148                          ic->f = instr(tst_rm_rn);                          ic->f = instr(tst_rm_rn);
3149                            if (r8 == r4)
3150                                    ic->f = instr(tst_rm);
3151                          break;                          break;
3152                  case 0x9:       /*  AND Rm,Rn  */                  case 0x9:       /*  AND Rm,Rn  */
3153                          ic->f = instr(and_rm_rn);                          ic->f = instr(and_rm_rn);
# Line 3101  X(to_be_translated) Line 3170  X(to_be_translated)
3170                  case 0xf:       /*  MULS.W Rm,Rn  */                  case 0xf:       /*  MULS.W Rm,Rn  */
3171                          ic->f = instr(muls_w_rm_rn);                          ic->f = instr(muls_w_rm_rn);
3172                          break;                          break;
3173                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3174                              main_opcode, lo4);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3175                                        main_opcode, lo4);
3176                          goto bad;                          goto bad;
3177                  }                  }
3178                  break;                  break;
# Line 3145  X(to_be_translated) Line 3215  X(to_be_translated)
3215                  case 0xe:       /*  ADDC Rm,Rn  */                  case 0xe:       /*  ADDC Rm,Rn  */
3216                          ic->f = instr(addc_rm_rn);                          ic->f = instr(addc_rm_rn);
3217                          break;                          break;
3218                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3219                              main_opcode, lo4);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3220                                        main_opcode, lo4);
3221                          goto bad;                          goto bad;
3222                  }                  }
3223                  break;                  break;
# Line 3369  X(to_be_translated) Line 3440  X(to_be_translated)
3440                                  ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];                                  ic->arg[0] = (size_t)&cpu->cd.sh.r[r8];
3441                                  ic->arg[1] = (size_t)&cpu->cd.sh.dbr;                                  ic->arg[1] = (size_t)&cpu->cd.sh.dbr;
3442                                  break;                                  break;
3443                          default:fatal("Unimplemented opcode 0x%x,0x%02x\n",                          default:if (!cpu->translation_readahead)
3444                                      main_opcode, lo8);                                          fatal("Unimplemented opcode 0x%x,"
3445                                                "0x%02x\n", main_opcode, lo8);
3446                                  goto bad;                                  goto bad;
3447                          }                          }
3448                  }                  }
# Line 3430  X(to_be_translated) Line 3502  X(to_be_translated)
3502                          break;                          break;
3503                  case 0xc:       /*  EXTU.B Rm,Rn  */                  case 0xc:       /*  EXTU.B Rm,Rn  */
3504                          ic->f = instr(extu_b_rm_rn);                          ic->f = instr(extu_b_rm_rn);
3505                            if (r8 == r4)
3506                                    ic->f = instr(extu_b_rm);
3507                          break;                          break;
3508                  case 0xd:       /*  EXTU.W Rm,Rn  */                  case 0xd:       /*  EXTU.W Rm,Rn  */
3509                          ic->f = instr(extu_w_rm_rn);                          ic->f = instr(extu_w_rm_rn);
3510                            if (r8 == r4)
3511                                    ic->f = instr(extu_w_rm);
3512                          break;                          break;
3513                  case 0xe:       /*  EXTS.B Rm,Rn  */                  case 0xe:       /*  EXTS.B Rm,Rn  */
3514                          ic->f = instr(exts_b_rm_rn);                          ic->f = instr(exts_b_rm_rn);
# Line 3440  X(to_be_translated) Line 3516  X(to_be_translated)
3516                  case 0xf:       /*  EXTS.W Rm,Rn  */                  case 0xf:       /*  EXTS.W Rm,Rn  */
3517                          ic->f = instr(exts_w_rm_rn);                          ic->f = instr(exts_w_rm_rn);
3518                          break;                          break;
3519                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3520                              main_opcode, lo4);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3521                                        main_opcode, lo4);
3522                          goto bad;                          goto bad;
3523                  }                  }
3524                  break;                  break;
# Line 3449  X(to_be_translated) Line 3526  X(to_be_translated)
3526          case 0x7:       /*  ADD #imm,Rn  */          case 0x7:       /*  ADD #imm,Rn  */
3527                  ic->f = instr(add_imm_rn);                  ic->f = instr(add_imm_rn);
3528                  ic->arg[0] = (int8_t)lo8;                  ic->arg[0] = (int8_t)lo8;
3529                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8];         /* n */
3530                    if (lo8 == 1)
3531                            ic->f = instr(inc_rn);
3532                    if (lo8 == 4)
3533                            ic->f = instr(add_4_rn);
3534                    if (lo8 == 0xfc)
3535                            ic->f = instr(sub_4_rn);
3536                    if (lo8 == 0xff)
3537                            ic->f = instr(dec_rn);
3538                  break;                  break;
3539    
3540          case 0x8:          case 0x8:
# Line 3457  X(to_be_translated) Line 3542  X(to_be_translated)
3542                  ic->arg[0] = (int8_t)lo8 * 2 +                  ic->arg[0] = (int8_t)lo8 * 2 +
3543                      (addr & ((SH_IC_ENTRIES_PER_PAGE-1)                      (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3544                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;
3545                    samepage_function = NULL;
3546    
3547                  switch (r8) {                  switch (r8) {
3548                  case 0x0:       /*  MOV.B R0,@(disp,Rn)  */                  case 0x0:       /*  MOV.B R0,@(disp,Rn)  */
3549                          ic->f = instr(mov_b_r0_disp_rn);                          ic->f = instr(mov_b_r0_disp_rn);
# Line 3484  X(to_be_translated) Line 3571  X(to_be_translated)
3571                          break;                          break;
3572                  case 0x9:       /*  BT (disp,PC)  */                  case 0x9:       /*  BT (disp,PC)  */
3573                          ic->f = instr(bt);                          ic->f = instr(bt);
3574                            samepage_function = instr(bt_samepage);
3575                          break;                          break;
3576                  case 0xb:       /*  BF (disp,PC)  */                  case 0xb:       /*  BF (disp,PC)  */
3577                          ic->f = instr(bf);                          ic->f = instr(bf);
3578                            samepage_function = instr(bf_samepage);
3579                          break;                          break;
3580                  case 0xd:       /*  BT/S (disp,PC)  */                  case 0xd:       /*  BT/S (disp,PC)  */
3581                          ic->f = instr(bt_s);                          ic->f = instr(bt_s);
3582                            samepage_function = instr(bt_s_samepage);
3583                          break;                          break;
3584                  case 0xf:       /*  BF/S (disp,PC)  */                  case 0xf:       /*  BF/S (disp,PC)  */
3585                          ic->f = instr(bf_s);                          ic->f = instr(bf_s);
3586                            samepage_function = instr(bf_s_samepage);
3587                          break;                          break;
3588                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3589                              main_opcode, r8);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3590                                        main_opcode, r8);
3591                          goto bad;                          goto bad;
3592                  }                  }
3593    
3594                    /*  samepage branches:  */
3595                    if (samepage_function != NULL && ic->arg[0] < 0x1000 &&
3596                        (addr & 0xfff) < 0xffe) {
3597                            ic->arg[1] = (size_t) (cpu->cd.sh.cur_ic_page +
3598                                (ic->arg[0] >> SH_INSTR_ALIGNMENT_SHIFT));
3599                            ic->f = samepage_function;
3600                    }
3601    
3602                  break;                  break;
3603    
3604          case 0x9:       /*  MOV.W @(disp,PC),Rn  */          case 0x9:       /*  MOV.W @(disp,PC),Rn  */
3605                  ic->f = instr(mov_w_disp_pc_rn);                  ic->f = instr(mov_w_disp_pc_rn);
3606                  ic->arg[0] = lo8 * 2 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)                  ic->arg[0] = lo8 * 2 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3607                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4;
3608                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */  
3609                    /*  If the word is reachable from the same page as the
3610                        current address, then optimize it as a mov_imm_rn:  */
3611                    if (ic->arg[0] < 0x1000 && page != NULL) {
3612                            uint16_t *p = (uint16_t *) page;
3613                            uint16_t data = p[ic->arg[0] >> 1];
3614                            if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3615                                    data = LE16_TO_HOST(data);
3616                            else
3617                                    data = BE16_TO_HOST(data);
3618                            ic->f = instr(mov_imm_rn);
3619                            ic->arg[0] = (int16_t) data;
3620                    }
3621                  break;                  break;
3622    
3623          case 0xa:       /*  BRA disp  */          case 0xa:       /*  BRA disp  */
3624          case 0xb:       /*  BSR disp  */          case 0xb:       /*  BSR disp  */
3625                  ic->f = main_opcode == 0xa? instr(bra) : instr(bsr);                  samepage_function = NULL;
3626    
3627                    switch (main_opcode) {
3628                    case 0xa:
3629                            ic->f = instr(bra);
3630                            samepage_function = instr(bra_samepage);
3631                            break;
3632                    case 0xb:
3633                            ic->f = instr(bsr);
3634                            samepage_function = instr(bsr_samepage);
3635                            break;
3636                    }
3637    
3638                  ic->arg[0] = (int32_t) ( (addr & ((SH_IC_ENTRIES_PER_PAGE-1)                  ic->arg[0] = (int32_t) ( (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3639                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4 +                      << SH_INSTR_ALIGNMENT_SHIFT) & ~1) + 4 +
3640                      (((int32_t)(int16_t)((iword & 0xfff) << 4)) >> 3) );                      (((int32_t)(int16_t)((iword & 0xfff) << 4)) >> 3) );
3641    
3642                    /*  samepage branches:  */
3643                    if (samepage_function != NULL && ic->arg[0] < 0x1000 &&
3644                        (addr & 0xfff) < 0xffe) {
3645                            ic->arg[0] = (size_t) (cpu->cd.sh.cur_ic_page +
3646                                (ic->arg[0] >> SH_INSTR_ALIGNMENT_SHIFT));
3647                            ic->f = samepage_function;
3648                    }
3649                  break;                  break;
3650    
3651          case 0xc:          case 0xc:
# Line 3579  X(to_be_translated) Line 3712  X(to_be_translated)
3712                          ic->f = instr(or_b_imm_r0_gbr);                          ic->f = instr(or_b_imm_r0_gbr);
3713                          ic->arg[0] = lo8;                          ic->arg[0] = lo8;
3714                          break;                          break;
3715                  default:fatal("Unimplemented opcode 0x%x,0x%x\n",                  default:if (!cpu->translation_readahead)
3716                              main_opcode, r8);                                  fatal("Unimplemented opcode 0x%x,0x%x\n",
3717                                        main_opcode, r8);
3718                          goto bad;                          goto bad;
3719                  }                  }
3720                  break;                  break;
# Line 3589  X(to_be_translated) Line 3723  X(to_be_translated)
3723                  ic->f = instr(mov_l_disp_pc_rn);                  ic->f = instr(mov_l_disp_pc_rn);
3724                  ic->arg[0] = lo8 * 4 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)                  ic->arg[0] = lo8 * 4 + (addr & ((SH_IC_ENTRIES_PER_PAGE-1)
3725                      << SH_INSTR_ALIGNMENT_SHIFT) & ~3) + 4;                      << SH_INSTR_ALIGNMENT_SHIFT) & ~3) + 4;
3726    
3727                    /*  If the word is reachable from the same page as the
3728                        current address, then optimize it as a mov_imm_rn:  */
3729                    if (ic->arg[0] < 0x1000 && page != NULL) {
3730                            uint32_t *p = (uint32_t *) page;
3731                            uint32_t data = p[ic->arg[0] >> 2];
3732                            if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
3733                                    data = LE32_TO_HOST(data);
3734                            else
3735                                    data = BE32_TO_HOST(data);
3736                            ic->f = instr(mov_imm_rn);
3737                            ic->arg[0] = data;
3738                    }
3739                  break;                  break;
3740    
3741          case 0xe:       /*  MOV #imm,Rn  */          case 0xe:       /*  MOV #imm,Rn  */
3742                  ic->f = instr(mov_imm_rn);                  ic->f = instr(mov_imm_rn);
3743                  ic->arg[0] = (int8_t)lo8;                  ic->arg[0] = (int8_t)lo8;
3744                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */                  ic->arg[1] = (size_t)&cpu->cd.sh.r[r8]; /* n */
3745                    if (lo8 == 0)
3746                            ic->f = instr(mov_0_rn);
3747                  break;                  break;
3748    
3749          case 0xf:          case 0xf:
# Line 3731  X(to_be_translated) Line 3880  X(to_be_translated)
3880                          ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];                          ic->arg[0] = (size_t)&cpu->cd.sh.fr[r4];
3881                          ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];                          ic->arg[1] = (size_t)&cpu->cd.sh.fr[r8];
3882                  } else {                  } else {
3883                          fatal("Unimplemented opcode 0x%x,0x%02x\n",                          if (!cpu->translation_readahead)
3884                              main_opcode, lo8);                                  fatal("Unimplemented opcode 0x%x,0x%02x\n",
3885                                        main_opcode, lo8);
3886                          goto bad;                          goto bad;
3887                  }                  }
3888                  break;                  break;
3889    
3890          default:fatal("Unimplemented main opcode 0x%x\n", main_opcode);          default:if (!cpu->translation_readahead)
3891                            fatal("Unimplemented main opcode 0x%x\n", main_opcode);
3892                  goto bad;                  goto bad;
3893          }          }
3894    

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

  ViewVC Help
Powered by ViewVC 1.1.26