This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch/wip] Save/restore cooked registers


>  > 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.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]