]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
Implemented exp2 intrinsic
authorDale Weiler <killfieldengine@gmail.com>
Sat, 23 Nov 2013 12:37:26 +0000 (07:37 -0500)
committerDale Weiler <killfieldengine@gmail.com>
Sat, 23 Nov 2013 12:37:26 +0000 (07:37 -0500)
fold.c
intrin.c

diff --git a/fold.c b/fold.c
index c75106ad74c472b8265e4f532a9e48257566e28b..823184f0024129337e684328dc20e34090f2b265 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -725,6 +725,10 @@ static GMQCC_INLINE ast_expression *fold_intrin_exp(fold_t *fold, ast_value *val
     return fold_constgen_float(fold, exp(fold_immvalue_float(value)));
 }
 
+static GMQCC_INLINE ast_expression *fold_intrin_exp2(fold_t *fold, ast_value *value) {
+    return fold_constgen_float(fold, pow(2, fold_immvalue_float(value)));
+}
+
 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);
 }
@@ -739,6 +743,7 @@ ast_expression *fold_intrin(fold_t *fold, const char *intrin, ast_expression **a
     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, "exp2"))  ret = fold_intrin_exp2 (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]);
 
index acd38462e8563e496e6de84f15fd8c0a1caf6f95..0ab278986bbbb7483e361eade69f98d6cbe05cff 100644 (file)
--- a/intrin.c
+++ b/intrin.c
@@ -647,6 +647,37 @@ static ast_expression *intrin_exp(intrin_t *intrin) {
     return (ast_expression*)value;
 }
 
+static ast_expression *intrin_exp2(intrin_t *intrin) {
+    /*
+     * float exp2(float x) {
+     *     return pow(2, x);
+     * }
+     */
+    ast_value    *value     = NULL;
+    ast_call     *callpow   = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "pow", "exp2"));
+    ast_value    *arg1      = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT);
+    ast_block    *body      = ast_block_new(intrin_ctx(intrin));
+    ast_function *func      = intrin_value(intrin, &value, "exp2", TYPE_FLOAT);
+
+    vec_push(value->expression.params, arg1);
+
+    vec_push(callpow->params, (ast_expression*)fold_constgen_float(intrin->fold, 2.0f));
+    vec_push(callpow->params, (ast_expression*)arg1);
+
+    /* return <callpow> */
+    vec_push(body->exprs,
+        (ast_expression*)ast_return_new(
+            intrin_ctx(intrin),
+            (ast_expression*)callpow
+        )
+    );
+
+    vec_push(func->blocks, body);
+
+    intrin_reg(intrin, value, func);
+    return (ast_expression*)value;
+}
+
 static ast_expression *intrin_isnan(intrin_t *intrin) {
     /*
      * float isnan(float x) {
@@ -743,6 +774,7 @@ ast_expression *intrin_debug_typestring(intrin_t *intrin) {
 
 static const intrin_func_t intrinsics[] = {
     {&intrin_exp,              "__builtin_exp",              "exp",      1},
+    {&intrin_exp2,             "__builtin_exp2",             "exp2",     1},
     {&intrin_mod,              "__builtin_mod",              "mod",      2},
     {&intrin_pow,              "__builtin_pow",              "pow",      2},
     {&intrin_isnan,            "__builtin_isnan",            "isnan",    1},