mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 09:13:55 -06:00
target/s390x: Use Int128 for passing float128
Acked-by: David Hildenbrand <david@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- v2: Fix SPEC_in1_x1.
This commit is contained in:
parent
ee5e866fd2
commit
2b91240f95
4 changed files with 121 additions and 105 deletions
|
@ -39,6 +39,11 @@ static inline Int128 RET128(float128 f)
|
|||
return int128_make128(f.low, f.high);
|
||||
}
|
||||
|
||||
static inline float128 ARG128(Int128 i)
|
||||
{
|
||||
return make_float128(int128_gethi(i), int128_getlo(i));
|
||||
}
|
||||
|
||||
uint8_t s390_softfloat_exc_to_ieee(unsigned int exc)
|
||||
{
|
||||
uint8_t s390_exc = 0;
|
||||
|
@ -227,12 +232,9 @@ uint64_t HELPER(adb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|||
}
|
||||
|
||||
/* 128-bit FP addition */
|
||||
Int128 HELPER(axb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
||||
uint64_t bh, uint64_t bl)
|
||||
Int128 HELPER(axb)(CPUS390XState *env, Int128 a, Int128 b)
|
||||
{
|
||||
float128 ret = float128_add(make_float128(ah, al),
|
||||
make_float128(bh, bl),
|
||||
&env->fpu_status);
|
||||
float128 ret = float128_add(ARG128(a), ARG128(b), &env->fpu_status);
|
||||
handle_exceptions(env, false, GETPC());
|
||||
return RET128(ret);
|
||||
}
|
||||
|
@ -254,12 +256,9 @@ uint64_t HELPER(sdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|||
}
|
||||
|
||||
/* 128-bit FP subtraction */
|
||||
Int128 HELPER(sxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
||||
uint64_t bh, uint64_t bl)
|
||||
Int128 HELPER(sxb)(CPUS390XState *env, Int128 a, Int128 b)
|
||||
{
|
||||
float128 ret = float128_sub(make_float128(ah, al),
|
||||
make_float128(bh, bl),
|
||||
&env->fpu_status);
|
||||
float128 ret = float128_sub(ARG128(a), ARG128(b), &env->fpu_status);
|
||||
handle_exceptions(env, false, GETPC());
|
||||
return RET128(ret);
|
||||
}
|
||||
|
@ -281,12 +280,9 @@ uint64_t HELPER(ddb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|||
}
|
||||
|
||||
/* 128-bit FP division */
|
||||
Int128 HELPER(dxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
||||
uint64_t bh, uint64_t bl)
|
||||
Int128 HELPER(dxb)(CPUS390XState *env, Int128 a, Int128 b)
|
||||
{
|
||||
float128 ret = float128_div(make_float128(ah, al),
|
||||
make_float128(bh, bl),
|
||||
&env->fpu_status);
|
||||
float128 ret = float128_div(ARG128(a), ARG128(b), &env->fpu_status);
|
||||
handle_exceptions(env, false, GETPC());
|
||||
return RET128(ret);
|
||||
}
|
||||
|
@ -317,21 +313,18 @@ uint64_t HELPER(mdeb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|||
}
|
||||
|
||||
/* 128-bit FP multiplication */
|
||||
Int128 HELPER(mxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
||||
uint64_t bh, uint64_t bl)
|
||||
Int128 HELPER(mxb)(CPUS390XState *env, Int128 a, Int128 b)
|
||||
{
|
||||
float128 ret = float128_mul(make_float128(ah, al),
|
||||
make_float128(bh, bl),
|
||||
&env->fpu_status);
|
||||
float128 ret = float128_mul(ARG128(a), ARG128(b), &env->fpu_status);
|
||||
handle_exceptions(env, false, GETPC());
|
||||
return RET128(ret);
|
||||
}
|
||||
|
||||
/* 128/64-bit FP multiplication */
|
||||
Int128 HELPER(mxdb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint64_t f2)
|
||||
Int128 HELPER(mxdb)(CPUS390XState *env, Int128 a, uint64_t f2)
|
||||
{
|
||||
float128 ret = float64_to_float128(f2, &env->fpu_status);
|
||||
ret = float128_mul(make_float128(ah, al), ret, &env->fpu_status);
|
||||
ret = float128_mul(ARG128(a), ret, &env->fpu_status);
|
||||
handle_exceptions(env, false, GETPC());
|
||||
return RET128(ret);
|
||||
}
|
||||
|
@ -345,11 +338,10 @@ uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2)
|
|||
}
|
||||
|
||||
/* convert 128-bit float to 64-bit float */
|
||||
uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
||||
uint32_t m34)
|
||||
uint64_t HELPER(ldxb)(CPUS390XState *env, Int128 a, uint32_t m34)
|
||||
{
|
||||
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
||||
float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status);
|
||||
float64 ret = float128_to_float64(ARG128(a), &env->fpu_status);
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
|
@ -384,11 +376,10 @@ uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2, uint32_t m34)
|
|||
}
|
||||
|
||||
/* convert 128-bit float to 32-bit float */
|
||||
uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
||||
uint32_t m34)
|
||||
uint64_t HELPER(lexb)(CPUS390XState *env, Int128 a, uint32_t m34)
|
||||
{
|
||||
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
||||
float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status);
|
||||
float32 ret = float128_to_float32(ARG128(a), &env->fpu_status);
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
|
@ -412,11 +403,9 @@ uint32_t HELPER(cdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|||
}
|
||||
|
||||
/* 128-bit FP compare */
|
||||
uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
||||
uint64_t bh, uint64_t bl)
|
||||
uint32_t HELPER(cxb)(CPUS390XState *env, Int128 a, Int128 b)
|
||||
{
|
||||
FloatRelation cmp = float128_compare_quiet(make_float128(ah, al),
|
||||
make_float128(bh, bl),
|
||||
FloatRelation cmp = float128_compare_quiet(ARG128(a), ARG128(b),
|
||||
&env->fpu_status);
|
||||
handle_exceptions(env, false, GETPC());
|
||||
return float_comp_to_cc(env, cmp);
|
||||
|
@ -564,10 +553,10 @@ uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
|||
}
|
||||
|
||||
/* convert 128-bit float to 64-bit int */
|
||||
uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
uint64_t HELPER(cgxb)(CPUS390XState *env, Int128 i2, uint32_t m34)
|
||||
{
|
||||
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
||||
float128 v2 = make_float128(h, l);
|
||||
float128 v2 = ARG128(i2);
|
||||
int64_t ret = float128_to_int64(v2, &env->fpu_status);
|
||||
uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status);
|
||||
|
||||
|
@ -613,10 +602,10 @@ uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
|||
}
|
||||
|
||||
/* convert 128-bit float to 32-bit int */
|
||||
uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
uint64_t HELPER(cfxb)(CPUS390XState *env, Int128 i2, uint32_t m34)
|
||||
{
|
||||
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
||||
float128 v2 = make_float128(h, l);
|
||||
float128 v2 = ARG128(i2);
|
||||
int32_t ret = float128_to_int32(v2, &env->fpu_status);
|
||||
uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status);
|
||||
|
||||
|
@ -662,10 +651,10 @@ uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
|||
}
|
||||
|
||||
/* convert 128-bit float to 64-bit uint */
|
||||
uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
uint64_t HELPER(clgxb)(CPUS390XState *env, Int128 i2, uint32_t m34)
|
||||
{
|
||||
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
||||
float128 v2 = make_float128(h, l);
|
||||
float128 v2 = ARG128(i2);
|
||||
uint64_t ret = float128_to_uint64(v2, &env->fpu_status);
|
||||
uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status);
|
||||
|
||||
|
@ -711,10 +700,10 @@ uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
|||
}
|
||||
|
||||
/* convert 128-bit float to 32-bit uint */
|
||||
uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
uint64_t HELPER(clfxb)(CPUS390XState *env, Int128 i2, uint32_t m34)
|
||||
{
|
||||
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
||||
float128 v2 = make_float128(h, l);
|
||||
float128 v2 = ARG128(i2);
|
||||
uint32_t ret = float128_to_uint32(v2, &env->fpu_status);
|
||||
uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status);
|
||||
|
||||
|
@ -750,11 +739,10 @@ uint64_t HELPER(fidb)(CPUS390XState *env, uint64_t f2, uint32_t m34)
|
|||
}
|
||||
|
||||
/* round to integer 128-bit */
|
||||
Int128 HELPER(fixb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint32_t m34)
|
||||
Int128 HELPER(fixb)(CPUS390XState *env, Int128 a, uint32_t m34)
|
||||
{
|
||||
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
||||
float128 ret = float128_round_to_int(make_float128(ah, al),
|
||||
&env->fpu_status);
|
||||
float128 ret = float128_round_to_int(ARG128(a), &env->fpu_status);
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
|
@ -778,11 +766,9 @@ uint32_t HELPER(kdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|||
}
|
||||
|
||||
/* 128-bit FP compare and signal */
|
||||
uint32_t HELPER(kxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
||||
uint64_t bh, uint64_t bl)
|
||||
uint32_t HELPER(kxb)(CPUS390XState *env, Int128 a, Int128 b)
|
||||
{
|
||||
FloatRelation cmp = float128_compare(make_float128(ah, al),
|
||||
make_float128(bh, bl),
|
||||
FloatRelation cmp = float128_compare(ARG128(a), ARG128(b),
|
||||
&env->fpu_status);
|
||||
handle_exceptions(env, false, GETPC());
|
||||
return float_comp_to_cc(env, cmp);
|
||||
|
@ -869,9 +855,9 @@ uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
|
|||
}
|
||||
|
||||
/* test data class 128-bit */
|
||||
uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint64_t m2)
|
||||
uint32_t HELPER(tcxb)(CPUS390XState *env, Int128 a, uint64_t m2)
|
||||
{
|
||||
return (m2 & float128_dcmask(env, make_float128(ah, al))) != 0;
|
||||
return (m2 & float128_dcmask(env, ARG128(a))) != 0;
|
||||
}
|
||||
|
||||
/* square root 32-bit */
|
||||
|
@ -891,9 +877,9 @@ uint64_t HELPER(sqdb)(CPUS390XState *env, uint64_t f2)
|
|||
}
|
||||
|
||||
/* square root 128-bit */
|
||||
Int128 HELPER(sqxb)(CPUS390XState *env, uint64_t ah, uint64_t al)
|
||||
Int128 HELPER(sqxb)(CPUS390XState *env, Int128 a)
|
||||
{
|
||||
float128 ret = float128_sqrt(make_float128(ah, al), &env->fpu_status);
|
||||
float128 ret = float128_sqrt(ARG128(a), &env->fpu_status);
|
||||
handle_exceptions(env, false, GETPC());
|
||||
return RET128(ret);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue