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;