]> de.git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - fold.c
Happy new year!
[xonotic/gmqcc.git] / fold.c
diff --git a/fold.c b/fold.c
index 7c2f66cf19f14e560be457c5ea5111e7388368b8..dd78beb46044f6b02a9d17233f8ada9197b66f74 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013
+ * Copyright (C) 2012, 2013, 2014
  *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
@@ -230,6 +230,7 @@ fold_t *fold_init(parser_t *parser) {
     (void)fold_constgen_float (fold,  0.0f);
     (void)fold_constgen_float (fold,  1.0f);
     (void)fold_constgen_float (fold, -1.0f);
+    (void)fold_constgen_float (fold,  2.0f);
 
     (void)fold_constgen_vector(fold, vec3_create(0.0f, 0.0f, 0.0f));
     (void)fold_constgen_vector(fold, vec3_create(-1.0f, -1.0f, -1.0f));
@@ -537,11 +538,10 @@ static GMQCC_INLINE ast_expression *fold_op_xor(fold_t *fold, ast_value *a, ast_
         if (fold_can_2(a, b))
             return fold_constgen_float(fold, (qcfloat_t)(((qcint_t)fold_immvalue_float(a)) ^ ((qcint_t)fold_immvalue_float(b))));
     } else {
-        if (isvector(b)) {
-            if (fold_can_2(a, b))
+        if (fold_can_2(a, b)) {
+            if (isvector(b))
                 return fold_constgen_vector(fold, vec3_xor(fold_immvalue_vector(a), fold_immvalue_vector(b)));
-        } else {
-            if (fold_can_2(a, b))
+            else
                 return fold_constgen_vector(fold, vec3_xorvf(fold_immvalue_vector(a), fold_immvalue_float(b)));
         }
     }
@@ -606,11 +606,15 @@ static GMQCC_INLINE ast_expression *fold_op_lteqgt(fold_t *fold, ast_value *a, a
 
 static GMQCC_INLINE ast_expression *fold_op_cmp(fold_t *fold, ast_value *a, ast_value *b, bool ne) {
     if (fold_can_2(a, b)) {
-        return fold_constgen_float(
-                    fold,
-                    (ne) ? (fold_immvalue_float(a) != fold_immvalue_float(b))
-                         : (fold_immvalue_float(a) == fold_immvalue_float(b))
-                );
+        if (isfloat(a) && isfloat(b)) {
+            float la = fold_immvalue_float(a);
+            float lb = fold_immvalue_float(b);
+            return (ast_expression*)fold->imm_float[!(ne ? la == lb : la != lb)];
+        } if (isvector(a) && isvector(b)) {
+            vec3_t la = fold_immvalue_vector(a);
+            vec3_t lb = fold_immvalue_vector(b);
+            return (ast_expression*)fold->imm_float[!(ne ? vec3_cmp(la, lb) : !vec3_cmp(la, lb))];
+        }
     }
     return NULL;
 }
@@ -618,7 +622,7 @@ static GMQCC_INLINE ast_expression *fold_op_cmp(fold_t *fold, ast_value *a, ast_
 static GMQCC_INLINE ast_expression *fold_op_bnot(fold_t *fold, ast_value *a) {
     if (isfloat(a)) {
         if (fold_can_1(a))
-            return fold_constgen_float(fold, ~((qcint_t)fold_immvalue_float(a)));
+            return fold_constgen_float(fold, -1-fold_immvalue_float(a));
     } else {
         if (isvector(a)) {
             if (fold_can_1(a))
@@ -703,46 +707,69 @@ ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **op
  * folding, primarly: individual functions for each intrinsics to fold,
  * and a generic selection function.
  */
+static GMQCC_INLINE ast_expression *fold_intrin_isfinite(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, isfinite(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_isinf(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, isinf(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_isnan(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, isnan(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_isnormal(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, isnormal(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_signbit(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, signbit(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intirn_acosh(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, acoshf(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_asinh(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, asinhf(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_atanh(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, atanhf(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_exp(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, expf(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_exp2(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, exp2f(fold_immvalue_float(a)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_expm1(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, expm1f(fold_immvalue_float(a)));
+}
 static GMQCC_INLINE ast_expression *fold_intrin_mod(fold_t *fold, ast_value *lhs, ast_value *rhs) {
-    return fold_constgen_float(
-                fold,
-                fmodf(
-                    fold_immvalue_float(lhs),
-                    fold_immvalue_float(rhs)
-                )
-            );
+    return fold_constgen_float(fold, fmodf(fold_immvalue_float(lhs), fold_immvalue_float(rhs)));
 }
-
 static GMQCC_INLINE ast_expression *fold_intrin_pow(fold_t *fold, ast_value *lhs, ast_value *rhs) {
-    return fold_constgen_float(
-                fold,
-                powf(
-                    fold_immvalue_float(lhs),
-                    fold_immvalue_float(rhs)
-                )
-            );
+    return fold_constgen_float(fold, powf(fold_immvalue_float(lhs), fold_immvalue_float(rhs)));
 }
-
-static GMQCC_INLINE ast_expression *fold_intrin_exp(fold_t *fold, ast_value *value) {
-    return fold_constgen_float(fold, exp(fold_immvalue_float(value)));
+static GMQCC_INLINE ast_expression *fold_intrin_fabs(fold_t *fold, ast_value *a) {
+    return fold_constgen_float(fold, fabsf(fold_immvalue_float(a)));
 }
 
-static GMQCC_INLINE ast_expression *fold_intrin_isnan(fold_t *fold, ast_value *value) {
-    return fold_constgen_float(fold, isnan(fold_immvalue_float(value)) != 0.0f);
-}
-
-static GMQCC_INLINE ast_expression *fold_intrin_fabs(fold_t *fold, ast_value *value) {
-    return fold_constgen_float(fold, fabs(fold_immvalue_float(value)));
-}
 
 ast_expression *fold_intrin(fold_t *fold, const char *intrin, ast_expression **arg) {
     ast_expression *ret = NULL;
-
-    if (!strcmp(intrin, "mod"))   ret = fold_intrin_mod  (fold, (ast_value*)arg[0], (ast_value*)arg[1]);
-    if (!strcmp(intrin, "pow"))   ret = fold_intrin_pow  (fold, (ast_value*)arg[0], (ast_value*)arg[1]);
-    if (!strcmp(intrin, "exp"))   ret = fold_intrin_exp  (fold, (ast_value*)arg[0]);
-    if (!strcmp(intrin, "isnan")) ret = fold_intrin_isnan(fold, (ast_value*)arg[0]);
-    if (!strcmp(intrin, "fabs"))  ret = fold_intrin_fabs (fold, (ast_value*)arg[0]);
+    ast_value      *a   = (ast_value*)arg[0];
+    ast_value      *b   = (ast_value*)arg[1];
+
+    if (!strcmp(intrin, "isfinite")) ret = fold_intrin_isfinite(fold, a);
+    if (!strcmp(intrin, "isinf"))    ret = fold_intrin_isinf(fold, a);
+    if (!strcmp(intrin, "isnan"))    ret = fold_intrin_isnan(fold, a);
+    if (!strcmp(intrin, "isnormal")) ret = fold_intrin_isnormal(fold, a);
+    if (!strcmp(intrin, "signbit"))  ret = fold_intrin_signbit(fold, a);
+    if (!strcmp(intrin, "acosh"))    ret = fold_intirn_acosh(fold, a);
+    if (!strcmp(intrin, "asinh"))    ret = fold_intrin_asinh(fold, a);
+    if (!strcmp(intrin, "atanh"))    ret = fold_intrin_atanh(fold, a);
+    if (!strcmp(intrin, "exp"))      ret = fold_intrin_exp(fold, a);
+    if (!strcmp(intrin, "exp2"))     ret = fold_intrin_exp2(fold, a);
+    if (!strcmp(intrin, "expm1"))    ret = fold_intrin_expm1(fold, a);
+    if (!strcmp(intrin, "mod"))      ret = fold_intrin_mod(fold, a, b);
+    if (!strcmp(intrin, "pow"))      ret = fold_intrin_pow(fold, a, b);
+    if (!strcmp(intrin, "fabs"))     ret = fold_intrin_fabs(fold, a);
 
     if (ret)
         ++opts_optimizationcount[OPTIM_CONST_FOLD];