libjit.git - libjit

index : libjit.git
libjit
summary refs log tree commit diff
path: root/jit/jit-insn.c
diff options
context:
space:
mode:
Diffstat (limited to 'jit/jit-insn.c')
-rw-r--r--jit/jit-insn.c 215
1 files changed, 206 insertions, 9 deletions
diff --git a/jit/jit-insn.c b/jit/jit-insn.c
index 6de9057..b12e48f 100644
--- a/jit/jit-insn.c
+++ b/jit/jit-insn.c
@@ -1096,9 +1096,8 @@ int jit_insn_label(jit_function_t func, jit_label_t *label)
if(last)
{
/* We will be entered via the top if the last block
- did not end in an unconditional branch and it
is not explicitly marked as "dead" */
- if(last->opcode != JIT_OP_BR && !(current->ends_in_dead))
+ if(!(current->ends_in_dead))
{
block->entered_via_top = 1;
}
@@ -3455,6 +3454,7 @@ int jit_insn_branch(jit_function_t func, jit_label_t *label)
insn->opcode = (short)JIT_OP_BR;
insn->flags = JIT_INSN_DEST_IS_LABEL;
insn->dest = (jit_value_t)(*label);
+ func->builder->current_block->ends_in_dead = 1;
block = _jit_block_create(func, 0);
if(!block)
{
@@ -5221,6 +5221,10 @@ jit_value_t jit_insn_call_native
insn->flags = JIT_INSN_DEST_IS_NATIVE | JIT_INSN_VALUE1_IS_NAME;
insn->dest = (jit_value_t)native_func;
insn->value1 = (jit_value_t)name;
+#ifdef JIT_BACKEND_INTERP
+ insn->flags |= JIT_INSN_VALUE2_IS_SIGNATURE;
+ insn->value2 = (jit_value_t)jit_type_copy(signature);
+#endif
/* If the function does not return, then end the current block.
The next block does not have "entered_via_top" set so that
@@ -5824,16 +5828,43 @@ int jit_insn_return(jit_function_t func, jit_value_t value)
case JIT_TYPE_UNION:
{
jit_value_t return_ptr = jit_value_get_struct_pointer(func);
+ jit_value_t value_addr;
if(return_ptr)
{
- /* Return the structure via the supplied pointer */
- /* TODO */
+ /* Copy the structure's contents to the supplied pointer */
+ value_addr = jit_insn_address_of(func, value);
+ if(!value_addr)
+ {
+ return 0;
+ }
+ if(!jit_insn_memcpy
+ (func, return_ptr, value_addr,
+ jit_value_create_nint_constant
+ (func, jit_type_nint,
+ (jit_nint)(jit_type_get_size(type)))))
+ {
+ return 0;
+ }
+
+ /* Output a regular return for the function */
+ if(!create_noarg_note(func, JIT_OP_RETURN))
+ {
+ return 0;
+ }
}
else
{
/* Return the structure via registers */
- if(!create_unary_note
- (func, JIT_OP_RETURN_SMALL_STRUCT, value))
+ value_addr = jit_insn_address_of(func, value);
+ if(!value_addr)
+ {
+ return 0;
+ }
+ if(!create_note
+ (func, JIT_OP_RETURN_SMALL_STRUCT, value_addr,
+ jit_value_create_nint_constant
+ (func, jit_type_nint,
+ (jit_nint)(jit_type_get_size(type)))))
{
break;
}
@@ -5847,7 +5878,107 @@ int jit_insn_return(jit_function_t func, jit_value_t value)
func->builder->current_block->ends_in_dead = 1;
/* Start a new block just after the "return" instruction */
- return jit_insn_label(func, 0);
+ if(!_jit_block_create(func, 0))
+ {
+ return 0;
+ }
+ return 1;
+}
+
+/*@
+ * @deftypefun int jit_insn_return_ptr (jit_function_t func, jit_value_t value, jit_type_t type)
+ * Output an instruction to return @code{*value} as the function's result.
+ * This is normally used for returning @code{struct} and @code{union}
+ * values where you have the effective address of the structure, rather
+ * than the structure's contents, in @code{value}.
+ * @end deftypefun
+@*/
+int jit_insn_return_ptr
+ (jit_function_t func, jit_value_t value, jit_type_t type)
+{
+ jit_value_t return_ptr;
+
+ /* Ensure that we have a builder for this function */
+ if(!_jit_function_ensure_builder(func))
+ {
+ return 0;
+ }
+
+ /* This function has an ordinary return path */
+ func->builder->ordinary_return = 1;
+
+ /* Convert the value into a pointer */
+ value = jit_insn_convert(func, value, jit_type_void_ptr, 0);
+ if(!value)
+ {
+ return 0;
+ }
+
+ /* Determine how to return the value, based on the pointed-to type */
+ switch(jit_type_normalize(type)->kind)
+ {
+ case JIT_TYPE_STRUCT:
+ case JIT_TYPE_UNION:
+ {
+ /* Handle "finally" clauses if necessary */
+ if(!handle_finally(func, JIT_OP_PREPARE_FOR_RETURN))
+ {
+ return 0;
+ }
+
+ /* Determine the kind of structure return to use */
+ return_ptr = jit_value_get_struct_pointer(func);
+ if(return_ptr)
+ {
+ /* Copy the structure's contents to the supplied pointer */
+ if(!jit_insn_memcpy
+ (func, return_ptr, value,
+ jit_value_create_nint_constant
+ (func, jit_type_nint,
+ (jit_nint)(jit_type_get_size(type)))))
+ {
+ return 0;
+ }
+
+ /* Output a regular return for the function */
+ if(!create_noarg_note(func, JIT_OP_RETURN))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ /* Return the structure via registers */
+ if(!create_note
+ (func, JIT_OP_RETURN_SMALL_STRUCT, value,
+ jit_value_create_nint_constant
+ (func, jit_type_nint,
+ (jit_nint)(jit_type_get_size(type)))))
+ {
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ /* Everything else uses the normal return logic */
+ return jit_insn_return
+ (func, jit_insn_load_relative(func, value, 0, type));
+ }
+ /* Not reached */
+ }
+
+ /* Mark the current block as "ends in dead" */
+ func->builder->current_block->ends_in_dead = 1;
+
+ /* Start a new block just after the "return" instruction */
+ if(!_jit_block_create(func, 0))
+ {
+ return 0;
+ }
+ return 1;
}
/*@
@@ -5884,9 +6015,9 @@ int jit_insn_default_return(jit_function_t func)
last = _jit_block_get_last(current);
if(last)
{
- if(last->opcode == JIT_OP_BR)
+ if(current->ends_in_dead)
{
- /* This block ends in an unconditional branch */
+ /* This block ends in an unconditional branch, return, etc */
return 2;
}
}
@@ -6374,6 +6505,72 @@ int jit_insn_memset
}
/*@
+ * @deftypefun int jit_insn_move_blocks (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
+ * Move all of the blocks between @code{from_label} (inclusive) and
+ * @code{to_label} (exclusive) to the end of the current function.
+ * This is typically used to move the expression in a @code{while}
+ * loop to the end of the body, where it can be executed more
+ * efficiently.
+ * @end deftypefun
+@*/
+int jit_insn_move_blocks
+ (jit_function_t func, jit_label_t from_label, jit_label_t to_label)
+{
+ jit_block_t first_block;
+ jit_block_t block;
+ jit_block_t next;
+
+ /* Find the first block that needs to be moved */
+ first_block = jit_block_from_label(func, from_label);
+ if(!first_block)
+ {
+ return 0;
+ }
+
+ /* Keep moving blocks until we come across "to_label" */
+ block = first_block;
+ while(block != 0 && block->label != to_label)
+ {
+ next = block->next;
+ if(block->next != 0)
+ {
+ block->next->prev = block->prev;
+ }
+ else
+ {
+ func->builder->last_block = block->prev;
+ }
+ if(block->prev != 0)
+ {
+ block->prev->next = block->next;
+ }
+ else
+ {
+ func->builder->first_block = block->next;
+ }
+ block->next = 0;
+ block->prev = func->builder->last_block;
+ if(func->builder->last_block)
+ {
+ func->builder->last_block->next = block;
+ }
+ else
+ {
+ func->builder->first_block = block;
+ }
+ func->builder->last_block = block;
+ block = next;
+ }
+ func->builder->current_block = func->builder->last_block;
+
+ /* The first block will be entered via its top now */
+ first_block->entered_via_top = 1;
+
+ /* Create a new block after the last one we moved, to start fresh */
+ return jit_insn_label(func, 0);
+}
+
+/*@
* @deftypefun void jit_insn_iter_init ({jit_insn_iter_t *} iter, jit_block_t block)
* Initialize an iterator to point to the first instruction in @code{block}.
* @end deftypefun
generated by cgit v1.2.3 (git 2.39.1) at 2025年09月25日 09:24:46 +0000

AltStyle によって変換されたページ (->オリジナル) /