jit_function_t parse_function() { jit_type_t params[3] = {jit_type_float64, jit_type_nuint, jit_type_nuint}, signature = jit_type_create_signature(jit_abi_cdecl, jit_type_float64, params, 3, 1); jit_function_t func = jit_function_create(jit_context, signature); const_rate = jit_value_create_float64_constant(func, jit_type_float64, (double)RATE), const_pi = jit_value_create_float64_constant(func, jit_type_float64, (double)M_PI), val_freq = jit_value_get_param(func, 0); val_sample = jit_value_get_param(func, 1); val_length = jit_value_get_param(func, 2); jit_insn_return(func, parse_recursive(func)); jit_function_compile(func); return func; }
static jit_value_t pj_jit_internal(jit_function_t function, jit_value_t *var_values, int nvars, pj_term_t *term) { if (term->type == pj_ttype_variable) { pj_variable_t *v = (pj_variable_t *)term; return var_values[v->ivar]; } else if (term->type == pj_ttype_constant) { pj_constant_t *c = (pj_constant_t *)term; if (c->const_type == pj_int_type) return jit_value_create_nint_constant(function, jit_type_sys_int, c->value_u.int_value); else if (c->const_type == pj_uint_type) /* FIXME no jit_value_create_nuint_constant defined? */ return jit_value_create_nint_constant(function, jit_type_sys_int, c->value_u.uint_value); else if (c->const_type == pj_double_type) return jit_value_create_float64_constant(function, jit_type_sys_double, c->value_u.dbl_value); else abort(); } else if (term->type == pj_ttype_op) { return pj_jit_internal_op(function, var_values, nvars, (pj_op_t *)term); } else { abort(); } }
jit_value jit_function::new_constant(jit_float64 value, jit_type_t type) { if(!type) { type = jit_type_float64; } value_wrap(jit_value_create_float64_constant(func, type, value)); }
/*@ * @deftypefun jit_value_t jit_value_create_constant (jit_function_t @var{func}, const jit_constant_t *@var{const_value}) * Create a new constant from a generic constant structure in the specified * function. Returns NULL if out of memory or if the type in * @var{const_value} is not suitable for a constant. * @end deftypefun @*/ jit_value_t jit_value_create_constant(jit_function_t func, const jit_constant_t *const_value) { jit_type_t stripped = jit_type_remove_tags(const_value->type); if(!stripped) { return 0; } switch(stripped->kind) { case JIT_TYPE_SBYTE: case JIT_TYPE_UBYTE: case JIT_TYPE_SHORT: case JIT_TYPE_USHORT: case JIT_TYPE_INT: case JIT_TYPE_UINT: return jit_value_create_nint_constant(func, const_value->type, const_value->un.int_value); case JIT_TYPE_NINT: case JIT_TYPE_NUINT: case JIT_TYPE_PTR: case JIT_TYPE_SIGNATURE: return jit_value_create_nint_constant(func, const_value->type, const_value->un.nint_value); case JIT_TYPE_LONG: case JIT_TYPE_ULONG: return jit_value_create_long_constant(func, const_value->type, const_value->un.long_value); case JIT_TYPE_FLOAT32: return jit_value_create_float32_constant(func, const_value->type, const_value->un.float32_value); case JIT_TYPE_FLOAT64: return jit_value_create_float64_constant(func, const_value->type, const_value->un.float64_value); case JIT_TYPE_NFLOAT: return jit_value_create_nfloat_constant(func, const_value->type, const_value->un.nfloat_value); } return 0; }
static jit_value_t parse_recursive(jit_function_t func) { jit_value_t arg1, arg2, result; jit_function_t func1; double val; char *t = token(); // Somebody, do something with this! // It's awful monkeycoding, but I'm too lazy to rewrite it :3 if (STREQ(t, "F")) result = val_freq; else if (STREQ(t, "X")) result = jit_insn_convert(func, val_sample, jit_type_float64, 0); else if (STREQ(t, "LEN")) result = jit_insn_convert(func, val_length, jit_type_float64, 0); else if (STREQ(t, "RATE")) result = const_rate; else if (STREQ(t, "PI")) result = const_pi; else if (STREQ(t, "+")) result = jit_insn_add(func, parse_recursive(func), parse_recursive(func)); else if (STREQ(t, "-")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_sub(func, arg1, arg2); } else if (STREQ(t, "*")) result = jit_insn_mul(func, parse_recursive(func), parse_recursive(func)); else if (STREQ(t, "/")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_div(func, arg1, arg2); } else if (STREQ(t, "%")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_rem(func, arg1, arg2); } else if (STREQ(t, ">")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_gt(func, arg1, arg2); } else if (STREQ(t, "<")) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); result = jit_insn_lt(func, arg1, arg2); } else if (STREQ(t, "if")) { jit_value_t tmpval = jit_value_create(func, jit_type_float64); jit_label_t lb_false = jit_label_undefined, lb_end = jit_label_undefined; jit_insn_branch_if_not(func, jit_insn_to_bool(func, parse_recursive(func)), &lb_false); jit_insn_store(func, tmpval, parse_recursive(func)); jit_insn_branch(func, &lb_end); jit_insn_label(func, &lb_false); jit_insn_store(func, tmpval, parse_recursive(func)); jit_insn_label(func, &lb_end); result = jit_insn_load(func, tmpval); } else if (STREQ(t, "sin")) result = jit_insn_sin(func, parse_recursive(func)); else if (sscanf(t, "%lf", &val) == 1) result = jit_value_create_float64_constant(func, jit_type_float64, val); else if ((func1 = get_function_by_name(t)) != NULL) { arg1 = parse_recursive(func); arg2 = parse_recursive(func); jit_value_t args[3] = {arg1, arg2, val_length}; result = jit_insn_call( func, t, func1, NULL, args, 3, 0); } else { LOGF("Unexpected token '%s'", t); result = NULL; } free(t); return result; }
void *LibJITFormula::emit (NumberExprAST *expr) { return jit_value_create_float64_constant (function, jit_type_float64, (jit_float64)expr->val); }
void *LibJITFormula::emit (CallExprAST *expr) { if (expr->function == "if") { // We're going to make a new temporary, and store a value to it depending // on what happens here. jit_value_t result = jit_value_create (function, jit_type_float64); // if (cond) jit_value_t cond = (jit_value_t)expr->args[0]->generate (this); if (!cond) return NULL; jit_value_t one = jit_value_create_float64_constant (function, jit_type_float64, 1.0); jit_value_t comparison = jit_insn_eq (function, cond, one); jit_label_t label_if = jit_label_undefined; jit_label_t label_end = jit_label_undefined; jit_insn_branch_if_not (function, comparison, &label_if); // (the if-value) jit_value_t t = (jit_value_t)expr->args[1]->generate (this); jit_insn_store (function, result, t); jit_insn_branch (function, &label_end); // The else branches to here... jit_insn_label (function, &label_if); // (the else-value) jit_value_t f = (jit_value_t)expr->args[2]->generate (this); jit_insn_store (function, result, f); jit_insn_label (function, &label_end); return result; } else if (expr->function == "sign") { // Same thing as the if-function above jit_value_t one = jit_value_create_float64_constant (function, jit_type_float64, 1.0); jit_value_t zero = jit_value_create_float64_constant (function, jit_type_float64, 0.0); jit_value_t minusone = jit_value_create_float64_constant (function, jit_type_float64, -1.0); jit_value_t arg = (jit_value_t)expr->args[0]->generate (this); jit_value_t result = jit_value_create (function, jit_type_float64); jit_label_t label_end = jit_label_undefined; jit_value_t positive = jit_insn_gt (function, arg, zero); jit_label_t label_positive = jit_label_undefined; jit_insn_branch_if_not (function, positive, &label_positive); jit_insn_store (function, result, one); jit_insn_branch (function, &label_end); jit_insn_label (function, &label_positive); jit_value_t negative = jit_insn_lt (function, arg, zero); jit_label_t label_negative = jit_label_undefined; jit_insn_branch_if_not (function, negative, &label_negative); jit_insn_store (function, result, minusone); jit_insn_branch (function, &label_end); jit_insn_label (function, &label_negative); jit_insn_store (function, result, zero); jit_insn_label (function, &label_end); return result; } else if (expr->function == "atan2") { // HACK: We have to put this here since it has two arguments jit_value_t args[2]; args[0] = (jit_value_t)expr->args[0]->generate (this); args[1] = (jit_value_t)expr->args[1]->generate (this); jit_type_t params[2]; params[0] = jit_type_float64; params[1] = jit_type_float64; jit_type_t signature; signature = jit_type_create_signature (jit_abi_cdecl, jit_type_float64, params, 2, 1); return jit_insn_call_native (function, "atan2", (void *)((double (*)(double, double))atan2), signature, args, 2, 0); } // Compile the arguments // HACK: we just assume for now that if() is the only thing with // more than one argument. jit_value_t arg = (jit_value_t)expr->args[0]->generate (this); // Create a native signature for our few native functions jit_type_t params[1]; params[0] = jit_type_float64; jit_type_t signature; signature = jit_type_create_signature (jit_abi_cdecl, jit_type_float64, params, 1, 1); // Several of the jit_insn_FUNC constructs below have been replaced // by jit_insn_call_native, because the intrinsic instructions seem to // give the wrong answers. if (expr->function == "sin") return jit_insn_call_native (function, "sin", (void *)((double (*)(double))sin), signature, &arg, 1, 0); else if (expr->function == "cos") return jit_insn_call_native (function, "cos", (void *)((double (*)(double))cos), signature, &arg, 1, 0); else if (expr->function == "tan") return jit_insn_call_native (function, "tan", (void *)((double (*)(double))tan), signature, &arg, 1, 0); else if (expr->function == "asin") return jit_insn_call_native (function, "asin", (void *)((double (*)(double))asin), signature, &arg, 1, 0); else if (expr->function == "acos") return jit_insn_call_native (function, "acos", (void *)((double (*)(double))acos), signature, &arg, 1, 0); else if (expr->function == "atan") return jit_insn_call_native (function, "atan", (void *)((double (*)(double))atan), signature, &arg, 1, 0); else if (expr->function == "sinh") return jit_insn_call_native (function, "sinh", (void *)((double (*)(double))sinh), signature, &arg, 1, 0); else if (expr->function == "cosh") return jit_insn_call_native (function, "cosh", (void *)((double (*)(double))cosh), signature, &arg, 1, 0); else if (expr->function == "tanh") return jit_insn_call_native (function, "tanh", (void *)((double (*)(double))tanh), signature, &arg, 1, 0); else if (expr->function == "asinh") return jit_insn_call_native (function, "asinh", (void *)((double (*)(double))asinh), signature, &arg, 1, 0); else if (expr->function == "acosh") return jit_insn_call_native (function, "acosh", (void *)((double (*)(double))acosh), signature, &arg, 1, 0); else if (expr->function == "atanh") return jit_insn_call_native (function, "atanh", (void *)((double (*)(double))atanh), signature, &arg, 1, 0); else if (expr->function == "log2") return jit_insn_call_native (function, "log2", (void *)((double (*)(double))log2), signature, &arg, 1, 0); else if (expr->function == "log" || expr->function == "log10") return jit_insn_call_native (function, "log10", (void *)((double (*)(double))log10), signature, &arg, 1, 0); else if (expr->function == "ln") return jit_insn_call_native (function, "log", (void *)((double (*)(double))log), signature, &arg, 1, 0); else if (expr->function == "exp") return jit_insn_call_native (function, "exp", (void *)((double (*)(double))exp), signature, &arg, 1, 0); else if (expr->function == "sqrt") return jit_insn_sqrt (function, arg); else if (expr->function == "abs") return jit_insn_abs (function, arg); else if (expr->function == "rint") return jit_insn_call_native (function, "rint", (void *)((double (*)(double))rint), signature, &arg, 1, 0); else return NULL; }