diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 1898f6b..959035e 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -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;
     }
