Alien-LibJIT

 view release on metacpan or  search on metacpan

libjit/jit/jit-insn.c  view on Meta::CPAN

}

/*@
 * @deftypefun jit_value_t jit_insn_or (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2})
 * Bitwise OR two values and return the result in a new temporary value.
 * @end deftypefun
@*/
jit_value_t jit_insn_or
		(jit_function_t func, jit_value_t value1, jit_value_t value2)
{
	static jit_opcode_descr const or_descr = {
		JIT_OP_IOR,
		JIT_OP_IOR,
		JIT_OP_LOR,
		JIT_OP_LOR,
		0, 0, 0,
		jit_intrinsic(jit_int_or, descr_i_ii),
		jit_intrinsic(jit_uint_or, descr_I_II),
		jit_intrinsic(jit_long_or, descr_l_ll),
		jit_intrinsic(jit_ulong_or, descr_L_LL),
		jit_no_intrinsic,
		jit_no_intrinsic,
		jit_no_intrinsic
	};
	return apply_arith(func, &or_descr, value1, value2, 1, 0, 0);
}

/*@
 * @deftypefun jit_value_t jit_insn_xor (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2})
 * Bitwise XOR two values and return the result in a new temporary value.
 * @end deftypefun
@*/
jit_value_t jit_insn_xor
		(jit_function_t func, jit_value_t value1, jit_value_t value2)
{
	static jit_opcode_descr const xor_descr = {
		JIT_OP_IXOR,
		JIT_OP_IXOR,
		JIT_OP_LXOR,
		JIT_OP_LXOR,
		0, 0, 0,
		jit_intrinsic(jit_int_xor, descr_i_ii),
		jit_intrinsic(jit_uint_xor, descr_I_II),
		jit_intrinsic(jit_long_xor, descr_l_ll),
		jit_intrinsic(jit_ulong_xor, descr_L_LL),
		jit_no_intrinsic,
		jit_no_intrinsic,
		jit_no_intrinsic
	};
	return apply_arith(func, &xor_descr, value1, value2, 1, 0, 0);
}

/*@
 * @deftypefun jit_value_t jit_insn_not (jit_function_t @var{func}, jit_value_t @var{value1})
 * Bitwise NOT a value and return the result in a new temporary value.
 * @end deftypefun
@*/
jit_value_t jit_insn_not
		(jit_function_t func, jit_value_t value1)
{
	static jit_opcode_descr const not_descr = {
		JIT_OP_INOT,
		JIT_OP_INOT,
		JIT_OP_LNOT,
		JIT_OP_LNOT,
		0, 0, 0,
		jit_intrinsic(jit_int_not, descr_i_i),
		jit_intrinsic(jit_uint_not, descr_I_I),
		jit_intrinsic(jit_long_not, descr_l_l),
		jit_intrinsic(jit_ulong_not, descr_L_L),
		jit_no_intrinsic,
		jit_no_intrinsic,
		jit_no_intrinsic
	};
	return apply_unary_arith(func, &not_descr, value1, 1, 0, 0);
}

/*@
 * @deftypefun jit_value_t jit_insn_shl (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2})
 * Perform a bitwise left shift on two values and return the
 * result in a new temporary value.
 * @end deftypefun
@*/
jit_value_t jit_insn_shl
		(jit_function_t func, jit_value_t value1, jit_value_t value2)
{
	static jit_opcode_descr const shl_descr = {
		JIT_OP_ISHL,
		JIT_OP_ISHL,
		JIT_OP_LSHL,
		JIT_OP_LSHL,
		0, 0, 0,
		jit_intrinsic(jit_int_shl, descr_i_iI),
		jit_intrinsic(jit_uint_shl, descr_I_II),
		jit_intrinsic(jit_long_shl, descr_l_lI),
		jit_intrinsic(jit_ulong_shl, descr_L_LI),
		jit_no_intrinsic,
		jit_no_intrinsic,
		jit_no_intrinsic
	};
	return apply_shift(func, &shl_descr, value1, value2);
}

/*@
 * @deftypefun jit_value_t jit_insn_shr (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2})
 * Perform a bitwise right shift on two values and return the
 * result in a new temporary value.  This performs a signed shift
 * on signed operators, and an unsigned shift on unsigned operands.
 * @end deftypefun
@*/
jit_value_t jit_insn_shr
		(jit_function_t func, jit_value_t value1, jit_value_t value2)
{
	static jit_opcode_descr const shr_descr = {
		JIT_OP_ISHR,
		JIT_OP_ISHR_UN,
		JIT_OP_LSHR,
		JIT_OP_LSHR_UN,
		0, 0, 0,
		jit_intrinsic(jit_int_shr, descr_i_iI),
		jit_intrinsic(jit_uint_shr, descr_I_II),
		jit_intrinsic(jit_long_shr, descr_l_lI),
		jit_intrinsic(jit_ulong_shr, descr_L_LI),
		jit_no_intrinsic,
		jit_no_intrinsic,
		jit_no_intrinsic
	};
	return apply_shift(func, &shr_descr, value1, value2);
}

/*@
 * @deftypefun jit_value_t jit_insn_ushr (jit_function_t @var{func}, jit_value_t @var{value1}, jit_value_t @var{value2})
 * Perform a bitwise right shift on two values and return the
 * result in a new temporary value.  This performs an unsigned
 * shift on both signed and unsigned operands.

libjit/jit/jit-insn.c  view on Meta::CPAN

		return 0;
	}

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

	/* If the previous instruction was a comparison, then there is
	   nothing that we need to do to make the value boolean */
	block = func->builder->current_block;
	last = _jit_block_get_last(block);
	if(value1->is_temporary && last && last->dest == value1)
	{
		opcode = last->opcode;
		if(opcode >= JIT_OP_IEQ && opcode <= JIT_OP_NFGE_INV)
		{
			return value1;
		}
	}

	/* Perform a comparison to determine if the value is non-zero */
	type = jit_type_promote_int(jit_type_normalize(value1->type));
	if(type == jit_type_int || type == jit_type_uint)
	{
		return jit_insn_ne
			(func, value1,
			 jit_value_create_nint_constant(func, jit_type_int, 0));
	}
	else if(type == jit_type_long || type == jit_type_ulong)
	{
		return jit_insn_ne
			(func, value1,
			 jit_value_create_long_constant(func, jit_type_long, 0));
	}
	else if(type == jit_type_float32)
	{
		return jit_insn_ne
			(func, value1,
			 jit_value_create_float32_constant
			 	(func, jit_type_float32, (jit_float32)0.0));
	}
	else if(type == jit_type_float64)
	{
		return jit_insn_ne
			(func, value1,
			 jit_value_create_float64_constant
			 	(func, jit_type_float64, (jit_float64)0.0));
	}
	else
	{
		return jit_insn_ne
			(func, value1,
			 jit_value_create_nfloat_constant
			 	(func, jit_type_nfloat, (jit_nfloat)0.0));
	}
}

/*@
 * @deftypefun jit_value_t jit_insn_to_not_bool (jit_function_t @var{func}, jit_value_t @var{value1})
 * Convert a value into a boolean 1 or 0 result of type @code{jit_type_int}
 * (i.e. the inverse of @code{jit_insn_to_bool}).
 * @end deftypefun
@*/
jit_value_t jit_insn_to_not_bool(jit_function_t func, jit_value_t value1)
{
	jit_type_t type;
	jit_block_t block;
	jit_insn_t last;
	int opcode;

	/* Bail out if the parameters are invalid */
	if(!value1)
	{
		return 0;
	}

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

	/* If the previous instruction was a comparison, then all
	   we have to do is invert the comparison opcode */
	block = func->builder->current_block;
	last = _jit_block_get_last(block);
	if(value1->is_temporary && last && last->dest == value1)
	{
		opcode = last->opcode;
		if(opcode >= JIT_OP_IEQ && opcode <= JIT_OP_NFGE_INV)
		{
			switch(opcode)
			{
				case JIT_OP_IEQ:		opcode = JIT_OP_INE;      break;
				case JIT_OP_INE:		opcode = JIT_OP_IEQ;      break;
				case JIT_OP_ILT:		opcode = JIT_OP_IGE;      break;
				case JIT_OP_ILT_UN:		opcode = JIT_OP_IGE_UN;   break;
				case JIT_OP_ILE:		opcode = JIT_OP_IGT;      break;
				case JIT_OP_ILE_UN:		opcode = JIT_OP_IGT_UN;   break;
				case JIT_OP_IGT:		opcode = JIT_OP_ILE;      break;
				case JIT_OP_IGT_UN:		opcode = JIT_OP_ILE_UN;   break;
				case JIT_OP_IGE:		opcode = JIT_OP_ILT;      break;
				case JIT_OP_IGE_UN:		opcode = JIT_OP_ILT_UN;   break;
				case JIT_OP_LEQ:		opcode = JIT_OP_LNE;      break;
				case JIT_OP_LNE:		opcode = JIT_OP_LEQ;      break;
				case JIT_OP_LLT:		opcode = JIT_OP_LGE;      break;
				case JIT_OP_LLT_UN:		opcode = JIT_OP_LGE_UN;   break;
				case JIT_OP_LLE:		opcode = JIT_OP_LGT;      break;
				case JIT_OP_LLE_UN:		opcode = JIT_OP_LGT_UN;   break;
				case JIT_OP_LGT:		opcode = JIT_OP_LLE;      break;
				case JIT_OP_LGT_UN:		opcode = JIT_OP_LLE_UN;   break;
				case JIT_OP_LGE:		opcode = JIT_OP_LLT;      break;
				case JIT_OP_LGE_UN:		opcode = JIT_OP_LLT_UN;   break;
				case JIT_OP_FEQ:		opcode = JIT_OP_FNE;      break;
				case JIT_OP_FNE:		opcode = JIT_OP_FEQ;      break;
				case JIT_OP_FLT:		opcode = JIT_OP_FGE_INV;  break;
				case JIT_OP_FLE:		opcode = JIT_OP_FGT_INV;  break;
				case JIT_OP_FGT:		opcode = JIT_OP_FLE_INV;  break;
				case JIT_OP_FGE:		opcode = JIT_OP_FLT_INV;  break;
				case JIT_OP_FLT_INV:	opcode = JIT_OP_FGE;      break;
				case JIT_OP_FLE_INV:	opcode = JIT_OP_FGT;      break;
				case JIT_OP_FGT_INV:	opcode = JIT_OP_FLE;      break;
				case JIT_OP_FGE_INV:	opcode = JIT_OP_FLT;      break;
				case JIT_OP_DEQ:		opcode = JIT_OP_DNE;      break;

libjit/jit/jit-insn.c  view on Meta::CPAN

		return 1;
	}
	func->has_try = 1;
	func->builder->may_throw = 1;
	func->builder->non_leaf = 1;
	return initialize_setjmp_block(func);
}

/*@
 * @deftypefun jit_value_t jit_insn_start_catcher (jit_function_t @var{func})
 * Start the catcher block for @var{func}.  There should be exactly one
 * catcher block for any function that involves a @code{try}.  All
 * exceptions that are thrown within the function will cause control
 * to jump to this point.  Returns a value that holds the exception
 * that was thrown.
 * @end deftypefun
@*/
jit_value_t jit_insn_start_catcher(jit_function_t func)
{
	jit_value_t value;
#if !defined(JIT_BACKEND_INTERP)
	jit_value_t last_exception;
	jit_type_t type;
#endif
	if(!_jit_function_ensure_builder(func))
	{
		return 0;
	}
	if(!jit_insn_label(func, &(func->builder->catcher_label)))
	{
		return 0;
	}
	value = jit_insn_thrown_exception(func);
	if(!value)
	{
		return 0;
	}
#if defined(JIT_BACKEND_INTERP)
	/* In the interpreter, the exception object will be on the top of
	   the operand stack when control reaches the catcher */
	if(!jit_insn_incoming_reg(func, value, 0))
	{
		return 0;
	}
#else
	type = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, 0, 0, 1);
	if(!type)
	{
		return 0;
	}
	last_exception = jit_insn_call_native(
		func, "jit_exception_get_last",
		(void *)jit_exception_get_last, type, 0, 0, JIT_CALL_NOTHROW);
	jit_insn_store(func, value, last_exception);
	jit_type_free(type);
#endif
	return value;
}

/*@
 * @deftypefun int jit_insn_branch_if_pc_not_in_range (jit_function_t @var{func}, jit_label_t @var{start_label}, jit_label_t @var{end_label}, jit_label_t *@var{label})
 * Branch to @var{label} if the program counter where an exception occurred
 * does not fall between @var{start_label} and @var{end_label}.
 * @end deftypefun
@*/
int jit_insn_branch_if_pc_not_in_range
	(jit_function_t func, jit_label_t start_label,
	 jit_label_t end_label, jit_label_t *label)
{
	jit_value_t value1;
	jit_value_t value2;

	/* Ensure that we have a function builder and a try block */
	if(!_jit_function_ensure_builder(func))
	{
		return 0;
	}
	if(!(func->has_try))
	{
		return 0;
	}

	/* Flush any stack pops that were deferred previously */
	if(!jit_insn_flush_defer_pop(func, 0))
	{
		return 0;
	}

	/* Get the location where the exception occurred in this function */
#if defined(JIT_BACKEND_INTERP)
	value1 = create_dest_note
		(func, JIT_OP_LOAD_EXCEPTION_PC, jit_type_void_ptr);
#else
	value1 = func->builder->thrown_pc;
#endif
	if(!value1)
	{
		return 0;
	}

	/* Compare the location against the start and end labels */
	value2 = jit_insn_address_of_label(func, &start_label);
	if(!value2)
	{
		return 0;
	}
	if(!jit_insn_branch_if(func, jit_insn_lt(func, value1, value2), label))
	{
		return 0;
	}
	value2 = jit_insn_address_of_label(func, &end_label);
	if(!value2)
	{
		return 0;
	}
	if(!jit_insn_branch_if(func, jit_insn_ge(func, value1, value2), label))
	{
		return 0;
	}

	/* If control gets here, then we have a location match */
	return 1;
}

/*@
 * @deftypefun int jit_insn_rethrow_unhandled (jit_function_t @var{func})



( run in 0.471 second using v1.01-cache-2.11-cpan-63c85eba8c4 )