[committed] avr: handle structure in return_value and push_dummy_call

Tristan Gingold gingold@adacore.com
Tue Nov 10 10:22:00 GMT 2009


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++)
       {



More information about the Gdb-patches mailing list