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,7 +220,7 @@ static inline TranslationBlock *tb_find_fast(void) | ||
| 220 | cs_base = 0; | 220 | cs_base = 0; |
| 221 | pc = env->pc; | 221 | pc = env->pc; |
| 222 | #elif defined(TARGET_CRIS) | 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 | flags |= env->dslot; | 224 | flags |= env->dslot; |
| 225 | cs_base = 0; | 225 | cs_base = 0; |
| 226 | pc = env->pc; | 226 | pc = env->pc; |
target-cris/helper.c
| @@ -119,7 +119,7 @@ void do_interrupt(CPUState *env) | @@ -119,7 +119,7 @@ void do_interrupt(CPUState *env) | ||
| 119 | /* These exceptions are genereated by the core itself. | 119 | /* These exceptions are genereated by the core itself. |
| 120 | ERP should point to the insn following the brk. */ | 120 | ERP should point to the insn following the brk. */ |
| 121 | ex_vec = env->trap_vector; | 121 | ex_vec = env->trap_vector; |
| 122 | - env->pregs[PR_ERP] = env->pc + 2; | 122 | + env->pregs[PR_ERP] = env->pc; |
| 123 | break; | 123 | break; |
| 124 | 124 | ||
| 125 | case EXCP_NMI: | 125 | case EXCP_NMI: |
target-cris/helper.h
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | void TCG_HELPER_PROTO helper_raise_exception(uint32_t index); | 3 | void TCG_HELPER_PROTO helper_raise_exception(uint32_t index); |
| 4 | void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid); | 4 | void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid); |
| 5 | +void TCG_HELPER_PROTO helper_spc_write(uint32_t pid); | ||
| 5 | void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2); | 6 | void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2); |
| 6 | void TCG_HELPER_PROTO helper_rfe(void); | 7 | void TCG_HELPER_PROTO helper_rfe(void); |
| 7 | void TCG_HELPER_PROTO helper_rfn(void); | 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,6 +97,14 @@ void helper_tlb_flush_pid(uint32_t pid) | ||
| 97 | #endif | 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 | void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2) | 108 | void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2) |
| 101 | { | 109 | { |
| 102 | (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1)); | 110 | (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1)); |
target-cris/translate.c
| @@ -41,7 +41,7 @@ | @@ -41,7 +41,7 @@ | ||
| 41 | 41 | ||
| 42 | #define DISAS_CRIS 0 | 42 | #define DISAS_CRIS 0 |
| 43 | #if DISAS_CRIS | 43 | #if DISAS_CRIS |
| 44 | -#define DIS(x) x | 44 | +#define DIS(x) if (loglevel & CPU_LOG_TB_IN_ASM) x |
| 45 | #else | 45 | #else |
| 46 | #define DIS(x) | 46 | #define DIS(x) |
| 47 | #endif | 47 | #endif |
| @@ -218,6 +218,8 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn) | @@ -218,6 +218,8 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn) | ||
| 218 | else { | 218 | else { |
| 219 | if (r == PR_PID) | 219 | if (r == PR_PID) |
| 220 | tcg_gen_helper_0_1(helper_tlb_flush_pid, tn); | 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 | else if (r == PR_CCS) | 223 | else if (r == PR_CCS) |
| 222 | dc->cpustate_changed = 1; | 224 | dc->cpustate_changed = 1; |
| 223 | tcg_gen_mov_tl(cpu_PR[r], tn); | 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,8 +1379,6 @@ static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize, | ||
| 1377 | } else | 1379 | } else |
| 1378 | imm = ldl_code(dc->pc + 2); | 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 | tcg_gen_movi_tl(dst, imm); | 1382 | tcg_gen_movi_tl(dst, imm); |
| 1383 | dc->postinc = 0; | 1383 | dc->postinc = 0; |
| 1384 | } else { | 1384 | } else { |
| @@ -2063,7 +2063,7 @@ static unsigned int dec_setclrf(DisasContext *dc) | @@ -2063,7 +2063,7 @@ static unsigned int dec_setclrf(DisasContext *dc) | ||
| 2063 | 2063 | ||
| 2064 | /* User space is not allowed to touch these. Silently ignore. */ | 2064 | /* User space is not allowed to touch these. Silently ignore. */ |
| 2065 | if (dc->tb_flags & U_FLAG) { | 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 | if (flags & X_FLAG) { | 2069 | if (flags & X_FLAG) { |
| @@ -2083,6 +2083,9 @@ static unsigned int dec_setclrf(DisasContext *dc) | @@ -2083,6 +2083,9 @@ static unsigned int dec_setclrf(DisasContext *dc) | ||
| 2083 | dc->cpustate_changed = 1; | 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 | /* Simply decode the flags. */ | 2091 | /* Simply decode the flags. */ |
| @@ -2784,9 +2787,6 @@ static unsigned int dec_basc_im(DisasContext *dc) | @@ -2784,9 +2787,6 @@ static unsigned int dec_basc_im(DisasContext *dc) | ||
| 2784 | 2787 | ||
| 2785 | static unsigned int dec_rfe_etc(DisasContext *dc) | 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 | cris_cc_mask(dc, 0); | 2790 | cris_cc_mask(dc, 0); |
| 2791 | 2791 | ||
| 2792 | if (dc->op2 == 15) /* ignore halt. */ | 2792 | if (dc->op2 == 15) /* ignore halt. */ |
| @@ -2795,19 +2795,29 @@ static unsigned int dec_rfe_etc(DisasContext *dc) | @@ -2795,19 +2795,29 @@ static unsigned int dec_rfe_etc(DisasContext *dc) | ||
| 2795 | switch (dc->op2 & 7) { | 2795 | switch (dc->op2 & 7) { |
| 2796 | case 2: | 2796 | case 2: |
| 2797 | /* rfe. */ | 2797 | /* rfe. */ |
| 2798 | + DIS(fprintf(logfile, "rfe\n")); | ||
| 2798 | cris_evaluate_flags(dc); | 2799 | cris_evaluate_flags(dc); |
| 2799 | tcg_gen_helper_0_0(helper_rfe); | 2800 | tcg_gen_helper_0_0(helper_rfe); |
| 2800 | dc->is_jmp = DISAS_UPDATE; | 2801 | dc->is_jmp = DISAS_UPDATE; |
| 2801 | break; | 2802 | break; |
| 2802 | case 5: | 2803 | case 5: |
| 2803 | /* rfn. */ | 2804 | /* rfn. */ |
| 2805 | + DIS(fprintf(logfile, "rfn\n")); | ||
| 2804 | cris_evaluate_flags(dc); | 2806 | cris_evaluate_flags(dc); |
| 2805 | tcg_gen_helper_0_0(helper_rfn); | 2807 | tcg_gen_helper_0_0(helper_rfn); |
| 2806 | dc->is_jmp = DISAS_UPDATE; | 2808 | dc->is_jmp = DISAS_UPDATE; |
| 2807 | break; | 2809 | break; |
| 2808 | case 6: | 2810 | case 6: |
| 2811 | + DIS(fprintf(logfile, "break %d\n", dc->op1)); | ||
| 2812 | + cris_evaluate_flags (dc); | ||
| 2809 | /* break. */ | 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 | /* Breaks start at 16 in the exception vector. */ | 2821 | /* Breaks start at 16 in the exception vector. */ |
| 2812 | t_gen_mov_env_TN(trap_vector, | 2822 | t_gen_mov_env_TN(trap_vector, |
| 2813 | tcg_const_tl(dc->op1 + 16)); | 2823 | tcg_const_tl(dc->op1 + 16)); |
| @@ -2984,6 +2994,22 @@ cris_decoder(DisasContext *dc) | @@ -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 | return insn_len; | 3013 | return insn_len; |
| 2988 | } | 3014 | } |
| 2989 | 3015 | ||
| @@ -3080,7 +3106,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | @@ -3080,7 +3106,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | ||
| 3080 | dc->cc_size_uptodate = -1; | 3106 | dc->cc_size_uptodate = -1; |
| 3081 | 3107 | ||
| 3082 | /* Decode TB flags. */ | 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 | dc->delayed_branch = !!(tb->flags & 7); | 3110 | dc->delayed_branch = !!(tb->flags & 7); |
| 3085 | if (dc->delayed_branch) | 3111 | if (dc->delayed_branch) |
| 3086 | dc->jmp = JMP_INDIRECT; | 3112 | dc->jmp = JMP_INDIRECT; |
| @@ -3108,7 +3134,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | @@ -3108,7 +3134,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | ||
| 3108 | env->regs[10], env->regs[11], | 3134 | env->regs[10], env->regs[11], |
| 3109 | env->regs[12], env->regs[13], | 3135 | env->regs[12], env->regs[13], |
| 3110 | env->regs[14], env->regs[15]); | 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 | next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; | 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,10 +3166,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | ||
| 3139 | } | 3166 | } |
| 3140 | 3167 | ||
| 3141 | /* Pretty disas. */ | 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 | if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) | 3171 | if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) |
| 3148 | gen_io_start(); | 3172 | gen_io_start(); |
| @@ -3241,14 +3265,14 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | @@ -3241,14 +3265,14 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, | ||
| 3241 | } | 3265 | } |
| 3242 | 3266 | ||
| 3243 | #ifdef DEBUG_DISAS | 3267 | #ifdef DEBUG_DISAS |
| 3268 | +#if !DISAS_CRIS | ||
| 3244 | if (loglevel & CPU_LOG_TB_IN_ASM) { | 3269 | if (loglevel & CPU_LOG_TB_IN_ASM) { |
| 3245 | - fprintf(logfile, "--------------\n"); | ||
| 3246 | - fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start)); | ||
| 3247 | target_disas(logfile, pc_start, dc->pc - pc_start, 0); | 3270 | target_disas(logfile, pc_start, dc->pc - pc_start, 0); |
| 3248 | fprintf(logfile, "\nisize=%d osize=%zd\n", | 3271 | fprintf(logfile, "\nisize=%d osize=%zd\n", |
| 3249 | dc->pc - pc_start, gen_opc_ptr - gen_opc_buf); | 3272 | dc->pc - pc_start, gen_opc_ptr - gen_opc_buf); |
| 3250 | } | 3273 | } |
| 3251 | #endif | 3274 | #endif |
| 3275 | +#endif | ||
| 3252 | } | 3276 | } |
| 3253 | 3277 | ||
| 3254 | void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) | 3278 | void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) |