From 1d10cd6185edfd46d51f6562bff832a9b5d36cff Mon Sep 17 00:00:00 2001 From: Rekai Gonzalez-Alberquilla Date: Tue, 25 Apr 2017 18:35:54 +0100 Subject: arch-arm: Fix some poorly done type max and min in NEON 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 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/3481 Reviewed-by: Jason Lowe-Power Maintainer: Andreas Sandberg --- src/arch/arm/isa/insts/neon.isa | 36 ++++++++++++++++++++---------------- src/arch/arm/isa/insts/neon64.isa | 20 ++++++++++---------- 2 files changed, 30 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/arch/arm/isa/insts/neon.isa b/src/arch/arm/isa/insts/neon.isa index 163b71c13..64419e46a 100644 --- a/src/arch/arm/isa/insts/neon.isa +++ b/src/arch/arm/isa/insts/neon.isa @@ -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::max(); + else + /* If (<0) plus (<0) yields (>=0), saturate to -. */ + destElem = std::numeric_limits::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::max(); + else + /* If (<0) minus (>=0) yields (>=0), saturate to -. */ + destElem = std::numeric_limits::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::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::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::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::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::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::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::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::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::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::min())) { fpscr.qc = 1; destElem = ~srcElem1; } else { diff --git a/src/arch/arm/isa/insts/neon64.isa b/src/arch/arm/isa/insts/neon64.isa index 697ea80e2..7c9040be3 100644 --- a/src/arch/arm/isa/insts/neon64.isa +++ b/src/arch/arm/isa/insts/neon64.isa @@ -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::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::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::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::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::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::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::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::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::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::min(); if (negDest) destElem -= 1; fpscr.qc = 1; -- cgit v1.2.3