2012-09-02 09:33:31 +02:00
|
|
|
/*
|
|
|
|
* S/390 FPU helper routines
|
|
|
|
*
|
|
|
|
* Copyright (c) 2009 Ulrich Hecht
|
|
|
|
* Copyright (c) 2009 Alexander Graf
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
2019-01-29 14:37:47 +01:00
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2012-09-02 09:33:31 +02:00
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2016-01-26 19:17:00 +01:00
|
|
|
#include "qemu/osdep.h"
|
2012-09-02 09:33:31 +02:00
|
|
|
#include "cpu.h"
|
2017-08-18 13:43:49 +02:00
|
|
|
#include "internal.h"
|
2018-09-27 15:02:56 +02:00
|
|
|
#include "tcg_s390x.h"
|
2016-03-15 13:18:37 +01:00
|
|
|
#include "exec/exec-all.h"
|
2014-03-28 19:42:10 +01:00
|
|
|
#include "exec/cpu_ldst.h"
|
2014-04-08 07:31:41 +02:00
|
|
|
#include "exec/helper-proto.h"
|
2018-01-19 19:24:22 +01:00
|
|
|
#include "fpu/softfloat.h"
|
2012-09-02 09:33:31 +02:00
|
|
|
|
|
|
|
/* #define DEBUG_HELPER */
|
|
|
|
#ifdef DEBUG_HELPER
|
|
|
|
#define HELPER_LOG(x...) qemu_log(x)
|
|
|
|
#else
|
|
|
|
#define HELPER_LOG(x...)
|
|
|
|
#endif
|
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
#define RET128(F) (env->retxl = F.low, F.high)
|
|
|
|
|
2019-02-18 13:26:58 +01:00
|
|
|
uint8_t s390_softfloat_exc_to_ieee(unsigned int exc)
|
|
|
|
{
|
|
|
|
uint8_t s390_exc = 0;
|
|
|
|
|
|
|
|
s390_exc |= (exc & float_flag_invalid) ? S390_IEEE_MASK_INVALID : 0;
|
|
|
|
s390_exc |= (exc & float_flag_divbyzero) ? S390_IEEE_MASK_DIVBYZERO : 0;
|
|
|
|
s390_exc |= (exc & float_flag_overflow) ? S390_IEEE_MASK_OVERFLOW : 0;
|
|
|
|
s390_exc |= (exc & float_flag_underflow) ? S390_IEEE_MASK_UNDERFLOW : 0;
|
|
|
|
s390_exc |= (exc & float_flag_inexact) ? S390_IEEE_MASK_INEXACT : 0;
|
|
|
|
|
|
|
|
return s390_exc;
|
|
|
|
}
|
2012-08-23 19:48:20 +02:00
|
|
|
|
|
|
|
/* Should be called after any operation that may raise IEEE exceptions. */
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
static void handle_exceptions(CPUS390XState *env, bool XxC, uintptr_t retaddr)
|
2012-08-23 19:48:20 +02:00
|
|
|
{
|
|
|
|
unsigned s390_exc, qemu_exc;
|
|
|
|
|
|
|
|
/* Get the exceptions raised by the current operation. Reset the
|
|
|
|
fpu_status contents so that the next operation has a clean slate. */
|
|
|
|
qemu_exc = env->fpu_status.float_exception_flags;
|
|
|
|
if (qemu_exc == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
env->fpu_status.float_exception_flags = 0;
|
2019-02-18 13:26:58 +01:00
|
|
|
s390_exc = s390_softfloat_exc_to_ieee(qemu_exc);
|
2012-08-23 19:48:20 +02:00
|
|
|
|
2019-02-18 13:27:00 +01:00
|
|
|
/*
|
|
|
|
* IEEE-Underflow exception recognition exists if a tininess condition
|
|
|
|
* (underflow) exists and
|
|
|
|
* - The mask bit in the FPC is zero and the result is inexact
|
|
|
|
* - The mask bit in the FPC is one
|
|
|
|
* So tininess conditions that are not inexact don't trigger any
|
|
|
|
* underflow action in case the mask bit is not one.
|
|
|
|
*/
|
|
|
|
if (!(s390_exc & S390_IEEE_MASK_INEXACT) &&
|
|
|
|
!((env->fpc >> 24) & S390_IEEE_MASK_UNDERFLOW)) {
|
|
|
|
s390_exc &= ~S390_IEEE_MASK_UNDERFLOW;
|
|
|
|
}
|
|
|
|
|
2019-02-18 13:26:59 +01:00
|
|
|
/*
|
|
|
|
* FIXME:
|
|
|
|
* 1. Right now, all inexact conditions are inidicated as
|
|
|
|
* "truncated" (0) and never as "incremented" (1) in the DXC.
|
|
|
|
* 2. Only traps due to invalid/divbyzero are suppressing. Other traps
|
|
|
|
* are completing, meaning the target register has to be written!
|
|
|
|
* This, however will mean that we have to write the register before
|
|
|
|
* triggering the trap - impossible right now.
|
|
|
|
*/
|
2012-08-23 19:48:20 +02:00
|
|
|
|
2019-02-18 13:26:59 +01:00
|
|
|
/*
|
|
|
|
* invalid/divbyzero cannot coexist with other conditions.
|
|
|
|
* overflow/underflow however can coexist with inexact, we have to
|
|
|
|
* handle it separatly.
|
|
|
|
*/
|
|
|
|
if (s390_exc & ~S390_IEEE_MASK_INEXACT) {
|
|
|
|
if (s390_exc & ~S390_IEEE_MASK_INEXACT & env->fpc >> 24) {
|
|
|
|
/* trap condition - inexact reported along */
|
|
|
|
tcg_s390_data_exception(env, s390_exc, retaddr);
|
|
|
|
}
|
|
|
|
/* nontrap condition - inexact handled differently */
|
|
|
|
env->fpc |= (s390_exc & ~S390_IEEE_MASK_INEXACT) << 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* inexact handling */
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
if (s390_exc & S390_IEEE_MASK_INEXACT && !XxC) {
|
2019-02-18 13:26:59 +01:00
|
|
|
/* trap condition - overflow/underflow _not_ reported along */
|
|
|
|
if (s390_exc & S390_IEEE_MASK_INEXACT & env->fpc >> 24) {
|
|
|
|
tcg_s390_data_exception(env, s390_exc & S390_IEEE_MASK_INEXACT,
|
|
|
|
retaddr);
|
|
|
|
}
|
|
|
|
/* nontrap condition */
|
|
|
|
env->fpc |= (s390_exc & S390_IEEE_MASK_INEXACT) << 16;
|
2012-08-23 19:48:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-25 10:46:36 +01:00
|
|
|
int float_comp_to_cc(CPUS390XState *env, int float_compare)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
|
|
|
switch (float_compare) {
|
|
|
|
case float_relation_equal:
|
|
|
|
return 0;
|
|
|
|
case float_relation_less:
|
|
|
|
return 1;
|
|
|
|
case float_relation_greater:
|
|
|
|
return 2;
|
|
|
|
case float_relation_unordered:
|
|
|
|
return 3;
|
|
|
|
default:
|
2019-03-23 03:21:48 +01:00
|
|
|
cpu_abort(env_cpu(env), "unknown return value for float compare\n");
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* condition codes for unary FP ops */
|
|
|
|
uint32_t set_cc_nz_f32(float32 v)
|
|
|
|
{
|
|
|
|
if (float32_is_any_nan(v)) {
|
|
|
|
return 3;
|
|
|
|
} else if (float32_is_zero(v)) {
|
|
|
|
return 0;
|
|
|
|
} else if (float32_is_neg(v)) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t set_cc_nz_f64(float64 v)
|
|
|
|
{
|
|
|
|
if (float64_is_any_nan(v)) {
|
|
|
|
return 3;
|
|
|
|
} else if (float64_is_zero(v)) {
|
|
|
|
return 0;
|
|
|
|
} else if (float64_is_neg(v)) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
uint32_t set_cc_nz_f128(float128 v)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
|
|
|
if (float128_is_any_nan(v)) {
|
|
|
|
return 3;
|
|
|
|
} else if (float128_is_zero(v)) {
|
|
|
|
return 0;
|
|
|
|
} else if (float128_is_neg(v)) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-18 13:27:07 +01:00
|
|
|
static inline uint8_t round_from_m34(uint32_t m34)
|
|
|
|
{
|
|
|
|
return extract32(m34, 0, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool xxc_from_m34(uint32_t m34)
|
|
|
|
{
|
|
|
|
/* XxC is bit 1 of m4 */
|
|
|
|
return extract32(m34, 4 + 3 - 1, 1);
|
|
|
|
}
|
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
/* 32-bit FP addition */
|
|
|
|
uint64_t HELPER(aeb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 19:48:20 +02:00
|
|
|
float32 ret = float32_add(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 19:48:20 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
/* 64-bit FP addition */
|
|
|
|
uint64_t HELPER(adb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 19:48:20 +02:00
|
|
|
float64 ret = float64_add(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 19:48:20 +02:00
|
|
|
return ret;
|
|
|
|
}
|
2012-09-02 09:33:31 +02:00
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
/* 128-bit FP addition */
|
|
|
|
uint64_t HELPER(axb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint64_t bh, uint64_t bl)
|
|
|
|
{
|
|
|
|
float128 ret = float128_add(make_float128(ah, al),
|
|
|
|
make_float128(bh, bl),
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 19:48:20 +02:00
|
|
|
return RET128(ret);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 20:05:03 +02:00
|
|
|
/* 32-bit FP subtraction */
|
|
|
|
uint64_t HELPER(seb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 20:05:03 +02:00
|
|
|
float32 ret = float32_sub(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 20:05:03 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 20:05:03 +02:00
|
|
|
/* 64-bit FP subtraction */
|
|
|
|
uint64_t HELPER(sdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 20:05:03 +02:00
|
|
|
float64 ret = float64_sub(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 20:05:03 +02:00
|
|
|
return ret;
|
|
|
|
}
|
2012-09-02 09:33:31 +02:00
|
|
|
|
2012-08-23 20:05:03 +02:00
|
|
|
/* 128-bit FP subtraction */
|
|
|
|
uint64_t HELPER(sxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint64_t bh, uint64_t bl)
|
|
|
|
{
|
|
|
|
float128 ret = float128_sub(make_float128(ah, al),
|
|
|
|
make_float128(bh, bl),
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 20:05:03 +02:00
|
|
|
return RET128(ret);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-09-07 20:41:12 +02:00
|
|
|
/* 32-bit FP division */
|
|
|
|
uint64_t HELPER(deb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-09-07 20:41:12 +02:00
|
|
|
float32 ret = float32_div(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-09-07 20:41:12 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-09-07 20:41:12 +02:00
|
|
|
/* 64-bit FP division */
|
|
|
|
uint64_t HELPER(ddb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-09-07 20:41:12 +02:00
|
|
|
float64 ret = float64_div(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-09-07 20:41:12 +02:00
|
|
|
return ret;
|
|
|
|
}
|
2012-09-02 09:33:31 +02:00
|
|
|
|
2012-09-07 20:41:12 +02:00
|
|
|
/* 128-bit FP division */
|
|
|
|
uint64_t HELPER(dxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint64_t bh, uint64_t bl)
|
|
|
|
{
|
|
|
|
float128 ret = float128_div(make_float128(ah, al),
|
|
|
|
make_float128(bh, bl),
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-09-07 20:41:12 +02:00
|
|
|
return RET128(ret);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 21:02:38 +02:00
|
|
|
/* 32-bit FP multiplication */
|
|
|
|
uint64_t HELPER(meeb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 21:02:38 +02:00
|
|
|
float32 ret = float32_mul(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:02:38 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 21:02:38 +02:00
|
|
|
/* 64-bit FP multiplication */
|
|
|
|
uint64_t HELPER(mdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 21:02:38 +02:00
|
|
|
float64 ret = float64_mul(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:02:38 +02:00
|
|
|
return ret;
|
|
|
|
}
|
2012-09-02 09:33:31 +02:00
|
|
|
|
2012-08-23 21:02:38 +02:00
|
|
|
/* 64/32-bit FP multiplication */
|
|
|
|
uint64_t HELPER(mdeb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|
|
|
{
|
|
|
|
float64 ret = float32_to_float64(f2, &env->fpu_status);
|
|
|
|
ret = float64_mul(f1, ret, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:02:38 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 128-bit FP multiplication */
|
|
|
|
uint64_t HELPER(mxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint64_t bh, uint64_t bl)
|
|
|
|
{
|
|
|
|
float128 ret = float128_mul(make_float128(ah, al),
|
|
|
|
make_float128(bh, bl),
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:02:38 +02:00
|
|
|
return RET128(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 128/64-bit FP multiplication */
|
|
|
|
uint64_t HELPER(mxdb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint64_t f2)
|
|
|
|
{
|
|
|
|
float128 ret = float64_to_float128(f2, &env->fpu_status);
|
|
|
|
ret = float128_mul(make_float128(ah, al), ret, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:02:38 +02:00
|
|
|
return RET128(ret);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 32-bit float to 64-bit float */
|
2012-08-23 19:48:20 +02:00
|
|
|
uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 19:48:20 +02:00
|
|
|
float64 ret = float32_to_float64(f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2018-05-10 22:55:15 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 128-bit float to 64-bit float */
|
2019-02-18 13:27:08 +01:00
|
|
|
uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:08 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-23 19:48:20 +02:00
|
|
|
float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status);
|
2019-02-18 13:27:08 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2018-05-10 22:55:15 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit float to 128-bit float */
|
2012-08-23 19:48:20 +02:00
|
|
|
uint64_t HELPER(lxdb)(CPUS390XState *env, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 19:48:20 +02:00
|
|
|
float128 ret = float64_to_float128(f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2018-05-10 22:55:15 +02:00
|
|
|
return RET128(ret);
|
2012-08-23 19:48:20 +02:00
|
|
|
}
|
2012-09-02 09:33:31 +02:00
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
/* convert 32-bit float to 128-bit float */
|
|
|
|
uint64_t HELPER(lxeb)(CPUS390XState *env, uint64_t f2)
|
|
|
|
{
|
|
|
|
float128 ret = float32_to_float128(f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2018-05-10 22:55:15 +02:00
|
|
|
return RET128(ret);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit float to 32-bit float */
|
2019-02-18 13:27:08 +01:00
|
|
|
uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2, uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:08 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-23 19:48:20 +02:00
|
|
|
float32 ret = float64_to_float32(f2, &env->fpu_status);
|
2019-02-18 13:27:08 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2018-05-10 22:55:15 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 128-bit float to 32-bit float */
|
2019-02-18 13:27:08 +01:00
|
|
|
uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:08 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-23 19:48:20 +02:00
|
|
|
float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status);
|
2019-02-18 13:27:08 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2018-05-10 22:55:15 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
/* 32-bit FP compare */
|
|
|
|
uint32_t HELPER(ceb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 19:48:20 +02:00
|
|
|
int cmp = float32_compare_quiet(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 19:48:20 +02:00
|
|
|
return float_comp_to_cc(env, cmp);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
/* 64-bit FP compare */
|
|
|
|
uint32_t HELPER(cdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 19:48:20 +02:00
|
|
|
int cmp = float64_compare_quiet(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 19:48:20 +02:00
|
|
|
return float_comp_to_cc(env, cmp);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 19:48:20 +02:00
|
|
|
/* 128-bit FP compare */
|
|
|
|
uint32_t HELPER(cxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint64_t bh, uint64_t bl)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 19:48:20 +02:00
|
|
|
int cmp = float128_compare_quiet(make_float128(ah, al),
|
|
|
|
make_float128(bh, bl),
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 19:48:20 +02:00
|
|
|
return float_comp_to_cc(env, cmp);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2019-02-18 13:27:05 +01:00
|
|
|
int s390_swap_bfp_rounding_mode(CPUS390XState *env, int m3)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-24 00:17:35 +02:00
|
|
|
int ret = env->fpu_status.float_rounding_mode;
|
2019-02-18 13:27:09 +01:00
|
|
|
|
2012-09-02 09:33:31 +02:00
|
|
|
switch (m3) {
|
|
|
|
case 0:
|
|
|
|
/* current mode */
|
|
|
|
break;
|
|
|
|
case 1:
|
2019-02-18 13:27:09 +01:00
|
|
|
/* round to nearest with ties away from 0 */
|
|
|
|
set_float_rounding_mode(float_round_ties_away, &env->fpu_status);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
/* round to prepare for shorter precision */
|
|
|
|
set_float_rounding_mode(float_round_to_odd, &env->fpu_status);
|
|
|
|
break;
|
2012-09-02 09:33:31 +02:00
|
|
|
case 4:
|
2019-02-18 13:27:09 +01:00
|
|
|
/* round to nearest with ties to even */
|
2012-09-02 09:33:31 +02:00
|
|
|
set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
/* round to zero */
|
|
|
|
set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
/* round to +inf */
|
|
|
|
set_float_rounding_mode(float_round_up, &env->fpu_status);
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
/* round to -inf */
|
|
|
|
set_float_rounding_mode(float_round_down, &env->fpu_status);
|
|
|
|
break;
|
2019-02-18 13:27:09 +01:00
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
2012-08-24 00:17:35 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2019-02-18 13:27:05 +01:00
|
|
|
void s390_restore_bfp_rounding_mode(CPUS390XState *env, int old_mode)
|
|
|
|
{
|
|
|
|
set_float_rounding_mode(old_mode, &env->fpu_status);
|
|
|
|
}
|
|
|
|
|
2012-08-24 06:08:22 +02:00
|
|
|
/* convert 64-bit int to 32-bit float */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cegb)(CPUS390XState *env, int64_t v2, uint32_t m34)
|
2012-08-24 06:08:22 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 06:08:22 +02:00
|
|
|
float32 ret = int64_to_float32(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 06:08:22 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit int to 64-bit float */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cdgb)(CPUS390XState *env, int64_t v2, uint32_t m34)
|
2012-08-24 06:08:22 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 06:08:22 +02:00
|
|
|
float64 ret = int64_to_float64(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 06:08:22 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit int to 128-bit float */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cxgb)(CPUS390XState *env, int64_t v2, uint32_t m34)
|
2012-08-24 06:08:22 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 06:08:22 +02:00
|
|
|
float128 ret = int64_to_float128(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 20:08:17 +02:00
|
|
|
return RET128(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit uint to 32-bit float */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(celgb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-01 20:08:17 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-09-01 20:08:17 +02:00
|
|
|
float32 ret = uint64_to_float32(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 20:08:17 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit uint to 64-bit float */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cdlgb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-01 20:08:17 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-09-01 20:08:17 +02:00
|
|
|
float64 ret = uint64_to_float64(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 20:08:17 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit uint to 128-bit float */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cxlgb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-01 20:08:17 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-09-10 01:04:17 +02:00
|
|
|
float128 ret = uint64_to_float128(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 06:08:22 +02:00
|
|
|
return RET128(ret);
|
|
|
|
}
|
|
|
|
|
2012-09-02 09:33:31 +02:00
|
|
|
/* convert 32-bit float to 64-bit int */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 00:17:35 +02:00
|
|
|
int64_t ret = float32_to_int64(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 00:17:35 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit float to 64-bit int */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 00:17:35 +02:00
|
|
|
int64_t ret = float64_to_int64(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 00:17:35 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 128-bit float to 64-bit int */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 00:17:35 +02:00
|
|
|
float128 v2 = make_float128(h, l);
|
|
|
|
int64_t ret = float128_to_int64(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 00:17:35 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 32-bit float to 32-bit int */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 00:17:35 +02:00
|
|
|
int32_t ret = float32_to_int32(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 00:17:35 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit float to 32-bit int */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 00:17:35 +02:00
|
|
|
int32_t ret = float64_to_int32(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 00:17:35 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 128-bit float to 32-bit int */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-08-24 00:17:35 +02:00
|
|
|
float128 v2 = make_float128(h, l);
|
|
|
|
int32_t ret = float128_to_int32(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-08-24 00:17:35 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-09-01 19:42:54 +02:00
|
|
|
/* convert 32-bit float to 64-bit uint */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(clgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-01 19:42:54 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-09-01 19:42:54 +02:00
|
|
|
uint64_t ret;
|
2019-02-18 13:27:05 +01:00
|
|
|
|
2012-09-01 19:42:54 +02:00
|
|
|
v2 = float32_to_float64(v2, &env->fpu_status);
|
|
|
|
ret = float64_to_uint64(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 19:42:54 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit float to 64-bit uint */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-01 19:42:54 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-09-01 19:42:54 +02:00
|
|
|
uint64_t ret = float64_to_uint64(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 19:42:54 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 128-bit float to 64-bit uint */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
2012-09-01 19:42:54 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2019-02-18 13:26:57 +01:00
|
|
|
uint64_t ret = float128_to_uint64(make_float128(h, l), &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 19:42:54 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 32-bit float to 32-bit uint */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(clfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-01 19:42:54 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-09-01 19:42:54 +02:00
|
|
|
uint32_t ret = float32_to_uint32(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 19:42:54 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 64-bit float to 32-bit uint */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
2012-09-01 19:42:54 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2012-09-01 19:42:54 +02:00
|
|
|
uint32_t ret = float64_to_uint32(v2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 19:42:54 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert 128-bit float to 32-bit uint */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
2012-09-01 19:42:54 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2019-02-18 13:26:57 +01:00
|
|
|
uint32_t ret = float128_to_uint32(make_float128(h, l), &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2012-09-01 19:42:54 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-03 23:09:46 +02:00
|
|
|
/* round to integer 32-bit */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(fieb)(CPUS390XState *env, uint64_t f2, uint32_t m34)
|
2015-06-03 23:09:46 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2015-06-03 23:09:46 +02:00
|
|
|
float32 ret = float32_round_to_int(f2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2015-06-03 23:09:46 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* round to integer 64-bit */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(fidb)(CPUS390XState *env, uint64_t f2, uint32_t m34)
|
2015-06-03 23:09:46 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2015-06-03 23:09:46 +02:00
|
|
|
float64 ret = float64_round_to_int(f2, &env->fpu_status);
|
2019-02-18 13:27:05 +01:00
|
|
|
|
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2015-06-03 23:09:46 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* round to integer 128-bit */
|
2019-02-18 13:27:07 +01:00
|
|
|
uint64_t HELPER(fixb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint32_t m34)
|
2015-06-03 23:09:46 +02:00
|
|
|
{
|
2019-02-18 13:27:07 +01:00
|
|
|
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
2015-06-03 23:09:46 +02:00
|
|
|
float128 ret = float128_round_to_int(make_float128(ah, al),
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
|
2019-02-18 13:27:05 +01:00
|
|
|
s390_restore_bfp_rounding_mode(env, old_mode);
|
2019-02-18 13:27:07 +01:00
|
|
|
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
2015-06-03 23:09:46 +02:00
|
|
|
return RET128(ret);
|
|
|
|
}
|
|
|
|
|
2017-06-01 00:01:08 +02:00
|
|
|
/* 32-bit FP compare and signal */
|
|
|
|
uint32_t HELPER(keb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|
|
|
{
|
|
|
|
int cmp = float32_compare(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2017-06-01 00:01:08 +02:00
|
|
|
return float_comp_to_cc(env, cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 64-bit FP compare and signal */
|
|
|
|
uint32_t HELPER(kdb)(CPUS390XState *env, uint64_t f1, uint64_t f2)
|
|
|
|
{
|
|
|
|
int cmp = float64_compare(f1, f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2017-06-01 00:01:08 +02:00
|
|
|
return float_comp_to_cc(env, cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 128-bit FP compare and signal */
|
|
|
|
uint32_t HELPER(kxb)(CPUS390XState *env, uint64_t ah, uint64_t al,
|
|
|
|
uint64_t bh, uint64_t bl)
|
|
|
|
{
|
|
|
|
int cmp = float128_compare(make_float128(ah, al),
|
|
|
|
make_float128(bh, bl),
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2017-06-01 00:01:08 +02:00
|
|
|
return float_comp_to_cc(env, cmp);
|
|
|
|
}
|
|
|
|
|
2012-08-23 21:30:12 +02:00
|
|
|
/* 32-bit FP multiply and add */
|
|
|
|
uint64_t HELPER(maeb)(CPUS390XState *env, uint64_t f1,
|
|
|
|
uint64_t f2, uint64_t f3)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 21:30:12 +02:00
|
|
|
float32 ret = float32_muladd(f2, f3, f1, 0, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:30:12 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 21:30:12 +02:00
|
|
|
/* 64-bit FP multiply and add */
|
|
|
|
uint64_t HELPER(madb)(CPUS390XState *env, uint64_t f1,
|
|
|
|
uint64_t f2, uint64_t f3)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 21:30:12 +02:00
|
|
|
float64 ret = float64_muladd(f2, f3, f1, 0, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:30:12 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 21:30:12 +02:00
|
|
|
/* 32-bit FP multiply and subtract */
|
|
|
|
uint64_t HELPER(mseb)(CPUS390XState *env, uint64_t f1,
|
|
|
|
uint64_t f2, uint64_t f3)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 21:30:12 +02:00
|
|
|
float32 ret = float32_muladd(f2, f3, f1, float_muladd_negate_c,
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:30:12 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 21:30:12 +02:00
|
|
|
/* 64-bit FP multiply and subtract */
|
|
|
|
uint64_t HELPER(msdb)(CPUS390XState *env, uint64_t f1,
|
|
|
|
uint64_t f2, uint64_t f3)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 21:30:12 +02:00
|
|
|
float64 ret = float64_muladd(f2, f3, f1, float_muladd_negate_c,
|
|
|
|
&env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 21:30:12 +02:00
|
|
|
return ret;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2019-02-18 13:26:56 +01:00
|
|
|
/* The rightmost bit has the number 11. */
|
|
|
|
static inline uint16_t dcmask(int bit, bool neg)
|
|
|
|
{
|
|
|
|
return 1 << (11 - bit - neg);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define DEF_FLOAT_DCMASK(_TYPE) \
|
2019-02-25 10:46:36 +01:00
|
|
|
uint16_t _TYPE##_dcmask(CPUS390XState *env, _TYPE f1) \
|
2019-02-18 13:26:56 +01:00
|
|
|
{ \
|
|
|
|
const bool neg = _TYPE##_is_neg(f1); \
|
|
|
|
\
|
|
|
|
/* Sorted by most common cases - only one class is possible */ \
|
|
|
|
if (_TYPE##_is_normal(f1)) { \
|
|
|
|
return dcmask(2, neg); \
|
|
|
|
} else if (_TYPE##_is_zero(f1)) { \
|
|
|
|
return dcmask(0, neg); \
|
|
|
|
} else if (_TYPE##_is_denormal(f1)) { \
|
|
|
|
return dcmask(4, neg); \
|
|
|
|
} else if (_TYPE##_is_infinity(f1)) { \
|
|
|
|
return dcmask(6, neg); \
|
|
|
|
} else if (_TYPE##_is_quiet_nan(f1, &env->fpu_status)) { \
|
|
|
|
return dcmask(8, neg); \
|
|
|
|
} \
|
|
|
|
/* signaling nan, as last remaining case */ \
|
|
|
|
return dcmask(10, neg); \
|
|
|
|
}
|
|
|
|
DEF_FLOAT_DCMASK(float32)
|
|
|
|
DEF_FLOAT_DCMASK(float64)
|
|
|
|
DEF_FLOAT_DCMASK(float128)
|
|
|
|
|
2012-09-02 09:33:31 +02:00
|
|
|
/* test data class 32-bit */
|
softfloat: Implement run-time-configurable meaning of signaling NaN bit
This patch modifies SoftFloat library so that it can be configured in
run-time in relation to the meaning of signaling NaN bit, while, at the
same time, strictly preserving its behavior on all existing platforms.
Background:
In floating-point calculations, there is a need for denoting undefined or
unrepresentable values. This is achieved by defining certain floating-point
numerical values to be NaNs (which stands for "not a number"). For additional
reasons, virtually all modern floating-point unit implementations use two
kinds of NaNs: quiet and signaling. The binary representations of these two
kinds of NaNs, as a rule, differ only in one bit (that bit is, traditionally,
the first bit of mantissa).
Up to 2008, standards for floating-point did not specify all details about
binary representation of NaNs. More specifically, the meaning of the bit
that is used for distinguishing between signaling and quiet NaNs was not
strictly prescribed. (IEEE 754-2008 was the first floating-point standard
that defined that meaning clearly, see [1], p. 35) As a result, different
platforms took different approaches, and that presented considerable
challenge for multi-platform emulators like QEMU.
Mips platform represents the most complex case among QEMU-supported
platforms regarding signaling NaN bit. Up to the Release 6 of Mips
architecture, "1" in signaling NaN bit denoted signaling NaN, which is
opposite to IEEE 754-2008 standard. From Release 6 on, Mips architecture
adopted IEEE standard prescription, and "0" denotes signaling NaN. On top of
that, Mips architecture for SIMD (also known as MSA, or vector instructions)
also specifies signaling bit in accordance to IEEE standard. MSA unit can be
implemented with both pre-Release 6 and Release 6 main processor units.
QEMU uses SoftFloat library to implement various floating-point-related
instructions on all platforms. The current QEMU implementation allows for
defining meaning of signaling NaN bit during build time, and is implemented
via preprocessor macro called SNAN_BIT_IS_ONE.
On the other hand, the change in this patch enables SoftFloat library to be
configured in run-time. This configuration is meant to occur during CPU
initialization, at the moment when it is definitely known what desired
behavior for particular CPU (or any additional FPUs) is.
The change is implemented so that it is consistent with existing
implementation of similar cases. This means that structure float_status is
used for passing the information about desired signaling NaN bit on each
invocation of SoftFloat functions. The additional field in float_status is
called snan_bit_is_one, which supersedes macro SNAN_BIT_IS_ONE.
IMPORTANT:
This change is not meant to create any change in emulator behavior or
functionality on any platform. It just provides the means for SoftFloat
library to be used in a more flexible way - in other words, it will just
prepare SoftFloat library for usage related to Mips platform and its
specifics regarding signaling bit meaning, which is done in some of
subsequent patches from this series.
Further break down of changes:
1) Added field snan_bit_is_one to the structure float_status, and
correspondent setter function set_snan_bit_is_one().
2) Constants <float16|float32|float64|floatx80|float128>_default_nan
(used both internally and externally) converted to functions
<float16|float32|float64|floatx80|float128>_default_nan(float_status*).
This is necessary since they are dependent on signaling bit meaning.
At the same time, for the sake of code cleanup and simplicity, constants
<floatx80|float128>_default_nan_<low|high> (used only internally within
SoftFloat library) are removed, as not needed.
3) Added a float_status* argument to SoftFloat library functions
XXX_is_quiet_nan(XXX a_), XXX_is_signaling_nan(XXX a_),
XXX_maybe_silence_nan(XXX a_). This argument must be present in
order to enable correct invocation of new version of functions
XXX_default_nan(). (XXX is <float16|float32|float64|floatx80|float128>
here)
4) Updated code for all platforms to reflect changes in SoftFloat library.
This change is twofolds: it includes modifications of SoftFloat library
functions invocations, and an addition of invocation of function
set_snan_bit_is_one() during CPU initialization, with arguments that
are appropriate for each particular platform. It was established that
all platforms zero their main CPU data structures, so snan_bit_is_one(0)
in appropriate places is not added, as it is not needed.
[1] "IEEE Standard for Floating-Point Arithmetic",
IEEE Computer Society, August 29, 2008.
Signed-off-by: Thomas Schwinge <thomas@codesourcery.com>
Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
Tested-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
Tested-by: Leon Alrae <leon.alrae@imgtec.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[leon.alrae@imgtec.com:
* cherry-picked 2 chunks from patch #2 to fix compilation warnings]
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
2016-06-10 11:57:28 +02:00
|
|
|
uint32_t HELPER(tceb)(CPUS390XState *env, uint64_t f1, uint64_t m2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:26:56 +01:00
|
|
|
return (m2 & float32_dcmask(env, f1)) != 0;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* test data class 64-bit */
|
softfloat: Implement run-time-configurable meaning of signaling NaN bit
This patch modifies SoftFloat library so that it can be configured in
run-time in relation to the meaning of signaling NaN bit, while, at the
same time, strictly preserving its behavior on all existing platforms.
Background:
In floating-point calculations, there is a need for denoting undefined or
unrepresentable values. This is achieved by defining certain floating-point
numerical values to be NaNs (which stands for "not a number"). For additional
reasons, virtually all modern floating-point unit implementations use two
kinds of NaNs: quiet and signaling. The binary representations of these two
kinds of NaNs, as a rule, differ only in one bit (that bit is, traditionally,
the first bit of mantissa).
Up to 2008, standards for floating-point did not specify all details about
binary representation of NaNs. More specifically, the meaning of the bit
that is used for distinguishing between signaling and quiet NaNs was not
strictly prescribed. (IEEE 754-2008 was the first floating-point standard
that defined that meaning clearly, see [1], p. 35) As a result, different
platforms took different approaches, and that presented considerable
challenge for multi-platform emulators like QEMU.
Mips platform represents the most complex case among QEMU-supported
platforms regarding signaling NaN bit. Up to the Release 6 of Mips
architecture, "1" in signaling NaN bit denoted signaling NaN, which is
opposite to IEEE 754-2008 standard. From Release 6 on, Mips architecture
adopted IEEE standard prescription, and "0" denotes signaling NaN. On top of
that, Mips architecture for SIMD (also known as MSA, or vector instructions)
also specifies signaling bit in accordance to IEEE standard. MSA unit can be
implemented with both pre-Release 6 and Release 6 main processor units.
QEMU uses SoftFloat library to implement various floating-point-related
instructions on all platforms. The current QEMU implementation allows for
defining meaning of signaling NaN bit during build time, and is implemented
via preprocessor macro called SNAN_BIT_IS_ONE.
On the other hand, the change in this patch enables SoftFloat library to be
configured in run-time. This configuration is meant to occur during CPU
initialization, at the moment when it is definitely known what desired
behavior for particular CPU (or any additional FPUs) is.
The change is implemented so that it is consistent with existing
implementation of similar cases. This means that structure float_status is
used for passing the information about desired signaling NaN bit on each
invocation of SoftFloat functions. The additional field in float_status is
called snan_bit_is_one, which supersedes macro SNAN_BIT_IS_ONE.
IMPORTANT:
This change is not meant to create any change in emulator behavior or
functionality on any platform. It just provides the means for SoftFloat
library to be used in a more flexible way - in other words, it will just
prepare SoftFloat library for usage related to Mips platform and its
specifics regarding signaling bit meaning, which is done in some of
subsequent patches from this series.
Further break down of changes:
1) Added field snan_bit_is_one to the structure float_status, and
correspondent setter function set_snan_bit_is_one().
2) Constants <float16|float32|float64|floatx80|float128>_default_nan
(used both internally and externally) converted to functions
<float16|float32|float64|floatx80|float128>_default_nan(float_status*).
This is necessary since they are dependent on signaling bit meaning.
At the same time, for the sake of code cleanup and simplicity, constants
<floatx80|float128>_default_nan_<low|high> (used only internally within
SoftFloat library) are removed, as not needed.
3) Added a float_status* argument to SoftFloat library functions
XXX_is_quiet_nan(XXX a_), XXX_is_signaling_nan(XXX a_),
XXX_maybe_silence_nan(XXX a_). This argument must be present in
order to enable correct invocation of new version of functions
XXX_default_nan(). (XXX is <float16|float32|float64|floatx80|float128>
here)
4) Updated code for all platforms to reflect changes in SoftFloat library.
This change is twofolds: it includes modifications of SoftFloat library
functions invocations, and an addition of invocation of function
set_snan_bit_is_one() during CPU initialization, with arguments that
are appropriate for each particular platform. It was established that
all platforms zero their main CPU data structures, so snan_bit_is_one(0)
in appropriate places is not added, as it is not needed.
[1] "IEEE Standard for Floating-Point Arithmetic",
IEEE Computer Society, August 29, 2008.
Signed-off-by: Thomas Schwinge <thomas@codesourcery.com>
Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
Tested-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
Tested-by: Leon Alrae <leon.alrae@imgtec.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[leon.alrae@imgtec.com:
* cherry-picked 2 chunks from patch #2 to fix compilation warnings]
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
2016-06-10 11:57:28 +02:00
|
|
|
uint32_t HELPER(tcdb)(CPUS390XState *env, uint64_t v1, uint64_t m2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2019-02-18 13:26:56 +01:00
|
|
|
return (m2 & float64_dcmask(env, v1)) != 0;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* test data class 128-bit */
|
2019-02-18 13:26:56 +01:00
|
|
|
uint32_t HELPER(tcxb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint64_t m2)
|
|
|
|
{
|
|
|
|
return (m2 & float128_dcmask(env, make_float128(ah, al))) != 0;
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 23:33:03 +02:00
|
|
|
/* square root 32-bit */
|
|
|
|
uint64_t HELPER(sqeb)(CPUS390XState *env, uint64_t f2)
|
2012-09-02 09:33:31 +02:00
|
|
|
{
|
2012-08-23 23:33:03 +02:00
|
|
|
float32 ret = float32_sqrt(f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 23:33:03 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* square root 64-bit */
|
|
|
|
uint64_t HELPER(sqdb)(CPUS390XState *env, uint64_t f2)
|
|
|
|
{
|
|
|
|
float64 ret = float64_sqrt(f2, &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 23:33:03 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* square root 128-bit */
|
|
|
|
uint64_t HELPER(sqxb)(CPUS390XState *env, uint64_t ah, uint64_t al)
|
|
|
|
{
|
|
|
|
float128 ret = float128_sqrt(make_float128(ah, al), &env->fpu_status);
|
s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
Some instructions allow to suppress IEEE inexact exceptions.
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
IEEE-inexact-exception control (XxC): Bit 1 of
the M4 field is the XxC bit. If XxC is zero, recogni-
tion of IEEE-inexact exception is not suppressed;
if XxC is one, recognition of IEEE-inexact excep-
tion is suppressed.
Especially, handling for overflow/unerflow remains as is, inexact is
reported along
z14 PoP, 9-23, "Suppression of Certain IEEE Exceptions"
For example, the IEEE-inexact-exception control (XxC)
has no effect on the DXC; that is, the DXC for IEEE-
overflow or IEEE-underflow exceptions along with the
detail for exact, inexact and truncated, or inexact and
incremented, is reported according to the actual con-
dition.
Follow up patches will wire it correctly up for the applicable
instructions.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-12-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:06 +01:00
|
|
|
handle_exceptions(env, false, GETPC());
|
2012-08-23 23:33:03 +02:00
|
|
|
return RET128(ret);
|
2012-09-02 09:33:31 +02:00
|
|
|
}
|
2012-08-24 16:44:43 +02:00
|
|
|
|
s390x/tcg: Handle SET FPC AND LOAD FPC 3-bit BFP rounding modes
We already forward the 3 bits correctly in the translation functions. We
also have to handle them properly and check for specification
exceptions.
Setting an invalid rounding mode (BFP only, all DFP rounding modes)
results in a specification exception. Setting unassigned bits in the
fpc, results in a specification exception.
This fixes LOAD FPC (AND SIGNAL), SET FPC (AND SIGNAL). Also for,
SET BFP ROUNDING MODE, 3-bit rounding mode is now explicitly checked.
Note: TCG_CALL_NO_WG is required for sfpc handler, as we now inject
exceptions.
We won't be modeling abscence of the "floating-point extension facility"
for now, not necessary as most take the facility for granted without
checking.
z14 PoP, 9-23, "LOAD FPC"
When the floating-point extension facility is
installed, bits 29-31 of the second operand must
specify a valid BFP rounding mode and bits 6-7,
14-15, 24, and 28 must be zero; otherwise, a
specification exception is recognized.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-9-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:03 +01:00
|
|
|
static const int fpc_to_rnd[8] = {
|
2012-09-11 02:23:13 +02:00
|
|
|
float_round_nearest_even,
|
|
|
|
float_round_to_zero,
|
|
|
|
float_round_up,
|
s390x/tcg: Handle SET FPC AND LOAD FPC 3-bit BFP rounding modes
We already forward the 3 bits correctly in the translation functions. We
also have to handle them properly and check for specification
exceptions.
Setting an invalid rounding mode (BFP only, all DFP rounding modes)
results in a specification exception. Setting unassigned bits in the
fpc, results in a specification exception.
This fixes LOAD FPC (AND SIGNAL), SET FPC (AND SIGNAL). Also for,
SET BFP ROUNDING MODE, 3-bit rounding mode is now explicitly checked.
Note: TCG_CALL_NO_WG is required for sfpc handler, as we now inject
exceptions.
We won't be modeling abscence of the "floating-point extension facility"
for now, not necessary as most take the facility for granted without
checking.
z14 PoP, 9-23, "LOAD FPC"
When the floating-point extension facility is
installed, bits 29-31 of the second operand must
specify a valid BFP rounding mode and bits 6-7,
14-15, 24, and 28 must be zero; otherwise, a
specification exception is recognized.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-9-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:03 +01:00
|
|
|
float_round_down,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
-1,
|
|
|
|
float_round_to_odd,
|
2012-09-11 02:23:13 +02:00
|
|
|
};
|
|
|
|
|
2012-08-24 16:44:43 +02:00
|
|
|
/* set fpc */
|
|
|
|
void HELPER(sfpc)(CPUS390XState *env, uint64_t fpc)
|
|
|
|
{
|
s390x/tcg: Handle SET FPC AND LOAD FPC 3-bit BFP rounding modes
We already forward the 3 bits correctly in the translation functions. We
also have to handle them properly and check for specification
exceptions.
Setting an invalid rounding mode (BFP only, all DFP rounding modes)
results in a specification exception. Setting unassigned bits in the
fpc, results in a specification exception.
This fixes LOAD FPC (AND SIGNAL), SET FPC (AND SIGNAL). Also for,
SET BFP ROUNDING MODE, 3-bit rounding mode is now explicitly checked.
Note: TCG_CALL_NO_WG is required for sfpc handler, as we now inject
exceptions.
We won't be modeling abscence of the "floating-point extension facility"
for now, not necessary as most take the facility for granted without
checking.
z14 PoP, 9-23, "LOAD FPC"
When the floating-point extension facility is
installed, bits 29-31 of the second operand must
specify a valid BFP rounding mode and bits 6-7,
14-15, 24, and 28 must be zero; otherwise, a
specification exception is recognized.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-9-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:03 +01:00
|
|
|
if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
|
|
|
|
(!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
|
|
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
|
|
|
|
}
|
|
|
|
|
2012-08-24 16:44:43 +02:00
|
|
|
/* Install everything in the main FPC. */
|
|
|
|
env->fpc = fpc;
|
|
|
|
|
|
|
|
/* Install the rounding mode in the shadow fpu_status. */
|
s390x/tcg: Handle SET FPC AND LOAD FPC 3-bit BFP rounding modes
We already forward the 3 bits correctly in the translation functions. We
also have to handle them properly and check for specification
exceptions.
Setting an invalid rounding mode (BFP only, all DFP rounding modes)
results in a specification exception. Setting unassigned bits in the
fpc, results in a specification exception.
This fixes LOAD FPC (AND SIGNAL), SET FPC (AND SIGNAL). Also for,
SET BFP ROUNDING MODE, 3-bit rounding mode is now explicitly checked.
Note: TCG_CALL_NO_WG is required for sfpc handler, as we now inject
exceptions.
We won't be modeling abscence of the "floating-point extension facility"
for now, not necessary as most take the facility for granted without
checking.
z14 PoP, 9-23, "LOAD FPC"
When the floating-point extension facility is
installed, bits 29-31 of the second operand must
specify a valid BFP rounding mode and bits 6-7,
14-15, 24, and 28 must be zero; otherwise, a
specification exception is recognized.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-9-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:03 +01:00
|
|
|
set_float_rounding_mode(fpc_to_rnd[fpc & 0x7], &env->fpu_status);
|
2012-09-11 02:23:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* set fpc and signal */
|
2019-02-18 13:27:01 +01:00
|
|
|
void HELPER(sfas)(CPUS390XState *env, uint64_t fpc)
|
2012-09-11 02:23:13 +02:00
|
|
|
{
|
|
|
|
uint32_t signalling = env->fpc;
|
|
|
|
uint32_t s390_exc;
|
|
|
|
|
s390x/tcg: Handle SET FPC AND LOAD FPC 3-bit BFP rounding modes
We already forward the 3 bits correctly in the translation functions. We
also have to handle them properly and check for specification
exceptions.
Setting an invalid rounding mode (BFP only, all DFP rounding modes)
results in a specification exception. Setting unassigned bits in the
fpc, results in a specification exception.
This fixes LOAD FPC (AND SIGNAL), SET FPC (AND SIGNAL). Also for,
SET BFP ROUNDING MODE, 3-bit rounding mode is now explicitly checked.
Note: TCG_CALL_NO_WG is required for sfpc handler, as we now inject
exceptions.
We won't be modeling abscence of the "floating-point extension facility"
for now, not necessary as most take the facility for granted without
checking.
z14 PoP, 9-23, "LOAD FPC"
When the floating-point extension facility is
installed, bits 29-31 of the second operand must
specify a valid BFP rounding mode and bits 6-7,
14-15, 24, and 28 must be zero; otherwise, a
specification exception is recognized.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-9-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:03 +01:00
|
|
|
if (fpc_to_rnd[fpc & 0x7] == -1 || fpc & 0x03030088u ||
|
|
|
|
(!s390_has_feat(S390_FEAT_FLOATING_POINT_EXT) && fpc & 0x4)) {
|
|
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
|
|
|
|
}
|
|
|
|
|
2019-02-18 13:27:01 +01:00
|
|
|
/*
|
|
|
|
* FPC is set to the FPC operand with a bitwise OR of the signalling
|
|
|
|
* flags.
|
|
|
|
*/
|
|
|
|
env->fpc = fpc | (signalling & 0x00ff0000);
|
s390x/tcg: Handle SET FPC AND LOAD FPC 3-bit BFP rounding modes
We already forward the 3 bits correctly in the translation functions. We
also have to handle them properly and check for specification
exceptions.
Setting an invalid rounding mode (BFP only, all DFP rounding modes)
results in a specification exception. Setting unassigned bits in the
fpc, results in a specification exception.
This fixes LOAD FPC (AND SIGNAL), SET FPC (AND SIGNAL). Also for,
SET BFP ROUNDING MODE, 3-bit rounding mode is now explicitly checked.
Note: TCG_CALL_NO_WG is required for sfpc handler, as we now inject
exceptions.
We won't be modeling abscence of the "floating-point extension facility"
for now, not necessary as most take the facility for granted without
checking.
z14 PoP, 9-23, "LOAD FPC"
When the floating-point extension facility is
installed, bits 29-31 of the second operand must
specify a valid BFP rounding mode and bits 6-7,
14-15, 24, and 28 must be zero; otherwise, a
specification exception is recognized.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190218122710.23639-9-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2019-02-18 13:27:03 +01:00
|
|
|
set_float_rounding_mode(fpc_to_rnd[fpc & 0x7], &env->fpu_status);
|
2012-09-11 02:23:13 +02:00
|
|
|
|
2019-02-18 13:27:01 +01:00
|
|
|
/*
|
|
|
|
* If any signaling flag is enabled in the new FPC mask, a
|
|
|
|
* simulated-iee-exception exception occurs.
|
|
|
|
*/
|
|
|
|
s390_exc = (signalling >> 16) & (fpc >> 24);
|
2012-09-11 02:23:13 +02:00
|
|
|
if (s390_exc) {
|
2019-02-18 13:27:02 +01:00
|
|
|
if (s390_exc & S390_IEEE_MASK_INVALID) {
|
|
|
|
s390_exc = S390_IEEE_MASK_INVALID;
|
|
|
|
} else if (s390_exc & S390_IEEE_MASK_DIVBYZERO) {
|
|
|
|
s390_exc = S390_IEEE_MASK_DIVBYZERO;
|
|
|
|
} else if (s390_exc & S390_IEEE_MASK_OVERFLOW) {
|
|
|
|
s390_exc &= (S390_IEEE_MASK_OVERFLOW | S390_IEEE_MASK_INEXACT);
|
|
|
|
} else if (s390_exc & S390_IEEE_MASK_UNDERFLOW) {
|
|
|
|
s390_exc &= (S390_IEEE_MASK_UNDERFLOW | S390_IEEE_MASK_INEXACT);
|
|
|
|
} else if (s390_exc & S390_IEEE_MASK_INEXACT) {
|
|
|
|
s390_exc = S390_IEEE_MASK_INEXACT;
|
|
|
|
} else if (s390_exc & S390_IEEE_MASK_QUANTUM) {
|
|
|
|
s390_exc = S390_IEEE_MASK_QUANTUM;
|
|
|
|
}
|
2018-09-27 15:02:56 +02:00
|
|
|
tcg_s390_data_exception(env, s390_exc | 3, GETPC());
|
2012-09-11 02:23:13 +02:00
|
|
|
}
|
2012-08-24 16:44:43 +02:00
|
|
|
}
|
2019-02-18 13:27:04 +01:00
|
|
|
|
|
|
|
/* set bfp rounding mode */
|
|
|
|
void HELPER(srnm)(CPUS390XState *env, uint64_t rnd)
|
|
|
|
{
|
|
|
|
if (rnd > 0x7 || fpc_to_rnd[rnd & 0x7] == -1) {
|
|
|
|
s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, GETPC());
|
|
|
|
}
|
|
|
|
|
|
|
|
env->fpc = deposit32(env->fpc, 0, 3, rnd);
|
|
|
|
set_float_rounding_mode(fpc_to_rnd[rnd & 0x7], &env->fpu_status);
|
|
|
|
}
|