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;