* x86-64-tdep.c (x86_64_push_arguments): Align stack to 16-byte
before the call. Set %rax only to number of SSE registers used.
This commit is contained in:
parent
772119ce53
commit
c1da67ba85
|
@ -597,13 +597,14 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
|
||||||
{
|
{
|
||||||
int intreg = 0;
|
int intreg = 0;
|
||||||
int ssereg = 0;
|
int ssereg = 0;
|
||||||
/* For varargs functions we have to pass the total number of SSE arguments
|
/* For varargs functions we have to pass the total number of SSE
|
||||||
in %rax. So, let's count this number. */
|
registers used in %rax. So, let's count this number. */
|
||||||
int total_sse_args = 0;
|
int total_sse_args = 0;
|
||||||
/* Once an SSE/int argument is passed on the stack, all subsequent
|
/* Once an SSE/int argument is passed on the stack, all subsequent
|
||||||
arguments are passed there. */
|
arguments are passed there. */
|
||||||
int sse_stack = 0;
|
int sse_stack = 0;
|
||||||
int int_stack = 0;
|
int int_stack = 0;
|
||||||
|
unsigned total_sp;
|
||||||
int i;
|
int i;
|
||||||
char buf[8];
|
char buf[8];
|
||||||
static int int_parameter_registers[INT_REGS] =
|
static int int_parameter_registers[INT_REGS] =
|
||||||
|
@ -644,7 +645,8 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
|
||||||
int_stack = 1;
|
int_stack = 1;
|
||||||
if (ssereg / 2 + needed_sseregs > SSE_REGS)
|
if (ssereg / 2 + needed_sseregs > SSE_REGS)
|
||||||
sse_stack = 1;
|
sse_stack = 1;
|
||||||
total_sse_args += needed_sseregs;
|
if (!sse_stack)
|
||||||
|
total_sse_args += needed_sseregs;
|
||||||
|
|
||||||
for (j = 0; j < n; j++)
|
for (j = 0; j < n; j++)
|
||||||
{
|
{
|
||||||
|
@ -720,13 +722,29 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We have to make sure that the stack is 16-byte aligned after the
|
||||||
|
setup. Let's calculate size of arguments first, align stack and
|
||||||
|
then fill in the arguments. */
|
||||||
|
total_sp = 0;
|
||||||
|
for (i = 0; i < stack_values_count; i++)
|
||||||
|
{
|
||||||
|
struct value *arg = args[stack_values[i]];
|
||||||
|
int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
|
||||||
|
total_sp += (len + 7) & ~7;
|
||||||
|
}
|
||||||
|
/* total_sp is now a multiple of 8, if it is not a multiple of 16,
|
||||||
|
change the stack pointer so that it will be afterwards correctly
|
||||||
|
aligned. */
|
||||||
|
if (total_sp & 15)
|
||||||
|
sp -= 8;
|
||||||
|
|
||||||
/* Push any remaining arguments onto the stack. */
|
/* Push any remaining arguments onto the stack. */
|
||||||
while (--stack_values_count >= 0)
|
while (--stack_values_count >= 0)
|
||||||
{
|
{
|
||||||
struct value *arg = args[stack_values[stack_values_count]];
|
struct value *arg = args[stack_values[stack_values_count]];
|
||||||
int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
|
int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
|
||||||
|
|
||||||
/* Make sure the stack stays eightbyte-aligned. */
|
/* Make sure the stack is 8-byte-aligned. */
|
||||||
sp -= (len + 7) & ~7;
|
sp -= (len + 7) & ~7;
|
||||||
write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
|
write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue