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