Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-insn.c view on Meta::CPAN
return 0;
}
}
*plast = last;
return insn;
}
/* Oops. This instruction modifies "value" and blocks
any previous address_of or add_relative instructions */
if((insn->flags & JIT_INSN_DEST_IS_VALUE) == 0)
{
break;
}
}
/* We are to check instructions that preceed the last one */
last = 0;
}
return 0;
}
/*@
* @deftypefun jit_value_t jit_insn_load_relative (jit_function_t @var{func}, jit_value_t @var{value}, jit_nint @var{offset}, jit_type_t @var{type})
* Load a value of the specified @var{type} from the effective address
* @code{(@var{value} + @var{offset})}, where @var{value} is a pointer.
* @end deftypefun
@*/
jit_value_t jit_insn_load_relative
(jit_function_t func, jit_value_t value,
jit_nint offset, jit_type_t type)
{
jit_insn_iter_t iter;
jit_insn_t insn;
int last;
if(!value)
{
return 0;
}
if(!_jit_function_ensure_builder(func))
{
return 0;
}
jit_insn_iter_init_last(&iter, func->builder->current_block);
insn = find_base_insn(func, iter, value, &last);
if(insn && insn->opcode == JIT_OP_ADD_RELATIVE)
{
/* We have a previous "add_relative" instruction for this
pointer. Adjust the current offset accordingly */
offset += jit_value_get_nint_constant(insn->value2);
value = insn->value1;
insn = find_base_insn(func, iter, value, &last);
last = 0;
}
if(insn && insn->opcode == JIT_OP_ADDRESS_OF && !last)
{
/* Shift the "address_of" instruction down, to make
it easier for the code generator to handle field
accesses within local and global variables */
value = jit_insn_address_of(func, insn->value1);
if(!value)
{
return 0;
}
}
return apply_binary
(func, _jit_load_opcode(JIT_OP_LOAD_RELATIVE_SBYTE, type, 0, 0), value,
jit_value_create_nint_constant(func, jit_type_nint, offset), type);
}
/*@
* @deftypefun int jit_insn_store_relative (jit_function_t @var{func}, jit_value_t @var{dest}, jit_nint @var{offset}, jit_value_t @var{value})
* Store @var{value} at the effective address @code{(@var{dest} + @var{offset})},
* where @var{dest} is a pointer.
* @end deftypefun
@*/
int jit_insn_store_relative
(jit_function_t func, jit_value_t dest,
jit_nint offset, jit_value_t value)
{
jit_insn_iter_t iter;
jit_insn_t insn;
int last;
jit_value_t offset_value;
if(!dest || !value)
{
return 0;
}
if(!_jit_function_ensure_builder(func))
{
return 0;
}
jit_insn_iter_init_last(&iter, func->builder->current_block);
insn = find_base_insn(func, iter, dest, &last);
if(insn && insn->opcode == JIT_OP_ADD_RELATIVE)
{
/* We have a previous "add_relative" instruction for this
pointer. Adjust the current offset accordingly */
offset += jit_value_get_nint_constant(insn->value2);
dest = insn->value1;
insn = find_base_insn(func, iter, value, &last);
last = 0;
}
if(insn && insn->opcode == JIT_OP_ADDRESS_OF && !last)
{
/* Shift the "address_of" instruction down, to make
it easier for the code generator to handle field
accesses within local and global variables */
dest = jit_insn_address_of(func, insn->value1);
if(!dest)
{
return 0;
}
}
offset_value = jit_value_create_nint_constant(func, jit_type_nint, offset);
if(!offset_value)
{
return 0;
}
insn = _jit_block_add_insn(func->builder->current_block);
if(!insn)
{
return 0;
}
jit_value_ref(func, dest);
jit_value_ref(func, value);
insn->opcode = (short)_jit_store_opcode(JIT_OP_STORE_RELATIVE_BYTE, 0, value->type);
insn->flags = JIT_INSN_DEST_IS_VALUE;
insn->dest = dest;
insn->value1 = value;
insn->value2 = offset_value;
return 1;
}
/*@
* @deftypefun jit_value_t jit_insn_add_relative (jit_function_t @var{func}, jit_value_t @var{value}, jit_nint @var{offset})
* Add the constant @var{offset} to the specified pointer @var{value}.
* This is functionally identical to calling @code{jit_insn_add}, but
* the JIT can optimize the code better if it knows that the addition
* is being used to perform a relative adjustment on a pointer.
* In particular, multiple relative adjustments on the same pointer
* can be collapsed into a single adjustment.
* @end deftypefun
@*/
jit_value_t jit_insn_add_relative
(jit_function_t func, jit_value_t value, jit_nint offset)
{
jit_insn_iter_t iter;
jit_insn_t insn;
int last;
if(!value)
{
return 0;
}
if(!_jit_function_ensure_builder(func))
{
return 0;
}
jit_insn_iter_init_last(&iter, func->builder->current_block);
insn = find_base_insn(func, iter, value, &last);
if(insn && insn->opcode == JIT_OP_ADD_RELATIVE)
{
/* We have a previous "add_relative" instruction for this
pointer. Adjust the current offset accordingly */
offset += jit_value_get_nint_constant(insn->value2);
( run in 0.477 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )