summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lightening/x86.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/lightening/x86.c b/lightening/x86.c
index 7b0c4a16c..ad0e8489c 100644
--- a/lightening/x86.c
+++ b/lightening/x86.c
@@ -701,6 +701,7 @@ struct abi_arg_iterator
size_t gpr_idx;
size_t fpr_idx;
size_t stack_size;
+ size_t stack_padding;
};
static size_t
@@ -770,6 +771,7 @@ next_abi_arg(struct abi_arg_iterator *iter, jit_operand_t *arg)
iter->arg_idx++;
}
+// Precondition: stack is already aligned.
static size_t
prepare_call_args(jit_state_t *_jit, size_t argc, jit_operand_t args[])
{
@@ -781,20 +783,25 @@ prepare_call_args(jit_state_t *_jit, size_t argc, jit_operand_t args[])
for (size_t i = 0; i < argc; i++)
next_abi_arg(&iter, &dst[i]);
+ size_t stack_size = iter.stack_size;
+
// Reserve space for spilled arguments, and fix up SP-relative
// operands.
- if (iter.stack_size)
+ if (stack_size)
{
- jit_subi(_jit, JIT_SP, JIT_SP, iter.stack_size);
+ // Align stack to 16-byte boundaries on 64-bit targets.
+ if (__WORDSIZE == 64)
+ stack_size = (stack_size + 15) & ~15;
+ jit_subi(_jit, JIT_SP, JIT_SP, stack_size);
for (size_t i = 0; i < argc; i++) {
switch(args[i].kind) {
case JIT_OPERAND_KIND_GPR:
if (jit_same_gprs (args[i].loc.mem.base, JIT_SP))
- args[i].loc.gpr.addend += iter.stack_size;
+ args[i].loc.gpr.addend += stack_size;
break;
case JIT_OPERAND_KIND_MEM:
if (jit_same_gprs (args[i].loc.mem.base, JIT_SP))
- args[i].loc.mem.offset += iter.stack_size;
+ args[i].loc.mem.offset += stack_size;
break;
default:
break;
@@ -804,7 +811,7 @@ prepare_call_args(jit_state_t *_jit, size_t argc, jit_operand_t args[])
jit_move_operands(_jit, dst, args, argc);
- return iter.stack_size;
+ return stack_size;
}
void