From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29989 invoked by alias); 15 Jun 2003 17:23:29 -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 29982 invoked from network); 15 Jun 2003 17:23:29 -0000 Received: from unknown (HELO localhost.redhat.com) (24.157.166.107) by sources.redhat.com with SMTP; 15 Jun 2003 17:23:29 -0000 Received: from redhat.com (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 396742B5F; Sun, 15 Jun 2003 13:23:21 -0400 (EDT) Message-ID: <3EECAB89.10609@redhat.com> Date: Sun, 15 Jun 2003 17:23:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-US; rv:1.0.2) Gecko/20030223 X-Accept-Language: en-us, en MIME-Version: 1.0 To: cgd@broadcom.com, Kevin Buettner Cc: gdb-patches@sources.redhat.com Subject: Re: [WIP/RFC] MIPS registers overhaul References: <1030510002453.ZM3880@localhost.localdomain> <3EBD6131.30209@redhat.com> <1030514220025.ZM10373@localhost.localdomain> <3EC461C1.1080104@redhat.com> <3ECA8EC6.6030405@redhat.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2003-06/txt/msg00518.txt.bz2 >> For instance, do a 64 bit FP restore then clear the FR bit; the reverse; >> some other variant; ...? > > > So, if the process is running with FR=0, then the save/restore should > ("must" i believe) be done with FR=0. > > When FR=0, there are two options as to how to do it: > > for (i = 0; i < 32; i++) > move/store word from c1 reg $i (i.e., dmfc1/sdc1) mfc1/sc1 > OR: > > for (i = 0; i < 32; i += 2) > move/store dword from c1 reg $i (i.e., dmfc1/sdc1) OK, I'm going to go out on a limb here. I don't think the two are equivalent, and I think the second is wrong. For big-endian, the second would store fp[n+0] ||| fp[n+1] backwards. When extracting a double from a MIPS register pair, GDB does the rough equivalent of: if (big-endian && type == double) memcpy (dest + 0, &fp[regnum + 1], 4); memcpy (dest + 4, &fp[regnum + 0], 4); else if (little-endian && type == double) memcpy (dest + 0, &fp[regnum + 0], 4); memcpy (dest + 4, &fp[regnum + 1], 4); (See register_to_type. The code dates back to ~92 and was added to fix IRIX double value display problems.) The effect is to always get the least significant part of a double value from fp[n+0], and the most significant from fp[n+1]. Given MIPS xor endian sillyness, it's hard to see this is happening, however looking at (MIPS IV ref 3.2) DMFC1, given a 32 bit FGR, it does: GPR[rt] = FGR[fs+1] ||| FGR[fs+0] A double word store of that GPR would then order the value as: 0: FGR[fs+0] 1: FGR[fs+1] little endian, and 0: FGR[fs+1] 1: FGR[fs+0] big endian. If you stare at LDC1 long enough, remembering that LoadMemory contains the horrible XOR magic, you'll realise that it has the same effect. Anyway, this, I believe, means that any implementation of: union { float flt; double dbl; int32 i32; int64 i64; } $fp0 is going to need, for BE, a big-byte little-word DOUBLE, and a similar INT64. Otherwize, $f0.int32 would modify the wrong part of the double register. Alternatively, some of those union values could be given magic offsets. Looking at kevin's patch: + t = init_composite_type ("__gdb_mips_type_float_double_register_big", + TYPE_CODE_UNION); + append_composite_type_field (t, "i", builtin_type_uint64); + append_composite_type_field (t, "f", builtin_type_ieee_single_big); + f = &(TYPE_FIELDS (t))[TYPE_NFIELDS (t) - 1]; + FIELD_BITPOS (f[0]) = 32; + append_composite_type_field (t, "d", builtin_type_ieee_double_big); + + TYPE_NAME (t) = "mips_type_float_double_register_big"; It appears to have taken the second option. Andrew > (move to / load for the state restore, of course.) > > (of course, these will typically be written in assembly code, and > "fully unrolled" -- the pseudo-C-code is to demonstrate the concept > only.) > > either one is valid, though all implementations that I know of choose > the latter because it's fewer instructions and almost certainly more > efficient. > > > the linux kernel presents that to o32 userland (o32 ptrace syscall) as > an array of 32 32-bit values, but IIRC it's stored internally as (8 > byte reg, 8 byte pad) * 16.