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, ¬_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 )