From e2ba77a5461096cb4f4a337ef3d8c2ef46552f97 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Thu, 15 Jan 2015 18:11:41 -0500 Subject: [PATCH] Rewrite intrinsic system in C++ --- intrin.cpp | 1064 ++++++++++++++++++++++++++-------------------------- parser.cpp | 21 +- parser.h | 27 +- 3 files changed, 536 insertions(+), 576 deletions(-) diff --git a/intrin.cpp b/intrin.cpp index 14cbf73..2916367 100644 --- a/intrin.cpp +++ b/intrin.cpp @@ -1,66 +1,58 @@ #include #include "parser.h" -#define intrin_ctx(I) parser_ctx((I)->parser) +lex_ctx_t intrin::ctx() const { + return parser_ctx(m_parser); +} -static GMQCC_INLINE ast_function *intrin_value(intrin_t *intrin, ast_value **out, const char *name, qcint_t vtype) { - ast_value *value = nullptr; +ast_function *intrin::value(ast_value **out, const char *name, qcint_t vtype) { + ast_value *value = nullptr; ast_function *func = nullptr; - char buffer[1024]; - char stype [1024]; + char buffer[1024]; + char stype [1024]; util_snprintf(buffer, sizeof(buffer), "__builtin_%s", name); util_snprintf(stype, sizeof(stype), "<%s>", type_name[vtype]); - value = ast_value_new(intrin_ctx(intrin), buffer, TYPE_FUNCTION); - value->intrinsic = true; - value->expression.next = (ast_expression*)ast_value_new(intrin_ctx(intrin), stype, vtype); - func = ast_function_new(intrin_ctx(intrin), buffer, value); + value = ast_value_new(ctx(), buffer, TYPE_FUNCTION); + value->intrinsic = true; + value->expression.next = (ast_expression*)ast_value_new(ctx(), stype, vtype); + func = ast_function_new(ctx(), buffer, value); value->expression.flags |= AST_FLAG_ERASEABLE; *out = value; return func; } -static GMQCC_INLINE void intrin_reg(intrin_t *intrin, ast_value *const value, ast_function *const func) { - intrin->parser->functions.push_back(func); - intrin->parser->globals.push_back((ast_expression*)value); +void intrin::reg(ast_value *const value, ast_function *const func) { + m_parser->functions.push_back(func); + m_parser->globals.push_back((ast_expression*)value); } #define QC_POW_EPSILON 0.00001f -/* - * since some intrinsics depend on each other there is the possibility - * that an intrinsic will fail to get a 'depended' function that a - * builtin needs, causing some dependency in the chain to have a nullptr - * function. This will cause a segmentation fault at code generation, - * even though an error was raised. To contiue to allow it (instead - * of stopping compilation right away). We need to return from the - * parser, before compilation stops after all the collected errors. - */ -static ast_expression *intrin_func_self(intrin_t *intrin, const char *name, const char *from); -static ast_expression *intrin_nullfunc(intrin_t *intrin) { - ast_value *value = nullptr; - ast_function *func = intrin_value(intrin, &value, nullptr, TYPE_VOID); - intrin_reg(intrin, value, func); - return (ast_expression*)value; +ast_expression *intrin::nullfunc() { + ast_value *val = nullptr; + ast_function *func = value(&val, nullptr, TYPE_VOID); + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_isfinite(intrin_t *intrin) { +ast_expression *intrin::isfinite_() { /* * float isfinite(float x) { * return !(isnan(x) || isinf(x)); * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_function *func = intrin_value(intrin, &value, "isfinite", TYPE_FLOAT); - ast_call *callisnan = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "isnan", "isfinite")); - ast_call *callisinf = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "isinf", "isfinite")); - ast_block *block = ast_block_new(intrin_ctx(intrin)); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_function *func = value(&val, "isfinite", TYPE_FLOAT); + ast_call *callisnan = ast_call_new(ctx(), func_self("isnan", "isfinite")); + ast_call *callisinf = ast_call_new(ctx(), func_self("isinf", "isfinite")); + ast_block *block = ast_block_new(ctx()); /* float x; */ - value->expression.params.push_back(x); + val->expression.params.push_back(x); /* = isnan(x); */ callisnan->params.push_back((ast_expression*)x); @@ -71,12 +63,12 @@ static ast_expression *intrin_isfinite(intrin_t *intrin) { /* return (! || ); */ block->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_unary_new( - intrin_ctx(intrin), + ctx(), INSTR_NOT_F, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_OR, (ast_expression*)callisnan, (ast_expression*)callisinf @@ -86,39 +78,39 @@ static ast_expression *intrin_isfinite(intrin_t *intrin) { ); func->blocks.push_back(block); - intrin_reg(intrin, value, func); + reg(val, func); - return (ast_expression*)value;; + return (ast_expression*)val;; } -static ast_expression *intrin_isinf(intrin_t *intrin) { +ast_expression *intrin::isinf_() { /* * float isinf(float x) { * return (x != 0.0) && (x + x == x); * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "isinf", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "isinf", TYPE_FLOAT); body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_AND, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_NE_F, (ast_expression*)x, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_EQ_F, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, (ast_expression*)x, (ast_expression*)x @@ -129,15 +121,15 @@ static ast_expression *intrin_isinf(intrin_t *intrin) { ) ); - value->expression.params.push_back(x); + val->expression.params.push_back(x); func->blocks.push_back(body); - intrin_reg(intrin, value, func); + reg(val, func); - return (ast_expression*)value; + return (ast_expression*)val; } -static ast_expression *intrin_isnan(intrin_t *intrin) { +ast_expression *intrin::isnan_() { /* * float isnan(float x) { * float local; @@ -146,16 +138,16 @@ static ast_expression *intrin_isnan(intrin_t *intrin) { * return (x != local); * } */ - ast_value *value = nullptr; - ast_value *arg1 = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_value *local = ast_value_new(intrin_ctx(intrin), "local", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "isnan", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *arg1 = ast_value_new(ctx(), "x",TYPE_FLOAT); + ast_value *local = ast_value_new(ctx(), "local", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "isnan", TYPE_FLOAT); body->locals.push_back(local); body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)local, (ast_expression*)arg1 @@ -164,9 +156,9 @@ static ast_expression *intrin_isnan(intrin_t *intrin) { body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_NE_F, (ast_expression*)arg1, (ast_expression*)local @@ -174,112 +166,112 @@ static ast_expression *intrin_isnan(intrin_t *intrin) { ) ); - value->expression.params.push_back(arg1); + val->expression.params.push_back(arg1); func->blocks.push_back(body); - intrin_reg(intrin, value, func); + reg(val, func); - return (ast_expression*)value; + return (ast_expression*)val; } -static ast_expression *intrin_isnormal(intrin_t *intrin) { +ast_expression *intrin::isnormal_() { /* * float isnormal(float x) { * return isfinite(x); * } */ - ast_value *value = nullptr; - ast_call *callisfinite = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "isfinite", "isnormal")); - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "isnormal", TYPE_FLOAT); + ast_value *val = nullptr; + ast_call *callisfinite = ast_call_new(ctx(), func_self("isfinite", "isnormal")); + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "isnormal", TYPE_FLOAT); - value->expression.params.push_back(x); + val->expression.params.push_back(x); callisfinite->params.push_back((ast_expression*)x); /* return */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)callisfinite ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_signbit(intrin_t *intrin) { +ast_expression *intrin::signbit_() { /* * float signbit(float x) { * return (x < 0); * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "signbit", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "signbit", TYPE_FLOAT); - value->expression.params.push_back(x); + val->expression.params.push_back(x); /* return (x < 0); */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_ternary_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LT, (ast_expression*)x, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ), - (ast_expression*)intrin->fold->imm_float[1], - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[1], + (ast_expression*)m_fold->imm_float[0] ) ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_acosh(intrin_t *intrin) { +ast_expression *intrin::acosh_() { /* * float acosh(float x) { * return log(x + sqrt((x * x) - 1)); * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_call *calllog = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "log", "acosh")); - ast_call *callsqrt = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "sqrt", "acosh")); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "acosh", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_call *calllog = ast_call_new(ctx(), func_self("log", "acosh")); + ast_call *callsqrt = ast_call_new(ctx(), func_self("sqrt", "acosh")); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "acosh", TYPE_FLOAT); - value->expression.params.push_back(x); + val->expression.params.push_back(x); /* = sqrt((x * x) - 1); */ callsqrt->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_SUB_F, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)x, (ast_expression*)x ), - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ) ); /* = log(x + ); */ calllog->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, (ast_expression*)x, (ast_expression*)callsqrt @@ -289,50 +281,50 @@ static ast_expression *intrin_acosh(intrin_t *intrin) { /* return ; */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)calllog ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_asinh(intrin_t *intrin) { +ast_expression *intrin::asinh_() { /* * float asinh(float x) { * return log(x + sqrt((x * x) + 1)); * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_call *calllog = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "log", "asinh")); - ast_call *callsqrt = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "sqrt", "asinh")); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "asinh", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_call *calllog = ast_call_new(ctx(), func_self("log", "asinh")); + ast_call *callsqrt = ast_call_new(ctx(), func_self("sqrt", "asinh")); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "asinh", TYPE_FLOAT); - value->expression.params.push_back(x); + val->expression.params.push_back(x); /* = sqrt((x * x) + 1); */ callsqrt->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)x, (ast_expression*)x ), - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ) ); /* = log(x + ); */ calllog->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, (ast_expression*)x, (ast_expression*)callsqrt @@ -342,45 +334,45 @@ static ast_expression *intrin_asinh(intrin_t *intrin) { /* return ; */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)calllog ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_atanh(intrin_t *intrin) { +ast_expression *intrin::atanh_() { /* * float atanh(float x) { * return 0.5 * log((1 + x) / (1 - x)) * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_call *calllog = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "log", "atanh")); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "atanh", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_call *calllog = ast_call_new(ctx(), func_self("log", "atanh")); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "atanh", TYPE_FLOAT); - value->expression.params.push_back(x); + val->expression.params.push_back(x); /* = log((1 + x) / (1 - x)); */ calllog->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, - (ast_expression*)intrin->fold->imm_float[1], + (ast_expression*)m_fold->imm_float[1], (ast_expression*)x ), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_SUB_F, - (ast_expression*)intrin->fold->imm_float[1], + (ast_expression*)m_fold->imm_float[1], (ast_expression*)x ) ) @@ -389,19 +381,19 @@ static ast_expression *intrin_atanh(intrin_t *intrin) { /* return 0.5 * ; */ body->exprs.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, - (ast_expression*)fold_constgen_float(intrin->fold, 0.5, false), + (ast_expression*)fold_constgen_float(m_fold, 0.5, false), (ast_expression*)calllog ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_exp(intrin_t *intrin) { +ast_expression *intrin::exp_() { /* * float exp(float x) { * float sum = 1.0; @@ -413,15 +405,15 @@ static ast_expression *intrin_exp(intrin_t *intrin) { * return sum; * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_value *sum = ast_value_new(intrin_ctx(intrin), "sum", TYPE_FLOAT); - ast_value *acc = ast_value_new(intrin_ctx(intrin), "acc", TYPE_FLOAT); - ast_value *i = ast_value_new(intrin_ctx(intrin), "i", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "exp", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_value *sum = ast_value_new(ctx(), "sum", TYPE_FLOAT); + ast_value *acc = ast_value_new(ctx(), "acc", TYPE_FLOAT); + ast_value *i = ast_value_new(ctx(), "i", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "exp", TYPE_FLOAT); - value->expression.params.push_back(x); + val->expression.params.push_back(x); body->locals.push_back(sum); body->locals.push_back(acc); @@ -430,20 +422,20 @@ static ast_expression *intrin_exp(intrin_t *intrin) { /* sum = 1.0; */ body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)sum, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ) ); /* acc = 1.0; */ body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)acc, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ) ); @@ -453,45 +445,45 @@ static ast_expression *intrin_exp(intrin_t *intrin) { */ body->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), + ctx(), /* i = 1; */ (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)i, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ), /* i < 200; */ (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LT, (ast_expression*)i, - (ast_expression*)fold_constgen_float(intrin->fold, 200.0f, false) + (ast_expression*)fold_constgen_float(m_fold, 200.0f, false) ), false, nullptr, false, /* ++i; */ (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_ADD_F, (ast_expression*)i, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ), /* sum += (acc *= (x / i)) */ (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_ADD_F, (ast_expression*)sum, (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_MUL_F, (ast_expression*)acc, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)x, (ast_expression*)i @@ -504,59 +496,59 @@ static ast_expression *intrin_exp(intrin_t *intrin) { /* return sum; */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)sum ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_exp2(intrin_t *intrin) { +ast_expression *intrin::exp2_() { /* * float exp2(float x) { * return pow(2, x); * } */ - ast_value *value = nullptr; - ast_call *callpow = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "pow", "exp2")); - ast_value *arg1 = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "exp2", TYPE_FLOAT); + ast_value *val = nullptr; + ast_call *callpow = ast_call_new(ctx(), func_self("pow", "exp2")); + ast_value *arg1 = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "exp2", TYPE_FLOAT); - value->expression.params.push_back(arg1); + val->expression.params.push_back(arg1); - callpow->params.push_back((ast_expression*)intrin->fold->imm_float[3]); + callpow->params.push_back((ast_expression*)m_fold->imm_float[3]); callpow->params.push_back((ast_expression*)arg1); /* return */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)callpow ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_expm1(intrin_t *intrin) { +ast_expression *intrin::expm1_() { /* * float expm1(float x) { * return exp(x) - 1; * } */ - ast_value *value = nullptr; - ast_call *callexp = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "exp", "expm1")); - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "expm1", TYPE_FLOAT); + ast_value *val = nullptr; + ast_call *callexp = ast_call_new(ctx(), func_self("exp", "expm1")); + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "expm1", TYPE_FLOAT); - value->expression.params.push_back(x); + val->expression.params.push_back(x); /* = exp(x); */ callexp->params.push_back((ast_expression*)x); @@ -564,22 +556,22 @@ static ast_expression *intrin_expm1(intrin_t *intrin) { /* return - 1; */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_SUB_F, (ast_expression*)callexp, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ) ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_pow(intrin_t *intrin) { +ast_expression *intrin::pow_() { /* * * float pow(float base, float exp) { @@ -621,27 +613,27 @@ static ast_expression *intrin_pow(intrin_t *intrin) { * return accumulate; * } */ - ast_value *value = nullptr; - ast_function *func = intrin_value(intrin, &value, "pow", TYPE_FLOAT); + ast_value *val = nullptr; + ast_function *func = value(&val, "pow", TYPE_FLOAT); /* prepare some calls for later */ - ast_call *callpow1 = ast_call_new(intrin_ctx(intrin), (ast_expression*)value); /* for pow(base, -exp) */ - ast_call *callpow2 = ast_call_new(intrin_ctx(intrin), (ast_expression*)value); /* for pow(vase, exp / 2) */ - ast_call *callsqrt1 = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "sqrt", "pow")); /* for sqrt(base) */ - ast_call *callsqrt2 = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "sqrt", "pow")); /* for sqrt(square) */ - ast_call *callfabs = ast_call_new(intrin_ctx(intrin), intrin_func_self(intrin, "fabs", "pow")); /* for fabs(mid - exp) */ + ast_call *callpow1 = ast_call_new(ctx(), (ast_expression*)val); /* for pow(base, -exp) */ + ast_call *callpow2 = ast_call_new(ctx(), (ast_expression*)val); /* for pow(vase, exp / 2) */ + ast_call *callsqrt1 = ast_call_new(ctx(), func_self("sqrt", "pow")); /* for sqrt(base) */ + ast_call *callsqrt2 = ast_call_new(ctx(), func_self("sqrt", "pow")); /* for sqrt(square) */ + ast_call *callfabs = ast_call_new(ctx(), func_self("fabs", "pow")); /* for fabs(mid - exp) */ /* prepare some blocks for later */ - ast_block *expgt1 = ast_block_new(intrin_ctx(intrin)); - ast_block *midltexp = ast_block_new(intrin_ctx(intrin)); - ast_block *midltexpelse = ast_block_new(intrin_ctx(intrin)); - ast_block *whileblock = ast_block_new(intrin_ctx(intrin)); + ast_block *expgt1 = ast_block_new(ctx()); + ast_block *midltexp = ast_block_new(ctx()); + ast_block *midltexpelse = ast_block_new(ctx()); + ast_block *whileblock = ast_block_new(ctx()); /* float pow(float base, float exp) */ - ast_value *base = ast_value_new(intrin_ctx(intrin), "base", TYPE_FLOAT); - ast_value *exp = ast_value_new(intrin_ctx(intrin), "exp", TYPE_FLOAT); + ast_value *base = ast_value_new(ctx(), "base", TYPE_FLOAT); + ast_value *exp = ast_value_new(ctx(), "exp", TYPE_FLOAT); /* { */ - ast_block *body = ast_block_new(intrin_ctx(intrin)); + ast_block *body = ast_block_new(ctx()); /* * float result; @@ -651,12 +643,12 @@ static ast_expression *intrin_pow(intrin_t *intrin) { * float accumulate; * float mid; */ - ast_value *result = ast_value_new(intrin_ctx(intrin), "result", TYPE_FLOAT); - ast_value *low = ast_value_new(intrin_ctx(intrin), "low", TYPE_FLOAT); - ast_value *high = ast_value_new(intrin_ctx(intrin), "high", TYPE_FLOAT); - ast_value *square = ast_value_new(intrin_ctx(intrin), "square", TYPE_FLOAT); - ast_value *accumulate = ast_value_new(intrin_ctx(intrin), "accumulate", TYPE_FLOAT); - ast_value *mid = ast_value_new(intrin_ctx(intrin), "mid", TYPE_FLOAT); + ast_value *result = ast_value_new(ctx(), "result", TYPE_FLOAT); + ast_value *low = ast_value_new(ctx(), "low", TYPE_FLOAT); + ast_value *high = ast_value_new(ctx(), "high", TYPE_FLOAT); + ast_value *square = ast_value_new(ctx(), "square", TYPE_FLOAT); + ast_value *accumulate = ast_value_new(ctx(), "accumulate", TYPE_FLOAT); + ast_value *mid = ast_value_new(ctx(), "mid", TYPE_FLOAT); body->locals.push_back(result); body->locals.push_back(low); body->locals.push_back(high); @@ -664,8 +656,8 @@ static ast_expression *intrin_pow(intrin_t *intrin) { body->locals.push_back(accumulate); body->locals.push_back(mid); - value->expression.params.push_back(base); - value->expression.params.push_back(exp); + val->expression.params.push_back(base); + val->expression.params.push_back(exp); /* * if (exp == 0.0) @@ -673,16 +665,16 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ body->exprs.push_back( (ast_expression*)ast_ifthen_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_EQ_F, (ast_expression*)exp, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ), (ast_expression*)ast_return_new( - intrin_ctx(intrin), - (ast_expression*)intrin->fold->imm_float[1] + ctx(), + (ast_expression*)m_fold->imm_float[1] ), nullptr ) @@ -694,15 +686,15 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ body->exprs.push_back( (ast_expression*)ast_ifthen_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_EQ_F, (ast_expression*)exp, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ), (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)base ), nullptr @@ -713,7 +705,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) { callpow1->params.push_back((ast_expression*)base); callpow1->params.push_back( (ast_expression*)ast_unary_new( - intrin_ctx(intrin), + ctx(), VINSTR_NEG_F, (ast_expression*)exp ) @@ -725,19 +717,19 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ body->exprs.push_back( (ast_expression*)ast_ifthen_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LT, (ast_expression*)exp, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ), (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, - (ast_expression*)intrin->fold->imm_float[1], + (ast_expression*)m_fold->imm_float[1], (ast_expression*)callpow1 ) ), @@ -749,10 +741,10 @@ static ast_expression *intrin_pow(intrin_t *intrin) { callpow2->params.push_back((ast_expression*)base); callpow2->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)exp, - (ast_expression*)intrin->fold->imm_float[3] /* 2.0f */ + (ast_expression*)m_fold->imm_float[3] /* 2.0f */ ) ); @@ -764,7 +756,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ expgt1->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)result, (ast_expression*)callpow2 @@ -772,9 +764,9 @@ static ast_expression *intrin_pow(intrin_t *intrin) { ); expgt1->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)result, (ast_expression*)result @@ -789,12 +781,12 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ body->exprs.push_back( (ast_expression*)ast_ifthen_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_GE, (ast_expression*)exp, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ), (ast_expression*)expgt1, nullptr @@ -814,24 +806,24 @@ static ast_expression *intrin_pow(intrin_t *intrin) { * mid = high / 2.0f; */ body->exprs.push_back( - (ast_expression*)ast_store_new(intrin_ctx(intrin), + (ast_expression*)ast_store_new(ctx(), INSTR_STORE_F, (ast_expression*)low, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ) ); body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)high, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ) ); body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)square, (ast_expression*)callsqrt1 @@ -840,7 +832,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) { body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)accumulate, (ast_expression*)square @@ -848,14 +840,14 @@ static ast_expression *intrin_pow(intrin_t *intrin) { ); body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)mid, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)high, - (ast_expression*)intrin->fold->imm_float[3] /* 2.0f */ + (ast_expression*)m_fold->imm_float[3] /* 2.0f */ ) ) ); @@ -868,7 +860,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ midltexp->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)low, (ast_expression*)mid @@ -876,7 +868,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) { ); midltexp->exprs.push_back( (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_MUL_F, (ast_expression*)accumulate, @@ -892,7 +884,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ midltexpelse->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)high, (ast_expression*)mid @@ -900,14 +892,14 @@ static ast_expression *intrin_pow(intrin_t *intrin) { ); midltexpelse->exprs.push_back( (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_MUL_F, (ast_expression*)accumulate, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, - (ast_expression*)intrin->fold->imm_float[1], + (ast_expression*)m_fold->imm_float[1], (ast_expression*)square ) ) @@ -931,7 +923,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ whileblock->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)square, (ast_expression*)callsqrt2 @@ -939,9 +931,9 @@ static ast_expression *intrin_pow(intrin_t *intrin) { ); whileblock->exprs.push_back( (ast_expression*)ast_ifthen_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LT, (ast_expression*)mid, (ast_expression*)exp @@ -952,19 +944,19 @@ static ast_expression *intrin_pow(intrin_t *intrin) { ); whileblock->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)mid, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, (ast_expression*)low, (ast_expression*)high ), - (ast_expression*)intrin->fold->imm_float[3] /* 2.0f */ + (ast_expression*)m_fold->imm_float[3] /* 2.0f */ ) ) ); @@ -974,7 +966,7 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ callfabs->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_SUB_F, (ast_expression*)mid, (ast_expression*)exp @@ -987,15 +979,15 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ body->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), + ctx(), /* init */ nullptr, /* pre condition */ (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_GT, (ast_expression*)callfabs, - (ast_expression*)fold_constgen_float(intrin->fold, QC_POW_EPSILON, false) + (ast_expression*)fold_constgen_float(m_fold, QC_POW_EPSILON, false) ), /* pre not */ false, @@ -1013,18 +1005,18 @@ static ast_expression *intrin_pow(intrin_t *intrin) { /* return accumulate */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)accumulate ) ); /* } */ func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_mod(intrin_t *intrin) { +ast_expression *intrin::mod_() { /* * float mod(float a, float b) { * float div = a / b; @@ -1032,17 +1024,17 @@ static ast_expression *intrin_mod(intrin_t *intrin) { * return a - b * sign * floor(sign * div); * } */ - ast_value *value = nullptr; - ast_call *call = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "floor", "mod")); - ast_value *a = ast_value_new(intrin_ctx(intrin), "a", TYPE_FLOAT); - ast_value *b = ast_value_new(intrin_ctx(intrin), "b", TYPE_FLOAT); - ast_value *div = ast_value_new(intrin_ctx(intrin), "div", TYPE_FLOAT); - ast_value *sign = ast_value_new(intrin_ctx(intrin), "sign", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "mod", TYPE_FLOAT); + ast_value *val = nullptr; + ast_call *call = ast_call_new(ctx(), func_self("floor", "mod")); + ast_value *a = ast_value_new(ctx(), "a", TYPE_FLOAT); + ast_value *b = ast_value_new(ctx(), "b", TYPE_FLOAT); + ast_value *div = ast_value_new(ctx(), "div", TYPE_FLOAT); + ast_value *sign = ast_value_new(ctx(), "sign", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "mod", TYPE_FLOAT); - value->expression.params.push_back(a); - value->expression.params.push_back(b); + val->expression.params.push_back(a); + val->expression.params.push_back(b); body->locals.push_back(div); body->locals.push_back(sign); @@ -1050,11 +1042,11 @@ static ast_expression *intrin_mod(intrin_t *intrin) { /* div = a / b; */ body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)div, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)a, (ast_expression*)b @@ -1065,19 +1057,19 @@ static ast_expression *intrin_mod(intrin_t *intrin) { /* sign = (div < 0.0f) ? -1 : 1; */ body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)sign, (ast_expression*)ast_ternary_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LT, (ast_expression*)div, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ), - (ast_expression*)intrin->fold->imm_float[2], - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[2], + (ast_expression*)m_fold->imm_float[1] ) ) ); @@ -1085,7 +1077,7 @@ static ast_expression *intrin_mod(intrin_t *intrin) { /* floor(sign * div) */ call->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)sign, (ast_expression*)div @@ -1095,17 +1087,17 @@ static ast_expression *intrin_mod(intrin_t *intrin) { /* return a - b * sign * */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_SUB_F, (ast_expression*)a, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)b, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)sign, (ast_expression*)call @@ -1116,34 +1108,34 @@ static ast_expression *intrin_mod(intrin_t *intrin) { ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_fabs(intrin_t *intrin) { +ast_expression *intrin::fabs_() { /* * float fabs(float x) { * return x < 0 ? -x : x; * } */ - ast_value *value = nullptr; - ast_value *arg1 = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "fabs", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *arg1 = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "fabs", TYPE_FLOAT); body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_ternary_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LE, (ast_expression*)arg1, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ), (ast_expression*)ast_unary_new( - intrin_ctx(intrin), + ctx(), VINSTR_NEG_F, (ast_expression*)arg1 ), @@ -1152,14 +1144,14 @@ static ast_expression *intrin_fabs(intrin_t *intrin) { ) ); - value->expression.params.push_back(arg1); + val->expression.params.push_back(arg1); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_epsilon(intrin_t *intrin) { +ast_expression *intrin::epsilon_() { /* * float epsilon(void) { * float eps = 1.0f; @@ -1167,53 +1159,53 @@ static ast_expression *intrin_epsilon(intrin_t *intrin) { * return eps; * } */ - ast_value *value = nullptr; - ast_value *eps = ast_value_new(intrin_ctx(intrin), "eps", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, "epsilon", TYPE_FLOAT); + ast_value *val = nullptr; + ast_value *eps = ast_value_new(ctx(), "eps", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, "epsilon", TYPE_FLOAT); body->locals.push_back(eps); /* eps = 1.0f; */ body->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)eps, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ) ); body->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), + ctx(), nullptr, nullptr, false, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_NE_F, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, - (ast_expression*)intrin->fold->imm_float[1], + (ast_expression*)m_fold->imm_float[1], (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)eps, - (ast_expression*)intrin->fold->imm_float[3] /* 2.0f */ + (ast_expression*)m_fold->imm_float[3] /* 2.0f */ ) ), - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ), false, nullptr, (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_DIV_F, (ast_expression*)eps, - (ast_expression*)intrin->fold->imm_float[3] /* 2.0f */ + (ast_expression*)m_fold->imm_float[3] /* 2.0f */ ) ) ); @@ -1221,44 +1213,44 @@ static ast_expression *intrin_epsilon(intrin_t *intrin) { /* return eps; */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)eps ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_nan(intrin_t *intrin) { +ast_expression *intrin::nan_() { /* * float nan(void) { * float x = 0.0f; * return x / x; * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_function *func = intrin_value(intrin, &value, "nan", TYPE_FLOAT); - ast_block *block = ast_block_new(intrin_ctx(intrin)); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_function *func = value(&val, "nan", TYPE_FLOAT); + ast_block *block = ast_block_new(ctx()); block->locals.push_back(x); block->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)x, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ) ); block->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)x, (ast_expression*)x @@ -1267,11 +1259,11 @@ static ast_expression *intrin_nan(intrin_t *intrin) { ); func->blocks.push_back(block); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_inf(intrin_t *intrin) { +ast_expression *intrin::inf_() { /* * float inf(void) { * float x = 1.0f; @@ -1279,11 +1271,11 @@ static ast_expression *intrin_inf(intrin_t *intrin) { * return x / y; * } */ - ast_value *value = nullptr; - ast_value *x = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_value *y = ast_value_new(intrin_ctx(intrin), "y", TYPE_FLOAT); - ast_function *func = intrin_value(intrin, &value, "inf", TYPE_FLOAT); - ast_block *block = ast_block_new(intrin_ctx(intrin)); + ast_value *val = nullptr; + ast_value *x = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_value *y = ast_value_new(ctx(), "y", TYPE_FLOAT); + ast_function *func = value(&val, "inf", TYPE_FLOAT); + ast_block *block = ast_block_new(ctx()); size_t i; block->locals.push_back(x); @@ -1293,19 +1285,19 @@ static ast_expression *intrin_inf(intrin_t *intrin) { for (i = 0; i <= 1; i++) { block->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)((i == 0) ? x : y), - (ast_expression*)intrin->fold->imm_float[i] + (ast_expression*)m_fold->imm_float[i] ) ); } block->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)x, (ast_expression*)y @@ -1314,11 +1306,11 @@ static ast_expression *intrin_inf(intrin_t *intrin) { ); func->blocks.push_back(block); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_ln(intrin_t *intrin) { +ast_expression *intrin::ln_() { /* * float log(float power, float base) { * float whole; @@ -1384,35 +1376,35 @@ static ast_expression *intrin_ln(intrin_t *intrin) { * } */ - ast_value *value = nullptr; - ast_value *power = ast_value_new(intrin_ctx(intrin), "power", TYPE_FLOAT); - ast_value *base = ast_value_new(intrin_ctx(intrin), "base", TYPE_FLOAT); - ast_value *whole = ast_value_new(intrin_ctx(intrin), "whole", TYPE_FLOAT); - ast_value *nth = ast_value_new(intrin_ctx(intrin), "nth", TYPE_FLOAT); - ast_value *sign = ast_value_new(intrin_ctx(intrin), "sign", TYPE_FLOAT); - ast_value *A_i = ast_value_new(intrin_ctx(intrin), "A_i", TYPE_FLOAT); - ast_value *B_i = ast_value_new(intrin_ctx(intrin), "B_i", TYPE_FLOAT); - ast_value *A_iminus1 = ast_value_new(intrin_ctx(intrin), "A_iminus1", TYPE_FLOAT); - ast_value *B_iminus1 = ast_value_new(intrin_ctx(intrin), "B_iminus1", TYPE_FLOAT); - ast_value *b_iplus1 = ast_value_new(intrin_ctx(intrin), "b_iplus1", TYPE_FLOAT); - ast_value *A_iplus1 = ast_value_new(intrin_ctx(intrin), "A_iplus1", TYPE_FLOAT); - ast_value *B_iplus1 = ast_value_new(intrin_ctx(intrin), "B_iplus1", TYPE_FLOAT); - ast_value *eps = ast_value_new(intrin_ctx(intrin), "eps", TYPE_FLOAT); - ast_value *base2 = ast_value_new(intrin_ctx(intrin), "base2", TYPE_FLOAT); - ast_value *n2 = ast_value_new(intrin_ctx(intrin), "n2", TYPE_FLOAT); - ast_value *newbase2 = ast_value_new(intrin_ctx(intrin), "newbase2", TYPE_FLOAT); - ast_block *block = ast_block_new(intrin_ctx(intrin)); - ast_block *plt1orblt1 = ast_block_new(intrin_ctx(intrin)); /* (power <= 1.0f || base <= 1.0f) */ - ast_block *plt1 = ast_block_new(intrin_ctx(intrin)); /* (power < 1.0f) */ - ast_block *blt1 = ast_block_new(intrin_ctx(intrin)); /* (base < 1.0f) */ - ast_block *forloop = ast_block_new(intrin_ctx(intrin)); /* for(;;) */ - ast_block *whileloop = ast_block_new(intrin_ctx(intrin)); /* while (whole >= base) */ - ast_block *nestwhile = ast_block_new(intrin_ctx(intrin)); /* while (whole >= newbase2) */ - ast_function *func = intrin_value(intrin, &value, "ln", TYPE_FLOAT); - size_t i; + ast_value *val = nullptr; + ast_value *power = ast_value_new(ctx(), "power", TYPE_FLOAT); + ast_value *base = ast_value_new(ctx(), "base",TYPE_FLOAT); + ast_value *whole= ast_value_new(ctx(), "whole", TYPE_FLOAT); + ast_value *nth = ast_value_new(ctx(), "nth", TYPE_FLOAT); + ast_value *sign = ast_value_new(ctx(), "sign", TYPE_FLOAT); + ast_value *A_i = ast_value_new(ctx(), "A_i", TYPE_FLOAT); + ast_value *B_i = ast_value_new(ctx(), "B_i", TYPE_FLOAT); + ast_value *A_iminus1 = ast_value_new(ctx(), "A_iminus1", TYPE_FLOAT); + ast_value *B_iminus1 = ast_value_new(ctx(), "B_iminus1", TYPE_FLOAT); + ast_value *b_iplus1 = ast_value_new(ctx(), "b_iplus1", TYPE_FLOAT); + ast_value *A_iplus1 = ast_value_new(ctx(), "A_iplus1", TYPE_FLOAT); + ast_value *B_iplus1 = ast_value_new(ctx(), "B_iplus1", TYPE_FLOAT); + ast_value *eps = ast_value_new(ctx(), "eps", TYPE_FLOAT); + ast_value *base2 = ast_value_new(ctx(), "base2", TYPE_FLOAT); + ast_value *n2 = ast_value_new(ctx(), "n2",TYPE_FLOAT); + ast_value *newbase2 = ast_value_new(ctx(), "newbase2", TYPE_FLOAT); + ast_block *block = ast_block_new(ctx()); + ast_block *plt1orblt1 = ast_block_new(ctx()); // (power <= 1.0f || base <= 1.0f) + ast_block *plt1 = ast_block_new(ctx()); // (power < 1.0f) + ast_block *blt1 = ast_block_new(ctx()); // (base< 1.0f) + ast_block *forloop = ast_block_new(ctx()); // for(;;) + ast_block *whileloop = ast_block_new(ctx()); // while (whole >= base) + ast_block *nestwhile= ast_block_new(ctx()); // while (whole >= newbase2) + ast_function *func = value(&val, "ln", TYPE_FLOAT); + size_t i; - value->expression.params.push_back(power); - value->expression.params.push_back(base); + val->expression.params.push_back(power); + val->expression.params.push_back(base); block->locals.push_back(whole); block->locals.push_back(nth); @@ -1426,22 +1418,22 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* sign = 1.0f; */ block->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)sign, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ) ); /* eps = __builtin_epsilon(); */ block->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)eps, (ast_expression*)ast_call_new( - intrin_ctx(intrin), - intrin_func_self(intrin, "__builtin_epsilon", "ln") + ctx(), + func_self("__builtin_epsilon", "ln") ) ) ); @@ -1457,11 +1449,11 @@ static ast_expression *intrin_ln(intrin_t *intrin) { for (j = 1; j >= 0; j--) { block->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)((j) ? ((i) ? B_iminus1 : A_i) : ((i) ? A_iminus1 : B_i)), - (ast_expression*)intrin->fold->imm_float[j] + (ast_expression*)m_fold->imm_float[j] ) ); } @@ -1480,24 +1472,24 @@ static ast_expression *intrin_ln(intrin_t *intrin) { for (i = 0; i <= 1; i++) { ((i) ? blt1 : plt1)->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)((i) ? base : power), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, - (ast_expression*)intrin->fold->imm_float[1], + (ast_expression*)m_fold->imm_float[1], (ast_expression*)((i) ? base : power) ) ) ); plt1->exprs.push_back( (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_MUL_F, (ast_expression*)sign, - (ast_expression*)intrin->fold->imm_float[2] + (ast_expression*)m_fold->imm_float[2] ) ); } @@ -1514,28 +1506,28 @@ static ast_expression *intrin_ln(intrin_t *intrin) { */ plt1orblt1->exprs.push_back( (ast_expression*)ast_ifthen_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_OR, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LE, (ast_expression*)power, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LE, (ast_expression*)base, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ) ), (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_call_new( - intrin_ctx(intrin), - intrin_func_self(intrin, "__builtin_nan", "ln") + ctx(), + func_self("__builtin_nan", "ln") ) ), nullptr @@ -1545,12 +1537,12 @@ static ast_expression *intrin_ln(intrin_t *intrin) { for (i = 0; i <= 1; i++) { plt1orblt1->exprs.push_back( (ast_expression*)ast_ifthen_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LT, (ast_expression*)((i) ? base : power), - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ), (ast_expression*)((i) ? blt1 : plt1), nullptr @@ -1564,7 +1556,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* whole = power; */ forloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)whole, (ast_expression*)power @@ -1574,17 +1566,17 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* nth = 0.0f; */ forloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)nth, - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->imm_float[0] ) ); /* base2 = base; */ whileloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)base2, (ast_expression*)base @@ -1594,21 +1586,21 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* n2 = 1.0f; */ whileloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)n2, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->imm_float[1] ) ); /* newbase2 = base2 * base2; */ whileloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)newbase2, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)base2, (ast_expression*)base2 @@ -1624,7 +1616,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* base2 = newbase2; */ nestwhile->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)base2, (ast_expression*)newbase2 @@ -1634,18 +1626,18 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* n2 *= 2; */ nestwhile->exprs.push_back( (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_MUL_F, (ast_expression*)n2, - (ast_expression*)intrin->fold->imm_float[3] /* 2.0f */ + (ast_expression*)m_fold->imm_float[3] /* 2.0f */ ) ); /* newbase2 *= newbase2; */ nestwhile->exprs.push_back( (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_MUL_F, (ast_expression*)newbase2, @@ -1656,10 +1648,10 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* while (whole >= newbase2) */ whileloop->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), + ctx(), nullptr, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_GE, (ast_expression*)whole, (ast_expression*)newbase2 @@ -1675,7 +1667,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* whole /= base2; */ whileloop->exprs.push_back( (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_DIV_F, (ast_expression*)whole, @@ -1686,7 +1678,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* nth += n2; */ whileloop->exprs.push_back( (ast_expression*)ast_binstore_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, INSTR_ADD_F, (ast_expression*)nth, @@ -1697,10 +1689,10 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* while (whole >= base) */ forloop->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), + ctx(), nullptr, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_GE, (ast_expression*)whole, (ast_expression*)base @@ -1720,7 +1712,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* b_iplus1 = nth; */ forloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)b_iplus1, (ast_expression*)nth @@ -1734,14 +1726,14 @@ static ast_expression *intrin_ln(intrin_t *intrin) { for (i = 0; i <= 1; i++) { forloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)((i) ? B_iplus1 : A_iplus1), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)b_iplus1, (ast_expression*) ((i) ? B_i : A_i) @@ -1759,7 +1751,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) { for (i = 0; i <= 1; i++) { forloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)((i) ? B_iminus1 : A_iminus1), (ast_expression*)((i) ? B_i : A_i) @@ -1774,7 +1766,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) { for (i = 0; i <= 1; i++) { forloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)((i) ? B_i : A_i), (ast_expression*)((i) ? B_iplus1 : A_iplus1) @@ -1788,20 +1780,20 @@ static ast_expression *intrin_ln(intrin_t *intrin) { */ forloop->exprs.push_back( (ast_expression*)ast_ifthen_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_LE, (ast_expression*)whole, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_ADD_F, - (ast_expression*)intrin->fold->imm_float[1], + (ast_expression*)m_fold->imm_float[1], (ast_expression*)eps ) ), (ast_expression*)ast_breakcont_new( - intrin_ctx(intrin), + ctx(), false, 0 ), @@ -1816,7 +1808,7 @@ static ast_expression *intrin_ln(intrin_t *intrin) { for (i = 0; i <= 1; i++) { forloop->exprs.push_back( (ast_expression*)ast_store_new( - intrin_ctx(intrin), + ctx(), INSTR_STORE_F, (ast_expression*)((i) ? base : power), (ast_expression*)((i) ? whole : base) @@ -1827,10 +1819,10 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* add the for loop block */ block->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), + ctx(), nullptr, /* for(; 1; ) ?? (can this be nullptr too?) */ - (ast_expression*)intrin->fold->imm_float[1], + (ast_expression*)m_fold->imm_float[1], false, nullptr, false, @@ -1842,13 +1834,13 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* return sign * A_i / B_il */ block->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_MUL_F, (ast_expression*)sign, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_DIV_F, (ast_expression*)A_i, (ast_expression*)B_i @@ -1858,72 +1850,72 @@ static ast_expression *intrin_ln(intrin_t *intrin) { ); func->blocks.push_back(block); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_log_variant(intrin_t *intrin, const char *name, float base) { - ast_value *value = nullptr; - ast_call *callln = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "__builtin_ln", name)); - ast_value *arg1 = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, name, TYPE_FLOAT); +ast_expression *intrin::log_variant(const char *name, float base) { + ast_value *val = nullptr; + ast_call *callln = ast_call_new (ctx(), func_self("__builtin_ln", name)); + ast_value *arg1 = ast_value_new(ctx(), "x", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, name, TYPE_FLOAT); - value->expression.params.push_back(arg1); + val->expression.params.push_back(arg1); callln->params.push_back((ast_expression*)arg1); - callln->params.push_back((ast_expression*)fold_constgen_float(intrin->fold, base, false)); + callln->params.push_back((ast_expression*)fold_constgen_float(m_fold, base, false)); body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)callln ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_log(intrin_t *intrin) { - return intrin_log_variant(intrin, "log", 2.7182818284590452354); +ast_expression *intrin::log_() { + return log_variant("log", 2.7182818284590452354); } -static ast_expression *intrin_log10(intrin_t *intrin) { - return intrin_log_variant(intrin, "log10", 10); +ast_expression *intrin::log10_() { + return log_variant("log10", 10); } -static ast_expression *intrin_log2(intrin_t *intrin) { - return intrin_log_variant(intrin, "log2", 2); +ast_expression *intrin::log2_() { + return log_variant("log2", 2); } -static ast_expression *intrin_logb(intrin_t *intrin) { +ast_expression *intrin::logb_() { /* FLT_RADIX == 2 for now */ - return intrin_log_variant(intrin, "log2", 2); + return log_variant("log2", 2); } -static ast_expression *intrin_shift_variant(intrin_t *intrin, const char *name, size_t instr) { +ast_expression *intrin::shift_variant(const char *name, size_t instr) { /* * float [shift] (float a, float b) { * return floor(a [instr] pow(2, b)); */ - ast_value *value = nullptr; - ast_call *callpow = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "pow", name)); - ast_call *callfloor = ast_call_new (intrin_ctx(intrin), intrin_func_self(intrin, "floor", name)); - ast_value *a = ast_value_new(intrin_ctx(intrin), "a", TYPE_FLOAT); - ast_value *b = ast_value_new(intrin_ctx(intrin), "b", TYPE_FLOAT); - ast_block *body = ast_block_new(intrin_ctx(intrin)); - ast_function *func = intrin_value(intrin, &value, name, TYPE_FLOAT); + ast_value *val = nullptr; + ast_call *callpow = ast_call_new(ctx(), func_self("pow", name)); + ast_call *callfloor = ast_call_new(ctx(), func_self("floor", name)); + ast_value *a = ast_value_new(ctx(), "a", TYPE_FLOAT); + ast_value *b = ast_value_new(ctx(), "b", TYPE_FLOAT); + ast_block *body = ast_block_new(ctx()); + ast_function *func = value(&val, name, TYPE_FLOAT); - value->expression.params.push_back(a); - value->expression.params.push_back(b); + val->expression.params.push_back(a); + val->expression.params.push_back(b); /* = pow(2, b) */ - callpow->params.push_back((ast_expression*)intrin->fold->imm_float[3]); + callpow->params.push_back((ast_expression*)m_fold->imm_float[3]); callpow->params.push_back((ast_expression*)b); /* = floor(a [instr] ) */ callfloor->params.push_back( (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), instr, (ast_expression*)a, (ast_expression*)callpow @@ -1933,133 +1925,121 @@ static ast_expression *intrin_shift_variant(intrin_t *intrin, const char *name, /* return */ body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)callfloor ) ); func->blocks.push_back(body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_lshift(intrin_t *intrin) { - return intrin_shift_variant(intrin, "lshift", INSTR_MUL_F); +ast_expression *intrin::lshift() { + return shift_variant("lshift", INSTR_MUL_F); } -static ast_expression *intrin_rshift(intrin_t *intrin) { - return intrin_shift_variant(intrin, "rshift", INSTR_DIV_F); +ast_expression *intrin::rshift() { + return shift_variant("rshift", INSTR_DIV_F); } -/* - * TODO: make static (and handle ast_type_string) here for the builtin - * instead of in SYA parse close. - */ -ast_expression *intrin_debug_typestring(intrin_t *intrin) { - (void)intrin; - return (ast_expression*)0x1; -} - -static const intrin_func_t intrinsics[] = { - {&intrin_isfinite, "__builtin_isfinite", "isfinite", 1}, - {&intrin_isinf, "__builtin_isinf", "isinf", 1}, - {&intrin_isnan, "__builtin_isnan", "isnan", 1}, - {&intrin_isnormal, "__builtin_isnormal", "isnormal", 1}, - {&intrin_signbit, "__builtin_signbit", "signbit", 1}, - {&intrin_acosh, "__builtin_acosh", "acosh", 1}, - {&intrin_asinh, "__builtin_asinh", "asinh", 1}, - {&intrin_atanh, "__builtin_atanh", "atanh", 1}, - {&intrin_exp, "__builtin_exp", "exp", 1}, - {&intrin_exp2, "__builtin_exp2", "exp2", 1}, - {&intrin_expm1, "__builtin_expm1", "expm1", 1}, - {&intrin_mod, "__builtin_mod", "mod", 2}, - {&intrin_pow, "__builtin_pow", "pow", 2}, - {&intrin_fabs, "__builtin_fabs", "fabs", 1}, - {&intrin_log, "__builtin_log", "log", 1}, - {&intrin_log10, "__builtin_log10", "log10", 1}, - {&intrin_log2, "__builtin_log2", "log2", 1}, - {&intrin_logb, "__builtin_logb", "logb", 1}, - {&intrin_lshift, "__builtin_lshift", "", 2}, - {&intrin_rshift, "__builtin_rshift", "", 2}, - {&intrin_epsilon, "__builtin_epsilon", "", 0}, - {&intrin_nan, "__builtin_nan", "", 0}, - {&intrin_inf, "__builtin_inf", "", 0}, - {&intrin_ln, "__builtin_ln", "", 2}, - {&intrin_debug_typestring, "__builtin_debug_typestring", "", 0}, - {&intrin_nullfunc, "#nullfunc", "", 0} -}; - -static void intrin_error(intrin_t *intrin, const char *fmt, ...) { +void intrin::error(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - vcompile_error(intrin->parser->lex->tok.ctx, fmt, ap); + vcompile_error(ctx(), fmt, ap); va_end(ap); } /* exposed */ -intrin_t *intrin_init(parser_t *parser) { - intrin_t *intrin = new intrin_t; +ast_expression *intrin::debug_typestring() { + return (ast_expression*)0x1; +} - intrin->parser = parser; - intrin->fold = parser->fold; +intrin::intrin(parser_t *parser) + : m_parser(parser) + , m_fold(parser->fold) +{ + static const intrin_func_t intrinsics[] = { + {&intrin::isfinite_, "__builtin_isfinite", "isfinite", 1}, + {&intrin::isinf_, "__builtin_isinf", "isinf", 1}, + {&intrin::isnan_, "__builtin_isnan", "isnan", 1}, + {&intrin::isnormal_, "__builtin_isnormal", "isnormal", 1}, + {&intrin::signbit_, "__builtin_signbit", "signbit", 1}, + {&intrin::acosh_, "__builtin_acosh", "acosh", 1}, + {&intrin::asinh_, "__builtin_asinh", "asinh", 1}, + {&intrin::atanh_, "__builtin_atanh", "atanh", 1}, + {&intrin::exp_, "__builtin_exp", "exp", 1}, + {&intrin::exp2_, "__builtin_exp2", "exp2", 1}, + {&intrin::expm1_, "__builtin_expm1", "expm1", 1}, + {&intrin::mod_, "__builtin_mod", "mod", 2}, + {&intrin::pow_, "__builtin_pow", "pow", 2}, + {&intrin::fabs_, "__builtin_fabs", "fabs", 1}, + {&intrin::log_, "__builtin_log", "log", 1}, + {&intrin::log10_, "__builtin_log10", "log10", 1}, + {&intrin::log2_, "__builtin_log2", "log2", 1}, + {&intrin::logb_, "__builtin_logb", "logb", 1}, + {&intrin::lshift, "__builtin_lshift", "", 2}, + {&intrin::rshift, "__builtin_rshift", "", 2}, + {&intrin::epsilon_, "__builtin_epsilon", "", 0}, + {&intrin::nan_, "__builtin_nan", "", 0}, + {&intrin::inf_, "__builtin_inf", "", 0}, + {&intrin::ln_, "__builtin_ln", "", 2}, + {&intrin::debug_typestring, "__builtin_debug_typestring", "", 0}, + {&intrin::nullfunc, "#nullfunc", "", 0} + }; for (auto &it : intrinsics) { - intrin->intrinsics.push_back(it); - intrin->generated.push_back(nullptr); + m_intrinsics.push_back(it); + m_generated.push_back(nullptr); } - - return intrin; } -void intrin_cleanup(intrin_t *intrin) { - delete intrin; -} - -ast_expression *intrin_fold(intrin_t *intrin, ast_value *value, ast_expression **exprs) { - if (!value || !value->name) +ast_expression *intrin::fold(ast_value *val, ast_expression **exprs) { + if (!val || !val->name) return nullptr; - for (auto &it : intrin->intrinsics) { - if (!strcmp(value->name, it.name)) + static constexpr size_t kPrefixLength = 10; // "__builtin_" + for (auto &it : m_intrinsics) { + if (!strcmp(val->name, it.name)) return (vec_size(exprs) != it.args) ? nullptr - : fold_intrin(intrin->fold, value->name + 10, exprs); + : fold_intrin(m_fold, val->name + kPrefixLength, exprs); } return nullptr; } -static GMQCC_INLINE ast_expression *intrin_func_try(intrin_t *intrin, size_t offset, const char *compare) { - for (auto &it : intrin->intrinsics) { - const size_t index = &it - &intrin->intrinsics[0]; +ast_expression *intrin::func_try(size_t offset, const char *compare) { + for (auto &it : m_intrinsics) { + const size_t index = &it - &m_intrinsics[0]; if (strcmp(*(char **)((char *)&it + offset), compare)) continue; - if (intrin->generated[index]) - return intrin->generated[index]; - return intrin->generated[index] = it.intrin(intrin); + if (m_generated[index]) + return m_generated[index]; + return m_generated[index] = (this->*it.intrin_func_t::function)(); } return nullptr; } -static ast_expression *intrin_func_self(intrin_t *intrin, const char *name, const char *from) { +ast_expression *intrin::func_self(const char *name, const char *from) { ast_expression *find; /* try current first */ - if ((find = parser_find_global(intrin->parser, name)) && ((ast_value*)find)->expression.vtype == TYPE_FUNCTION) - for (auto &it : intrin->parser->functions) + if ((find = parser_find_global(m_parser, name)) && ((ast_value*)find)->expression.vtype == TYPE_FUNCTION) + for (auto &it : m_parser->functions) if (((ast_value*)find)->name && !strcmp(it->name, ((ast_value*)find)->name) && it->builtin < 0) return find; /* try name second */ - if ((find = intrin_func_try(intrin, offsetof(intrin_func_t, name), name))) + if ((find = func_try(offsetof(intrin_func_t, name), name))) return find; /* try alias third */ - if ((find = intrin_func_try(intrin, offsetof(intrin_func_t, alias), name))) + if ((find = func_try(offsetof(intrin_func_t, alias), name))) return find; if (from) { - intrin_error(intrin, "need function `%s', compiler depends on it for `__builtin_%s'", name, from); - return intrin_func_self(intrin, "#nullfunc", nullptr); + error("need function `%s', compiler depends on it for `__builtin_%s'", name, from); + return func_self("#nullfunc", nullptr); } return nullptr; } -ast_expression *intrin_func(intrin_t *intrin, const char *name) { - return intrin_func_self(intrin, name, nullptr); +ast_expression *intrin::func(const char *name) { + return func_self(name, nullptr); } diff --git a/parser.cpp b/parser.cpp index 4c24cac..eea0863 100644 --- a/parser.cpp +++ b/parser.cpp @@ -588,7 +588,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) return false; } else if (!(out = fold_op(parser->fold, op, exprs))) { /* generate a call to __builtin_mod */ - ast_expression *mod = intrin_func(parser->intrin, "mod"); + ast_expression *mod = parser->m_intrin.func("mod"); ast_call *call = nullptr; if (!mod) return false; /* can return null for missing floor */ @@ -658,7 +658,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) } if (!(out = fold_op(parser->fold, op, exprs))) { - ast_expression *shift = intrin_func(parser->intrin, (op->id == opid2('<','<')) ? "__builtin_lshift" : "__builtin_rshift"); + ast_expression *shift = parser->m_intrin.func((op->id == opid2('<','<')) ? "__builtin_lshift" : "__builtin_rshift"); ast_call *call = ast_call_new(parser_ctx(parser), shift); call->params.push_back(exprs[0]); call->params.push_back(exprs[1]); @@ -676,7 +676,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) } if(!(out = fold_op(parser->fold, op, exprs))) { - ast_expression *shift = intrin_func(parser->intrin, (op->id == opid3('<','<','=')) ? "__builtin_lshift" : "__builtin_rshift"); + ast_expression *shift = parser->m_intrin.func((op->id == opid3('<','<','=')) ? "__builtin_lshift" : "__builtin_rshift"); ast_call *call = ast_call_new(parser_ctx(parser), shift); call->params.push_back(exprs[0]); call->params.push_back(exprs[1]); @@ -755,7 +755,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) } if (!(out = fold_op(parser->fold, op, exprs))) { - ast_call *gencall = ast_call_new(parser_ctx(parser), intrin_func(parser->intrin, "pow")); + ast_call *gencall = ast_call_new(parser_ctx(parser), parser->m_intrin.func("pow")); gencall->params.push_back(exprs[0]); gencall->params.push_back(exprs[1]); out = (ast_expression*)gencall; @@ -1189,7 +1189,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy) * TODO handle this at the intrinsic level with an ast_intrinsic * node and codegen. */ - if ((fun = sy->out[fid].out) == intrin_debug_typestring(parser->intrin)) { + if ((fun = sy->out[fid].out) == parser->m_intrin.debug_typestring()) { char ty[1024]; if (fid+2 != sy->out.size() || sy->out.back().block) { parseerror(parser, "intrinsic __builtin_debug_typestring requires exactly 1 parameter"); @@ -1233,7 +1233,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy) for (i = 0; i < paramcount; i++) vec_push(exprs, sy->out[fid+1 + i].out); - if (!(foldval = intrin_fold(parser->intrin, (ast_value*)fun, exprs))) { + if (!(foldval = parser->m_intrin.fold((ast_value*)fun, exprs))) { vec_free(exprs); goto fold_leave; } @@ -1595,7 +1595,7 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels) * use the identifier as is. */ if (!strncmp(parser_tokval(parser), "__builtin_", 10)) { - var = intrin_func(parser->intrin, parser_tokval(parser)); + var = parser->m_intrin.func(parser_tokval(parser)); } /* @@ -1603,7 +1603,7 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels) * the first one masks for __builtin though, we emit warning here. */ if (!var) { - if ((var = intrin_func(parser->intrin, parser_tokval(parser)))) { + if ((var = parser->m_intrin.func(parser_tokval(parser)))) { (void)!compile_warning( parser_ctx(parser), WARN_BUILTINS, @@ -6017,8 +6017,8 @@ parser_t *parser_create() parser->reserved_version = nullptr; } - parser->fold = fold_init (parser); - parser->intrin = intrin_init(parser); + parser->fold = fold_init(parser); + parser->m_intrin = intrin(parser); return parser; } @@ -6116,7 +6116,6 @@ static void parser_remove_ast(parser_t *parser) util_htdel(parser->aliases); fold_cleanup(parser->fold); - intrin_cleanup(parser->intrin); } void parser_cleanup(parser_t *parser) diff --git a/parser.h b/parser.h index 2393fce..f9f0ab5 100644 --- a/parser.h +++ b/parser.h @@ -3,9 +3,9 @@ #include "gmqcc.h" #include "lexer.h" #include "ast.h" +#include "intrin.h" struct parser_t; -struct intrin_t; struct fold_t { parser_t *parser; @@ -16,23 +16,11 @@ struct fold_t { hash_table_t *imm_string_dotranslate; /* map */ }; -struct intrin_func_t { - ast_expression *(*intrin)(intrin_t *); - const char *name; - const char *alias; - size_t args; -}; - -struct intrin_t { - std::vector intrinsics; - std::vector generated; - parser_t *parser; - fold_t *fold; -}; - #define parser_ctx(p) ((p)->lex->tok.ctx) struct parser_t { + parser_t() { } + lex_file *lex; int tok; @@ -89,7 +77,7 @@ struct parser_t { size_t max_param_count; fold_t *fold; - intrin_t *intrin; + intrin m_intrin; }; @@ -111,11 +99,4 @@ ast_expression *fold_binary (lex_ctx_t ctx, int, ast_expression *, ast_e int fold_cond_ifthen (ir_value *, ast_function *, ast_ifthen *); int fold_cond_ternary (ir_value *, ast_function *, ast_ternary *); -/* intrin.c */ -intrin_t *intrin_init (parser_t *parser); -void intrin_cleanup (intrin_t *intrin); -ast_expression *intrin_fold (intrin_t *intrin, ast_value *, ast_expression **); -ast_expression *intrin_func (intrin_t *intrin, const char *name); -ast_expression *intrin_debug_typestring(intrin_t *intrin); - #endif