X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=intrin.c;h=d713df0f4000f0786353ea4d5de3239073986916;hp=50f90bfacdf72f0bfee32c9f3b1211319506feb3;hb=3968dc84fda0084db9dad2a2f8cf8ebeb9b5a320;hpb=bbe4927a20492e98c1b58d6f10fbe6eddcc72189 diff --git a/intrin.c b/intrin.c index 50f90bf..d713df0 100644 --- 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;