int regno;
{
unsigned short sval;
+ unsigned int ival;
unsigned long lval;
+ int size;
+
if (!register_valid[regno])
target_fetch_registers (regno);
- switch (REGISTER_RAW_SIZE(regno))
+ size = REGISTER_RAW_SIZE(regno);
+
+ if (size == sizeof (unsigned char))
+ return registers[REGISTER_BYTE (regno)];
+ else if (size == sizeof (sval))
{
- case sizeof (unsigned char):
- return registers[REGISTER_BYTE (regno)];
- case sizeof (sval):
memcpy (&sval, ®isters[REGISTER_BYTE (regno)], sizeof (sval));
SWAP_TARGET_AND_HOST (&sval, sizeof (sval));
return sval;
- case sizeof (lval):
+ }
+ else if (size == sizeof (ival))
+ {
+ memcpy (&ival, ®isters[REGISTER_BYTE (regno)], sizeof (ival));
+ SWAP_TARGET_AND_HOST (&ival, sizeof (ival));
+ return ival;
+ }
+ else if (size == sizeof (lval))
+ {
memcpy (&lval, ®isters[REGISTER_BYTE (regno)], sizeof (lval));
SWAP_TARGET_AND_HOST (&lval, sizeof (lval));
return lval;
- default:
- error ("Can't handle register size of %d for register %d\n",
- REGISTER_RAW_SIZE(regno), regno);
+ }
+ else
+ {
+ error ("GDB Internal Error in read_register() for register %d, size %d",
+ regno, REGISTER_RAW_SIZE(regno));
}
}
write_register (regno, val)
int regno, val;
{
+ unsigned char cval;
unsigned short sval;
+ unsigned int ival;
unsigned long lval;
-
+ int size;
+ PTR ptr;
+
/* 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;
- target_prepare_to_store ();
+ /* If we have a valid copy of the register, and new value == old value,
+ then don't bother doing the actual store. */
- register_valid [regno] = 1;
+ size = REGISTER_RAW_SIZE(regno);
- switch (REGISTER_RAW_SIZE(regno))
+ if (size == sizeof(cval))
{
- case sizeof (unsigned char):
- registers[REGISTER_BYTE (regno)] = val;
- break;
- case sizeof (sval):
+ ptr = (PTR) &cval;
+ cval = val;
+ }
+ else if (size == sizeof(sval))
+ {
+ ptr = (PTR) &sval;
sval = val;
- SWAP_TARGET_AND_HOST (&sval, sizeof (sval));
- memcpy (®isters[REGISTER_BYTE (regno)], &sval, sizeof (sval));
- break;
- case sizeof (lval):
+ }
+ else if (size == sizeof(ival))
+ {
+ ptr = (PTR) &ival;
+ ival = val;
+ }
+ else if (size == sizeof(lval))
+ {
+ ptr = (PTR) &lval;
lval = val;
- SWAP_TARGET_AND_HOST (&lval, sizeof (lval));
- memcpy (®isters[REGISTER_BYTE (regno)], &lval, sizeof (lval));
- break;
}
+ else
+ {
+ error ("GDB Internal Error in write_register() for register %d, size %d",
+ regno, size);
+ }
+
+ if (register_valid [regno])
+ {
+ SWAP_TARGET_AND_HOST (ptr, size);
+ if (memcmp (®isters[REGISTER_BYTE (regno)],
+ ptr, size) == 0)
+ return;
+ }
+
+ target_prepare_to_store ();
+
+ memcpy (®isters[REGISTER_BYTE (regno)], ptr, size);
+
+ register_valid [regno] = 1;
target_store_registers (regno);
}
case LOC_REGISTER:
case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
{
struct block *b;
v = value_from_register (type, SYMBOL_VALUE (var), frame);
- /* Nonzero if a struct which is located in a register or a LOC_ARG
- really contains
- the address of the struct, not the struct itself. GCC_P is nonzero
- if the function was compiled with GCC. */
- /* A cleaner way to do this would be to add LOC_REGISTER_ADDR
- (register contains the address of the value) and LOC_REGPARM_ADDR,
- and have the symbol-reading code set them -kingdon. */
-#if !defined (REG_STRUCT_HAS_ADDR)
-#define REG_STRUCT_HAS_ADDR(gcc_p) 0
-#endif
-
- if (REG_STRUCT_HAS_ADDR (BLOCK_GCC_COMPILED (b))
- && ( (TYPE_CODE (type) == TYPE_CODE_STRUCT)
- || (TYPE_CODE (type) == TYPE_CODE_UNION)))
+ if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR)
{
addr = *(CORE_ADDR *)VALUE_CONTENTS (v);
VALUE_LVAL (v) = lval_memory;
}
break;
+ case LOC_OPTIMIZED_OUT:
+ VALUE_LVAL (v) = not_lval;
+ VALUE_OPTIMIZED_OUT (v) = 1;
+ return v;
+
default:
error ("Cannot look up value of a botched symbol.");
break;
numbers for the pointer & non-pointer form of the register. But, it
doesn't, so we're stuck with this. */
- if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ if (TYPE_CODE (type) == TYPE_CODE_PTR
+ && len > 2)
{
int page_regnum;
if (lval == lval_register)
reg_stor++;
else
- {
- mem_stor++;
- first_addr = addr;
- }
+ mem_stor++;
+ first_addr = addr;
last_addr = addr;
get_saved_register (value_bytes + 2,
frame,
local_regnum,
&lval);
+
+ if (regnum == local_regnum)
+ first_addr = addr;
if (lval == lval_register)
reg_stor++;
else
{
mem_stor++;
-
- if (regnum == local_regnum)
- first_addr = addr;
mem_tracking =
(mem_tracking
/* Copy into the contents section of the value. */
memcpy (VALUE_CONTENTS_RAW (v), value_bytes, len);
+ /* Finally do any conversion necessary when extracting this
+ type from more than one register. */
+#ifdef REGISTER_CONVERT_TO_TYPE
+ REGISTER_CONVERT_TO_TYPE(regnum, type, VALUE_CONTENTS_RAW(v));
+#endif
return v;
}