fix __builtin_nan and add some missing builtins
authorDale Weiler <weilercdale@gmail.com>
Wed, 14 Nov 2018 13:43:22 +0000 (08:43 -0500)
committerDale Weiler <weilercdale@gmail.com>
Wed, 14 Nov 2018 13:43:22 +0000 (08:43 -0500)
fold.cpp
fold.h
intrin.cpp

index 7b13db6..a982bf6 100644 (file)
--- a/fold.cpp
+++ b/fold.cpp
@@ -1486,29 +1486,54 @@ ast_expression *fold::intrinsic_pow(ast_value *lhs, ast_value *rhs) {
 ast_expression *fold::intrinsic_fabs(ast_value *a) {
     return constgen_float(fabsf(immvalue_float(a)), false);
 }
+ast_expression* fold::intrinsic_nan(void) {
+    return constgen_float(0.0f / 0.0f, false);
+}
+ast_expression* fold::intrinsic_epsilon(void) {
+  static bool calculated = false;
+  static float eps = 1.0f;
+  if (!calculated) {
+    do {
+      eps /= 2.0f;
+    } while ((1.0f + (eps / 2.0f)) != 1.0f);
+    calculated = true;
+  }
+  return constgen_float(eps, false);
+}
 
-ast_expression *fold::intrinsic(const char *intrinsic, ast_expression **arg) {
+ast_expression* fold::intrinsic_inf(void) {
+  return constgen_float(1.0f / 0.0f, false);
+}
+
+ast_expression *fold::intrinsic(const char *intrinsic, size_t n_args, ast_expression **args) {
     ast_expression *ret = nullptr;
-    ast_value *a = (ast_value*)arg[0];
-    ast_value *b = (ast_value*)arg[1];
-
-    if (!strcmp(intrinsic, "isfinite")) ret = intrinsic_isfinite(a);
-    if (!strcmp(intrinsic, "isinf"))    ret = intrinsic_isinf(a);
-    if (!strcmp(intrinsic, "isnan"))    ret = intrinsic_isnan(a);
-    if (!strcmp(intrinsic, "isnormal")) ret = intrinsic_isnormal(a);
-    if (!strcmp(intrinsic, "signbit"))  ret = intrinsic_signbit(a);
-    if (!strcmp(intrinsic, "acosh"))    ret = intrinsic_acosh(a);
-    if (!strcmp(intrinsic, "asinh"))    ret = intrinsic_asinh(a);
-    if (!strcmp(intrinsic, "atanh"))    ret = intrinsic_atanh(a);
-    if (!strcmp(intrinsic, "exp"))      ret = intrinsic_exp(a);
-    if (!strcmp(intrinsic, "exp2"))     ret = intrinsic_exp2(a);
-    if (!strcmp(intrinsic, "expm1"))    ret = intrinsic_expm1(a);
-    if (!strcmp(intrinsic, "mod"))      ret = intrinsic_mod(a, b);
-    if (!strcmp(intrinsic, "pow"))      ret = intrinsic_pow(a, b);
-    if (!strcmp(intrinsic, "fabs"))     ret = intrinsic_fabs(a);
 
-    if (ret)
+    if (n_args) {
+      ast_value *a = (ast_value*)args[0];
+      ast_value *b = (ast_value*)args[1];
+      if (!strcmp(intrinsic, "isfinite")) ret = intrinsic_isfinite(a);
+      if (!strcmp(intrinsic, "isinf"))    ret = intrinsic_isinf(a);
+      if (!strcmp(intrinsic, "isnan"))    ret = intrinsic_isnan(a);
+      if (!strcmp(intrinsic, "isnormal")) ret = intrinsic_isnormal(a);
+      if (!strcmp(intrinsic, "signbit"))  ret = intrinsic_signbit(a);
+      if (!strcmp(intrinsic, "acosh"))    ret = intrinsic_acosh(a);
+      if (!strcmp(intrinsic, "asinh"))    ret = intrinsic_asinh(a);
+      if (!strcmp(intrinsic, "atanh"))    ret = intrinsic_atanh(a);
+      if (!strcmp(intrinsic, "exp"))      ret = intrinsic_exp(a);
+      if (!strcmp(intrinsic, "exp2"))     ret = intrinsic_exp2(a);
+      if (!strcmp(intrinsic, "expm1"))    ret = intrinsic_expm1(a);
+      if (!strcmp(intrinsic, "mod"))      ret = intrinsic_mod(a, b);
+      if (!strcmp(intrinsic, "pow"))      ret = intrinsic_pow(a, b);
+      if (!strcmp(intrinsic, "fabs"))     ret = intrinsic_fabs(a);
+    } else {
+      if (!strcmp(intrinsic, "nan"))      ret = intrinsic_nan();
+      if (!strcmp(intrinsic, "epsilon"))  ret = intrinsic_epsilon();
+      if (!strcmp(intrinsic, "inf"))      ret = intrinsic_inf();
+    }
+
+    if (ret) {
         ++opts_optimizationcount[OPTIM_CONST_FOLD];
+    }
 
     return ret;
 }
diff --git a/fold.h b/fold.h
index 1d096e8..693231f 100644 (file)
--- a/fold.h
+++ b/fold.h
@@ -21,7 +21,7 @@ struct fold {
 
     bool generate(ir_builder *ir);
     ast_expression *op(const oper_info *info, ast_expression **opexprs);
-    ast_expression *intrinsic(const char *intrinsic, ast_expression **arg);
+    ast_expression *intrinsic(const char *intrinsic, size_t n_args, ast_expression **args);
 
     static int cond_ternary(ir_value *condval, ast_function *func, ast_ternary *branch);
     static int cond_ifthen(ir_value *condval, ast_function *func, ast_ifthen *branch);
@@ -83,10 +83,14 @@ protected:
     ast_expression *intrinsic_exp(ast_value *a);
     ast_expression *intrinsic_exp2(ast_value *a);
     ast_expression *intrinsic_expm1(ast_value *a);
-    ast_expression *intrinsic_mod(ast_value *lhs, ast_value *rhs);
     ast_expression *intrinsic_pow(ast_value *lhs, ast_value *rhs);
+    ast_expression *intrinsic_mod(ast_value *lhs, ast_value *rhs);
     ast_expression *intrinsic_fabs(ast_value *a);
 
+    ast_expression* intrinsic_nan(void);
+    ast_expression* intrinsic_epsilon(void);
+    ast_expression* intrinsic_inf(void);
+
     static qcfloat_t immvalue_float(ir_value *value);
     static vec3_t immvalue_vector(ir_value *value);
 
index b37b50f..8053b31 100644 (file)
@@ -32,8 +32,6 @@ void intrin::reg(ast_value *const value, ast_function *const func) {
     m_parser->globals.push_back(value);
 }
 
-#define QC_POW_EPSILON 0.00001f
-
 ast_expression *intrin::nullfunc() {
     ast_value *val = nullptr;
     ast_function *func = value(&val, nullptr, TYPE_VOID);
@@ -575,6 +573,8 @@ ast_expression *intrin::expm1_() {
 }
 
 ast_expression *intrin::pow_() {
+               #define QC_POW_EPSILON 0.00001f
+
     /*
      *
      * float pow(float base, float exp) {
@@ -2005,7 +2005,7 @@ ast_expression *intrin::do_fold(ast_value *val, ast_expression **exprs) {
         if (val->m_name == it.name)
             return (vec_size(exprs) != it.args)
                         ? nullptr
-                        : m_fold->intrinsic(val->m_name.c_str() + kPrefixLength, exprs);
+                        : m_fold->intrinsic(val->m_name.c_str() + kPrefixLength, it.args, exprs);
     }
     return nullptr;
 }