/[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.22 by bellard, Sat Apr 23 18:46:03 2005 UTC revision 1.23 by bellard, Tue Apr 26 20:36:11 2005 UTC
# Line 32  Line 32 
32  typedef struct DisasContext {  typedef struct DisasContext {
33      target_ulong pc;      target_ulong pc;
34      int is_jmp;      int is_jmp;
35        /* Nonzero if this instruction has been conditionally skipped.  */
36        int condjmp;
37        /* The label that will be jumped to when the instruction is skipped.  */
38        int condlabel;
39      struct TranslationBlock *tb;      struct TranslationBlock *tb;
40      int singlestep_enabled;      int singlestep_enabled;
41  } DisasContext;  } DisasContext;
# Line 53  enum { Line 57  enum {
57    
58  #include "gen-op.h"  #include "gen-op.h"
59    
60  static GenOpFunc2 *gen_test_cc[14] = {  static GenOpFunc1 *gen_test_cc[14] = {
61      gen_op_test_eq,      gen_op_test_eq,
62      gen_op_test_ne,      gen_op_test_ne,
63      gen_op_test_cs,      gen_op_test_cs,
# Line 896  static inline void gen_jmp (DisasContext Line 900  static inline void gen_jmp (DisasContext
900          gen_op_movl_T0_im(dest);          gen_op_movl_T0_im(dest);
901          gen_bx(s);          gen_bx(s);
902      } else {      } else {
903          gen_op_jmp((long)s->tb, dest);          gen_op_jmp0((long)s->tb, dest);
904          s->is_jmp = DISAS_TB_JUMP;          s->is_jmp = DISAS_TB_JUMP;
905      }      }
906  }  }
# Line 939  static void disas_arm_insn(CPUState * en Line 943  static void disas_arm_insn(CPUState * en
943      if (cond != 0xe) {      if (cond != 0xe) {
944          /* if not always execute, we generate a conditional jump to          /* if not always execute, we generate a conditional jump to
945             next instruction */             next instruction */
946          gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);          s->condlabel = gen_new_label();
947          s->is_jmp = DISAS_JUMP_NEXT;          gen_test_cc[cond ^ 1](s->condlabel);
948            s->condjmp = 1;
949            //gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);
950            //s->is_jmp = DISAS_JUMP_NEXT;
951      }      }
952      if ((insn & 0x0f900000) == 0x03000000) {      if ((insn & 0x0f900000) == 0x03000000) {
953          if ((insn & 0x0ff0f000) != 0x0360f000)          if ((insn & 0x0ff0f000) != 0x0360f000)
# Line 1961  static void disas_thumb_insn(DisasContex Line 1968  static void disas_thumb_insn(DisasContex
1968              break;              break;
1969          }          }
1970          /* generate a conditional jump to next instruction */          /* generate a conditional jump to next instruction */
1971          gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);          s->condlabel = gen_new_label();
1972          s->is_jmp = DISAS_JUMP_NEXT;          gen_test_cc[cond ^ 1](s->condlabel);
1973            s->condjmp = 1;
1974            //gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);
1975            //s->is_jmp = DISAS_JUMP_NEXT;
1976          gen_movl_T1_reg(s, 15);          gen_movl_T1_reg(s, 15);
1977    
1978          /* jump to the offset */          /* jump to the offset */
# Line 2034  static inline int gen_intermediate_code_ Line 2044  static inline int gen_intermediate_code_
2044      dc->is_jmp = DISAS_NEXT;      dc->is_jmp = DISAS_NEXT;
2045      dc->pc = pc_start;      dc->pc = pc_start;
2046      dc->singlestep_enabled = env->singlestep_enabled;      dc->singlestep_enabled = env->singlestep_enabled;
2047        dc->condjmp = 0;
2048        nb_gen_labels = 0;
2049      lj = -1;      lj = -1;
2050      do {      do {
2051          if (env->nb_breakpoints > 0) {          if (env->nb_breakpoints > 0) {
# Line 2057  static inline int gen_intermediate_code_ Line 2069  static inline int gen_intermediate_code_
2069              gen_opc_pc[lj] = dc->pc;              gen_opc_pc[lj] = dc->pc;
2070              gen_opc_instr_start[lj] = 1;              gen_opc_instr_start[lj] = 1;
2071          }          }
2072    
2073          if (env->thumb)          if (env->thumb)
2074            disas_thumb_insn(dc);            disas_thumb_insn(dc);
2075          else          else
2076            disas_arm_insn(env, dc);            disas_arm_insn(env, dc);
2077    
2078            if (dc->condjmp && !dc->is_jmp) {
2079                gen_set_label(dc->condlabel);
2080                dc->condjmp = 0;
2081            }
2082            /* Translation stops when a conditional branch is enoutered.
2083             * Otherwise the subsequent code could get translated several times.
2084             */
2085      } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&      } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
2086               !env->singlestep_enabled &&               !env->singlestep_enabled &&
2087               (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));               (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
2088        /* It this stage dc->condjmp will only be set when the skipped
2089         * instruction was a conditional branch, and teh PC has already been
2090         * written.  */
2091      if (__builtin_expect(env->singlestep_enabled, 0)) {      if (__builtin_expect(env->singlestep_enabled, 0)) {
2092          /* Make sure the pc is updated, and raise a debug exception.  */          /* Make sure the pc is updated, and raise a debug exception.  */
2093          if (dc->is_jmp == DISAS_NEXT || dc->is_jmp == DISAS_JUMP_NEXT) {          if (dc->condjmp) {
2094                gen_op_debug();
2095                gen_set_label(dc->condlabel);
2096            }
2097            if (dc->condjmp || !dc->is_jmp) {
2098              gen_op_movl_T0_im((long)dc->pc);              gen_op_movl_T0_im((long)dc->pc);
2099              gen_op_movl_reg_TN[0][15]();              gen_op_movl_reg_TN[0][15]();
2100                dc->condjmp = 0;
2101          }          }
2102          gen_op_debug();          gen_op_debug();
2103      } else {      } else {
2104          switch(dc->is_jmp) {          switch(dc->is_jmp) {
         case DISAS_JUMP_NEXT:  
2105          case DISAS_NEXT:          case DISAS_NEXT:
2106              gen_op_jmp((long)dc->tb, (long)dc->pc);              gen_op_jmp1((long)dc->tb, (long)dc->pc);
2107              break;              break;
2108          default:          default:
2109          case DISAS_JUMP:          case DISAS_JUMP:
# Line 2088  static inline int gen_intermediate_code_ Line 2116  static inline int gen_intermediate_code_
2116              /* nothing more to generate */              /* nothing more to generate */
2117              break;              break;
2118          }          }
2119            if (dc->condjmp) {
2120                gen_set_label(dc->condlabel);
2121                gen_op_jmp1((long)dc->tb, (long)dc->pc);
2122                dc->condjmp = 0;
2123            }
2124      }      }
2125      *gen_opc_ptr = INDEX_op_end;      *gen_opc_ptr = INDEX_op_end;
2126    

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

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