]> de.git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - intrin.c
Arithmetic exception flag and a plethora of tests.
[xonotic/gmqcc.git] / intrin.c
index f3ae818caac0fee0a9441d6a9f6bdf8e81ef7b5c..c1b84ed230c9165619bdcca9f8461b5589125271 100644 (file)
--- a/intrin.c
+++ b/intrin.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
@@ -422,7 +422,7 @@ static ast_expression *intrin_atanh(intrin_t *intrin) {
         (ast_expression*)ast_binary_new(
             intrin_ctx(intrin),
             INSTR_MUL_F,
-            (ast_expression*)fold_constgen_float(intrin->fold, 0.5),
+            (ast_expression*)fold_constgen_float(intrin->fold, 0.5, false),
             (ast_expression*)calllog
         )
     );
@@ -496,7 +496,7 @@ static ast_expression *intrin_exp(intrin_t *intrin) {
                 intrin_ctx(intrin),
                 INSTR_LT,
                 (ast_expression*)i,
-                (ast_expression*)fold_constgen_float(intrin->fold, 200.0f)
+                (ast_expression*)fold_constgen_float(intrin->fold, 200.0f, false)
             ),
             false,
             NULL,
@@ -1027,7 +1027,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) {
                 intrin_ctx(intrin),
                 INSTR_GT,
                 (ast_expression*)callfabs,
-                (ast_expression*)fold_constgen_float(intrin->fold, QC_POW_EPSILON)
+                (ast_expression*)fold_constgen_float(intrin->fold, QC_POW_EPSILON, false)
             ),
             /* pre not */
             false,
@@ -1911,7 +1911,7 @@ static ast_expression *intrin_log_variant(intrin_t *intrin, const char *name, fl
     vec_push(value->expression.params, arg1);
 
     vec_push(callln->params, (ast_expression*)arg1);
-    vec_push(callln->params, (ast_expression*)fold_constgen_float(intrin->fold, base));
+    vec_push(callln->params, (ast_expression*)fold_constgen_float(intrin->fold, base, false));
 
     vec_push(body->exprs,
         (ast_expression*)ast_return_new(
@@ -1940,28 +1940,41 @@ static ast_expression *intrin_logb(intrin_t *intrin) {
 }
 
 static ast_expression *intrin_shift_variant(intrin_t *intrin, const char *name, size_t instr) {
-    ast_value    *value    = NULL;
-    ast_call     *callpow  = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "pow", name));
-    ast_value    *a        = ast_value_new(intrin_ctx(intrin), "a", TYPE_FLOAT);
-    ast_value    *b        = ast_value_new(intrin_ctx(intrin), "b", TYPE_FLOAT);
-    ast_block    *body     = ast_block_new(intrin_ctx(intrin));
-    ast_function *func     = intrin_value(intrin, &value, name, TYPE_FLOAT);
+    /*
+     * float [shift] (float a, float b) {
+     *   return floor(a [instr] pow(2, b));
+     */
+    ast_value    *value     = NULL;
+    ast_call     *callpow   = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "pow", name));
+    ast_call     *callfloor = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "floor", name));
+    ast_value    *a         = ast_value_new(intrin_ctx(intrin), "a", TYPE_FLOAT);
+    ast_value    *b         = ast_value_new(intrin_ctx(intrin), "b", TYPE_FLOAT);
+    ast_block    *body      = ast_block_new(intrin_ctx(intrin));
+    ast_function *func      = intrin_value(intrin, &value, name, TYPE_FLOAT);
 
     vec_push(value->expression.params, a);
     vec_push(value->expression.params, b);
 
+    /* <callpow> = pow(2, b) */
     vec_push(callpow->params, (ast_expression*)intrin->fold->imm_float[3]);
     vec_push(callpow->params, (ast_expression*)b);
 
+    /* <callfloor> = floor(a [instr] <callpow>) */
+    vec_push(
+        callfloor->params,
+        (ast_expression*)ast_binary_new(
+            intrin_ctx(intrin),
+            instr,
+            (ast_expression*)a,
+            (ast_expression*)callpow
+        )
+    );
+
+    /* return <callfloor> */
     vec_push(body->exprs,
         (ast_expression*)ast_return_new(
             intrin_ctx(intrin),
-            (ast_expression*)ast_binary_new(
-                intrin_ctx(intrin),
-                instr,
-                (ast_expression*)a,
-                (ast_expression*)callpow
-            )
+            (ast_expression*)callfloor
         )
     );