From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26602 invoked by alias); 2 Jun 2003 05:40:47 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 26561 invoked from network); 2 Jun 2003 05:40:46 -0000 Received: from unknown (HELO are.twiddle.net) (64.81.246.98) by sources.redhat.com with SMTP; 2 Jun 2003 05:40:46 -0000 Received: from are.twiddle.net (localhost.localdomain [127.0.0.1]) by are.twiddle.net (8.12.8/8.12.8) with ESMTP id h525ejLH007577 for ; Sun, 1 Jun 2003 22:40:45 -0700 Received: (from rth@localhost) by are.twiddle.net (8.12.8/8.12.8/Submit) id h525ejWO007575 for gdb-patches@sources.redhat.com; Sun, 1 Jun 2003 22:40:45 -0700 X-Authentication-Warning: are.twiddle.net: rth set sender to rth@twiddle.net using -f Date: Mon, 02 Jun 2003 05:40:00 -0000 From: Richard Henderson To: gdb-patches@sources.redhat.com Subject: [RFA] handle complex arguments/return values Message-ID: <20030602054045.GA7569@twiddle.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2003-06/txt/msg00058.txt.bz2 Ok? r~ * alpha-tdep.c (alpha_push_dummy_call): Handle COMPLEX types. (alpha_extract_return_value): Likewise. (alpha_store_return_value): Likewise. --- alpha-tdep.c.4 2003-06-01 22:27:00.000000000 -0700 +++ alpha-tdep.c 2003-06-01 22:30:53.000000000 -0700 @@ -282,6 +282,7 @@ alpha_push_dummy_call (struct gdbarch *g 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 *g 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 } 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 *v } 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);