/[qemu]/qemu/target-arm/translate.c
ViewVC logotype

Diff of /qemu/target-arm/translate.c

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

revision 1.23 by bellard, Tue Apr 26 20:36:11 2005 UTC revision 1.24 by bellard, Wed Apr 27 20:25:20 2005 UTC
# Line 38  typedef struct DisasContext { Line 38  typedef struct DisasContext {
38      int condlabel;      int condlabel;
39      struct TranslationBlock *tb;      struct TranslationBlock *tb;
40      int singlestep_enabled;      int singlestep_enabled;
41        int thumb;
42  } DisasContext;  } DisasContext;
43    
44  #define DISAS_JUMP_NEXT 4  #define DISAS_JUMP_NEXT 4
# Line 268  static inline void gen_movl_TN_reg(Disas Line 269  static inline void gen_movl_TN_reg(Disas
269      int val;      int val;
270    
271      if (reg == 15) {      if (reg == 15) {
272          /* normaly, since we updated PC, we need only to add 4 */          /* normaly, since we updated PC, we need only to add one insn */
273          val = (long)s->pc + 4;          if (s->thumb)
274                val = (long)s->pc + 2;
275            else
276                val = (long)s->pc + 4;
277          gen_op_movl_TN_im[t](val);          gen_op_movl_TN_im[t](val);
278      } else {      } else {
279          gen_op_movl_TN_reg[t][reg]();          gen_op_movl_TN_reg[t][reg]();
# Line 897  static inline void gen_jmp (DisasContext Line 901  static inline void gen_jmp (DisasContext
901  {  {
902      if (__builtin_expect(s->singlestep_enabled, 0)) {      if (__builtin_expect(s->singlestep_enabled, 0)) {
903          /* An indirect jump so that we still trigger the debug exception.  */          /* An indirect jump so that we still trigger the debug exception.  */
904            if (s->thumb)
905              dest |= 1;
906          gen_op_movl_T0_im(dest);          gen_op_movl_T0_im(dest);
907          gen_bx(s);          gen_bx(s);
908      } else {      } else {
# Line 1552  static void disas_thumb_insn(DisasContex Line 1558  static void disas_thumb_insn(DisasContex
1558                  gen_movl_T1_reg(s, rm);                  gen_movl_T1_reg(s, rm);
1559              }              }
1560              if (insn & (1 << 9))              if (insn & (1 << 9))
1561                  gen_op_addl_T0_T1_cc();                  gen_op_subl_T0_T1_cc();
1562              else              else
1563                  gen_op_addl_T0_T1_cc();                  gen_op_addl_T0_T1_cc();
1564              gen_movl_reg_T0(s, rd);              gen_movl_reg_T0(s, rd);
# Line 1595  static void disas_thumb_insn(DisasContex Line 1601  static void disas_thumb_insn(DisasContex
1601      case 4:      case 4:
1602          if (insn & (1 << 11)) {          if (insn & (1 << 11)) {
1603              rd = (insn >> 8) & 7;              rd = (insn >> 8) & 7;
1604              /* load pc-relative */              /* load pc-relative.  Bit 1 of PC is ignored.  */
1605              val = (insn & 0xff) * 4;              val = s->pc + 2 + ((insn & 0xff) * 4);
1606                val &= ~(uint32_t)2;
1607              gen_op_movl_T1_im(val);              gen_op_movl_T1_im(val);
             gen_movl_T2_reg(s, 15);  
             gen_op_addl_T1_T2();  
1608              gen_op_ldl_T0_T1();              gen_op_ldl_T0_T1();
1609              gen_movl_reg_T0(s, rd);              gen_movl_reg_T0(s, rd);
1610              break;              break;
# Line 1658  static void disas_thumb_insn(DisasContex Line 1663  static void disas_thumb_insn(DisasContex
1663              gen_movl_T0_reg(s, rd);              gen_movl_T0_reg(s, rd);
1664    
1665          gen_movl_T1_reg(s, rm);          gen_movl_T1_reg(s, rm);
1666          switch (insn >> 6) {          switch (op) {
1667          case 0x0: /* and */          case 0x0: /* and */
1668              gen_op_andl_T0_T1();              gen_op_andl_T0_T1();
1669              gen_op_logic_T0_cc();              gen_op_logic_T0_cc();
# Line 1689  static void disas_thumb_insn(DisasContex Line 1694  static void disas_thumb_insn(DisasContex
1694              gen_op_andl_T0_T1();              gen_op_andl_T0_T1();
1695              gen_op_logic_T0_cc();              gen_op_logic_T0_cc();
1696              rd = 16;              rd = 16;
1697                break;
1698          case 0x9: /* neg */          case 0x9: /* neg */
1699              gen_op_rsbl_T0_T1_cc();              gen_op_subl_T0_T1_cc();
1700              break;              break;
1701          case 0xa: /* cmp */          case 0xa: /* cmp */
1702              gen_op_subl_T0_T1_cc();              gen_op_subl_T0_T1_cc();
# Line 1716  static void disas_thumb_insn(DisasContex Line 1722  static void disas_thumb_insn(DisasContex
1722              gen_op_notl_T1();              gen_op_notl_T1();
1723              gen_op_logic_T1_cc();              gen_op_logic_T1_cc();
1724              val = 1;              val = 1;
1725                rm = rd;
1726              break;              break;
1727          }          }
1728          if (rd != 16) {          if (rd != 16) {
1729              if (val)              if (val)
1730                  gen_movl_reg_T1(s, rd);                  gen_movl_reg_T1(s, rm);
1731              else              else
1732                  gen_movl_reg_T0(s, rd);                  gen_movl_reg_T0(s, rd);
1733          }          }
# Line 1756  static void disas_thumb_insn(DisasContex Line 1763  static void disas_thumb_insn(DisasContex
1763              gen_op_ldl_T0_T1();              gen_op_ldl_T0_T1();
1764              break;              break;
1765          case 5: /* ldrh */          case 5: /* ldrh */
1766              gen_op_ldsw_T0_T1();              gen_op_lduw_T0_T1();
1767              break;              break;
1768          case 6: /* ldrb */          case 6: /* ldrb */
1769              gen_op_ldub_T0_T1();              gen_op_ldub_T0_T1();
# Line 1851  static void disas_thumb_insn(DisasContex Line 1858  static void disas_thumb_insn(DisasContex
1858      case 10:      case 10:
1859          /* add to high reg */          /* add to high reg */
1860          rd = (insn >> 8) & 7;          rd = (insn >> 8) & 7;
1861          if (insn & (1 << 11))          if (insn & (1 << 11)) {
1862              rm = 13; /* sp */              /* SP */
1863          else              gen_movl_T0_reg(s, 13);
1864              rm = 15; /* pc */          } else {
1865          gen_movl_T0_reg(s, rm);              /* PC. bit 1 is ignored.  */
1866                gen_op_movl_T0_im((s->pc + 2) & ~(uint32_t)2);
1867            }
1868          val = (insn & 0xff) * 4;          val = (insn & 0xff) * 4;
1869          gen_op_movl_T1_im(val);          gen_op_movl_T1_im(val);
1870          gen_op_addl_T0_T1();          gen_op_addl_T0_T1();
# Line 1880  static void disas_thumb_insn(DisasContex Line 1889  static void disas_thumb_insn(DisasContex
1889          case 4: case 5: case 0xc: case 0xd:          case 4: case 5: case 0xc: case 0xd:
1890              /* push/pop */              /* push/pop */
1891              gen_movl_T1_reg(s, 13);              gen_movl_T1_reg(s, 13);
1892              if (insn & (1 << 11))              if (insn & (1 << 8))
1893                  val = 4;                  offset = 4;
1894              else              else
1895                  val = -4;                  offset = 0;
1896              gen_op_movl_T2_im(val);              for (i = 0; i < 8; i++) {
1897                    if (insn & (1 << i))
1898                        offset += 4;
1899                }
1900                if ((insn & (1 << 11)) == 0) {
1901                    gen_op_movl_T2_im(-offset);
1902                    gen_op_addl_T1_T2();
1903                }
1904                gen_op_movl_T2_im(4);
1905              for (i = 0; i < 8; i++) {              for (i = 0; i < 8; i++) {
1906                  if (insn & (1 << i)) {                  if (insn & (1 << i)) {
1907                      if (insn & (1 << 11)) {                      if (insn & (1 << 11)) {
# Line 1896  static void disas_thumb_insn(DisasContex Line 1913  static void disas_thumb_insn(DisasContex
1913                          gen_movl_T0_reg(s, i);                          gen_movl_T0_reg(s, i);
1914                          gen_op_stl_T0_T1();                          gen_op_stl_T0_T1();
1915                      }                      }
1916                      /* move to the next address */                      /* advance to the next address.  */
1917                      gen_op_addl_T1_T2();                      gen_op_addl_T1_T2();
1918                  }                  }
1919              }              }
# Line 1913  static void disas_thumb_insn(DisasContex Line 1930  static void disas_thumb_insn(DisasContex
1930                  }                  }
1931                  gen_op_addl_T1_T2();                  gen_op_addl_T1_T2();
1932              }              }
1933                if ((insn & (1 << 11)) == 0) {
1934                    gen_op_movl_T2_im(-offset);
1935                    gen_op_addl_T1_T2();
1936                }
1937              /* write back the new stack pointer */              /* write back the new stack pointer */
1938              gen_movl_reg_T1(s, 13);              gen_movl_reg_T1(s, 13);
1939              /* set the new PC value */              /* set the new PC value */
# Line 1931  static void disas_thumb_insn(DisasContex Line 1951  static void disas_thumb_insn(DisasContex
1951          rn = (insn >> 8) & 0x7;          rn = (insn >> 8) & 0x7;
1952          gen_movl_T1_reg(s, rn);          gen_movl_T1_reg(s, rn);
1953          gen_op_movl_T2_im(4);          gen_op_movl_T2_im(4);
         val = 0;  
1954          for (i = 0; i < 8; i++) {          for (i = 0; i < 8; i++) {
1955              if (insn & (1 << i)) {              if (insn & (1 << i)) {
                 /* advance to the next address */  
                 if (val)  
                     gen_op_addl_T1_T2();  
                 else  
                     val = 1;  
1956                  if (insn & (1 << 11)) {                  if (insn & (1 << 11)) {
1957                      /* load */                      /* load */
1958                      gen_op_ldl_T0_T1();                      gen_op_ldl_T0_T1();
# Line 1948  static void disas_thumb_insn(DisasContex Line 1962  static void disas_thumb_insn(DisasContex
1962                      gen_movl_T0_reg(s, i);                      gen_movl_T0_reg(s, i);
1963                      gen_op_stl_T0_T1();                      gen_op_stl_T0_T1();
1964                  }                  }
1965                    /* advance to the next address */
1966                    gen_op_addl_T1_T2();
1967              }              }
1968          }          }
1969            /* Base register writeback.  */
1970            gen_movl_reg_T1(s, rn);
1971          break;          break;
1972    
1973      case 13:      case 13:
# Line 1976  static void disas_thumb_insn(DisasContex Line 1994  static void disas_thumb_insn(DisasContex
1994          gen_movl_T1_reg(s, 15);          gen_movl_T1_reg(s, 15);
1995    
1996          /* jump to the offset */          /* jump to the offset */
1997          val = (uint32_t)s->pc;          val = (uint32_t)s->pc + 2;
1998          offset = ((int32_t)insn << 24) >> 24;          offset = ((int32_t)insn << 24) >> 24;
1999          val += (offset << 1) + 2;          val += offset << 1;
2000          gen_jmp(s, val);          gen_jmp(s, val);
2001          break;          break;
2002    
# Line 2002  static void disas_thumb_insn(DisasContex Line 2020  static void disas_thumb_insn(DisasContex
2020          gen_op_movl_T1_im(val | 1);          gen_op_movl_T1_im(val | 1);
2021          gen_movl_reg_T1(s, 14);          gen_movl_reg_T1(s, 14);
2022                    
2023          val += offset;          val += offset << 1;
2024          if (insn & (1 << 11)) {          if (insn & (1 << 11)) {
2025              /* bl */              /* bl */
2026              gen_jmp(s, val);              gen_jmp(s, val);
2027          } else {          } else {
2028              /* blx */              /* blx */
2029                val &= ~(uint32_t)2;
2030              gen_op_movl_T0_im(val);              gen_op_movl_T0_im(val);
2031              gen_bx(s);              gen_bx(s);
2032          }          }
2033      }      }
2034      return;      return;
2035  undef:  undef:
2036      gen_op_movl_T0_im((long)s->pc - 4);      gen_op_movl_T0_im((long)s->pc - 2);
2037      gen_op_movl_reg_TN[0][15]();      gen_op_movl_reg_TN[0][15]();
2038      gen_op_undef_insn();      gen_op_undef_insn();
2039      s->is_jmp = DISAS_JUMP;      s->is_jmp = DISAS_JUMP;
# Line 2045  static inline int gen_intermediate_code_ Line 2064  static inline int gen_intermediate_code_
2064      dc->pc = pc_start;      dc->pc = pc_start;
2065      dc->singlestep_enabled = env->singlestep_enabled;      dc->singlestep_enabled = env->singlestep_enabled;
2066      dc->condjmp = 0;      dc->condjmp = 0;
2067        dc->thumb = env->thumb;
2068      nb_gen_labels = 0;      nb_gen_labels = 0;
2069      lj = -1;      lj = -1;
2070      do {      do {
# Line 2128  static inline int gen_intermediate_code_ Line 2148  static inline int gen_intermediate_code_
2148      if (loglevel & CPU_LOG_TB_IN_ASM) {      if (loglevel & CPU_LOG_TB_IN_ASM) {
2149          fprintf(logfile, "----------------\n");          fprintf(logfile, "----------------\n");
2150          fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));          fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2151          target_disas(logfile, pc_start, dc->pc - pc_start, 0);          target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
2152          fprintf(logfile, "\n");          fprintf(logfile, "\n");
2153          if (loglevel & (CPU_LOG_TB_OP)) {          if (loglevel & (CPU_LOG_TB_OP)) {
2154              fprintf(logfile, "OP:\n");              fprintf(logfile, "OP:\n");

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.24

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26