add built-in function "atan2pi"
authorHomer Hsing <homer.xing@intel.com>
Fri, 13 Sep 2013 02:22:48 +0000 (10:22 +0800)
committerZhigang Gong <zhigang.gong@linux.intel.com>
Fri, 13 Sep 2013 03:20:26 +0000 (11:20 +0800)
version 2: fix a typo. and add corner cases

Signed-off-by: Homer Hsing <homer.xing@intel.com>
Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
backend/src/builtin_vector_proto.def
backend/src/ocl_stdlib.tmpl.h

index 23ed8d3..2b8f913 100644 (file)
@@ -9,7 +9,7 @@ gentype atan (gentype y_over_x)
 gentype atan2 (gentype y, gentype x)
 gentype atanh (gentype)
 gentype atanpi (gentype x)
-#gentype atan2pi (gentype y, gentype x)
+gentype atan2pi (gentype y, gentype x)
 gentype cbrt (gentype)
 gentype ceil (gentype)
 gentype copysign (gentype x, gentype y)
index bc6ecbe..0f91bf5 100644 (file)
@@ -1391,6 +1391,66 @@ INLINE_OVERLOADABLE float __gen_ocl_internal_atan2(float y, float x) {
     return - M_PI_F + z;
   }
 }
+INLINE_OVERLOADABLE float __gen_ocl_internal_atan2pi(float y, float x) {
+  uint ix = as_uint(x), iy = as_uint(y),
+       pos_zero = 0, neg_zero = 0x80000000u,
+       pos_inf = 0x7f800000, neg_inf = 0xff800000u;
+  if(iy == pos_zero) {
+    if(ix == pos_zero)
+      return 0;
+    if(ix == neg_zero)
+      return 1;
+    if(x < 0)
+      return 1;
+    if(x > 0)
+      return 0;
+  }
+  if(iy == neg_zero) {
+    if(ix == pos_zero)
+      return -0.f;
+    if(ix == neg_zero)
+      return -1;
+    if(x < 0)
+      return -1;
+    if(x > 0)
+      return -0.f;
+  }
+  if((ix & 0x7fffffff) == 0) {
+    if(y < 0)
+      return -.5f;
+    if(y > 0)
+      return .5f;
+  }
+  if(ix == pos_inf) {
+    if(y > 0 && iy != pos_inf)
+      return 0;
+    if(y < 0 && iy != neg_inf)
+      return -0.f;
+  }
+  if(ix == neg_inf) {
+    if(y > 0 && iy != pos_inf)
+      return 1;
+    if(y < 0 && iy != neg_inf)
+      return -1;
+  }
+  if(iy == pos_inf) {
+    if(ix == pos_inf)
+      return 0.25f;
+    if(ix == neg_inf)
+      return 0.75f;
+    if(x >= 0 || x <= 0)
+      return 0.5f;
+  }
+  if(iy == neg_inf) {
+    if(ix == pos_inf)
+      return -0.25f;
+    if(ix == neg_inf)
+      return -0.75f;
+    if(x >= 0 || x <= 0)
+      return -0.5f;
+  }
+  return __gen_ocl_internal_atan2(y, x) / M_PI_F;
+}
 INLINE_OVERLOADABLE float __gen_ocl_internal_fabs(float x)  { return __gen_ocl_fabs(x); }
 INLINE_OVERLOADABLE float __gen_ocl_internal_trunc(float x) { return __gen_ocl_rndz(x); }
 INLINE_OVERLOADABLE float __gen_ocl_internal_round(float x) { return __gen_ocl_rnde(x); }
@@ -1424,6 +1484,7 @@ INLINE_OVERLOADABLE float __gen_ocl_internal_rint(float x) {
 #define tanh __gen_ocl_internal_tanh
 #define atan __gen_ocl_internal_atan
 #define atan2 __gen_ocl_internal_atan2
+#define atan2pi __gen_ocl_internal_atan2pi
 #define atanpi __gen_ocl_internal_atanpi
 #define atanh __gen_ocl_internal_atanh
 #define pow powr