[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 2/5] target-tricore: Added MADD.F and MSUB.F
From: |
Richard Henderson |
Subject: |
Re: [Qemu-devel] [PATCH v2 2/5] target-tricore: Added MADD.F and MSUB.F instructions |
Date: |
Tue, 8 Nov 2016 12:42:38 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 |
On 11/07/2016 03:44 PM, Bastian Koppelmann wrote:
Multiplies D[a] and D[b] and adds/subtracts the result to/from D[d].
The result is put in D[c]. All operands are floating-point numbers.
Signed-off-by: Bastian Koppelmann <address@hidden>
---
target-tricore/fpu_helper.c | 93 ++++++++++++++++++++++++++++++++++++++++++++-
target-tricore/helper.h | 2 +
target-tricore/translate.c | 8 ++++
3 files changed, 102 insertions(+), 1 deletion(-)
diff --git a/target-tricore/fpu_helper.c b/target-tricore/fpu_helper.c
index f717b53..d530a0b 100644
--- a/target-tricore/fpu_helper.c
+++ b/target-tricore/fpu_helper.c
@@ -21,7 +21,8 @@
#include "cpu.h"
#include "exec/helper-proto.h"
-#define ADD_NAN 0x7cf00001
+#define QUIET_NAN 0x7fc00000
+#define ADD_NAN 0x7fc00001
#define DIV_NAN 0x7fc00008
#define MUL_NAN 0x7fc00002
#define FPU_FS PSW_USB_C
@@ -47,6 +48,42 @@ static inline bool f_is_denormal(float32 arg)
return float32_is_zero_or_denormal(arg) && !float32_is_zero(arg);
}
+static inline float32 f_maddsub_nan_result(float32 arg1, float32 arg2,
+ float32 arg3, float32 result,
+ uint32_t flags)
+{
+ uint32_t aSign, bSign, cSign;
+ uint32_t aExp, bExp, cExp;
+
+ if (float32_is_any_nan(arg1) || float32_is_any_nan(arg2) ||
+ float32_is_any_nan(arg3)) {
+ return QUIET_NAN;
+ } else if (float32_is_infinity(arg1) && float32_is_zero(arg2)) {
+ return MUL_NAN;
+ } else if (float32_is_zero(arg1) && float32_is_infinity(arg2)) {
+ return MUL_NAN;
+ } else {
+ aSign = arg1 >> 31;
+ bSign = arg2 >> 31;
+ cSign = arg3 >> 31;
+
+ aExp = (arg1 >> 23) & 0xff;
+ bExp = (arg2 >> 23) & 0xff;
+ cExp = (arg3 >> 23) & 0xff;
+
+ if (flags & float_muladd_negate_c) {
flags here is muladd argument,
+ flags = f_get_excp_flags(env);
+ if (flags) {
+ if (flags & float_flag_invalid) {
+ arg1 = float32_squash_input_denormal(arg1, &env->fp_status);
+ arg2 = float32_squash_input_denormal(arg2, &env->fp_status);
+ arg3 = float32_squash_input_denormal(arg3, &env->fp_status);
+ f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result, flags);
but passed here as exception bits.
+ }
+ f_update_psw_flags(env, flags);
+ } else {
+ env->FPU_FS = 0;
+ }
+ return (uint32_t)f_result;
+}
+
+uint32_t helper_fmsub(CPUTriCoreState *env, uint32_t r1,
+ uint32_t r2, uint32_t r3)
+{
+ uint32_t flags;
+ float32 arg1 = make_float32(r1);
+ float32 arg2 = make_float32(r2);
+ float32 arg3 = make_float32(r3);
+ float32 f_result;
+
+ f_result = float32_muladd(arg1, arg2, arg3, float_muladd_negate_product,
+ &env->fp_status);
+
+ flags = f_get_excp_flags(env);
+ if (flags) {
+ if (flags & float_flag_invalid) {
+ arg1 = float32_squash_input_denormal(arg1, &env->fp_status);
+ arg2 = float32_squash_input_denormal(arg2, &env->fp_status);
+ arg3 = float32_squash_input_denormal(arg3, &env->fp_status);
+
+ f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result, flags);
Same. Also, nan_result needs to check float_muladd_negate_product as used
here, not float_muladd_negate_c as used above.
r~
- [Qemu-devel] [PATCH v2 5/5] target-tricore: Add updfl instruction, (continued)
[Qemu-devel] [PATCH v2 2/5] target-tricore: Added MADD.F and MSUB.F instructions, Bastian Koppelmann, 2016/11/07
- Re: [Qemu-devel] [PATCH v2 2/5] target-tricore: Added MADD.F and MSUB.F instructions,
Richard Henderson <=