From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nick Duffek To: ac131313@cygnus.com Cc: gdb@sources.redhat.com Subject: Re: A better register interface Date: Mon, 26 Feb 2001 14:01:00 -0000 Message-id: <200102262210.f1QMAC000611@rtl.cygnus.com> References: <3A8B5C60.92EEABA3@cygnus.com> X-SW-Source: 2001-02/msg00387.html On 14-Feb-2001, Andrew Cagney wrote: >While eventually, I'd like to see a clear separation between the two >sides of the register cache Note that the register cache already separates target and core ("raw" and "cooked") register numbers. REGNUM in core GDB is an opaque identifier that happens to coincide with certain target register numbers, but if a particular target uses a different numbering scheme, it can do so using REGISTER_BUFFER. For example, if PowerPC target "foo" identifies general purpose register 0 as 33, the target can supply the register as follows: char rawbuf[FOO_MAXREG_SIZE]; if (!foo_read_register (33, rawbuf)) error ("can't read register 33"); memcpy (REGISTER_BUFFER (PPC_GP0_REGNUM), rawbuf, REGISTER_SIZE (PPC_GP0_REGNUM)); SET_REGISTER_CACHED (PPC_GP0_REGNUM, 1); > supply_raw_register(RAWNUM, buf, sizeof buf) > set_raw_register_state (RAWNUM, that register valid stuff); > fetch_raw_register(RAWNUM, buf, sizeof buf) > something for value changed? > raw_register_size(RAWNUM) > raw_register_name(RAWNUM) If I understand you correctly, we would also need a target interface to tell the register cache how to map between RAWNUM and cooked REGNUM. For example: /* Associate raw register number RAWNUM in GDBARCH with internal register id REGNUM. */ void map_raw_register (struct gdbarch *gdbarch, int rawnum, int regnum) Right? Or perhaps REGNUM in map_raw_register() would actually be a register name. To catch spelling errors at compile-time rather than run-time, though, register names would have to be presented as C symbols. As far as I can see, there's not much advantage of this: #define PPC_GP0_REGNUM "gp0" #define PPC_GP1_REGNUM "gp1" ... over this: enum { PPC_GP0_REGNUM, PPC_GP1_REGNUM, ... }; So with your proposal, the architecture "foo" example above would be accomplished as follows: map_raw_register (gdbarch, 33, PPC_GP0_REGNUM); ... supply_raw_register(RAWNUM, buf, sizeof buf) The map_raw_register() call would be performed in the appropriate gdbarch initialization phase. That looks like a reasonable change to me, but it doesn't significantly reduce code complexity: for a particular piece of hardware, we'd still have M*N map_raw_register() sequences, where M is the number of ISAs and N is the number of targets. To address that complexity, we could formalize the concept of pure hardware descriptions, perhaps autogenerated from CGEN. They would define canonical register names, sizes, default types, numeric IDs, default groupings, etc. Targets would provide mappings from their numbers to those IDs if necessary. ISAs could override register names, add pseudo-registers, etc. These hardware descriptions could be stored in *-hwdep.c and *-hwdep.h. Nick