X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=intrin.cpp;h=e55cf0ff5546d639554e8f00a79cfad7f2e1b709;hp=228fd788d24be0346bc8eb11988a45299dc40566;hb=db9c37d18bcced1c3b0f1421044155b1d88f0b25;hpb=4de08db0e7b73a832d638acc03c6936395fd2095 diff --git a/intrin.cpp b/intrin.cpp index 228fd78..e55cf0f 100644 --- a/intrin.cpp +++ b/intrin.cpp @@ -1,66 +1,61 @@ #include + +#include "ast.h" +#include "fold.h" #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 = NULL; - ast_function *func = NULL; - char buffer[1024]; - char stype [1024]; +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]; 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) { - vec_push(intrin->parser->functions, func); - vec_push(intrin->parser->globals, (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 NULL - * 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 = NULL; - ast_function *func = intrin_value(intrin, &value, NULL, 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 = NULL; - 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 +66,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 @@ -85,40 +80,40 @@ static ast_expression *intrin_isfinite(intrin_t *intrin) { ) ); - vec_push(func->blocks, block); - intrin_reg(intrin, value, func); + func->blocks.push_back(block); + 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 = NULL; - 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->m_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 +124,15 @@ static ast_expression *intrin_isinf(intrin_t *intrin) { ) ); - value->expression.params.push_back(x); - vec_push(func->blocks, body); + 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 +141,16 @@ static ast_expression *intrin_isnan(intrin_t *intrin) { * return (x != local); * } */ - ast_value *value = NULL; - 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 +159,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 +169,112 @@ static ast_expression *intrin_isnan(intrin_t *intrin) { ) ); - value->expression.params.push_back(arg1); - vec_push(func->blocks, body); + 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 = NULL; - 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 ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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->m_imm_float[0] ), - (ast_expression*)intrin->fold->imm_float[1], - (ast_expression*)intrin->fold->imm_float[0] + (ast_expression*)m_fold->m_imm_float[1], + (ast_expression*)m_fold->m_imm_float[0] ) ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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->m_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 +284,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 ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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->m_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 +337,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 ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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->m_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->m_imm_float[1], (ast_expression*)x ) ) @@ -389,19 +384,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*)m_fold->constgen_float(0.5, false), (ast_expression*)calllog ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 +408,15 @@ static ast_expression *intrin_exp(intrin_t *intrin) { * return sum; * } */ - ast_value *value = NULL; - 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 +425,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->m_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->m_imm_float[1] ) ); @@ -453,45 +448,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->m_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*)m_fold->constgen_float(200.0f, false) ), false, - NULL, + 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->m_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,61 +499,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 ) ); - vec_push(func->blocks, body); - - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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->m_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 ) ); - vec_push(func->blocks, body); - - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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); @@ -566,22 +559,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->m_imm_float[1] ) ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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) { @@ -623,27 +616,27 @@ static ast_expression *intrin_pow(intrin_t *intrin) { * return accumulate; * } */ - ast_value *value = NULL; - 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; @@ -653,12 +646,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); @@ -666,8 +659,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) @@ -675,18 +668,18 @@ 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->m_imm_float[0] ), (ast_expression*)ast_return_new( - intrin_ctx(intrin), - (ast_expression*)intrin->fold->imm_float[1] + ctx(), + (ast_expression*)m_fold->m_imm_float[1] ), - NULL + nullptr ) ); @@ -696,18 +689,18 @@ 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->m_imm_float[1] ), (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)base ), - NULL + nullptr ) ); @@ -715,7 +708,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 ) @@ -727,23 +720,23 @@ 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->m_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->m_imm_float[1], (ast_expression*)callpow1 ) ), - NULL + nullptr ) ); @@ -751,10 +744,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->m_imm_float[3] /* 2.0f */ ) ); @@ -766,7 +759,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 @@ -774,9 +767,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 @@ -791,15 +784,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_GE, (ast_expression*)exp, - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->m_imm_float[1] ), (ast_expression*)expgt1, - NULL + nullptr ) ); @@ -816,24 +809,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->m_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->m_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 @@ -842,7 +835,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 @@ -850,14 +843,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->m_imm_float[3] /* 2.0f */ ) ) ); @@ -870,7 +863,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 @@ -878,7 +871,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, @@ -894,7 +887,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 @@ -902,14 +895,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->m_imm_float[1], (ast_expression*)square ) ) @@ -933,7 +926,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 @@ -941,9 +934,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 @@ -954,19 +947,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->m_imm_float[3] /* 2.0f */ ) ) ); @@ -976,7 +969,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 @@ -989,24 +982,24 @@ static ast_expression *intrin_pow(intrin_t *intrin) { */ body->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), + ctx(), /* init */ - NULL, + 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*)m_fold->constgen_float(QC_POW_EPSILON, false) ), /* pre not */ false, /* post condition */ - NULL, + nullptr, /* post not */ false, /* increment expression */ - NULL, + nullptr, /* code block */ (ast_expression*)whileblock ) @@ -1015,19 +1008,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 ) ); /* } */ - vec_push(func->blocks, body); - - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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; @@ -1035,17 +1027,17 @@ static ast_expression *intrin_mod(intrin_t *intrin) { * return a - b * sign * floor(sign * div); * } */ - ast_value *value = NULL; - 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); - - value->expression.params.push_back(a); - value->expression.params.push_back(b); + 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); + + val->expression.params.push_back(a); + val->expression.params.push_back(b); body->locals.push_back(div); body->locals.push_back(sign); @@ -1053,11 +1045,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 @@ -1068,19 +1060,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->m_imm_float[0] ), - (ast_expression*)intrin->fold->imm_float[2], - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->m_imm_float[2], + (ast_expression*)m_fold->m_imm_float[1] ) ) ); @@ -1088,7 +1080,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 @@ -1098,17 +1090,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 @@ -1118,36 +1110,35 @@ static ast_expression *intrin_mod(intrin_t *intrin) { ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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->m_imm_float[0] ), (ast_expression*)ast_unary_new( - intrin_ctx(intrin), + ctx(), VINSTR_NEG_F, (ast_expression*)arg1 ), @@ -1156,16 +1147,14 @@ static ast_expression *intrin_fabs(intrin_t *intrin) { ) ); - value->expression.params.push_back(arg1); - - vec_push(func->blocks, body); + val->expression.params.push_back(arg1); - intrin_reg(intrin, value, func); - - return (ast_expression*)value; + func->blocks.push_back(body); + 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; @@ -1173,53 +1162,53 @@ static ast_expression *intrin_epsilon(intrin_t *intrin) { * return eps; * } */ - ast_value *value = NULL; - 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->m_imm_float[0] ) ); body->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), - NULL, - NULL, + 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->m_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->m_imm_float[3] /* 2.0f */ ) ), - (ast_expression*)intrin->fold->imm_float[1] + (ast_expression*)m_fold->m_imm_float[1] ), false, - NULL, + 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->m_imm_float[3] /* 2.0f */ ) ) ); @@ -1227,45 +1216,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 ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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->m_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 @@ -1273,13 +1261,12 @@ static ast_expression *intrin_nan(intrin_t *intrin) { ) ); - vec_push(func->blocks, block); - intrin_reg(intrin, value, func); - - return (ast_expression*)value; + func->blocks.push_back(block); + 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; @@ -1287,11 +1274,11 @@ static ast_expression *intrin_inf(intrin_t *intrin) { * return x / y; * } */ - ast_value *value = NULL; - 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); @@ -1301,19 +1288,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->m_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 @@ -1321,13 +1308,12 @@ static ast_expression *intrin_inf(intrin_t *intrin) { ) ); - vec_push(func->blocks, block); - intrin_reg(intrin, value, func); - - return (ast_expression*)value; + func->blocks.push_back(block); + 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; @@ -1393,35 +1379,35 @@ static ast_expression *intrin_ln(intrin_t *intrin) { * } */ - ast_value *value = NULL; - 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); @@ -1435,22 +1421,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->m_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") ) ) ); @@ -1466,11 +1452,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->m_imm_float[j] ) ); } @@ -1489,24 +1475,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->m_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->m_imm_float[2] ) ); } @@ -1523,46 +1509,46 @@ 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->m_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->m_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") ) ), - NULL + nullptr ) ); 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->m_imm_float[1] ), (ast_expression*)((i) ? blt1 : plt1), - NULL + nullptr ) ); } @@ -1573,7 +1559,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 @@ -1583,17 +1569,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->m_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 @@ -1603,21 +1589,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->m_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 @@ -1633,7 +1619,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 @@ -1643,18 +1629,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->m_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, @@ -1665,18 +1651,18 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* while (whole >= newbase2) */ whileloop->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), - NULL, + ctx(), + nullptr, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_GE, (ast_expression*)whole, (ast_expression*)newbase2 ), false, - NULL, + nullptr, false, - NULL, + nullptr, (ast_expression*)nestwhile ) ); @@ -1684,7 +1670,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, @@ -1695,7 +1681,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, @@ -1706,18 +1692,18 @@ static ast_expression *intrin_ln(intrin_t *intrin) { /* while (whole >= base) */ forloop->exprs.push_back( (ast_expression*)ast_loop_new( - intrin_ctx(intrin), - NULL, + ctx(), + nullptr, (ast_expression*)ast_binary_new( - intrin_ctx(intrin), + ctx(), INSTR_GE, (ast_expression*)whole, (ast_expression*)base ), false, - NULL, + nullptr, false, - NULL, + nullptr, (ast_expression*)whileloop ) ); @@ -1729,7 +1715,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 @@ -1743,14 +1729,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) @@ -1768,7 +1754,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) @@ -1783,7 +1769,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) @@ -1797,24 +1783,24 @@ 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->m_imm_float[1], (ast_expression*)eps ) ), (ast_expression*)ast_breakcont_new( - intrin_ctx(intrin), + ctx(), false, 0 ), - NULL + nullptr ) ); @@ -1825,7 +1811,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) @@ -1836,14 +1822,14 @@ 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), - NULL, - /* for(; 1; ) ?? (can this be NULL too?) */ - (ast_expression*)intrin->fold->imm_float[1], + ctx(), + nullptr, + /* for(; 1; ) ?? (can this be nullptr too?) */ + (ast_expression*)m_fold->m_imm_float[1], false, - NULL, + nullptr, false, - NULL, + nullptr, (ast_expression*)forloop ) ); @@ -1851,13 +1837,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 @@ -1866,74 +1852,73 @@ static ast_expression *intrin_ln(intrin_t *intrin) { ) ); - vec_push(func->blocks, block); - intrin_reg(intrin, value, func); - - return (ast_expression*)value; + func->blocks.push_back(block); + reg(val, func); + return (ast_expression*)val; } -static ast_expression *intrin_log_variant(intrin_t *intrin, const char *name, float base) { - ast_value *value = NULL; - 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*)m_fold->constgen_float(base, false)); body->exprs.push_back( (ast_expression*)ast_return_new( - intrin_ctx(intrin), + ctx(), (ast_expression*)callln ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = NULL; - 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->m_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 @@ -1943,141 +1928,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 ) ); - vec_push(func->blocks, body); - intrin_reg(intrin, value, func); - return (ast_expression*)value; + func->blocks.push_back(body); + 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 = (intrin_t*)mem_a(sizeof(intrin_t)); - size_t i; - - intrin->parser = parser; - intrin->fold = parser->fold; - intrin->intrinsics = NULL; - intrin->generated = NULL; - - vec_append(intrin->intrinsics, GMQCC_ARRAY_COUNT(intrinsics), intrinsics); - - /* populate with null pointers for tracking generation */ - for (i = 0; i < GMQCC_ARRAY_COUNT(intrinsics); i++) - vec_push(intrin->generated, NULL); - - return intrin; +ast_expression *intrin::debug_typestring() { + return (ast_expression*)0x1; } -void intrin_cleanup(intrin_t *intrin) { - vec_free(intrin->intrinsics); - vec_free(intrin->generated); - mem_d(intrin); +intrin::intrin(parser_t *parser) + : m_parser(parser) + , m_fold(&parser->m_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) { + m_intrinsics.push_back(it); + m_generated.push_back(nullptr); + } } -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)) - return (vec_size(exprs) != intrin->intrinsics[i].args) - ? NULL - : fold_intrin(intrin->fold, value->name + 10, exprs); - return NULL; +ast_expression *intrin::do_fold(ast_value *val, ast_expression **exprs) { + if (!val || !val->name) + return nullptr; + 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 + : m_fold->intrinsic(val->name + kPrefixLength, exprs); + } + return nullptr; } -static GMQCC_INLINE ast_expression *intrin_func_try(intrin_t *intrin, size_t offset, const char *compare) { - size_t i; - for (i = 0; i < vec_size(intrin->intrinsics); i++) { - if (strcmp(*(char **)((char *)&intrin->intrinsics[i] + offset), compare)) +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[i]) - return intrin->generated[i]; - return intrin->generated[i] = intrin->intrinsics[i].intrin(intrin); + if (m_generated[index]) + return m_generated[index]; + return m_generated[index] = (this->*it.intrin_func_t::function)(); } - return NULL; + return nullptr; } -static ast_expression *intrin_func_self(intrin_t *intrin, const char *name, const char *from) { - size_t i; - ast_expression *find; - +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 (i = 0; i < vec_size(intrin->parser->functions); ++i) - if (((ast_value*)find)->name && !strcmp(intrin->parser->functions[i]->name, ((ast_value*)find)->name) && intrin->parser->functions[i]->builtin < 0) + 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", NULL); + error("need function `%s', compiler depends on it for `__builtin_%s'", name, from); + return func_self("#nullfunc", nullptr); } - return NULL; + return nullptr; } -ast_expression *intrin_func(intrin_t *intrin, const char *name) { - return intrin_func_self(intrin, name, NULL); +ast_expression *intrin::func(const char *name) { + return func_self(name, nullptr); }