Commit a1aebcb8e68a90b9fe130aef6b2667e4369574b4

Authored by edgar_igl
1 parent 890b1658

CRIS: Fix brk 8 and add S-flag emulation.

* break 8 sets ERP to the current insn.
* First shot at S flag single-stepping.
* Make it easier to use the local disasm.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5445 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
... ... @@ -220,7 +220,7 @@ static inline TranslationBlock *tb_find_fast(void)
220 220 cs_base = 0;
221 221 pc = env->pc;
222 222 #elif defined(TARGET_CRIS)
223   - flags = env->pregs[PR_CCS] & (P_FLAG | U_FLAG | X_FLAG);
  223 + flags = env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG | X_FLAG);
224 224 flags |= env->dslot;
225 225 cs_base = 0;
226 226 pc = env->pc;
... ...
target-cris/helper.c
... ... @@ -119,7 +119,7 @@ void do_interrupt(CPUState *env)
119 119 /* These exceptions are genereated by the core itself.
120 120 ERP should point to the insn following the brk. */
121 121 ex_vec = env->trap_vector;
122   - env->pregs[PR_ERP] = env->pc + 2;
  122 + env->pregs[PR_ERP] = env->pc;
123 123 break;
124 124  
125 125 case EXCP_NMI:
... ...
target-cris/helper.h
... ... @@ -2,6 +2,7 @@
2 2  
3 3 void TCG_HELPER_PROTO helper_raise_exception(uint32_t index);
4 4 void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid);
  5 +void TCG_HELPER_PROTO helper_spc_write(uint32_t pid);
5 6 void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2);
6 7 void TCG_HELPER_PROTO helper_rfe(void);
7 8 void TCG_HELPER_PROTO helper_rfn(void);
... ...
target-cris/op_helper.c
... ... @@ -97,6 +97,14 @@ void helper_tlb_flush_pid(uint32_t pid)
97 97 #endif
98 98 }
99 99  
  100 +void helper_spc_write(uint32_t new_spc)
  101 +{
  102 +#if !defined(CONFIG_USER_ONLY)
  103 + tlb_flush_page(env, env->pregs[PR_SPC]);
  104 + tlb_flush_page(env, new_spc);
  105 +#endif
  106 +}
  107 +
100 108 void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
101 109 {
102 110 (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1));
... ...
target-cris/translate.c
... ... @@ -41,7 +41,7 @@
41 41  
42 42 #define DISAS_CRIS 0
43 43 #if DISAS_CRIS
44   -#define DIS(x) x
  44 +#define DIS(x) if (loglevel & CPU_LOG_TB_IN_ASM) x
45 45 #else
46 46 #define DIS(x)
47 47 #endif
... ... @@ -218,6 +218,8 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
218 218 else {
219 219 if (r == PR_PID)
220 220 tcg_gen_helper_0_1(helper_tlb_flush_pid, tn);
  221 + if (dc->tb_flags & S_FLAG && r == PR_SPC)
  222 + tcg_gen_helper_0_1(helper_spc_write, tn);
221 223 else if (r == PR_CCS)
222 224 dc->cpustate_changed = 1;
223 225 tcg_gen_mov_tl(cpu_PR[r], tn);
... ... @@ -1377,8 +1379,6 @@ static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
1377 1379 } else
1378 1380 imm = ldl_code(dc->pc + 2);
1379 1381  
1380   - DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
1381   - imm, rd, s_ext, memsize));
1382 1382 tcg_gen_movi_tl(dst, imm);
1383 1383 dc->postinc = 0;
1384 1384 } else {
... ... @@ -2063,7 +2063,7 @@ static unsigned int dec_setclrf(DisasContext *dc)
2063 2063  
2064 2064 /* User space is not allowed to touch these. Silently ignore. */
2065 2065 if (dc->tb_flags & U_FLAG) {
2066   - flags &= ~(I_FLAG | U_FLAG);
  2066 + flags &= ~(S_FLAG | I_FLAG | U_FLAG);
2067 2067 }
2068 2068  
2069 2069 if (flags & X_FLAG) {
... ... @@ -2083,6 +2083,9 @@ static unsigned int dec_setclrf(DisasContext *dc)
2083 2083 dc->cpustate_changed = 1;
2084 2084 }
2085 2085 }
  2086 + if (flags & S_FLAG) {
  2087 + dc->cpustate_changed = 1;
  2088 + }
2086 2089  
2087 2090  
2088 2091 /* Simply decode the flags. */
... ... @@ -2784,9 +2787,6 @@ static unsigned int dec_basc_im(DisasContext *dc)
2784 2787  
2785 2788 static unsigned int dec_rfe_etc(DisasContext *dc)
2786 2789 {
2787   - DIS(fprintf (logfile, "rfe_etc opc=%x pc=0x%x op1=%d op2=%d\n",
2788   - dc->opcode, dc->pc, dc->op1, dc->op2));
2789   -
2790 2790 cris_cc_mask(dc, 0);
2791 2791  
2792 2792 if (dc->op2 == 15) /* ignore halt. */
... ... @@ -2795,19 +2795,29 @@ static unsigned int dec_rfe_etc(DisasContext *dc)
2795 2795 switch (dc->op2 & 7) {
2796 2796 case 2:
2797 2797 /* rfe. */
  2798 + DIS(fprintf(logfile, "rfe\n"));
2798 2799 cris_evaluate_flags(dc);
2799 2800 tcg_gen_helper_0_0(helper_rfe);
2800 2801 dc->is_jmp = DISAS_UPDATE;
2801 2802 break;
2802 2803 case 5:
2803 2804 /* rfn. */
  2805 + DIS(fprintf(logfile, "rfn\n"));
2804 2806 cris_evaluate_flags(dc);
2805 2807 tcg_gen_helper_0_0(helper_rfn);
2806 2808 dc->is_jmp = DISAS_UPDATE;
2807 2809 break;
2808 2810 case 6:
  2811 + DIS(fprintf(logfile, "break %d\n", dc->op1));
  2812 + cris_evaluate_flags (dc);
2809 2813 /* break. */
2810   - tcg_gen_movi_tl(env_pc, dc->pc);
  2814 + if (dc->op1 == 8) {
  2815 + /* TODO: Find out whats special with brk8. */
  2816 + tcg_gen_movi_tl(env_pc, dc->pc);
  2817 + }
  2818 + else
  2819 + tcg_gen_movi_tl(env_pc, dc->pc + 2);
  2820 +
2811 2821 /* Breaks start at 16 in the exception vector. */
2812 2822 t_gen_mov_env_TN(trap_vector,
2813 2823 tcg_const_tl(dc->op1 + 16));
... ... @@ -2984,6 +2994,22 @@ cris_decoder(DisasContext *dc)
2984 2994 }
2985 2995 }
2986 2996  
  2997 +#if defined(CONFIG_USER_ONLY)
  2998 + /* Single-stepping ? */
  2999 + if (dc->tb_flags & S_FLAG) {
  3000 + int l1;
  3001 +
  3002 + l1 = gen_new_label();
  3003 + tcg_gen_brcondi_tl(TCG_COND_NE,
  3004 + cpu_PR[PR_SPC], tcg_const_tl(dc->pc), l1);
  3005 + /* We treat SPC as a break with an odd trap vector. */
  3006 + cris_evaluate_flags (dc);
  3007 + t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
  3008 + tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
  3009 + t_gen_raise_exception(EXCP_BREAK);
  3010 + gen_set_label(l1);
  3011 + }
  3012 +#endif
2987 3013 return insn_len;
2988 3014 }
2989 3015  
... ... @@ -3080,7 +3106,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3080 3106 dc->cc_size_uptodate = -1;
3081 3107  
3082 3108 /* Decode TB flags. */
3083   - dc->tb_flags = tb->flags & (P_FLAG | U_FLAG | X_FLAG);
  3109 + dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG);
3084 3110 dc->delayed_branch = !!(tb->flags & 7);
3085 3111 if (dc->delayed_branch)
3086 3112 dc->jmp = JMP_INDIRECT;
... ... @@ -3108,7 +3134,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3108 3134 env->regs[10], env->regs[11],
3109 3135 env->regs[12], env->regs[13],
3110 3136 env->regs[14], env->regs[15]);
3111   -
  3137 + fprintf(logfile, "--------------\n");
  3138 + fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3112 3139 }
3113 3140  
3114 3141 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
... ... @@ -3139,10 +3166,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3139 3166 }
3140 3167  
3141 3168 /* Pretty disas. */
3142   - DIS(fprintf(logfile, "%x ", dc->pc));
3143   - if (search_pc) {
3144   - DIS(fprintf(logfile, "%x ", dc->pc));
3145   - }
  3169 + DIS(fprintf(logfile, "%8.8x:\t", dc->pc));
3146 3170  
3147 3171 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
3148 3172 gen_io_start();
... ... @@ -3241,14 +3265,14 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
3241 3265 }
3242 3266  
3243 3267 #ifdef DEBUG_DISAS
  3268 +#if !DISAS_CRIS
3244 3269 if (loglevel & CPU_LOG_TB_IN_ASM) {
3245   - fprintf(logfile, "--------------\n");
3246   - fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3247 3270 target_disas(logfile, pc_start, dc->pc - pc_start, 0);
3248 3271 fprintf(logfile, "\nisize=%d osize=%zd\n",
3249 3272 dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
3250 3273 }
3251 3274 #endif
  3275 +#endif
3252 3276 }
3253 3277  
3254 3278 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
... ...