Exemple #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;
	}
}
/*
 * 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;
}
jit_value jit_function::insn_ge
	(const jit_value& value1, const jit_value& value2)
{
	value_wrap(jit_insn_ge(func, value1.raw(), value2.raw()));
}
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;
}
Exemple #5
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;
}