+static void
+ia64_store_return_value (struct type *type, struct regcache *regcache,
+ const gdb_byte *valbuf)
+{
+ struct type *float_elt_type;
+
+ float_elt_type = is_float_or_hfa_type (type);
+ if (float_elt_type != NULL)
+ {
+ char to[MAX_REGISTER_SIZE];
+ int offset = 0;
+ int regnum = IA64_FR8_REGNUM;
+ int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
+
+ while (n-- > 0)
+ {
+ convert_typed_floating ((char *)valbuf + offset, float_elt_type,
+ to, builtin_type_ia64_ext);
+ regcache_cooked_write (regcache, regnum, to);
+ offset += TYPE_LENGTH (float_elt_type);
+ regnum++;
+ }
+ }
+ else
+ {
+ ULONGEST val;
+ int offset = 0;
+ int regnum = IA64_GR8_REGNUM;
+ int reglen = TYPE_LENGTH (register_type (get_regcache_arch (regcache),
+ IA64_GR8_REGNUM));
+ int n = TYPE_LENGTH (type) / reglen;
+ int m = TYPE_LENGTH (type) % reglen;
+
+ while (n-- > 0)
+ {
+ ULONGEST val;
+ memcpy (&val, (char *)valbuf + offset, reglen);
+ regcache_cooked_write_unsigned (regcache, regnum, val);
+ offset += reglen;
+ regnum++;
+ }
+
+ if (m)
+ {
+ memcpy (&val, (char *)valbuf + offset, m);
+ regcache_cooked_write_unsigned (regcache, regnum, val);
+ }
+ }
+}
+
+static enum return_value_convention
+ia64_return_value (struct gdbarch *gdbarch, struct type *valtype,
+ struct regcache *regcache, gdb_byte *readbuf,
+ const gdb_byte *writebuf)
+{
+ int struct_return = ia64_use_struct_convention (valtype);
+
+ if (writebuf != NULL)
+ {
+ gdb_assert (!struct_return);
+ ia64_store_return_value (valtype, regcache, writebuf);
+ }
+
+ if (readbuf != NULL)
+ {
+ gdb_assert (!struct_return);
+ ia64_extract_return_value (valtype, regcache, readbuf);
+ }
+
+ if (struct_return)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else
+ return RETURN_VALUE_REGISTER_CONVENTION;
+}