arch-arm: Fix some poorly done type max and min in NEON
authorRekai Gonzalez-Alberquilla <rekai.gonzalezalberquilla@arm.com>
Tue, 25 Apr 2017 17:35:54 +0000 (18:35 +0100)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Tue, 23 May 2017 17:30:03 +0000 (17:30 +0000)
The ISA code for ARM calculates min and max elements for types using
bit manipulation. That triggers some warnings, treated as errors, as
the compiler can tell that there is an overflow and the sign
flips. Fixed using standard lib definitions instead.

Change-Id: Ie2331b410c7f76d4bd87da5afe9edf20c8ac91b3
Reviewed-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/3481
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

src/arch/arm/isa/insts/neon.isa
src/arch/arm/isa/insts/neon64.isa

index 163b71c138c7cbc39302793c009456ec822ba255..64419e46abf2753279dedbf4b5defe1f6779574a 100644 (file)
@@ -2170,9 +2170,12 @@ let {{
         bool negSrc1 = (srcElem1 < 0);
         bool negSrc2 = (srcElem2 < 0);
         if ((negDest != negSrc1) && (negSrc1 == negSrc2)) {
-            destElem = (Element)1 << (sizeof(Element) * 8 - 1);
             if (negDest)
-                destElem -= 1;
+                /* If (>=0) plus (>=0) yields (<0), saturate to +. */
+                destElem = std::numeric_limits<Element>::max();
+            else
+                /* If (<0) plus (<0) yields (>=0), saturate to -. */
+                destElem = std::numeric_limits<Element>::min();
             fpscr.qc = 1;
         }
         FpscrQc = fpscr;
@@ -2199,9 +2202,12 @@ let {{
         bool negSrc1 = (srcElem1 < 0);
         bool posSrc2 = (srcElem2 >= 0);
         if ((negDest != negSrc1) && (negSrc1 == posSrc2)) {
-            destElem = (Element)1 << (sizeof(Element) * 8 - 1);
             if (negDest)
-                destElem -= 1;
+                /* If (>=0) minus (<0) yields (<0), saturate to +. */
+                destElem = std::numeric_limits<Element>::max();
+            else
+                /* If (<0) minus (>=0) yields (>=0), saturate to -. */
+                destElem = std::numeric_limits<Element>::min();
             fpscr.qc = 1;
         }
         FpscrQc = fpscr;
@@ -2514,7 +2520,7 @@ let {{
     vqdmlalCode = '''
         FPSCR fpscr = (FPSCR) FpscrQc;
         BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
-        Element maxNeg = (Element)1 << (sizeof(Element) * 8 - 1);
+        Element maxNeg = std::numeric_limits<Element>::min();
         Element halfNeg = maxNeg / 2;
         if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
             (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
@@ -2539,7 +2545,7 @@ let {{
     vqdmlslCode = '''
         FPSCR fpscr = (FPSCR) FpscrQc;
         BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
-        Element maxNeg = (Element)1 << (sizeof(Element) * 8 - 1);
+        Element maxNeg = std::numeric_limits<Element>::min();
         Element halfNeg = maxNeg / 2;
         if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
             (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
@@ -2565,8 +2571,7 @@ let {{
         FPSCR fpscr = (FPSCR) FpscrQc;
         destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
         if (srcElem1 == srcElem2 &&
-                srcElem1 == (Element)((Element)1 <<
-                    (Element)(sizeof(Element) * 8 - 1))) {
+                srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
             destElem = ~((BigElement)srcElem1 << (sizeof(Element) * 8));
             fpscr.qc = 1;
         }
@@ -2611,8 +2616,7 @@ let {{
         destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2) >>
                    (sizeof(Element) * 8);
         if (srcElem1 == srcElem2 &&
-                srcElem1 == (Element)((Element)1 <<
-                    (sizeof(Element) * 8 - 1))) {
+                srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
             destElem = ~srcElem1;
             fpscr.qc = 1;
         }
@@ -2626,7 +2630,7 @@ let {{
         destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2 +
                     ((int64_t)1 << (sizeof(Element) * 8 - 1))) >>
                    (sizeof(Element) * 8);
-        Element maxNeg = (Element)1 << (sizeof(Element) * 8 - 1);
+        Element maxNeg = std::numeric_limits<Element>::min();
         Element halfNeg = maxNeg / 2;
         if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
             (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
@@ -2634,7 +2638,7 @@ let {{
             if (destElem < 0) {
                 destElem = mask(sizeof(Element) * 8 - 1);
             } else {
-                destElem = (Element)1 << (sizeof(Element) * 8 - 1);
+                destElem = std::numeric_limits<Element>::min();
             }
             fpscr.qc = 1;
         }
@@ -2973,7 +2977,7 @@ let {{
         FPSCR fpscr = (FPSCR) FpscrQc;
         if (imm >= sizeof(Element) * 8) {
             if (srcElem1 != 0) {
-                destElem = (Element)1 << (sizeof(Element) * 8 - 1);
+                destElem = std::numeric_limits<Element>::min();
                 if (srcElem1 > 0)
                     destElem = ~destElem;
                 fpscr.qc = 1;
@@ -2986,7 +2990,7 @@ let {{
                                     sizeof(Element) * 8 - 1,
                                     sizeof(Element) * 8 - 1 - imm);
             if (topBits != 0 && topBits != mask(imm + 1)) {
-                destElem = (Element)1 << (sizeof(Element) * 8 - 1);
+                destElem = std::numeric_limits<Element>::min();
                 if (srcElem1 > 0)
                     destElem = ~destElem;
                 fpscr.qc = 1;
@@ -3489,7 +3493,7 @@ let {{
 
     vqabsCode = '''
         FPSCR fpscr = (FPSCR) FpscrQc;
-        if (srcElem1 == (Element)((Element)1 << (sizeof(Element) * 8 - 1))) {
+        if (srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
             fpscr.qc = 1;
             destElem = ~srcElem1;
         } else if (srcElem1 < 0) {
@@ -3504,7 +3508,7 @@ let {{
 
     vqnegCode = '''
         FPSCR fpscr = (FPSCR) FpscrQc;
-        if (srcElem1 == (Element)((Element)1 << (sizeof(Element) * 8 - 1))) {
+        if (srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
             fpscr.qc = 1;
             destElem = ~srcElem1;
         } else {
index 697ea80e2b89f79fbe0cdc299d508deae35b8c19..7c9040be30984801a524be029056f66383d749ab 100644 (file)
@@ -2006,7 +2006,7 @@ let {{
     # SQABS
     sqabsCode = '''
         FPSCR fpscr = (FPSCR) FpscrQc;
-        if (srcElem1 == (Element)((Element)1 << (sizeof(Element) * 8 - 1))) {
+        if (srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
             fpscr.qc = 1;
             destElem = ~srcElem1;
         } else if (srcElem1 < 0) {
@@ -2030,7 +2030,7 @@ let {{
             bool negSrc1 = (srcElem1 < 0);
             bool negSrc2 = (srcElem2 < 0);
             if ((negDest != negSrc1) && (negSrc1 == negSrc2)) {
-                destElem = (Element)1 << (sizeof(Element) * 8 - 1);
+                destElem = std::numeric_limits<Element>::min();
                 if (negDest)
                     destElem -= 1;
                 fpscr.qc = 1;
@@ -2047,7 +2047,7 @@ let {{
     qdmlalCode = '''
         FPSCR fpscr = (FPSCR) FpscrQc;
         BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
-        Element maxNeg = (Element)1 << (sizeof(Element) * 8 - 1);
+        Element maxNeg = std::numeric_limits<Element>::min();
         Element halfNeg = maxNeg / 2;
         if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
             (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
@@ -2086,7 +2086,7 @@ let {{
     qdmlslCode = '''
         FPSCR fpscr = (FPSCR) FpscrQc;
         BigElement midElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2);
-        Element maxNeg = (Element)1 << (sizeof(Element) * 8 - 1);
+        Element maxNeg = std::numeric_limits<Element>::min();
         Element halfNeg = maxNeg / 2;
         if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
             (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
@@ -2178,7 +2178,7 @@ let {{
     # SQNEG
     sqnegCode = '''
         FPSCR fpscr = (FPSCR) FpscrQc;
-        if (srcElem1 == (Element)((Element)1 << (sizeof(Element) * 8 - 1))) {
+        if (srcElem1 == (Element)(std::numeric_limits<Element>::min())) {
             fpscr.qc = 1;
             destElem = ~srcElem1;
         } else {
@@ -2198,7 +2198,7 @@ let {{
             destElem = (2 * (int64_t)srcElem1 * (int64_t)srcElem2 +
                         ((int64_t)1 << (sizeof(Element) * 8 - 1))) >>
                        (sizeof(Element) * 8);
-            Element maxNeg = (Element)1 << (sizeof(Element) * 8 - 1);
+            Element maxNeg = std::numeric_limits<Element>::min();
             Element halfNeg = maxNeg / 2;
             if ((srcElem1 == maxNeg && srcElem2 == maxNeg) ||
                 (srcElem1 == halfNeg && srcElem2 == maxNeg) ||
@@ -2206,7 +2206,7 @@ let {{
                 if (destElem < 0) {
                     destElem = mask(sizeof(Element) * 8 - 1);
                 } else {
-                    destElem = (Element)1 << (sizeof(Element) * 8 - 1);
+                    destElem = std::numeric_limits<Element>::min();
                 }
                 fpscr.qc = 1;
             }
@@ -2368,7 +2368,7 @@ let {{
             FPSCR fpscr = (FPSCR) FpscrQc;
             if (imm >= sizeof(Element) * 8) {
                 if (srcElem1 != 0) {
-                    destElem = (Element)1 << (sizeof(Element) * 8 - 1);
+                    destElem = std::numeric_limits<Element>::min();
                     if (srcElem1 > 0)
                         destElem = ~destElem;
                     fpscr.qc = 1;
@@ -2381,7 +2381,7 @@ let {{
                                         sizeof(Element) * 8 - 1,
                                         sizeof(Element) * 8 - 1 - imm);
                 if (topBits != 0 && topBits != mask(imm + 1)) {
-                    destElem = (Element)1 << (sizeof(Element) * 8 - 1);
+                    destElem = std::numeric_limits<Element>::min();
                     if (srcElem1 > 0)
                         destElem = ~destElem;
                     fpscr.qc = 1;
@@ -2557,7 +2557,7 @@ let {{
             bool negSrc1 = (srcElem1 < 0);
             bool posSrc2 = (srcElem2 >= 0);
             if ((negDest != negSrc1) && (negSrc1 == posSrc2)) {
-                destElem = (Element)1 << (sizeof(Element) * 8 - 1);
+                destElem = std::numeric_limits<Element>::min();
                 if (negDest)
                     destElem -= 1;
                 fpscr.qc = 1;