X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=fold.cpp;h=a982bf601b9cb7e60e2372bc17de94b7f3cb52f8;hp=6d56d8af1d59e0cc95adb389d5337e6a12ee3ced;hb=refs%2Fheads%2Fgraphitemaster%2Fmaster;hpb=a9ac6987a6a0526f55c6866a504609699d19de5d diff --git a/fold.cpp b/fold.cpp index 6d56d8a..a982bf6 100644 --- a/fold.cpp +++ b/fold.cpp @@ -508,7 +508,7 @@ static GMQCC_INLINE void sfloat_check(lex_ctx_t ctx, sfloat_state_t *state, cons compile_error(ctx, "arithmetic overflow in `%s' component", vec); if (state->exceptionflags & SFLOAT_UNDERFLOW) compile_error(ctx, "arithmetic underflow in `%s' component", vec); - return; + return; } if (state->exceptionflags & SFLOAT_DIVBYZERO) compile_error(ctx, "division by zero"); @@ -1392,8 +1392,8 @@ ast_expression *fold::op(const oper_info *info, ast_expression **opexprs) { return nullptr; switch(info->operands) { - case 3: if(!c) return nullptr; - case 2: if(!b) return nullptr; + case 3: if(!c) return nullptr; [[fallthrough]]; + case 2: if(!b) return nullptr; [[fallthrough]]; case 1: if(!a) { compile_error(ctx(), "internal error: fold_op no operands to fold\n"); @@ -1486,29 +1486,54 @@ ast_expression *fold::intrinsic_pow(ast_value *lhs, ast_value *rhs) { ast_expression *fold::intrinsic_fabs(ast_value *a) { return constgen_float(fabsf(immvalue_float(a)), false); } +ast_expression* fold::intrinsic_nan(void) { + return constgen_float(0.0f / 0.0f, false); +} +ast_expression* fold::intrinsic_epsilon(void) { + static bool calculated = false; + static float eps = 1.0f; + if (!calculated) { + do { + eps /= 2.0f; + } while ((1.0f + (eps / 2.0f)) != 1.0f); + calculated = true; + } + return constgen_float(eps, false); +} + +ast_expression* fold::intrinsic_inf(void) { + return constgen_float(1.0f / 0.0f, false); +} -ast_expression *fold::intrinsic(const char *intrinsic, ast_expression **arg) { +ast_expression *fold::intrinsic(const char *intrinsic, size_t n_args, ast_expression **args) { ast_expression *ret = nullptr; - ast_value *a = (ast_value*)arg[0]; - ast_value *b = (ast_value*)arg[1]; - - if (!strcmp(intrinsic, "isfinite")) ret = intrinsic_isfinite(a); - if (!strcmp(intrinsic, "isinf")) ret = intrinsic_isinf(a); - if (!strcmp(intrinsic, "isnan")) ret = intrinsic_isnan(a); - if (!strcmp(intrinsic, "isnormal")) ret = intrinsic_isnormal(a); - if (!strcmp(intrinsic, "signbit")) ret = intrinsic_signbit(a); - if (!strcmp(intrinsic, "acosh")) ret = intrinsic_acosh(a); - if (!strcmp(intrinsic, "asinh")) ret = intrinsic_asinh(a); - if (!strcmp(intrinsic, "atanh")) ret = intrinsic_atanh(a); - if (!strcmp(intrinsic, "exp")) ret = intrinsic_exp(a); - if (!strcmp(intrinsic, "exp2")) ret = intrinsic_exp2(a); - if (!strcmp(intrinsic, "expm1")) ret = intrinsic_expm1(a); - if (!strcmp(intrinsic, "mod")) ret = intrinsic_mod(a, b); - if (!strcmp(intrinsic, "pow")) ret = intrinsic_pow(a, b); - if (!strcmp(intrinsic, "fabs")) ret = intrinsic_fabs(a); - if (ret) + if (n_args) { + ast_value *a = (ast_value*)args[0]; + ast_value *b = (ast_value*)args[1]; + if (!strcmp(intrinsic, "isfinite")) ret = intrinsic_isfinite(a); + if (!strcmp(intrinsic, "isinf")) ret = intrinsic_isinf(a); + if (!strcmp(intrinsic, "isnan")) ret = intrinsic_isnan(a); + if (!strcmp(intrinsic, "isnormal")) ret = intrinsic_isnormal(a); + if (!strcmp(intrinsic, "signbit")) ret = intrinsic_signbit(a); + if (!strcmp(intrinsic, "acosh")) ret = intrinsic_acosh(a); + if (!strcmp(intrinsic, "asinh")) ret = intrinsic_asinh(a); + if (!strcmp(intrinsic, "atanh")) ret = intrinsic_atanh(a); + if (!strcmp(intrinsic, "exp")) ret = intrinsic_exp(a); + if (!strcmp(intrinsic, "exp2")) ret = intrinsic_exp2(a); + if (!strcmp(intrinsic, "expm1")) ret = intrinsic_expm1(a); + if (!strcmp(intrinsic, "mod")) ret = intrinsic_mod(a, b); + if (!strcmp(intrinsic, "pow")) ret = intrinsic_pow(a, b); + if (!strcmp(intrinsic, "fabs")) ret = intrinsic_fabs(a); + } else { + if (!strcmp(intrinsic, "nan")) ret = intrinsic_nan(); + if (!strcmp(intrinsic, "epsilon")) ret = intrinsic_epsilon(); + if (!strcmp(intrinsic, "inf")) ret = intrinsic_inf(); + } + + if (ret) { ++opts_optimizationcount[OPTIM_CONST_FOLD]; + } return ret; } @@ -1560,6 +1585,7 @@ ast_expression *fold::superfluous(ast_expression *left, ast_expression *right, i case INSTR_DIV_F: if (swapped) return nullptr; + [[fallthrough]]; case INSTR_MUL_F: if (immvalue_float(load) == 1.0f) { ++opts_optimizationcount[OPTIM_PEEPHOLE]; @@ -1572,6 +1598,7 @@ ast_expression *fold::superfluous(ast_expression *left, ast_expression *right, i case INSTR_SUB_F: if (swapped) return nullptr; + [[fallthrough]]; case INSTR_ADD_F: if (immvalue_float(load) == 0.0f) { ++opts_optimizationcount[OPTIM_PEEPHOLE]; @@ -1591,6 +1618,7 @@ ast_expression *fold::superfluous(ast_expression *left, ast_expression *right, i case INSTR_SUB_V: if (swapped) return nullptr; + [[fallthrough]]; case INSTR_ADD_V: if (vec3_cmp(immvalue_vector(load), vec3_create(0, 0, 0))) { ++opts_optimizationcount[OPTIM_PEEPHOLE];