Fix complex floats on sparc.

* sparc-tdep.h (SPARC_F2_REGNUM, SPARC_F3_REGNUM, SPARC_F4_REGNUM,
	SPARC_F5_REGNUM, SPARC_F6_REGNUM, SPARC_F7_REGNUM): New enums.
	* sparc-tdep.c (sparc_complex_floating_p): New function.
	(sparc32_store_arguments): Handle complex floats.
	(sparc32_extract_return_value): Likewise.
	(sparc32_store_return_value): Likewise.
	(sparc32_stabs_argument_has_addr): Likewise.
	* sparc64-tdep.c (sparc64_complex_floating_p): New function.
	(sparc64_store_floating_fields): Handle complex floats.
	(sparc64_store_arguments): Likewise.
	(sparc64_store_return_value): Likewise.
This commit is contained in:
David S. Miller 2011-09-28 17:59:42 +00:00
parent 766ad87609
commit fe10a582b6
4 changed files with 97 additions and 10 deletions

View file

@ -1,3 +1,17 @@
2011-09-28 David S. Miller <davem@davemloft.net>
* sparc-tdep.h (SPARC_F2_REGNUM, SPARC_F3_REGNUM, SPARC_F4_REGNUM,
SPARC_F5_REGNUM, SPARC_F6_REGNUM, SPARC_F7_REGNUM): New enums.
* sparc-tdep.c (sparc_complex_floating_p): New function.
(sparc32_store_arguments): Handle complex floats.
(sparc32_extract_return_value): Likewise.
(sparc32_store_return_value): Likewise.
(sparc32_stabs_argument_has_addr): Likewise.
* sparc64-tdep.c (sparc64_complex_floating_p): New function.
(sparc64_store_floating_fields): Handle complex floats.
(sparc64_store_arguments): Likewise.
(sparc64_store_return_value): Likewise.
2011-09-28 Eli Zaretskii <eliz@gnu.org> 2011-09-28 Eli Zaretskii <eliz@gnu.org>
* windows-nat.c (env_sort) [!__CYGWIN__]: Function restored from * windows-nat.c (env_sort) [!__CYGWIN__]: Function restored from

View file

@ -221,6 +221,25 @@ sparc_floating_p (const struct type *type)
return 0; return 0;
} }
/* Check whether TYPE is "Complex Floating". */
static int
sparc_complex_floating_p (const struct type *type)
{
switch (TYPE_CODE (type))
{
case TYPE_CODE_COMPLEX:
{
int len = TYPE_LENGTH (type);
return (len == 8 || len == 16 || len == 32);
}
default:
break;
}
return 0;
}
/* Check whether TYPE is "Structure or Union". /* Check whether TYPE is "Structure or Union".
In terms of Ada subprogram calls, arrays are treated the same as In terms of Ada subprogram calls, arrays are treated the same as
@ -454,7 +473,8 @@ sparc32_store_arguments (struct regcache *regcache, int nargs,
int len = TYPE_LENGTH (type); int len = TYPE_LENGTH (type);
if (sparc_structure_or_union_p (type) if (sparc_structure_or_union_p (type)
|| (sparc_floating_p (type) && len == 16)) || (sparc_floating_p (type) && len == 16)
|| sparc_complex_floating_p (type))
{ {
/* Structure, Union and Quad-Precision Arguments. */ /* Structure, Union and Quad-Precision Arguments. */
sp -= len; sp -= len;
@ -1233,17 +1253,29 @@ sparc32_extract_return_value (struct type *type, struct regcache *regcache,
gdb_byte *valbuf) gdb_byte *valbuf)
{ {
int len = TYPE_LENGTH (type); int len = TYPE_LENGTH (type);
gdb_byte buf[8]; gdb_byte buf[32];
gdb_assert (!sparc_structure_or_union_p (type)); gdb_assert (!sparc_structure_or_union_p (type));
gdb_assert (!(sparc_floating_p (type) && len == 16)); gdb_assert (!(sparc_floating_p (type) && len == 16));
if (sparc_floating_p (type)) if (sparc_floating_p (type) || sparc_complex_floating_p (type))
{ {
/* Floating return values. */ /* Floating return values. */
regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf); regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf);
if (len > 4) if (len > 4)
regcache_cooked_read (regcache, SPARC_F1_REGNUM, buf + 4); regcache_cooked_read (regcache, SPARC_F1_REGNUM, buf + 4);
if (len > 8)
{
regcache_cooked_read (regcache, SPARC_F2_REGNUM, buf + 8);
regcache_cooked_read (regcache, SPARC_F3_REGNUM, buf + 12);
}
if (len > 16)
{
regcache_cooked_read (regcache, SPARC_F4_REGNUM, buf + 16);
regcache_cooked_read (regcache, SPARC_F5_REGNUM, buf + 20);
regcache_cooked_read (regcache, SPARC_F6_REGNUM, buf + 24);
regcache_cooked_read (regcache, SPARC_F7_REGNUM, buf + 28);
}
memcpy (valbuf, buf, len); memcpy (valbuf, buf, len);
} }
else else
@ -1281,13 +1313,25 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache,
gdb_assert (!(sparc_floating_p (type) && len == 16)); gdb_assert (!(sparc_floating_p (type) && len == 16));
gdb_assert (len <= 8); gdb_assert (len <= 8);
if (sparc_floating_p (type)) if (sparc_floating_p (type) || sparc_complex_floating_p (type))
{ {
/* Floating return values. */ /* Floating return values. */
memcpy (buf, valbuf, len); memcpy (buf, valbuf, len);
regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf); regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf);
if (len > 4) if (len > 4)
regcache_cooked_write (regcache, SPARC_F1_REGNUM, buf + 4); regcache_cooked_write (regcache, SPARC_F1_REGNUM, buf + 4);
if (len > 8)
{
regcache_cooked_write (regcache, SPARC_F2_REGNUM, buf + 8);
regcache_cooked_write (regcache, SPARC_F3_REGNUM, buf + 12);
}
if (len > 16)
{
regcache_cooked_write (regcache, SPARC_F4_REGNUM, buf + 16);
regcache_cooked_write (regcache, SPARC_F5_REGNUM, buf + 20);
regcache_cooked_write (regcache, SPARC_F6_REGNUM, buf + 24);
regcache_cooked_write (regcache, SPARC_F7_REGNUM, buf + 28);
}
} }
else else
{ {
@ -1351,7 +1395,8 @@ static int
sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type) sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
{ {
return (sparc_structure_or_union_p (type) return (sparc_structure_or_union_p (type)
|| (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)); || (sparc_floating_p (type) && TYPE_LENGTH (type) == 16)
|| sparc_complex_floating_p (type));
} }
static int static int

View file

@ -114,6 +114,12 @@ enum sparc_regnum
SPARC_I7_REGNUM, /* %i7 */ SPARC_I7_REGNUM, /* %i7 */
SPARC_F0_REGNUM, /* %f0 */ SPARC_F0_REGNUM, /* %f0 */
SPARC_F1_REGNUM, SPARC_F1_REGNUM,
SPARC_F2_REGNUM,
SPARC_F3_REGNUM,
SPARC_F4_REGNUM,
SPARC_F5_REGNUM,
SPARC_F6_REGNUM,
SPARC_F7_REGNUM,
SPARC_F31_REGNUM /* %f31 */ SPARC_F31_REGNUM /* %f31 */
= SPARC_F0_REGNUM + 31 = SPARC_F0_REGNUM + 31
}; };

View file

@ -103,6 +103,26 @@ sparc64_floating_p (const struct type *type)
return 0; return 0;
} }
/* Check whether TYPE is "Complex Floating". */
static int
sparc64_complex_floating_p (const struct type *type)
{
switch (TYPE_CODE (type))
{
case TYPE_CODE_COMPLEX:
{
int len = TYPE_LENGTH (type);
gdb_assert (len == 8 || len == 16 || len == 32);
}
return 1;
default:
break;
}
return 0;
}
/* Check whether TYPE is "Structure or Union". /* Check whether TYPE is "Structure or Union".
In terms of Ada subprogram calls, arrays are treated the same as In terms of Ada subprogram calls, arrays are treated the same as
@ -622,11 +642,13 @@ static void
sparc64_store_floating_fields (struct regcache *regcache, struct type *type, sparc64_store_floating_fields (struct regcache *regcache, struct type *type,
const gdb_byte *valbuf, int element, int bitpos) const gdb_byte *valbuf, int element, int bitpos)
{ {
int len = TYPE_LENGTH (type);
gdb_assert (element < 16); gdb_assert (element < 16);
if (sparc64_floating_p (type)) if (sparc64_floating_p (type)
|| (sparc64_complex_floating_p (type) && len <= 16))
{ {
int len = TYPE_LENGTH (type);
int regnum; int regnum;
if (len == 16) if (len == 16)
@ -886,7 +908,7 @@ sparc64_store_arguments (struct regcache *regcache, int nargs,
if (element < 16) if (element < 16)
sparc64_store_floating_fields (regcache, type, valbuf, element, 0); sparc64_store_floating_fields (regcache, type, valbuf, element, 0);
} }
else if (sparc64_floating_p (type)) else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
{ {
/* Floating arguments. */ /* Floating arguments. */
if (len == 16) if (len == 16)
@ -901,7 +923,7 @@ sparc64_store_arguments (struct regcache *regcache, int nargs,
if (element < 16) if (element < 16)
regnum = SPARC64_D0_REGNUM + element; regnum = SPARC64_D0_REGNUM + element;
} }
else else if (len == 4)
{ {
/* The psABI says "Each single-precision parameter value /* The psABI says "Each single-precision parameter value
will be assigned to one extended word in the will be assigned to one extended word in the
@ -1067,7 +1089,7 @@ sparc64_store_return_value (struct type *type, struct regcache *regcache,
if (TYPE_CODE (type) != TYPE_CODE_UNION) if (TYPE_CODE (type) != TYPE_CODE_UNION)
sparc64_store_floating_fields (regcache, type, buf, 0, 0); sparc64_store_floating_fields (regcache, type, buf, 0, 0);
} }
else if (sparc64_floating_p (type)) else if (sparc64_floating_p (type) || sparc64_complex_floating_p (type))
{ {
/* Floating return values. */ /* Floating return values. */
memcpy (buf, valbuf, len); memcpy (buf, valbuf, len);