This is the mail archive of the gdb-prs@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]

pending/1387: [RFA] sh-tdep.c: Follow up patch to implement two different ABIs


>Number:         1387
>Category:       pending
>Synopsis:       [RFA] sh-tdep.c: Follow up patch to implement two different ABIs
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          change-request
>Submitter-Id:   unknown
>Arrival-Date:   Sat Sep 20 21:38:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        
>Organization:
>Environment:
>Description:
 Hi,
 
 the below patch is a follow up patch which relies on the pending sh frame
 stuff patch.  This patch now adds the ability to switch between two
 different ABIs on the gdb command line, the "gcc" and the "renesas" ABI. 
 The patch also implements the differences between these ABIs which changes
 the way how arguments are passed and values are returned.  Additionally it
 fixes the argument passing of doubles in the gcc ABI on sh variations with
 FPU.  The changes in detail:
 
 - Add the commands `set calling_convention <foo>' and
   `show calling_convention' with <foo> being one of "gcc" and "renesas".
   Default to "gcc".
 
 - Differ between a fpu and a nofpu version of sh_use_struct_convention.
   The nofpu version behaves like the fpu version, except that it uses
   struct convention also for all types >= 8 bytes when the Renesas ABI
   is active.  This especially affects long longs and doubles which are
   then passed on the stack.
 
 - The Renesas ABI passes the address in which structs have to be returned
   not in r2 as the gcc ABI, but instead this return address is pushed
   onto the stack after all arguments have been pushed.  This affects
   sh_extract_struct_value_address() as well as the sh_push_dummy_call*()
   functions.
 
 - To simplify the sh_push_dummy_call*() functions, I created two helper
   functions which took the part of right-justifying values < 4 byte,
   called sh_justify_value_in_reg(), and to count the number of bytes
   to be allocated on stack for all arguments, called sh_stack_allocsize().
 
 - Two new functions are now used to evaluate the next floating point
   register to use for an argument.  The tricky part with floats is
   that gcc and Renesas ABI are different in two situations:
 
   - gcc passes floats in little-endian mode using regsters criss-crossing,
     fr5, fr4, fr7, fr6, fr9, fr8 ...  In big-endian mode or in Renesas
     ABI, the order is simple fr4, fr5, fr6, ...
 
   - In both ABIs doubles are passed in even register pairs, fr4/fr5,
     fr6/fr7, ...  The difference is when a register is skipped to pass
     the next double.  Example:
 
       void foo(float a, double b, float c);
 
     In gcc ABI, a is passed in fr4, b then skips the odd-numbered fr5
     register, so it's passed in fr6/fr7 and c is then passed in the next
     free register, fr8.
 
     In Renesas ABI, a is passed in fr4, b is passed as in gcc ABI in
     fr6/fr7 but c is passed in the lowest unused register, in this example
     in fr5.
 
 - In the Renesas ABI for CPUs with FPU, long longs are not passed in
   registers but on stack.
 
 - The struct_return code in both sh_push_dummy_call*() functions is moved
   to the end of the function since it must be done after the argument
   passing for the Rensas ABI.
 
 - I renamed the flag `odd_sized_struct' to a more descriptive name,
   `pass_on_stack' since the old name does in no way reflect how the
   decision about passing on stack or in register is actually made.  The
   actual decision is as follows:
 
   - On FPU CPUs, pass in registers unless the datatype is bigger than
     16 bytes.  Renesas ABI additionally passes long longs on the stack
     as well.
 
   - On non-FPU CPUs, doubles and long doubles are passed always on the stack.
 
   - On all CPUs, everything else is passed in registers until the argument
     registers are filled up, the remaining arguments are passed on stack. 
     If an argument doesn't fit entirely in the remaining registers, it's
     split between regs and stack as see fit.
 
 - The code and comment that some data is sometimes passed in registers
   *and* stack simultaneously is dropped.  That's not how it works.
   Seems to be something sh5 specific but that's now in sh64-tdep.c.
 
 - Also in sh_push_dummy_call*(), the code which adds 4 for every 4 bytes
   managed, is changed from e.g.
 
     len -= register_size (gdbarch, argreg);
 
   to
   
     len -= 4;
 
   The reason is that the original line is not exactly correct.  It adds the
   register_size of the *next* register, not the register actually filled
   with data.  Since all data and registers in question are 4 byte regs (and
   the target specific code should know that anyway), I've simplified the
   affected code.
 
 
 Corinna
 
 
 ChangeLog:
 ==========
 
 	* sh-tdep.c (sh_cc_gcc): New static string.
 	(sh_cc_renesas): Ditto.
 	(sh_cc_enum): New array pointing to calling convention strings.
 	(sh_active_calling_convention): New variable pointing to
 	current active calling convention.
 	(sh_use_struct_convention_fpu): New function.
 	(sh_use_struct_convention_nofpu): New function.
 	(sh_use_struct_convention): Remove.  Superseeded by the previous
 	two functions.
 	(sh_extract_struct_value_address): Care for Renesas ABI.
 	(sh_justify_value_in_reg): New function.
 	(sh_stack_allocsize): Ditto.
 	(flt_argreg_array): New array used for floating point argument
 	passing.
 	(sh_init_flt_argreg): New function.
 	(sh_next_flt_argreg): Ditto.
 	(sh_push_dummy_call_fpu): Simplify. Rename "odd_sized_struct" to
 	"pass_on_stack". Use new helper functions.  Accomodate Renesas ABI.
 	Fix argument passing strategy.
 	(sh_push_dummy_call_nofpu): Ditto.
 	(sh_gdbarch_init): Accomodate new sh_use_struct_convention_fpu and
 	sh_use_struct_convention_nofpu functions.
 	(_initialize_sh_tdep): Initialize new "set calling_convention",
 	"show calling_convention" commands.
 
 --- sh-tdep.c.AFTERPATCH2	2003-09-15 17:14:33.000000000 +0200
 +++ sh-tdep.c	2003-09-16 18:17:39.000000000 +0200
 @@ -55,6 +55,17 @@
  /* registers numbers shared with the simulator */
  #include "gdb/sim-sh.h"
  
 +static const char sh_cc_gcc[] = "gcc";
 +static const char sh_cc_renesas[] = "renesas";
 +static const char *sh_cc_enum[] =
 +{
 +  sh_cc_gcc,
 +  sh_cc_renesas,
 +  NULL
 +};
 +
 +static const char *sh_active_calling_convention = sh_cc_gcc;
 +
  static void (*sh_show_regs) (void);
  
  #define SH_NUM_REGS 59
 @@ -569,10 +580,25 @@ sh_skip_prologue (CORE_ADDR start_pc)
  
  /* Should call_function allocate stack space for a struct return?  */
  static int
 -sh_use_struct_convention (int gcc_p, struct type *type)
 +sh_use_struct_convention_fpu (int gcc_p, struct type *type)
 +{
 +  int len = TYPE_LENGTH (type);
 +  int nelem = TYPE_NFIELDS (type);
 +
 +  return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) &&
 +	  (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4);
 +}
 +
 +static int
 +sh_use_struct_convention_nofpu (int gcc_p, struct type *type)
  {
    int len = TYPE_LENGTH (type);
    int nelem = TYPE_NFIELDS (type);
 +
 +  /* The Renesas ABI returns long longs/doubles etc.  always on stack. */
 +  if (sh_active_calling_convention == sh_cc_renesas && len >= 8)
 +    return 1;
 +
    return ((len != 1 && len != 2 && len != 4 && len != 8) || nelem != 1) &&
  	  (len != 8 || TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) != 4);
  }
 @@ -584,8 +610,13 @@ static CORE_ADDR
  sh_extract_struct_value_address (struct regcache *regcache)
  {
    ULONGEST addr;
 -
 -  regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr);
 +  if (sh_active_calling_convention != sh_cc_renesas)
 +    regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr);
 +  else
 +    {
 +      regcache_cooked_read_unsigned (regcache, SP_REGNUM, &addr);
 +      addr = read_memory_unsigned_integer (addr, 4);
 +    }
    return addr;
  }
  
 @@ -647,6 +678,102 @@ sh_frame_align (struct gdbarch *ignore, 
     not displace any of the other arguments passed in via registers R4
     to R7.   */
  
 +/* Helper function to justify value in register according to endianess. */
 +static char *
 +sh_justify_value_in_reg (struct value *val, int len)
 +{
 +  static char valbuf[4];
 +
 +  memset (valbuf, 0, sizeof (valbuf));
 +  if (len < 4)
 +    {
 +      /* value gets right-justified in the register or stack word */
 +      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
 +	memcpy (valbuf + (4 - len), (char *) VALUE_CONTENTS (val), len);
 +      else
 +	memcpy (valbuf, (char *) VALUE_CONTENTS (val), len);
 +      return valbuf;
 +    }
 +  return (char *) VALUE_CONTENTS (val);
 +}
 +
 +/* Helper function to eval number of bytes to allocate on stack. */
 +static CORE_ADDR
 +sh_stack_allocsize (int nargs, struct value **args)
 +{
 +  int stack_alloc = 0;
 +  while (nargs-- > 0)
 +    stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[nargs])) + 3) & ~3);
 +  return stack_alloc;
 +}
 +
 +/* Helper functions for getting the float arguments right.  Registers usage
 +   depends on the ABI and the endianess.  The comments should enlighten how
 +   it's intended to work. */
 +
 +/* This array stores which of the float arg registers are already in use. */
 +static int flt_argreg_array[FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM + 1];
 +
 +/* This function just resets the above array to "no reg used so far". */
 +static void
 +sh_init_flt_argreg (void)
 +{
 +  memset (flt_argreg_array, 0, sizeof flt_argreg_array);
 +}
 +
 +/* This function returns the next register to use for float arg passing.
 +   It returns either a valid value between FLOAT_ARG0_REGNUM and
 +   FLOAT_ARGLAST_REGNUM if a register is available, otherwise it returns 
 +   FLOAT_ARGLAST_REGNUM + 1 to indicate that no register is available.
 +
 +   Note that register number 0 in flt_argreg_array corresponds with the
 +   real float register fr4.  In contrast to FLOAT_ARG0_REGNUM (value is
 +   29) the parity of the register number is preserved, which is important
 +   for the double register passing test (see the "argreg & 1" test below). */
 +static int
 +sh_next_flt_argreg (int len)
 +{
 +  int argreg;
 +
 +  /* First search for the next free register. */
 +  for (argreg = 0; argreg <= FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM; ++argreg)
 +    if (!flt_argreg_array[argreg])
 +      break;
 +
 +  /* No register left? */
 +  if (argreg > FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM)
 +    return FLOAT_ARGLAST_REGNUM + 1;
 +
 +  if (len == 8)
 +    {
 +      /* Doubles are always starting in a even register number. */
 +      if (argreg & 1)
 +        {
 +	  /* In gcc ABI, the skipped register is lost for further argument
 +	     passing now.  Not so in Renesas ABI. */
 +	  if (sh_active_calling_convention != sh_cc_renesas)
 +	    flt_argreg_array[argreg] = 1;
 +
 +	  ++argreg;
 +
 +	  /* No register left? */
 +	  if (argreg > FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM)
 +	    return FLOAT_ARGLAST_REGNUM + 1;
 +	}
 +      /* Also mark the next register as used. */
 +      flt_argreg_array[argreg + 1] = 1;
 +    }
 +  else if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE
 +	   && sh_active_calling_convention != sh_cc_renesas)
 +    {
 +      /* In little endian, gcc passes floats like this: f5, f4, f7, f6, ... */
 +      if (!flt_argreg_array[argreg + 1])
 +	++argreg;
 +    }
 +  flt_argreg_array[argreg] = 1;
 +  return FLOAT_ARG0_REGNUM + argreg;
 +}
 +
  static CORE_ADDR
  sh_push_dummy_call_fpu (struct gdbarch *gdbarch, 
  			CORE_ADDR func_addr,
 @@ -656,77 +783,61 @@ sh_push_dummy_call_fpu (struct gdbarch *
  			CORE_ADDR sp, int struct_return,
  			CORE_ADDR struct_addr)
  {
 -  int stack_offset, stack_alloc;
 -  int argreg, flt_argreg;
 +  int stack_offset = 0;
 +  int argreg = ARG0_REGNUM;
 +  int flt_argreg;
    int argnum;
    struct type *type;
    CORE_ADDR regval;
    char *val;
 -  char valbuf[4];
    int len;
 -  int odd_sized_struct;
 +  int pass_on_stack;
  
    /* first force sp to a 4-byte alignment */
    sp = sh_frame_align (gdbarch, sp);
  
 -  if (struct_return)
 -    regcache_cooked_write_unsigned (regcache,
 -				    STRUCT_RETURN_REGNUM,
 -				    struct_addr);
 -
 -  /* Now make sure there's space on the stack */
 -  for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
 -    stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
 -  sp -= stack_alloc;		/* make room on stack for args */
 +  /* make room on stack for args */
 +  sp -= sh_stack_allocsize (nargs, args);
 +
 +  /* Initialize float argument mechanism. */
 +  sh_init_flt_argreg ();
  
    /* Now load as many as possible of the first arguments into
       registers, and push the rest onto the stack.  There are 16 bytes
       in four registers available.  Loop thru args from first to last.  */
 -
 -  argreg = ARG0_REGNUM;
 -  flt_argreg = FLOAT_ARG0_REGNUM;
 -  for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
 +  for (argnum = 0; argnum < nargs; argnum++)
      {
        type = VALUE_TYPE (args[argnum]);
        len = TYPE_LENGTH (type);
 -      memset (valbuf, 0, sizeof (valbuf));
 -      if (len < 4)
 -	{
 -	  /* value gets right-justified in the register or stack word */
 -	  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
 -	    memcpy (valbuf + (4 - len),
 -		    (char *) VALUE_CONTENTS (args[argnum]), len);
 -	  else
 -	    memcpy (valbuf, (char *) VALUE_CONTENTS (args[argnum]), len);
 -	  val = valbuf;
 -	}
 -      else
 -	val = (char *) VALUE_CONTENTS (args[argnum]);
 +      val = sh_justify_value_in_reg (args[argnum], len);
 +
 +      /* Some decisions have to be made how various types are handled.
 +         This also differs in different ABIs. */
 +      pass_on_stack = 0;
 +      if (len > 16)
 +	pass_on_stack = 1; /* Types bigger than 16 bytes are passed on stack. */
 +      else if (sh_active_calling_convention == sh_cc_renesas
 +	       && TYPE_CODE (type) == TYPE_CODE_INT && len == 8)
 +	pass_on_stack = 1; /* So are long longs in renesas ABI */
 +
 +      /* Find out the next register to use for a floating point value. */
 +      if (TYPE_CODE (type) == TYPE_CODE_FLT)
 +        flt_argreg = sh_next_flt_argreg (len);
  
 -      if (len > 4 && (len & 3) != 0)
 -	odd_sized_struct = 1;	/* Such structs go entirely on stack.  */
 -      else if (len > 16)
 -	odd_sized_struct = 1;	/* So do aggregates bigger than 4 words.  */
 -      else
 -	odd_sized_struct = 0;
        while (len > 0)
  	{
  	  if ((TYPE_CODE (type) == TYPE_CODE_FLT 
  	       && flt_argreg > FLOAT_ARGLAST_REGNUM) 
  	      || argreg > ARGLAST_REGNUM
 -	      || odd_sized_struct)
 +	      || pass_on_stack)
  	    {			
 -	      /* must go on the stack */
  	      write_memory (sp + stack_offset, val, 4);
  	      stack_offset += 4;
  	    }
 -	  /* NOTE WELL!!!!!  This is not an "else if" clause!!!
 -	     That's because some *&^%$ things get passed on the stack
 -	     AND in the registers!   */
 -	  if (TYPE_CODE (type) == TYPE_CODE_FLT &&
 -	      flt_argreg > 0 && flt_argreg <= FLOAT_ARGLAST_REGNUM)
 +	  else if (TYPE_CODE (type) == TYPE_CODE_FLT
 +		   && flt_argreg <= FLOAT_ARGLAST_REGNUM)
  	    {
 -	      /* Argument goes in a single-precision fp reg.  */
 +	      /* Argument goes in a float argument register.  */
  	      regval = extract_unsigned_integer (val, register_size (gdbarch,
  								     argreg));
  	      regcache_cooked_write_unsigned (regcache, flt_argreg++, regval);
 @@ -741,11 +852,25 @@ sh_push_dummy_call_fpu (struct gdbarch *
  	  /* Store the value 4 bytes at a time.  This means that things
  	     larger than 4 bytes may go partly in registers and partly
  	     on the stack.  */
 -	  len -= register_size (gdbarch, argreg);
 -	  val += register_size (gdbarch, argreg);
 +	  len -= 4;
 +	  val += 4;
  	}
      }
  
 +  if (struct_return)
 +    {
 +      if (sh_active_calling_convention != sh_cc_renesas)
 +	/* Using the gcc ABI, the "struct return pointer" pseudo-argument has
 +	   its own dedicated register */
 +	regcache_cooked_write_unsigned (regcache,
 +					STRUCT_RETURN_REGNUM,
 +					struct_addr);
 +      else
 +	/* If the function uses the renesas ABI, subtract another 4 bytes from
 +	   the stack and store the struct return address there. */
 +	write_memory_unsigned_integer (sp -= 4, 4, struct_addr);
 +    }
 +
    /* Store return address. */
    regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
  
 @@ -764,69 +889,45 @@ sh_push_dummy_call_nofpu (struct gdbarch
  			  CORE_ADDR sp, int struct_return, 
  			  CORE_ADDR struct_addr)
  {
 -  int stack_offset, stack_alloc;
 -  int argreg;
 +  int stack_offset = 0;
 +  int argreg = ARG0_REGNUM;
    int argnum;
    struct type *type;
    CORE_ADDR regval;
    char *val;
 -  char valbuf[4];
    int len;
 -  int odd_sized_struct;
 +  int pass_on_stack;
  
    /* first force sp to a 4-byte alignment */
    sp = sh_frame_align (gdbarch, sp);
  
 -  if (struct_return)
 -    regcache_cooked_write_unsigned (regcache,
 -				    STRUCT_RETURN_REGNUM,
 -				    struct_addr);
 -
 -  /* Now make sure there's space on the stack */
 -  for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
 -    stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
 -  sp -= stack_alloc;		/* make room on stack for args */
 +  /* make room on stack for args */
 +  sp -= sh_stack_allocsize (nargs, args);
  
    /* Now load as many as possible of the first arguments into
       registers, and push the rest onto the stack.  There are 16 bytes
       in four registers available.  Loop thru args from first to last.  */
 -
 -  argreg = ARG0_REGNUM;
 -  for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
 +  for (argnum = 0; argnum < nargs; argnum++)
      {
        type = VALUE_TYPE (args[argnum]);
        len = TYPE_LENGTH (type);
 -      memset (valbuf, 0, sizeof (valbuf));
 -      if (len < 4)
 -	{
 -	  /* value gets right-justified in the register or stack word */
 -	  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
 -	    memcpy (valbuf + (4 - len),
 -		    (char *) VALUE_CONTENTS (args[argnum]), len);
 -	  else
 -	    memcpy (valbuf, (char *) VALUE_CONTENTS (args[argnum]), len);
 -	  val = valbuf;
 -	}
 -      else
 -	val = (char *) VALUE_CONTENTS (args[argnum]);
 +      val = sh_justify_value_in_reg (args[argnum], len);
 +
 +      /* Some decisions have to be made how various types are handled.
 +         This also differs in different ABIs. */
 +      pass_on_stack = 0;
 +      if (TYPE_CODE (type) == TYPE_CODE_FLT && len > 4
 +	  && sh_active_calling_convention == sh_cc_renesas)
 +	pass_on_stack = 1; /* Renesas ABI pushes doubles entirely on stack. */
  
 -      if (len > 4 && (len & 3) != 0)
 -	odd_sized_struct = 1;	/* such structs go entirely on stack */
 -      else
 -	odd_sized_struct = 0;
        while (len > 0)
  	{
 -	  if (argreg > ARGLAST_REGNUM
 -	      || odd_sized_struct)
 +	  if (argreg > ARGLAST_REGNUM || pass_on_stack)
  	    {			
 -	      /* must go on the stack */
  	      write_memory (sp + stack_offset, val, 4);
  	      stack_offset += 4;
  	    }
 -	  /* NOTE WELL!!!!!  This is not an "else if" clause!!!
 -	     That's because some *&^%$ things get passed on the stack
 -	     AND in the registers!   */
 -	  if (argreg <= ARGLAST_REGNUM)
 +	  else if (argreg <= ARGLAST_REGNUM)
  	    {			
  	      /* there's room in a register */
  	      regval = extract_unsigned_integer (val, register_size (gdbarch,
 @@ -836,11 +937,25 @@ sh_push_dummy_call_nofpu (struct gdbarch
  	  /* Store the value 4 bytes at a time.  This means that things
  	     larger than 4 bytes may go partly in registers and partly
  	     on the stack.  */
 -	  len -= register_size (gdbarch, argreg);
 -	  val += register_size (gdbarch, argreg);
 +	  len -= 4;
 +	  val += 4;
  	}
      }
  
 +  if (struct_return)
 +    {
 +      if (sh_active_calling_convention != sh_cc_renesas)
 +	/* Using the gcc ABI, the "struct return pointer" pseudo-argument has
 +	   its own dedicated register */
 +	regcache_cooked_write_unsigned (regcache,
 +					STRUCT_RETURN_REGNUM,
 +					struct_addr);
 +      else
 +	/* If the function uses the renesas ABI, subtract another 4 bytes from
 +	   the stack and store the struct return address there. */
 +	write_memory_unsigned_integer (sp -= 4, 4, struct_addr);
 +    }
 +
    /* Store return address. */
    regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
  
 @@ -2060,7 +2175,6 @@ sh_gdbarch_init (struct gdbarch_info inf
    set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
  
    set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
 -  set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention);
  
    set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh);
    set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
 @@ -2079,6 +2193,7 @@ sh_gdbarch_init (struct gdbarch_info inf
  
    set_gdbarch_push_dummy_code (gdbarch, sh_push_dummy_code);
    set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
 +  set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention_nofpu);
  
    set_gdbarch_frame_args_skip (gdbarch, 0);
    set_gdbarch_frameless_function_invocation (gdbarch,
 @@ -2114,6 +2229,7 @@ sh_gdbarch_init (struct gdbarch_info inf
        set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value);
        set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
        set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
 +      set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention_fpu);
        break;
  
      case bfd_mach_sh_dsp:
 @@ -2135,6 +2251,7 @@ sh_gdbarch_init (struct gdbarch_info inf
        set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value);
        set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
        set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
 +      set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention_fpu);
        break;
  
      case bfd_mach_sh3_dsp:
 @@ -2152,6 +2269,7 @@ sh_gdbarch_init (struct gdbarch_info inf
        set_gdbarch_store_return_value (gdbarch, sh3e_sh4_store_return_value);
        set_gdbarch_extract_return_value (gdbarch, sh3e_sh4_extract_return_value);
        set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
 +      set_gdbarch_use_struct_convention (gdbarch, sh_use_struct_convention_fpu);
        break;
  
      default:
 @@ -2178,4 +2296,11 @@ _initialize_sh_tdep (void)
    gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
  
    add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
 +
 +  add_show_from_set (
 +    add_set_enum_cmd ("calling_convention", class_vars, sh_cc_enum,
 +		      &sh_active_calling_convention,
 +		      "Set calling convention used when calling target "
 +		      "functions from GDB.",
 +		      &setlist), &showlist);
  }
 
 -- 
 Corinna Vinschen
 Cygwin Developer
 Red Hat, Inc.
 
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:


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