-#define expect(X) \
- do { \
- if (vec_size(params) != (X)) { \
- compile_error( \
- fold_ctx(fold), \
- "internal error: attempted to constant-fold with invalid paramaters for intrinsic `%s`", \
- intrin \
- ); \
- return NULL; \
- } \
- } while (0)
-
-ast_expression *fold_intrin(fold_t *fold, const char *intrin, ast_expression **params) {
- if (!fold) return NULL;
- if (!intrin) return NULL;
-
- if (!strcmp(intrin, "__builtin_exp")) {
- expect(1);
- ++opts_optimizationcount[OPTIM_CONST_FOLD];
- return fold_constgen_float(fold, exp(fold_immvalue_float((ast_value*)params[0])));
- }
+/*
+ * Constant folding for compiler intrinsics, simaler approach to operator
+ * 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)));
+}
+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)));
+}
+static GMQCC_INLINE ast_expression *fold_intrin_fabs(fold_t *fold, ast_value *a) {
+ return fold_constgen_float(fold, fabsf(fold_immvalue_float(a)));
+}