File: RegisterInfoPOSIX_arm64.h

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-19
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,999,616 kB
  • sloc: cpp: 6,951,724; ansic: 1,486,157; asm: 913,598; python: 232,059; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,079; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,430; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (186 lines) | stat: -rw-r--r-- 5,635 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//===-- RegisterInfoPOSIX_arm64.h -------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H

#include "RegisterInfoAndSetInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Flags.h"
#include "lldb/lldb-private.h"
#include <map>

enum class SVEState : uint8_t { Unknown, Disabled, FPSIMD, Full, Streaming };

class RegisterInfoPOSIX_arm64
    : public lldb_private::RegisterInfoAndSetInterface {
public:
  enum { GPRegSet = 0, FPRegSet };

  // AArch64 register set mask value
  enum {
    eRegsetMaskDefault = 0,
    eRegsetMaskSVE = 1,
    eRegsetMaskSSVE = 2,
    eRegsetMaskPAuth = 4,
    eRegsetMaskMTE = 8,
    eRegsetMaskTLS = 16,
    eRegsetMaskZA = 32,
    eRegsetMaskZT = 64,
    eRegsetMaskDynamic = ~1,
  };

  // AArch64 Register set FP/SIMD feature configuration
  enum {
    eVectorQuadwordAArch64,
    eVectorQuadwordAArch64SVE,
    eVectorQuadwordAArch64SVEMax = 256
  };

  // based on RegisterContextDarwin_arm64.h
  LLVM_PACKED_START
  struct GPR {
    uint64_t x[29]; // x0-x28
    uint64_t fp;    // x29
    uint64_t lr;    // x30
    uint64_t sp;    // x31
    uint64_t pc;    // pc
    uint32_t cpsr;  // cpsr
    uint32_t pad;
  };
  LLVM_PACKED_END

  // based on RegisterContextDarwin_arm64.h
  struct VReg {
    uint8_t bytes[16];
  };

  // based on RegisterContextDarwin_arm64.h
  struct FPU {
    VReg v[32];
    uint32_t fpsr;
    uint32_t fpcr;
  };

  // based on RegisterContextDarwin_arm64.h
  struct EXC {
    uint64_t far;       // Virtual Fault Address
    uint32_t esr;       // Exception syndrome
    uint32_t exception; // number of arm exception token
  };

  // based on RegisterContextDarwin_arm64.h
  struct DBG {
    uint64_t bvr[16];
    uint64_t bcr[16];
    uint64_t wvr[16];
    uint64_t wcr[16];
    uint64_t mdscr_el1;
  };

  RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch,
                          lldb_private::Flags opt_regsets);

  static size_t GetGPRSizeStatic();
  size_t GetGPRSize() const override { return GetGPRSizeStatic(); }

  size_t GetFPRSize() const override;

  const lldb_private::RegisterInfo *GetRegisterInfo() const override;

  uint32_t GetRegisterCount() const override;

  const lldb_private::RegisterSet *
  GetRegisterSet(size_t reg_set) const override;

  size_t GetRegisterSetCount() const override;

  size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;

  void AddRegSetPAuth();

  void AddRegSetMTE();

  void AddRegSetTLS(bool has_tpidr2);

  void AddRegSetSME(bool has_zt);

  uint32_t ConfigureVectorLengthSVE(uint32_t sve_vq);

  void ConfigureVectorLengthZA(uint32_t za_vq);

  bool VectorSizeIsValid(uint32_t vq) {
    // coverity[unsigned_compare]
    if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax)
      return true;
    return false;
  }

  bool IsSVEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); }
  bool IsSSVEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskSSVE); }
  bool IsZAPresent() const { return m_opt_regsets.AnySet(eRegsetMaskZA); }
  bool IsZTPresent() const { return m_opt_regsets.AnySet(eRegsetMaskZT); }
  bool IsPAuthPresent() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
  bool IsMTEPresent() const { return m_opt_regsets.AnySet(eRegsetMaskMTE); }
  bool IsTLSPresent() const { return m_opt_regsets.AnySet(eRegsetMaskTLS); }

  bool IsSVEReg(unsigned reg) const;
  bool IsSVEZReg(unsigned reg) const;
  bool IsSVEPReg(unsigned reg) const;
  bool IsSVERegVG(unsigned reg) const;
  bool IsPAuthReg(unsigned reg) const;
  bool IsMTEReg(unsigned reg) const;
  bool IsTLSReg(unsigned reg) const;
  bool IsSMEReg(unsigned reg) const;
  bool IsSMERegZA(unsigned reg) const;
  bool IsSMERegZT(unsigned reg) const;

  uint32_t GetRegNumSVEZ0() const;
  uint32_t GetRegNumSVEFFR() const;
  uint32_t GetRegNumFPCR() const;
  uint32_t GetRegNumFPSR() const;
  uint32_t GetRegNumSVEVG() const;
  uint32_t GetRegNumSMESVG() const;
  uint32_t GetPAuthOffset() const;
  uint32_t GetMTEOffset() const;
  uint32_t GetTLSOffset() const;
  uint32_t GetSMEOffset() const;

private:
  typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>>
      per_vq_register_infos;

  per_vq_register_infos m_per_vq_reg_infos;

  uint32_t m_vector_reg_vq = eVectorQuadwordAArch64;
  uint32_t m_za_reg_vq = eVectorQuadwordAArch64;

  // In normal operation this is const. Only when SVE or SME registers change
  // size is it either replaced or the content modified.
  const lldb_private::RegisterInfo *m_register_info_p;
  uint32_t m_register_info_count;

  const lldb_private::RegisterSet *m_register_set_p;
  uint32_t m_register_set_count;

  // Contains pair of [start, end] register numbers of a register set with start
  // and end included.
  std::map<uint32_t, std::pair<uint32_t, uint32_t>> m_per_regset_regnum_range;

  lldb_private::Flags m_opt_regsets;

  std::vector<lldb_private::RegisterInfo> m_dynamic_reg_infos;
  std::vector<lldb_private::RegisterSet> m_dynamic_reg_sets;

  std::vector<uint32_t> pauth_regnum_collection;
  std::vector<uint32_t> m_mte_regnum_collection;
  std::vector<uint32_t> m_tls_regnum_collection;
  std::vector<uint32_t> m_sme_regnum_collection;
};

#endif