aboutsummaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2008-03-14 19:42:42 +0000
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>2008-03-14 19:42:42 +0000
commit1a7b60e727d10b55fe573a471662442306eaa24b (patch)
tree463cfbc048c084aeae782c0b248c82bbfeaf7802 /target-sparc
parente01a11572f99b5e9266f0d53bfd1be3c19544d77 (diff)
downloadqemu-1a7b60e727d10b55fe573a471662442306eaa24b.zip
qemu-1a7b60e727d10b55fe573a471662442306eaa24b.tar.gz
qemu-1a7b60e727d10b55fe573a471662442306eaa24b.tar.bz2
Convert udivx and sdivx to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4064 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/op.c23
-rw-r--r--target-sparc/translate.c31
2 files changed, 30 insertions, 24 deletions
diff --git a/target-sparc/op.c b/target-sparc/op.c
index 0c3e090..79b669b 100644
--- a/target-sparc/op.c
+++ b/target-sparc/op.c
@@ -269,29 +269,6 @@ void OPPROTO op_sdiv_T1_T0(void)
FORCE_RET();
}
-#ifdef TARGET_SPARC64
-void OPPROTO op_udivx_T1_T0(void)
-{
- if (T1 == 0) {
- raise_exception(TT_DIV_ZERO);
- }
- T0 /= T1;
- FORCE_RET();
-}
-
-void OPPROTO op_sdivx_T1_T0(void)
-{
- if (T1 == 0) {
- raise_exception(TT_DIV_ZERO);
- }
- if (T0 == INT64_MIN && T1 == -1)
- T0 = INT64_MIN;
- else
- T0 /= (target_long) T1;
- FORCE_RET();
-}
-#endif
-
/* Load and store */
#define MEMSUFFIX _raw
#include "op_mem.h"
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 933a2f1..4c6faba 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -729,6 +729,34 @@ static inline void gen_op_tsub_T1_T0_ccTV(void)
gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
}
+#ifdef TARGET_SPARC64
+static inline void gen_trap_ifdivzero_i64(TCGv divisor)
+{
+ int l1;
+
+ l1 = gen_new_label();
+ tcg_gen_brcond_i64(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
+ gen_op_exception(TT_DIV_ZERO);
+ gen_set_label(l1);
+}
+
+static inline void gen_op_sdivx_T1_T0(void)
+{
+ int l1, l2;
+
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+ gen_trap_ifdivzero_i64(cpu_T[1]);
+ tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[0], tcg_const_i64(INT64_MIN), l1);
+ tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[1], tcg_const_i64(-1), l1);
+ tcg_gen_movi_i64(cpu_T[0], INT64_MIN);
+ gen_op_jmp_label(l2);
+ gen_set_label(l1);
+ tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
+ gen_set_label(l2);
+}
+#endif
+
static inline void gen_op_div_cc(void)
{
int l1;
@@ -3037,7 +3065,8 @@ static void disas_sparc_insn(DisasContext * dc)
break;
#ifdef TARGET_SPARC64
case 0xd: /* V9 udivx */
- gen_op_udivx_T1_T0();
+ gen_trap_ifdivzero_i64(cpu_T[1]);
+ tcg_gen_divu_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
break;
#endif
case 0xe: