1From 6bc0b2cffab0ee280ae9730262f162f25c16f6c2 Mon Sep 17 00:00:00 2001 2From: Richard Henderson <richard.henderson@linaro.org> 3Date: Fri, 17 Dec 2021 17:57:14 +0100 4Subject: [PATCH 05/21] softfloat: Add flag specific to signaling nans 5MIME-Version: 1.0 6Content-Type: text/plain; charset=UTF-8 7Content-Transfer-Encoding: 8bit 8 9PowerPC has this flag, and it's easier to compute it here 10than after the fact. 11 12Upstream-Status: Backport 13[https://git.qemu.org/?p=qemu.git;a=commit;h=e706d4455b8d54252b11fc504c56df060151cb89] 14 15Signed-off-by: Richard Henderson <richard.henderson@linaro.org> 16Message-Id: <20211119160502.17432-8-richard.henderson@linaro.org> 17Signed-off-by: Cédric Le Goater <clg@kaod.org> 18Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com> 19--- 20 fpu/softfloat-parts.c.inc | 18 ++++++++++++------ 21 fpu/softfloat.c | 4 +++- 22 include/fpu/softfloat-types.h | 1 + 23 3 files changed, 16 insertions(+), 7 deletions(-) 24 25diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc 26index b8563cd2df..9518f3dc61 100644 27--- a/fpu/softfloat-parts.c.inc 28+++ b/fpu/softfloat-parts.c.inc 29@@ -19,7 +19,7 @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s) 30 { 31 switch (a->cls) { 32 case float_class_snan: 33- float_raise(float_flag_invalid, s); 34+ float_raise(float_flag_invalid | float_flag_invalid_snan, s); 35 if (s->default_nan_mode) { 36 parts_default_nan(a, s); 37 } else { 38@@ -40,7 +40,7 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b, 39 float_status *s) 40 { 41 if (is_snan(a->cls) || is_snan(b->cls)) { 42- float_raise(float_flag_invalid, s); 43+ float_raise(float_flag_invalid | float_flag_invalid_snan, s); 44 } 45 46 if (s->default_nan_mode) { 47@@ -68,7 +68,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b, 48 int which; 49 50 if (unlikely(abc_mask & float_cmask_snan)) { 51- float_raise(float_flag_invalid, s); 52+ float_raise(float_flag_invalid | float_flag_invalid_snan, s); 53 } 54 55 which = pickNaNMulAdd(a->cls, b->cls, c->cls, 56@@ -1049,8 +1049,10 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode, 57 58 switch (p->cls) { 59 case float_class_snan: 60+ flags |= float_flag_invalid_snan; 61+ /* fall through */ 62 case float_class_qnan: 63- flags = float_flag_invalid; 64+ flags |= float_flag_invalid; 65 r = max; 66 break; 67 68@@ -1114,8 +1116,10 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode, 69 70 switch (p->cls) { 71 case float_class_snan: 72+ flags |= float_flag_invalid_snan; 73+ /* fall through */ 74 case float_class_qnan: 75- flags = float_flag_invalid; 76+ flags |= float_flag_invalid; 77 r = max; 78 break; 79 80@@ -1341,7 +1345,9 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b, 81 } 82 83 if (unlikely(ab_mask & float_cmask_anynan)) { 84- if (!is_quiet || (ab_mask & float_cmask_snan)) { 85+ if (ab_mask & float_cmask_snan) { 86+ float_raise(float_flag_invalid | float_flag_invalid_snan, s); 87+ } else if (!is_quiet) { 88 float_raise(float_flag_invalid, s); 89 } 90 return float_relation_unordered; 91diff --git a/fpu/softfloat.c b/fpu/softfloat.c 92index 9a28720d82..834ed3a054 100644 93--- a/fpu/softfloat.c 94+++ b/fpu/softfloat.c 95@@ -2543,8 +2543,10 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status) 96 static void parts_float_to_ahp(FloatParts64 *a, float_status *s) 97 { 98 switch (a->cls) { 99- case float_class_qnan: 100 case float_class_snan: 101+ float_raise(float_flag_invalid_snan, s); 102+ /* fall through */ 103+ case float_class_qnan: 104 /* 105 * There is no NaN in the destination format. Raise Invalid 106 * and return a zero with the sign of the input NaN. 107diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h 108index 5a9671e564..e557b9126b 100644 109--- a/include/fpu/softfloat-types.h 110+++ b/include/fpu/softfloat-types.h 111@@ -156,6 +156,7 @@ enum { 112 float_flag_invalid_imz = 0x0100, /* inf * 0 */ 113 float_flag_invalid_idi = 0x0200, /* inf / inf */ 114 float_flag_invalid_zdz = 0x0400, /* 0 / 0 */ 115+ float_flag_invalid_snan = 0x2000, /* any operand was snan */ 116 }; 117 118 /* 119-- 1202.17.1 121 122