From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18356 invoked by alias); 20 Jul 2002 03:11:31 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 18347 invoked from network); 20 Jul 2002 03:11:29 -0000 Received: from unknown (HELO zwingli.cygnus.com) (208.245.165.35) by sources.redhat.com with SMTP; 20 Jul 2002 03:11:29 -0000 Received: by zwingli.cygnus.com (Postfix, from userid 442) id 7F5815EA11; Fri, 19 Jul 2002 22:11:27 -0500 (EST) To: Andrew Cagney Cc: gdb@sources.redhat.com Subject: Re: WIP: Register doco References: <3D38AF69.7020902@ges.redhat.com> From: Jim Blandy Date: Fri, 19 Jul 2002 20:11:00 -0000 In-Reply-To: <3D38AF69.7020902@ges.redhat.com> Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.1 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-07/txt/msg00203.txt.bz2 I'm not saying the questions below couldn't be worked out by examining the whole document carefully. But ideally, a document makes sense in the first read-through. Andrew Cagney writes: > @table @emph > @item cooked > @itemize @bullet > @item > manipulated by core @value{GDBN} > @item > correspond to user level, or abi registers Don't you mean "ISA" here, not "ABI"? If I disassemble some code and see an instruction that refers to r12, then I should be able to see that register's value by saying "print $r12". The ABI in use has nothing to do with it. > @end itemize > @item raw > @itemize @bullet > @item > manipulated by target backends > @item > correspond to physical registers I think you're introducing a new term here, "physical", which doesn't do anything for you. When I see "physical", I think of actual flip-flops. But that's clearly not what you're talking about: GDB has no idea how many ports these registers have, whether they get renamed for speculative execution, etc. In effect, all that phrase does is define "raw" in terms of another undefined term, "physical". By "raw", do you really mean the registers as presented by the underlying protocol GDB uses to examine the inferior (be it remote, /proc, or ptrace)? I dunno. > @subsection Raw Registers > > The raw register space, containing @code{NUM_REGS} > @c index NUM_REGS > raw registers, abstracts the instruction set architectures physical > register set. @value{GDBN}'s register cache contains raw registers. > Each raw register is mapped, one-to-one, onto a corresponding physical > register. For instance: > > @itemize @bullet > > @item > For 64 bit architecture that has 32 general purpose registers, the > register cache, and the raw register space would include space for those > 32 registers. > > @item > For an architectures that has register banks, the register cache, and > raw register space would contain space for registers from all banks. > The one-to-one relationship between the raw registers and the > architecture's physical registers being preserved. > > @item > For a 64 bit architecture that is running in 32 bit mode, the register > cache and raw register space would contain the 64 bit hardware > registers. The raw register space would not include cut down 32 bit > registers. By "32 bit mode", do you mean that there's an actual bit on the processor that makes shift, divide, etc. instructions behave as if there were only 32 bits? Or do you mean an ABI that simply only uses the lower 32 bits of the registers? > @item > For an architecture that determines the program-counter by examining the > value of severaal hardware registers, the register cache and raw > register space will contain the separate hardware values. The raw > register space would not include the program-counter. > > @item > For an architecture that has memory mapped registers, those registers > are not be part of the register cache or raw register space (there is no > corresponding hardware register). I think it would be nice to use the IA-64's arrangement as an example here. I assume the raw registers would include the unrotated register file, and the registers that determine how they're rotated at the current point. Whereas the cooked registers would be numbered the way they appear in the machine instructions. > @end itemize > > @emph{Maintainer note: Old architectures, since they didn't know better, > broke all of the above rules, sigh!} > > The raw registers are not necessarily directly visible to the user. > > @emph{Maintainer note: There should be be a @samp{maint info registers} > command so that the raw register cache is visible.} > > @section Cooked Registers > > The core of @value{GDBN} manipulates registers in the cooked register > space. Any external or user visible register is mapped onto the cooked > register space, in particular: > > @itemize @bullet > @item > registers refered to by debug information > @item > user visible registers (specified by name) > @item > mode dependant registers (e.g., a 64 bit architecture in 32 bit mode may > need to manipulate the 32 bits of 64 bit registers) > @item > memory mapped registers > space. > @item > state dependant registers (e.g., bank registers) > @end itemize > > Architecture methods then map the @code{NUM_REGS + NUM_PSEUDO_REGS} > cooked registers onto raw registers or memory. So pseudo registers are different from cooked registers? Or are they the same? If they're the same, then distinguishing NUM_REGS and NUM_PSEUDO_REGS sort of implies that NUM_REGS corresponds to the number of raw registers. But that shouldn't be visible to the outside at all. > While arbitrary mappings > are possible, the first @code{NUM_REGS} registers should be be mapped > direct to the raw registers. The remaining @code{NUM_PSEUDO_REGS then > having more arbitrary mappings. That is: > > @smallexample > cooked: [0..NUM_REGS) [..NUM_REGS+NUM_PSEUDO_REGS) > | / | > | / | > | / | > | / | > raw: RAW REGISTERS MEMORY > @end smallexample One of the problems with this explanation is that we have a real menagerie of different kinds of registers: - raw registers - cooked registers - pseudo registers - whatever you call a cooked register that isn't a pseudo register This is a big source of confusion --- for me, at least. Why can't we just have "cooked" and "raw" registers, and draw the picture like this? > cooked: [0..NUM_REGS) > | \ > | \ > | \ > | \ > raw: RAW REGISTERS MEMORY In other words, given that we're allowing cooked registers to be computed arbitrarily from raw registers and memory contents, why not dispense with pseudo registers altogether? > @section The Register Cache > > @value{GDBN} stores the target register state in a register cache > (@code{struct regcache}). > > The register cache has three separate interfaces: > > @itemize @bullet > @item > cooked > @item > raw > @item > target > @end itemize > > Core @value{GDBN} manipulates the register cache using the cooked > interfaces: > > @deftypefun void regcache_cooked_read (struct regcache > *@var{regcache}, int @var{regnum}, void *@var{buf}) > Read a cooked register value from the register cache (or memory). > @end deftypefun > @deftypefun void regcache_cooked_write (struct regcache > *@var{regcache}, int @var{regnum}, const void *@var{buf}) > Write a cooked register value to the register cache (or memory). > @end deftypefun > > These methods then use corresponding architecture methods to map the > cooked registers onto either raw registers or memory: > > @deftypefun void gdbarch_cooked_register_read (struct gdbarch > *@var{gdbarch}, struct regcache *@var{regcache}, int @var{regnum}, > void *@var{buf}) > Read the specified @var{regnum} register value from the @var{regcache} > (or memory for memory mapped registers). > @end deftypefun > @deftypefun void gdbarch_cooked_register_write (struct gdbarch > *@var{gdbarch}, struct regcache *@var{regcache}, int @var{regnum}, > const void *@var{buf}) > Write the specified @var{regnum} register value into the @var{regcache} > (or memory for memory mapped registers). > @end deftypefun > > The raw register values being manipulated using: > > @deftypefun void regcache_raw_read (struct regcache *@var{regcache}, > int @var{regnum}, void *@var{buf}) > Read a cooked register value from the register cache (or memory). > @end deftypefun > @deftypefun void regcache_raw_write (struct regcache *@var{regcache}, > int @var{regnum}, const void *@var{buf}) > Write a raw register value to the register cache (or memory). > @end deftypefun > > When a raw register read or write needs to go through to the target (the > value isn't yet in the cache or a modification needs to be written to > the target) the register cache state is then manipulated by the target > using the methods: > > @deftypefun regcache_collect (struct regcache *@var{regcache}, int > @var{regnum}, void *@var{buf}) > @end deftypefun > @deftypefun regcache_supply (struct regcache *@var{regcache}, int > @var{regnum}, const void *@var{buf}) > @end deftypefun