@@ -373,14 +373,14 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
373
373
if (dst == nullptr )
374
374
return false ;
375
375
376
- // Code below is specific to AArch64 target in SVE state
376
+ // Code below is specific to AArch64 target in SVE or SME state
377
377
// If vector granule (vg) register is being written then thread's
378
378
// register context reconfiguration is triggered on success.
379
- bool do_reconfigure_arm64_sve = false ;
379
+ // We do not allow writes to SVG so it is not mentioned here.
380
380
const ArchSpec &arch = process->GetTarget ().GetArchitecture ();
381
- if ( arch.IsValid () && arch. GetTriple (). isAArch64 ())
382
- if ( strcmp (reg_info-> name , " vg " ) == 0 )
383
- do_reconfigure_arm64_sve = true ;
381
+ bool do_reconfigure_arm64_sve = arch.IsValid () &&
382
+ arch. GetTriple (). isAArch64 () &&
383
+ ( strcmp (reg_info-> name , " vg " ) == 0 ) ;
384
384
385
385
if (data.CopyByteOrderedData (data_offset, // src offset
386
386
reg_info->byte_size , // src length
@@ -400,10 +400,10 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
400
400
{m_reg_data.GetDataStart (), size_t (m_reg_data.GetByteSize ())}))
401
401
402
402
{
403
- SetAllRegisterValid (false );
404
-
405
403
if (do_reconfigure_arm64_sve)
406
- AArch64SVEReconfigure ();
404
+ AArch64Reconfigure ();
405
+
406
+ InvalidateAllRegisters ();
407
407
408
408
return true ;
409
409
}
@@ -435,8 +435,10 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
435
435
// This is an actual register, write it
436
436
success = SetPrimordialRegister (reg_info, gdb_comm);
437
437
438
- if (success && do_reconfigure_arm64_sve)
439
- AArch64SVEReconfigure ();
438
+ if (success && do_reconfigure_arm64_sve) {
439
+ AArch64Reconfigure ();
440
+ InvalidateAllRegisters ();
441
+ }
440
442
}
441
443
442
444
// Check if writing this register will invalidate any other register
@@ -760,37 +762,47 @@ uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
760
762
return m_reg_info_sp->ConvertRegisterKindToRegisterNumber (kind, num);
761
763
}
762
764
763
- bool GDBRemoteRegisterContext::AArch64SVEReconfigure () {
764
- if (!m_reg_info_sp)
765
- return false ;
766
-
767
- const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo (" vg" );
768
- if (!reg_info)
769
- return false ;
770
-
771
- uint64_t fail_value = LLDB_INVALID_ADDRESS;
772
- uint32_t vg_reg_num = reg_info->kinds [eRegisterKindLLDB];
773
- uint64_t vg_reg_value = ReadRegisterAsUnsigned (vg_reg_num, fail_value);
765
+ void GDBRemoteRegisterContext::AArch64Reconfigure () {
766
+ assert (m_reg_info_sp);
774
767
775
- if (vg_reg_value == fail_value || vg_reg_value > 32 )
776
- return false ;
777
-
778
- reg_info = m_reg_info_sp->GetRegisterInfo (" p0" );
779
- // Predicate registers have 1 bit per byte in the vector so their size is
780
- // VL / 8. VG is in units of 8 bytes already, so if the size of p0 == VG
781
- // already, we do not have to reconfigure.
782
- if (!reg_info || vg_reg_value == reg_info->byte_size )
783
- return false ;
768
+ // Once we start to reconfigure registers, we cannot read any of them.
769
+ // So we must read VG and SVG up front.
784
770
785
- m_reg_info_sp->UpdateARM64SVERegistersInfos (vg_reg_value);
786
- // Make a heap based buffer that is big enough to store all registers
787
- m_reg_data.SetData (std::make_shared<DataBufferHeap>(
788
- m_reg_info_sp->GetRegisterDataByteSize (), 0 ));
789
- m_reg_data.SetByteOrder (GetByteOrder ());
771
+ const uint64_t fail_value = LLDB_INVALID_ADDRESS;
772
+ std::optional<uint64_t > vg_reg_value;
773
+ const RegisterInfo *vg_reg_info = m_reg_info_sp->GetRegisterInfo (" vg" );
774
+ if (vg_reg_info) {
775
+ uint32_t vg_reg_num = vg_reg_info->kinds [eRegisterKindLLDB];
776
+ uint64_t reg_value = ReadRegisterAsUnsigned (vg_reg_num, fail_value);
777
+ if (reg_value != fail_value && reg_value <= 32 )
778
+ vg_reg_value = reg_value;
779
+ }
790
780
791
- InvalidateAllRegisters ();
781
+ std::optional<uint64_t > svg_reg_value;
782
+ const RegisterInfo *svg_reg_info = m_reg_info_sp->GetRegisterInfo (" svg" );
783
+ if (svg_reg_info) {
784
+ uint32_t svg_reg_num = svg_reg_info->kinds [eRegisterKindLLDB];
785
+ uint64_t reg_value = ReadRegisterAsUnsigned (svg_reg_num, fail_value);
786
+ if (reg_value != fail_value && reg_value <= 32 )
787
+ svg_reg_value = reg_value;
788
+ }
792
789
793
- return true ;
790
+ if (vg_reg_value)
791
+ m_reg_info_sp->UpdateARM64SVERegistersInfos (*vg_reg_value);
792
+ if (svg_reg_value)
793
+ m_reg_info_sp->UpdateARM64SMERegistersInfos (*svg_reg_value);
794
+
795
+ // At this point if we have updated any registers, their offsets will all be
796
+ // invalid. If we did, we need to update them all.
797
+ if (vg_reg_value || svg_reg_value) {
798
+ m_reg_info_sp->ConfigureOffsets ();
799
+ // From here we are able to read registers again.
800
+
801
+ // Make a heap based buffer that is big enough to store all registers
802
+ m_reg_data.SetData (std::make_shared<DataBufferHeap>(
803
+ m_reg_info_sp->GetRegisterDataByteSize (), 0 ));
804
+ m_reg_data.SetByteOrder (GetByteOrder ());
805
+ }
794
806
}
795
807
796
808
void GDBRemoteDynamicRegisterInfo::UpdateARM64SVERegistersInfos (uint64_t vg) {
@@ -811,7 +823,14 @@ void GDBRemoteDynamicRegisterInfo::UpdateARM64SVERegistersInfos(uint64_t vg) {
811
823
}
812
824
reg.byte_offset = LLDB_INVALID_INDEX32;
813
825
}
826
+ }
814
827
815
- // Re-calculate register offsets
816
- ConfigureOffsets ();
828
+ void GDBRemoteDynamicRegisterInfo::UpdateARM64SMERegistersInfos (uint64_t svg) {
829
+ for (auto ® : m_regs) {
830
+ if (strcmp (reg.name , " za" ) == 0 ) {
831
+ // ZA is a register with size (svg*8) * (svg*8). A square essentially.
832
+ reg.byte_size = (svg * 8 ) * (svg * 8 );
833
+ }
834
+ reg.byte_offset = LLDB_INVALID_INDEX32;
835
+ }
817
836
}
0 commit comments