Re: [WIP/RFC] MIPS registers overhaul

Kevin Buettner
2003-05-16T17:20:05Z

On May 15, 11:57pm, Andrew Cagney wrote:

> >> > BTW, the raw floating point registers are still accessible. Doing
> >> > "info registers raw" will display all of the raw registers. Or, if
> >> > you know the names of the registers you want to display, you can do,
> >> > e.g, "info registers raw_f20".
> >
> >>
> >> Hmm, is this necessary? Confusing? ``maint print
> >> {raw-,cooked-,}registers'' are already available and provide access to
> >> the underlying values.
> >
> >
> > Maybe we need to name the prefix something different than "raw_"?
> >
> > Whatever we call them, I think it's still useful to have names
> > associated with them. E.g, you can do any of the following:
> >
> > print $raw_f20
> > print/x ($raw_f20 >> 32)
> > set $raw_f20=0xbadbeef
>
> But how often will that actually happen?

Personally, I don't think that it'll happen that often. If, however,
the 32 unpredictable bits of a floating point register (for o32) are
meaningful, it may be useful to be able to manipulate the raw register
in various ways.

> I think a user debugging o32 on ISA64 still should expect to be
> manipulating the full 64 bit register.

I disagree. When debugging o32, the FR bit in the CP0 status register
should be 0 and, according to the MIPS64 documentation, the FPRs are
treated as 32 32-bit registers.

> Only on ISA32 should the
> registers be restricted to their 32 bit values.
>
> Even if the upper 32 bits of the FP registers are unpredictable, I think
> they should still be displayed.

With my WIP patch, for o32 single precision code, you'll something like
this:

(gdb) p $f20
$2 = {i = 18446744070510660813, f = 13.3000002, d = -nan(0xfffff4154cccd)}

For double precision code, you'll instead see:

(gdb) p $f20
$3 = {i = 4623676852435261850, f = -1.58818684e-23, d = 13.300000000000001}

where the 13.3 value in both cases is the value of interest.

If I were to do as you suggest and display the full 64 bits of the raw
f20, you'd never be able to see that interesting 13.3 value for the
double case. (This is because the bits which form the double are
split between raw f20 and raw f21.) The user should expect to see
values which make sense for the mode of the processor. As I said
before, if the user suspects that something else is going on, they
still have recourse to $raw_f20 and $raw_f21 for looking at the full
64-bit register. E.g.:

(gdb) p/x $raw_f20
$5 = 0xffffffff9999999a
(gdb) p/x $raw_f21
$6 = 0x402a9999

And, for reference:

(gdb) p/x $f20.i
$7 = 0x402a99999999999a

If you really think that the $f20 name should be the full 64-bit register
regardless of the fact that 32-bits are meaningless, then lets just take
the "raw_" prefix off of them and put a prefix on the cooked names. Maybe
we should call them "cooked_f20" or "pretty_f20" or some such.

I do agree that we want to provide the user with the ability to look
at the full 64-bit value, but I think it's also important that the
user be able to see values that make the most sense for the mode that
the processor is in. My WIP patch provides you with the ability to
see both. It sounds like you may have an objection to the names that
I've chosen. If that's the case, then I'm willing to discard the
"raw_" prefix on the raw floating point registers and put a different
prefix on the cooked fp registers.

[...]
> > I think that you definitely want "last_arg_regnum" and
> > "last_fp_arg_regnum" to appear in both structs. At the moment, the
> > various MIPS *_push_argument() code uses the register names from the
> > raw regnums struct. I think it may be desirable at some point to make
> > this code use cooked regnums instead. (It will hopefully simplify a
> > bunch of code that worries about shifting values to the correct
> > position within a register.) For the floating point registers, where
> > the cooked and raw numbers are actually different, we would like
> > "first_fp_arg_regnum" and "last_fp_arg_regnum" to actually refer to
> > numbers within this space.
>
> The only code that should manipulate the raw register values
> (regcache_raw_*) is:
> - the cooked <-> raw mapping functions
> - the target side code that supplies register values
> The rest should use cooked values. Hence, I think the variables like
> last_arg_regnum has a strictly cooked value (note that a cooked register
> number can fall in the range [0 .. NUM_REGS).

Well, ideally, yes. But, I think it's going to be a while before we
get there. As a specific example, consider the various MIPS
push_arguments code. At the present time, this code is written to use
raw numbers and will need to be converted at some point to use cooked
numbers. For last_fp_arg_regnum, the raw and cooked numbers will
differ, and, I expect that the various push_arguments functions will
be converted incrementally, so it is important that this field appear
in both structs. (I should note that I have this detail wrong in my
WIP patch. I forgot to set the cooked value for last_fp_arg_regnum.
That means that the cooked value is the same as the raw value which is
wrong.)

I will also note that since last_fp_arg_regnum is _only_ used by the
push_arguments code, it would be possible to seperate this value out,
BUT, it will be necessary for the code which initializes
last_fp_arg_regnum to keep track of whether or not the appropriate
push_arguments function has been converted or not. mips_gdbarch_init()
will need to be rearranged somewhat in order for this to occur.

> >> How do you know that the raw register numbers were computed correctly?
> >
> >
> > I just used the same values as the macros used to use. The user can see
> > what they are via "maint print architecture".
>
> I'm wondering how you know that the transformation from macro (defined
> in .h files?) to variables worked?

By inspection and by testing.

Kevin