summaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2008-09-26 18:05:23 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2008-09-26 18:05:23 +0000
commitb158a785d2f58469b5c78c2484a7c1b22e9dbaaa (patch)
tree2b1289a16096031bb490ce4ae2d2aa7a903f5e69 /target-sparc
parentd81fd7220e02c7ddb708fc16e26adfb36f6c430d (diff)
Implement UA2005 hypervisor traps
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5327 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/helper.h2
-rw-r--r--target-sparc/op_helper.c14
-rw-r--r--target-sparc/translate.c25
3 files changed, 23 insertions, 18 deletions
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index e85ed344b1..5e07917b27 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -38,8 +38,6 @@ DEF_HELPER(void, helper_tick_set_count, (void *opaque, uint64_t count))
DEF_HELPER(uint64_t, helper_tick_get_count, (void *opaque))
DEF_HELPER(void, helper_tick_set_limit, (void *opaque, uint64_t limit))
#endif
-DEF_HELPER(void, helper_trap, (target_ulong nb_trap))
-DEF_HELPER(void, helper_trapcc, (target_ulong nb_trap, target_ulong do_trap))
DEF_HELPER(void, helper_check_align, (target_ulong addr, uint32_t align))
DEF_HELPER(void, helper_debug, (void))
DEF_HELPER(void, helper_save, (void))
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 64b56e3864..47b4b87aae 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -55,20 +55,6 @@ void raise_exception(int tt)
cpu_loop_exit();
}
-void helper_trap(target_ulong nb_trap)
-{
- env->exception_index = TT_TRAP + (nb_trap & 0x7f);
- cpu_loop_exit();
-}
-
-void helper_trapcc(target_ulong nb_trap, target_ulong do_trap)
-{
- if (do_trap) {
- env->exception_index = TT_TRAP + (nb_trap & 0x7f);
- cpu_loop_exit();
- }
-}
-
static inline void set_cwp(int new_cwp)
{
cpu_set_cwp(env, new_cwp);
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index abea2f15a2..0391bcf93d 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -93,6 +93,9 @@ typedef struct DisasContext {
#define QFPREG(r) (r & 0x1c)
#endif
+#define UA2005_HTRAP_MASK 0xff
+#define V8_TRAP_MASK 0x7f
+
static int sign_extend(int x, int len)
{
len = 32 - len;
@@ -2019,9 +2022,16 @@ static void disas_sparc_insn(DisasContext * dc)
cond = GET_FIELD(insn, 3, 6);
if (cond == 0x8) {
save_state(dc, cpu_cond);
- tcg_gen_helper_0_1(helper_trap, cpu_dst);
+ if ((dc->def->features & CPU_FEATURE_HYPV) &&
+ supervisor(dc))
+ tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
+ else
+ tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
+ tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
+ tcg_gen_helper_0_1(raise_exception, cpu_dst);
} else if (cond != 0) {
TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
+ int l1;
#ifdef TARGET_SPARC64
/* V9 icc/xcc */
int cc = GET_FIELD_SP(insn, 11, 12);
@@ -2037,7 +2047,18 @@ static void disas_sparc_insn(DisasContext * dc)
save_state(dc, cpu_cond);
gen_cond(r_cond, 0, cond);
#endif
- tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
+ l1 = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
+
+ if ((dc->def->features & CPU_FEATURE_HYPV) &&
+ supervisor(dc))
+ tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
+ else
+ tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
+ tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
+ tcg_gen_helper_0_1(raise_exception, cpu_dst);
+
+ gen_set_label(l1);
tcg_temp_free(r_cond);
}
gen_op_next_insn();