+ 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 *out = ast_value_new(intrin_ctx(intrin), "out", 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_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_function *func = intrin_value(intrin, &value, "ln", TYPE_FLOAT);
+ size_t i;
+
+ vec_push(value->expression.params, power);
+ vec_push(value->expression.params, base);
+
+ vec_push(block->locals, whole);
+ vec_push(block->locals, nth);
+ vec_push(block->locals, sign);
+ vec_push(block->locals, eps);
+ vec_push(block->locals, out);
+ vec_push(block->locals, A_i);
+ vec_push(block->locals, B_i);
+ vec_push(block->locals, A_iminus1);
+ vec_push(block->locals, B_iminus1);
+
+ /* sign = 1.0f; */
+ vec_push(block->exprs,
+ (ast_expression*)ast_store_new(
+ intrin_ctx(intrin),
+ INSTR_STORE_F,
+ (ast_expression*)sign,
+ (ast_expression*)intrin->fold->imm_float[1]
+ )
+ );
+
+ /* eps = __builtin_epsilon(); */
+ vec_push(block->exprs,
+ (ast_expression*)ast_store_new(
+ intrin_ctx(intrin),
+ INSTR_STORE_F,
+ (ast_expression*)eps,
+ (ast_expression*)ast_call_new(
+ intrin_ctx(intrin),
+ intrin_func_self(intrin, "__builtin_epsilon", "ln")
+ )
+ )
+ );
+
+ /*
+ * A_i = 1;
+ * B_i = 0;
+ * A_iminus1 = 0;
+ * B_iminus1 = 1;
+ */
+ for (i = 0; i <= 1; i++) {
+ int j;
+ for (j = 1; j >= 0; j--) {
+ vec_push(block->exprs,
+ (ast_expression*)ast_store_new(
+ intrin_ctx(intrin),
+ INSTR_STORE_F,
+ (ast_expression*)((j) ? ((i) ? B_iminus1 : A_i)
+ : ((i) ? A_iminus1 : B_i)),
+ (ast_expression*)intrin->fold->imm_float[j]
+ )
+ );
+ }
+ }