- int local_regnum;
- int mem_stor = 0, reg_stor = 0;
- int mem_tracking = 1;
- CORE_ADDR last_addr = 0;
- CORE_ADDR first_addr = 0;
- int first_realnum = regnum;
- int len = TYPE_LENGTH (type);
- int value_bytes_copied;
- int optimized = 0;
- char *value_bytes = (char *) alloca (len + MAX_REGISTER_SIZE);
-
- /* Copy all of the data out, whereever it may be. */
- for (local_regnum = regnum, value_bytes_copied = 0;
- value_bytes_copied < len;
- (value_bytes_copied += register_size (current_gdbarch, local_regnum),
- ++local_regnum))
- {
- int realnum;
- int optim;
- enum lval_type lval;
- CORE_ADDR addr;
- frame_register (frame, local_regnum, &optim, &lval, &addr,
- &realnum, value_bytes + value_bytes_copied);
- optimized += optim;
- if (register_cached (local_regnum) == -1)
- return NULL; /* register value not available */
-
- if (regnum == local_regnum)
- {
- first_addr = addr;
- first_realnum = realnum;
- }
- if (lval == lval_register)
- reg_stor++;
- else
- {
- mem_stor++;
-
- /* FIXME: cagney/2004-11-12: I think this is trying to
- check that the stored registers are adjacent in
- memory. It isn't doing a good job? */
- mem_tracking = (mem_tracking
- && (regnum == local_regnum
- || addr == last_addr));
- }
- last_addr = addr;
- }
-
- if (mem_tracking && mem_stor && !reg_stor)
- {
- VALUE_LVAL (v) = lval_memory;
- VALUE_ADDRESS (v) = first_addr;
- }
- else
- {
- VALUE_LVAL (v) = lval_register;
- VALUE_FRAME_ID (v) = get_frame_id (frame);
- VALUE_REGNUM (v) = regnum;
- }
-
- set_value_optimized_out (v, optimized);
-
- /* 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 (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && len < register_size (current_gdbarch, regnum))
- /* Big-endian, and we want less than full size. */
- v->offset = register_size (current_gdbarch, regnum) - len;
- else
- v->offset = 0;
- memcpy (value_contents_raw (v), value_bytes + value_offset (v), len);