15ffd83dbSDimitry Andric //===-- RegisterInfoPOSIX_arm64.cpp ---------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===---------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include <cassert> 100b57cec5SDimitry Andric #include <stddef.h> 110b57cec5SDimitry Andric #include <vector> 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "lldb/lldb-defines.h" 140b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "RegisterInfoPOSIX_arm64.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric // Based on RegisterContextDarwin_arm64.cpp 190b57cec5SDimitry Andric #define GPR_OFFSET(idx) ((idx)*8) 200b57cec5SDimitry Andric #define GPR_OFFSET_NAME(reg) \ 210b57cec5SDimitry Andric (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::GPR, reg)) 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #define FPU_OFFSET(idx) ((idx)*16 + sizeof(RegisterInfoPOSIX_arm64::GPR)) 240b57cec5SDimitry Andric #define FPU_OFFSET_NAME(reg) \ 250b57cec5SDimitry Andric (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::FPU, reg) + \ 260b57cec5SDimitry Andric sizeof(RegisterInfoPOSIX_arm64::GPR)) 270b57cec5SDimitry Andric 28e8d8bef9SDimitry Andric // This information is based on AArch64 with SVE architecture reference manual. 29e8d8bef9SDimitry Andric // AArch64 with SVE has 32 Z and 16 P vector registers. There is also an FFR 30e8d8bef9SDimitry Andric // (First Fault) register and a VG (Vector Granule) pseudo register. 31e8d8bef9SDimitry Andric 32e8d8bef9SDimitry Andric // SVE 16-byte quad word is the basic unit of expansion in vector length. 33e8d8bef9SDimitry Andric #define SVE_QUAD_WORD_BYTES 16 34e8d8bef9SDimitry Andric 35e8d8bef9SDimitry Andric // Vector length is the multiplier which decides the no of quad words, 36e8d8bef9SDimitry Andric // (multiples of 128-bits or 16-bytes) present in a Z register. Vector length 37e8d8bef9SDimitry Andric // is decided during execution and can change at runtime. SVE AArch64 register 38e8d8bef9SDimitry Andric // infos have modes one for each valid value of vector length. A change in 39e8d8bef9SDimitry Andric // vector length requires register context to update sizes of SVE Z, P and FFR. 40e8d8bef9SDimitry Andric // Also register context needs to update byte offsets of all registers affected 41e8d8bef9SDimitry Andric // by the change in vector length. 42e8d8bef9SDimitry Andric #define SVE_REGS_DEFAULT_OFFSET_LINUX sizeof(RegisterInfoPOSIX_arm64::GPR) 43e8d8bef9SDimitry Andric 44e8d8bef9SDimitry Andric #define SVE_OFFSET_VG SVE_REGS_DEFAULT_OFFSET_LINUX 45e8d8bef9SDimitry Andric 460b57cec5SDimitry Andric #define EXC_OFFSET_NAME(reg) \ 470b57cec5SDimitry Andric (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::EXC, reg) + \ 480b57cec5SDimitry Andric sizeof(RegisterInfoPOSIX_arm64::GPR) + \ 490b57cec5SDimitry Andric sizeof(RegisterInfoPOSIX_arm64::FPU)) 500b57cec5SDimitry Andric #define DBG_OFFSET_NAME(reg) \ 510b57cec5SDimitry Andric (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::DBG, reg) + \ 520b57cec5SDimitry Andric sizeof(RegisterInfoPOSIX_arm64::GPR) + \ 530b57cec5SDimitry Andric sizeof(RegisterInfoPOSIX_arm64::FPU) + \ 540b57cec5SDimitry Andric sizeof(RegisterInfoPOSIX_arm64::EXC)) 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric #define DEFINE_DBG(reg, i) \ 570b57cec5SDimitry Andric #reg, NULL, \ 580b57cec5SDimitry Andric sizeof(((RegisterInfoPOSIX_arm64::DBG *) NULL)->reg[i]), \ 590b57cec5SDimitry Andric DBG_OFFSET_NAME(reg[i]), lldb::eEncodingUint, lldb::eFormatHex, \ 600b57cec5SDimitry Andric {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 610b57cec5SDimitry Andric LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 620b57cec5SDimitry Andric dbg_##reg##i }, \ 630b57cec5SDimitry Andric NULL, NULL, NULL, 0 640b57cec5SDimitry Andric #define REG_CONTEXT_SIZE \ 650b57cec5SDimitry Andric (sizeof(RegisterInfoPOSIX_arm64::GPR) + \ 660b57cec5SDimitry Andric sizeof(RegisterInfoPOSIX_arm64::FPU) + \ 670b57cec5SDimitry Andric sizeof(RegisterInfoPOSIX_arm64::EXC)) 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric // Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure. 700b57cec5SDimitry Andric #define DECLARE_REGISTER_INFOS_ARM64_STRUCT 710b57cec5SDimitry Andric #include "RegisterInfos_arm64.h" 72e8d8bef9SDimitry Andric #include "RegisterInfos_arm64_sve.h" 730b57cec5SDimitry Andric #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric static const lldb_private::RegisterInfo * 760b57cec5SDimitry Andric GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) { 770b57cec5SDimitry Andric switch (target_arch.GetMachine()) { 780b57cec5SDimitry Andric case llvm::Triple::aarch64: 799dba64beSDimitry Andric case llvm::Triple::aarch64_32: 800b57cec5SDimitry Andric return g_register_infos_arm64_le; 810b57cec5SDimitry Andric default: 820b57cec5SDimitry Andric assert(false && "Unhandled target architecture."); 830b57cec5SDimitry Andric return nullptr; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 875ffd83dbSDimitry Andric // Number of register sets provided by this context. 885ffd83dbSDimitry Andric enum { 895ffd83dbSDimitry Andric k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, 905ffd83dbSDimitry Andric k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1, 91e8d8bef9SDimitry Andric k_num_sve_registers = sve_ffr - sve_vg + 1, 92e8d8bef9SDimitry Andric k_num_register_sets = 3 935ffd83dbSDimitry Andric }; 945ffd83dbSDimitry Andric 955ffd83dbSDimitry Andric // ARM64 general purpose registers. 965ffd83dbSDimitry Andric static const uint32_t g_gpr_regnums_arm64[] = { 975ffd83dbSDimitry Andric gpr_x0, gpr_x1, gpr_x2, gpr_x3, 985ffd83dbSDimitry Andric gpr_x4, gpr_x5, gpr_x6, gpr_x7, 995ffd83dbSDimitry Andric gpr_x8, gpr_x9, gpr_x10, gpr_x11, 1005ffd83dbSDimitry Andric gpr_x12, gpr_x13, gpr_x14, gpr_x15, 1015ffd83dbSDimitry Andric gpr_x16, gpr_x17, gpr_x18, gpr_x19, 1025ffd83dbSDimitry Andric gpr_x20, gpr_x21, gpr_x22, gpr_x23, 1035ffd83dbSDimitry Andric gpr_x24, gpr_x25, gpr_x26, gpr_x27, 1045ffd83dbSDimitry Andric gpr_x28, gpr_fp, gpr_lr, gpr_sp, 1055ffd83dbSDimitry Andric gpr_pc, gpr_cpsr, gpr_w0, gpr_w1, 1065ffd83dbSDimitry Andric gpr_w2, gpr_w3, gpr_w4, gpr_w5, 1075ffd83dbSDimitry Andric gpr_w6, gpr_w7, gpr_w8, gpr_w9, 1085ffd83dbSDimitry Andric gpr_w10, gpr_w11, gpr_w12, gpr_w13, 1095ffd83dbSDimitry Andric gpr_w14, gpr_w15, gpr_w16, gpr_w17, 1105ffd83dbSDimitry Andric gpr_w18, gpr_w19, gpr_w20, gpr_w21, 1115ffd83dbSDimitry Andric gpr_w22, gpr_w23, gpr_w24, gpr_w25, 1125ffd83dbSDimitry Andric gpr_w26, gpr_w27, gpr_w28, LLDB_INVALID_REGNUM}; 1135ffd83dbSDimitry Andric 1145ffd83dbSDimitry Andric static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - 1155ffd83dbSDimitry Andric 1) == k_num_gpr_registers, 1165ffd83dbSDimitry Andric "g_gpr_regnums_arm64 has wrong number of register infos"); 1175ffd83dbSDimitry Andric 1185ffd83dbSDimitry Andric // ARM64 floating point registers. 1195ffd83dbSDimitry Andric static const uint32_t g_fpu_regnums_arm64[] = { 1205ffd83dbSDimitry Andric fpu_v0, fpu_v1, fpu_v2, 1215ffd83dbSDimitry Andric fpu_v3, fpu_v4, fpu_v5, 1225ffd83dbSDimitry Andric fpu_v6, fpu_v7, fpu_v8, 1235ffd83dbSDimitry Andric fpu_v9, fpu_v10, fpu_v11, 1245ffd83dbSDimitry Andric fpu_v12, fpu_v13, fpu_v14, 1255ffd83dbSDimitry Andric fpu_v15, fpu_v16, fpu_v17, 1265ffd83dbSDimitry Andric fpu_v18, fpu_v19, fpu_v20, 1275ffd83dbSDimitry Andric fpu_v21, fpu_v22, fpu_v23, 1285ffd83dbSDimitry Andric fpu_v24, fpu_v25, fpu_v26, 1295ffd83dbSDimitry Andric fpu_v27, fpu_v28, fpu_v29, 1305ffd83dbSDimitry Andric fpu_v30, fpu_v31, fpu_s0, 1315ffd83dbSDimitry Andric fpu_s1, fpu_s2, fpu_s3, 1325ffd83dbSDimitry Andric fpu_s4, fpu_s5, fpu_s6, 1335ffd83dbSDimitry Andric fpu_s7, fpu_s8, fpu_s9, 1345ffd83dbSDimitry Andric fpu_s10, fpu_s11, fpu_s12, 1355ffd83dbSDimitry Andric fpu_s13, fpu_s14, fpu_s15, 1365ffd83dbSDimitry Andric fpu_s16, fpu_s17, fpu_s18, 1375ffd83dbSDimitry Andric fpu_s19, fpu_s20, fpu_s21, 1385ffd83dbSDimitry Andric fpu_s22, fpu_s23, fpu_s24, 1395ffd83dbSDimitry Andric fpu_s25, fpu_s26, fpu_s27, 1405ffd83dbSDimitry Andric fpu_s28, fpu_s29, fpu_s30, 1415ffd83dbSDimitry Andric fpu_s31, fpu_d0, fpu_d1, 1425ffd83dbSDimitry Andric fpu_d2, fpu_d3, fpu_d4, 1435ffd83dbSDimitry Andric fpu_d5, fpu_d6, fpu_d7, 1445ffd83dbSDimitry Andric fpu_d8, fpu_d9, fpu_d10, 1455ffd83dbSDimitry Andric fpu_d11, fpu_d12, fpu_d13, 1465ffd83dbSDimitry Andric fpu_d14, fpu_d15, fpu_d16, 1475ffd83dbSDimitry Andric fpu_d17, fpu_d18, fpu_d19, 1485ffd83dbSDimitry Andric fpu_d20, fpu_d21, fpu_d22, 1495ffd83dbSDimitry Andric fpu_d23, fpu_d24, fpu_d25, 1505ffd83dbSDimitry Andric fpu_d26, fpu_d27, fpu_d28, 1515ffd83dbSDimitry Andric fpu_d29, fpu_d30, fpu_d31, 1525ffd83dbSDimitry Andric fpu_fpsr, fpu_fpcr, LLDB_INVALID_REGNUM}; 1535ffd83dbSDimitry Andric static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - 1545ffd83dbSDimitry Andric 1) == k_num_fpr_registers, 1555ffd83dbSDimitry Andric "g_fpu_regnums_arm64 has wrong number of register infos"); 156e8d8bef9SDimitry Andric 157e8d8bef9SDimitry Andric // ARM64 SVE registers. 158e8d8bef9SDimitry Andric static const uint32_t g_sve_regnums_arm64[] = { 159e8d8bef9SDimitry Andric sve_vg, sve_z0, sve_z1, 160e8d8bef9SDimitry Andric sve_z2, sve_z3, sve_z4, 161e8d8bef9SDimitry Andric sve_z5, sve_z6, sve_z7, 162e8d8bef9SDimitry Andric sve_z8, sve_z9, sve_z10, 163e8d8bef9SDimitry Andric sve_z11, sve_z12, sve_z13, 164e8d8bef9SDimitry Andric sve_z14, sve_z15, sve_z16, 165e8d8bef9SDimitry Andric sve_z17, sve_z18, sve_z19, 166e8d8bef9SDimitry Andric sve_z20, sve_z21, sve_z22, 167e8d8bef9SDimitry Andric sve_z23, sve_z24, sve_z25, 168e8d8bef9SDimitry Andric sve_z26, sve_z27, sve_z28, 169e8d8bef9SDimitry Andric sve_z29, sve_z30, sve_z31, 170e8d8bef9SDimitry Andric sve_p0, sve_p1, sve_p2, 171e8d8bef9SDimitry Andric sve_p3, sve_p4, sve_p5, 172e8d8bef9SDimitry Andric sve_p6, sve_p7, sve_p8, 173e8d8bef9SDimitry Andric sve_p9, sve_p10, sve_p11, 174e8d8bef9SDimitry Andric sve_p12, sve_p13, sve_p14, 175e8d8bef9SDimitry Andric sve_p15, sve_ffr, LLDB_INVALID_REGNUM}; 176e8d8bef9SDimitry Andric static_assert(((sizeof g_sve_regnums_arm64 / sizeof g_sve_regnums_arm64[0]) - 177e8d8bef9SDimitry Andric 1) == k_num_sve_registers, 178e8d8bef9SDimitry Andric "g_sve_regnums_arm64 has wrong number of register infos"); 179e8d8bef9SDimitry Andric 1805ffd83dbSDimitry Andric // Register sets for ARM64. 1815ffd83dbSDimitry Andric static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = { 1825ffd83dbSDimitry Andric {"General Purpose Registers", "gpr", k_num_gpr_registers, 1835ffd83dbSDimitry Andric g_gpr_regnums_arm64}, 1845ffd83dbSDimitry Andric {"Floating Point Registers", "fpu", k_num_fpr_registers, 185e8d8bef9SDimitry Andric g_fpu_regnums_arm64}, 186e8d8bef9SDimitry Andric {"Scalable Vector Extension Registers", "sve", k_num_sve_registers, 187e8d8bef9SDimitry Andric g_sve_regnums_arm64}}; 1885ffd83dbSDimitry Andric 1890b57cec5SDimitry Andric static uint32_t 1900b57cec5SDimitry Andric GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) { 1910b57cec5SDimitry Andric switch (target_arch.GetMachine()) { 1920b57cec5SDimitry Andric case llvm::Triple::aarch64: 1939dba64beSDimitry Andric case llvm::Triple::aarch64_32: 1940b57cec5SDimitry Andric return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) / 1950b57cec5SDimitry Andric sizeof(g_register_infos_arm64_le[0])); 1960b57cec5SDimitry Andric default: 1970b57cec5SDimitry Andric assert(false && "Unhandled target architecture."); 1980b57cec5SDimitry Andric return 0; 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( 2030b57cec5SDimitry Andric const lldb_private::ArchSpec &target_arch) 2045ffd83dbSDimitry Andric : lldb_private::RegisterInfoAndSetInterface(target_arch), 2050b57cec5SDimitry Andric m_register_info_p(GetRegisterInfoPtr(target_arch)), 2065ffd83dbSDimitry Andric m_register_info_count(GetRegisterInfoCount(target_arch)) { 2075ffd83dbSDimitry Andric } 2085ffd83dbSDimitry Andric 2095ffd83dbSDimitry Andric uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const { 210e8d8bef9SDimitry Andric if (IsSVEEnabled()) 211e8d8bef9SDimitry Andric return k_num_gpr_registers + k_num_fpr_registers + k_num_sve_registers; 212e8d8bef9SDimitry Andric 213e8d8bef9SDimitry Andric return k_num_gpr_registers + k_num_fpr_registers; 2145ffd83dbSDimitry Andric } 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric size_t RegisterInfoPOSIX_arm64::GetGPRSize() const { 2170b57cec5SDimitry Andric return sizeof(struct RegisterInfoPOSIX_arm64::GPR); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2205ffd83dbSDimitry Andric size_t RegisterInfoPOSIX_arm64::GetFPRSize() const { 2215ffd83dbSDimitry Andric return sizeof(struct RegisterInfoPOSIX_arm64::FPU); 2225ffd83dbSDimitry Andric } 2235ffd83dbSDimitry Andric 2240b57cec5SDimitry Andric const lldb_private::RegisterInfo * 2250b57cec5SDimitry Andric RegisterInfoPOSIX_arm64::GetRegisterInfo() const { 2260b57cec5SDimitry Andric return m_register_info_p; 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2295ffd83dbSDimitry Andric size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const { 230e8d8bef9SDimitry Andric if (IsSVEEnabled()) 2315ffd83dbSDimitry Andric return k_num_register_sets; 232e8d8bef9SDimitry Andric return k_num_register_sets - 1; 2335ffd83dbSDimitry Andric } 2345ffd83dbSDimitry Andric 2355ffd83dbSDimitry Andric size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex( 2365ffd83dbSDimitry Andric uint32_t reg_index) const { 237e8d8bef9SDimitry Andric if (reg_index <= gpr_w28) 2385ffd83dbSDimitry Andric return GPRegSet; 239e8d8bef9SDimitry Andric if (reg_index <= fpu_fpcr) 2405ffd83dbSDimitry Andric return FPRegSet; 241e8d8bef9SDimitry Andric if (reg_index <= sve_ffr) 242e8d8bef9SDimitry Andric return SVERegSet; 2435ffd83dbSDimitry Andric return LLDB_INVALID_REGNUM; 2445ffd83dbSDimitry Andric } 2455ffd83dbSDimitry Andric 2465ffd83dbSDimitry Andric const lldb_private::RegisterSet * 2475ffd83dbSDimitry Andric RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const { 248e8d8bef9SDimitry Andric if (set_index < GetRegisterSetCount()) 2495ffd83dbSDimitry Andric return &g_reg_sets_arm64[set_index]; 2505ffd83dbSDimitry Andric return nullptr; 2510b57cec5SDimitry Andric } 252e8d8bef9SDimitry Andric 253e8d8bef9SDimitry Andric uint32_t 254e8d8bef9SDimitry Andric RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) { 255e8d8bef9SDimitry Andric // sve_vq contains SVE Quad vector length in context of AArch64 SVE. 256e8d8bef9SDimitry Andric // SVE register infos if enabled cannot be disabled by selecting sve_vq = 0. 257e8d8bef9SDimitry Andric // Also if an invalid or previously set vector length is passed to this 258e8d8bef9SDimitry Andric // function then it will exit immediately with previously set vector length. 259e8d8bef9SDimitry Andric if (!VectorSizeIsValid(sve_vq) || m_vector_reg_vq == sve_vq) 260e8d8bef9SDimitry Andric return m_vector_reg_vq; 261e8d8bef9SDimitry Andric 262e8d8bef9SDimitry Andric // We cannot enable AArch64 only mode if SVE was enabled. 263e8d8bef9SDimitry Andric if (sve_vq == eVectorQuadwordAArch64 && 264e8d8bef9SDimitry Andric m_vector_reg_vq > eVectorQuadwordAArch64) 265e8d8bef9SDimitry Andric sve_vq = eVectorQuadwordAArch64SVE; 266e8d8bef9SDimitry Andric 267e8d8bef9SDimitry Andric m_vector_reg_vq = sve_vq; 268e8d8bef9SDimitry Andric 269e8d8bef9SDimitry Andric if (sve_vq == eVectorQuadwordAArch64) { 270e8d8bef9SDimitry Andric m_register_info_count = 271e8d8bef9SDimitry Andric static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) / 272e8d8bef9SDimitry Andric sizeof(g_register_infos_arm64_le[0])); 273e8d8bef9SDimitry Andric m_register_info_p = g_register_infos_arm64_le; 274e8d8bef9SDimitry Andric 275e8d8bef9SDimitry Andric return m_vector_reg_vq; 276e8d8bef9SDimitry Andric } 277e8d8bef9SDimitry Andric 278e8d8bef9SDimitry Andric m_register_info_count = 279e8d8bef9SDimitry Andric static_cast<uint32_t>(sizeof(g_register_infos_arm64_sve_le) / 280e8d8bef9SDimitry Andric sizeof(g_register_infos_arm64_sve_le[0])); 281e8d8bef9SDimitry Andric 282e8d8bef9SDimitry Andric std::vector<lldb_private::RegisterInfo> ®_info_ref = 283e8d8bef9SDimitry Andric m_per_vq_reg_infos[sve_vq]; 284e8d8bef9SDimitry Andric 285e8d8bef9SDimitry Andric if (reg_info_ref.empty()) { 286e8d8bef9SDimitry Andric reg_info_ref = llvm::makeArrayRef(g_register_infos_arm64_sve_le, 287e8d8bef9SDimitry Andric m_register_info_count); 288e8d8bef9SDimitry Andric 289e8d8bef9SDimitry Andric uint32_t offset = SVE_REGS_DEFAULT_OFFSET_LINUX; 290e8d8bef9SDimitry Andric 291e8d8bef9SDimitry Andric reg_info_ref[fpu_fpsr].byte_offset = offset; 292e8d8bef9SDimitry Andric reg_info_ref[fpu_fpcr].byte_offset = offset + 4; 293e8d8bef9SDimitry Andric reg_info_ref[sve_vg].byte_offset = offset + 8; 294e8d8bef9SDimitry Andric offset += 16; 295e8d8bef9SDimitry Andric 296e8d8bef9SDimitry Andric // Update Z registers size and offset 297e8d8bef9SDimitry Andric uint32_t s_reg_base = fpu_s0; 298e8d8bef9SDimitry Andric uint32_t d_reg_base = fpu_d0; 299e8d8bef9SDimitry Andric uint32_t v_reg_base = fpu_v0; 300e8d8bef9SDimitry Andric uint32_t z_reg_base = sve_z0; 301e8d8bef9SDimitry Andric 302e8d8bef9SDimitry Andric for (uint32_t index = 0; index < 32; index++) { 303e8d8bef9SDimitry Andric reg_info_ref[s_reg_base + index].byte_offset = offset; 304e8d8bef9SDimitry Andric reg_info_ref[d_reg_base + index].byte_offset = offset; 305e8d8bef9SDimitry Andric reg_info_ref[v_reg_base + index].byte_offset = offset; 306e8d8bef9SDimitry Andric reg_info_ref[z_reg_base + index].byte_offset = offset; 307e8d8bef9SDimitry Andric 308e8d8bef9SDimitry Andric reg_info_ref[z_reg_base + index].byte_size = sve_vq * SVE_QUAD_WORD_BYTES; 309e8d8bef9SDimitry Andric offset += reg_info_ref[z_reg_base + index].byte_size; 310e8d8bef9SDimitry Andric } 311e8d8bef9SDimitry Andric 312e8d8bef9SDimitry Andric // Update P registers and FFR size and offset 313e8d8bef9SDimitry Andric for (uint32_t it = sve_p0; it <= sve_ffr; it++) { 314e8d8bef9SDimitry Andric reg_info_ref[it].byte_offset = offset; 315e8d8bef9SDimitry Andric reg_info_ref[it].byte_size = sve_vq * SVE_QUAD_WORD_BYTES / 8; 316e8d8bef9SDimitry Andric offset += reg_info_ref[it].byte_size; 317e8d8bef9SDimitry Andric } 318e8d8bef9SDimitry Andric 319e8d8bef9SDimitry Andric m_per_vq_reg_infos[sve_vq] = reg_info_ref; 320e8d8bef9SDimitry Andric } 321e8d8bef9SDimitry Andric 322e8d8bef9SDimitry Andric m_register_info_p = reg_info_ref.data(); 323e8d8bef9SDimitry Andric return m_vector_reg_vq; 324e8d8bef9SDimitry Andric } 325e8d8bef9SDimitry Andric 326e8d8bef9SDimitry Andric bool RegisterInfoPOSIX_arm64::IsSVEZReg(unsigned reg) const { 327e8d8bef9SDimitry Andric return (sve_z0 <= reg && reg <= sve_z31); 328e8d8bef9SDimitry Andric } 329e8d8bef9SDimitry Andric 330e8d8bef9SDimitry Andric bool RegisterInfoPOSIX_arm64::IsSVEPReg(unsigned reg) const { 331e8d8bef9SDimitry Andric return (sve_p0 <= reg && reg <= sve_p15); 332e8d8bef9SDimitry Andric } 333e8d8bef9SDimitry Andric 334e8d8bef9SDimitry Andric bool RegisterInfoPOSIX_arm64::IsSVERegVG(unsigned reg) const { 335e8d8bef9SDimitry Andric return sve_vg == reg; 336e8d8bef9SDimitry Andric } 337e8d8bef9SDimitry Andric 338e8d8bef9SDimitry Andric uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEZ0() const { return sve_z0; } 339e8d8bef9SDimitry Andric 340e8d8bef9SDimitry Andric uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEFFR() const { return sve_ffr; } 341e8d8bef9SDimitry Andric 342e8d8bef9SDimitry Andric uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPCR() const { return fpu_fpcr; } 343e8d8bef9SDimitry Andric 344e8d8bef9SDimitry Andric uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPSR() const { return fpu_fpsr; } 345e8d8bef9SDimitry Andric 346e8d8bef9SDimitry Andric uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEVG() const { return sve_vg; } 347