void JitInstanceMemberFunction::compileThisAdjustementThunk( size_t a_uiThisOffset ) const
{
    o_assert(m_ThisAdjustmentThunks.find(a_uiThisOffset) == m_ThisAdjustmentThunks.end());

    size_t argCount = getSignature()->getParameterCount()+1; // parameters+this
    jit_value_t* args = o_allocate_n(argCount, jit_value_t); 

    // The fixing function has the same signature as the indirected one
    jit_function_t func = jit_function_create((jit_context_t)m_jit_context.context, jit_function_get_signature((jit_function_t)m_jit_function.function));

    jit_value_t new_this = jit_insn_add(func, jit_value_get_param(func, 0), jit_value_create_nint_constant(func, jit_type_nint, -((int)a_uiThisOffset)));

    args[0] = new_this;

    size_t i = 1;
    for(;i<argCount;++i)
    {
        args[i] = jit_value_get_param(func, i);
    }
    string name = "[thunk]:"+m_pSubroutine->getQualifiedDecoratedName()+":adjustor{"+boost::lexical_cast<string>(a_uiThisOffset)+"}";
    jit_insn_call(func
                , name.c_str()
                , (jit_function_t)m_jit_function.function
                , jit_function_get_signature((jit_function_t)m_jit_function.function)
                , args
                , argCount
                , 0);

    int result = jit_function_compile(func);
    o_assert(result != 0);

    o_deallocate_n(args, argCount, jit_value_t);

    m_ThisAdjustmentThunks[a_uiThisOffset] = func;
}
Beispiel #2
0
void emitIncrement(jit_function_t function, jit_value_t ptr, ops *unit) {
    jit_value_t tmp = jit_insn_load_relative(function, ptr, 0, jit_type_ubyte);
    jit_value_t numbyte = jit_value_create_nint_constant(function, jit_type_ubyte, unit->count);
    tmp = jit_insn_add(function, tmp, numbyte);
    tmp = jit_insn_convert(function, tmp, jit_type_ubyte, 0);
    jit_insn_store_relative(function, ptr, 0, tmp);
}
Beispiel #3
0
int main() {
  jit_context_t ctx;

  // Create a context to hold the JIT's primary stats
  ctx = jit_context_create();

  // Lock the context while we build and compile the function
  jit_context_build_start(ctx);

  // Build the function signature
  jit_function_t function;
  jit_type_t params[3];
  jit_type_t signature;
  params[0] = jit_type_int;
  params[1] = jit_type_int;
  params[2] = jit_type_int;
  signature =
      jit_type_create_signature(jit_abi_cdecl, jit_type_int, params, 3, 1);

  // Create the function object
  function = jit_function_create(ctx, signature);
  jit_type_free(signature);

  // Construct the function body
  jit_value_t x, y, z;
  x = jit_value_get_param(function, 0);
  y = jit_value_get_param(function, 1);
  z = jit_value_get_param(function, 2);
  jit_value_t temp1, temp2;
  temp1 = jit_insn_mul(function, x, y);
  temp2 = jit_insn_add(function, temp1, z);
  jit_insn_return(function, temp2);

  // Compile the function
  jit_function_compile(function);

  // Unlock the context
  jit_context_build_end(ctx);

  // Execute the function and print the result
  jit_int arg1, arg2, arg3;
  jit_int result;
  void *args[3];
  arg1 = 3;
  arg2 = 5;
  arg3 = 2;
  args[0] = &arg1;
  args[1] = &arg2;
  args[2] = &arg3;
  jit_function_apply(function, args, &result);
  printf("mul_add(3,5,2) = %d\n", (int)result);

  // Clean up
  jit_context_destroy(ctx);
  return 0;
}
Beispiel #4
0
int compile_mul_add(jit_function_t function)
{
	jit_value_t x, y, z;
	jit_value_t temp1, temp2;
    
	printf("Compiling mul_add on demand\n");
    
	x = jit_value_get_param(function, 0);
	y = jit_value_get_param(function, 1);
	z = jit_value_get_param(function, 2);
    
	temp1 = jit_insn_mul(function, x, y);
	temp2 = jit_insn_add(function, temp1, z);
    
	jit_insn_return(function, temp2);
	return 1;
}
/*
 * Handle a binary opcode.
 */
static void JITCoder_Binary(ILCoder *coder, int opcode,
							ILEngineType type1, ILEngineType type2)
{
	ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
	_ILJitStackItemNew(value2);
	_ILJitStackItemNew(value1);
	ILJitValue result = 0;

	_ILJitStackPop(jitCoder, value2);
	_ILJitStackPop(jitCoder, value1);
	switch(opcode)
	{
		case IL_OP_ADD:
		{
			AdjustMixedBinary(jitCoder, 0,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_add(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_ADD_OVF:
		{
			AdjustMixedBinary(jitCoder, 0,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_add_ovf(jitCoder->jitFunction,
									  _ILJitStackItemValue(value1),
									  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_ADD_OVF_UN:
		{
			AdjustMixedBinary(jitCoder, 1,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_add_ovf(jitCoder->jitFunction,
									 _ILJitStackItemValue(value1),
									 _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_SUB:
		{
			AdjustMixedBinary(jitCoder, 0,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_sub(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_SUB_OVF:
		{
			AdjustMixedBinary(jitCoder, 0,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_sub_ovf(jitCoder->jitFunction,
									  _ILJitStackItemValue(value1),
									  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_SUB_OVF_UN:
		{
			AdjustMixedBinary(jitCoder, 1,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_sub_ovf(jitCoder->jitFunction,
									  _ILJitStackItemValue(value1),
									  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_MUL:
		{
			AdjustMixedBinary(jitCoder, 0,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_mul(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_MUL_OVF:
		{
			AdjustMixedBinary(jitCoder, 0,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_mul_ovf(jitCoder->jitFunction,
									  _ILJitStackItemValue(value1),
									  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_MUL_OVF_UN:
		{
			AdjustMixedBinary(jitCoder, 1,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_mul_ovf(jitCoder->jitFunction,
									  _ILJitStackItemValue(value1),
									  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_DIV:
		{
			AdjustMixedBinary(jitCoder, 0,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_div(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_DIV_UN:
		{
			AdjustMixedBinary(jitCoder, 1,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_div(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_REM:
		{
			AdjustMixedBinary(jitCoder, 0,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_rem(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_REM_UN:
		{
			AdjustMixedBinary(jitCoder, 1,
							  &(_ILJitStackItemValue(value1)),
							  &(_ILJitStackItemValue(value2)));
			result = jit_insn_rem(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_AND:
		{
			result = jit_insn_and(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_OR:
		{
			result = jit_insn_or(jitCoder->jitFunction,
								 _ILJitStackItemValue(value1),
								 _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_XOR:
		{
			result = jit_insn_xor(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		break;
		
		default:
		{
			return;
		}
	}
	_ILJitStackPushValue(jitCoder, result);
}
/*
 * Handle a binary opcode when pointer arithmetic is involved.
 */
static void JITCoder_BinaryPtr(ILCoder *coder, int opcode,
							   ILEngineType type1, ILEngineType type2)
{
	ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
	int value1IsPointer = _IL_JIT_ENGINE_TYPE_IS_POINTER(type1);
	int value2IsPointer = _IL_JIT_ENGINE_TYPE_IS_POINTER(type2);
	_ILJitStackItemNew(value2);
	_ILJitStackItemNew(value1);
	ILJitValue result = 0;

	_ILJitStackPop(jitCoder, value2);
	_ILJitStackPop(jitCoder, value1);
	switch(opcode)
	{
		case IL_OP_ADD:
		{
			result = jit_insn_add(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		case IL_OP_ADD_OVF_UN:
		{
			result = jit_insn_add_ovf(jitCoder->jitFunction,
									  _ILJitStackItemValue(value1),
									  _ILJitStackItemValue(value2));
		}
		break;

		case IL_OP_SUB:
		{
			result = jit_insn_sub(jitCoder->jitFunction,
								  _ILJitStackItemValue(value1),
								  _ILJitStackItemValue(value2));
		}
		case IL_OP_SUB_OVF_UN:
		{
			result = jit_insn_sub_ovf(jitCoder->jitFunction,
									  _ILJitStackItemValue(value1),
									  _ILJitStackItemValue(value2));
		}
		break;
	}
	if(value1IsPointer && value2IsPointer)
	{
		/* We can't keep the reference information for this case. */
		_ILJitStackPushValue(jitCoder, result);
	}
	else if(value1IsPointer)
	{
		/* Keep the reference information for value1. */
		_ILJitStackItemSetValue(value1, result);
		_ILJitStackPush(jitCoder, value1);
	}
	else if(value2IsPointer)
	{
		/* Keep the reference information for value2. */
		_ILJitStackItemSetValue(value2, result);
		_ILJitStackPush(jitCoder, value2);
	}
	else
	{
		/* There is no pointer involved in this operation. */
		_ILJitStackPushValue(jitCoder, result);
	}
}
Beispiel #7
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;
}
Beispiel #8
0
void emitIncrementPtr(jit_function_t function, jit_value_t ptr, ops *unit) {
    jit_value_t numbyte = jit_value_create_nint_constant(function, ubyte_ptr, unit->count);
    jit_value_t tmp = jit_insn_add(function, ptr, numbyte);
    jit_insn_store(function, ptr, tmp);
}
Beispiel #9
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;
}
Beispiel #10
0
jit_value jit_function::insn_add
	(const jit_value& value1, const jit_value& value2)
{
	value_wrap(jit_insn_add(func, value1.raw(), value2.raw()));
}
Beispiel #11
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
jit_value operator+(const jit_value& value1, const jit_value& value2)
{
	return jit_value(jit_insn_add(value_owner(value1, value2),
								  value1.raw(), value2.raw()));
}
Beispiel #14
0
// LIBJIT
void vm_cpu_4(uint32_t newPC,int opt, int size)
{
	int i;
	PC = newPC;
	nPC = 4;
	RF[0] = 0; //Register $zero must always be zero
	RF[31] = 1; //Return default (if the program does not set to zero, should put error)
	uint32_t HI = 0, LO = 0;  
	uint32_t offset = 4;
	uint8_t halted = 0;
	
	uint32_t instr;
	uint8_t op;
	uint8_t rs;
	uint8_t rt;
	uint8_t rd;
	int16_t immediate;
	uint32_t address;
	
	uint8_t shamt;
	uint8_t funct;
	
	uint64_t mult; 
	
	/*lib jit variables */
	
	jit_context_t context;
	jit_type_t signature;
        jit_function_t function;
	jit_type_t params[VM_MEMORY_SZ+2];
	jit_int result;
	
	jit_value_t constant_sum;
	jit_value_t constant_while;
	jit_value_t v_it;
	jit_value_t constant_update;
	jit_value_t compare;
	jit_value_t reg[32];		/* Reg */
	jit_value_t mem[VM_MEMORY_SZ];	/* Memory */
	jit_label_t labels[10]; /* Labs for jumping :D */
	jit_value_t sum, t_sum;
	void *args[VM_MEMORY_SZ+2];	/* Args */
	jit_int arg_uint[VM_MEMORY_SZ+2];

	/* 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);
	
	for(i=0; i<(VM_MEMORY_SZ+2); i++) {
	    params[i] = jit_type_int;
	}
		
	signature = jit_type_create_signature(jit_abi_cdecl, jit_type_int, params, VM_MEMORY_SZ+2, 1);
	
	/* Create the function object */
	function = jit_function_create(context, signature);
	jit_type_free(signature);
	
	// Read memory and start registers
	for(i=0; i<VM_MEMORY_SZ; i++) {
	  //printf("%d\n",i);
	  mem[i] = jit_value_get_param(function, i);
	}
	reg[0] = jit_value_get_param(function, VM_MEMORY_SZ);
	reg[31] = jit_value_get_param(function, VM_MEMORY_SZ+1);

	/*int verify = 0 - 1;
	for (i=1; i<VM_MEMORY_SZ; i++) {
	    if((i%2)==0) {
		verify = verify + (i);
	    }
	    else {
		verify = verify - i;
	    }
	}
	printf("verify %d\n", verify); */

	int l_index;
				
	// Only doing the micro benchmark, for analysis 
	// Addiu
#define loopSize 10000 
#define smallerLoopSize 1000
#define opPerLoop 100
	// v_it = 0 ; constant_while = loopSize ; constant_update = 1
	v_it = jit_value_create(function, jit_type_uint);
	constant_update = jit_value_create_nint_constant(function, jit_type_int, (int)0);
	jit_insn_store(function, v_it, constant_update);
	
	reg[2] = jit_value_create(function, jit_type_uint);
	constant_while = jit_value_create_nint_constant(function, jit_type_int, 0);
	jit_insn_store(function, reg[2], constant_while);
	reg[3] = jit_value_create(function, jit_type_uint);
	constant_while = jit_value_create_nint_constant(function, jit_type_int, 1);
	jit_insn_store(function, reg[3], constant_while);
	
	
	// do while (v_it < constant_while) {
	jit_insn_label(function, &labels[0]);
	
	if (opt == 0) {
	  constant_update = jit_insn_add(function, reg[2], reg[3]);
	}
	else if(opt == 1) {
	  constant_update = jit_insn_xor(function, reg[2], reg[3]);
	}
	else if(opt == 2) {
	  constant_update = jit_insn_load(function, mem[0]);
	}
	for (l_index = 1; l_index < opPerLoop; l_index++) {
	  if (opt == 0) {
	    constant_update = jit_insn_add(function, constant_update, reg[3]);
	  } 
	  else if(opt == 1) {
	    constant_update = jit_insn_xor(function, constant_update, reg[3]);
	  }
	  else if(opt == 2) {
	    constant_update = jit_insn_load(function, mem[l_index % 5]);
	  }
	}
	
	jit_insn_store(function, reg[2], constant_update);
	
	// do while
	constant_update = jit_value_create_nint_constant(function, jit_type_uint, 1);
	constant_sum = jit_insn_add(function, v_it, constant_update);
	jit_insn_store(function, v_it, constant_sum);
	
	if(size > 0) {
	  constant_while = jit_value_create_nint_constant(function, jit_type_uint, loopSize);
	}
	else {
	  constant_while = jit_value_create_nint_constant(function, jit_type_uint, smallerLoopSize);
	}
	compare = jit_insn_gt(function, constant_while, v_it);
	jit_insn_branch_if(function, compare, &labels[0]);
	
	
	// Return 
	//jit_insn_return(function, reg[2]);
	jit_insn_return(function, reg[2]);
	
	// START OF FINAL PART
	
	/* Compile the function */
	jit_function_compile(function);

	/* Unlock the context */
	jit_context_build_end(context);
	
	// Put memory and first registers
	for (i=0; i<VM_MEMORY_SZ; i++) {
	  arg_uint[i] = (int) VM_memory[i];
	  //arg_uint[i] = (int)i;
	  args[i] = &(arg_uint[i]);
	}
	arg_uint[VM_MEMORY_SZ] = 0;
	args[VM_MEMORY_SZ] = &(arg_uint[VM_MEMORY_SZ]);
	arg_uint[VM_MEMORY_SZ+1] = 1;
	args[VM_MEMORY_SZ+1] = &(arg_uint[VM_MEMORY_SZ+1]);
	
	jit_function_apply(function, args, &result);
	//printf("%d\n", result);
	
	return;
	
	/* end lib jit variables */
	
}