Diff for /qemu/target-xtensa/translate.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2018/04/24 19:33:12 version 1.1.1.2, 2018/04/24 19:54:02
Line 37 Line 37
 #include "qemu-log.h"  #include "qemu-log.h"
 #include "sysemu.h"  #include "sysemu.h"
   
 #include "helpers.h"  #include "helper.h"
 #define GEN_HELPER 1  #define GEN_HELPER 1
 #include "helpers.h"  #include "helper.h"
   
 typedef struct DisasContext {  typedef struct DisasContext {
     const XtensaConfig *config;      const XtensaConfig *config;
Line 61  typedef struct DisasContext { Line 61  typedef struct DisasContext {
   
     uint32_t ccount_delta;      uint32_t ccount_delta;
     unsigned used_window;      unsigned used_window;
   
       bool debug;
       bool icount;
       TCGv_i32 next_icount;
 } DisasContext;  } DisasContext;
   
 static TCGv_ptr cpu_env;  static TCGv_ptr cpu_env;
Line 91  static const char * const sregnames[256] Line 95  static const char * const sregnames[256]
     [RASID] = "RASID",      [RASID] = "RASID",
     [ITLBCFG] = "ITLBCFG",      [ITLBCFG] = "ITLBCFG",
     [DTLBCFG] = "DTLBCFG",      [DTLBCFG] = "DTLBCFG",
       [IBREAKENABLE] = "IBREAKENABLE",
       [IBREAKA] = "IBREAKA0",
       [IBREAKA + 1] = "IBREAKA1",
       [DBREAKA] = "DBREAKA0",
       [DBREAKA + 1] = "DBREAKA1",
       [DBREAKC] = "DBREAKC0",
       [DBREAKC + 1] = "DBREAKC1",
     [EPC1] = "EPC1",      [EPC1] = "EPC1",
     [EPC1 + 1] = "EPC2",      [EPC1 + 1] = "EPC2",
     [EPC1 + 2] = "EPC3",      [EPC1 + 2] = "EPC3",
Line 119  static const char * const sregnames[256] Line 130  static const char * const sregnames[256]
     [PS] = "PS",      [PS] = "PS",
     [VECBASE] = "VECBASE",      [VECBASE] = "VECBASE",
     [EXCCAUSE] = "EXCCAUSE",      [EXCCAUSE] = "EXCCAUSE",
       [DEBUGCAUSE] = "DEBUGCAUSE",
     [CCOUNT] = "CCOUNT",      [CCOUNT] = "CCOUNT",
     [PRID] = "PRID",      [PRID] = "PRID",
       [ICOUNT] = "ICOUNT",
       [ICOUNTLEVEL] = "ICOUNTLEVEL",
     [EXCVADDR] = "EXCVADDR",      [EXCVADDR] = "EXCVADDR",
     [CCOMPARE] = "CCOMPARE0",      [CCOMPARE] = "CCOMPARE0",
     [CCOMPARE + 1] = "CCOMPARE1",      [CCOMPARE + 1] = "CCOMPARE1",
Line 145  void xtensa_translate_init(void) Line 159  void xtensa_translate_init(void)
   
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");      cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
     cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,      cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
             offsetof(CPUState, pc), "pc");              offsetof(CPUXtensaState, pc), "pc");
   
     for (i = 0; i < 16; i++) {      for (i = 0; i < 16; i++) {
         cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,          cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
                 offsetof(CPUState, regs[i]),                  offsetof(CPUXtensaState, regs[i]),
                 regnames[i]);                  regnames[i]);
     }      }
   
     for (i = 0; i < 256; ++i) {      for (i = 0; i < 256; ++i) {
         if (sregnames[i]) {          if (sregnames[i]) {
             cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,              cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
                     offsetof(CPUState, sregs[i]),                      offsetof(CPUXtensaState, sregs[i]),
                     sregnames[i]);                      sregnames[i]);
         }          }
     }      }
Line 164  void xtensa_translate_init(void) Line 178  void xtensa_translate_init(void)
     for (i = 0; i < 256; ++i) {      for (i = 0; i < 256; ++i) {
         if (uregnames[i]) {          if (uregnames[i]) {
             cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,              cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
                     offsetof(CPUState, uregs[i]),                      offsetof(CPUXtensaState, uregs[i]),
                     uregnames[i]);                      uregnames[i]);
         }          }
     }      }
 #define GEN_HELPER 2  #define GEN_HELPER 2
 #include "helpers.h"  #include "helper.h"
 }  }
   
 static inline bool option_bits_enabled(DisasContext *dc, uint64_t opt)  static inline bool option_bits_enabled(DisasContext *dc, uint64_t opt)
Line 283  static void gen_exception_cause_vaddr(Di Line 297  static void gen_exception_cause_vaddr(Di
     tcg_temp_free(tcause);      tcg_temp_free(tcause);
 }  }
   
   static void gen_debug_exception(DisasContext *dc, uint32_t cause)
   {
       TCGv_i32 tpc = tcg_const_i32(dc->pc);
       TCGv_i32 tcause = tcg_const_i32(cause);
       gen_advance_ccount(dc);
       gen_helper_debug_exception(tpc, tcause);
       tcg_temp_free(tpc);
       tcg_temp_free(tcause);
       if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
           dc->is_jmp = DISAS_UPDATE;
       }
   }
   
 static void gen_check_privilege(DisasContext *dc)  static void gen_check_privilege(DisasContext *dc)
 {  {
     if (dc->cring) {      if (dc->cring) {
Line 294  static void gen_check_privilege(DisasCon Line 321  static void gen_check_privilege(DisasCon
 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)  static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
 {  {
     tcg_gen_mov_i32(cpu_pc, dest);      tcg_gen_mov_i32(cpu_pc, dest);
       gen_advance_ccount(dc);
       if (dc->icount) {
           tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
       }
     if (dc->singlestep_enabled) {      if (dc->singlestep_enabled) {
         gen_exception(dc, EXCP_DEBUG);          gen_exception(dc, EXCP_DEBUG);
     } else {      } else {
         gen_advance_ccount(dc);  
         if (slot >= 0) {          if (slot >= 0) {
             tcg_gen_goto_tb(slot);              tcg_gen_goto_tb(slot);
             tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);              tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
Line 358  static bool gen_check_loop_end(DisasCont Line 388  static bool gen_check_loop_end(DisasCont
             dc->next_pc == dc->lend) {              dc->next_pc == dc->lend) {
         int label = gen_new_label();          int label = gen_new_label();
   
           gen_advance_ccount(dc);
         tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);          tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
         tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);          tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
         gen_jumpi(dc, dc->lbeg, slot);          gen_jumpi(dc, dc->lbeg, slot);
Line 380  static void gen_brcond(DisasContext *dc, Line 411  static void gen_brcond(DisasContext *dc,
 {  {
     int label = gen_new_label();      int label = gen_new_label();
   
       gen_advance_ccount(dc);
     tcg_gen_brcond_i32(cond, t0, t1, label);      tcg_gen_brcond_i32(cond, t0, t1, label);
     gen_jumpi_check_loop_end(dc, 0);      gen_jumpi_check_loop_end(dc, 0);
     gen_set_label(label);      gen_set_label(label);
Line 429  static void gen_rsr(DisasContext *dc, TC Line 461  static void gen_rsr(DisasContext *dc, TC
 static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)  static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 {  {
     gen_helper_wsr_lbeg(s);      gen_helper_wsr_lbeg(s);
       gen_jumpi_check_loop_end(dc, 0);
 }  }
   
 static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)  static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 {  {
     gen_helper_wsr_lend(s);      gen_helper_wsr_lend(s);
       gen_jumpi_check_loop_end(dc, 0);
 }  }
   
 static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)  static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
Line 492  static void gen_wsr_tlbcfg(DisasContext  Line 526  static void gen_wsr_tlbcfg(DisasContext 
     tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);      tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
 }  }
   
   static void gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
   {
       gen_helper_wsr_ibreakenable(v);
       gen_jumpi_check_loop_end(dc, 0);
   }
   
   static void gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
   {
       unsigned id = sr - IBREAKA;
   
       if (id < dc->config->nibreak) {
           TCGv_i32 tmp = tcg_const_i32(id);
           gen_helper_wsr_ibreaka(tmp, v);
           tcg_temp_free(tmp);
           gen_jumpi_check_loop_end(dc, 0);
       }
   }
   
   static void gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
   {
       unsigned id = sr - DBREAKA;
   
       if (id < dc->config->ndbreak) {
           TCGv_i32 tmp = tcg_const_i32(id);
           gen_helper_wsr_dbreaka(tmp, v);
           tcg_temp_free(tmp);
       }
   }
   
   static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
   {
       unsigned id = sr - DBREAKC;
   
       if (id < dc->config->ndbreak) {
           TCGv_i32 tmp = tcg_const_i32(id);
           gen_helper_wsr_dbreakc(tmp, v);
           tcg_temp_free(tmp);
       }
   }
   
 static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)  static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 {  {
     tcg_gen_andi_i32(cpu_SR[sr], v,      tcg_gen_andi_i32(cpu_SR[sr], v,
Line 535  static void gen_wsr_ps(DisasContext *dc, Line 609  static void gen_wsr_ps(DisasContext *dc,
     gen_jumpi_check_loop_end(dc, -1);      gen_jumpi_check_loop_end(dc, -1);
 }  }
   
   static void gen_wsr_debugcause(DisasContext *dc, uint32_t sr, TCGv_i32 v)
   {
   }
   
 static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v)  static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 {  {
 }  }
   
   static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
   {
       if (dc->icount) {
           tcg_gen_mov_i32(dc->next_icount, v);
       } else {
           tcg_gen_mov_i32(cpu_SR[sr], v);
       }
   }
   
   static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v)
   {
       tcg_gen_andi_i32(cpu_SR[sr], v, 0xf);
       /* This can change tb->flags, so exit tb */
       gen_jumpi_check_loop_end(dc, -1);
   }
   
 static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)  static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 {  {
     uint32_t id = sr - CCOMPARE;      uint32_t id = sr - CCOMPARE;
Line 567  static void gen_wsr(DisasContext *dc, ui Line 661  static void gen_wsr(DisasContext *dc, ui
         [RASID] = gen_wsr_rasid,          [RASID] = gen_wsr_rasid,
         [ITLBCFG] = gen_wsr_tlbcfg,          [ITLBCFG] = gen_wsr_tlbcfg,
         [DTLBCFG] = gen_wsr_tlbcfg,          [DTLBCFG] = gen_wsr_tlbcfg,
           [IBREAKENABLE] = gen_wsr_ibreakenable,
           [IBREAKA] = gen_wsr_ibreaka,
           [IBREAKA + 1] = gen_wsr_ibreaka,
           [DBREAKA] = gen_wsr_dbreaka,
           [DBREAKA + 1] = gen_wsr_dbreaka,
           [DBREAKC] = gen_wsr_dbreakc,
           [DBREAKC + 1] = gen_wsr_dbreakc,
         [INTSET] = gen_wsr_intset,          [INTSET] = gen_wsr_intset,
         [INTCLEAR] = gen_wsr_intclear,          [INTCLEAR] = gen_wsr_intclear,
         [INTENABLE] = gen_wsr_intenable,          [INTENABLE] = gen_wsr_intenable,
         [PS] = gen_wsr_ps,          [PS] = gen_wsr_ps,
           [DEBUGCAUSE] = gen_wsr_debugcause,
         [PRID] = gen_wsr_prid,          [PRID] = gen_wsr_prid,
           [ICOUNT] = gen_wsr_icount,
           [ICOUNTLEVEL] = gen_wsr_icountlevel,
         [CCOMPARE] = gen_wsr_ccompare,          [CCOMPARE] = gen_wsr_ccompare,
         [CCOMPARE + 1] = gen_wsr_ccompare,          [CCOMPARE + 1] = gen_wsr_ccompare,
         [CCOMPARE + 2] = gen_wsr_ccompare,          [CCOMPARE + 2] = gen_wsr_ccompare,
Line 749  static void disas_xtensa_insn(DisasConte Line 853  static void disas_xtensa_insn(DisasConte
   
     uint8_t b0 = ldub_code(dc->pc);      uint8_t b0 = ldub_code(dc->pc);
     uint8_t b1 = ldub_code(dc->pc + 1);      uint8_t b1 = ldub_code(dc->pc + 1);
     uint8_t b2 = ldub_code(dc->pc + 2);      uint8_t b2 = 0;
   
     static const uint32_t B4CONST[] = {      static const uint32_t B4CONST[] = {
         0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256          0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
Line 764  static void disas_xtensa_insn(DisasConte Line 868  static void disas_xtensa_insn(DisasConte
         HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);          HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);
     } else {      } else {
         dc->next_pc = dc->pc + 3;          dc->next_pc = dc->pc + 3;
           b2 = ldub_code(dc->pc + 2);
     }      }
   
     switch (OP0) {      switch (OP0) {
Line 968  static void disas_xtensa_insn(DisasConte Line 1073  static void disas_xtensa_insn(DisasConte
                     break;                      break;
   
                 case 4: /*BREAKx*/                  case 4: /*BREAKx*/
                     HAS_OPTION(XTENSA_OPTION_EXCEPTION);                      HAS_OPTION(XTENSA_OPTION_DEBUG);
                     TBD();                      if (dc->debug) {
                           gen_debug_exception(dc, DEBUGCAUSE_BI);
                       }
                     break;                      break;
   
                 case 5: /*SYSCALLx*/                  case 5: /*SYSCALLx*/
Line 2173  static void disas_xtensa_insn(DisasConte Line 2280  static void disas_xtensa_insn(DisasConte
   
                         tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1);                          tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1);
                         tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);                          tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
                         gen_wsr_lend(dc, LEND, tmp);                          gen_helper_wsr_lend(tmp);
                         tcg_temp_free(tmp);                          tcg_temp_free(tmp);
   
                         if (BRI8_R > 8) {                          if (BRI8_R > 8) {
Line 2349  static void disas_xtensa_insn(DisasConte Line 2456  static void disas_xtensa_insn(DisasConte
                 break;                  break;
   
             case 2: /*BREAK.Nn*/              case 2: /*BREAK.Nn*/
                 TBD();                  HAS_OPTION(XTENSA_OPTION_DEBUG);
                   if (dc->debug) {
                       gen_debug_exception(dc, DEBUGCAUSE_BN);
                   }
                 break;                  break;
   
             case 3: /*NOP.Nn*/              case 3: /*NOP.Nn*/
Line 2387  invalid_opcode: Line 2497  invalid_opcode:
 #undef HAS_OPTION  #undef HAS_OPTION
 }  }
   
 static void check_breakpoint(CPUState *env, DisasContext *dc)  static void check_breakpoint(CPUXtensaState *env, DisasContext *dc)
 {  {
     CPUBreakpoint *bp;      CPUBreakpoint *bp;
   
Line 2402  static void check_breakpoint(CPUState *e Line 2512  static void check_breakpoint(CPUState *e
     }      }
 }  }
   
   static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
   {
       unsigned i;
   
       for (i = 0; i < dc->config->nibreak; ++i) {
           if ((env->sregs[IBREAKENABLE] & (1 << i)) &&
                   env->sregs[IBREAKA + i] == dc->pc) {
               gen_debug_exception(dc, DEBUGCAUSE_IB);
               break;
           }
       }
   }
   
 static void gen_intermediate_code_internal(  static void gen_intermediate_code_internal(
         CPUState *env, TranslationBlock *tb, int search_pc)          CPUXtensaState *env, TranslationBlock *tb, int search_pc)
 {  {
     DisasContext dc;      DisasContext dc;
     int insn_count = 0;      int insn_count = 0;
Line 2428  static void gen_intermediate_code_intern Line 2551  static void gen_intermediate_code_intern
     dc.lend = env->sregs[LEND];      dc.lend = env->sregs[LEND];
     dc.is_jmp = DISAS_NEXT;      dc.is_jmp = DISAS_NEXT;
     dc.ccount_delta = 0;      dc.ccount_delta = 0;
       dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;
       dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;
   
     init_litbase(&dc);      init_litbase(&dc);
     init_sar_tracker(&dc);      init_sar_tracker(&dc);
     reset_used_window(&dc);      reset_used_window(&dc);
       if (dc.icount) {
           dc.next_icount = tcg_temp_local_new_i32();
       }
   
     gen_icount_start();      gen_icount_start();
   
Line 2467  static void gen_intermediate_code_intern Line 2595  static void gen_intermediate_code_intern
             gen_io_start();              gen_io_start();
         }          }
   
           if (dc.icount) {
               int label = gen_new_label();
   
               tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1);
               tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label);
               tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]);
               if (dc.debug) {
                   gen_debug_exception(&dc, DEBUGCAUSE_IC);
               }
               gen_set_label(label);
           }
   
           if (dc.debug) {
               gen_ibreak_check(env, &dc);
           }
   
         disas_xtensa_insn(&dc);          disas_xtensa_insn(&dc);
         ++insn_count;          ++insn_count;
           if (dc.icount) {
               tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
           }
         if (env->singlestep_enabled) {          if (env->singlestep_enabled) {
             tcg_gen_movi_i32(cpu_pc, dc.pc);              tcg_gen_movi_i32(cpu_pc, dc.pc);
             gen_exception(&dc, EXCP_DEBUG);              gen_exception(&dc, EXCP_DEBUG);
Line 2481  static void gen_intermediate_code_intern Line 2628  static void gen_intermediate_code_intern
   
     reset_litbase(&dc);      reset_litbase(&dc);
     reset_sar_tracker(&dc);      reset_sar_tracker(&dc);
       if (dc.icount) {
           tcg_temp_free(dc.next_icount);
       }
   
     if (tb->cflags & CF_LAST_IO) {      if (tb->cflags & CF_LAST_IO) {
         gen_io_end();          gen_io_end();
Line 2498  static void gen_intermediate_code_intern Line 2648  static void gen_intermediate_code_intern
     }      }
 }  }
   
 void gen_intermediate_code(CPUState *env, TranslationBlock *tb)  void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
 {  {
     gen_intermediate_code_internal(env, tb, 0);      gen_intermediate_code_internal(env, tb, 0);
 }  }
   
 void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)  void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb)
 {  {
     gen_intermediate_code_internal(env, tb, 1);      gen_intermediate_code_internal(env, tb, 1);
 }  }
   
 void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,  void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
         int flags)          int flags)
 {  {
     int i, j;      int i, j;
Line 2546  void cpu_dump_state(CPUState *env, FILE  Line 2696  void cpu_dump_state(CPUState *env, FILE 
     }      }
 }  }
   
 void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)  void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, int pc_pos)
 {  {
     env->pc = gen_opc_pc[pc_pos];      env->pc = gen_opc_pc[pc_pos];
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


unix.superglobalmegacorp.com