diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2011-01-12 17:39:36 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2011-01-12 17:39:36 +0200 |
commit | c2e08bddcd1fa32415c0ee5aa6d3c88a258db4c0 (patch) | |
tree | 9ee42d082f17ebb559a69e90a3e7c3f0fa6cad54 | |
parent | b36e391441906c36ed0856b69de84001860402bf (diff) | |
parent | 05bf441eb69a813d3893174d54faa6afa8c0d39b (diff) |
Merge remote branch 'origin/master' into pci
-rw-r--r-- | cris-dis.c | 9 | ||||
-rw-r--r-- | dis-asm.h | 1 | ||||
-rw-r--r-- | disas.c | 9 | ||||
-rw-r--r-- | target-cris/translate.c | 41 | ||||
-rw-r--r-- | target-cris/translate_v10.c | 10 |
5 files changed, 50 insertions, 20 deletions
diff --git a/cris-dis.c b/cris-dis.c index afd775c29b..5fa67d9f29 100644 --- a/cris-dis.c +++ b/cris-dis.c @@ -2767,7 +2767,6 @@ print_insn_cris_generic (bfd_vma memaddr, } /* Disassemble, prefixing register names with `$'. CRIS v0..v10. */ -#if 0 static int print_insn_cris_with_register_prefix (bfd_vma vma, disassemble_info *info) @@ -2777,7 +2776,6 @@ print_insn_cris_with_register_prefix (bfd_vma vma, return -1; return print_insn_cris_generic (vma, info, true); } -#endif /* Disassemble, prefixing register names with `$'. CRIS v32. */ static int @@ -2843,6 +2841,13 @@ print_insn_crisv10_v32_without_register_prefix (bfd_vma vma, #endif int +print_insn_crisv10 (bfd_vma vma, + disassemble_info *info) +{ + return print_insn_cris_with_register_prefix(vma, info); +} + +int print_insn_crisv32 (bfd_vma vma, disassemble_info *info) { @@ -397,6 +397,7 @@ extern int print_insn_tic30 (bfd_vma, disassemble_info*); extern int print_insn_ppc (bfd_vma, disassemble_info*); extern int print_insn_s390 (bfd_vma, disassemble_info*); extern int print_insn_crisv32 (bfd_vma, disassemble_info*); +extern int print_insn_crisv10 (bfd_vma, disassemble_info*); extern int print_insn_microblaze (bfd_vma, disassemble_info*); extern int print_insn_ia64 (bfd_vma, disassemble_info*); @@ -208,8 +208,13 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) disasm_info.mach = bfd_mach_alpha; print_insn = print_insn_alpha; #elif defined(TARGET_CRIS) - disasm_info.mach = bfd_mach_cris_v32; - print_insn = print_insn_crisv32; + if (flags != 32) { + disasm_info.mach = bfd_mach_cris_v0_v10; + print_insn = print_insn_crisv10; + } else { + disasm_info.mach = bfd_mach_cris_v32; + print_insn = print_insn_crisv32; + } #elif defined(TARGET_MICROBLAZE) disasm_info.mach = bfd_arch_microblaze; print_insn = print_insn_microblaze; diff --git a/target-cris/translate.c b/target-cris/translate.c index 5184155302..e09aaa9e9d 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -120,9 +120,10 @@ typedef struct DisasContext { unsigned int tb_flags; /* tb dependent flags. */ int is_jmp; -#define JMP_NOJMP 0 -#define JMP_DIRECT 1 -#define JMP_INDIRECT 2 +#define JMP_NOJMP 0 +#define JMP_DIRECT 1 +#define JMP_DIRECT_CC 2 +#define JMP_INDIRECT 3 int jmp; /* 0=nojmp, 1=direct, 2=indirect. */ uint32_t jmp_pc; @@ -1127,7 +1128,7 @@ static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond) static void cris_store_direct_jmp(DisasContext *dc) { /* Store the direct jmp state into the cpu-state. */ - if (dc->jmp == JMP_DIRECT) { + if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) { tcg_gen_movi_tl(env_btarget, dc->jmp_pc); dc->jmp = JMP_INDIRECT; } @@ -1139,7 +1140,7 @@ static void cris_prepare_cc_branch (DisasContext *dc, /* This helps us re-schedule the micro-code to insns in delay-slots before the actual jump. */ dc->delayed_branch = 2; - dc->jmp = JMP_DIRECT; + dc->jmp = JMP_DIRECT_CC; dc->jmp_pc = dc->pc + offset; gen_tst_cc (dc, env_btaken, cond); @@ -1155,7 +1156,9 @@ static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type) before the actual jump. */ dc->delayed_branch = 2; dc->jmp = type; - tcg_gen_movi_tl(env_btaken, 1); + if (type == JMP_INDIRECT) { + tcg_gen_movi_tl(env_btaken, 1); + } } static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr) @@ -3182,7 +3185,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, { uint16_t *gen_opc_end; uint32_t pc_start; - unsigned int insn_len, orig_flags; + unsigned int insn_len; int j, lj; struct DisasContext ctx; struct DisasContext *dc = &ctx; @@ -3193,10 +3196,13 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, qemu_log_try_set_file(stderr); - if (env->pregs[PR_VR] == 32) + if (env->pregs[PR_VR] == 32) { dc->decoder = crisv32_decoder; - else + dc->clear_locked_irq = 0; + } else { dc->decoder = crisv10_decoder; + dc->clear_locked_irq = 1; + } /* Odd PC indicates that branch is rexecuting due to exception in the * delayslot, like in real hw. @@ -3218,13 +3224,12 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, dc->cc_mask = 0; dc->update_cc = 0; dc->clear_prefix = 0; - dc->clear_locked_irq = 1; cris_update_cc_op(dc, CC_OP_FLAGS, 4); dc->cc_size_uptodate = -1; /* Decode TB flags. */ - orig_flags = dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \ + dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \ | X_FLAG | PFIX_FLAG); dc->delayed_branch = !!(tb->flags & 7); if (dc->delayed_branch) @@ -3312,7 +3317,14 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, || (dc->flags_x != (tb->flags & X_FLAG))) { cris_store_direct_jmp(dc); } - if (dc->jmp == JMP_DIRECT) { + + if (dc->clear_locked_irq) { + dc->clear_locked_irq = 0; + t_gen_mov_env_TN(locked_irq, + tcg_const_tl(0)); + } + + if (dc->jmp == JMP_DIRECT_CC) { int l1; l1 = gen_new_label(); @@ -3326,6 +3338,11 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, gen_goto_tb(dc, 0, dc->pc); dc->is_jmp = DISAS_TB_JUMP; dc->jmp = JMP_NOJMP; + } else if (dc->jmp == JMP_DIRECT) { + cris_evaluate_flags(dc); + gen_goto_tb(dc, 0, dc->jmp_pc); + dc->is_jmp = DISAS_TB_JUMP; + dc->jmp = JMP_NOJMP; } else { t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc)); diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c index 6944827a57..41db158965 100644 --- a/target-cris/translate_v10.c +++ b/target-cris/translate_v10.c @@ -1060,15 +1060,15 @@ static unsigned int dec10_ind(DisasContext *dc) break; case CRISV10_IND_JUMP_M: if (dc->src == 15) { - LOG_DIS("jump.%d %d r%d r%d\n", size, + LOG_DIS("jump.%d %d r%d r%d direct\n", size, dc->opcode, dc->src, dc->dst); imm = ldl_code(dc->pc + 2); if (dc->mode == CRISV10_MODE_AUTOINC) insn_len += size; t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len)); - tcg_gen_movi_tl(env_btarget, imm); - cris_prepare_jmp(dc, JMP_INDIRECT); + dc->jmp_pc = imm; + cris_prepare_jmp(dc, JMP_DIRECT); dc->delayed_branch--; /* v10 has no dslot here. */ } else { if (dc->dst == 14) { @@ -1184,7 +1184,9 @@ static unsigned int crisv10_decoder(DisasContext *dc) if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) { dc->tb_flags &= ~PFIX_FLAG; tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG); - dc->cpustate_changed = 1; + if (dc->tb_flags != dc->tb->flags) { + dc->cpustate_changed = 1; + } } /* CRISv10 locks out interrupts on dslots. */ |