-\f
-/* Low level examining and depositing of registers.
-
- The caller is responsible for making
- sure that the inferior is stopped before calling the fetching routines,
- or it will get garbage. (a change from GDB version 3, in which
- the caller got the value from the last stop). */
-
-/* Contents of the registers in target byte order.
- We allocate some extra slop since we do a lot of memcpy's around `registers',
- and failing-soft is better than failing hard. */
-char registers[REGISTER_BYTES + /* SLOP */ 256];
-
-/* Nonzero if that register has been fetched. */
-char register_valid[NUM_REGS];
-
-/* The thread/process associated with the current set of registers. For now,
- -1 is special, and means `no current process'. */
-int registers_pid = -1;
-
-/* Indicate that registers may have changed, so invalidate the cache. */
-
-void
-registers_changed ()
-{
- int i;
- int numregs = ARCH_NUM_REGS;
-
- registers_pid = -1;
-
- for (i = 0; i < numregs; i++)
- register_valid[i] = 0;
-
- if (registers_changed_hook)
- registers_changed_hook ();
-}
-
-/* Indicate that all registers have been fetched, so mark them all valid. */
-void
-registers_fetched ()
-{
- int i;
- int numregs = ARCH_NUM_REGS;
- for (i = 0; i < numregs; i++)
- register_valid[i] = 1;
-}
-
-/* read_register_bytes and write_register_bytes are generally a *BAD* idea.
- They are inefficient because they need to check for partial updates, which
- can only be done by scanning through all of the registers and seeing if the
- bytes that are being read/written fall inside of an invalid register. [The
- main reason this is necessary is that register sizes can vary, so a simple
- index won't suffice.] It is far better to call read_register_gen if you
- want to get at the raw register contents, as it only takes a regno as an
- argument, and therefore can't do a partial register update. It would also
- be good to have a write_register_gen for similar reasons.
-
- Prior to the recent fixes to check for partial updates, both read and
- write_register_bytes always checked to see if any registers were stale, and
- then called target_fetch_registers (-1) to update the whole set. This
- caused really slowed things down for remote targets. */
-
-/* Copy INLEN bytes of consecutive data from registers
- starting with the INREGBYTE'th byte of register data
- into memory at MYADDR. */
-
-void
-read_register_bytes (inregbyte, myaddr, inlen)
- int inregbyte;
- char *myaddr;
- int inlen;
-{
- int inregend = inregbyte + inlen;
- int regno;
-
- if (registers_pid != inferior_pid)
- {
- registers_changed ();
- registers_pid = inferior_pid;
- }
-
- /* See if we are trying to read bytes from out-of-date registers. If so,
- update just those registers. */
-
- for (regno = 0; regno < NUM_REGS; regno++)
- {
- int regstart, regend;
- int startin, endin;
-
- if (register_valid[regno])
- continue;
-
- regstart = REGISTER_BYTE (regno);
- regend = regstart + REGISTER_RAW_SIZE (regno);
-
- startin = regstart >= inregbyte && regstart < inregend;
- endin = regend > inregbyte && regend <= inregend;
-
- if (!startin && !endin)
- continue;
-
- /* We've found an invalid register where at least one byte will be read.
- Update it from the target. */
-
- target_fetch_registers (regno);
-
- if (!register_valid[regno])
- error ("read_register_bytes: Couldn't update register %d.", regno);
- }
-
- if (myaddr != NULL)
- memcpy (myaddr, ®isters[inregbyte], inlen);
-}
-
-/* Read register REGNO into memory at MYADDR, which must be large enough
- for REGISTER_RAW_BYTES (REGNO). Target byte-order.
- If the register is known to be the size of a CORE_ADDR or smaller,
- read_register can be used instead. */
-void
-read_register_gen (regno, myaddr)
- int regno;
- char *myaddr;
-{
- if (registers_pid != inferior_pid)
- {
- registers_changed ();
- registers_pid = inferior_pid;
- }
-
- if (!register_valid[regno])
- target_fetch_registers (regno);
- memcpy (myaddr, ®isters[REGISTER_BYTE (regno)],
- REGISTER_RAW_SIZE (regno));
-}
-
-/* Write register REGNO at MYADDR to the target. MYADDR points at
- REGISTER_RAW_BYTES(REGNO), which must be in target byte-order. */
-
-void
-write_register_gen (regno, myaddr)
- int regno;
- char *myaddr;
-{
- int size;
-
- /* On the sparc, writing %g0 is a no-op, so we don't even want to change
- the registers array if something writes to this register. */
- if (CANNOT_STORE_REGISTER (regno))
- return;
-
- if (registers_pid != inferior_pid)
- {
- registers_changed ();
- registers_pid = inferior_pid;
- }
-
- size = REGISTER_RAW_SIZE(regno);
-
- /* If we have a valid copy of the register, and new value == old value,
- then don't bother doing the actual store. */
-
- if (register_valid [regno]
- && memcmp (®isters[REGISTER_BYTE (regno)], myaddr, size) == 0)
- return;
-
- target_prepare_to_store ();
-
- memcpy (®isters[REGISTER_BYTE (regno)], myaddr, size);
-
- register_valid [regno] = 1;
-
- target_store_registers (regno);
-}
-
-/* Copy INLEN bytes of consecutive data from memory at MYADDR
- into registers starting with the MYREGSTART'th byte of register data. */
-
-void
-write_register_bytes (myregstart, myaddr, inlen)
- int myregstart;
- char *myaddr;
- int inlen;
-{
- int myregend = myregstart + inlen;
- int regno;
-
- target_prepare_to_store ();
-
- /* Scan through the registers updating any that are covered by the range
- myregstart<=>myregend using write_register_gen, which does nice things
- like handling threads, and avoiding updates when the new and old contents
- are the same. */
-
- for (regno = 0; regno < NUM_REGS; regno++)
- {
- int regstart, regend;
- int startin, endin;
- char regbuf[MAX_REGISTER_RAW_SIZE];
-
- regstart = REGISTER_BYTE (regno);
- regend = regstart + REGISTER_RAW_SIZE (regno);
-
- startin = regstart >= myregstart && regstart < myregend;
- endin = regend > myregstart && regend <= myregend;
-
- if (!startin && !endin)
- continue; /* Register is completely out of range */
-
- if (startin && endin) /* register is completely in range */
- {
- write_register_gen (regno, myaddr + (regstart - myregstart));
- continue;
- }
-
- /* We may be doing a partial update of an invalid register. Update it
- from the target before scribbling on it. */
- read_register_gen (regno, regbuf);
-
- if (startin)
- memcpy (registers + regstart,
- myaddr + regstart - myregstart,
- myregend - regstart);
- else /* endin */
- memcpy (registers + myregstart,
- myaddr,
- regend - myregstart);
- target_store_registers (regno);
- }
-}
-
-/* Return the raw contents of register REGNO, regarding it as an integer. */
-/* This probably should be returning LONGEST rather than CORE_ADDR. */
-
-CORE_ADDR
-read_register (regno)
- int regno;
-{
- if (registers_pid != inferior_pid)
- {
- registers_changed ();
- registers_pid = inferior_pid;
- }
-
- if (!register_valid[regno])
- target_fetch_registers (regno);
-
- return extract_address (®isters[REGISTER_BYTE (regno)],
- REGISTER_RAW_SIZE(regno));
-}