This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [patch/wip] Save/restore cooked registers
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: Elena Zannoni <ezannoni at redhat dot com>, Andrew Cagney <ac131313 at ges dot redhat dot com>
- Cc: Kevin Buettner <kevinb at redhat dot com>, gdb-patches at sources dot redhat dot com, Richard dot Earnshaw at arm dot com
- Date: Wed, 28 Aug 2002 15:23:02 +0100
- Subject: Re: [patch/wip] Save/restore cooked registers
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
> > If I'm not mistaken, the pseudos on the e500 are synthesized from the
> > raw registers without the need for outside sources such as memory.
> > That being the case, saving the raw registers (or, more precisely, the
> > cooked registers corresponding to the raw registers) should be
> > sufficient.
> >
>
> Yes. I was thinking about this other problem I encountered:
> http://sources.redhat.com/ml/gdb-patches/2002-08/msg00689.html
>
> > In fact, for the e500, I think we'll need to take care NOT to write
> > back the pseudos since this could potentially cause information to
> > be lost. It would depend upon the order in which things were done.
> > If the pseudos are restored after the raw registers that they map
> > onto, the most significant bits would likely be wiped out. (In this
> > case the pseudos are narrower than the raw registers, right?)
> >
>
> The pseudo register write function is written so that it preserves the
> upper bits. If you use that technique you should be safe.
Ok, this is theoretical since I can't point to a machine where this is in
fact the case; but I do think it would be a reasonable implementation.
Consider a machine where a floating point register can contain either a
double or a single-precision value. The 'type' in the register is stored
in some special bit in the register that indicates the type. Now, if we
start saving and restoring the cooked registers in this context then the
order in which they are called is critical to restoring the correct value.
Consider the case where the raw register, f0_raw, contains a 'float' value.
Now we extract both the float and the double representations into the two
pseudos s0 and d0 (what we put into d0 doesn't really matter, it could be
a 'double' visualization of f0_raw, or it could be some other value, eg
NaN or 0). However, when we restore the values then if we restore s0
before restoring d0 then f0_raw will contain an invalid value and that
could cause a fault on continuing.
I really don't see what saving and restoring the cooked-but-not-raw
registers buys us. These should never have any persistent storage (which
might need saving) and should always be calculable on demand from the bits
in the raw registers -- similarly a write to a pseudo should always update
the corresponding raw registers, so again there is no need to have any
persistent storage for them.
In summary, I still think that cooked registers should just be considered
as views of the raw register set and that there should never be any need
to save or restore the views, just the underlying data that is the
registers themselves.
Going back to some of the points raised in Andrew's original mail:
> I'd like to propose the following changes to the register cache:
> - save/restore cooked, rather than raw, registers
No, I really think this is a backwards step.
> This would make it possible to save memory based registers across an
> inferior call or return. By default, only [0..NUM_REGS) cooked registers
> would be saved and since they are 1:1 with the raw registers, existing new
> code wouldn't notice the change.
> I suspect this is why the old code was saving the full register range.
I think it saved the entire range because it didn't know any better.
> - disallow writes to a saved copy of the register cache
I don't see that this matters, see below.
> If this isn't done, there is a problem with keeping the cooked registers coherent.
No, the cooked registers can never be incoherrent if you just consider
them as view-ports onto a register-cache set. That is, they have no
persistent state in themselves.
I really think we need to break this implicit link between the raw regs
and part of the cooked regs, it just causes no-end of confusion. It's
fine if we want to say that some cooked regs are mapped 1:1 onto part of
the raw regcache, but that should/must be a back-end convenience, and not
part of gdb's fundamental design (that is asking for the r0 cooked view
may just happen to fetch the raw r0 register that is at offset zero in the
regcache, but nothing in GDB-core should assume this).
If you are trying to just add some code that optimizes the storing of
registers back to the inferior, then surely the easiest way to do this is
to have a further 'inferior' set of values that we never update, then when
we need to update a value we check to see if the value we want to write
matches that which we know the inferior to have and suppress the write if
there is no change.
R.