From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27432 invoked by alias); 6 Dec 2006 16:29:41 -0000 Received: (qmail 27421 invoked by uid 22791); 6 Dec 2006 16:29:39 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate1.de.ibm.com (HELO mtagate1.de.ibm.com) (195.212.29.150) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 06 Dec 2006 16:29:32 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate1.de.ibm.com (8.13.8/8.13.8) with ESMTP id kB6GTSVt147586 for ; Wed, 6 Dec 2006 16:29:28 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.6/8.13.6/NCO v8.1.1) with ESMTP id kB6GTRwc2986056 for ; Wed, 6 Dec 2006 17:29:27 +0100 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id kB6GTRuJ021282 for ; Wed, 6 Dec 2006 17:29:27 +0100 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id kB6GTROh021274; Wed, 6 Dec 2006 17:29:27 +0100 Message-Id: <200612061629.kB6GTROh021274@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Wed, 6 Dec 2006 17:29:27 +0100 Subject: Re: [RFA][2/5] New port: Cell BE SPU (valops.c fix) To: drow@false.org (Daniel Jacobowitz) Date: Wed, 06 Dec 2006 16:29:00 -0000 From: "Ulrich Weigand" Cc: jimb@codesourcery.com (Jim Blandy), gdb-patches@sourceware.org In-Reply-To: <20061128000117.GA21865@nevyn.them.org> from "Daniel Jacobowitz" at Nov 27, 2006 07:01:17 PM X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-12/txt/msg00064.txt.bz2 Daniel Jacobowitz wrote: > On Tue, Nov 28, 2006 at 12:23:34AM +0100, Ulrich Weigand wrote: > > However, I still think there's something fundamentally broken in the > > way value_assign calls VALUE_TO_REGISTER. As the documentation says, > > that gdbarch functions is supposed to "convert a data value of type > > TYPE to register number REG's raw format". Calling the conversion > > function with a type that does not actually denote the type of the > > register contents, but some subfield, must break all other implementations > > of that routine as well ... > > Except that I suspect there are no other implementations of > VALUE_TO_REGISTER which offer any subfields. It was usually used for > things like registers which can only hold a float by converting it to > double, and those floating point registers generally can't hold > arbitrary structs or arrays. > > There might be some trouble on i386 though... I think you'd need > extraordinary bad luck to trigger it. A field of a struct spread > across multiple registers. > > These three hooks are simply not very clearly defined. Here's an overview of what register_to_value / value_to_register are currently being used for on various platforms: arch float reg float values type of only only conversion alpha Y N special i387 (*) Y Y float i386 N N multi-reg ia64 Y Y float m68k Y Y float mips Y Y multi-reg rs6000 Y Y float s390 Y N offset spu N N offset (*) on amd64 and i386 The default code extracts a value from a register using a certain set of assumptions: the bits making up the value are the same for values in registers as in memory, and there is well-defined way to *find* which bits of the register(s) make up that value. Depending on which of those assumptions is violated, different platforms use r_t_v / v_t_r for different purposes: - On some platforms, the bits in the register are the same as in memory, they're just not at the default location: * For multi-register values, the value is not formed by registers concatenated like X, X+1, X+2, ... -> This is the case for 8-byte float values on mips, and for certain multi-register values on i386. ("multi-reg") * For single-register values of size smaller than register size, the bits are not at the default offset -> This is the case for 4-byte values in s390 float registers, and for all values < 16 bytes on spu. ("offset") - On some platforms, the bits making up the value are themselves different, i.e. a real conversion needs to take place: * Floating point values may need to be converted into a different floating point number format -> E.g. on i387, ia64, m68k, rs6000 ("float") * There's a particular special case on the alpha, where 4-byte integer values may reside in floating point registers, but still undergo a conversion as if to a different floating point format (however, that conversion is fully reversible, so when the value is stored back to memory, we still get the same integer). Independently, we have the question of how to handle sub-types of values in registers. This may happen if the value residing in the register is of aggregate type (struct / bitfield / array). The compiler is free to allocate such values into registers, and may generally do so if the size of the aggregate equals the size of an integral type that would otherwise be allowed to reside in the register in question. If this happens to a register under r_t_v / v_t_r conversion, the current implementation is broken, since v_t_r may be called with a different base type than r_t_v. This is not an issue for those platforms that only ever accept floating-point types in their r_t_v / v_t_r routines, since those do not have sub-types. However, it remains a problem, at least in principle, for alpha, i386, s390, and spu. Jim's suggestion was to allow the r_t_v / v_t_r routines to set and access the value's offset and bitfield information. This would enable both s390 and spu to encode the non-standard offset in r_t_v, and otherwise use the default methods. However, for i386 and alpha this still would not work, since there's simply not enough information available. Let's assume we have an value of aggregate 8-byte type composed of two 4-byte subfields of type "int". Such a value could reside in a float register on alpha, or the %eax/%edx register pair on i386. Now, when accessing one sub-field of this value via type "int", the target routine needs enough information to distinguish it from the case where you simply have a plain "int" in a register. You could attempt to recognize that using the offset field. And in fact, on i386 it may happen to work after all, because the platform is little-endian and there is no difference between accessing the element at offset 0 in the pair %eax/%edx, and just plain accessing an "int" in %eax. It would definitely break on a platform that swaps multi-register values (like mips floating point registers), and still allows types with sub-fields. On alpha, it doesn't work at all; accessing the value at offset 0 in the 8-byte struct needs completely different code than accessing a simple "int" in the same register, and there is no way how v_t_r can distinguish the two cases. The patch I proposed to remember the type of the value residing in the register would allow all the above cases to work without changes to architecture code, and would in fact work correctly with any conceivable implementation of the current r_t_v / v_t_r interface. However, it does have the disadvantage of requiring an additional field in struct value. (Maybe we can make up that loss -- do we actually still require VALUE_ADDRESS for register values?) Any suggestions? Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com