aboutsummaryrefslogtreecommitdiff
path: root/gdb/mips-tdep.c
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2007-04-17 14:48:49 +0000
committerMaciej W. Rozycki <macro@linux-mips.org>2007-04-17 14:48:49 +0000
commit968b53918b58e35bc65bcd8bf4436d77380db2c0 (patch)
tree1833b0a542c949b77a0a57351fad341fc8d74934 /gdb/mips-tdep.c
parent5750dcecf6a09f90007d130f93da4bca48b2ce48 (diff)
downloadgdb-968b53918b58e35bc65bcd8bf4436d77380db2c0.zip
gdb-968b53918b58e35bc65bcd8bf4436d77380db2c0.tar.gz
gdb-968b53918b58e35bc65bcd8bf4436d77380db2c0.tar.bz2
* mips-tdep.c (mips_o32_push_dummy_call): Take account of
argument alignment requirements when calculating stack space required. When aligning an arg register to eight bytes boundary, align stack_offset too. Write floating-point arguments to the appropriate integer register if need go there. (mips_o64_push_dummy_call): Likewise.
Diffstat (limited to 'gdb/mips-tdep.c')
-rw-r--r--gdb/mips-tdep.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index e31610b..5551839 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -3064,8 +3064,17 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* Now make space on the stack for the args. */
for (argnum = 0; argnum < nargs; argnum++)
- len += align_up (TYPE_LENGTH (value_type (args[argnum])),
- mips_stack_argsize (gdbarch));
+ {
+ struct type *arg_type = check_typedef (value_type (args[argnum]));
+ int arglen = TYPE_LENGTH (arg_type);
+
+ /* Align to double-word if necessary. */
+ if (mips_abi_regsize (gdbarch) < 8
+ && mips_type_needs_double_align (arg_type))
+ len = align_up (len, mips_stack_argsize (gdbarch) * 2);
+ /* Allocate space on the stack. */
+ len += align_up (arglen, mips_stack_argsize (gdbarch));
+ }
sp -= align_up (len, 16);
if (mips_debug)
@@ -3201,10 +3210,11 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
&& mips_type_needs_double_align (arg_type))
{
if ((argreg & 1))
- argreg++;
+ {
+ argreg++;
+ stack_offset += mips_abi_regsize (gdbarch);
+ }
}
- /* Note: Floating-point values that didn't fit into an FP
- register are only written to memory. */
while (len > 0)
{
/* Remember if the argument was written to the stack. */
@@ -3218,8 +3228,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* Write this portion of the argument to the stack. */
if (argreg > MIPS_LAST_ARG_REGNUM
- || odd_sized_struct
- || fp_register_arg_p (typecode, arg_type))
+ || odd_sized_struct)
{
/* Should shorter than int integer values be
promoted to int before being stored? */
@@ -3260,12 +3269,10 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
}
/* Note!!! This is NOT an else clause. Odd sized
- structs may go thru BOTH paths. Floating point
- arguments will not. */
+ structs may go thru BOTH paths. */
/* Write this portion of the argument to a general
purpose register. */
- if (argreg <= MIPS_LAST_ARG_REGNUM
- && !fp_register_arg_p (typecode, arg_type))
+ if (argreg <= MIPS_LAST_ARG_REGNUM)
{
LONGEST regval = extract_signed_integer (val, partial_len);
/* Value may need to be sign extended, because
@@ -3518,8 +3525,17 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* Now make space on the stack for the args. */
for (argnum = 0; argnum < nargs; argnum++)
- len += align_up (TYPE_LENGTH (value_type (args[argnum])),
- mips_stack_argsize (gdbarch));
+ {
+ struct type *arg_type = check_typedef (value_type (args[argnum]));
+ int arglen = TYPE_LENGTH (arg_type);
+
+ /* Align to double-word if necessary. */
+ if (mips_abi_regsize (gdbarch) < 8
+ && mips_type_needs_double_align (arg_type))
+ len = align_up (len, mips_stack_argsize (gdbarch) * 2);
+ /* Allocate space on the stack. */
+ len += align_up (arglen, mips_stack_argsize (gdbarch));
+ }
sp -= align_up (len, 16);
if (mips_debug)
@@ -3655,10 +3671,11 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
&& mips_type_needs_double_align (arg_type))
{
if ((argreg & 1))
- argreg++;
+ {
+ argreg++;
+ stack_offset += mips_abi_regsize (gdbarch);
+ }
}
- /* Note: Floating-point values that didn't fit into an FP
- register are only written to memory. */
while (len > 0)
{
/* Remember if the argument was written to the stack. */
@@ -3672,8 +3689,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* Write this portion of the argument to the stack. */
if (argreg > MIPS_LAST_ARG_REGNUM
- || odd_sized_struct
- || fp_register_arg_p (typecode, arg_type))
+ || odd_sized_struct)
{
/* Should shorter than int integer values be
promoted to int before being stored? */
@@ -3714,12 +3730,10 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
}
/* Note!!! This is NOT an else clause. Odd sized
- structs may go thru BOTH paths. Floating point
- arguments will not. */
+ structs may go thru BOTH paths. */
/* Write this portion of the argument to a general
purpose register. */
- if (argreg <= MIPS_LAST_ARG_REGNUM
- && !fp_register_arg_p (typecode, arg_type))
+ if (argreg <= MIPS_LAST_ARG_REGNUM)
{
LONGEST regval = extract_signed_integer (val, partial_len);
/* Value may need to be sign extended, because