@@ -1382,6 +1382,16 @@ pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache,
}
}
+static gdb_byte * reg_addr_in_vreg (struct gdbarch *gdbarch,
+ gdb_byte *vreg_addr,
+ size_t size)
+{
+ gdb_byte *ret = vreg_addr;
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ ret = vreg_addr + (V_REGISTER_SIZE - size);
+ return ret;
+}
+
/* Attempt to marshall a value in a V register. Return 1 if
successful, or 0 if insufficient registers are available. This
function, unlike the equivalent pass_in_x() function does not
@@ -1391,17 +1401,21 @@ static int
pass_in_v (struct gdbarch *gdbarch,
struct regcache *regcache,
struct aarch64_call_info *info,
+ struct type *type,
const bfd_byte *buf)
{
if (info->nsrn < 8)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ bfd_byte xbuf[V_REGISTER_SIZE];
+ int len = TYPE_LENGTH (type);
+ int copy_len = len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len;
int regnum = AARCH64_V0_REGNUM + info->nsrn;
info->argnum++;
info->nsrn++;
- regcache_cooked_write (regcache, regnum, buf);
+ memcpy (reg_addr_in_vreg (gdbarch, xbuf, copy_len), buf, copy_len);
+ regcache_cooked_write (regcache, regnum, xbuf);
if (aarch64_debug)
fprintf_unfiltered (gdb_stdlog, "arg %d in %s\n",
info->argnum,
@@ -1491,7 +1505,7 @@ pass_in_v_or_stack (struct gdbarch *gdbarch,
struct type *type,
const bfd_byte *buf)
{
- if (!pass_in_v (gdbarch, regcache, info, buf))
+ if (!pass_in_v (gdbarch, regcache, info, type, buf))
pass_on_stack (info, type, buf);
}
@@ -1616,8 +1630,8 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
struct type *target_type =
check_typedef (TYPE_TARGET_TYPE (arg_type));
- pass_in_v (gdbarch, regcache, &info, buf);
- pass_in_v (gdbarch, regcache, &info,
+ pass_in_v (gdbarch, regcache, &info, target_type, buf);
+ pass_in_v (gdbarch, regcache, &info, target_type,
buf + TYPE_LENGTH (target_type));
}
else
@@ -1925,7 +1939,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
int len = TYPE_LENGTH (type);
regcache_cooked_read (regs, AARCH64_V0_REGNUM, buf);
- memcpy (valbuf, buf, len);
+ memcpy (valbuf, reg_addr_in_vreg (gdbarch, buf, len), len);
}
else if (TYPE_CODE (type) == TYPE_CODE_INT
|| TYPE_CODE (type) == TYPE_CODE_CHAR
@@ -1961,10 +1975,10 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
int len = TYPE_LENGTH (target_type);
regcache_cooked_read (regs, regno, buf);
- memcpy (valbuf, buf, len);
+ memcpy (valbuf, reg_addr_in_vreg (gdbarch, buf, len), len);
valbuf += len;
regcache_cooked_read (regs, regno + 1, buf);
- memcpy (valbuf, buf, len);
+ memcpy (valbuf, reg_addr_in_vreg (gdbarch, buf, len), len);
valbuf += len;
}
else if (is_hfa (type))
@@ -1986,7 +2000,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
gdbarch_register_name (gdbarch, regno));
regcache_cooked_read (regs, regno, buf);
- memcpy (valbuf, buf, len);
+ memcpy (valbuf, reg_addr_in_vreg (gdbarch, buf, len), len);
valbuf += len;
}
}
@@ -2058,8 +2072,9 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
{
bfd_byte buf[V_REGISTER_SIZE];
int len = TYPE_LENGTH (type);
+ int copy_len = len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len;
- memcpy (buf, valbuf, len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len);
+ memcpy (reg_addr_in_vreg (gdbarch, buf, copy_len), valbuf, copy_len);
regcache_cooked_write (regs, AARCH64_V0_REGNUM, buf);
}
else if (TYPE_CODE (type) == TYPE_CODE_INT
@@ -2113,7 +2128,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
i + 1,
gdbarch_register_name (gdbarch, regno));
- memcpy (tmpbuf, valbuf, len);
+ memcpy (reg_addr_in_vreg (gdbarch, tmpbuf, len), valbuf, len);
regcache_cooked_write (regs, regno, tmpbuf);
valbuf += len;
}
@@ -2360,7 +2375,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch,
mark_value_bytes_unavailable (result_value, 0,
TYPE_LENGTH (value_type (result_value)));
else
- memcpy (buf, reg_buf, Q_REGISTER_SIZE);
+ memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, Q_REGISTER_SIZE), Q_REGISTER_SIZE);
return result_value;
}
@@ -2375,7 +2390,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch,
mark_value_bytes_unavailable (result_value, 0,
TYPE_LENGTH (value_type (result_value)));
else
- memcpy (buf, reg_buf, D_REGISTER_SIZE);
+ memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, D_REGISTER_SIZE), D_REGISTER_SIZE);
return result_value;
}
@@ -2386,7 +2401,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch,
v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM;
status = regcache_raw_read (regcache, v_regnum, reg_buf);
- memcpy (buf, reg_buf, S_REGISTER_SIZE);
+ memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, S_REGISTER_SIZE), S_REGISTER_SIZE);
return result_value;
}
@@ -2401,7 +2416,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch,
mark_value_bytes_unavailable (result_value, 0,
TYPE_LENGTH (value_type (result_value)));
else
- memcpy (buf, reg_buf, H_REGISTER_SIZE);
+ memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, H_REGISTER_SIZE), H_REGISTER_SIZE);
return result_value;
}
@@ -2416,7 +2431,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch,
mark_value_bytes_unavailable (result_value, 0,
TYPE_LENGTH (value_type (result_value)));
else
- memcpy (buf, reg_buf, B_REGISTER_SIZE);
+ memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, B_REGISTER_SIZE), B_REGISTER_SIZE);
return result_value;
}
@@ -2445,7 +2460,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
unsigned v_regnum;
v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_Q0_REGNUM;
- memcpy (reg_buf, buf, Q_REGISTER_SIZE);
+ memcpy (reg_addr_in_vreg (gdbarch, reg_buf, Q_REGISTER_SIZE), buf, Q_REGISTER_SIZE);
regcache_raw_write (regcache, v_regnum, reg_buf);
return;
}
@@ -2456,7 +2471,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
unsigned v_regnum;
v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_D0_REGNUM;
- memcpy (reg_buf, buf, D_REGISTER_SIZE);
+ memcpy (reg_addr_in_vreg (gdbarch, reg_buf, D_REGISTER_SIZE), buf, D_REGISTER_SIZE);
regcache_raw_write (regcache, v_regnum, reg_buf);
return;
}
@@ -2466,7 +2481,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
unsigned v_regnum;
v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM;
- memcpy (reg_buf, buf, S_REGISTER_SIZE);
+ memcpy (reg_addr_in_vreg (gdbarch, reg_buf, S_REGISTER_SIZE), buf, S_REGISTER_SIZE);
regcache_raw_write (regcache, v_regnum, reg_buf);
return;
}
@@ -2477,7 +2492,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
unsigned v_regnum;
v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_H0_REGNUM;
- memcpy (reg_buf, buf, H_REGISTER_SIZE);
+ memcpy (reg_addr_in_vreg (gdbarch, reg_buf, H_REGISTER_SIZE), buf, H_REGISTER_SIZE);
regcache_raw_write (regcache, v_regnum, reg_buf);
return;
}
@@ -2488,7 +2503,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
unsigned v_regnum;
v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_B0_REGNUM;
- memcpy (reg_buf, buf, B_REGISTER_SIZE);
+ memcpy (reg_addr_in_vreg (gdbarch, reg_buf, B_REGISTER_SIZE), buf, B_REGISTER_SIZE);
regcache_raw_write (regcache, v_regnum, reg_buf);
return;
}