예제 #1
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};
}
예제 #2
0
파일: bf-jit.c 프로젝트: sankha93/bf-jit
void loop_stop(jit_function_t function, bf_loop_t *loop) {
    bf_loop_t curloop = *loop;
    if (curloop == NULL) return;
    jit_insn_branch(function, &curloop->start);
    jit_insn_label(function, &curloop->stop);
    *loop = curloop->parent;
}
예제 #3
0
void jit_function::insn_branch(jit_label& label)
{
	if(!jit_insn_branch(func, label.rawp()))
	{
		out_of_memory();
	}
}
예제 #4
0
파일: If.cpp 프로젝트: antigol/LeekScript
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};
}
예제 #5
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;
	}

}
예제 #6
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;
}
예제 #7
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;
}