arm64: fix the conversion from/to VEX fpsr to/from GDB representation



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14219 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_gdbserver/valgrind-low-arm64.c b/coregrind/m_gdbserver/valgrind-low-arm64.c
index 1b5a539..5a32ef8 100644
--- a/coregrind/m_gdbserver/valgrind-low-arm64.c
+++ b/coregrind/m_gdbserver/valgrind-low-arm64.c
@@ -218,17 +218,19 @@
    case 64: VG_(transfer) (&arm->guest_Q30, buf, dir, size, mod); break;
    case 65: VG_(transfer) (&arm->guest_Q31, buf, dir, size, mod); break;
    case 66: {
-      /* The ARM64 FPSR representation is not the same as the
+      /* The VEX ARM64 FPSR representation is not the same as the
           architecturally defined representation.  Hence use conversion
-          functions to convert to/from it. */
+          functions to convert to/from it.
+          VEX FPSR only models QC (bit 27), and uses a 64 bits to store
+          this FPSR QC bit. So, we need to transfer from/to the lowest part
+          of the ULong that VEX provides/needs, as GDB expects or
+          gives only 4 bytes. */
       if (dir == valgrind_to_gdbserver) {
          ULong fpsr = LibVEX_GuestARM64_get_fpsr(arm);
-         // XXX FIXME what if size != 8 ?  Does this still work?
-         VG_(transfer) (&fpsr, buf, dir, size, mod);
+         VG_(transfer) ((UInt*)&fpsr + 1, buf, dir, size, mod);
       } else {
-         // XXX FIXME what if size != 8 ?  Does this still work?
          ULong fpsr = 0;
-         VG_(transfer) (&fpsr, buf, dir, size, mod);
+         VG_(transfer) ((UInt*)&fpsr + 1, buf, dir, size, mod);
          LibVEX_GuestARM64_set_fpsr(arm, fpsr);
       }
       break;