Commit a1aebcb8e68a90b9fe130aef6b2667e4369574b4
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
Showing
5 changed files
with
51 additions
and
18 deletions
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) | ... | ... |