aboutsummaryrefslogtreecommitdiff
path: root/gdb/mips-tdep.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2001-07-12 17:34:33 +0000
committerDaniel Jacobowitz <drow@false.org>2001-07-12 17:34:33 +0000
commit49e790b035044a3a9916a34b478fcf273345a81e (patch)
tree28f5c47bd34fe8fcdcbf3146f45919e03b7023d7 /gdb/mips-tdep.c
parente7df82123202fd32525961ec05437102f0270308 (diff)
downloadgdb-49e790b035044a3a9916a34b478fcf273345a81e.zip
gdb-49e790b035044a3a9916a34b478fcf273345a81e.tar.gz
gdb-49e790b035044a3a9916a34b478fcf273345a81e.tar.bz2
* mips-tdep.c (mips_type_needs_double_align): New function.
(mips_push_arguments): Align o32 structs to even argument registers if necessary.
Diffstat (limited to 'gdb/mips-tdep.c')
-rw-r--r--gdb/mips-tdep.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index f723e46..8750d28 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -2126,6 +2126,35 @@ fp_register_arg_p (enum type_code typecode, struct type *arg_type)
&& MIPS_FPU_TYPE != MIPS_FPU_NONE);
}
+/* On o32, argument passing in GPRs depends on the alignment of the type being
+ passed. Return 1 if this type must be aligned to a doubleword boundary. */
+
+static int
+mips_type_needs_double_align (struct type *type)
+{
+ enum type_code typecode = TYPE_CODE (type);
+
+ if (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)
+ return 1;
+ else if (typecode == TYPE_CODE_STRUCT)
+ {
+ if (TYPE_NFIELDS (type) < 1)
+ return 0;
+ return mips_type_needs_double_align (TYPE_FIELD_TYPE (type, 0));
+ }
+ else if (typecode == TYPE_CODE_UNION)
+ {
+ int i, n;
+
+ n = TYPE_NFIELDS (type);
+ for (i = 0; i < n; i++)
+ if (mips_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
+ return 1;
+ return 0;
+ }
+ return 0;
+}
+
CORE_ADDR
mips_push_arguments (int nargs,
value_ptr *args,
@@ -2312,6 +2341,14 @@ mips_push_arguments (int nargs,
compatibility, we will put them in both places. */
int odd_sized_struct = ((len > MIPS_SAVED_REGSIZE) &&
(len % MIPS_SAVED_REGSIZE != 0));
+ /* Structures should be aligned to eight bytes (even arg registers)
+ on MIPS_ABI_O32 if their first member has double precision. */
+ if (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_O32
+ && mips_type_needs_double_align (arg_type))
+ {
+ if ((argreg & 1))
+ argreg++;
+ }
/* Note: Floating-point values that didn't fit into an FP
register are only written to memory. */
while (len > 0)