1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-26 13:10:22 +02:00

Merge branch 'callr-fix3' into 'main'

Fix some problems with callr and calli.

See merge request wingo/lightening!19
This commit is contained in:
Andy Wingo 2024-06-03 13:43:19 +00:00
commit 434fe2b4aa
7 changed files with 485 additions and 7 deletions

View file

@ -261,3 +261,9 @@ bless_function_pointer(void *ptr)
{
return ptr;
}
static jit_gpr_t
get_callr_temp (jit_state_t * _jit)
{
return _LR;
}

View file

@ -109,7 +109,7 @@ next_abi_arg(struct abi_arg_iterator *iter, jit_operand_t *arg)
}
}
*arg = jit_operand_mem (abi, JIT_SP, iter->stack_size);
iter->stack_size += 4;
iter->stack_size += 4 + (abi == JIT_OPERAND_ABI_DOUBLE ? 4 : 0);
}
static void
@ -137,3 +137,9 @@ bless_function_pointer(void *ptr)
// Set low bit to mark as thumb mode.
return (void*) (((uintptr_t)ptr) | 1);
}
static jit_gpr_t
get_callr_temp (jit_state_t * _jit)
{
return _LR;
}

View file

@ -124,6 +124,8 @@ static void reset_abi_arg_iterator(struct abi_arg_iterator *iter, size_t argc,
static void next_abi_arg(struct abi_arg_iterator *iter,
jit_operand_t *arg);
static jit_gpr_t get_callr_temp (jit_state_t * _jit);
jit_bool_t
init_jit(void)
{
@ -1096,6 +1098,15 @@ jit_move_operands(jit_state_t *_jit, jit_operand_t *dst, jit_operand_t *src,
enum move_status status[argc];
for (size_t i = 0; i < argc; i++)
status[i] = TO_MOVE;
// Mem-to-mem moves require a temp register but don't overwrite
// other argument registers. Perform them first to free up the tmp
// for other uses.
for (size_t i = 0; i < argc; i++)
if ((status[i] == TO_MOVE)
&& (MOVE_KIND (src[i].kind, dst[i].kind) == MOVE_MEM_TO_MEM))
move_one(_jit, dst, src, argc, status, i);
for (size_t i = 0; i < argc; i++)
if (status[i] == TO_MOVE)
move_one(_jit, dst, src, argc, status, i);
@ -1236,11 +1247,23 @@ jit_leave_jit_abi(jit_state_t *_jit, size_t v, size_t vf, size_t frame_size)
// Precondition: stack is already aligned.
static size_t
prepare_call_args(jit_state_t *_jit, size_t argc, jit_operand_t args[])
prepare_call_args(jit_state_t *_jit, size_t argc, jit_operand_t args[],
jit_gpr_t *fun)
{
jit_operand_t dst[argc];
size_t count = argc + (fun == NULL ? 0 : 1);
jit_operand_t src[count];
jit_operand_t dst[count];
memcpy (src, args, sizeof (jit_operand_t) * argc);
if (fun != NULL) {
jit_gpr_t fun_tmp = argc == 0 ? *fun : get_callr_temp (_jit);
src[argc] = jit_operand_gpr (JIT_OPERAND_ABI_POINTER, *fun);
dst[argc] = jit_operand_gpr (JIT_OPERAND_ABI_POINTER, fun_tmp);
*fun = fun_tmp;
}
struct abi_arg_iterator iter;
// Compute shuffle destinations and space for spilled arguments.
reset_abi_arg_iterator(&iter, argc, args);
for (size_t i = 0; i < argc; i++)
@ -1265,7 +1288,7 @@ prepare_call_args(jit_state_t *_jit, size_t argc, jit_operand_t args[])
}
}
jit_move_operands(_jit, dst, args, argc);
jit_move_operands(_jit, dst, src, count);
return stack_size;
}
@ -1273,7 +1296,7 @@ prepare_call_args(jit_state_t *_jit, size_t argc, jit_operand_t args[])
void
jit_calli(jit_state_t *_jit, jit_pointer_t f, size_t argc, jit_operand_t args[])
{
size_t stack_bytes = prepare_call_args(_jit, argc, args);
size_t stack_bytes = prepare_call_args(_jit, argc, args, NULL);
calli(_jit, (jit_word_t)f);
@ -1283,7 +1306,7 @@ jit_calli(jit_state_t *_jit, jit_pointer_t f, size_t argc, jit_operand_t args[])
void
jit_callr(jit_state_t *_jit, jit_gpr_t f, size_t argc, jit_operand_t args[])
{
size_t stack_bytes = prepare_call_args(_jit, argc, args);
size_t stack_bytes = prepare_call_args(_jit, argc, args, &f);
callr(_jit, jit_gpr_regno(f));

View file

@ -405,3 +405,9 @@ bless_function_pointer(void *ptr)
{
return ptr;
}
static jit_gpr_t
get_callr_temp (jit_state_t * _jit)
{
return _RAX;
}