- static ast_value *value = NULL;
-
- if (!value) {
- ast_value *arg1 = ast_value_new(parser_ctx(intrin->parser), "x", TYPE_FLOAT);
- ast_value *arg2 = ast_value_new(parser_ctx(intrin->parser), "y", TYPE_FLOAT);
- ast_value *local = ast_value_new(parser_ctx(intrin->parser), "local", TYPE_FLOAT);
- ast_block *body = ast_block_new(parser_ctx(intrin->parser));
- ast_block *l1b = ast_block_new(parser_ctx(intrin->parser)); /* loop 1 body */
- ast_block *l2b = ast_block_new(parser_ctx(intrin->parser)); /* loop 2 body */
- ast_loop *loop1 = NULL;
- ast_loop *loop2 = NULL;
- ast_function *func = NULL;
-
- INTRIN_VAL(value, "pow", func, "<float>", TYPE_FLOAT);
-
- /* arguments */
- vec_push(value->expression.params, arg1);
- vec_push(value->expression.params, arg2);
-
- /* local */
- vec_push(body->locals, local);
-
- /* assignment to local of value 1.0f */
- vec_push(body->exprs,
- (ast_expression*)ast_store_new (
- parser_ctx(intrin->parser),
- INSTR_STORE_F,
- (ast_expression*)local,
- (ast_expression*)intrin->fold->imm_float[1] /* 1 == 1.0f */
- )
- );
-
- /* y >>= 2 */
- vec_push(l2b->exprs,
- (ast_expression*)ast_binstore_new (
- parser_ctx(intrin->parser),
- INSTR_STORE_F,
- INSTR_MUL_F,
- (ast_expression*)arg2,
- (ast_expression*)fold_constgen_float(intrin->parser->fold, 0.25f)
- )
- );
-
- /* x *= x */
- vec_push(l2b->exprs,
- (ast_expression*)ast_binstore_new (
- parser_ctx(intrin->parser),
- INSTR_STORE_F,
- INSTR_MUL_F,
- (ast_expression*)arg1,
- (ast_expression*)arg1
- )
- );
-
- /* while (!(y&1)) */
- loop2 = ast_loop_new (
- parser_ctx(intrin->parser),
- NULL,
- (ast_expression*)ast_binary_new (
- parser_ctx(intrin->parser),
- INSTR_AND,
- (ast_expression*)arg2,
- (ast_expression*)intrin->fold->imm_float[1] /* 1 == 1.0f */
- ),
- true, /* ! not */
- NULL,
- false,
- NULL,
- (ast_expression*)l2b
- );
-
- /* push nested loop into loop expressions */
- vec_push(l1b->exprs, (ast_expression*)loop2);
-
- /* y-- */
- vec_push(l1b->exprs,
- (ast_expression*)ast_binstore_new (
- parser_ctx(intrin->parser),
- INSTR_STORE_F,
- INSTR_SUB_F,
- (ast_expression*)arg2,
- (ast_expression*)intrin->fold->imm_float[1] /* 1 == 1.0f */
- )
- );
- /* local *= x */
- vec_push(l1b->exprs,
- (ast_expression*)ast_binstore_new (
- parser_ctx(intrin->parser),
- INSTR_STORE_F,
- INSTR_MUL_F,
- (ast_expression*)local,
- (ast_expression*)arg1
- )
- );
-
- /* while (y > 0) */
- loop1 = ast_loop_new (
- parser_ctx(intrin->parser),
- NULL,
- (ast_expression*)ast_binary_new (
- parser_ctx(intrin->parser),
- INSTR_GT,
- (ast_expression*)arg2,
- (ast_expression*)intrin->fold->imm_float[0] /* 0 == 0.0f */
- ),
- false,
- NULL,
- false,
- NULL,
- (ast_expression*)l1b
- );
-
- /* push the loop1 into the body for the function */
- vec_push(body->exprs, (ast_expression*)loop1);
-
- /* return local; */
- vec_push(body->exprs,
- (ast_expression*)ast_return_new (
- parser_ctx(intrin->parser),
- (ast_expression*)local
- )
- );
-
- /* push block and register intrin for codegen */
- vec_push(func->blocks, body);
-
- INTRIN_REG(func, value);
- }
+ ast_value *value = NULL;
+ ast_value *arg1 = ast_value_new(intrin_ctx(intrin), "x", TYPE_FLOAT);
+ ast_value *arg2 = ast_value_new(intrin_ctx(intrin), "y", TYPE_FLOAT);
+ ast_value *local = ast_value_new(intrin_ctx(intrin), "local", TYPE_FLOAT);
+ ast_block *body = ast_block_new(intrin_ctx(intrin));
+ ast_block *l1b = ast_block_new(intrin_ctx(intrin)); /* loop 1 body */
+ ast_block *l2b = ast_block_new(intrin_ctx(intrin)); /* loop 2 body */
+ ast_loop *loop1 = NULL;
+ ast_loop *loop2 = NULL;
+ ast_function *func = intrin_value(intrin, &value, "pow", TYPE_FLOAT);
+
+ /* arguments */
+ vec_push(value->expression.params, arg1);
+ vec_push(value->expression.params, arg2);
+
+ /* local */
+ vec_push(body->locals, local);
+
+ /* assignment to local of value 1.0f */
+ vec_push(body->exprs,
+ (ast_expression*)ast_store_new (
+ intrin_ctx(intrin),
+ INSTR_STORE_F,
+ (ast_expression*)local,
+ (ast_expression*)intrin->fold->imm_float[1] /* 1 == 1.0f */
+ )
+ );
+
+ /* y >>= 2 */
+ vec_push(l2b->exprs,
+ (ast_expression*)ast_binstore_new (
+ intrin_ctx(intrin),
+ INSTR_STORE_F,
+ INSTR_MUL_F,
+ (ast_expression*)arg2,
+ (ast_expression*)fold_constgen_float(intrin->parser->fold, 0.25f)
+ )
+ );
+
+ /* x *= x */
+ vec_push(l2b->exprs,
+ (ast_expression*)ast_binstore_new (
+ intrin_ctx(intrin),
+ INSTR_STORE_F,
+ INSTR_MUL_F,
+ (ast_expression*)arg1,
+ (ast_expression*)arg1
+ )
+ );
+
+ /* while (!(y&1)) */
+ loop2 = ast_loop_new (
+ intrin_ctx(intrin),
+ NULL,
+ (ast_expression*)ast_binary_new (
+ intrin_ctx(intrin),
+ INSTR_AND,
+ (ast_expression*)arg2,
+ (ast_expression*)intrin->fold->imm_float[1] /* 1 == 1.0f */
+ ),
+ true, /* ! not */
+ NULL,
+ false,
+ NULL,
+ (ast_expression*)l2b
+ );
+
+ /* push nested loop into loop expressions */
+ vec_push(l1b->exprs, (ast_expression*)loop2);
+
+ /* y-- */
+ vec_push(l1b->exprs,
+ (ast_expression*)ast_binstore_new (
+ intrin_ctx(intrin),
+ INSTR_STORE_F,
+ INSTR_SUB_F,
+ (ast_expression*)arg2,
+ (ast_expression*)intrin->fold->imm_float[1] /* 1 == 1.0f */
+ )
+ );
+ /* local *= x */
+ vec_push(l1b->exprs,
+ (ast_expression*)ast_binstore_new (
+ intrin_ctx(intrin),
+ INSTR_STORE_F,
+ INSTR_MUL_F,
+ (ast_expression*)local,
+ (ast_expression*)arg1
+ )
+ );
+
+ /* while (y > 0) */
+ loop1 = ast_loop_new (
+ intrin_ctx(intrin),
+ NULL,
+ (ast_expression*)ast_binary_new (
+ intrin_ctx(intrin),
+ INSTR_GT,
+ (ast_expression*)arg2,
+ (ast_expression*)intrin->fold->imm_float[0] /* 0 == 0.0f */
+ ),
+ false,
+ NULL,
+ false,
+ NULL,
+ (ast_expression*)l1b
+ );
+
+ /* push the loop1 into the body for the function */
+ vec_push(body->exprs, (ast_expression*)loop1);
+
+ /* return local; */
+ vec_push(body->exprs,
+ (ast_expression*)ast_return_new (
+ intrin_ctx(intrin),
+ (ast_expression*)local
+ )
+ );
+
+ /* push block and register intrin for codegen */
+ vec_push(func->blocks, body);
+
+ intrin_reg(intrin, value, func);