This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] gdbarch changes for mips_abi_n32 on Irix


Michael Snyder wrote:
> 
> Actually, these are probably not specific to Irix at all.
> 
> Basically, this change implements gdbarch_reg_struct_has_addr,
> and removes the code that was implementing it inline in
> mips_push_arguments.
> 
> I've only tested it on the N32 ABI, but it should not
> functionally change any others.  The methods for
> O32 and O64 are empty, which also won't produce any
> change in behavior, but I or someone else can fill
> them in, if/as/when we find out what they should be.
> 
> Michael

Andrew, I could break this patch down into two smaller, 
functionally discrete chunks if you'd prefer.

> 
> 2002-07-31  Michael Snyder  <msnyder@redhat.com>
> 
>         *  mips-tdep.c: Define new macros MIPS_NEWABI, MIPS_OLDABI
>         (by analogy with MIPS_EABI).
>         (mips_use_struct_convention):  NEWABI (n32 and n64) use
>         same scheme as EABI.
>         (mips_eabi_reg_struct_has_addr, mips_newabi_reg_struct_has_addr,
>         mips_oldabi_reg_struct_has_addr): New gdbarch functions.
>         (mips_push_argument): Don't convert struct args to pointers.
>         (mips_gdbarch_init): Set gdbarch_reg_struct_has_addr.
> 
> Index: mips-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/mips-tdep.c,v
> retrieving revision 1.85
> diff -p -r1.85 mips-tdep.c
> *** mips-tdep.c 31 Jul 2002 20:26:49 -0000      1.85
> --- mips-tdep.c 31 Jul 2002 21:45:00 -0000
> *************** struct gdbarch_tdep
> *** 146,153 ****
>       enum gdb_osabi osabi;
>     };
> 
> ! #define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
> !                  || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64)
> 
>   #define MIPS_LAST_FP_ARG_REGNUM (gdbarch_tdep (current_gdbarch)->mips_last_fp_arg_regnum)
> 
> --- 146,162 ----
>       enum gdb_osabi osabi;
>     };
> 
> ! #define MIPS_EABI \
> !      (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
> !       || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64)
> !
> ! #define MIPS_NEWABI \
> !      (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_N32 \
> !       || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_N64)
> !
> ! #define MIPS_OLDABI \
> !      (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_O32 \
> !       || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_O64)
> 
>   #define MIPS_LAST_FP_ARG_REGNUM (gdbarch_tdep (current_gdbarch)->mips_last_fp_arg_regnum)
> 
> *************** show_mask_address (char *cmd, int from_t
> *** 531,542 ****
>   int
>   mips_use_struct_convention (int gcc_p, struct type *type)
>   {
> !   if (MIPS_EABI)
>       return (TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE);
>     else
> !     return 1;                 /* Structures are returned by ref in extra arg0 */
>   }
> 
>   /* Tell if the program counter value in MEMADDR is in a MIPS16 function.  */
> 
>   static int
> --- 540,586 ----
>   int
>   mips_use_struct_convention (int gcc_p, struct type *type)
>   {
> !   if (MIPS_EABI || MIPS_NEWABI)
>       return (TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE);
>     else
> !     return 1; /* Old ABI: structures are returned by ref in extra arg0 */
>   }
> 
> + /* Should call_function pass struct by reference?
> +    For each architecture, structs are passed either by
> +    value or by reference, depending on their size.  */
> +
> + static int
> + mips_eabi_reg_struct_has_addr (int gcc_p, struct type *type)
> + {
> +   enum type_code typecode = TYPE_CODE (check_typedef (type));
> +   int len = TYPE_LENGTH (check_typedef (type));
> +
> +   if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
> +     return (len > MIPS_SAVED_REGSIZE);
> +
> +   return 0;
> + }
> +
> + static int
> + mips_newabi_reg_struct_has_addr (int gcc_p, struct type *type)
> + {
> +   enum type_code typecode = TYPE_CODE (check_typedef (type));
> +   int len = TYPE_LENGTH (check_typedef (type));
> +
> +   if (typecode == TYPE_CODE_STRUCT   || typecode == TYPE_CODE_UNION)
> +     return (len > MIPS_SAVED_REGSIZE && len % MIPS_SAVED_REGSIZE != 0);
> +
> +   return 0;
> + }
> +
> + int
> + mips_oldabi_reg_struct_has_addr (int gcc_p, struct type *type)
> + {
> +   return 0;   /* FIXME: what should we do for old abi?  */
> + }
> +
> +
>   /* Tell if the program counter value in MEMADDR is in a MIPS16 function.  */
> 
>   static int
> *************** mips_push_arguments (int nargs,
> *** 2427,2440 ****
>         }
> 
>         /* Floating point arguments passed in registers have to be
> !          treated specially.  On 32-bit architectures, doubles
> !          are passed in register pairs; the even register gets
> !          the low word, and the odd register gets the high word.
> !          On non-EABI processors, the first two floating point arguments are
> !          also copied to general registers, because MIPS16 functions
> !          don't use float registers for arguments.  This duplication of
> !          arguments in general registers can't hurt non-MIPS16 functions
> !          because those registers are normally skipped.  */
>         /* MIPS_EABI squeezes a struct that contains a single floating
>            point value into an FP register instead of pushing it onto the
>            stack. */
> --- 2471,2487 ----
>         }
> 
>         /* Floating point arguments passed in registers have to be
> !          treated specially (and so do double fields in a struct.  FIXME:)
> !
> !          On 32-bit architectures, doubles are passed in register
> !          pairs; the even register gets the low word, and the odd
> !          register gets the high word.  On non-EABI processors, the
> !          first two floating point arguments are also copied to general
> !          registers, because MIPS16 functions don't use float registers
> !          for arguments.  This duplication of arguments in general
> !          registers can't hurt non-MIPS16 functions because those
> !          registers are normally skipped.  */
> !
>         /* MIPS_EABI squeezes a struct that contains a single floating
>            point value into an FP register instead of pushing it onto the
>            stack. */
> *************** mips_push_arguments (int nargs,
> *** 2573,2579 ****
>                       fprintf_unfiltered (gdb_stdlog, " @0x%lx ", (long) addr);
>                       for (i = 0; i < partial_len; i++)
>                         {
> !                         fprintf_unfiltered (gdb_stdlog, "%02x", val[i] & 0xff);
>                         }
>                     }
>                   write_memory (addr, val, partial_len);
> --- 2622,2629 ----
>                       fprintf_unfiltered (gdb_stdlog, " @0x%lx ", (long) addr);
>                       for (i = 0; i < partial_len; i++)
>                         {
> !                         fprintf_unfiltered (gdb_stdlog, "%02x",
> !                                             val[i] & 0xff);
>                         }
>                     }
>                   write_memory (addr, val, partial_len);
> *************** mips_push_arguments (int nargs,
> *** 2599,2611 ****
>                      same for integral types.
> 
>                      Also don't do this adjustment on EABI and O64
> !                    binaries.
> 
>                      cagney/2001-07-23: gdb/179: Also, GCC, when
>                      outputting LE O32 with sizeof (struct) <
>                      MIPS_SAVED_REGSIZE, generates a left shift as
> !                    part of storing the argument in a register a
> !                    register (the left shift isn't generated when
>                      sizeof (struct) >= MIPS_SAVED_REGSIZE).  Since it
>                      is quite possible that this is GCC contradicting
>                      the LE/O32 ABI, GDB has not been adjusted to
> --- 2649,2662 ----
>                      same for integral types.
> 
>                      Also don't do this adjustment on EABI and O64
> !                    binaries.   FIXME: comment does not agree with
> !                    code, which tests for O32, not O64.   MVS
> 
>                      cagney/2001-07-23: gdb/179: Also, GCC, when
>                      outputting LE O32 with sizeof (struct) <
>                      MIPS_SAVED_REGSIZE, generates a left shift as
> !                    part of storing the argument in a register
> !                    (the left shift isn't generated when
>                      sizeof (struct) >= MIPS_SAVED_REGSIZE).  Since it
>                      is quite possible that this is GCC contradicting
>                      the LE/O32 ABI, GDB has not been adjusted to
> *************** mips_gdbarch_init (struct gdbarch_info i
> *** 4465,4470 ****
> --- 4518,4526 ----
>         set_gdbarch_long_bit (gdbarch, 32);
>         set_gdbarch_ptr_bit (gdbarch, 32);
>         set_gdbarch_long_long_bit (gdbarch, 64);
> +       /* Set up reg_struct_has_addr.  */
> +       set_gdbarch_reg_struct_has_addr (gdbarch,
> +                                      mips_eabi_reg_struct_has_addr);
>         break;
>       case MIPS_ABI_EABI64:
>         tdep->mips_default_saved_regsize = 8;
> *************** mips_gdbarch_init (struct gdbarch_info i
> *** 4478,4486 ****
>         set_gdbarch_long_bit (gdbarch, 64);
>         set_gdbarch_ptr_bit (gdbarch, 64);
>         set_gdbarch_long_long_bit (gdbarch, 64);
>         break;
>       case MIPS_ABI_N32:
> !       tdep->mips_default_saved_regsize = 4;
>         tdep->mips_default_stack_argsize = 8;
>         tdep->mips_fp_register_double = 1;
>         tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
> --- 4534,4545 ----
>         set_gdbarch_long_bit (gdbarch, 64);
>         set_gdbarch_ptr_bit (gdbarch, 64);
>         set_gdbarch_long_long_bit (gdbarch, 64);
> +       /* Set up reg_struct_has_addr.  */
> +       set_gdbarch_reg_struct_has_addr (gdbarch,
> +                                      mips_eabi_reg_struct_has_addr);
>         break;
>       case MIPS_ABI_N32:
> !       tdep->mips_default_saved_regsize = 8;
>         tdep->mips_default_stack_argsize = 8;
>         tdep->mips_fp_register_double = 1;
>         tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
> *************** mips_gdbarch_init (struct gdbarch_info i
> *** 4491,4496 ****
> --- 4550,4558 ----
>         set_gdbarch_long_bit (gdbarch, 32);
>         set_gdbarch_ptr_bit (gdbarch, 32);
>         set_gdbarch_long_long_bit (gdbarch, 64);
> +       /* Set up reg_struct_has_addr.  */
> +       set_gdbarch_reg_struct_has_addr (gdbarch,
> +                                      mips_newabi_reg_struct_has_addr);
> 
>         /* Set up the disassembler info, so that we get the right
>          register names from libopcodes.  */
> *************** mips_gdbarch_init (struct gdbarch_info i
> *** 4515,4520 ****
> --- 4577,4585 ----
>         set_gdbarch_long_bit (gdbarch, 64);
>         set_gdbarch_ptr_bit (gdbarch, 64);
>         set_gdbarch_long_long_bit (gdbarch, 64);
> +       /* Set up reg_struct_has_addr.  */
> +       set_gdbarch_reg_struct_has_addr (gdbarch,
> +                                      mips_newabi_reg_struct_has_addr);
> 
>         /* Set up the disassembler info, so that we get the right
>          register names from libopcodes.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]