aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2011-01-12 17:39:36 +0200
committerMichael S. Tsirkin <mst@redhat.com>2011-01-12 17:39:36 +0200
commitc2e08bddcd1fa32415c0ee5aa6d3c88a258db4c0 (patch)
tree9ee42d082f17ebb559a69e90a3e7c3f0fa6cad54
parentb36e391441906c36ed0856b69de84001860402bf (diff)
parent05bf441eb69a813d3893174d54faa6afa8c0d39b (diff)
Merge remote branch 'origin/master' into pci
-rw-r--r--cris-dis.c9
-rw-r--r--dis-asm.h1
-rw-r--r--disas.c9
-rw-r--r--target-cris/translate.c41
-rw-r--r--target-cris/translate_v10.c10
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)
{
diff --git a/dis-asm.h b/dis-asm.h
index 3fb483815a..356459c5fd 100644
--- a/dis-asm.h
+++ b/dis-asm.h
@@ -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*);
diff --git a/disas.c b/disas.c
index afe331fdb9..dd2db142d7 100644
--- a/disas.c
+++ b/disas.c
@@ -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. */