diff options
author | Yi Sun <yi.sun@intel.com> | 2013-08-12 10:35:38 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@linux.intel.com> | 2013-08-12 12:43:16 +0800 |
commit | d5359e693b1bd12627d53ccf1152e73f739df185 (patch) | |
tree | f89311a23221f79873babee3dc3fb92187639914 | |
parent | c17c749820ba448527e2aecff7d73973a0315a7e (diff) | |
download | beignet-d5359e693b1bd12627d53ccf1152e73f739df185.tar.gz |
Handle boundary and illegal values.
Such as |x| = 1.0, |x| < 2**-27 and |x| > 1.
v2. Replace some constant variable with existing macro value.
Signed-off-by: Yi Sun <yi.sun@intel.com>
Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
-rw-r--r-- | backend/src/ocl_stdlib.tmpl.h | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/backend/src/ocl_stdlib.tmpl.h b/backend/src/ocl_stdlib.tmpl.h index 84f15ca4..d1cc6aa4 100644 --- a/backend/src/ocl_stdlib.tmpl.h +++ b/backend/src/ocl_stdlib.tmpl.h @@ -123,6 +123,7 @@ typedef size_t __event_t; #define FLT_MIN_10_EXP -37 #define FLT_MIN_EXP -125 #define FLT_RADIX 2 +#define FLT_ONE 1.0000000000e+00 /* 0x3F800000 */ #define FLT_MAX 0x1.fffffep127f #define FLT_MIN 0x1.0p-126f #define FLT_EPSILON 0x1.0p-23f @@ -561,7 +562,36 @@ INLINE_OVERLOADABLE float __gen_ocl_internal_tanh(float x) { float y = native_exp(-2 * x); return (1 - y) / (1 + y); } + +typedef union +{ + float value; + int word; +} ieee_float_shape_type; + +#ifndef GET_FLOAT_WORD +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) +#endif + INLINE_OVERLOADABLE float __gen_ocl_internal_asin(float x) { + int hx, ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix == 0x3f800000) { + return x * M_PI_2_F; /* asin(|1|)=+-pi/2 with inexact */ + } + if(ix > 0x3f800000) { /* |x|>= 1 */ + return (x-x) / (x-x); /* asin(|x|>1) is NaN */ + } + if(ix < 0x32000000) { /* if |x| < 2**-27 */ + if(HUGE_VALF + x > FLT_ONE) return x; /* return x with inexact if x!=0*/ + } + /* 1 > |x| >= 2**-27 */ float sum = x, c = x, m = 1.0; int n = 1; do |