]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - intrin.c
Got Xonotic stuff for check-proj to function.
[xonotic/gmqcc.git] / intrin.c
index 50f90bfacdf72f0bfee32c9f3b1211319506feb3..d713df0f4000f0786353ea4d5de3239073986916 100644 (file)
--- a/intrin.c
+++ b/intrin.c
@@ -39,6 +39,7 @@
             "__builtin_" NAME,                                         \
             TYPE_FUNCTION                                              \
         );                                                             \
+        (VALUE)->intrinsic = true;                                     \
         (VALUE)->expression.next = (ast_expression*)ast_value_new (    \
             parser_ctx(intrin->parser),                                \
             STYPE,                                                     \
@@ -49,6 +50,7 @@
             "__builtin_" NAME,                                         \
             (VALUE)                                                    \
         );                                                             \
+        (VALUE)->expression.flags |= AST_FLAG_ERASEABLE;               \
     } while (0)
 
 #define INTRIN_REG(FUNC, VALUE)                                        \
@@ -407,12 +409,12 @@ ast_expression *intrin_debug_typestring(intrin_t *intrin) {
 }
 
 static const intrin_func_t intrinsics[] = {
-    {&intrin_exp,              "__builtin_exp",              "exp"},
-    {&intrin_mod,              "__builtin_mod",              "mod"},
-    {&intrin_pow,              "__builtin_pow",              "pow"},
-    {&intrin_isnan,            "__builtin_isnan",            "isnan"},
-    {&intrin_fabs,             "__builtin_fabs",             "fabs"},
-    {&intrin_debug_typestring, "__builtin_debug_typestring", ""}
+    {&intrin_exp,              "__builtin_exp",              "exp",   1},
+    {&intrin_mod,              "__builtin_mod",              "mod",   2},
+    {&intrin_pow,              "__builtin_pow",              "pow",   2},
+    {&intrin_isnan,            "__builtin_isnan",            "isnan", 1},
+    {&intrin_fabs,             "__builtin_fabs",             "fabs",  1},
+    {&intrin_debug_typestring, "__builtin_debug_typestring", "",      0}
 };
 
 static void intrin_error(intrin_t *intrin, const char *fmt, ...) {
@@ -439,6 +441,24 @@ void intrin_cleanup(intrin_t *intrin) {
     mem_d(intrin);
 }
 
+ast_expression *intrin_fold(intrin_t *intrin, ast_value *value, ast_expression **exprs) {
+    size_t i;
+
+    if (!value || !value->name)
+        return NULL;
+
+    for (i = 0; i < vec_size(intrin->intrinsics); i++) {
+        if (!strcmp(value->name, intrin->intrinsics[i].name)) {
+            if (intrin->intrinsics[i].args != vec_size(exprs))
+                return NULL;
+            /* +10 to skip the "__builtin_" substring in the string */
+            return fold_intrin(intrin->fold, value->name + 10, exprs);
+        }
+    }
+
+    return NULL;
+}
+
 ast_expression *intrin_func(intrin_t *intrin, const char *name) {
     size_t       i    = 0;
     void        *find;