From: Richard Henderson Date: Mon, 2 Jun 2003 16:16:52 +0000 (+0000) Subject: * alpha-tdep.c (alpha_push_dummy_call): Handle COMPLEX types. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7b5e1cb37df34656476b693c53996ec158f92e39;p=binutils-gdb.git * alpha-tdep.c (alpha_push_dummy_call): Handle COMPLEX types. (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2460477268d..2f337d9ff3e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,9 @@ 2003-06-02 Richard Henderson + * 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. diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index e97ff30b524..ff5fe7a6c1e 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -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);