/* The functions on this page are intended to be used to classify
function arguments. */
-/* Return the contents if register REGNUM as an address. */
-
-static CORE_ADDR
-sparc_address_from_register (int regnum)
-{
- ULONGEST addr;
-
- regcache_cooked_read_unsigned (current_regcache, regnum, &addr);
- return addr;
-}
-
/* Check whether TYPE is "Integral or Pointer". */
static int
&& regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
- frame_register_unwind (next_frame, regnum,
- optimizedp, lvalp, addrp, realnump, valuep);
+ *optimizedp = 0;
+ *lvalp = lval_register;
+ *addrp = 0;
+ *realnump = regnum;
+ if (valuep)
+ frame_unwind_register (next_frame, regnum, valuep);
}
static const struct frame_unwind sparc64_frame_unwind =
struct sparc_frame_cache *cache =
sparc64_frame_cache (next_frame, this_cache);
- /* ??? Should we take BIAS into account here? */
- return cache->base;
+ return cache->base + BIAS;
}
static const struct frame_base sparc64_frame_base =
int i;
for (i = 0; i < TYPE_NFIELDS (type); i++)
- if (sparc64_16_byte_align_p (TYPE_FIELD_TYPE (type, i)))
- return 1;
+ {
+ struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+
+ if (sparc64_16_byte_align_p (subtype))
+ return 1;
+ }
}
return 0;
int i;
for (i = 0; i < TYPE_NFIELDS (type); i++)
- sparc64_store_floating_fields (regcache, TYPE_FIELD_TYPE (type, i),
- valbuf, element,
- bitpos + TYPE_FIELD_BITPOS (type, i));
+ {
+ struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+ int subpos = bitpos + TYPE_FIELD_BITPOS (type, i);
+
+ sparc64_store_floating_fields (regcache, subtype, valbuf,
+ element, subpos);
+ }
+
+ /* GCC has an interesting bug. If TYPE is a structure that has
+ a single `float' member, GCC doesn't treat it as a structure
+ at all, but rather as an ordinary `float' argument. This
+ argument will be stored in %f1, as required by the psABI.
+ However, as a member of a structure the psABI requires it to
+ be stored in %f0. This bug is present in GCC 3.3.2, but
+ probably in older releases to. To appease GCC, if a
+ structure has only a single `float' member, we store its
+ value in %f1 too (we already have stored in %f0). */
+ if (TYPE_NFIELDS (type) == 1)
+ {
+ struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, 0));
+
+ if (sparc64_floating_p (subtype) && TYPE_LENGTH (subtype) == 4)
+ regcache_cooked_write (regcache, SPARC_F1_REGNUM, valbuf);
+ }
}
}
int i;
for (i = 0; i < TYPE_NFIELDS (type); i++)
- sparc64_extract_floating_fields (regcache, TYPE_FIELD_TYPE (type, i),
- valbuf,
- bitpos + TYPE_FIELD_BITPOS (type, i));
+ {
+ struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+ int subpos = bitpos + TYPE_FIELD_BITPOS (type, i);
+
+ sparc64_extract_floating_fields (regcache, subtype, valbuf, subpos);
+ }
}
}
for (i = 0; i < nargs; i++)
{
- struct type *type = VALUE_TYPE (args[i]);
+ struct type *type = value_type (args[i]);
int len = TYPE_LENGTH (type);
if (sparc64_structure_or_union_p (type))
for (i = 0; i < nargs; i++)
{
char *valbuf = VALUE_CONTENTS (args[i]);
- struct type *type = VALUE_TYPE (args[i]);
+ struct type *type = value_type (args[i]);
int len = TYPE_LENGTH (type);
int regnum = -1;
char buf[16];
undefined." Even though the psABI says that "the
left half is undefined", set it to zero here. */
memset (buf, 0, 4);
- valbuf = memcpy (buf + 4, valbuf, 4);
+ memcpy (buf + 4, valbuf, 4);
+ valbuf = buf;
len = 8;
if (element < 16)
- regnum = SPARC64_D0_REGNUM;
+ regnum = SPARC64_D0_REGNUM + element;
}
}
else
gdb_assert (element < 6);
regnum = SPARC_O0_REGNUM + element;
regcache_cooked_write (regcache, regnum, valbuf);
- regcache_cooked_write (regcache, regnum + 1, valbuf);
+ regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
}
}
- /* Always store the argument in memeory. */
+ /* Always store the argument in memory. */
write_memory (sp + element * 8, valbuf, len);
element += ((len + 7) / 8);
}
}
static CORE_ADDR
-sparc64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+sparc64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct regcache *regcache, CORE_ADDR bp_addr,
int nargs, struct value **args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
memset (buf, 0, sizeof (buf));
memcpy (buf, valbuf, len);
for (i = 0; i < ((len + 7) / 8); i++)
- regcache_cooked_write (regcache, SPARC_O0_REGNUM + i, buf + i * 4);
+ regcache_cooked_write (regcache, SPARC_O0_REGNUM + i, buf + i * 8);
if (TYPE_CODE (type) != TYPE_CODE_UNION)
sparc64_store_floating_fields (regcache, type, buf, 0, 0);
}
}
}
-static int
-sparc64_use_struct_convention (int gcc_p, struct type *type)
+static enum return_value_convention
+sparc64_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, void *readbuf,
+ const void *writebuf)
{
- /* Structure and union types up to 32 bytes in size are returned in
- registers. */
- return (TYPE_LENGTH (type) > 32);
+ if (TYPE_LENGTH (type) > 32)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+
+ if (readbuf)
+ sparc64_extract_return_value (type, regcache, readbuf);
+ if (writebuf)
+ sparc64_store_return_value (type, regcache, writebuf);
+
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
\f
set_gdbarch_push_dummy_code (gdbarch, NULL);
set_gdbarch_push_dummy_call (gdbarch, sparc64_push_dummy_call);
- set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, sparc64_store_return_value);
- set_gdbarch_use_struct_convention (gdbarch, sparc64_use_struct_convention);
- set_gdbarch_return_value_on_stack
- (gdbarch, generic_return_value_on_stack_not);
+ set_gdbarch_return_value (gdbarch, sparc64_return_value);
set_gdbarch_stabs_argument_has_addr
(gdbarch, default_stabs_argument_has_addr);