diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-03-14 19:42:42 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-03-14 19:42:42 +0000 |
commit | 1a7b60e727d10b55fe573a471662442306eaa24b (patch) | |
tree | 463cfbc048c084aeae782c0b248c82bbfeaf7802 /target-sparc | |
parent | e01a11572f99b5e9266f0d53bfd1be3c19544d77 (diff) | |
download | qemu-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.c | 23 | ||||
-rw-r--r-- | target-sparc/translate.c | 31 |
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: |