This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH] Handle struct_return and char return values for d10v.
- From: Michael Snyder <msnyder at cygnus dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 6 Jun 2002 12:04:14 -0700
- Subject: [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);
}
}