diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-09-26 18:05:23 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-09-26 18:05:23 +0000 |
commit | b158a785d2f58469b5c78c2484a7c1b22e9dbaaa (patch) | |
tree | 2b1289a16096031bb490ce4ae2d2aa7a903f5e69 /target-sparc | |
parent | d81fd7220e02c7ddb708fc16e26adfb36f6c430d (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.h | 2 | ||||
-rw-r--r-- | target-sparc/op_helper.c | 14 | ||||
-rw-r--r-- | target-sparc/translate.c | 25 |
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(); |