mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-23 12:22:26 +00:00
fix __builtin_nan and add some missing builtins
This commit is contained in:
parent
2d99ce609d
commit
620bd76e76
3 changed files with 52 additions and 23 deletions
61
fold.cpp
61
fold.cpp
|
@ -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(const char *intrinsic, ast_expression **arg) {
|
||||
ast_expression* fold::intrinsic_inf(void) {
|
||||
return constgen_float(1.0f / 0.0f, false);
|
||||
}
|
||||
|
||||
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 (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)
|
||||
if (ret) {
|
||||
++opts_optimizationcount[OPTIM_CONST_FOLD];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
8
fold.h
8
fold.h
|
@ -21,7 +21,7 @@ struct fold {
|
|||
|
||||
bool generate(ir_builder *ir);
|
||||
ast_expression *op(const oper_info *info, ast_expression **opexprs);
|
||||
ast_expression *intrinsic(const char *intrinsic, ast_expression **arg);
|
||||
ast_expression *intrinsic(const char *intrinsic, size_t n_args, ast_expression **args);
|
||||
|
||||
static int cond_ternary(ir_value *condval, ast_function *func, ast_ternary *branch);
|
||||
static int cond_ifthen(ir_value *condval, ast_function *func, ast_ifthen *branch);
|
||||
|
@ -83,10 +83,14 @@ protected:
|
|||
ast_expression *intrinsic_exp(ast_value *a);
|
||||
ast_expression *intrinsic_exp2(ast_value *a);
|
||||
ast_expression *intrinsic_expm1(ast_value *a);
|
||||
ast_expression *intrinsic_mod(ast_value *lhs, ast_value *rhs);
|
||||
ast_expression *intrinsic_pow(ast_value *lhs, ast_value *rhs);
|
||||
ast_expression *intrinsic_mod(ast_value *lhs, ast_value *rhs);
|
||||
ast_expression *intrinsic_fabs(ast_value *a);
|
||||
|
||||
ast_expression* intrinsic_nan(void);
|
||||
ast_expression* intrinsic_epsilon(void);
|
||||
ast_expression* intrinsic_inf(void);
|
||||
|
||||
static qcfloat_t immvalue_float(ir_value *value);
|
||||
static vec3_t immvalue_vector(ir_value *value);
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@ void intrin::reg(ast_value *const value, ast_function *const func) {
|
|||
m_parser->globals.push_back(value);
|
||||
}
|
||||
|
||||
#define QC_POW_EPSILON 0.00001f
|
||||
|
||||
ast_expression *intrin::nullfunc() {
|
||||
ast_value *val = nullptr;
|
||||
ast_function *func = value(&val, nullptr, TYPE_VOID);
|
||||
|
@ -575,6 +573,8 @@ ast_expression *intrin::expm1_() {
|
|||
}
|
||||
|
||||
ast_expression *intrin::pow_() {
|
||||
#define QC_POW_EPSILON 0.00001f
|
||||
|
||||
/*
|
||||
*
|
||||
* float pow(float base, float exp) {
|
||||
|
@ -2005,7 +2005,7 @@ ast_expression *intrin::do_fold(ast_value *val, ast_expression **exprs) {
|
|||
if (val->m_name == it.name)
|
||||
return (vec_size(exprs) != it.args)
|
||||
? nullptr
|
||||
: m_fold->intrinsic(val->m_name.c_str() + kPrefixLength, exprs);
|
||||
: m_fold->intrinsic(val->m_name.c_str() + kPrefixLength, it.args, exprs);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue