aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShow Liu <show.liu@linaro.org>2015-06-04 18:07:43 +0800
committerGil Pitney <gil.pitney@linaro.org>2015-06-05 17:21:49 +0000
commitdff2da92de7f00d899954180562e71e8ff7b370b (patch)
treea53c8eab45886bce9a3004c38f1bcd29a291c58f
parente65e7cbfad8685359a7e2a6b32abcaaa810ad19f (diff)
downloadshamrock-dff2da92de7f00d899954180562e71e8ff7b370b.tar.gz
fixed the sub_sat() builin function crash issue
-rw-r--r--src/builtins/sub_sat.cl83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/builtins/sub_sat.cl b/src/builtins/sub_sat.cl
index 78442f0..84fbbd9 100644
--- a/src/builtins/sub_sat.cl
+++ b/src/builtins/sub_sat.cl
@@ -27,6 +27,89 @@
*****************************************************************************/
#include "cpu.h"
+_CLC_OVERLOAD _CLC_DECL char sub_sat(char x, char y)
+{
+ int bits = CHAR_BIT * sizeof(char);
+ char min = (char)1 << (char)(bits-1);
+ char max = min - (char)1;
+ return ((x^y) >= (char)0 ?
+ /* different signs: no overflow/underflow */
+ x-y : x >= (char)0 ?
+ /* x and y positive: can overflow */
+ (x > max+y ? max : x-y) :
+ /* x and y negative: can underflow */
+ (x < min+y ? min : x-y));
+
+}
+
+_CLC_OVERLOAD _CLC_DECL short sub_sat(short x, short y)
+{
+ int bits = CHAR_BIT * sizeof(short);
+ short min = (short)1 << (short)(bits-1);
+ short max = min - (short)1;
+ return ((x^y) >= (short)0 ?
+ /* different signs: no overflow/underflow */
+ x-y : x >= (short)0 ?
+ /* x and y positive: can overflow */
+ (x > max+y ? max : x-y) :
+ /* x and y negative: can underflow */
+ (x < min+y ? min : x-y));
+
+}
+_CLC_OVERLOAD _CLC_DECL int sub_sat(int x, int y)
+{
+ int bits = CHAR_BIT * sizeof(int);
+ int min = (int)1 << (int)(bits-1);
+ int max = min - (int)1;
+ return ((x^y) >= (int)0 ?
+ /* different signs: no overflow/underflow */
+ x-y : x >= (int)0 ?
+ /* x and y positive: can overflow */
+ (x > max+y ? max : x-y) :
+ /* x and y negative: can underflow */
+ (x < min+y ? min : x-y));
+
+}
+
+_CLC_OVERLOAD _CLC_DECL long sub_sat(long x, long y)
+{
+ int bits = CHAR_BIT * sizeof(long);
+ long min = (long)1 << (long)(bits-1);
+ long max = min - (long)1;
+ return ((x^y) >= (long)0 ?
+ /* different signs: no overflow/underflow */
+ x-y : x >= (long)0 ?
+ /* x and y positive: can overflow */
+ (x > max+y ? max : x-y) :
+ /* x and y negative: can underflow */
+ (x < min+y ? min : x-y));
+
+}
+
+_CLC_OVERLOAD _CLC_DECL uchar sub_sat(uchar x, uchar y)
+{
+ uchar min = (uchar)0;
+ return (x < min+y ? min : x-y);
+}
+
+_CLC_OVERLOAD _CLC_DECL ushort sub_sat(ushort x, ushort y)
+{
+ ushort min = (ushort)0;
+ return (x < min+y ? min : x-y);
+}
+
+_CLC_OVERLOAD _CLC_DECL uint sub_sat(uint x, uint y)
+{
+ uint min = (uint)0;
+ return (x < min+y ? min : x-y);
+}
+
+_CLC_OVERLOAD _CLC_DECL ulong sub_sat(ulong x, ulong y)
+{
+ ulong min = (ulong)0;
+ return (x < min+y ? min : x-y);
+}
+
BINARY_VEC_DEF(char, char, sub_sat, sub_sat)
BINARY_VEC_DEF(uchar, uchar, sub_sat, sub_sat)
BINARY_VEC_DEF(short, short, sub_sat, sub_sat)