This is the mail archive of the gdb-patches@sourceware.org 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]

[committed] avr: handle structure in return_value and push_dummy_call


Hi,

this patch fixes the handling of structures in both return_value and push_dummy_call methods. Previous code
was either incomplete or wrong.


Tristan.


2009-11-10 Tristan Gingold <gingold@adacore.com>


	* avr-tdep.c (avr_extract_return_value): Remove.
	(avr_return_value): Mostly rewritten.  Fix handling for structures.
	(avr_push_dummy_call): Handle struct_return.

diff -c -r1.118 avr-tdep.c
*** avr-tdep.c	10 Nov 2009 10:05:47 -0000	1.118
--- avr-tdep.c	10 Nov 2009 10:20:42 -0000
***************
*** 815,854 ****
      return avr_break_insn;
  }

- /* Given a return value in `regcache' with a type `type',
- extract and copy its value into `valbuf'.
-
- Return values are always passed via registers r25:r24:... */
-
- static void
- avr_extract_return_value (struct type *type, struct regcache *regcache,
- gdb_byte *valbuf)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- ULONGEST r24, r25;
- ULONGEST c;
- int len;
- if (TYPE_LENGTH (type) == 1)
- {
- regcache_cooked_read_unsigned (regcache, 24, &c);
- store_unsigned_integer (valbuf, 1, byte_order, c);
- }
- else
- {
- int i;
- /* The MSB of the return value is always in r25, calculate which
- register holds the LSB. */
- int lsb_reg = 25 - TYPE_LENGTH (type) + 1;
-
- for (i=0; i< TYPE_LENGTH (type); i++)
- {
- regcache_cooked_read (regcache, lsb_reg + i,
- (bfd_byte *) valbuf + i);
- }
- }
- }
-
/* Determine, for architecture GDBARCH, how a return value of TYPE
should be returned. If it is supposed to be returned in registers,
and READBUF is non-zero, read the appropriate value from REGCACHE,
--- 837,842 ----
***************
*** 860,889 ****
struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
! int struct_return = ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
! || TYPE_CODE (valtype) == TYPE_CODE_UNION
! || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
! && !(TYPE_LENGTH (valtype) == 1
! || TYPE_LENGTH (valtype) == 2
! || TYPE_LENGTH (valtype) == 4
! || TYPE_LENGTH (valtype) == 8));


    if (writebuf != NULL)
      {
!       gdb_assert (!struct_return);
!       error (_("Cannot store return value."));
      }

    if (readbuf != NULL)
      {
!       gdb_assert (!struct_return);
!       avr_extract_return_value (valtype, regcache, readbuf);
      }

!   if (struct_return)
!     return RETURN_VALUE_STRUCT_CONVENTION;
!   else
!     return RETURN_VALUE_REGISTER_CONVENTION;
  }


--- 848,887 ----
struct type *valtype, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
! int i;
! /* Single byte are returned in r24.
! Otherwise, the MSB of the return value is always in r25, calculate which
! register holds the LSB. */
! int lsb_reg;
!
! if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
! || TYPE_CODE (valtype) == TYPE_CODE_UNION
! || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
! && TYPE_LENGTH (valtype) > 8)
! return RETURN_VALUE_STRUCT_CONVENTION;
!
! if (TYPE_LENGTH (valtype) <= 2)
! lsb_reg = 24;
! else if (TYPE_LENGTH (valtype) <= 4)
! lsb_reg = 22;
! else if (TYPE_LENGTH (valtype) <= 8)
! lsb_reg = 18;
! else
! gdb_assert (0);


    if (writebuf != NULL)
      {
!       for (i = 0; i < TYPE_LENGTH (valtype); i++)
!         regcache_cooked_write (regcache, lsb_reg + i, writebuf + i);
      }

    if (readbuf != NULL)
      {
!       for (i = 0; i < TYPE_LENGTH (valtype); i++)
!         regcache_cooked_read (regcache, lsb_reg + i, readbuf + i);
      }

!   return RETURN_VALUE_REGISTER_CONVENTION;
  }


*************** *** 1191,1205 **** int regnum = AVR_ARGN_REGNUM; struct stack_item *si = NULL;

- #if 0
- /* FIXME: TRoth/2003-06-18: Not sure what to do when returning a struct. */
if (struct_return)
{
! fprintf_unfiltered (gdb_stderr, "struct_return: 0x%lx\n", struct_addr);
! regcache_cooked_write_unsigned (regcache, argreg--, struct_addr & 0xff);
! regcache_cooked_write_unsigned (regcache, argreg--, (struct_addr >>8) & 0xff);
}
- #endif


    for (i = 0; i < nargs; i++)
      {
--- 1189,1201 ----
    int regnum = AVR_ARGN_REGNUM;
    struct stack_item *si = NULL;

    if (struct_return)
      {
!       regcache_cooked_write_unsigned (regcache, regnum--,
!                                       struct_addr & 0xff);
!       regcache_cooked_write_unsigned (regcache, regnum--,
!                                       (struct_addr >> 8) & 0xff);
      }

    for (i = 0; i < nargs; i++)
      {


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