diff options
author | Show Liu <show.liu@linaro.org> | 2015-06-04 11:04:44 +0800 |
---|---|---|
committer | Gil Pitney <gil.pitney@linaro.org> | 2015-06-05 17:21:49 +0000 |
commit | e65e7cbfad8685359a7e2a6b32abcaaa810ad19f (patch) | |
tree | 4fe507b6c8d168e577d8e626151b7dd471ebcf42 | |
parent | ee27714b3919d58ee0c096bee743feaf5cb7341c (diff) |
fixed the add_sat() builtin function crash issue
-rw-r--r-- | src/builtins/add_sat.cl | 85 |
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) |