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]

[RFA] gdbarch changes for mips_abi_n32 on Irix


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

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]