void jit_function::insn_branch_if_not(const jit_value& value, jit_label& label) { if(!jit_insn_branch_if_not(func, value.raw(), label.rawp())) { out_of_memory(); } }
Compiler::value If::compile(Compiler& c) const { jit_value_t res = nullptr; if (type != Type::VOID) { res = jit_value_create(c.F, VM::get_jit_type(type)); } jit_label_t label_else = jit_label_undefined; jit_label_t label_end = jit_label_undefined; auto cond = condition->compile(c); condition->compile_end(c); if (condition->type.nature == Nature::POINTER) { auto cond_bool = c.insn_to_bool(cond); c.insn_delete_temporary(cond); jit_insn_branch_if_not(c.F, cond_bool.v, &label_else); } else { jit_insn_branch_if_not(c.F, cond.v, &label_else); } auto then_v = then->compile(c); then->compile_end(c); if (then_v.v) { jit_insn_store(c.F, res, then_v.v); } jit_insn_branch(c.F, &label_end); jit_insn_label(c.F, &label_else); if (elze != nullptr) { auto else_v = elze->compile(c); elze->compile_end(c); if (else_v.v) { jit_insn_store(c.F, res, else_v.v); } } else { if (type != Type::VOID) { jit_insn_store(c.F, res, c.new_null().v); } } jit_insn_label(c.F, &label_end); return {res, type}; }
Compiler::value Match::compile(Compiler& c) const { auto v = value->compile(c); jit_value_t res = jit_value_create(c.F, VM::get_jit_type(type)); jit_label_t label_end = jit_label_undefined; for (size_t i = 0; i < pattern_list.size(); ++i) { bool is_default = false; for (const Pattern& pattern : pattern_list[i]) { is_default = is_default || pattern.is_default(); } if (is_default) { auto ret = returns[i]->compile(c); jit_insn_store(c.F, res, ret.v); jit_insn_label(c.F, &label_end); c.insn_delete_temporary(v); return {res, type}; } jit_label_t label_next = jit_label_undefined; if (pattern_list[i].size() == 1) { jit_value_t cond = pattern_list[i][0].match(c, v.v); jit_insn_branch_if_not(c.F, cond, &label_next); } else { jit_label_t label_match = jit_label_undefined; for (const Pattern& pattern : pattern_list[i]) { jit_value_t cond = pattern.match(c, v.v); jit_insn_branch_if(c.F, cond, &label_match); } jit_insn_branch(c.F, &label_next); jit_insn_label(c.F, &label_match); } auto ret = returns[i]->compile(c); jit_insn_store(c.F, res, ret.v); jit_insn_branch(c.F, &label_end); jit_insn_label(c.F, &label_next); } // In the case of no default pattern jit_insn_store(c.F, res, c.new_null().v); jit_insn_label(c.F, &label_end); c.insn_delete_temporary(v); return {res, type}; }
int main(int argc, char **argv) { jit_context_t context; jit_type_t params[2]; jit_type_t signature; jit_function_t function; jit_value_t x, y; jit_value_t temp1, temp2; jit_value_t temp3, temp4; jit_value_t temp_args[2]; jit_label_t label1 = jit_label_undefined; jit_label_t label2 = jit_label_undefined; jit_uint arg1, arg2; void *args[2]; jit_uint result; /* Create a context to hold the JIT's primary state */ context = jit_context_create(); /* Lock the context while we build and compile the function */ jit_context_build_start(context); /* Build the function signature */ params[0] = jit_type_uint; params[1] = jit_type_uint; signature = jit_type_create_signature (jit_abi_cdecl, jit_type_uint, params, 2, 1); /* Create the function object */ function = jit_function_create(context, signature); /* Check the condition "if(x == y)" */ x = jit_value_get_param(function, 0); y = jit_value_get_param(function, 1); temp1 = jit_insn_eq(function, x, y); jit_insn_branch_if_not(function, temp1, &label1); /* Implement "return x" */ jit_insn_return(function, x); /* Set "label1" at this position */ jit_insn_label(function, &label1); /* Check the condition "if(x < y)" */ temp2 = jit_insn_lt(function, x, y); jit_insn_branch_if_not(function, temp2, &label2); /* Implement "return gcd(x, y - x)" */ temp_args[0] = x; temp_args[1] = jit_insn_sub(function, y, x); temp3 = jit_insn_call (function, "gcd", function, 0, temp_args, 2, 0); jit_insn_return(function, temp3); /* Set "label2" at this position */ jit_insn_label(function, &label2); /* Implement "return gcd(x - y, y)" */ temp_args[0] = jit_insn_sub(function, x, y); temp_args[1] = y; temp4 = jit_insn_call (function, "gcd", function, 0, temp_args, 2, 0); jit_insn_return(function, temp4); /* Compile the function */ jit_function_compile(function); /* Unlock the context */ jit_context_build_end(context); /* Execute the function and print the result */ arg1 = 27; arg2 = 14; args[0] = &arg1; args[1] = &arg2; jit_function_apply(function, args, &result); printf("gcd(27, 14) = %u\n", (unsigned int)result); /* Clean up */ jit_context_destroy(context); /* Finished */ return 0; }
/* * Output a branch instruction using a JIT coder. */ static void JITCoder_Branch(ILCoder *coder, int opcode, ILUInt32 dest, ILEngineType type1, ILEngineType type2) { ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder); ILJITLabel *label = 0; ILJitValue temp = 0; _ILJitStackItemNew(value2); _ILJitStackItemNew(value1); #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) if (jitCoder->flags & IL_CODER_FLAG_STATS) { ILMutexLock(globalTraceMutex); fprintf(stdout, "Branch: %i\n", dest); ILMutexUnlock(globalTraceMutex); } #endif /* Determine what form of branch to use */ switch(opcode) { case IL_OP_BR: case IL_OP_BR_S: case IL_OP_LEAVE: case IL_OP_LEAVE_S: { /* Unconditional branch */ label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL); jit_insn_branch(jitCoder->jitFunction, &(label->label)); } break; case IL_OP_BRTRUE_S: case IL_OP_BRTRUE: { /* Branch if the top-most stack item is true */ _ILJitStackPop(jitCoder, value1); label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL); jit_insn_branch_if(jitCoder->jitFunction, _ILJitStackItemValue(value1), &(label->label)); } break; case IL_OP_BRFALSE_S: case IL_OP_BRFALSE: { /* Branch if the top-most stack item is false */ _ILJitStackPop(jitCoder, value1); label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL); jit_insn_branch_if_not(jitCoder->jitFunction, _ILJitStackItemValue(value1), &(label->label)); } break; default: { _ILJitStackPop(jitCoder, value2); _ILJitStackPop(jitCoder, value1); label = _ILJitLabelGet(jitCoder, dest, _IL_JIT_LABEL_NORMAL); switch(opcode) { case IL_OP_BEQ: case IL_OP_BEQ_S: { /* Equality testing branch */ temp = OutputCompare(jitCoder, IL_OP_BEQ, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BNE_UN: case IL_OP_BNE_UN_S: { /* Unsigned inequality testing branch */ temp = OutputCompare(jitCoder, IL_OP_BNE_UN, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BGT: case IL_OP_BGT_S: { /* Signed greater than testing branch */ temp = OutputCompare(jitCoder, IL_OP_BGT, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BGT_UN: case IL_OP_BGT_UN_S: { /* Unsigned greater than testing branch */ temp = OutputCompare(jitCoder, IL_OP_BGT_UN, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BGE: case IL_OP_BGE_S: { /* Signed greater than or equal testing branch */ temp = OutputCompare(jitCoder, IL_OP_BGE, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BGE_UN: case IL_OP_BGE_UN_S: { /* Unsigned greater than or equal testing branch */ temp = OutputCompare(jitCoder, IL_OP_BGE_UN, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BLT: case IL_OP_BLT_S: { /* Signed less than testing branch */ temp = OutputCompare(jitCoder, IL_OP_BLT, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BLT_UN: case IL_OP_BLT_UN_S: { /* Unsigned less than testing branch */ temp = OutputCompare(jitCoder, IL_OP_BLT_UN, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BLE: case IL_OP_BLE_S: { /* Signed less than or equal testing branch */ temp = OutputCompare(jitCoder, IL_OP_BLE, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; case IL_OP_BLE_UN: case IL_OP_BLE_UN_S: { /* Unsigned less than or equal testing branch */ temp = OutputCompare(jitCoder, IL_OP_BLE_UN, &(_ILJitStackItemValue(value1)), &(_ILJitStackItemValue(value2))); jit_insn_branch_if(jitCoder->jitFunction, temp, &(label->label)); } break; } } break; } }
jit_function_t bf_compile(jit_context_t cx, FILE *fp) { jit_type_t params[1], putchar_params[1], signature, putchar_sig, getchar_sig; jit_value_t ptr, uptr, ubyte, tmp; bf_loop_t loop = NULL; ubyte_ptr = jit_type_create_pointer(jit_type_ubyte, 1); params[0] = ubyte_ptr; putchar_params[0] = jit_type_ubyte; signature = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 1, 1); putchar_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_ubyte, putchar_params, 1, 1); getchar_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_ubyte, NULL, 0, 1); jit_function_t function = jit_function_create(cx, signature); ptr = jit_value_get_param(function, 0); uptr = jit_value_create_nint_constant(function, ubyte_ptr, 1); ubyte = jit_value_create_nint_constant(function, jit_type_ubyte, 1); ops *unit = (ops*)malloc(sizeof(ops)); unit->count = 0; int first = 1; while(!feof(fp)) { char c = fgetc(fp); if (first) { unit->token = c; first = 0; } switch(c) { case '>': OPTIMIZE_TOKEN('>') case '<': OPTIMIZE_TOKEN('<') case '+': OPTIMIZE_TOKEN('+') case '-': OPTIMIZE_TOKEN('-') case '.': emitOpcodes(function, ptr, unit); unit->token = '.'; tmp = jit_insn_load_relative(function, ptr, 0, jit_type_ubyte); jit_insn_call_native(function, "putchar", putchar, putchar_sig, &tmp, 1, JIT_CALL_NOTHROW); break; case ',': emitOpcodes(function, ptr, unit); unit->token = ','; jit_insn_call_native(function, "getchar", getchar, getchar_sig, NULL, 0, JIT_CALL_NOTHROW); jit_insn_store_relative(function, ptr, 0, tmp); break; case '[': emitOpcodes(function, ptr, unit); unit->token = '['; loop_start(function, &loop); tmp = jit_insn_load_relative(function, ptr, 0, jit_type_ubyte); jit_insn_branch_if_not(function, tmp, &loop->stop); break; case ']': emitOpcodes(function, ptr, unit); unit->token = ']'; loop_stop(function, &loop); break; } } jit_insn_return(function, NULL); jit_function_compile(function); return function; }
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 (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; }
jit_function_t GPerlJITCompiler::compile(JITParam *param) { GPerlVirtualMachineCode *pc = param->mtd; jit_context_t ctx = jit_context_create(); jit_context_build_start(ctx); int argc = param->argc; jit_type_t _params[argc]; for (int i = 0; i < argc; i++) { _params[i] = getJitType(param->arg_types[i]); } jit_type_t rtype = getJitType(param->return_type); jit_value_t curstack[32] = {0}; jit_value_t argstack[MAX_ARGSTACK_SIZE] = {0}; jit_type_t signature = jit_type_create_signature(jit_abi_fastcall, rtype, _params, argc, 0); jit_function_t func = jit_function_create(ctx, signature); jit_value_t _v[MAX_REG_SIZE] = {0}; GPerlJmpStack *jmp_stack = new GPerlJmpStack(); argc = 0; for (; pc->op != UNDEF; pc++) { if (jmp_stack->isJmp()) { GPerlJmpInfo *inf = jmp_stack->pop(); jit_insn_label(func, &inf->label); } switch (pc->op) { case LET: DBG_PL("COMPILE LET"); curstack[pc->dst] = _v[pc->src]; break; case MOV: DBG_PL("COMPILE MOV"); _v[pc->dst] = compileMOV(pc, &func); break; case ARRAY_ARGAT: { DBG_PL("COMPILE ARGAT"); jit_value_t arg = jit_value_get_param(func, pc->src); jit_nint offset = 48; jit_value_t list = jit_insn_load_relative(func, arg, offset, object_ptr_type); jit_value_t idx = jit_value_create_nint_constant(func, jit_type_int, pc->idx); jit_value_t elem = jit_insn_load_elem(func, list, idx, value_type); _v[pc->dst] = elem; break; } case vMOV: DBG_PL("COMPILE vMOV"); _v[pc->dst] = curstack[pc->src]; break; case gMOV: break; case ARGMOV: DBG_PL("COMPILE ARGMOV"); _v[pc->dst] = jit_value_get_param(func, pc->src); break; case ADD: DBG_PL("COMPILE ADD"); _v[pc->dst] = jit_insn_add(func, _v[pc->dst], _v[pc->src]); break; case SUB: DBG_PL("COMPILE SUB"); _v[pc->dst] = jit_insn_sub(func, _v[pc->dst], _v[pc->src]); break; case iADDC: { DBG_PL("COMPILE iADDC"); jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, pc->v.ivalue); _v[pc->dst] = jit_insn_add(func, _v[pc->dst], c); break; } case iSUBC: { DBG_PL("COMPILE iSUBC"); jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, pc->v.ivalue); _v[pc->dst] = jit_insn_sub(func, _v[pc->dst], c); break; } case IS: { DBG_PL("COMPILE IS"); jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, 1); jit_value_t tmp = jit_insn_eq(func, _v[pc->dst], c); GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp); jmp_stack->push(inf); jit_insn_branch_if_not(func, tmp, &inf->label); break; } case iJLC: { DBG_PL("COMPILE iJLC"); jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, pc->v.ivalue); jit_value_t tmp = jit_insn_lt(func, _v[pc->dst], c); GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp); jmp_stack->push(inf); jit_insn_branch_if_not(func, tmp, &inf->label); break; } case iJLEC: { DBG_PL("COMPILE iJLEC"); jit_value_t c = jit_value_create_nint_constant(func, jit_type_int, pc->v.ivalue); jit_value_t tmp = jit_insn_le(func, _v[pc->dst], c); GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp); jmp_stack->push(inf); jit_insn_branch_if_not(func, tmp, &inf->label); break; } case JE: { DBG_PL("COMPILE JE"); jit_value_t tmp = jit_insn_eq(func, _v[pc->dst], _v[pc->src]); GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp); jmp_stack->push(inf); jit_insn_branch_if_not(func, tmp, &inf->label); break; } case JLE: { DBG_PL("COMPILE JLE"); jit_value_t tmp = jit_insn_le(func, _v[pc->dst], _v[pc->src]); GPerlJmpInfo *inf = new GPerlJmpInfo(pc->jmp); jmp_stack->push(inf); jit_insn_branch_if_not(func, tmp, &inf->label); break; } case PUSH: DBG_PL("COMPILE PUSH"); argstack[pc->src] = _v[pc->dst]; argc++; break; case SELFCALL: { DBG_PL("COMPILE SELFCALL"); _v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, argc, 0);//JIT_CALL_TAIL); argc = 0; break; } case SELF_FASTCALL0: { DBG_PL("COMPILE SELF_FASTCALL0"); argstack[0] = _v[pc->arg0]; _v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, 1, 0);//JIT_CALL_TAIL); break; } case SELF_FASTCALL1: { DBG_PL("COMPILE SELF_FASTCALL1"); argstack[0] = _v[pc->arg0]; argstack[1] = _v[pc->arg1]; _v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, 2, 0);//JIT_CALL_TAIL); break; } case SELF_FASTCALL2: { DBG_PL("COMPILE SELF_FASTCALL2"); argstack[0] = _v[pc->arg0]; argstack[1] = _v[pc->arg1]; argstack[2] = _v[pc->arg2]; _v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, 3, 0);//JIT_CALL_TAIL); break; } case SELF_FASTCALL3: { DBG_PL("COMPILE SELF_FASTCALL3"); argstack[0] = _v[pc->arg0]; argstack[1] = _v[pc->arg1]; argstack[2] = _v[pc->arg2]; argstack[3] = _v[pc->arg3]; _v[pc->dst] = jit_insn_call(func, "", func, NULL, argstack, 4, 0);//JIT_CALL_TAIL); break; } case REF: { //int ret = 0; //if (TYPE_CHECK(v) > 1) { //GPerlObject *o = (GPerlObject *)getObject(v); //if (o->h.type == ArrayRef) { //ret = 1; //} //} //INT_init(reg[0], ret); break; } case RET: case JIT_COUNTDOWN_RET: DBG_PL("COMPILE RET"); _v[0] = _v[pc->src]; jit_insn_return(func, _v[0]); break; default: DBG_PL("COMPILE DEFALUT"); break; } } jit_function_compile(func); jit_context_build_end(ctx); return func; }