aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShow Liu <show.liu@linaro.org>2015-06-04 11:04:44 +0800
committerGil Pitney <gil.pitney@linaro.org>2015-06-05 17:21:49 +0000
commite65e7cbfad8685359a7e2a6b32abcaaa810ad19f (patch)
tree4fe507b6c8d168e577d8e626151b7dd471ebcf42
parentee27714b3919d58ee0c096bee743feaf5cb7341c (diff)
downloadshamrock-e65e7cbfad8685359a7e2a6b32abcaaa810ad19f.tar.gz
fixed the add_sat() builtin function crash issue
-rw-r--r--src/builtins/add_sat.cl85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/builtins/add_sat.cl b/src/builtins/add_sat.cl
index e70b3fb..1e41bb3 100644
--- a/src/builtins/add_sat.cl
+++ b/src/builtins/add_sat.cl
@@ -27,6 +27,91 @@
*****************************************************************************/
#include "cpu.h"
+
+_CLC_OVERLOAD _CLC_DECL char add_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 add_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 add_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 add_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 add_sat(uchar x, uchar y)
+{
+ uchar max = ~(uchar)0;
+ return (x > max-y ? max : x+y);
+}
+
+_CLC_OVERLOAD _CLC_DECL ushort add_sat(ushort x, ushort y)
+{
+ ushort max = ~(ushort)0;
+ return (x > max-y ? max : x+y);
+}
+
+_CLC_OVERLOAD _CLC_DECL uint add_sat(uint x, uint y)
+{
+ uint max = ~(uint)0;
+ return (x > max-y ? max : x+y);
+}
+
+_CLC_OVERLOAD _CLC_DECL ulong add_sat(ulong x, ulong y)
+{
+ ulong max = ~(ulong)0;
+ return (x > max-y ? max : x+y);
+}
+
BINARY_VEC_DEF(char, char, add_sat, add_sat)
BINARY_VEC_DEF(uchar, uchar, add_sat, add_sat)
BINARY_VEC_DEF(short, short, add_sat, add_sat)