@@ -1715,6 +1715,7 @@ read_pieced_value (struct value *v)
for (i = 0; i < c->n_pieces && offset < type_len; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
+ size_t piece_bytes = (p->size + 7) / 8;
size_t this_size, this_size_bits;
long dest_offset_bits, source_offset_bits, source_offset;
const gdb_byte *intermediate_buffer;
@@ -1759,17 +1760,13 @@ read_pieced_value (struct value *v)
struct gdbarch *arch = get_frame_arch (frame);
int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
int optim, unavail;
- int reg_offset = source_offset;
+ int reg_offset = gdbarch_register_part (arch, piece_bytes,
+ &gdb_regnum);
- if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && this_size < register_size (arch, gdb_regnum))
- {
- /* Big-endian, and we want less than full size. */
- reg_offset = register_size (arch, gdb_regnum) - this_size;
- /* We want the lower-order THIS_SIZE_BITS of the bytes
- we extract from the register. */
- source_offset_bits += 8 * this_size - this_size_bits;
- }
+ source_offset_bits += 8 * reg_offset;
+ if (bits_big_endian)
+ source_offset_bits += 8 * piece_bytes - this_size_bits;
+ reg_offset = source_offset_bits / 8;
if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
this_size, buffer,
@@ -1890,6 +1887,7 @@ write_pieced_value (struct value *to, struct value *from)
for (i = 0; i < c->n_pieces && offset < type_len; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
+ size_t piece_bytes = (p->size + 7) / 8;
size_t this_size_bits, this_size;
long dest_offset_bits, source_offset_bits, dest_offset, source_offset;
int need_bitwise;
@@ -1941,14 +1939,13 @@ write_pieced_value (struct value *to, struct value *from)
{
struct gdbarch *arch = get_frame_arch (frame);
int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
- int reg_offset = dest_offset;
+ int reg_offset = gdbarch_register_part (arch, piece_bytes,
+ &gdb_regnum);
- if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && this_size <= register_size (arch, gdb_regnum))
- {
- /* Big-endian, and we want less than full size. */
- reg_offset = register_size (arch, gdb_regnum) - this_size;
- }
+ source_offset_bits += 8 * reg_offset;
+ if (bits_big_endian)
+ source_offset_bits += 8 * piece_bytes - this_size_bits;
+ reg_offset = source_offset_bits / 8;
if (need_bitwise)
{
@@ -797,29 +797,19 @@ read_var_value (struct symbol *var, const struct block *var_block,
/* Install default attributes for register values. */
-struct value *
-default_value_from_register (struct gdbarch *gdbarch, struct type *type,
- int regnum, struct frame_id frame_id)
+int
+default_register_part (struct gdbarch *gdbarch, int len, int *regnum)
{
- int len = TYPE_LENGTH (type);
- struct value *value = allocate_value (type);
-
- VALUE_LVAL (value) = lval_register;
- VALUE_FRAME_ID (value) = frame_id;
- VALUE_REGNUM (value) = regnum;
-
/* Any structure stored in more than one register will always be
an integral number of registers. Otherwise, you need to do
some fiddling with the last register copied here for little
endian machines. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
- && len < register_size (gdbarch, regnum))
+ && len < register_size (gdbarch, *regnum))
/* Big-endian, and we want less than full size. */
- set_value_offset (value, register_size (gdbarch, regnum) - len);
- else
- set_value_offset (value, 0);
+ return register_size (gdbarch, *regnum) - len;
- return value;
+ return 0;
}
/* VALUE must be an lval_register value. If regnum is the value's
@@ -877,6 +867,10 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
struct type *type1 = check_typedef (type);
struct value *v;
+ v = allocate_value (type);
+ VALUE_LVAL (v) = lval_register;
+ VALUE_FRAME_ID (v) = get_frame_id (frame);
+
if (gdbarch_convert_register_p (gdbarch, regnum, type1))
{
int optim, unavail, ok;
@@ -888,9 +882,6 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
the corresponding [integer] type (see Alpha). The assumption
is that gdbarch_register_to_value populates the entire value
including the location. */
- v = allocate_value (type);
- VALUE_LVAL (v) = lval_register;
- VALUE_FRAME_ID (v) = get_frame_id (frame);
VALUE_REGNUM (v) = regnum;
ok = gdbarch_register_to_value (gdbarch, frame, regnum, type1,
value_contents_raw (v), &optim,
@@ -907,8 +898,10 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
else
{
/* Construct the value. */
- v = gdbarch_value_from_register (gdbarch, type,
- regnum, get_frame_id (frame));
+ int offset = gdbarch_register_part (gdbarch, TYPE_LENGTH (type),
+ ®num);
+ VALUE_REGNUM (v) = regnum;
+ set_value_offset (v, offset);
/* Get the data. */
read_frame_register_value (v, frame);
@@ -927,6 +920,7 @@ address_from_register (int regnum, struct frame_info *frame)
struct type *type = builtin_type (gdbarch)->builtin_data_ptr;
struct value *value;
CORE_ADDR result;
+ int offset;
int regnum_max_excl = (gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch));
@@ -962,7 +956,11 @@ address_from_register (int regnum, struct frame_info *frame)
return unpack_long (type, buf);
}
- value = gdbarch_value_from_register (gdbarch, type, regnum, null_frame_id);
+ offset = gdbarch_register_part (gdbarch, TYPE_LENGTH (type), ®num);
+ value = allocate_value (type);
+ VALUE_LVAL (value) = lval_register;
+ VALUE_REGNUM (value) = regnum;
+ set_value_offset (value, offset);
read_frame_register_value (value, frame);
if (value_optimized_out (value))
@@ -216,7 +216,7 @@ struct gdbarch
gdbarch_convert_register_p_ftype *convert_register_p;
gdbarch_register_to_value_ftype *register_to_value;
gdbarch_value_to_register_ftype *value_to_register;
- gdbarch_value_from_register_ftype *value_from_register;
+ gdbarch_register_part_ftype *register_part;
gdbarch_pointer_to_address_ftype *pointer_to_address;
gdbarch_address_to_pointer_ftype *address_to_pointer;
gdbarch_integer_to_address_ftype *integer_to_address;
@@ -393,7 +393,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
gdbarch->cannot_fetch_register = cannot_register_not;
gdbarch->cannot_store_register = cannot_register_not;
gdbarch->convert_register_p = generic_convert_register_p;
- gdbarch->value_from_register = default_value_from_register;
+ gdbarch->register_part = default_register_part;
gdbarch->pointer_to_address = unsigned_pointer_to_address;
gdbarch->address_to_pointer = unsigned_address_to_pointer;
gdbarch->return_in_first_hidden_param_p = default_return_in_first_hidden_param_p;
@@ -560,7 +560,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of cannot_store_register, invalid_p == 0 */
/* Skip verify of get_longjmp_target, has predicate. */
/* Skip verify of convert_register_p, invalid_p == 0 */
- /* Skip verify of value_from_register, invalid_p == 0 */
+ /* Skip verify of register_part, invalid_p == 0 */
/* Skip verify of pointer_to_address, invalid_p == 0 */
/* Skip verify of address_to_pointer, invalid_p == 0 */
/* Skip verify of integer_to_address, has predicate. */
@@ -1242,6 +1242,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: register_name = <%s>\n",
host_address_to_string (gdbarch->register_name));
fprintf_unfiltered (file,
+ "gdbarch_dump: register_part = <%s>\n",
+ host_address_to_string (gdbarch->register_part));
+ fprintf_unfiltered (file,
"gdbarch_dump: register_reggroup_p = <%s>\n",
host_address_to_string (gdbarch->register_reggroup_p));
fprintf_unfiltered (file,
@@ -1398,9 +1401,6 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: unwind_sp = <%s>\n",
host_address_to_string (gdbarch->unwind_sp));
fprintf_unfiltered (file,
- "gdbarch_dump: value_from_register = <%s>\n",
- host_address_to_string (gdbarch->value_from_register));
- fprintf_unfiltered (file,
"gdbarch_dump: value_to_register = <%s>\n",
host_address_to_string (gdbarch->value_to_register));
fprintf_unfiltered (file,
@@ -2514,21 +2514,21 @@ set_gdbarch_value_to_register (struct gdbarch *gdbarch,
gdbarch->value_to_register = value_to_register;
}
-struct value *
-gdbarch_value_from_register (struct gdbarch *gdbarch, struct type *type, int regnum, struct frame_id frame_id)
+int
+gdbarch_register_part (struct gdbarch *gdbarch, int len, int *regnum)
{
gdb_assert (gdbarch != NULL);
- gdb_assert (gdbarch->value_from_register != NULL);
+ gdb_assert (gdbarch->register_part != NULL);
if (gdbarch_debug >= 2)
- fprintf_unfiltered (gdb_stdlog, "gdbarch_value_from_register called\n");
- return gdbarch->value_from_register (gdbarch, type, regnum, frame_id);
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_register_part called\n");
+ return gdbarch->register_part (gdbarch, len, regnum);
}
void
-set_gdbarch_value_from_register (struct gdbarch *gdbarch,
- gdbarch_value_from_register_ftype value_from_register)
+set_gdbarch_register_part (struct gdbarch *gdbarch,
+ gdbarch_register_part_ftype register_part)
{
- gdbarch->value_from_register = value_from_register;
+ gdbarch->register_part = register_part;
}
CORE_ADDR
@@ -450,14 +450,13 @@ typedef void (gdbarch_value_to_register_ftype) (struct frame_info *frame, int re
extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf);
extern void set_gdbarch_value_to_register (struct gdbarch *gdbarch, gdbarch_value_to_register_ftype *value_to_register);
-/* Construct a value representing the contents of register REGNUM in
- frame FRAME_ID, interpreted as type TYPE. The routine needs to
- allocate and return a struct value with all value attributes
- (but not the value contents) filled in. */
-
-typedef struct value * (gdbarch_value_from_register_ftype) (struct gdbarch *gdbarch, struct type *type, int regnum, struct frame_id frame_id);
-extern struct value * gdbarch_value_from_register (struct gdbarch *gdbarch, struct type *type, int regnum, struct frame_id frame_id);
-extern void set_gdbarch_value_from_register (struct gdbarch *gdbarch, gdbarch_value_from_register_ftype *value_from_register);
+/* Locate a part of size LEN within register *REGNUM, possibly overwriting
+ *REGNUM. Return the offset of the part within the (possibly adjusted)
+ register. */
+
+typedef int (gdbarch_register_part_ftype) (struct gdbarch *gdbarch, int len, int *regnum);
+extern int gdbarch_register_part (struct gdbarch *gdbarch, int len, int *regnum);
+extern void set_gdbarch_register_part (struct gdbarch *gdbarch, gdbarch_register_part_ftype *register_part);
typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf);
extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf);
@@ -506,11 +506,11 @@ v:int:believe_pcc_promotion:::::::
m:int:convert_register_p:int regnum, struct type *type:regnum, type:0:generic_convert_register_p::0
f:int:register_to_value:struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep:frame, regnum, type, buf, optimizedp, unavailablep:0
f:void:value_to_register:struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf:frame, regnum, type, buf:0
-# Construct a value representing the contents of register REGNUM in
-# frame FRAME_ID, interpreted as type TYPE. The routine needs to
-# allocate and return a struct value with all value attributes
-# (but not the value contents) filled in.
-m:struct value *:value_from_register:struct type *type, int regnum, struct frame_id frame_id:type, regnum, frame_id::default_value_from_register::0
+
+# Locate a part of size LEN within register *REGNUM, possibly overwriting
+# *REGNUM. Return the offset of the part within the (possibly adjusted)
+# register.
+m:int:register_part:int len, int *regnum:len, regnum::default_register_part::0
#
m:CORE_ADDR:pointer_to_address:struct type *type, const gdb_byte *buf:type, buf::unsigned_pointer_to_address::0
m:void:address_to_pointer:struct type *type, gdb_byte *buf, CORE_ADDR addr:type, buf, addr::unsigned_address_to_pointer::0
@@ -513,28 +513,23 @@ s390_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
registers, even though we are otherwise a big-endian platform. The
same applies to a 'float' value within a vector. */
-static struct value *
-s390_value_from_register (struct gdbarch *gdbarch, struct type *type,
- int regnum, struct frame_id frame_id)
+static int
+s390_register_part (struct gdbarch *gdbarch, int len, int *regnum)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- unsigned int len = TYPE_LENGTH (check_typedef (type));
- struct value *value;
/* If the value fits in a sub-register, use that instead. */
- if (regnum_is_vxr_full (tdep, regnum) && len <= 8)
- regnum = regnum - tdep->v0_full_regnum + S390_F0_REGNUM;
- else if (regnum_is_gpr_full (tdep, regnum) && len <= 4)
- regnum = regnum - tdep->gpr_full_regnum + S390_R0_REGNUM;
-
- value = default_value_from_register (gdbarch, type, regnum, frame_id);
-
- if ((regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM && len < 8)
- || regnum_is_vxr_full (tdep, regnum)
- || (regnum >= S390_V16_REGNUM && regnum <= S390_V31_REGNUM))
- set_value_offset (value, 0);
+ if (regnum_is_vxr_full (tdep, *regnum) && len <= 8)
+ *regnum = *regnum - tdep->v0_full_regnum + S390_F0_REGNUM;
+ else if (regnum_is_gpr_full (tdep, *regnum) && len <= 4)
+ *regnum = *regnum - tdep->gpr_full_regnum + S390_R0_REGNUM;
+
+ if ((*regnum >= S390_F0_REGNUM && *regnum <= S390_F15_REGNUM && len < 8)
+ || regnum_is_vxr_full (tdep, *regnum)
+ || (*regnum >= S390_V16_REGNUM && *regnum <= S390_V31_REGNUM))
+ return 0;
- return value;
+ return default_register_part (gdbarch, len, regnum);
}
/* Register groups. */
@@ -8005,7 +8000,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_fp0_regnum (gdbarch, S390_F0_REGNUM);
set_gdbarch_stab_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
- set_gdbarch_value_from_register (gdbarch, s390_value_from_register);
+ set_gdbarch_register_part (gdbarch, s390_register_part);
set_gdbarch_core_read_description (gdbarch, s390_core_read_description);
set_gdbarch_iterate_over_regset_sections (gdbarch,
s390_iterate_over_regset_sections);
@@ -357,21 +357,13 @@ spu_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
/* Value conversion -- access scalar values at the preferred slot. */
-static struct value *
-spu_value_from_register (struct gdbarch *gdbarch, struct type *type,
- int regnum, struct frame_id frame_id)
+static int
+spu_register_part (struct gdbarch *gdbarch, int len, int *regnum)
{
- struct value *value = default_value_from_register (gdbarch, type,
- regnum, frame_id);
- int len = TYPE_LENGTH (type);
-
- if (regnum < SPU_NUM_GPRS && len < 16)
- {
- int preferred_slot = len < 4 ? 4 - len : 0;
- set_value_offset (value, preferred_slot);
- }
+ if (*regnum < SPU_NUM_GPRS && len < 16)
+ return len < 4 ? 4 - len : 0;
- return value;
+ return default_register_part (gdbarch, len, regnum);
}
/* Register groups. */
@@ -2738,7 +2730,7 @@ spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_register_type (gdbarch, spu_register_type);
set_gdbarch_pseudo_register_read (gdbarch, spu_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, spu_pseudo_register_write);
- set_gdbarch_value_from_register (gdbarch, spu_value_from_register);
+ set_gdbarch_register_part (gdbarch, spu_register_part);
set_gdbarch_register_reggroup_p (gdbarch, spu_register_reggroup_p);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, spu_dwarf_reg_to_regnum);
set_gdbarch_ax_pseudo_register_collect
@@ -647,10 +647,8 @@ extern struct value *value_from_contents_and_address (struct type *,
CORE_ADDR);
extern struct value *value_from_contents (struct type *, const gdb_byte *);
-extern struct value *default_value_from_register (struct gdbarch *gdbarch,
- struct type *type,
- int regnum,
- struct frame_id frame_id);
+extern int default_register_part (struct gdbarch *gdbarch,
+ int len, int *regnum);
extern void read_frame_register_value (struct value *value,
struct frame_info *frame);