* alpha-tdep.c (alpha_push_dummy_call): Handle COMPLEX types.

(alpha_extract_return_value): Likewise.
        (alpha_store_return_value): Likewise.
This commit is contained in:
Richard Henderson 2003-06-02 16:16:52 +00:00
parent 24064b5c1a
commit 7b5e1cb37d
2 changed files with 79 additions and 2 deletions

View File

@ -1,5 +1,9 @@
2003-06-02 Richard Henderson <rth@redhat.com>
* alpha-tdep.c (alpha_push_dummy_call): Handle COMPLEX types.
(alpha_extract_return_value): Likewise.
(alpha_store_return_value): Likewise.
* alpha-tdep.c (alpha_extract_return_value): Handle IEEE Quad floats.
(alpha_store_return_value): Error on IEEE Quad floats.

View File

@ -282,6 +282,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
arg = value_cast (arg_type, arg);
}
break;
case TYPE_CODE_FLT:
/* "float" arguments loaded in registers must be passed in
register format, aka "double". */
@ -306,6 +307,28 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
arg = value_from_pointer (arg_type, sp);
}
break;
case TYPE_CODE_COMPLEX:
/* ??? The ABI says that complex values are passed as two
separate scalar values. This distinction only matters
for complex float. However, GCC does not implement this. */
/* Tru64 5.1 has a 128-bit long double, and passes this by
invisible reference. */
if (TYPE_LENGTH (arg_type) == 32)
{
/* Allocate aligned storage. */
sp = (sp & -16) - 16;
/* Write the real data into the stack. */
write_memory (sp, VALUE_CONTENTS (arg), 32);
/* Construct the indirection. */
arg_type = lookup_pointer_type (arg_type);
arg = value_from_pointer (arg_type, sp);
}
break;
default:
break;
}
@ -384,13 +407,14 @@ static void
alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
void *valbuf)
{
int length = TYPE_LENGTH (valtype);
char raw_buffer[ALPHA_REGISTER_SIZE];
ULONGEST l;
switch (TYPE_CODE (valtype))
{
case TYPE_CODE_FLT:
switch (TYPE_LENGTH (valtype))
switch (length)
{
case 4:
regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, raw_buffer);
@ -411,10 +435,34 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
}
break;
case TYPE_CODE_COMPLEX:
switch (length)
{
case 8:
/* ??? This isn't correct wrt the ABI, but it's what GCC does. */
regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
break;
case 16:
regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
regcache_cooked_read (regcache, ALPHA_FP0_REGNUM+1,
(char *)valbuf + 8);
break;
case 32:
regcache_cooked_read_signed (regcache, ALPHA_V0_REGNUM, &l);
read_memory (l, valbuf, 32);
break;
default:
abort ();
}
break;
default:
/* Assume everything else degenerates to an integer. */
regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l);
store_unsigned_integer (valbuf, TYPE_LENGTH (valtype), l);
store_unsigned_integer (valbuf, length, l);
break;
}
}
@ -466,6 +514,31 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
}
break;
case TYPE_CODE_COMPLEX:
switch (length)
{
case 8:
/* ??? This isn't correct wrt the ABI, but it's what GCC does. */
regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
break;
case 16:
regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
regcache_cooked_write (regcache, ALPHA_FP0_REGNUM+1,
(const char *)valbuf + 8);
break;
case 32:
/* FIXME: 128-bit long doubles are returned like structures:
by writing into indirect storage provided by the caller
as the first argument. */
error ("Cannot set a 128-bit long double return value.");
default:
abort ();
}
break;
default:
/* Assume everything else degenerates to an integer. */
l = unpack_long (valtype, valbuf);