diff options
author | Andrew Cagney <cagney@redhat.com> | 2000-06-23 07:44:00 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2000-06-23 07:44:00 +0000 |
commit | f09ded24229f68245da53149e1ac46a8066057cd (patch) | |
tree | 156cba54aedc61f23eaa4883f71b3030e9e06e4b | |
parent | 70d6ecf3bf23fe901a2e52e645e200e4f49c3006 (diff) | |
download | ppe42-binutils-f09ded24229f68245da53149e1ac46a8066057cd.tar.gz ppe42-binutils-f09ded24229f68245da53149e1ac46a8066057cd.zip |
When FP registers are full, store FP arguments on stack and not in
integer registers.
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/mips-tdep.c | 41 |
2 files changed, 35 insertions, 12 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c00074329c..6338d11196 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +Fri Jun 23 16:20:21 2000 Andrew Cagney <cagney@b1.cygnus.com> + + * mips-tdep.c (fp_register_arg_p): New function. + (mips_push_arguments): Use. Do not pass floating point arguments + on in an integer register. + 2000-06-21 Pierre Muller <muller@ics.u-strasbg.fr> * symfile.c (init_filename_language_table): add ".pas", ".p" and ".pp" as pascal source file extensions. diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 0922ceed2c..6ba42a281c 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -2062,6 +2062,23 @@ setup_arbitrary_frame (argc, argv) return create_new_frame (argv[0], argv[1]); } +/* According to the current ABI, should the type be passed in a + floating-point register (assuming that there is space)? When there + is no FPU, FP are not even considered as possibile candidates for + FP registers and, consequently this returns false - forces FP + arguments into integer registers. */ + +static int +fp_register_arg_p (enum type_code typecode, struct type *arg_type) +{ + return ((typecode == TYPE_CODE_FLT + || (MIPS_EABI + && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) + && TYPE_NFIELDS (arg_type) == 1 + && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT)) + && MIPS_FPU_TYPE != MIPS_FPU_NONE); +} + CORE_ADDR mips_push_arguments (nargs, args, sp, struct_return, struct_addr) int nargs; @@ -2165,13 +2182,8 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr) /* MIPS_EABI squeeses a struct that contains a single floating point value into an FP register instead of pusing it onto the stack. */ - if ((typecode == TYPE_CODE_FLT - || (MIPS_EABI - && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) - && TYPE_NFIELDS (arg_type) == 1 - && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT)) - && float_argreg <= MIPS_LAST_FP_ARG_REGNUM - && MIPS_FPU_TYPE != MIPS_FPU_NONE) + if (fp_register_arg_p (typecode, arg_type) + && float_argreg <= MIPS_LAST_FP_ARG_REGNUM) { if (!FP_REGISTER_DOUBLE && len == 8) { @@ -2241,14 +2253,17 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr) are treated specially: Irix cc passes them in registers where gcc sometimes puts them on the stack. For maximum compatibility, we will put them in both places. */ - int odd_sized_struct = ((len > MIPS_SAVED_REGSIZE) && (len % MIPS_SAVED_REGSIZE != 0)); + /* Note: Floating-point values that didn't fit into an FP + register are only written to memory. */ while (len > 0) { int partial_len = len < MIPS_SAVED_REGSIZE ? len : MIPS_SAVED_REGSIZE; - if (argreg > MIPS_LAST_ARG_REGNUM || odd_sized_struct) + if (argreg > MIPS_LAST_ARG_REGNUM + || odd_sized_struct + || fp_register_arg_p (typecode, arg_type)) { /* Write this portion of the argument to the stack. */ /* Should shorter than int integer values be @@ -2291,9 +2306,11 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr) write_memory (addr, val, partial_len); } - /* Note!!! This is NOT an else clause. - Odd sized structs may go thru BOTH paths. */ - if (argreg <= MIPS_LAST_ARG_REGNUM) + /* Note!!! This is NOT an else clause. Odd sized + structs may go thru BOTH paths. Floating point + arguments will not. */ + if (argreg <= MIPS_LAST_ARG_REGNUM + && !fp_register_arg_p (typecode, arg_type)) { LONGEST regval = extract_unsigned_integer (val, partial_len); |