diff options
Diffstat (limited to 'target-sparc/op.c')
-rw-r--r-- | target-sparc/op.c | 178 |
1 files changed, 177 insertions, 1 deletions
diff --git a/target-sparc/op.c b/target-sparc/op.c index 613bcb09a..52b824cc7 100644 --- a/target-sparc/op.c +++ b/target-sparc/op.c @@ -534,7 +534,7 @@ void OPPROTO op_tadd_T1_T0_ccTV(void) ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) raise_exception(TT_TOVF); #else - if ((src1 & 0x03) || (T1 & 0x03)) + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) raise_exception(TT_TOVF); #endif @@ -1023,6 +1023,11 @@ void OPPROTO op_sra(void) #define MEMSUFFIX _kernel #include "op_mem.h" + +#ifdef TARGET_SPARC64 +#define MEMSUFFIX _hypv +#include "op_mem.h" +#endif #endif void OPPROTO op_ldfsr(void) @@ -1239,12 +1244,14 @@ void OPPROTO op_exception(void) { env->exception_index = PARAM1; cpu_loop_exit(); + FORCE_RET(); } void OPPROTO op_trap_T0(void) { env->exception_index = TT_TRAP + (T0 & 0x7f); cpu_loop_exit(); + FORCE_RET(); } void OPPROTO op_trapcc_T0(void) @@ -1576,6 +1583,7 @@ void OPPROTO op_clear_ieee_excp_and_FTT(void) #define F_OP(name, p) void OPPROTO op_f##name##p(void) +#if defined(CONFIG_USER_ONLY) #define F_BINOP(name) \ F_OP(name, s) \ { \ @@ -1588,7 +1596,28 @@ void OPPROTO op_clear_ieee_excp_and_FTT(void) set_float_exception_flags(0, &env->fp_status); \ DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \ check_ieee_exceptions(); \ + } \ + F_OP(name, q) \ + { \ + set_float_exception_flags(0, &env->fp_status); \ + QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \ + check_ieee_exceptions(); \ } +#else +#define F_BINOP(name) \ + F_OP(name, s) \ + { \ + set_float_exception_flags(0, &env->fp_status); \ + FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \ + check_ieee_exceptions(); \ + } \ + F_OP(name, d) \ + { \ + set_float_exception_flags(0, &env->fp_status); \ + DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \ + check_ieee_exceptions(); \ + } +#endif F_BINOP(add); F_BINOP(sub); @@ -1605,6 +1634,32 @@ void OPPROTO op_fsmuld(void) check_ieee_exceptions(); } +#if defined(CONFIG_USER_ONLY) +void OPPROTO op_fdmulq(void) +{ + set_float_exception_flags(0, &env->fp_status); + QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status), + float64_to_float128(DT1, &env->fp_status), + &env->fp_status); + check_ieee_exceptions(); +} +#endif + +#if defined(CONFIG_USER_ONLY) +#define F_HELPER(name) \ + F_OP(name, s) \ + { \ + do_f##name##s(); \ + } \ + F_OP(name, d) \ + { \ + do_f##name##d(); \ + } \ + F_OP(name, q) \ + { \ + do_f##name##q(); \ + } +#else #define F_HELPER(name) \ F_OP(name, s) \ { \ @@ -1614,6 +1669,7 @@ void OPPROTO op_fsmuld(void) { \ do_f##name##d(); \ } +#endif F_HELPER(sqrt); @@ -1641,6 +1697,18 @@ F_OP(abs, d) do_fabsd(); } +#if defined(CONFIG_USER_ONLY) +F_OP(neg, q) +{ + QT0 = float128_chs(QT1); +} + +F_OP(abs, q) +{ + do_fabsd(); +} +#endif + void OPPROTO op_fcmps_fcc1(void) { do_fcmps_fcc1(); @@ -1701,11 +1769,46 @@ void OPPROTO op_fcmped_fcc3(void) do_fcmped_fcc3(); } +#if defined(CONFIG_USER_ONLY) +void OPPROTO op_fcmpq_fcc1(void) +{ + do_fcmpq_fcc1(); +} + +void OPPROTO op_fcmpq_fcc2(void) +{ + do_fcmpq_fcc2(); +} + +void OPPROTO op_fcmpq_fcc3(void) +{ + do_fcmpq_fcc3(); +} + +void OPPROTO op_fcmpeq_fcc1(void) +{ + do_fcmpeq_fcc1(); +} + +void OPPROTO op_fcmpeq_fcc2(void) +{ + do_fcmpeq_fcc2(); +} + +void OPPROTO op_fcmpeq_fcc3(void) +{ + do_fcmpeq_fcc3(); +} +#endif + #endif /* Integer to float conversion. */ #ifdef USE_INT_TO_FLOAT_HELPERS F_HELPER(ito); +#ifdef TARGET_SPARC64 +F_HELPER(xto); +#endif #else F_OP(ito, s) { @@ -1721,6 +1824,15 @@ F_OP(ito, d) check_ieee_exceptions(); } +#if defined(CONFIG_USER_ONLY) +F_OP(ito, q) +{ + set_float_exception_flags(0, &env->fp_status); + QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status); + check_ieee_exceptions(); +} +#endif + #ifdef TARGET_SPARC64 F_OP(xto, s) { @@ -1735,6 +1847,14 @@ F_OP(xto, d) DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status); check_ieee_exceptions(); } +#if defined(CONFIG_USER_ONLY) +F_OP(xto, q) +{ + set_float_exception_flags(0, &env->fp_status); + QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status); + check_ieee_exceptions(); +} +#endif #endif #endif #undef F_HELPER @@ -1754,6 +1874,36 @@ void OPPROTO op_fstod(void) check_ieee_exceptions(); } +#if defined(CONFIG_USER_ONLY) +void OPPROTO op_fqtos(void) +{ + set_float_exception_flags(0, &env->fp_status); + FT0 = float128_to_float32(QT1, &env->fp_status); + check_ieee_exceptions(); +} + +void OPPROTO op_fstoq(void) +{ + set_float_exception_flags(0, &env->fp_status); + QT0 = float32_to_float128(FT1, &env->fp_status); + check_ieee_exceptions(); +} + +void OPPROTO op_fqtod(void) +{ + set_float_exception_flags(0, &env->fp_status); + DT0 = float128_to_float64(QT1, &env->fp_status); + check_ieee_exceptions(); +} + +void OPPROTO op_fdtoq(void) +{ + set_float_exception_flags(0, &env->fp_status); + QT0 = float64_to_float128(DT1, &env->fp_status); + check_ieee_exceptions(); +} +#endif + /* Float to integer conversion. */ void OPPROTO op_fstoi(void) { @@ -1769,6 +1919,15 @@ void OPPROTO op_fdtoi(void) check_ieee_exceptions(); } +#if defined(CONFIG_USER_ONLY) +void OPPROTO op_fqtoi(void) +{ + set_float_exception_flags(0, &env->fp_status); + *((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status); + check_ieee_exceptions(); +} +#endif + #ifdef TARGET_SPARC64 void OPPROTO op_fstox(void) { @@ -1784,6 +1943,15 @@ void OPPROTO op_fdtox(void) check_ieee_exceptions(); } +#if defined(CONFIG_USER_ONLY) +void OPPROTO op_fqtox(void) +{ + set_float_exception_flags(0, &env->fp_status); + *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status); + check_ieee_exceptions(); +} +#endif + void OPPROTO op_fmovs_cc(void) { if (T2) @@ -1796,6 +1964,14 @@ void OPPROTO op_fmovd_cc(void) DT0 = DT1; } +#if defined(CONFIG_USER_ONLY) +void OPPROTO op_fmovq_cc(void) +{ + if (T2) + QT0 = QT1; +} +#endif + void OPPROTO op_mov_cc(void) { if (T2) |