Example #1
0
jit_value_t Match::Pattern::match(Compiler &c, jit_value_t v) const {

	jit_type_t args_types[2] = {LS_POINTER, LS_POINTER};
	jit_type_t sig = jit_type_create_signature(jit_abi_cdecl, jit_type_sys_bool, args_types, 2, 1);

	if (interval) {
		jit_value_t ge = nullptr;
		if (begin) {
			auto b = begin->compile(c);
			if (begin->type.nature == Nature::VALUE) {
				ge = jit_insn_ge(c.F, v, b.v);
			} else {
				jit_value_t args[2] = { v, b.v };
				ge = jit_insn_call_native(c.F, "", (void*) jit_greater_equal_, sig, args, 2, JIT_CALL_NOTHROW);
				c.insn_delete_temporary(b);
			}
		}
		jit_value_t lt = nullptr;
		if (end) {
			auto e = end->compile(c);
			if (end->type.nature == Nature::VALUE) {
				lt = jit_insn_lt(c.F, v, e.v);
			} else {
				jit_value_t args[2] = { v, e.v };
				lt = jit_insn_call_native(c.F, "", (void*) jit_less_, sig, args, 2, JIT_CALL_NOTHROW);
				c.insn_delete_temporary(e);
			}
		}
		jit_type_free(sig);
		if (ge) {
			if (lt) {
				return jit_insn_and(c.F, ge, lt);
			} else {
				return ge;
			}
		} else {
			return lt;
		}
	} else {
		jit_value_t cond;
		auto p = begin->compile(c);

		if (begin->type.nature == Nature::VALUE) {
			cond = jit_insn_eq(c.F, v, p.v);
		} else {
			jit_value_t args[2] = { v, p.v };
			cond = jit_insn_call_native(c.F, "", (void*) jit_equals_, sig, args, 2, JIT_CALL_NOTHROW);
			c.insn_delete_temporary(p);
		}
		jit_type_free(sig);
		return cond;
	}
}
Example #2
0
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 comparision between the 2 top most values on the evaluation stack.
 * The result value is returned.
 */
static ILJitValue OutputCompare(ILJITCoder *coder, int opcode,
				   		     ILJitValue *value1, ILJitValue *value2)
{
	switch(opcode)
	{
		case IL_OP_PREFIX + IL_PREFIX_OP_CEQ:
		case IL_OP_BEQ:
		{
			/* Test two values for equality */
			AdjustMixedBinary(coder, 0, value1, value2);
			return jit_insn_eq(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_BNE_UN:
		{
			/* Test two unsigned values for inequality */
			AdjustMixedBinary(coder, 1, value1, value2);
			return jit_insn_ne(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_PREFIX + IL_PREFIX_OP_CGT:
		case IL_OP_BGT:
		{
			/* Test two signed values for greater than */
			AdjustMixedBinary(coder, 0, value1, value2);
			return jit_insn_gt(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_PREFIX + IL_PREFIX_OP_CGT_UN:
		case IL_OP_BGT_UN:
		{
			/* Test two unsigned values for greater than */
			AdjustMixedBinary(coder, 1, value1, value2);
			return jit_insn_gt(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_BGE:
		{
			/* Test two signed values for greater than  or equal */
			AdjustMixedBinary(coder, 0, value1, value2);
			return jit_insn_ge(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_BGE_UN:
		{
			/* Test two unsigned values for greater than  or equal */
			AdjustMixedBinary(coder, 1, value1, value2);
			return jit_insn_ge(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_PREFIX + IL_PREFIX_OP_CLT:
		case IL_OP_BLT:
		{
			/* Test two signed values for less than */
			AdjustMixedBinary(coder, 0, value1, value2);
			return jit_insn_lt(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_PREFIX + IL_PREFIX_OP_CLT_UN:
		case IL_OP_BLT_UN:
		{
			/* Test two unsigned values for less than */
			AdjustMixedBinary(coder, 1, value1, value2);
			return jit_insn_lt(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_BLE:
		{
			/* Test two signed values for less than or equal */
			AdjustMixedBinary(coder, 0, value1, value2);
			return jit_insn_le(coder->jitFunction, *value1, *value2);
		}
		break;

		case IL_OP_BLE_UN:
		{
			/* Test two unsigned values for less than  or equal */
			AdjustMixedBinary(coder, 1, value1, value2);
			return jit_insn_le(coder->jitFunction, *value1, *value2);
		}
		break;
	}
	return 0;
}
Example #4
0
static jit_value_t
pj_jit_internal_op(jit_function_t function, jit_value_t *var_values, int nvars, pj_op_t *op)
{
  jit_value_t tmp1, tmp2, rv;
  tmp1 = pj_jit_internal(function, var_values, nvars, op->op1);
  if (op->op2 != NULL)
    tmp2 = pj_jit_internal(function, var_values, nvars, op->op2);

  switch (op->optype) {
  case pj_unop_negate:
    rv = jit_insn_neg(function, tmp1);
    break;
  case pj_unop_sin:
    rv = jit_insn_sin(function, tmp1);
    break;
  case pj_unop_cos:
    rv = jit_insn_cos(function, tmp1);
    break;
  case pj_unop_abs:
    rv = jit_insn_abs(function, tmp1);
    break;
  case pj_unop_sqrt:
    rv = jit_insn_sqrt(function, tmp1);
    break;
  case pj_unop_log:
    rv = jit_insn_log(function, tmp1);
    break;
  case pj_unop_exp:
    rv = jit_insn_exp(function, tmp1);
    break;
  case pj_unop_not:
    rv = jit_insn_not(function, tmp1);
    break;
  case pj_unop_not_bool:
    rv = jit_insn_to_not_bool(function, tmp1);
    break;
  case pj_binop_add:
    rv = jit_insn_add(function, tmp1, tmp2);
    break;
  case pj_binop_subtract:
    rv = jit_insn_sub(function, tmp1, tmp2);
    break;
  case pj_binop_multiply:
    rv = jit_insn_mul(function, tmp1, tmp2);
    break;
  case pj_binop_divide:
    rv = jit_insn_div(function, tmp1, tmp2);
    break;
  case pj_binop_modulo:
    rv = jit_insn_rem(function, tmp1, tmp2); /* FIXME should this use jit_insn_rem_ieee? */
    break;
  case pj_binop_atan2:
    rv = jit_insn_atan2(function, tmp1, tmp2);
    break;
  case pj_binop_left_shift:
    rv = jit_insn_shl(function, tmp1, tmp2);
    break;
  case pj_binop_right_shift:
    rv = jit_insn_shr(function, tmp1, tmp2);
    break;
  case pj_binop_and:
    rv = jit_insn_and(function, tmp1, tmp2);
    break;
  case pj_binop_or:
    rv = jit_insn_or(function, tmp1, tmp2);
    break;
  case pj_binop_xor:
    rv = jit_insn_xor(function, tmp1, tmp2);
    break;
  case pj_binop_eq:
    rv = jit_insn_eq(function, tmp1, tmp2);
    break;
  case pj_binop_ne:
    rv = jit_insn_ne(function, tmp1, tmp2);
    break;
  case pj_binop_lt:
    rv = jit_insn_lt(function, tmp1, tmp2);
    break;
  case pj_binop_le:
    rv = jit_insn_le(function, tmp1, tmp2);
    break;
  case pj_binop_gt:
    rv = jit_insn_gt(function, tmp1, tmp2);
    break;
  case pj_binop_ge:
    rv = jit_insn_ge(function, tmp1, tmp2);
    break;
  default:
    abort();
  }

  return rv;
}
Example #5
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;
}
Example #6
0
jit_value jit_function::insn_lt
	(const jit_value& value1, const jit_value& value2)
{
	value_wrap(jit_insn_lt(func, value1.raw(), value2.raw()));
}
Example #7
0
void *LibJITFormula::emit (BinaryExprAST *expr)
{
	// Deal with assign separately, we don't want to compile the LHS
	if (expr->op == "=")
	{
		VariableExprAST *var = dynamic_cast<VariableExprAST *>(expr->LHS);
		if (!var) return NULL;

		jit_value_t val = (jit_value_t)expr->RHS->generate (this);
		if (!val) return NULL;

		// Get a pointer for this variable
		jit_value_t pointer = jit_value_create_nint_constant (function, jit_type_void_ptr,
		                                                      (jit_nint)var->pointer);

		// Emit a store instruction
		jit_insn_store_relative (function, pointer, 0, val);

		// Return value
		return val;
	}

	// Generate both sides
	jit_value_t L = (jit_value_t)expr->LHS->generate (this);
	jit_value_t R = (jit_value_t)expr->RHS->generate (this);
	if (L == NULL || R == NULL) return NULL;

	if (expr->op == "<=")
		return jit_insn_le (function, L, R);
	else if (expr->op == ">=")
		return jit_insn_ge (function, L, R);
	else if (expr->op == "!=")
		return jit_insn_ne (function, L, R);
	else if (expr->op == "==")
		return jit_insn_eq (function, L, R);
	else if (expr->op == "<")
		return jit_insn_lt (function, L, R);
	else if (expr->op == ">")
		return jit_insn_gt (function, L, R);
	else if (expr->op == "+")
		return jit_insn_add (function, L, R);
	else if (expr->op == "-")
		return jit_insn_sub (function, L, R);
	else if (expr->op == "*")
		return jit_insn_mul (function, L, R);
	else if (expr->op == "/")
		return jit_insn_div (function, L, R);
	else if (expr->op == "^")
	{
		// jit_insn_pow seems to give the wrong results?
		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);
		jit_value_t args[2];
		args[0] = L;
		args[1] = R;

		return jit_insn_call_native (function, "pow",
                                 (void *)((double (*)(double, double))pow),
                                 signature, args, 2, 0);
	}
	else
		return NULL;
}
Example #8
0
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;
}
Example #9
0
File: jit.cpp Project: goccy/gperl
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;
}