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]

[PATCH] Handle struct_return and char return values for d10v.


2002-06-06  Michael Snyder  <msnyder@redhat.com>

	* d10v-tdep.c (d10v_push_arguments): Handle struct_return.
	Delete extra braces and re-indent.
	(d10v_store_return_value): Char return values
	must be shifted over by one byte in R0.
	(d10v_extract_return_value): Delete extra braces, re-indent.

Index: d10v-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/d10v-tdep.c,v
retrieving revision 1.44
retrieving revision 1.46
diff -p -r1.44 -r1.46
*** d10v-tdep.c	6 Jun 2002 16:35:37 -0000	1.44
--- d10v-tdep.c	6 Jun 2002 18:57:08 -0000	1.46
*************** d10v_store_struct_return (CORE_ADDR addr
*** 482,490 ****
  static void
  d10v_store_return_value (struct type *type, char *valbuf)
  {
!   write_register_bytes (REGISTER_BYTE (RET1_REGNUM),
! 			valbuf,
! 			TYPE_LENGTH (type));
  }
  
  /* Extract from an array REGBUF containing the (raw) register state
--- 482,501 ----
  static void
  d10v_store_return_value (struct type *type, char *valbuf)
  {
!   char tmp = 0;
!   /* Only char return values need to be shifted right within R0.  */
!   if (TYPE_LENGTH (type) == 1
!       && TYPE_CODE (type) == TYPE_CODE_INT)
!     {
!       write_register_bytes (REGISTER_BYTE (RET1_REGNUM),
! 			    &tmp, 1);	/* zero the high byte */
!       write_register_bytes (REGISTER_BYTE (RET1_REGNUM) + 1,
! 			    valbuf, 1);	/* copy the low byte */
!     }
!   else
!     write_register_bytes (REGISTER_BYTE (RET1_REGNUM),
! 			  valbuf,
! 			  TYPE_LENGTH (type));
  }
  
  /* Extract from an array REGBUF containing the (raw) register state
*************** d10v_push_arguments (int nargs, struct v
*** 1075,1080 ****
--- 1086,1100 ----
    int i;
    int regnum = ARG1_REGNUM;
    struct stack_item *si = NULL;
+   long val;
+ 
+   /* If struct_return is true, then the struct return address will
+      consume one argument-passing register.  No need to actually 
+      write the value to the register -- that's done by 
+      d10v_store_struct_return().  */
+ 
+   if (struct_return)
+     regnum++;
  
    /* Fill in registers and arg lists */
    for (i = 0; i < nargs; i++)
*************** d10v_push_arguments (int nargs, struct v
*** 1083,1121 ****
        struct type *type = check_typedef (VALUE_TYPE (arg));
        char *contents = VALUE_CONTENTS (arg);
        int len = TYPE_LENGTH (type);
        /* printf ("push: type=%d len=%d\n", TYPE_CODE (type), len); */
  	{
! 	  int aligned_regnum = (regnum + 1) & ~1;
! 	  if (len <= 2 && regnum <= ARGN_REGNUM)
! 	    /* fits in a single register, do not align */
  	    {
! 	      long val = extract_unsigned_integer (contents, len);
  	      write_register (regnum++, val);
  	    }
! 	  else if (len <= (ARGN_REGNUM - aligned_regnum + 1) * 2)
! 	    /* value fits in remaining registers, store keeping left
! 	       aligned */
! 	    {
! 	      int b;
! 	      regnum = aligned_regnum;
! 	      for (b = 0; b < (len & ~1); b += 2)
! 		{
! 		  long val = extract_unsigned_integer (&contents[b], 2);
! 		  write_register (regnum++, val);
! 		}
! 	      if (b < len)
! 		{
! 		  long val = extract_unsigned_integer (&contents[b], 1);
! 		  write_register (regnum++, (val << 8));
! 		}
! 	    }
! 	  else
  	    {
! 	      /* arg will go onto stack */
! 	      regnum = ARGN_REGNUM + 1;
! 	      si = push_stack_item (si, contents, len);
  	    }
  	}
      }
  
    while (si)
--- 1103,1140 ----
        struct type *type = check_typedef (VALUE_TYPE (arg));
        char *contents = VALUE_CONTENTS (arg);
        int len = TYPE_LENGTH (type);
+       int aligned_regnum = (regnum + 1) & ~1;
+ 
        /* printf ("push: type=%d len=%d\n", TYPE_CODE (type), len); */
+       if (len <= 2 && regnum <= ARGN_REGNUM)
+ 	/* fits in a single register, do not align */
+ 	{
+ 	  val = extract_unsigned_integer (contents, len);
+ 	  write_register (regnum++, val);
+ 	}
+       else if (len <= (ARGN_REGNUM - aligned_regnum + 1) * 2)
+ 	/* value fits in remaining registers, store keeping left
+ 	   aligned */
  	{
! 	  int b;
! 	  regnum = aligned_regnum;
! 	  for (b = 0; b < (len & ~1); b += 2)
  	    {
! 	      val = extract_unsigned_integer (&contents[b], 2);
  	      write_register (regnum++, val);
  	    }
! 	  if (b < len)
  	    {
! 	      val = extract_unsigned_integer (&contents[b], 1);
! 	      write_register (regnum++, (val << 8));
  	    }
  	}
+       else
+ 	{
+ 	  /* arg will go onto stack */
+ 	  regnum = ARGN_REGNUM + 1;
+ 	  si = push_stack_item (si, contents, len);
+ 	}
      }
  
    while (si)
*************** d10v_extract_return_value (struct type *
*** 1137,1161 ****
  			   char *valbuf)
  {
    int len;
!   /*    printf("RET: TYPE=%d len=%d r%d=0x%x\n", TYPE_CODE (type), TYPE_LENGTH (type), RET1_REGNUM - R0_REGNUM, (int) extract_unsigned_integer (regbuf + REGISTER_BYTE(RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM)));  */
      {
!       len = TYPE_LENGTH (type);
!       if (len == 1)
! 	{
! 	  unsigned short c = extract_unsigned_integer (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
! 	  store_unsigned_integer (valbuf, 1, c);
! 	}
!       else if ((len & 1) == 0)
! 	memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM), len);
!       else
! 	{
! 	  /* For return values of odd size, the first byte is in the
! 	     least significant part of the first register.  The
! 	     remaining bytes in remaining registers. Interestingly,
! 	     when such values are passed in, the last byte is in the
! 	     most significant byte of that same register - wierd. */
! 	  memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM) + 1, len);
! 	}
      }
  }
  
--- 1156,1186 ----
  			   char *valbuf)
  {
    int len;
! #if 0
!   printf("RET: TYPE=%d len=%d r%d=0x%x\n", TYPE_CODE (type), 
! 	 TYPE_LENGTH (type), RET1_REGNUM - R0_REGNUM, 
! 	 (int) extract_unsigned_integer (regbuf + REGISTER_BYTE(RET1_REGNUM), 
! 					 REGISTER_RAW_SIZE (RET1_REGNUM)));
! #endif
!   len = TYPE_LENGTH (type);
!   if (len == 1)
!     {
!       unsigned short c;
! 
!       c = extract_unsigned_integer (regbuf + REGISTER_BYTE (RET1_REGNUM), 
! 				    REGISTER_RAW_SIZE (RET1_REGNUM));
!       store_unsigned_integer (valbuf, 1, c);
!     }
!   else if ((len & 1) == 0)
!     memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM), len);
!   else
      {
!       /* For return values of odd size, the first byte is in the
! 	 least significant part of the first register.  The
! 	 remaining bytes in remaining registers. Interestingly,
! 	 when such values are passed in, the last byte is in the
! 	 most significant byte of that same register - wierd. */
!       memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM) + 1, len);
      }
  }
  


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