/*
 * Create the slots for the declared local variables.
 * Returns zero if out of memory.
 */
static int _ILJitLocalSlotsCreateLocals(ILJITCoder *jitCoder,
										ILJitLocalSlots *localSlots,
										ILStandAloneSig *localVarSig)
{
	if(localVarSig)
	{
		ILType *signature;
		ILType *type;
		ILJitType jitType;
		ILUInt32 num;
		ILUInt32 current;

		/* Determine the number of locals to allocate */
		if(!(signature = ILStandAloneSigGetType(localVarSig)))
		{
			return 0;
		}
		num = ILTypeNumLocals(signature);

		/* Allocate the "jitLocals" array for the variables */
		_ILJitLocalsAlloc(*localSlots, num);

		/* Create the jit values for the local variables */
		for(current = 0; current < num; ++current)
		{
			ILJitLocalSlot *local = &_ILJitLocalSlotFromSlots(*localSlots, current);

			if(!(type = ILTypeGetLocal(signature, current)))
			{
				return 0;
			}
			if(!(jitType = _ILJitGetLocalsType(type, jitCoder->process)))
			{
				return 0;
			}
			if(!(local->value = jit_value_create(jitCoder->jitFunction, jitType)))
			{
				return 0;
			}
			local->flags = 0;
			local->refValue = 0;
		}
		/* Record the number of used locals in the local slots. */
		localSlots->numSlots = num;
	}
	else
	{
		/* Set the number of used locals to 0. */
		localSlots->numSlots = 0;
	}
	return 1;
}
Example #2
0
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};
}
Example #3
0
/*@
 * @deftypefun jit_value_t jit_value_get_param (jit_function_t @var{func}, unsigned int @var{param})
 * Get the value that corresponds to a specified function parameter.
 * Returns NULL if out of memory or @var{param} is invalid.
 * @end deftypefun
@*/
jit_value_t
jit_value_get_param(jit_function_t func, unsigned int param)
{
	unsigned int num_params, current;

	/* Ensure that we have a builder for this function */
	if(!_jit_function_ensure_builder(func))
	{
		return 0;
	}

	/* Ensure valid param number. */
	jit_type_t signature = func->signature;
	num_params = jit_type_num_params(signature);
	if(param >= num_params)
	{
		return 0;
	}

	/* If we have already created the values, then exit immediately */
	jit_value_t *values = func->builder->param_values;
	if(values)
	{
		return values[param];
	}

	/* Create the values for the first time */
	values = (jit_value_t *) jit_calloc(num_params, sizeof(jit_value_t));
	if(!values)
	{
		return 0;
	}
	func->builder->param_values = values;
	for(current = 0; current < num_params; ++current)
	{
		jit_type_t type = jit_type_get_param(signature, current);
		values[current] = jit_value_create(func, type);
		if(values[current])
		{
			/* The value belongs to the entry block, no matter
			   where it happens to be created */
			values[current]->block = func->builder->entry_block;
			values[current]->is_parameter = 1;
		}
	}

	/* Return the value block for the desired parameter */
	return values[param];
}
Example #4
0
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};
}
/*
 * Create a new jit_value_t with the type of the existing jit_value_t in the
 * local slot and replace the existing one with the new one.
 * Clear the protect flag afterwards.
 */
static int _ILJitLocalSlotNewValue(ILJITCoder *jitCoder,
                                   ILJitLocalSlot *localSlot)
{
	ILJitType type;
	ILJitValue value;

	if(!(type = jit_value_get_type(localSlot->value)))
	{
		return 0;
	}
	if(!(value = jit_value_create(jitCoder->jitFunction, type)))
	{
		return 0;
	}
	localSlot->value = value;
	localSlot->refValue = 0;
	localSlot->flags &= ~_IL_JIT_VALUE_PROTECT;
	return 1;
}
Example #6
0
/*@
 * @deftypefun jit_value_t jit_value_get_struct_pointer (jit_function_t @var{func})
 * Get the value that contains the structure return pointer for
 * a function.  If the function does not have a structure return pointer
 * (i.e. structures are returned in registers), then this returns NULL.
 * @end deftypefun
@*/
jit_value_t
jit_value_get_struct_pointer(jit_function_t func)
{
	jit_type_t type;
	jit_value_t value;

	/* Ensure that we have a builder for this function */
	if(!_jit_function_ensure_builder(func))
	{
		return 0;
	}

	type = jit_type_remove_tags(jit_type_get_return(func->signature));
	if(jit_type_is_struct(type) || jit_type_is_union(type))
	{
		if(jit_type_return_via_pointer(type))
		{
			if(!func->builder->struct_return)
			{
				type = jit_type_create_pointer(type, 1);
				if(!type)
				{
					return 0;
				}
				value = jit_value_create(func, type);
				func->builder->struct_return = value;
				if(value)
				{
					/* The value belongs to the entry block, no matter
					   where it happens to be created */
					value->block = func->builder->entry_block;
					value->is_parameter = 1;
				}
				jit_type_free(type);
			}
			return func->builder->struct_return;
		}
	}
	return 0;
}
/*
 * Save the current jitStack status to the label.
 * This is done when the label is referenced the first time.
 */
static int _ILJitLabelSaveStack(ILJITCoder *coder, ILJITLabel *label)
{
	int coderStackHeight = _ILJitStackHeight(coder);
#ifdef	_IL_JIT_ENABLE_INLINE
	int coderStackBase;

	if(coder->currentInlineContext)
	{
		coderStackBase = coder->currentInlineContext->stackBase;
		coderStackHeight -= coderStackBase;
	}
	else
	{
		coderStackBase = 0;
	}
#else	/* !_IL_JIT_ENABLE_INLINE */
	int coderStackBase = 0;
#endif	/* !_IL_JIT_ENABLE_INLINE */

	if(((label->labelType & (_IL_JIT_LABEL_NORMAL |
							 _IL_JIT_LABEL_STARTCATCH)) != 0) &&
		(coderStackHeight > 0))
	{
		int current = 0;
		ILJitValue *stack = ILMemStackAllocItem(&(coder->stackStates),
									coderStackHeight * sizeof(ILJitValue));
		if(!stack)
		{
			return 0;
		}
		/* Now save the current stack state. */
		for(current = 0; current < coderStackHeight; current++)
		{
			ILJitStackItem *stackItem = _ILJitStackItemGet(coder, coderStackBase + current);

			stack[current] = _ILJitStackItemValue(*stackItem);
			if(jit_value_is_constant(_ILJitStackItemValue(*stackItem)))
			{
				/* We have to handle this case different. */
				/* Create a local value of the type of the constant. */
				ILJitValue temp = jit_value_create(coder->jitFunction,
												   jit_value_get_type(_ILJitStackItemValue(*stackItem)));
				/* and store the value of the constant in the new temporary. */
				jit_insn_store(coder->jitFunction, temp, _ILJitStackItemValue(*stackItem));
				/* Now replace the constant with the new temporary. */
				stack[current] = temp;
				_ILJitStackItemSetValue(*stackItem, temp);
			}
			else if(_ILJitStackItemNeedsDupOnLabel(*stackItem))
			{
				ILJitValue temp = jit_insn_dup(coder->jitFunction,
											   _ILJitStackItemValue(*stackItem));
				stack[current] = temp;
				_ILJitStackItemSetValue(*stackItem, temp);
			}
		}
		label->jitStack = stack;
		label->stackSize = coderStackHeight;
	}
	return 1;
}
Example #8
0
/*@
 * @deftypefun int _jit_create_call_setup_insns (jit_function_t @var{func}, jit_type_t @var{signature}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{is_nested}, int @var{nested_level}, jit_value_t *@var{struct_return}, int @var{flags})
 * Create instructions within @var{func} necessary to set up for a
 * function call to a function with the specified @var{signature}.
 * Use @code{jit_insn_push} to push values onto the system stack,
 * or @code{jit_insn_outgoing_reg} to copy values into call registers.
 *
 * If @var{is_nested} is non-zero, then it indicates that we are calling a
 * nested function within the current function's nested relationship tree.
 * The @var{nested_level} value will be -1 to call a child, zero to call a
 * sibling of @var{func}, 1 to call a sibling of the parent, 2 to call
 * a sibling of the grandparent, etc.  The @code{jit_insn_setup_for_nested}
 * instruction should be used to create the nested function setup code.
 *
 * If the function returns a structure by pointer, then @var{struct_return}
 * must be set to a new local variable that will contain the returned
 * structure.  Otherwise it should be set to NULL.
 * @end deftypefun
@*/
int _jit_create_call_setup_insns
	(jit_function_t func, jit_type_t signature,
	 jit_value_t *args, unsigned int num_args,
	 int is_nested, int nested_level, jit_value_t *struct_return, int flags)
{
	jit_type_t type;
	jit_type_t vtype;
	jit_value_t value;
	unsigned int arg_num;
	jit_nint offset;
	jit_nuint size;

	/* Regular or tail call? */
	if((flags & JIT_CALL_TAIL) == 0)
	{
		/* Push all of the arguments in reverse order */
		while(num_args > 0)
		{
			--num_args;
			type = jit_type_get_param(signature, num_args);
			type = jit_type_remove_tags(type);
			if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION)
			{
				/* If the value is a pointer, then we are pushing a structure
				   argument by pointer rather than by local variable */
				vtype = jit_type_normalize(jit_value_get_type(args[num_args]));
				if(vtype->kind <= JIT_TYPE_MAX_PRIMITIVE)
				{
					if(!jit_insn_push_ptr(func, args[num_args], type))
					{
						return 0;
					}
					continue;
				}
			}
			if(!jit_insn_push(func, args[num_args]))
			{
				return 0;
			}
		}

		/* Do we need to add a structure return pointer argument? */
		type = jit_type_get_return(signature);
		if(jit_type_return_via_pointer(type))
		{
			value = jit_value_create(func, type);
			if(!value)
			{
				return 0;
			}
			*struct_return = value;
			value = jit_insn_address_of(func, value);
			if(!value)
			{
				return 0;
			}
			if(!jit_insn_push(func, value))
			{
				return 0;
			}
		}
		else if((flags & JIT_CALL_NATIVE) != 0)
		{
			/* Native calls always return a return area pointer */
			if(!jit_insn_push_return_area_ptr(func))
			{
				return 0;
			}
			*struct_return = 0;
		}
		else
		{
			*struct_return = 0;
		}

		/* Do we need to add nested function scope information? */
		if(is_nested)
		{
			if(!jit_insn_setup_for_nested(func, nested_level, -1))
			{
				return 0;
			}
		}
	}
	else
	{
		/* Copy the arguments into our own parameter slots */
		offset = -1;
		if(func->nested_parent)
		{
			offset -= 2;
		}
		type = jit_type_get_return(signature);
		if(jit_type_return_via_pointer(type))
		{
			--offset;
		}
		for(arg_num = 0; arg_num < num_args; ++arg_num)
		{
			type = jit_type_get_param(signature, arg_num);
			value = jit_value_create(func, type);
			if(!value)
			{
				return 0;
			}
			if(!jit_insn_outgoing_frame_posn(func, value, offset))
			{
				return 0;
			}
			type = jit_type_remove_tags(type);
			size = jit_type_get_size(type);
			offset -= (jit_nint)(JIT_NUM_ITEMS_IN_STRUCT(size));
			if(type->kind == JIT_TYPE_STRUCT || type->kind == JIT_TYPE_UNION)
			{
				/* If the value is a pointer, then we are pushing a structure
				   argument by pointer rather than by local variable */
				vtype = jit_type_normalize(jit_value_get_type(args[arg_num]));
				if(vtype->kind <= JIT_TYPE_MAX_PRIMITIVE)
				{
					value = jit_insn_address_of(func, value);
					if(!value)
					{
						return 0;
					}
					if(!jit_insn_memcpy
							(func, value, args[arg_num],
							 jit_value_create_nint_constant
								(func, jit_type_nint, (jit_nint)size)))
					{
						return 0;
					}
					continue;
				}
			}
			if(!jit_insn_store(func, value, args[arg_num]))
			{
				return 0;
			}
		}
		*struct_return = 0;
	}

	/* The call is ready to proceed */
	return 1;
}
Example #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;
}
Example #10
0
/*@
 * @deftypemethod jit_function jit_value new_value (jit_type_t @var{type})
 * Create a new temporary value.  This is the C++ counterpart to
 * @code{jit_value_create}.
 * @end deftypemethod
@*/
jit_value jit_function::new_value(jit_type_t type)
{
	value_wrap(jit_value_create(func, type));
}
Example #11
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 #12
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 */
	
}