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) | ... | ... |