1*f5c631daSSadaf Ebrahimi // Copyright 2014, VIXL authors 2*f5c631daSSadaf Ebrahimi // All rights reserved. 3*f5c631daSSadaf Ebrahimi // 4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without 5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met: 6*f5c631daSSadaf Ebrahimi // 7*f5c631daSSadaf Ebrahimi // * Redistributions of source code must retain the above copyright notice, 8*f5c631daSSadaf Ebrahimi // this list of conditions and the following disclaimer. 9*f5c631daSSadaf Ebrahimi // * Redistributions in binary form must reproduce the above copyright notice, 10*f5c631daSSadaf Ebrahimi // this list of conditions and the following disclaimer in the documentation 11*f5c631daSSadaf Ebrahimi // and/or other materials provided with the distribution. 12*f5c631daSSadaf Ebrahimi // * Neither the name of ARM Limited nor the names of its contributors may be 13*f5c631daSSadaf Ebrahimi // used to endorse or promote products derived from this software without 14*f5c631daSSadaf Ebrahimi // specific prior written permission. 15*f5c631daSSadaf Ebrahimi // 16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18*f5c631daSSadaf Ebrahimi // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19*f5c631daSSadaf Ebrahimi // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20*f5c631daSSadaf Ebrahimi // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*f5c631daSSadaf Ebrahimi // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22*f5c631daSSadaf Ebrahimi // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23*f5c631daSSadaf Ebrahimi // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24*f5c631daSSadaf Ebrahimi // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25*f5c631daSSadaf Ebrahimi // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*f5c631daSSadaf Ebrahimi 27*f5c631daSSadaf Ebrahimi #ifndef VIXL_CPU_AARCH64_H 28*f5c631daSSadaf Ebrahimi #define VIXL_CPU_AARCH64_H 29*f5c631daSSadaf Ebrahimi 30*f5c631daSSadaf Ebrahimi #include "../cpu-features.h" 31*f5c631daSSadaf Ebrahimi #include "../globals-vixl.h" 32*f5c631daSSadaf Ebrahimi 33*f5c631daSSadaf Ebrahimi #include "instructions-aarch64.h" 34*f5c631daSSadaf Ebrahimi 35*f5c631daSSadaf Ebrahimi #ifndef VIXL_INCLUDE_TARGET_AARCH64 36*f5c631daSSadaf Ebrahimi // The supporting .cc file is only compiled when the A64 target is selected. 37*f5c631daSSadaf Ebrahimi // Throw an explicit error now to avoid a harder-to-debug linker error later. 38*f5c631daSSadaf Ebrahimi // 39*f5c631daSSadaf Ebrahimi // These helpers _could_ work on any AArch64 host, even when generating AArch32 40*f5c631daSSadaf Ebrahimi // code, but we don't support this because the available features may differ 41*f5c631daSSadaf Ebrahimi // between AArch32 and AArch64 on the same platform, so basing AArch32 code 42*f5c631daSSadaf Ebrahimi // generation on aarch64::CPU features is probably broken. 43*f5c631daSSadaf Ebrahimi #error cpu-aarch64.h requires VIXL_INCLUDE_TARGET_AARCH64 (scons target=a64). 44*f5c631daSSadaf Ebrahimi #endif 45*f5c631daSSadaf Ebrahimi 46*f5c631daSSadaf Ebrahimi namespace vixl { 47*f5c631daSSadaf Ebrahimi namespace aarch64 { 48*f5c631daSSadaf Ebrahimi 49*f5c631daSSadaf Ebrahimi // A CPU ID register, for use with CPUFeatures::kIDRegisterEmulation. Fields 50*f5c631daSSadaf Ebrahimi // specific to each register are described in relevant subclasses. 51*f5c631daSSadaf Ebrahimi class IDRegister { 52*f5c631daSSadaf Ebrahimi protected: value_(value)53*f5c631daSSadaf Ebrahimi explicit IDRegister(uint64_t value = 0) : value_(value) {} 54*f5c631daSSadaf Ebrahimi 55*f5c631daSSadaf Ebrahimi class Field { 56*f5c631daSSadaf Ebrahimi public: 57*f5c631daSSadaf Ebrahimi enum Type { kUnsigned, kSigned }; 58*f5c631daSSadaf Ebrahimi 59*f5c631daSSadaf Ebrahimi // This needs to be constexpr so that fields have "constant initialisation". 60*f5c631daSSadaf Ebrahimi // This avoids initialisation order problems when these values are used to 61*f5c631daSSadaf Ebrahimi // (dynamically) initialise static variables, etc. 62*f5c631daSSadaf Ebrahimi explicit constexpr Field(int lsb, Type type = kUnsigned) lsb_(lsb)63*f5c631daSSadaf Ebrahimi : lsb_(lsb), type_(type) {} 64*f5c631daSSadaf Ebrahimi 65*f5c631daSSadaf Ebrahimi static const int kMaxWidthInBits = 4; 66*f5c631daSSadaf Ebrahimi GetWidthInBits()67*f5c631daSSadaf Ebrahimi int GetWidthInBits() const { 68*f5c631daSSadaf Ebrahimi // All current ID fields have four bits. 69*f5c631daSSadaf Ebrahimi return kMaxWidthInBits; 70*f5c631daSSadaf Ebrahimi } GetLsb()71*f5c631daSSadaf Ebrahimi int GetLsb() const { return lsb_; } GetMsb()72*f5c631daSSadaf Ebrahimi int GetMsb() const { return lsb_ + GetWidthInBits() - 1; } GetType()73*f5c631daSSadaf Ebrahimi Type GetType() const { return type_; } 74*f5c631daSSadaf Ebrahimi 75*f5c631daSSadaf Ebrahimi private: 76*f5c631daSSadaf Ebrahimi int lsb_; 77*f5c631daSSadaf Ebrahimi Type type_; 78*f5c631daSSadaf Ebrahimi }; 79*f5c631daSSadaf Ebrahimi 80*f5c631daSSadaf Ebrahimi public: 81*f5c631daSSadaf Ebrahimi // Extract the specified field, performing sign-extension for signed fields. 82*f5c631daSSadaf Ebrahimi // This allows us to implement the 'value >= number' detection mechanism 83*f5c631daSSadaf Ebrahimi // recommended by the Arm ARM, for both signed and unsigned fields. 84*f5c631daSSadaf Ebrahimi int Get(Field field) const; 85*f5c631daSSadaf Ebrahimi 86*f5c631daSSadaf Ebrahimi private: 87*f5c631daSSadaf Ebrahimi uint64_t value_; 88*f5c631daSSadaf Ebrahimi }; 89*f5c631daSSadaf Ebrahimi 90*f5c631daSSadaf Ebrahimi class AA64PFR0 : public IDRegister { 91*f5c631daSSadaf Ebrahimi public: AA64PFR0(uint64_t value)92*f5c631daSSadaf Ebrahimi explicit AA64PFR0(uint64_t value) : IDRegister(value) {} 93*f5c631daSSadaf Ebrahimi 94*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 95*f5c631daSSadaf Ebrahimi 96*f5c631daSSadaf Ebrahimi private: 97*f5c631daSSadaf Ebrahimi static const Field kFP; 98*f5c631daSSadaf Ebrahimi static const Field kAdvSIMD; 99*f5c631daSSadaf Ebrahimi static const Field kRAS; 100*f5c631daSSadaf Ebrahimi static const Field kSVE; 101*f5c631daSSadaf Ebrahimi static const Field kDIT; 102*f5c631daSSadaf Ebrahimi static const Field kCSV2; 103*f5c631daSSadaf Ebrahimi static const Field kCSV3; 104*f5c631daSSadaf Ebrahimi }; 105*f5c631daSSadaf Ebrahimi 106*f5c631daSSadaf Ebrahimi class AA64PFR1 : public IDRegister { 107*f5c631daSSadaf Ebrahimi public: AA64PFR1(uint64_t value)108*f5c631daSSadaf Ebrahimi explicit AA64PFR1(uint64_t value) : IDRegister(value) {} 109*f5c631daSSadaf Ebrahimi 110*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 111*f5c631daSSadaf Ebrahimi 112*f5c631daSSadaf Ebrahimi private: 113*f5c631daSSadaf Ebrahimi static const Field kBT; 114*f5c631daSSadaf Ebrahimi static const Field kSSBS; 115*f5c631daSSadaf Ebrahimi static const Field kMTE; 116*f5c631daSSadaf Ebrahimi }; 117*f5c631daSSadaf Ebrahimi 118*f5c631daSSadaf Ebrahimi class AA64ISAR0 : public IDRegister { 119*f5c631daSSadaf Ebrahimi public: AA64ISAR0(uint64_t value)120*f5c631daSSadaf Ebrahimi explicit AA64ISAR0(uint64_t value) : IDRegister(value) {} 121*f5c631daSSadaf Ebrahimi 122*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 123*f5c631daSSadaf Ebrahimi 124*f5c631daSSadaf Ebrahimi private: 125*f5c631daSSadaf Ebrahimi static const Field kAES; 126*f5c631daSSadaf Ebrahimi static const Field kSHA1; 127*f5c631daSSadaf Ebrahimi static const Field kSHA2; 128*f5c631daSSadaf Ebrahimi static const Field kCRC32; 129*f5c631daSSadaf Ebrahimi static const Field kAtomic; 130*f5c631daSSadaf Ebrahimi static const Field kRDM; 131*f5c631daSSadaf Ebrahimi static const Field kSHA3; 132*f5c631daSSadaf Ebrahimi static const Field kSM3; 133*f5c631daSSadaf Ebrahimi static const Field kSM4; 134*f5c631daSSadaf Ebrahimi static const Field kDP; 135*f5c631daSSadaf Ebrahimi static const Field kFHM; 136*f5c631daSSadaf Ebrahimi static const Field kTS; 137*f5c631daSSadaf Ebrahimi static const Field kRNDR; 138*f5c631daSSadaf Ebrahimi }; 139*f5c631daSSadaf Ebrahimi 140*f5c631daSSadaf Ebrahimi class AA64ISAR1 : public IDRegister { 141*f5c631daSSadaf Ebrahimi public: AA64ISAR1(uint64_t value)142*f5c631daSSadaf Ebrahimi explicit AA64ISAR1(uint64_t value) : IDRegister(value) {} 143*f5c631daSSadaf Ebrahimi 144*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 145*f5c631daSSadaf Ebrahimi 146*f5c631daSSadaf Ebrahimi private: 147*f5c631daSSadaf Ebrahimi static const Field kDPB; 148*f5c631daSSadaf Ebrahimi static const Field kAPA; 149*f5c631daSSadaf Ebrahimi static const Field kAPI; 150*f5c631daSSadaf Ebrahimi static const Field kJSCVT; 151*f5c631daSSadaf Ebrahimi static const Field kFCMA; 152*f5c631daSSadaf Ebrahimi static const Field kLRCPC; 153*f5c631daSSadaf Ebrahimi static const Field kGPA; 154*f5c631daSSadaf Ebrahimi static const Field kGPI; 155*f5c631daSSadaf Ebrahimi static const Field kFRINTTS; 156*f5c631daSSadaf Ebrahimi static const Field kSB; 157*f5c631daSSadaf Ebrahimi static const Field kSPECRES; 158*f5c631daSSadaf Ebrahimi static const Field kBF16; 159*f5c631daSSadaf Ebrahimi static const Field kDGH; 160*f5c631daSSadaf Ebrahimi static const Field kI8MM; 161*f5c631daSSadaf Ebrahimi }; 162*f5c631daSSadaf Ebrahimi 163*f5c631daSSadaf Ebrahimi class AA64ISAR2 : public IDRegister { 164*f5c631daSSadaf Ebrahimi public: AA64ISAR2(uint64_t value)165*f5c631daSSadaf Ebrahimi explicit AA64ISAR2(uint64_t value) : IDRegister(value) {} 166*f5c631daSSadaf Ebrahimi 167*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 168*f5c631daSSadaf Ebrahimi 169*f5c631daSSadaf Ebrahimi private: 170*f5c631daSSadaf Ebrahimi static const Field kRPRES; 171*f5c631daSSadaf Ebrahimi }; 172*f5c631daSSadaf Ebrahimi 173*f5c631daSSadaf Ebrahimi class AA64MMFR0 : public IDRegister { 174*f5c631daSSadaf Ebrahimi public: AA64MMFR0(uint64_t value)175*f5c631daSSadaf Ebrahimi explicit AA64MMFR0(uint64_t value) : IDRegister(value) {} 176*f5c631daSSadaf Ebrahimi 177*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 178*f5c631daSSadaf Ebrahimi 179*f5c631daSSadaf Ebrahimi private: 180*f5c631daSSadaf Ebrahimi static const Field kECV; 181*f5c631daSSadaf Ebrahimi }; 182*f5c631daSSadaf Ebrahimi 183*f5c631daSSadaf Ebrahimi class AA64MMFR1 : public IDRegister { 184*f5c631daSSadaf Ebrahimi public: AA64MMFR1(uint64_t value)185*f5c631daSSadaf Ebrahimi explicit AA64MMFR1(uint64_t value) : IDRegister(value) {} 186*f5c631daSSadaf Ebrahimi 187*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 188*f5c631daSSadaf Ebrahimi 189*f5c631daSSadaf Ebrahimi private: 190*f5c631daSSadaf Ebrahimi static const Field kLO; 191*f5c631daSSadaf Ebrahimi static const Field kAFP; 192*f5c631daSSadaf Ebrahimi }; 193*f5c631daSSadaf Ebrahimi 194*f5c631daSSadaf Ebrahimi class AA64MMFR2 : public IDRegister { 195*f5c631daSSadaf Ebrahimi public: AA64MMFR2(uint64_t value)196*f5c631daSSadaf Ebrahimi explicit AA64MMFR2(uint64_t value) : IDRegister(value) {} 197*f5c631daSSadaf Ebrahimi 198*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 199*f5c631daSSadaf Ebrahimi 200*f5c631daSSadaf Ebrahimi private: 201*f5c631daSSadaf Ebrahimi static const Field kAT; 202*f5c631daSSadaf Ebrahimi }; 203*f5c631daSSadaf Ebrahimi 204*f5c631daSSadaf Ebrahimi class AA64ZFR0 : public IDRegister { 205*f5c631daSSadaf Ebrahimi public: AA64ZFR0(uint64_t value)206*f5c631daSSadaf Ebrahimi explicit AA64ZFR0(uint64_t value) : IDRegister(value) {} 207*f5c631daSSadaf Ebrahimi 208*f5c631daSSadaf Ebrahimi CPUFeatures GetCPUFeatures() const; 209*f5c631daSSadaf Ebrahimi 210*f5c631daSSadaf Ebrahimi private: 211*f5c631daSSadaf Ebrahimi static const Field kSVEver; 212*f5c631daSSadaf Ebrahimi static const Field kAES; 213*f5c631daSSadaf Ebrahimi static const Field kBitPerm; 214*f5c631daSSadaf Ebrahimi static const Field kBF16; 215*f5c631daSSadaf Ebrahimi static const Field kSHA3; 216*f5c631daSSadaf Ebrahimi static const Field kSM4; 217*f5c631daSSadaf Ebrahimi static const Field kI8MM; 218*f5c631daSSadaf Ebrahimi static const Field kF32MM; 219*f5c631daSSadaf Ebrahimi static const Field kF64MM; 220*f5c631daSSadaf Ebrahimi }; 221*f5c631daSSadaf Ebrahimi 222*f5c631daSSadaf Ebrahimi class CPU { 223*f5c631daSSadaf Ebrahimi public: 224*f5c631daSSadaf Ebrahimi // Initialise CPU support. 225*f5c631daSSadaf Ebrahimi static void SetUp(); 226*f5c631daSSadaf Ebrahimi 227*f5c631daSSadaf Ebrahimi // Ensures the data at a given address and with a given size is the same for 228*f5c631daSSadaf Ebrahimi // the I and D caches. I and D caches are not automatically coherent on ARM 229*f5c631daSSadaf Ebrahimi // so this operation is required before any dynamically generated code can 230*f5c631daSSadaf Ebrahimi // safely run. 231*f5c631daSSadaf Ebrahimi static void EnsureIAndDCacheCoherency(void *address, size_t length); 232*f5c631daSSadaf Ebrahimi 233*f5c631daSSadaf Ebrahimi // Read and interpret the ID registers. This requires 234*f5c631daSSadaf Ebrahimi // CPUFeatures::kIDRegisterEmulation, and therefore cannot be called on 235*f5c631daSSadaf Ebrahimi // non-AArch64 platforms. 236*f5c631daSSadaf Ebrahimi static CPUFeatures InferCPUFeaturesFromIDRegisters(); 237*f5c631daSSadaf Ebrahimi 238*f5c631daSSadaf Ebrahimi // Read and interpret CPUFeatures reported by the OS. Failed queries (or 239*f5c631daSSadaf Ebrahimi // unsupported platforms) return an empty list. Note that this is 240*f5c631daSSadaf Ebrahimi // indistinguishable from a successful query on a platform that advertises no 241*f5c631daSSadaf Ebrahimi // features. 242*f5c631daSSadaf Ebrahimi // 243*f5c631daSSadaf Ebrahimi // Non-AArch64 hosts are considered to be unsupported platforms, and this 244*f5c631daSSadaf Ebrahimi // function returns an empty list. 245*f5c631daSSadaf Ebrahimi static CPUFeatures InferCPUFeaturesFromOS( 246*f5c631daSSadaf Ebrahimi CPUFeatures::QueryIDRegistersOption option = 247*f5c631daSSadaf Ebrahimi CPUFeatures::kQueryIDRegistersIfAvailable); 248*f5c631daSSadaf Ebrahimi 249*f5c631daSSadaf Ebrahimi // Query the SVE vector length. This requires CPUFeatures::kSVE. 250*f5c631daSSadaf Ebrahimi static int ReadSVEVectorLengthInBits(); 251*f5c631daSSadaf Ebrahimi 252*f5c631daSSadaf Ebrahimi // Handle tagged pointers. 253*f5c631daSSadaf Ebrahimi template <typename T> SetPointerTag(T pointer,uint64_t tag)254*f5c631daSSadaf Ebrahimi static T SetPointerTag(T pointer, uint64_t tag) { 255*f5c631daSSadaf Ebrahimi VIXL_ASSERT(IsUintN(kAddressTagWidth, tag)); 256*f5c631daSSadaf Ebrahimi 257*f5c631daSSadaf Ebrahimi // Use C-style casts to get static_cast behaviour for integral types (T), 258*f5c631daSSadaf Ebrahimi // and reinterpret_cast behaviour for other types. 259*f5c631daSSadaf Ebrahimi 260*f5c631daSSadaf Ebrahimi uint64_t raw = (uint64_t)pointer; 261*f5c631daSSadaf Ebrahimi VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(raw)); 262*f5c631daSSadaf Ebrahimi 263*f5c631daSSadaf Ebrahimi raw = (raw & ~kAddressTagMask) | (tag << kAddressTagOffset); 264*f5c631daSSadaf Ebrahimi return (T)raw; 265*f5c631daSSadaf Ebrahimi } 266*f5c631daSSadaf Ebrahimi 267*f5c631daSSadaf Ebrahimi template <typename T> GetPointerTag(T pointer)268*f5c631daSSadaf Ebrahimi static uint64_t GetPointerTag(T pointer) { 269*f5c631daSSadaf Ebrahimi // Use C-style casts to get static_cast behaviour for integral types (T), 270*f5c631daSSadaf Ebrahimi // and reinterpret_cast behaviour for other types. 271*f5c631daSSadaf Ebrahimi 272*f5c631daSSadaf Ebrahimi uint64_t raw = (uint64_t)pointer; 273*f5c631daSSadaf Ebrahimi VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(raw)); 274*f5c631daSSadaf Ebrahimi 275*f5c631daSSadaf Ebrahimi return (raw & kAddressTagMask) >> kAddressTagOffset; 276*f5c631daSSadaf Ebrahimi } 277*f5c631daSSadaf Ebrahimi 278*f5c631daSSadaf Ebrahimi private: 279*f5c631daSSadaf Ebrahimi #define VIXL_AARCH64_ID_REG_LIST(V) \ 280*f5c631daSSadaf Ebrahimi V(AA64PFR0, "ID_AA64PFR0_EL1") \ 281*f5c631daSSadaf Ebrahimi V(AA64PFR1, "ID_AA64PFR1_EL1") \ 282*f5c631daSSadaf Ebrahimi V(AA64ISAR0, "ID_AA64ISAR0_EL1") \ 283*f5c631daSSadaf Ebrahimi V(AA64ISAR1, "ID_AA64ISAR1_EL1") \ 284*f5c631daSSadaf Ebrahimi V(AA64MMFR0, "ID_AA64MMFR0_EL1") \ 285*f5c631daSSadaf Ebrahimi V(AA64MMFR1, "ID_AA64MMFR1_EL1") \ 286*f5c631daSSadaf Ebrahimi /* These registers are RES0 in the baseline Arm8.0. We can always safely */ \ 287*f5c631daSSadaf Ebrahimi /* read them, but some compilers don't accept the symbolic names. */ \ 288*f5c631daSSadaf Ebrahimi V(AA64ISAR2, "S3_0_C0_C6_2") \ 289*f5c631daSSadaf Ebrahimi V(AA64MMFR2, "S3_0_C0_C7_2") \ 290*f5c631daSSadaf Ebrahimi V(AA64ZFR0, "S3_0_C0_C4_4") 291*f5c631daSSadaf Ebrahimi 292*f5c631daSSadaf Ebrahimi #define VIXL_READ_ID_REG(NAME, MRS_ARG) static NAME Read##NAME(); 293*f5c631daSSadaf Ebrahimi // On native AArch64 platforms, read the named CPU ID registers. These require 294*f5c631daSSadaf Ebrahimi // CPUFeatures::kIDRegisterEmulation, and should not be called on non-AArch64 295*f5c631daSSadaf Ebrahimi // platforms. 296*f5c631daSSadaf Ebrahimi VIXL_AARCH64_ID_REG_LIST(VIXL_READ_ID_REG) 297*f5c631daSSadaf Ebrahimi #undef VIXL_READ_ID_REG 298*f5c631daSSadaf Ebrahimi 299*f5c631daSSadaf Ebrahimi // Return the content of the cache type register. 300*f5c631daSSadaf Ebrahimi static uint32_t GetCacheType(); 301*f5c631daSSadaf Ebrahimi 302*f5c631daSSadaf Ebrahimi // I and D cache line size in bytes. 303*f5c631daSSadaf Ebrahimi static unsigned icache_line_size_; 304*f5c631daSSadaf Ebrahimi static unsigned dcache_line_size_; 305*f5c631daSSadaf Ebrahimi }; 306*f5c631daSSadaf Ebrahimi 307*f5c631daSSadaf Ebrahimi } // namespace aarch64 308*f5c631daSSadaf Ebrahimi } // namespace vixl 309*f5c631daSSadaf Ebrahimi 310*f5c631daSSadaf Ebrahimi #endif // VIXL_CPU_AARCH64_H 311