/*
 * 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);
}
示例#2
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;
}
示例#3
0
jit_value jit_function::insn_rem
	(const jit_value& value1, const jit_value& value2)
{
	value_wrap(jit_insn_rem(func, value1.raw(), value2.raw()));
}
示例#4
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;
}
示例#5
0
jit_value operator%(const jit_value& value1, const jit_value& value2)
{
	return jit_value(jit_insn_rem(value_owner(value1, value2),
								  value1.raw(), value2.raw()));
}