1b8021494Sopenharmony_ci// Copyright 2017, VIXL authors 2b8021494Sopenharmony_ci// All rights reserved. 3b8021494Sopenharmony_ci// 4b8021494Sopenharmony_ci// Redistribution and use in source and binary forms, with or without 5b8021494Sopenharmony_ci// modification, are permitted provided that the following conditions are met: 6b8021494Sopenharmony_ci// 7b8021494Sopenharmony_ci// * Redistributions of source code must retain the above copyright notice, 8b8021494Sopenharmony_ci// this list of conditions and the following disclaimer. 9b8021494Sopenharmony_ci// * Redistributions in binary form must reproduce the above copyright notice, 10b8021494Sopenharmony_ci// this list of conditions and the following disclaimer in the documentation 11b8021494Sopenharmony_ci// and/or other materials provided with the distribution. 12b8021494Sopenharmony_ci// * Neither the name of ARM Limited nor the names of its contributors may be 13b8021494Sopenharmony_ci// used to endorse or promote products derived from this software without 14b8021494Sopenharmony_ci// specific prior written permission. 15b8021494Sopenharmony_ci// 16b8021494Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17b8021494Sopenharmony_ci// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18b8021494Sopenharmony_ci// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19b8021494Sopenharmony_ci// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20b8021494Sopenharmony_ci// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21b8021494Sopenharmony_ci// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22b8021494Sopenharmony_ci// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23b8021494Sopenharmony_ci// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24b8021494Sopenharmony_ci// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25b8021494Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26b8021494Sopenharmony_ci 27b8021494Sopenharmony_ci#include <cstdio> 28b8021494Sopenharmony_ci#include <cstring> 29b8021494Sopenharmony_ci#include <string> 30b8021494Sopenharmony_ci 31b8021494Sopenharmony_ci#include "test-runner.h" 32b8021494Sopenharmony_ci#include "test-utils.h" 33b8021494Sopenharmony_ci 34b8021494Sopenharmony_ci#include "aarch64/macro-assembler-aarch64.h" 35b8021494Sopenharmony_ci#include "aarch64/registers-aarch64.h" 36b8021494Sopenharmony_ci#include "aarch64/simulator-aarch64.h" 37b8021494Sopenharmony_ci#include "aarch64/test-utils-aarch64.h" 38b8021494Sopenharmony_ci 39b8021494Sopenharmony_ci#define __ masm. 40b8021494Sopenharmony_ci#define TEST(name) TEST_(AARCH64_API_##name) 41b8021494Sopenharmony_ci 42b8021494Sopenharmony_ci 43b8021494Sopenharmony_cinamespace vixl { 44b8021494Sopenharmony_cinamespace aarch64 { 45b8021494Sopenharmony_ci 46b8021494Sopenharmony_ci// Check compiler intrinsics helpers. 47b8021494Sopenharmony_ci 48b8021494Sopenharmony_ciTEST(count_leading_sign_bits) { 49b8021494Sopenharmony_ci class Helper { 50b8021494Sopenharmony_ci public: 51b8021494Sopenharmony_ci static void Check(int64_t value, int non_sign_bits) { 52b8021494Sopenharmony_ci VIXL_ASSERT((0 <= non_sign_bits) && (non_sign_bits < 64)); 53b8021494Sopenharmony_ci 54b8021494Sopenharmony_ci for (int width = 1; width <= 64; width *= 2) { 55b8021494Sopenharmony_ci // Note that leading_sign_bits does not include the topmost bit. 56b8021494Sopenharmony_ci int leading_sign_bits = width - non_sign_bits - 1; 57b8021494Sopenharmony_ci if (leading_sign_bits < 0) continue; 58b8021494Sopenharmony_ci 59b8021494Sopenharmony_ci int64_t result = CountLeadingSignBits(value, width); 60b8021494Sopenharmony_ci int64_t fallback_result = CountLeadingSignBitsFallBack(value, width); 61b8021494Sopenharmony_ci VIXL_CHECK(result == leading_sign_bits); 62b8021494Sopenharmony_ci VIXL_CHECK(fallback_result == leading_sign_bits); 63b8021494Sopenharmony_ci } 64b8021494Sopenharmony_ci } 65b8021494Sopenharmony_ci }; 66b8021494Sopenharmony_ci 67b8021494Sopenharmony_ci // Basic positive (and zero) cases. Sign bits are all zeroes. 68b8021494Sopenharmony_ci Helper::Check(0, 0); // 0b++++ 69b8021494Sopenharmony_ci Helper::Check(1, 1); // 0b+++1 70b8021494Sopenharmony_ci Helper::Check(2, 2); // 0b++10 71b8021494Sopenharmony_ci Helper::Check(3, 2); // 0b++11 72b8021494Sopenharmony_ci Helper::Check(4, 3); // 0b+100 73b8021494Sopenharmony_ci 74b8021494Sopenharmony_ci // Basic negative cases. Sign bits are all ones. 75b8021494Sopenharmony_ci Helper::Check(-1, 0); // 0b---- 76b8021494Sopenharmony_ci Helper::Check(-2, 1); // 0b---0 77b8021494Sopenharmony_ci Helper::Check(-3, 2); // 0b--01 78b8021494Sopenharmony_ci Helper::Check(-4, 2); // 0b--00 79b8021494Sopenharmony_ci Helper::Check(-5, 3); // 0b-011 80b8021494Sopenharmony_ci 81b8021494Sopenharmony_ci // Boundary conditions. 82b8021494Sopenharmony_ci Helper::Check(INT8_MAX, 7); 83b8021494Sopenharmony_ci Helper::Check(INT8_MIN, 7); 84b8021494Sopenharmony_ci Helper::Check(static_cast<int64_t>(INT8_MAX) + 1, 8); 85b8021494Sopenharmony_ci Helper::Check(static_cast<int64_t>(INT8_MIN) - 1, 8); 86b8021494Sopenharmony_ci 87b8021494Sopenharmony_ci Helper::Check(INT16_MAX, 15); 88b8021494Sopenharmony_ci Helper::Check(INT16_MIN, 15); 89b8021494Sopenharmony_ci Helper::Check(static_cast<int64_t>(INT16_MAX) + 1, 16); 90b8021494Sopenharmony_ci Helper::Check(static_cast<int64_t>(INT16_MIN) - 1, 16); 91b8021494Sopenharmony_ci 92b8021494Sopenharmony_ci Helper::Check(INT32_MAX, 31); 93b8021494Sopenharmony_ci Helper::Check(INT32_MIN, 31); 94b8021494Sopenharmony_ci Helper::Check(static_cast<int64_t>(INT32_MAX) + 1, 32); 95b8021494Sopenharmony_ci Helper::Check(static_cast<int64_t>(INT32_MIN) - 1, 32); 96b8021494Sopenharmony_ci 97b8021494Sopenharmony_ci Helper::Check(INT64_MAX, 63); 98b8021494Sopenharmony_ci Helper::Check(INT64_MIN, 63); 99b8021494Sopenharmony_ci 100b8021494Sopenharmony_ci // Check automatic width detection. 101b8021494Sopenharmony_ci VIXL_CHECK(CountLeadingSignBits(static_cast<int8_t>(42)) == 1); // 0b00101010 102b8021494Sopenharmony_ci VIXL_CHECK(CountLeadingSignBits(static_cast<int16_t>(42)) == 9); 103b8021494Sopenharmony_ci VIXL_CHECK(CountLeadingSignBits(static_cast<int32_t>(42)) == 25); 104b8021494Sopenharmony_ci VIXL_CHECK(CountLeadingSignBits(static_cast<int64_t>(42)) == 57); 105b8021494Sopenharmony_ci} 106b8021494Sopenharmony_ci 107b8021494Sopenharmony_ci// Check SimFloat16 class mechanics. 108b8021494Sopenharmony_ciTEST(float16_operators) { 109b8021494Sopenharmony_ci ::vixl::internal::SimFloat16 f1 = kFP16DefaultNaN; 110b8021494Sopenharmony_ci ::vixl::internal::SimFloat16 f2 = kFP16DefaultNaN; 111b8021494Sopenharmony_ci ::vixl::internal::SimFloat16 f3 = kFP16PositiveInfinity; 112b8021494Sopenharmony_ci ::vixl::internal::SimFloat16 f4 = kFP16NegativeInfinity; 113b8021494Sopenharmony_ci VIXL_CHECK(!(f1 == f2)); 114b8021494Sopenharmony_ci VIXL_CHECK(f1 != f2); 115b8021494Sopenharmony_ci VIXL_CHECK(!(f3 == f4)); 116b8021494Sopenharmony_ci VIXL_CHECK(f3 != f4); 117b8021494Sopenharmony_ci VIXL_CHECK(::vixl::internal::SimFloat16(kFP16PositiveZero) == 118b8021494Sopenharmony_ci ::vixl::internal::SimFloat16(kFP16NegativeZero)); 119b8021494Sopenharmony_ci VIXL_CHECK(!(::vixl::internal::SimFloat16(kFP16PositiveZero) != 120b8021494Sopenharmony_ci ::vixl::internal::SimFloat16(kFP16NegativeZero))); 121b8021494Sopenharmony_ci} 122b8021494Sopenharmony_ci 123b8021494Sopenharmony_ciTEST(rawbits_conversions) { 124b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt64(0x0) == 0x0); 125b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt64(0x123) == 0x123); 126b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt64(INT64_MAX) == INT64_MAX); 127b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt64(UINT64_C(0xffffffffffffffff)) == -1); 128b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt64(UINT64_C(0x8000000000000000)) == INT64_MIN); 129b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt64(UINT64_C(0x8000000000000001)) == -INT64_MAX); 130b8021494Sopenharmony_ci 131b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt32(0x0) == 0x0); 132b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt32(0x123) == 0x123); 133b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt32(INT32_MAX) == INT32_MAX); 134b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt32(UINT32_C(0xffffffff)) == -1); 135b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt32(UINT32_C(0x80000000)) == INT32_MIN); 136b8021494Sopenharmony_ci VIXL_CHECK(RawbitsToInt32(UINT32_C(0x80000001)) == -INT32_MAX); 137b8021494Sopenharmony_ci} 138b8021494Sopenharmony_ci 139b8021494Sopenharmony_ci// Check moved FP constants are still accessible via the AArch64 namespace. 140b8021494Sopenharmony_ciTEST(float_constants_scope) { 141b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kFP64PositiveInfinity == 142b8021494Sopenharmony_ci vixl::kFP64PositiveInfinity); 143b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kFP64NegativeInfinity == 144b8021494Sopenharmony_ci vixl::kFP64NegativeInfinity); 145b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kFP32PositiveInfinity == 146b8021494Sopenharmony_ci vixl::kFP32PositiveInfinity); 147b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kFP32NegativeInfinity == 148b8021494Sopenharmony_ci vixl::kFP32NegativeInfinity); 149b8021494Sopenharmony_ci VIXL_CHECK(Float16ToRawbits(vixl::aarch64::kFP16PositiveInfinity) == 150b8021494Sopenharmony_ci Float16ToRawbits(vixl::aarch64::kFP16PositiveInfinity)); 151b8021494Sopenharmony_ci VIXL_CHECK(Float16ToRawbits(vixl::aarch64::kFP16NegativeInfinity) == 152b8021494Sopenharmony_ci Float16ToRawbits(vixl::aarch64::kFP16NegativeInfinity)); 153b8021494Sopenharmony_ci VIXL_CHECK(DoubleToRawbits(vixl::aarch64::kFP64DefaultNaN) == 154b8021494Sopenharmony_ci DoubleToRawbits(vixl::kFP64DefaultNaN)); 155b8021494Sopenharmony_ci VIXL_CHECK(FloatToRawbits(vixl::aarch64::kFP32DefaultNaN) == 156b8021494Sopenharmony_ci FloatToRawbits(vixl::kFP32DefaultNaN)); 157b8021494Sopenharmony_ci VIXL_CHECK(IsNaN(vixl::aarch64::kFP16DefaultNaN) == 158b8021494Sopenharmony_ci IsNaN(vixl::kFP16DefaultNaN)); 159b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kDoubleExponentBits == vixl::kDoubleExponentBits); 160b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kDoubleMantissaBits == vixl::kDoubleMantissaBits); 161b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kFloatExponentBits == vixl::kFloatExponentBits); 162b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kFloatMantissaBits == vixl::kFloatMantissaBits); 163b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kFloat16ExponentBits == vixl::kFloat16ExponentBits); 164b8021494Sopenharmony_ci VIXL_CHECK(vixl::aarch64::kFloat16MantissaBits == vixl::kFloat16MantissaBits); 165b8021494Sopenharmony_ci} 166b8021494Sopenharmony_ci 167b8021494Sopenharmony_ci 168b8021494Sopenharmony_ciTEST(register_bit) { 169b8021494Sopenharmony_ci VIXL_CHECK(x0.GetBit() == (UINT64_C(1) << 0)); 170b8021494Sopenharmony_ci VIXL_CHECK(x1.GetBit() == (UINT64_C(1) << 1)); 171b8021494Sopenharmony_ci VIXL_CHECK(x10.GetBit() == (UINT64_C(1) << 10)); 172b8021494Sopenharmony_ci 173b8021494Sopenharmony_ci // AAPCS64 definitions. 174b8021494Sopenharmony_ci VIXL_CHECK(lr.GetBit() == (UINT64_C(1) << kLinkRegCode)); 175b8021494Sopenharmony_ci 176b8021494Sopenharmony_ci // Fixed (hardware) definitions. 177b8021494Sopenharmony_ci VIXL_CHECK(xzr.GetBit() == (UINT64_C(1) << kZeroRegCode)); 178b8021494Sopenharmony_ci 179b8021494Sopenharmony_ci // Internal ABI definitions. 180b8021494Sopenharmony_ci VIXL_CHECK(sp.GetBit() == (UINT64_C(1) << kSPRegInternalCode)); 181b8021494Sopenharmony_ci VIXL_CHECK(sp.GetBit() != xzr.GetBit()); 182b8021494Sopenharmony_ci 183b8021494Sopenharmony_ci // xn.GetBit() == wn.GetBit() at all times, for the same n. 184b8021494Sopenharmony_ci VIXL_CHECK(x0.GetBit() == w0.GetBit()); 185b8021494Sopenharmony_ci VIXL_CHECK(x1.GetBit() == w1.GetBit()); 186b8021494Sopenharmony_ci VIXL_CHECK(x10.GetBit() == w10.GetBit()); 187b8021494Sopenharmony_ci VIXL_CHECK(xzr.GetBit() == wzr.GetBit()); 188b8021494Sopenharmony_ci VIXL_CHECK(sp.GetBit() == wsp.GetBit()); 189b8021494Sopenharmony_ci} 190b8021494Sopenharmony_ci 191b8021494Sopenharmony_ci 192b8021494Sopenharmony_ciTEST(noreg) { 193b8021494Sopenharmony_ci VIXL_CHECK(NoReg.Is(NoVReg)); 194b8021494Sopenharmony_ci VIXL_CHECK(NoVReg.Is(NoReg)); 195b8021494Sopenharmony_ci 196b8021494Sopenharmony_ci VIXL_CHECK(NoVReg.Is(NoReg)); 197b8021494Sopenharmony_ci VIXL_CHECK(NoReg.Is(NoVReg)); 198b8021494Sopenharmony_ci 199b8021494Sopenharmony_ci VIXL_CHECK(NoReg.Is(NoCPUReg)); 200b8021494Sopenharmony_ci VIXL_CHECK(NoCPUReg.Is(NoReg)); 201b8021494Sopenharmony_ci 202b8021494Sopenharmony_ci VIXL_CHECK(NoVReg.Is(NoCPUReg)); 203b8021494Sopenharmony_ci VIXL_CHECK(NoCPUReg.Is(NoVReg)); 204b8021494Sopenharmony_ci 205b8021494Sopenharmony_ci VIXL_CHECK(NoVReg.Is(NoCPUReg)); 206b8021494Sopenharmony_ci VIXL_CHECK(NoCPUReg.Is(NoVReg)); 207b8021494Sopenharmony_ci 208b8021494Sopenharmony_ci VIXL_CHECK(NoReg.IsNone()); 209b8021494Sopenharmony_ci VIXL_CHECK(NoVReg.IsNone()); 210b8021494Sopenharmony_ci VIXL_CHECK(NoCPUReg.IsNone()); 211b8021494Sopenharmony_ci} 212b8021494Sopenharmony_ci 213b8021494Sopenharmony_ci 214b8021494Sopenharmony_ciTEST(constructors) { 215b8021494Sopenharmony_ci // *Register(code) 216b8021494Sopenharmony_ci VIXL_CHECK(WRegister(0).Is(w0)); 217b8021494Sopenharmony_ci VIXL_CHECK(XRegister(1).Is(x1)); 218b8021494Sopenharmony_ci 219b8021494Sopenharmony_ci VIXL_CHECK(BRegister(2).Is(b2)); 220b8021494Sopenharmony_ci VIXL_CHECK(HRegister(3).Is(h3)); 221b8021494Sopenharmony_ci VIXL_CHECK(SRegister(4).Is(s4)); 222b8021494Sopenharmony_ci VIXL_CHECK(DRegister(5).Is(d5)); 223b8021494Sopenharmony_ci VIXL_CHECK(QRegister(6).Is(q6)); 224b8021494Sopenharmony_ci 225b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(7).Is(z7)); 226b8021494Sopenharmony_ci VIXL_CHECK(PRegister(8).Is(p8)); 227b8021494Sopenharmony_ci} 228b8021494Sopenharmony_ci 229b8021494Sopenharmony_ci 230b8021494Sopenharmony_ciTEST(constructors_r) { 231b8021494Sopenharmony_ci // Register(code, size_in_bits) 232b8021494Sopenharmony_ci VIXL_CHECK(Register(0, kWRegSize).Is(w0)); 233b8021494Sopenharmony_ci VIXL_CHECK(Register(1, kXRegSize).Is(x1)); 234b8021494Sopenharmony_ci} 235b8021494Sopenharmony_ci 236b8021494Sopenharmony_ci 237b8021494Sopenharmony_ciTEST(constructors_v) { 238b8021494Sopenharmony_ci // VRegister(code) 239b8021494Sopenharmony_ci VIXL_CHECK(VRegister(0).Is(v0)); 240b8021494Sopenharmony_ci VIXL_CHECK(VRegister(1).Is(v1)); 241b8021494Sopenharmony_ci VIXL_CHECK(VRegister(2).Is(v2)); 242b8021494Sopenharmony_ci VIXL_CHECK(VRegister(3).Is(v3)); 243b8021494Sopenharmony_ci VIXL_CHECK(VRegister(4).Is(v4)); 244b8021494Sopenharmony_ci 245b8021494Sopenharmony_ci // VRegister(code, size_in_bits) 246b8021494Sopenharmony_ci VIXL_CHECK(VRegister(0, kBRegSize).Is(b0)); 247b8021494Sopenharmony_ci VIXL_CHECK(VRegister(1, kHRegSize).Is(h1)); 248b8021494Sopenharmony_ci VIXL_CHECK(VRegister(2, kSRegSize).Is(s2)); 249b8021494Sopenharmony_ci VIXL_CHECK(VRegister(3, kDRegSize).Is(d3)); 250b8021494Sopenharmony_ci VIXL_CHECK(VRegister(4, kQRegSize).Is(q4)); 251b8021494Sopenharmony_ci 252b8021494Sopenharmony_ci // VRegister(code, size_in_bits, lanes) 253b8021494Sopenharmony_ci VIXL_CHECK(VRegister(0, kBRegSize, 1).Is(b0)); 254b8021494Sopenharmony_ci VIXL_CHECK(VRegister(1, kHRegSize, 1).Is(h1)); 255b8021494Sopenharmony_ci VIXL_CHECK(VRegister(2, kSRegSize, 1).Is(s2)); 256b8021494Sopenharmony_ci VIXL_CHECK(VRegister(3, kDRegSize, 1).Is(d3)); 257b8021494Sopenharmony_ci VIXL_CHECK(VRegister(4, kQRegSize, 1).Is(q4)); 258b8021494Sopenharmony_ci 259b8021494Sopenharmony_ci VIXL_CHECK(VRegister(0, kSRegSize, 2).Is(v0.V2H())); 260b8021494Sopenharmony_ci 261b8021494Sopenharmony_ci VIXL_CHECK(VRegister(1, kDRegSize, 1).Is(v1.V1D())); 262b8021494Sopenharmony_ci VIXL_CHECK(VRegister(2, kDRegSize, 2).Is(v2.V2S())); 263b8021494Sopenharmony_ci VIXL_CHECK(VRegister(3, kDRegSize, 4).Is(v3.V4H())); 264b8021494Sopenharmony_ci VIXL_CHECK(VRegister(4, kDRegSize, 8).Is(v4.V8B())); 265b8021494Sopenharmony_ci 266b8021494Sopenharmony_ci VIXL_CHECK(VRegister(5, kQRegSize, 2).Is(v5.V2D())); 267b8021494Sopenharmony_ci VIXL_CHECK(VRegister(6, kQRegSize, 4).Is(v6.V4S())); 268b8021494Sopenharmony_ci VIXL_CHECK(VRegister(7, kQRegSize, 8).Is(v7.V8H())); 269b8021494Sopenharmony_ci VIXL_CHECK(VRegister(8, kQRegSize, 16).Is(v8.V16B())); 270b8021494Sopenharmony_ci 271b8021494Sopenharmony_ci // VRegister(code, format) 272b8021494Sopenharmony_ci VIXL_CHECK(VRegister(0, kFormatB).Is(b0)); 273b8021494Sopenharmony_ci VIXL_CHECK(VRegister(1, kFormatH).Is(h1)); 274b8021494Sopenharmony_ci VIXL_CHECK(VRegister(2, kFormatS).Is(s2)); 275b8021494Sopenharmony_ci VIXL_CHECK(VRegister(3, kFormatD).Is(d3)); 276b8021494Sopenharmony_ci VIXL_CHECK(VRegister(4, kFormat8B).Is(v4.V8B())); 277b8021494Sopenharmony_ci VIXL_CHECK(VRegister(5, kFormat16B).Is(v5.V16B())); 278b8021494Sopenharmony_ci VIXL_CHECK(VRegister(6, kFormat2H).Is(v6.V2H())); 279b8021494Sopenharmony_ci VIXL_CHECK(VRegister(7, kFormat4H).Is(v7.V4H())); 280b8021494Sopenharmony_ci VIXL_CHECK(VRegister(8, kFormat8H).Is(v8.V8H())); 281b8021494Sopenharmony_ci VIXL_CHECK(VRegister(9, kFormat2S).Is(v9.V2S())); 282b8021494Sopenharmony_ci VIXL_CHECK(VRegister(10, kFormat4S).Is(v10.V4S())); 283b8021494Sopenharmony_ci VIXL_CHECK(VRegister(11, kFormat1D).Is(v11.V1D())); 284b8021494Sopenharmony_ci VIXL_CHECK(VRegister(12, kFormat2D).Is(v12.V2D())); 285b8021494Sopenharmony_ci} 286b8021494Sopenharmony_ci 287b8021494Sopenharmony_ci 288b8021494Sopenharmony_ciTEST(constructors_z) { 289b8021494Sopenharmony_ci // ZRegister(code, lane_size_in_bits) 290b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(0, kBRegSize).Is(z0.VnB())); 291b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(1, kHRegSize).Is(z1.VnH())); 292b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(2, kSRegSize).Is(z2.VnS())); 293b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(3, kDRegSize).Is(z3.VnD())); 294b8021494Sopenharmony_ci 295b8021494Sopenharmony_ci // ZRegister(code, format) 296b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(0, kFormatVnB).Is(z0.VnB())); 297b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(1, kFormatVnH).Is(z1.VnH())); 298b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(2, kFormatVnS).Is(z2.VnS())); 299b8021494Sopenharmony_ci VIXL_CHECK(ZRegister(3, kFormatVnD).Is(z3.VnD())); 300b8021494Sopenharmony_ci} 301b8021494Sopenharmony_ci 302b8021494Sopenharmony_ci 303b8021494Sopenharmony_ciTEST(constructors_p) { 304b8021494Sopenharmony_ci // ZRegister(code, lane_size_in_bits) 305b8021494Sopenharmony_ci VIXL_CHECK(PRegisterWithLaneSize(0, kBRegSize).Is(p0.VnB())); 306b8021494Sopenharmony_ci VIXL_CHECK(PRegisterWithLaneSize(1, kHRegSize).Is(p1.VnH())); 307b8021494Sopenharmony_ci VIXL_CHECK(PRegisterWithLaneSize(2, kSRegSize).Is(p2.VnS())); 308b8021494Sopenharmony_ci VIXL_CHECK(PRegisterWithLaneSize(3, kDRegSize).Is(p3.VnD())); 309b8021494Sopenharmony_ci 310b8021494Sopenharmony_ci // ZRegister(code, format) 311b8021494Sopenharmony_ci VIXL_CHECK(PRegisterWithLaneSize(0, kFormatVnB).Is(p0.VnB())); 312b8021494Sopenharmony_ci VIXL_CHECK(PRegisterWithLaneSize(1, kFormatVnH).Is(p1.VnH())); 313b8021494Sopenharmony_ci VIXL_CHECK(PRegisterWithLaneSize(2, kFormatVnS).Is(p2.VnS())); 314b8021494Sopenharmony_ci VIXL_CHECK(PRegisterWithLaneSize(3, kFormatVnD).Is(p3.VnD())); 315b8021494Sopenharmony_ci 316b8021494Sopenharmony_ci VIXL_CHECK(PRegisterZ(0).Is(p0.Zeroing())); 317b8021494Sopenharmony_ci VIXL_CHECK(PRegisterM(1).Is(p1.Merging())); 318b8021494Sopenharmony_ci} 319b8021494Sopenharmony_ci 320b8021494Sopenharmony_ci 321b8021494Sopenharmony_ciTEST(constructors_cpu) { 322b8021494Sopenharmony_ci // ZRegister(code, size_in_bits, type) 323b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(0, kWRegSize, CPURegister::kRegister).Is(w0)); 324b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(1, kXRegSize, CPURegister::kRegister).Is(x1)); 325b8021494Sopenharmony_ci 326b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(2, kBRegSize, CPURegister::kVRegister).Is(b2)); 327b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(3, kHRegSize, CPURegister::kVRegister).Is(h3)); 328b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(4, kSRegSize, CPURegister::kVRegister).Is(s4)); 329b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(5, kDRegSize, CPURegister::kVRegister).Is(d5)); 330b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(6, kQRegSize, CPURegister::kVRegister).Is(q6)); 331b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(7, kQRegSize, CPURegister::kVRegister).Is(v7)); 332b8021494Sopenharmony_ci 333b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(0, CPURegister::kUnknownSize, CPURegister::kVRegister) 334b8021494Sopenharmony_ci .Is(z0)); 335b8021494Sopenharmony_ci VIXL_CHECK(CPURegister(1, CPURegister::kUnknownSize, CPURegister::kPRegister) 336b8021494Sopenharmony_ci .Is(p1)); 337b8021494Sopenharmony_ci} 338b8021494Sopenharmony_ci 339b8021494Sopenharmony_ci 340b8021494Sopenharmony_ci#ifdef __aarch64__ 341b8021494Sopenharmony_cistatic void CPURegisterByValueHelper(CPURegister reg) { 342b8021494Sopenharmony_ci // Test that `reg` can be passed in one register. We'd like to use 343b8021494Sopenharmony_ci // __attribute__((naked)) for this, but it isn't supported for AArch64, so 344b8021494Sopenharmony_ci // generate a function using VIXL instead. 345b8021494Sopenharmony_ci 346b8021494Sopenharmony_ci MacroAssembler masm; 347b8021494Sopenharmony_ci // CPURegister fn(int placeholder, CPURegister reg); 348b8021494Sopenharmony_ci // Move `reg` to its result register. 349b8021494Sopenharmony_ci __ Mov(x0, x1); 350b8021494Sopenharmony_ci // Clobber all other result registers. 351b8021494Sopenharmony_ci __ Mov(x1, 0xfffffffffffffff1); 352b8021494Sopenharmony_ci __ Mov(x2, 0xfffffffffffffff2); 353b8021494Sopenharmony_ci __ Mov(x3, 0xfffffffffffffff3); 354b8021494Sopenharmony_ci __ Mov(x4, 0xfffffffffffffff4); 355b8021494Sopenharmony_ci __ Mov(x5, 0xfffffffffffffff5); 356b8021494Sopenharmony_ci __ Mov(x6, 0xfffffffffffffff6); 357b8021494Sopenharmony_ci __ Mov(x7, 0xfffffffffffffff7); 358b8021494Sopenharmony_ci __ Ret(); 359b8021494Sopenharmony_ci masm.FinalizeCode(); 360b8021494Sopenharmony_ci 361b8021494Sopenharmony_ci CodeBuffer* buffer = masm.GetBuffer(); 362b8021494Sopenharmony_ci auto fn = buffer->GetStartAddress<CPURegister (*)(int, CPURegister)>(); 363b8021494Sopenharmony_ci buffer->SetExecutable(); 364b8021494Sopenharmony_ci CPURegister out = fn(42, reg); 365b8021494Sopenharmony_ci 366b8021494Sopenharmony_ci VIXL_CHECK(out.Is(reg)); 367b8021494Sopenharmony_ci} 368b8021494Sopenharmony_ci 369b8021494Sopenharmony_ci 370b8021494Sopenharmony_ciTEST(cpureg_by_value) { 371b8021494Sopenharmony_ci VIXL_STATIC_ASSERT(sizeof(CPURegister) <= sizeof(void*)); 372b8021494Sopenharmony_ci // Check some arbitrary registers to try to exercise each encoding field. 373b8021494Sopenharmony_ci CPURegisterByValueHelper(x0); 374b8021494Sopenharmony_ci CPURegisterByValueHelper(v31.V8H()); 375b8021494Sopenharmony_ci CPURegisterByValueHelper(z16.VnD()); 376b8021494Sopenharmony_ci CPURegisterByValueHelper(p15.Merging()); 377b8021494Sopenharmony_ci} 378b8021494Sopenharmony_ci#endif // __aarch64__ 379b8021494Sopenharmony_ci 380b8021494Sopenharmony_ci 381b8021494Sopenharmony_ciTEST(isvalid) { 382b8021494Sopenharmony_ci VIXL_CHECK(!NoReg.IsValid()); 383b8021494Sopenharmony_ci VIXL_CHECK(!NoVReg.IsValid()); 384b8021494Sopenharmony_ci VIXL_CHECK(!NoCPUReg.IsValid()); 385b8021494Sopenharmony_ci 386b8021494Sopenharmony_ci VIXL_CHECK(x0.IsValid()); 387b8021494Sopenharmony_ci VIXL_CHECK(w0.IsValid()); 388b8021494Sopenharmony_ci VIXL_CHECK(x30.IsValid()); 389b8021494Sopenharmony_ci VIXL_CHECK(w30.IsValid()); 390b8021494Sopenharmony_ci VIXL_CHECK(xzr.IsValid()); 391b8021494Sopenharmony_ci VIXL_CHECK(wzr.IsValid()); 392b8021494Sopenharmony_ci 393b8021494Sopenharmony_ci VIXL_CHECK(sp.IsValid()); 394b8021494Sopenharmony_ci VIXL_CHECK(wsp.IsValid()); 395b8021494Sopenharmony_ci 396b8021494Sopenharmony_ci VIXL_CHECK(d0.IsValid()); 397b8021494Sopenharmony_ci VIXL_CHECK(s0.IsValid()); 398b8021494Sopenharmony_ci VIXL_CHECK(d31.IsValid()); 399b8021494Sopenharmony_ci VIXL_CHECK(s31.IsValid()); 400b8021494Sopenharmony_ci 401b8021494Sopenharmony_ci VIXL_CHECK(x0.IsValidRegister()); 402b8021494Sopenharmony_ci VIXL_CHECK(w0.IsValidRegister()); 403b8021494Sopenharmony_ci VIXL_CHECK(xzr.IsValidRegister()); 404b8021494Sopenharmony_ci VIXL_CHECK(wzr.IsValidRegister()); 405b8021494Sopenharmony_ci VIXL_CHECK(sp.IsValidRegister()); 406b8021494Sopenharmony_ci VIXL_CHECK(wsp.IsValidRegister()); 407b8021494Sopenharmony_ci VIXL_CHECK(!x0.IsValidVRegister()); 408b8021494Sopenharmony_ci VIXL_CHECK(!w0.IsValidVRegister()); 409b8021494Sopenharmony_ci VIXL_CHECK(!xzr.IsValidVRegister()); 410b8021494Sopenharmony_ci VIXL_CHECK(!wzr.IsValidVRegister()); 411b8021494Sopenharmony_ci VIXL_CHECK(!sp.IsValidVRegister()); 412b8021494Sopenharmony_ci VIXL_CHECK(!wsp.IsValidVRegister()); 413b8021494Sopenharmony_ci VIXL_CHECK(!x0.IsValidFPRegister()); 414b8021494Sopenharmony_ci VIXL_CHECK(!w0.IsValidFPRegister()); 415b8021494Sopenharmony_ci VIXL_CHECK(!xzr.IsValidFPRegister()); 416b8021494Sopenharmony_ci VIXL_CHECK(!wzr.IsValidFPRegister()); 417b8021494Sopenharmony_ci VIXL_CHECK(!sp.IsValidFPRegister()); 418b8021494Sopenharmony_ci VIXL_CHECK(!wsp.IsValidFPRegister()); 419b8021494Sopenharmony_ci 420b8021494Sopenharmony_ci VIXL_CHECK(q0.IsValidVRegister()); 421b8021494Sopenharmony_ci VIXL_CHECK(!q0.IsValidFPRegister()); 422b8021494Sopenharmony_ci VIXL_CHECK(!q0.IsValidRegister()); 423b8021494Sopenharmony_ci 424b8021494Sopenharmony_ci VIXL_CHECK(d0.IsValidVRegister()); 425b8021494Sopenharmony_ci VIXL_CHECK(d0.IsValidFPRegister()); 426b8021494Sopenharmony_ci VIXL_CHECK(!d0.IsValidRegister()); 427b8021494Sopenharmony_ci 428b8021494Sopenharmony_ci VIXL_CHECK(s0.IsValidVRegister()); 429b8021494Sopenharmony_ci VIXL_CHECK(s0.IsValidFPRegister()); 430b8021494Sopenharmony_ci VIXL_CHECK(!s0.IsValidRegister()); 431b8021494Sopenharmony_ci 432b8021494Sopenharmony_ci VIXL_CHECK(h0.IsValidVRegister()); 433b8021494Sopenharmony_ci VIXL_CHECK(h0.IsValidFPRegister()); 434b8021494Sopenharmony_ci VIXL_CHECK(!h0.IsValidRegister()); 435b8021494Sopenharmony_ci 436b8021494Sopenharmony_ci VIXL_CHECK(b0.IsValidVRegister()); 437b8021494Sopenharmony_ci VIXL_CHECK(!b0.IsValidFPRegister()); 438b8021494Sopenharmony_ci VIXL_CHECK(!b0.IsValidRegister()); 439b8021494Sopenharmony_ci 440b8021494Sopenharmony_ci // IsValidFPRegister() is only true for scalar types. 441b8021494Sopenharmony_ci VIXL_CHECK(q0.V2D().IsValidVRegister()); 442b8021494Sopenharmony_ci VIXL_CHECK(!q0.V2D().IsValidFPRegister()); 443b8021494Sopenharmony_ci VIXL_CHECK(d0.V2S().IsValidVRegister()); 444b8021494Sopenharmony_ci VIXL_CHECK(!d0.V2S().IsValidFPRegister()); 445b8021494Sopenharmony_ci VIXL_CHECK(s0.V2H().IsValidVRegister()); 446b8021494Sopenharmony_ci VIXL_CHECK(!s0.V2H().IsValidFPRegister()); 447b8021494Sopenharmony_ci} 448b8021494Sopenharmony_ci 449b8021494Sopenharmony_ci 450b8021494Sopenharmony_ciTEST(isvalid_cpu) { 451b8021494Sopenharmony_ci // As 'isvalid', but using CPURegister types where possible. This shouldn't 452b8021494Sopenharmony_ci // make any difference. 453b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(NoReg).IsValid()); 454b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(NoVReg).IsValid()); 455b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(NoCPUReg).IsValid()); 456b8021494Sopenharmony_ci 457b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(x0).IsValid()); 458b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(w0).IsValid()); 459b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(x30).IsValid()); 460b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(w30).IsValid()); 461b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(xzr).IsValid()); 462b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(wzr).IsValid()); 463b8021494Sopenharmony_ci 464b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(sp).IsValid()); 465b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(wsp).IsValid()); 466b8021494Sopenharmony_ci 467b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(d0).IsValid()); 468b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(s0).IsValid()); 469b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(d31).IsValid()); 470b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(s31).IsValid()); 471b8021494Sopenharmony_ci 472b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(x0).IsValidRegister()); 473b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(w0).IsValidRegister()); 474b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(xzr).IsValidRegister()); 475b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(wzr).IsValidRegister()); 476b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(sp).IsValidRegister()); 477b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(wsp).IsValidRegister()); 478b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidVRegister()); 479b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidVRegister()); 480b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidVRegister()); 481b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidVRegister()); 482b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidVRegister()); 483b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidVRegister()); 484b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister()); 485b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister()); 486b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister()); 487b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister()); 488b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister()); 489b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister()); 490b8021494Sopenharmony_ci 491b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(q0).IsValidVRegister()); 492b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(q0).IsValidFPRegister()); 493b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(q0).IsValidRegister()); 494b8021494Sopenharmony_ci 495b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(d0).IsValidVRegister()); 496b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(d0).IsValidFPRegister()); 497b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(d0).IsValidRegister()); 498b8021494Sopenharmony_ci 499b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(s0).IsValidVRegister()); 500b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(s0).IsValidFPRegister()); 501b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(s0).IsValidRegister()); 502b8021494Sopenharmony_ci 503b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(h0).IsValidVRegister()); 504b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(h0).IsValidFPRegister()); 505b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(h0).IsValidRegister()); 506b8021494Sopenharmony_ci 507b8021494Sopenharmony_ci VIXL_CHECK(static_cast<CPURegister>(b0).IsValidVRegister()); 508b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(b0).IsValidFPRegister()); 509b8021494Sopenharmony_ci VIXL_CHECK(!static_cast<CPURegister>(b0).IsValidRegister()); 510b8021494Sopenharmony_ci} 511b8021494Sopenharmony_ci 512b8021494Sopenharmony_ci 513b8021494Sopenharmony_ciTEST(are_consecutive) { 514b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(b0, NoVReg)); 515b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(b1, b2)); 516b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(b3, b4, b5)); 517b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(b6, b7, b8, b9)); 518b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(h10, NoVReg)); 519b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(h11, h12)); 520b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(h13, h14, h15)); 521b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(h16, h17, h18, h19)); 522b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(s20, NoVReg)); 523b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(s21, s22)); 524b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(s23, s24, s25)); 525b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(s26, s27, s28, s29)); 526b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(d30, NoVReg)); 527b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(d31, d0)); 528b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(d1, d2, d3)); 529b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(d4, d5, d6, d7)); 530b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(q8, NoVReg)); 531b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(q9, q10)); 532b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(q11, q12, q13)); 533b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(q14, q15, q16, q17)); 534b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(v18, NoVReg)); 535b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(v19, v20)); 536b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(v21, v22, v23)); 537b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(v24, v25, v26, v27)); 538b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(b29, h30)); 539b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(s31, d0, q1)); 540b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(v2, b3, h4, s5)); 541b8021494Sopenharmony_ci 542b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(b0, b2)); 543b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(h1, h0)); 544b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(s31, s1)); 545b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(d12, d12)); 546b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(q31, q1)); 547b8021494Sopenharmony_ci 548b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(b0, b1, b3)); 549b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(h4, h5, h6, h6)); 550b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(d11, d13, NoVReg, d14)); 551b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(d15, d16, d18, NoVReg)); 552b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(b26, b28, NoVReg, b29)); 553b8021494Sopenharmony_ci VIXL_CHECK(!AreConsecutive(s28, s30, NoVReg, NoVReg)); 554b8021494Sopenharmony_ci 555b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(q19, NoVReg, NoVReg, q22)); 556b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(v23, NoVReg, v25, NoVReg)); 557b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(b26, b27, NoVReg, NoVReg)); 558b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(h28, NoVReg, NoVReg, NoVReg)); 559b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(s30, s31, NoVReg, s2)); 560b8021494Sopenharmony_ci VIXL_CHECK(AreConsecutive(d3, NoVReg, d6, d7)); 561b8021494Sopenharmony_ci} 562b8021494Sopenharmony_ci 563b8021494Sopenharmony_ci 564b8021494Sopenharmony_ciTEST(sve_p_registers) { 565b8021494Sopenharmony_ci enum Qualification { kNone, kZeroing, kMerging, kWithLaneSize }; 566b8021494Sopenharmony_ci class Helper { 567b8021494Sopenharmony_ci public: 568b8021494Sopenharmony_ci static Qualification GetQualification(PRegister) { return kNone; } 569b8021494Sopenharmony_ci static Qualification GetQualification(PRegisterZ) { return kZeroing; } 570b8021494Sopenharmony_ci static Qualification GetQualification(PRegisterM) { return kMerging; } 571b8021494Sopenharmony_ci static Qualification GetQualification(PRegisterWithLaneSize) { 572b8021494Sopenharmony_ci return kWithLaneSize; 573b8021494Sopenharmony_ci } 574b8021494Sopenharmony_ci }; 575b8021494Sopenharmony_ci 576b8021494Sopenharmony_ci VIXL_CHECK(kNumberOfPRegisters == 16); 577b8021494Sopenharmony_ci VIXL_CHECK(p0.GetCode() == 0); 578b8021494Sopenharmony_ci VIXL_CHECK(p15.GetCode() == 15); 579b8021494Sopenharmony_ci VIXL_CHECK(p14.VnB().GetLaneSizeInBits() == kBRegSize); 580b8021494Sopenharmony_ci VIXL_CHECK(p14.VnH().GetLaneSizeInBits() == kHRegSize); 581b8021494Sopenharmony_ci VIXL_CHECK(p14.VnS().GetLaneSizeInBits() == kSRegSize); 582b8021494Sopenharmony_ci VIXL_CHECK(p14.VnD().GetLaneSizeInBits() == kDRegSize); 583b8021494Sopenharmony_ci VIXL_CHECK(p14.VnB().GetLaneSizeInBytes() == kBRegSizeInBytes); 584b8021494Sopenharmony_ci VIXL_CHECK(p14.VnH().GetLaneSizeInBytes() == kHRegSizeInBytes); 585b8021494Sopenharmony_ci VIXL_CHECK(p14.VnS().GetLaneSizeInBytes() == kSRegSizeInBytes); 586b8021494Sopenharmony_ci VIXL_CHECK(p14.VnD().GetLaneSizeInBytes() == kDRegSizeInBytes); 587b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetQualification(p1) == kNone); 588b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetQualification(p2.Zeroing()) == kZeroing); 589b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetQualification(p3.Merging()) == kMerging); 590b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetQualification(p4.VnB()) == kWithLaneSize); 591b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetQualification(p5.VnH()) == kWithLaneSize); 592b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetQualification(p6.VnS()) == kWithLaneSize); 593b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetQualification(p7.VnD()) == kWithLaneSize); 594b8021494Sopenharmony_ci} 595b8021494Sopenharmony_ci 596b8021494Sopenharmony_ci 597b8021494Sopenharmony_ciTEST(sve_z_registers) { 598b8021494Sopenharmony_ci VIXL_CHECK(z0.GetCode() == 0); 599b8021494Sopenharmony_ci VIXL_CHECK(z31.GetCode() == 31); 600b8021494Sopenharmony_ci 601b8021494Sopenharmony_ci VIXL_CHECK(z0.Is(z0)); 602b8021494Sopenharmony_ci VIXL_CHECK(!z0.Is(z1)); 603b8021494Sopenharmony_ci VIXL_CHECK(!z0.Is(v0)); 604b8021494Sopenharmony_ci VIXL_CHECK(!z0.Is(b0)); 605b8021494Sopenharmony_ci VIXL_CHECK(!z0.Is(q0)); 606b8021494Sopenharmony_ci 607b8021494Sopenharmony_ci VIXL_CHECK(AreAliased(z5, z5)); 608b8021494Sopenharmony_ci VIXL_CHECK(AreAliased(z5, b5)); 609b8021494Sopenharmony_ci VIXL_CHECK(AreAliased(b5, z5)); 610b8021494Sopenharmony_ci VIXL_CHECK(AreAliased(z5, z5.B())); 611b8021494Sopenharmony_ci VIXL_CHECK(AreAliased(z5, z5.VnB())); 612b8021494Sopenharmony_ci 613b8021494Sopenharmony_ci VIXL_CHECK(!AreAliased(z6, z7)); 614b8021494Sopenharmony_ci VIXL_CHECK(!AreAliased(b6, z7)); 615b8021494Sopenharmony_ci VIXL_CHECK(!AreAliased(x7, z7)); 616b8021494Sopenharmony_ci} 617b8021494Sopenharmony_ci 618b8021494Sopenharmony_ci 619b8021494Sopenharmony_ciTEST(sve_z_registers_vs_neon) { 620b8021494Sopenharmony_ci // There are three related register variants to consider in VIXL's API: 621b8021494Sopenharmony_ci // 622b8021494Sopenharmony_ci // "b0": NEON: The least-significant byte of v0. 623b8021494Sopenharmony_ci // "v0.B": NEON: v0, with an unspecified number of byte-sized lanes. 624b8021494Sopenharmony_ci // "z0.B": SVE: z0, with an unspecified number of byte-sized lanes. 625b8021494Sopenharmony_ci // 626b8021494Sopenharmony_ci // The first two cases are indistinguishable in VIXL; both are obtained using 627b8021494Sopenharmony_ci // something like `v0.B()`. This is fine for NEON because there is no 628b8021494Sopenharmony_ci // ambiguity in practice; the "v0.B" form is always used with an index that 629b8021494Sopenharmony_ci // makes the meaning clear. 630b8021494Sopenharmony_ci 631b8021494Sopenharmony_ci VIXL_ASSERT(v6.B().Is(b6)); 632b8021494Sopenharmony_ci VIXL_ASSERT(v7.H().Is(h7)); 633b8021494Sopenharmony_ci VIXL_ASSERT(v8.S().Is(s8)); 634b8021494Sopenharmony_ci VIXL_ASSERT(v9.D().Is(d9)); 635b8021494Sopenharmony_ci 636b8021494Sopenharmony_ci VIXL_ASSERT(z6.B().Is(b6)); 637b8021494Sopenharmony_ci VIXL_ASSERT(z7.H().Is(h7)); 638b8021494Sopenharmony_ci VIXL_ASSERT(z8.S().Is(s8)); 639b8021494Sopenharmony_ci VIXL_ASSERT(z9.D().Is(d9)); 640b8021494Sopenharmony_ci 641b8021494Sopenharmony_ci // We cannot use the same approach for SVE's "z0.B" because, for example, 642b8021494Sopenharmony_ci // `Add(VRegister, ...)` and `Add(ZRegister, ...)` generate different 643b8021494Sopenharmony_ci // instructions. 644b8021494Sopenharmony_ci 645b8021494Sopenharmony_ci // Test that the variants can be distinguished with `Is`. 646b8021494Sopenharmony_ci VIXL_CHECK(!z6.VnB().Is(b6)); 647b8021494Sopenharmony_ci VIXL_CHECK(!z7.VnH().Is(h7)); 648b8021494Sopenharmony_ci VIXL_CHECK(!z8.VnS().Is(s8)); 649b8021494Sopenharmony_ci VIXL_CHECK(!z9.VnD().Is(d9)); 650b8021494Sopenharmony_ci 651b8021494Sopenharmony_ci VIXL_CHECK(!z6.VnB().Is(v6.B())); 652b8021494Sopenharmony_ci VIXL_CHECK(!z7.VnH().Is(v7.H())); 653b8021494Sopenharmony_ci VIXL_CHECK(!z8.VnS().Is(v8.S())); 654b8021494Sopenharmony_ci VIXL_CHECK(!z9.VnD().Is(v9.D())); 655b8021494Sopenharmony_ci 656b8021494Sopenharmony_ci VIXL_CHECK(!z6.VnB().Is(z6.B())); 657b8021494Sopenharmony_ci VIXL_CHECK(!z7.VnH().Is(z7.H())); 658b8021494Sopenharmony_ci VIXL_CHECK(!z8.VnS().Is(z8.S())); 659b8021494Sopenharmony_ci VIXL_CHECK(!z9.VnD().Is(z9.D())); 660b8021494Sopenharmony_ci 661b8021494Sopenharmony_ci // Test that the variants can be distinguished at compile-time using 662b8021494Sopenharmony_ci // overloading. VIXL's API relies on this. 663b8021494Sopenharmony_ci enum Variant { kNEON, kSVE, kUnknown }; 664b8021494Sopenharmony_ci class Helper { 665b8021494Sopenharmony_ci public: 666b8021494Sopenharmony_ci static Variant GetVariant(ZRegister) { return kSVE; } 667b8021494Sopenharmony_ci static Variant GetVariant(VRegister) { return kNEON; } 668b8021494Sopenharmony_ci static Variant GetVariant(CPURegister) { return kUnknown; } 669b8021494Sopenharmony_ci }; 670b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(z10.VnB()) == kSVE); 671b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(z11.VnH()) == kSVE); 672b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(z12.VnS()) == kSVE); 673b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(z13.VnD()) == kSVE); 674b8021494Sopenharmony_ci 675b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(v10.B()) == kNEON); 676b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(v11.H()) == kNEON); 677b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(v12.S()) == kNEON); 678b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(v13.D()) == kNEON); 679b8021494Sopenharmony_ci 680b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(v10.V16B()) == kNEON); 681b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(v11.V8H()) == kNEON); 682b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(v12.V4S()) == kNEON); 683b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(v13.V2D()) == kNEON); 684b8021494Sopenharmony_ci 685b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(b10) == kNEON); 686b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(h11) == kNEON); 687b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(s12) == kNEON); 688b8021494Sopenharmony_ci VIXL_CHECK(Helper::GetVariant(d13) == kNEON); 689b8021494Sopenharmony_ci} 690b8021494Sopenharmony_ci 691b8021494Sopenharmony_ci 692b8021494Sopenharmony_ciTEST(move_immediate_helpers) { 693b8021494Sopenharmony_ci // Using these helpers to query information (without generating code) should 694b8021494Sopenharmony_ci // not crash. 695b8021494Sopenharmony_ci MacroAssembler::MoveImmediateHelper(NULL, x0, 0x12345678); 696b8021494Sopenharmony_ci MacroAssembler::OneInstrMoveImmediateHelper(NULL, x1, 0xabcdef); 697b8021494Sopenharmony_ci} 698b8021494Sopenharmony_ci 699b8021494Sopenharmony_ci 700b8021494Sopenharmony_ciTEST(generic_operand_helpers) { 701b8021494Sopenharmony_ci GenericOperand invalid_1; 702b8021494Sopenharmony_ci GenericOperand invalid_2; 703b8021494Sopenharmony_ci GenericOperand reg(x3); 704b8021494Sopenharmony_ci GenericOperand mem(MemOperand(sp, 8), kXRegSizeInBytes); 705b8021494Sopenharmony_ci 706b8021494Sopenharmony_ci VIXL_CHECK(!invalid_1.IsValid()); 707b8021494Sopenharmony_ci VIXL_CHECK(!invalid_2.IsValid()); 708b8021494Sopenharmony_ci 709b8021494Sopenharmony_ci VIXL_CHECK(invalid_1.Equals(invalid_1)); 710b8021494Sopenharmony_ci VIXL_CHECK(invalid_2.Equals(invalid_2)); 711b8021494Sopenharmony_ci VIXL_CHECK(reg.Equals(reg)); 712b8021494Sopenharmony_ci VIXL_CHECK(mem.Equals(mem)); 713b8021494Sopenharmony_ci 714b8021494Sopenharmony_ci VIXL_CHECK(invalid_1.Equals(invalid_2)); 715b8021494Sopenharmony_ci VIXL_CHECK(invalid_2.Equals(invalid_1)); 716b8021494Sopenharmony_ci 717b8021494Sopenharmony_ci VIXL_CHECK(!invalid_1.Equals(reg)); 718b8021494Sopenharmony_ci VIXL_CHECK(!invalid_1.Equals(mem)); 719b8021494Sopenharmony_ci VIXL_CHECK(!reg.Equals(invalid_1)); 720b8021494Sopenharmony_ci VIXL_CHECK(!reg.Equals(invalid_2)); 721b8021494Sopenharmony_ci VIXL_CHECK(!reg.Equals(mem)); 722b8021494Sopenharmony_ci VIXL_CHECK(!mem.Equals(invalid_1)); 723b8021494Sopenharmony_ci VIXL_CHECK(!mem.Equals(reg)); 724b8021494Sopenharmony_ci} 725b8021494Sopenharmony_ci 726b8021494Sopenharmony_ci 727b8021494Sopenharmony_ciTEST(integer_operand_is) { 728b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0).IsZero()); 729b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(1).IsZero()); 730b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(-1).IsZero()); 731b8021494Sopenharmony_ci 732b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(-0x81).IsIntN(8)); 733b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-0x80).IsIntN(8)); 734b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).IsIntN(8)); 735b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0).IsIntN(8)); 736b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).IsIntN(8)); 737b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x7f).IsIntN(8)); 738b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(0x80).IsIntN(8)); 739b8021494Sopenharmony_ci 740b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(-1).IsUintN(8)); 741b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0).IsUintN(8)); 742b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).IsUintN(8)); 743b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0xff).IsUintN(8)); 744b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(0x100).IsUintN(8)); 745b8021494Sopenharmony_ci 746b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT64_MIN).IsIntN(64)); 747b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0).IsIntN(64)); 748b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT64_MAX).IsIntN(64)); 749b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(0x8000000000000000).IsIntN(64)); 750b8021494Sopenharmony_ci 751b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(-1).IsUintN(64)); 752b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0).IsUintN(64)); 753b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT64_MAX).IsUintN(64)); 754b8021494Sopenharmony_ci 755b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(-0x801).FitsInBits(12)); 756b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-0x800).FitsInBits(12)); 757b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0).FitsInBits(12)); 758b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x7ff).FitsInBits(12)); 759b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x800).FitsInBits(12)); 760b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0xfff).FitsInBits(12)); 761b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(0x1000).FitsInBits(12)); 762b8021494Sopenharmony_ci 763b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(-0x8001).FitsInLane(z0.VnH())); 764b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-0x8000).FitsInLane(z0.VnH())); 765b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0).FitsInLane(z0.VnH())); 766b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x7fff).FitsInLane(z0.VnH())); 767b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x8000).FitsInLane(z0.VnH())); 768b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0xffff).FitsInLane(z0.VnH())); 769b8021494Sopenharmony_ci VIXL_CHECK(!IntegerOperand(0x10000).FitsInLane(z0.VnH())); 770b8021494Sopenharmony_ci} 771b8021494Sopenharmony_ci 772b8021494Sopenharmony_ciTEST(integer_operand_as_uint) { 773b8021494Sopenharmony_ci // Simple cases. 774b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).AsUintN(8) == 1); 775b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).AsUintN(16) == 1); 776b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).AsUintN(32) == 1); 777b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).AsUintN(64) == 1); 778b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).AsUintN(8) == 0xff); 779b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).AsUintN(16) == 0xffff); 780b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).AsUintN(32) == 0xffffffff); 781b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).AsUintN(64) == 0xffffffffffffffff); 782b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0xf0).AsUintN(8) == 0xf0); 783b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0xf420).AsUintN(16) == 0xf420); 784b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0xf4242420).AsUintN(32) == 0xf4242420); 785b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0xf424242424242420).AsUintN(64) == 786b8021494Sopenharmony_ci 0xf424242424242420); 787b8021494Sopenharmony_ci 788b8021494Sopenharmony_ci // Boundary conditions for known-size types. 789b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT8_MIN).AsUintN(8) == 0x80); 790b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT8_MAX).AsUintN(8) == 0x7f); 791b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT8_MAX).AsUintN(8) == 0xff); 792b8021494Sopenharmony_ci 793b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT16_MIN).AsUintN(16) == 0x8000); 794b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT16_MAX).AsUintN(16) == 0x7fff); 795b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT16_MAX).AsUintN(16) == 0xffff); 796b8021494Sopenharmony_ci 797b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT32_MIN).AsUintN(32) == 0x80000000); 798b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT32_MAX).AsUintN(32) == 0x7fffffff); 799b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT32_MAX).AsUintN(32) == 0xffffffff); 800b8021494Sopenharmony_ci 801b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT64_MIN).AsUintN(64) == 0x8000000000000000); 802b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT64_MAX).AsUintN(64) == 0x7fffffffffffffff); 803b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT64_MAX).AsUintN(64) == 0xffffffffffffffff); 804b8021494Sopenharmony_ci} 805b8021494Sopenharmony_ci 806b8021494Sopenharmony_ciTEST(integer_operand_as_int) { 807b8021494Sopenharmony_ci // Simple cases. 808b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).AsIntN(8) == 1); 809b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).AsIntN(16) == 1); 810b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).AsIntN(32) == 1); 811b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(1).AsIntN(64) == 1); 812b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).AsIntN(8) == -1); 813b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).AsIntN(16) == -1); 814b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).AsIntN(32) == -1); 815b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(-1).AsIntN(64) == -1); 816b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x70).AsIntN(8) == 0x70); 817b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x7420).AsIntN(16) == 0x7420); 818b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x74242420).AsIntN(32) == 0x74242420); 819b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x7424242424242420).AsIntN(64) == 820b8021494Sopenharmony_ci 0x7424242424242420); 821b8021494Sopenharmony_ci 822b8021494Sopenharmony_ci // Boundary conditions for known-size types. 823b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT8_MAX).AsIntN(8) == -1); 824b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT16_MAX).AsIntN(16) == -1); 825b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT32_MAX).AsIntN(32) == -1); 826b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(UINT64_MAX).AsIntN(64) == -1); 827b8021494Sopenharmony_ci 828b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT8_MAX).AsIntN(8) == INT8_MAX); 829b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT16_MAX).AsIntN(16) == INT16_MAX); 830b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT32_MAX).AsIntN(32) == INT32_MAX); 831b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(INT64_MAX).AsIntN(64) == INT64_MAX); 832b8021494Sopenharmony_ci 833b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x80).AsIntN(8) == INT8_MIN); 834b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x8000).AsIntN(16) == INT16_MIN); 835b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x80000000).AsIntN(32) == INT32_MIN); 836b8021494Sopenharmony_ci VIXL_CHECK(IntegerOperand(0x8000000000000000).AsIntN(64) == INT64_MIN); 837b8021494Sopenharmony_ci} 838b8021494Sopenharmony_ci 839b8021494Sopenharmony_citemplate <unsigned N> 840b8021494Sopenharmony_ciclass IntegerOperandTryEncodeShiftedIntHelper { 841b8021494Sopenharmony_ci public: 842b8021494Sopenharmony_ci IntegerOperandTryEncodeShiftedIntHelper() {} 843b8021494Sopenharmony_ci 844b8021494Sopenharmony_ci template <unsigned kShift, typename T> 845b8021494Sopenharmony_ci void TestEncodable(T value, const ZRegister& zd, int64_t expected_imm) { 846b8021494Sopenharmony_ci VIXL_CHECK(TestImpl<kShift>(value, zd, expected_imm)); 847b8021494Sopenharmony_ci } 848b8021494Sopenharmony_ci 849b8021494Sopenharmony_ci template <unsigned kShift, typename T> 850b8021494Sopenharmony_ci void TestUnencodable(T value, const ZRegister& zd) { 851b8021494Sopenharmony_ci // The `expected_imm` value is ignored, so its value is arbitrary. 852b8021494Sopenharmony_ci VIXL_CHECK(!TestImpl<kShift>(value, zd, 0)); 853b8021494Sopenharmony_ci } 854b8021494Sopenharmony_ci 855b8021494Sopenharmony_ci private: 856b8021494Sopenharmony_ci template <unsigned kShift, typename T> 857b8021494Sopenharmony_ci bool TestImpl(T value, const ZRegister& zd, int64_t expected_imm) { 858b8021494Sopenharmony_ci IntegerOperand operand(value); 859b8021494Sopenharmony_ci int64_t imm = 0xdeadbeef42; 860b8021494Sopenharmony_ci unsigned shift = 0xbeef43; 861b8021494Sopenharmony_ci bool success = 862b8021494Sopenharmony_ci operand.TryEncodeAsShiftedIntNForLane<N, kShift>(zd, &imm, &shift); 863b8021494Sopenharmony_ci if (success) { 864b8021494Sopenharmony_ci VIXL_CHECK(imm == expected_imm); 865b8021494Sopenharmony_ci VIXL_CHECK(shift == kShift); 866b8021494Sopenharmony_ci } else { 867b8021494Sopenharmony_ci // Check that the outputs were unmodified. 868b8021494Sopenharmony_ci VIXL_CHECK(imm == 0xdeadbeef42); 869b8021494Sopenharmony_ci VIXL_CHECK(shift == 0xbeef43); 870b8021494Sopenharmony_ci } 871b8021494Sopenharmony_ci 872b8021494Sopenharmony_ci // If kShift is 0, also check TryEncodeAsIntNForLane. 873b8021494Sopenharmony_ci if (kShift == 0) { 874b8021494Sopenharmony_ci int64_t unshifted_imm = 0xdeadbeef99; 875b8021494Sopenharmony_ci bool unshifted_success = 876b8021494Sopenharmony_ci operand.TryEncodeAsIntNForLane<N>(zd, &unshifted_imm); 877b8021494Sopenharmony_ci 878b8021494Sopenharmony_ci VIXL_CHECK(unshifted_success == success); 879b8021494Sopenharmony_ci if (unshifted_success) { 880b8021494Sopenharmony_ci VIXL_CHECK(unshifted_imm == expected_imm); 881b8021494Sopenharmony_ci } else { 882b8021494Sopenharmony_ci VIXL_CHECK(unshifted_imm == 0xdeadbeef99); 883b8021494Sopenharmony_ci } 884b8021494Sopenharmony_ci } 885b8021494Sopenharmony_ci 886b8021494Sopenharmony_ci return success; 887b8021494Sopenharmony_ci } 888b8021494Sopenharmony_ci}; 889b8021494Sopenharmony_ci 890b8021494Sopenharmony_ciTEST(integer_operand_encode_as_intn) { 891b8021494Sopenharmony_ci IntegerOperandTryEncodeShiftedIntHelper<4> int4_helper; 892b8021494Sopenharmony_ci IntegerOperandTryEncodeShiftedIntHelper<8> int8_helper; 893b8021494Sopenharmony_ci IntegerOperandTryEncodeShiftedIntHelper<12> int12_helper; 894b8021494Sopenharmony_ci 895b8021494Sopenharmony_ci // Simple cases, where the value is directly encodable. 896b8021494Sopenharmony_ci int4_helper.TestEncodable<0>(-8, z0.VnH(), -8); 897b8021494Sopenharmony_ci int4_helper.TestEncodable<0>(-7, z0.VnH(), -7); 898b8021494Sopenharmony_ci int4_helper.TestEncodable<0>(-1, z0.VnS(), -1); 899b8021494Sopenharmony_ci int4_helper.TestEncodable<0>(0, z0.VnD(), 0); 900b8021494Sopenharmony_ci int4_helper.TestEncodable<0>(1, z0.VnB(), 1); 901b8021494Sopenharmony_ci int4_helper.TestEncodable<0>(7, z0.VnH(), 7); 902b8021494Sopenharmony_ci 903b8021494Sopenharmony_ci int8_helper.TestEncodable<0>(0x7f, z0.VnB(), 0x7f); 904b8021494Sopenharmony_ci int8_helper.TestEncodable<0>(0x7f, z0.VnH(), 0x7f); 905b8021494Sopenharmony_ci int12_helper.TestEncodable<0>(0x7ff, z0.VnH(), 0x7ff); 906b8021494Sopenharmony_ci 907b8021494Sopenharmony_ci int8_helper.TestEncodable<0>(-0x80, z0.VnB(), -0x80); 908b8021494Sopenharmony_ci int8_helper.TestEncodable<0>(-0x80, z0.VnH(), -0x80); 909b8021494Sopenharmony_ci int12_helper.TestEncodable<0>(-0x800, z0.VnH(), -0x800); 910b8021494Sopenharmony_ci 911b8021494Sopenharmony_ci // Cases that are directly encodable with a shift. 912b8021494Sopenharmony_ci int8_helper.TestEncodable<4>(-0x800, z0.VnH(), -0x80); 913b8021494Sopenharmony_ci int8_helper.TestEncodable<4>(-0x7f0, z0.VnH(), -0x7f); 914b8021494Sopenharmony_ci int8_helper.TestEncodable<4>(-0x010, z0.VnH(), -1); 915b8021494Sopenharmony_ci int8_helper.TestEncodable<4>(0x000, z0.VnH(), 0); 916b8021494Sopenharmony_ci int8_helper.TestEncodable<4>(0x010, z0.VnH(), 1); 917b8021494Sopenharmony_ci int8_helper.TestEncodable<4>(0x7f0, z0.VnH(), 0x7f); 918b8021494Sopenharmony_ci 919b8021494Sopenharmony_ci // Ensure that (positive) bit representations of negative values are treated 920b8021494Sopenharmony_ci // as negative values, even though their arithmetic values are unencodable. 921b8021494Sopenharmony_ci int12_helper.TestEncodable<0>(0xffd6, z0.VnH(), -42); 922b8021494Sopenharmony_ci int12_helper.TestEncodable<0>(0xffffffd6, z0.VnS(), -42); 923b8021494Sopenharmony_ci int12_helper.TestEncodable<4>(0xfd60, z0.VnH(), -42); 924b8021494Sopenharmony_ci int12_helper.TestEncodable<8>(0xffffd600, z0.VnS(), -42); 925b8021494Sopenharmony_ci 926b8021494Sopenharmony_ci int8_helper.TestEncodable<0>(UINT8_MAX, z0.VnB(), -1); 927b8021494Sopenharmony_ci int8_helper.TestEncodable<0>(UINT16_MAX, z0.VnH(), -1); 928b8021494Sopenharmony_ci int8_helper.TestEncodable<0>(UINT32_MAX, z0.VnS(), -1); 929b8021494Sopenharmony_ci int8_helper.TestEncodable<0>(UINT64_MAX, z0.VnD(), -1); 930b8021494Sopenharmony_ci 931b8021494Sopenharmony_ci int4_helper.TestEncodable<1>(UINT8_MAX ^ 0x1, z0.VnB(), -1); 932b8021494Sopenharmony_ci int4_helper.TestEncodable<2>(UINT16_MAX ^ 0x3, z0.VnH(), -1); 933b8021494Sopenharmony_ci int4_helper.TestEncodable<3>(UINT32_MAX ^ 0x7, z0.VnS(), -1); 934b8021494Sopenharmony_ci int4_helper.TestEncodable<4>(UINT64_MAX ^ 0xf, z0.VnD(), -1); 935b8021494Sopenharmony_ci 936b8021494Sopenharmony_ci // Unencodable cases. 937b8021494Sopenharmony_ci int8_helper.TestUnencodable<0>(INT16_MAX, z0.VnH()); 938b8021494Sopenharmony_ci int8_helper.TestUnencodable<0>(INT32_MAX, z0.VnS()); 939b8021494Sopenharmony_ci int8_helper.TestUnencodable<0>(INT64_MAX, z0.VnD()); 940b8021494Sopenharmony_ci 941b8021494Sopenharmony_ci int4_helper.TestUnencodable<0>(0x10, z0.VnB()); 942b8021494Sopenharmony_ci int4_helper.TestUnencodable<1>(0x20, z0.VnB()); 943b8021494Sopenharmony_ci 944b8021494Sopenharmony_ci int12_helper.TestUnencodable<1>(1, z0.VnD()); 945b8021494Sopenharmony_ci int12_helper.TestUnencodable<12>(1, z0.VnD()); 946b8021494Sopenharmony_ci int12_helper.TestUnencodable<12>(0x800, z0.VnD()); 947b8021494Sopenharmony_ci} 948b8021494Sopenharmony_ci 949b8021494Sopenharmony_ciTEST(static_register_types) { 950b8021494Sopenharmony_ci // [WX]Register implicitly casts to Register. 951b8021494Sopenharmony_ci XRegister x_x0(0); 952b8021494Sopenharmony_ci WRegister w_w0(0); 953b8021494Sopenharmony_ci Register r_x0 = x_x0; 954b8021494Sopenharmony_ci Register r_w0 = w_w0; 955b8021494Sopenharmony_ci VIXL_CHECK(r_x0.Is(x_x0)); 956b8021494Sopenharmony_ci VIXL_CHECK(x_x0.Is(r_x0)); 957b8021494Sopenharmony_ci VIXL_CHECK(r_w0.Is(w_w0)); 958b8021494Sopenharmony_ci VIXL_CHECK(w_w0.Is(r_w0)); 959b8021494Sopenharmony_ci 960b8021494Sopenharmony_ci // Register explicitly casts to [WX]Register. 961b8021494Sopenharmony_ci Register r_x1(1, kXRegSize); 962b8021494Sopenharmony_ci Register r_w1(1, kWRegSize); 963b8021494Sopenharmony_ci XRegister x_x1(r_x1); 964b8021494Sopenharmony_ci WRegister w_w1(r_w1); 965b8021494Sopenharmony_ci VIXL_CHECK(r_x1.Is(x_x1)); 966b8021494Sopenharmony_ci VIXL_CHECK(x_x1.Is(r_x1)); 967b8021494Sopenharmony_ci VIXL_CHECK(r_w1.Is(w_w1)); 968b8021494Sopenharmony_ci VIXL_CHECK(w_w1.Is(r_w1)); 969b8021494Sopenharmony_ci 970b8021494Sopenharmony_ci // [WX]Register implicitly casts to CPURegister. 971b8021494Sopenharmony_ci XRegister x_x2(2); 972b8021494Sopenharmony_ci WRegister w_w2(2); 973b8021494Sopenharmony_ci CPURegister cpu_x2 = x_x2; 974b8021494Sopenharmony_ci CPURegister cpu_w2 = w_w2; 975b8021494Sopenharmony_ci VIXL_CHECK(cpu_x2.Is(x_x2)); 976b8021494Sopenharmony_ci VIXL_CHECK(x_x2.Is(cpu_x2)); 977b8021494Sopenharmony_ci VIXL_CHECK(cpu_w2.Is(w_w2)); 978b8021494Sopenharmony_ci VIXL_CHECK(w_w2.Is(cpu_w2)); 979b8021494Sopenharmony_ci} 980b8021494Sopenharmony_ci 981b8021494Sopenharmony_ci 982b8021494Sopenharmony_ciTEST(operand_is_plain_register) { 983b8021494Sopenharmony_ci VIXL_CHECK(Operand(x0).IsPlainRegister()); 984b8021494Sopenharmony_ci VIXL_CHECK(Operand(x1, LSL, 0).IsPlainRegister()); 985b8021494Sopenharmony_ci VIXL_CHECK(Operand(x2, LSR, 0).IsPlainRegister()); 986b8021494Sopenharmony_ci VIXL_CHECK(Operand(x3, ASR, 0).IsPlainRegister()); 987b8021494Sopenharmony_ci VIXL_CHECK(Operand(x4, ROR, 0).IsPlainRegister()); 988b8021494Sopenharmony_ci VIXL_CHECK(Operand(x5, UXTX).IsPlainRegister()); 989b8021494Sopenharmony_ci VIXL_CHECK(Operand(x6, SXTX).IsPlainRegister()); 990b8021494Sopenharmony_ci VIXL_CHECK(Operand(w7).IsPlainRegister()); 991b8021494Sopenharmony_ci VIXL_CHECK(Operand(w8, LSL, 0).IsPlainRegister()); 992b8021494Sopenharmony_ci VIXL_CHECK(Operand(w9, LSR, 0).IsPlainRegister()); 993b8021494Sopenharmony_ci VIXL_CHECK(Operand(w10, ASR, 0).IsPlainRegister()); 994b8021494Sopenharmony_ci VIXL_CHECK(Operand(w11, ROR, 0).IsPlainRegister()); 995b8021494Sopenharmony_ci 996b8021494Sopenharmony_ci VIXL_CHECK(!Operand(x0, LSL, 1).IsPlainRegister()); 997b8021494Sopenharmony_ci VIXL_CHECK(!Operand(x1, LSR, 2).IsPlainRegister()); 998b8021494Sopenharmony_ci VIXL_CHECK(!Operand(x2, ASR, 3).IsPlainRegister()); 999b8021494Sopenharmony_ci VIXL_CHECK(!Operand(x3, ROR, 4).IsPlainRegister()); 1000b8021494Sopenharmony_ci VIXL_CHECK(!Operand(x5, UXTX, 1).IsPlainRegister()); 1001b8021494Sopenharmony_ci VIXL_CHECK(!Operand(x6, SXTX, 2).IsPlainRegister()); 1002b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w7, LSL, 1).IsPlainRegister()); 1003b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w8, LSR, 2).IsPlainRegister()); 1004b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w9, ASR, 3).IsPlainRegister()); 1005b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w10, ROR, 4).IsPlainRegister()); 1006b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w11, UXTB).IsPlainRegister()); 1007b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w12, SXTB).IsPlainRegister()); 1008b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w13, UXTH).IsPlainRegister()); 1009b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w14, SXTH).IsPlainRegister()); 1010b8021494Sopenharmony_ci // UXTW and SXTW could be treated as plain registers in 32-bit contexts, but 1011b8021494Sopenharmony_ci // the Operand class doesn't know the context so it has to return false. 1012b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w15, UXTW).IsPlainRegister()); 1013b8021494Sopenharmony_ci VIXL_CHECK(!Operand(w16, SXTW).IsPlainRegister()); 1014b8021494Sopenharmony_ci} 1015b8021494Sopenharmony_ci 1016b8021494Sopenharmony_ci 1017b8021494Sopenharmony_ciTEST(memoperand_is_plain_register) { 1018b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x0).IsPlainRegister()); 1019b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(sp).IsPlainRegister()); 1020b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x1, 0).IsPlainRegister()); 1021b8021494Sopenharmony_ci 1022b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x2, xzr).IsPlainRegister()); 1023b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x3, xzr, SXTX).IsPlainRegister()); 1024b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x4, xzr, SXTX, 2).IsPlainRegister()); 1025b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x5, wzr, UXTW).IsPlainRegister()); 1026b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x6, wzr, UXTW, 3).IsPlainRegister()); 1027b8021494Sopenharmony_ci 1028b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x7, 0, PostIndex).IsPlainRegister()); 1029b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x8, 0, PreIndex).IsPlainRegister()); 1030b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x9, xzr, PostIndex).IsPlainRegister()); 1031b8021494Sopenharmony_ci 1032b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x20, 1).IsPlainRegister()); 1033b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x21, x30).IsPlainRegister()); 1034b8021494Sopenharmony_ci} 1035b8021494Sopenharmony_ci 1036b8021494Sopenharmony_ciTEST(memoperand_is_plain_register_or_equivalent) { 1037b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x0).IsEquivalentToPlainRegister()); 1038b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(sp).IsEquivalentToPlainRegister()); 1039b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x1, 0).IsEquivalentToPlainRegister()); 1040b8021494Sopenharmony_ci 1041b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x2, xzr).IsEquivalentToPlainRegister()); 1042b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x3, xzr, SXTX).IsEquivalentToPlainRegister()); 1043b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x4, xzr, SXTX, 2).IsEquivalentToPlainRegister()); 1044b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x5, wzr, UXTW).IsEquivalentToPlainRegister()); 1045b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x6, wzr, UXTW, 3).IsEquivalentToPlainRegister()); 1046b8021494Sopenharmony_ci 1047b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x7, 0, PostIndex).IsEquivalentToPlainRegister()); 1048b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x8, 0, PreIndex).IsEquivalentToPlainRegister()); 1049b8021494Sopenharmony_ci VIXL_CHECK(MemOperand(x9, xzr, PostIndex).IsEquivalentToPlainRegister()); 1050b8021494Sopenharmony_ci 1051b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x20, 1).IsEquivalentToPlainRegister()); 1052b8021494Sopenharmony_ci VIXL_CHECK(!MemOperand(x21, x30).IsEquivalentToPlainRegister()); 1053b8021494Sopenharmony_ci} 1054b8021494Sopenharmony_ci 1055b8021494Sopenharmony_ciTEST(sve_memoperand_is_plain_scalar) { 1056b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x0).IsPlainScalar()); 1057b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(sp).IsPlainScalar()); 1058b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x1, 0).IsPlainScalar()); 1059b8021494Sopenharmony_ci 1060b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x2, xzr).IsPlainScalar()); 1061b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x4, xzr, LSL, 2).IsPlainScalar()); 1062b8021494Sopenharmony_ci 1063b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x20, 1).IsPlainScalar()); 1064b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x21, x30).IsPlainScalar()); 1065b8021494Sopenharmony_ci 1066b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x0, z1.VnD()).IsPlainScalar()); 1067b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x2, z3.VnS(), UXTW).IsPlainScalar()); 1068b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(z4.VnD(), 0).IsPlainScalar()); 1069b8021494Sopenharmony_ci} 1070b8021494Sopenharmony_ci 1071b8021494Sopenharmony_ciTEST(sve_memoperand_is_scalar_or_equivalent) { 1072b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x0).IsEquivalentToScalar()); 1073b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(sp).IsEquivalentToScalar()); 1074b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x1, 0).IsEquivalentToScalar()); 1075b8021494Sopenharmony_ci 1076b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x2, xzr).IsEquivalentToScalar()); 1077b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x4, xzr, LSL, 2).IsEquivalentToScalar()); 1078b8021494Sopenharmony_ci 1079b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x20, 1).IsEquivalentToScalar()); 1080b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x21, x30).IsEquivalentToScalar()); 1081b8021494Sopenharmony_ci 1082b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x0, z1.VnD()).IsEquivalentToScalar()); 1083b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x2, z3.VnD(), SXTW).IsEquivalentToScalar()); 1084b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(z4.VnD(), 0).IsEquivalentToScalar()); 1085b8021494Sopenharmony_ci} 1086b8021494Sopenharmony_ci 1087b8021494Sopenharmony_ciTEST(sve_memoperand_types) { 1088b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x0, 42).IsScalarPlusImmediate()); 1089b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x1, 42, SVE_MUL_VL).IsScalarPlusImmediate()); 1090b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x2, -42, SVE_MUL_VL).IsScalarPlusImmediate()); 1091b8021494Sopenharmony_ci 1092b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(sp, x3).IsScalarPlusScalar()); 1093b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x4, xzr).IsScalarPlusScalar()); 1094b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x5, x6, LSL, 1).IsScalarPlusScalar()); 1095b8021494Sopenharmony_ci 1096b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x7, z0.VnD()).IsScalarPlusVector()); 1097b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x8, z1.VnS(), SXTW).IsScalarPlusVector()); 1098b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x9, z2.VnD(), UXTW).IsScalarPlusVector()); 1099b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x10, z3.VnD(), LSL, 2).IsScalarPlusVector()); 1100b8021494Sopenharmony_ci 1101b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(z4.VnD(), 42).IsVectorPlusImmediate()); 1102b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(z5.VnS(), -42).IsVectorPlusImmediate()); 1103b8021494Sopenharmony_ci} 1104b8021494Sopenharmony_ci 1105b8021494Sopenharmony_ciTEST(sve_memoperand_scatter_gather) { 1106b8021494Sopenharmony_ci // Single-address accesses. 1107b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x0, 42).IsScatterGather()); 1108b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x1, 42, SVE_MUL_VL).IsScatterGather()); 1109b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x2, -42, SVE_MUL_VL).IsScatterGather()); 1110b8021494Sopenharmony_ci 1111b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(sp, x3).IsScatterGather()); 1112b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x4, xzr).IsScatterGather()); 1113b8021494Sopenharmony_ci VIXL_CHECK(!SVEMemOperand(x5, x6, LSL, 1).IsScatterGather()); 1114b8021494Sopenharmony_ci 1115b8021494Sopenharmony_ci // Scatter-gather accesses. 1116b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x7, z0.VnD()).IsScatterGather()); 1117b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x8, z1.VnS(), SXTW).IsScatterGather()); 1118b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x9, z2.VnD(), UXTW).IsScatterGather()); 1119b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(x10, z3.VnD(), LSL, 2).IsScatterGather()); 1120b8021494Sopenharmony_ci 1121b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(z4.VnD(), 42).IsScatterGather()); 1122b8021494Sopenharmony_ci VIXL_CHECK(SVEMemOperand(z5.VnS(), -42).IsScatterGather()); 1123b8021494Sopenharmony_ci} 1124b8021494Sopenharmony_ci 1125b8021494Sopenharmony_ciTEST(scratch_scope_basic) { 1126b8021494Sopenharmony_ci MacroAssembler masm; 1127b8021494Sopenharmony_ci // x16 and x17 are available as scratch registers by default. 1128b8021494Sopenharmony_ci { 1129b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1130b8021494Sopenharmony_ci Register temp1 = temps.AcquireW(); 1131b8021494Sopenharmony_ci Register temp2 = temps.AcquireX(); 1132b8021494Sopenharmony_ci VIXL_CHECK(temp1.Is(w16)); 1133b8021494Sopenharmony_ci VIXL_CHECK(temp2.Is(x17)); 1134b8021494Sopenharmony_ci } 1135b8021494Sopenharmony_ci { 1136b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1137b8021494Sopenharmony_ci Register temp1 = temps.AcquireRegisterOfSize(kXRegSize); 1138b8021494Sopenharmony_ci Register temp2 = temps.AcquireRegisterOfSize(kWRegSize); 1139b8021494Sopenharmony_ci VIXL_CHECK(temp1.Is(x16)); 1140b8021494Sopenharmony_ci VIXL_CHECK(temp2.Is(w17)); 1141b8021494Sopenharmony_ci } 1142b8021494Sopenharmony_ci} 1143b8021494Sopenharmony_ci 1144b8021494Sopenharmony_ciTEST(scratch_scope_basic_v) { 1145b8021494Sopenharmony_ci MacroAssembler masm; 1146b8021494Sopenharmony_ci // v31 is the only V scratch register available by default. 1147b8021494Sopenharmony_ci { 1148b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1149b8021494Sopenharmony_ci VRegister temp = temps.AcquireH(); 1150b8021494Sopenharmony_ci VIXL_CHECK(temp.Is(h31)); 1151b8021494Sopenharmony_ci } 1152b8021494Sopenharmony_ci { 1153b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1154b8021494Sopenharmony_ci VRegister temp = temps.AcquireS(); 1155b8021494Sopenharmony_ci VIXL_CHECK(temp.Is(s31)); 1156b8021494Sopenharmony_ci } 1157b8021494Sopenharmony_ci { 1158b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1159b8021494Sopenharmony_ci VRegister temp = temps.AcquireD(); 1160b8021494Sopenharmony_ci VIXL_CHECK(temp.Is(d31)); 1161b8021494Sopenharmony_ci } 1162b8021494Sopenharmony_ci { 1163b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1164b8021494Sopenharmony_ci VRegister temp = temps.AcquireVRegisterOfSize(kQRegSize); 1165b8021494Sopenharmony_ci VIXL_CHECK(temp.Is(q31)); 1166b8021494Sopenharmony_ci } 1167b8021494Sopenharmony_ci { 1168b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1169b8021494Sopenharmony_ci VRegister temp = temps.AcquireVRegisterOfSize(kDRegSize); 1170b8021494Sopenharmony_ci VIXL_CHECK(temp.Is(d31)); 1171b8021494Sopenharmony_ci } 1172b8021494Sopenharmony_ci { 1173b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1174b8021494Sopenharmony_ci VRegister temp = temps.AcquireVRegisterOfSize(kSRegSize); 1175b8021494Sopenharmony_ci VIXL_CHECK(temp.Is(s31)); 1176b8021494Sopenharmony_ci } 1177b8021494Sopenharmony_ci} 1178b8021494Sopenharmony_ci 1179b8021494Sopenharmony_ciTEST(scratch_scope_basic_z) { 1180b8021494Sopenharmony_ci MacroAssembler masm; 1181b8021494Sopenharmony_ci // z31 is the only Z scratch register available by default. 1182b8021494Sopenharmony_ci { 1183b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1184b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(v31)); 1185b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(z31)); 1186b8021494Sopenharmony_ci ZRegister temp = temps.AcquireZ(); 1187b8021494Sopenharmony_ci VIXL_CHECK(temp.Is(z31)); 1188b8021494Sopenharmony_ci // Check that allocating a Z register properly reserves the corresponding V 1189b8021494Sopenharmony_ci // register. 1190b8021494Sopenharmony_ci VIXL_CHECK(!temps.IsAvailable(v31)); 1191b8021494Sopenharmony_ci VIXL_CHECK(!temps.IsAvailable(z31)); 1192b8021494Sopenharmony_ci } 1193b8021494Sopenharmony_ci // Check that the destructor restored the acquired register. 1194b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1195b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(v31)); 1196b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(z31)); 1197b8021494Sopenharmony_ci} 1198b8021494Sopenharmony_ci 1199b8021494Sopenharmony_ciTEST(scratch_scope_basic_p) { 1200b8021494Sopenharmony_ci MacroAssembler masm; 1201b8021494Sopenharmony_ci { 1202b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1203b8021494Sopenharmony_ci // There are no P scratch registers available by default. 1204b8021494Sopenharmony_ci VIXL_CHECK(masm.GetScratchPRegisterList()->IsEmpty()); 1205b8021494Sopenharmony_ci temps.Include(p0, p1); 1206b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(p0)); 1207b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(p1)); 1208b8021494Sopenharmony_ci temps.Include(p7, p8, p15); 1209b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(p7)); 1210b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(p8)); 1211b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(p15)); 1212b8021494Sopenharmony_ci 1213b8021494Sopenharmony_ci // AcquireGoverningP() can only return p0-p7. 1214b8021494Sopenharmony_ci VIXL_CHECK(temps.AcquireGoverningP().GetCode() < 1215b8021494Sopenharmony_ci kNumberOfGoverningPRegisters); 1216b8021494Sopenharmony_ci VIXL_CHECK(temps.AcquireGoverningP().GetCode() < 1217b8021494Sopenharmony_ci kNumberOfGoverningPRegisters); 1218b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(p8)); 1219b8021494Sopenharmony_ci VIXL_CHECK(temps.IsAvailable(p15)); 1220b8021494Sopenharmony_ci 1221b8021494Sopenharmony_ci // AcquireP() prefers p8-p15, ... 1222b8021494Sopenharmony_ci VIXL_CHECK(temps.AcquireP().GetCode() >= kNumberOfGoverningPRegisters); 1223b8021494Sopenharmony_ci VIXL_CHECK(temps.AcquireP().GetCode() >= kNumberOfGoverningPRegisters); 1224b8021494Sopenharmony_ci // ... but will return p0-p7 if none of p8-p15 are available. 1225b8021494Sopenharmony_ci VIXL_CHECK(temps.AcquireP().GetCode() < kNumberOfGoverningPRegisters); 1226b8021494Sopenharmony_ci 1227b8021494Sopenharmony_ci VIXL_CHECK(masm.GetScratchPRegisterList()->IsEmpty()); 1228b8021494Sopenharmony_ci 1229b8021494Sopenharmony_ci // Leave some registers available so we can test the destructor. 1230b8021494Sopenharmony_ci temps.Include(p3, p6, p9, p12); 1231b8021494Sopenharmony_ci VIXL_CHECK(!masm.GetScratchPRegisterList()->IsEmpty()); 1232b8021494Sopenharmony_ci } 1233b8021494Sopenharmony_ci // Check that the destructor correctly cleared the list. 1234b8021494Sopenharmony_ci VIXL_CHECK(masm.GetScratchPRegisterList()->IsEmpty()); 1235b8021494Sopenharmony_ci} 1236b8021494Sopenharmony_ci 1237b8021494Sopenharmony_ciTEST(scratch_scope_include_ignored) { 1238b8021494Sopenharmony_ci MacroAssembler masm; 1239b8021494Sopenharmony_ci { 1240b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1241b8021494Sopenharmony_ci // Start with an empty set of scratch registers. 1242b8021494Sopenharmony_ci temps.ExcludeAll(); 1243b8021494Sopenharmony_ci 1244b8021494Sopenharmony_ci // Including NoReg has no effect. 1245b8021494Sopenharmony_ci temps.Include(NoReg); 1246b8021494Sopenharmony_ci temps.Include(NoCPUReg); 1247b8021494Sopenharmony_ci temps.Include(CPURegList(CPURegister::kNoRegister, 0, 0)); 1248b8021494Sopenharmony_ci 1249b8021494Sopenharmony_ci // Including sp or zr has no effect, since they are never appropriate 1250b8021494Sopenharmony_ci // scratch registers. 1251b8021494Sopenharmony_ci temps.Include(sp); 1252b8021494Sopenharmony_ci temps.Include(xzr, wsp); 1253b8021494Sopenharmony_ci temps.Include(wzr); 1254b8021494Sopenharmony_ci temps.Include(CPURegList(xzr, sp)); 1255b8021494Sopenharmony_ci 1256b8021494Sopenharmony_ci VIXL_CHECK(masm.GetScratchRegisterList()->IsEmpty()); 1257b8021494Sopenharmony_ci VIXL_CHECK(masm.GetScratchVRegisterList()->IsEmpty()); 1258b8021494Sopenharmony_ci } 1259b8021494Sopenharmony_ci} 1260b8021494Sopenharmony_ci 1261b8021494Sopenharmony_ciclass ScratchScopeHelper { 1262b8021494Sopenharmony_ci public: 1263b8021494Sopenharmony_ci enum Action { kRelease, kInclude, kExclude }; 1264b8021494Sopenharmony_ci 1265b8021494Sopenharmony_ci ScratchScopeHelper(MacroAssembler* masm, 1266b8021494Sopenharmony_ci Action action, 1267b8021494Sopenharmony_ci CPURegister::RegisterType type) 1268b8021494Sopenharmony_ci : masm_(masm), 1269b8021494Sopenharmony_ci action_(action), 1270b8021494Sopenharmony_ci type_(type), 1271b8021494Sopenharmony_ci expected_(GetGuardListFor(CPURegister::kRegister)), 1272b8021494Sopenharmony_ci expected_v_(GetGuardListFor(CPURegister::kVRegister)), 1273b8021494Sopenharmony_ci expected_p_(GetGuardListFor(CPURegister::kPRegister)) { 1274b8021494Sopenharmony_ci *GetExpectedFor(type) = GetInitialList(); 1275b8021494Sopenharmony_ci masm->GetScratchRegisterList()->SetList(expected_); 1276b8021494Sopenharmony_ci masm->GetScratchVRegisterList()->SetList(expected_v_); 1277b8021494Sopenharmony_ci masm->GetScratchPRegisterList()->SetList(expected_p_); 1278b8021494Sopenharmony_ci } 1279b8021494Sopenharmony_ci 1280b8021494Sopenharmony_ci // Notify the helper that the registers in `update` have been passed into 1281b8021494Sopenharmony_ci // DoAction(), and assert that the MacroAssembler's scratch lists are as 1282b8021494Sopenharmony_ci // expected. 1283b8021494Sopenharmony_ci void RecordActionsAndCheck(RegList update) { 1284b8021494Sopenharmony_ci RegList* expected = GetExpectedFor(type_); 1285b8021494Sopenharmony_ci switch (action_) { 1286b8021494Sopenharmony_ci case kRelease: 1287b8021494Sopenharmony_ci // It isn't valid to release a register that is already available. 1288b8021494Sopenharmony_ci VIXL_CHECK((*expected & update) == 0); 1289b8021494Sopenharmony_ci VIXL_FALLTHROUGH(); 1290b8021494Sopenharmony_ci case kInclude: 1291b8021494Sopenharmony_ci *expected |= update; 1292b8021494Sopenharmony_ci break; 1293b8021494Sopenharmony_ci case kExclude: 1294b8021494Sopenharmony_ci *expected &= ~update; 1295b8021494Sopenharmony_ci break; 1296b8021494Sopenharmony_ci } 1297b8021494Sopenharmony_ci VIXL_CHECK(masm_->GetScratchRegisterList()->GetList() == expected_); 1298b8021494Sopenharmony_ci VIXL_CHECK(masm_->GetScratchVRegisterList()->GetList() == expected_v_); 1299b8021494Sopenharmony_ci VIXL_CHECK(masm_->GetScratchPRegisterList()->GetList() == expected_p_); 1300b8021494Sopenharmony_ci } 1301b8021494Sopenharmony_ci 1302b8021494Sopenharmony_ci private: 1303b8021494Sopenharmony_ci RegList GetInitialList() { 1304b8021494Sopenharmony_ci switch (action_) { 1305b8021494Sopenharmony_ci case kRelease: 1306b8021494Sopenharmony_ci case kInclude: 1307b8021494Sopenharmony_ci return 0; 1308b8021494Sopenharmony_ci case kExclude: 1309b8021494Sopenharmony_ci return GetPotentialListFor(type_); 1310b8021494Sopenharmony_ci } 1311b8021494Sopenharmony_ci VIXL_UNREACHABLE(); 1312b8021494Sopenharmony_ci return 0; 1313b8021494Sopenharmony_ci } 1314b8021494Sopenharmony_ci 1315b8021494Sopenharmony_ci // Return some valid, non-zero RegList suitable for use as a guard value. 1316b8021494Sopenharmony_ci static RegList GetGuardListFor(CPURegister::RegisterType type) { 1317b8021494Sopenharmony_ci return (0x1111111111111111 * (type + 1)) & GetPotentialListFor(type); 1318b8021494Sopenharmony_ci } 1319b8021494Sopenharmony_ci 1320b8021494Sopenharmony_ci static RegList GetPotentialListFor(CPURegister::RegisterType type) { 1321b8021494Sopenharmony_ci RegList list = CPURegList::All(type).GetList(); 1322b8021494Sopenharmony_ci // The zr and sp registers cannot be scratch registers. 1323b8021494Sopenharmony_ci if (type == CPURegister::kRegister) list &= ~(xzr.GetBit() | sp.GetBit()); 1324b8021494Sopenharmony_ci return list; 1325b8021494Sopenharmony_ci } 1326b8021494Sopenharmony_ci 1327b8021494Sopenharmony_ci RegList* GetExpectedFor(CPURegister::RegisterType type) { 1328b8021494Sopenharmony_ci switch (type) { 1329b8021494Sopenharmony_ci case CPURegister::kNoRegister: 1330b8021494Sopenharmony_ci VIXL_UNREACHABLE(); 1331b8021494Sopenharmony_ci return NULL; 1332b8021494Sopenharmony_ci case CPURegister::kRegister: 1333b8021494Sopenharmony_ci return &expected_; 1334b8021494Sopenharmony_ci case CPURegister::kVRegister: 1335b8021494Sopenharmony_ci case CPURegister::kZRegister: 1336b8021494Sopenharmony_ci return &expected_v_; 1337b8021494Sopenharmony_ci case CPURegister::kPRegister: 1338b8021494Sopenharmony_ci return &expected_p_; 1339b8021494Sopenharmony_ci } 1340b8021494Sopenharmony_ci VIXL_UNREACHABLE(); 1341b8021494Sopenharmony_ci return NULL; 1342b8021494Sopenharmony_ci } 1343b8021494Sopenharmony_ci 1344b8021494Sopenharmony_ci MacroAssembler* masm_; 1345b8021494Sopenharmony_ci Action action_; 1346b8021494Sopenharmony_ci CPURegister::RegisterType type_; 1347b8021494Sopenharmony_ci 1348b8021494Sopenharmony_ci RegList expected_; 1349b8021494Sopenharmony_ci RegList expected_v_; 1350b8021494Sopenharmony_ci RegList expected_p_; 1351b8021494Sopenharmony_ci}; 1352b8021494Sopenharmony_ci 1353b8021494Sopenharmony_ciTEST(scratch_scope_include) { 1354b8021494Sopenharmony_ci MacroAssembler masm; 1355b8021494Sopenharmony_ci { 1356b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1357b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1358b8021494Sopenharmony_ci ScratchScopeHelper::kInclude, 1359b8021494Sopenharmony_ci CPURegister::kRegister); 1360b8021494Sopenharmony_ci 1361b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be included. 1362b8021494Sopenharmony_ci temps.Include(w0); 1363b8021494Sopenharmony_ci temps.Include(x1); 1364b8021494Sopenharmony_ci temps.Include(WRegister(2)); 1365b8021494Sopenharmony_ci temps.Include(XRegister(3)); 1366b8021494Sopenharmony_ci temps.Include(Register(w4)); 1367b8021494Sopenharmony_ci temps.Include(Register(x5)); 1368b8021494Sopenharmony_ci temps.Include(CPURegister(w6)); 1369b8021494Sopenharmony_ci temps.Include(CPURegister(x7)); 1370b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0xff); 1371b8021494Sopenharmony_ci // Multiple registers can be included at once. 1372b8021494Sopenharmony_ci temps.Include(x8, w9, x10); 1373b8021494Sopenharmony_ci temps.Include(Register(w12), Register(x13), Register(w14)); 1374b8021494Sopenharmony_ci temps.Include(XRegister(16), XRegister(17), XRegister(18)); 1375b8021494Sopenharmony_ci temps.Include(WRegister(20), WRegister(21), WRegister(22)); 1376b8021494Sopenharmony_ci temps.Include(CPURegList(w24, w25, w26)); 1377b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x7777700); 1378b8021494Sopenharmony_ci // Including a register again has no effect. 1379b8021494Sopenharmony_ci temps.Include(Register(w26)); 1380b8021494Sopenharmony_ci temps.Include(Register(x25)); 1381b8021494Sopenharmony_ci temps.Include(CPURegister(x24)); 1382b8021494Sopenharmony_ci temps.Include(CPURegister(x22)); 1383b8021494Sopenharmony_ci temps.Include(x21, x20, w18, x17); 1384b8021494Sopenharmony_ci temps.Include(CPURegList(x16, x14, x13, x12)); 1385b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x7777700); 1386b8021494Sopenharmony_ci } 1387b8021494Sopenharmony_ci} 1388b8021494Sopenharmony_ci 1389b8021494Sopenharmony_ciTEST(scratch_scope_exclude) { 1390b8021494Sopenharmony_ci MacroAssembler masm; 1391b8021494Sopenharmony_ci { 1392b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1393b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1394b8021494Sopenharmony_ci ScratchScopeHelper::kExclude, 1395b8021494Sopenharmony_ci CPURegister::kRegister); 1396b8021494Sopenharmony_ci 1397b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be excluded. 1398b8021494Sopenharmony_ci temps.Exclude(w0); 1399b8021494Sopenharmony_ci temps.Exclude(x1); 1400b8021494Sopenharmony_ci temps.Exclude(WRegister(2)); 1401b8021494Sopenharmony_ci temps.Exclude(XRegister(3)); 1402b8021494Sopenharmony_ci temps.Exclude(Register(w4)); 1403b8021494Sopenharmony_ci temps.Exclude(Register(x5)); 1404b8021494Sopenharmony_ci temps.Exclude(CPURegister(w6)); 1405b8021494Sopenharmony_ci temps.Exclude(CPURegister(x7)); 1406b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0xff); 1407b8021494Sopenharmony_ci // Multiple registers can be excluded at once. 1408b8021494Sopenharmony_ci temps.Exclude(x8, w9, x10); 1409b8021494Sopenharmony_ci temps.Exclude(Register(w12), Register(x13), Register(w14)); 1410b8021494Sopenharmony_ci temps.Exclude(XRegister(16), XRegister(17), XRegister(18)); 1411b8021494Sopenharmony_ci temps.Exclude(WRegister(20), WRegister(21), WRegister(22)); 1412b8021494Sopenharmony_ci temps.Exclude(CPURegList(w24, w25, w26)); 1413b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x7777700); 1414b8021494Sopenharmony_ci // Excluding a register again has no effect. 1415b8021494Sopenharmony_ci temps.Exclude(Register(w26)); 1416b8021494Sopenharmony_ci temps.Exclude(Register(x25)); 1417b8021494Sopenharmony_ci temps.Exclude(CPURegister(x24)); 1418b8021494Sopenharmony_ci temps.Exclude(CPURegister(x22)); 1419b8021494Sopenharmony_ci temps.Exclude(x21, x20, w18, x17); 1420b8021494Sopenharmony_ci temps.Exclude(CPURegList(x16, x14, x13, x12)); 1421b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x7777700); 1422b8021494Sopenharmony_ci } 1423b8021494Sopenharmony_ci} 1424b8021494Sopenharmony_ci 1425b8021494Sopenharmony_ciTEST(scratch_scope_release) { 1426b8021494Sopenharmony_ci MacroAssembler masm; 1427b8021494Sopenharmony_ci { 1428b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1429b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1430b8021494Sopenharmony_ci ScratchScopeHelper::kRelease, 1431b8021494Sopenharmony_ci CPURegister::kRegister); 1432b8021494Sopenharmony_ci 1433b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be released. 1434b8021494Sopenharmony_ci temps.Release(w0); 1435b8021494Sopenharmony_ci temps.Release(x1); 1436b8021494Sopenharmony_ci temps.Release(WRegister(2)); 1437b8021494Sopenharmony_ci temps.Release(XRegister(3)); 1438b8021494Sopenharmony_ci temps.Release(Register(w4)); 1439b8021494Sopenharmony_ci temps.Release(Register(x5)); 1440b8021494Sopenharmony_ci temps.Release(CPURegister(w6)); 1441b8021494Sopenharmony_ci temps.Release(CPURegister(x7)); 1442b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0xff); 1443b8021494Sopenharmony_ci // It is not possible to release more than one register at a time, and it is 1444b8021494Sopenharmony_ci // invalid to release a register that is already available. 1445b8021494Sopenharmony_ci } 1446b8021494Sopenharmony_ci} 1447b8021494Sopenharmony_ci 1448b8021494Sopenharmony_ciTEST(scratch_scope_include_v) { 1449b8021494Sopenharmony_ci MacroAssembler masm; 1450b8021494Sopenharmony_ci { 1451b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1452b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1453b8021494Sopenharmony_ci ScratchScopeHelper::kInclude, 1454b8021494Sopenharmony_ci CPURegister::kVRegister); 1455b8021494Sopenharmony_ci 1456b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be included. 1457b8021494Sopenharmony_ci temps.Include(b0); 1458b8021494Sopenharmony_ci temps.Include(h1); 1459b8021494Sopenharmony_ci temps.Include(SRegister(2)); 1460b8021494Sopenharmony_ci temps.Include(DRegister(3)); 1461b8021494Sopenharmony_ci temps.Include(VRegister(q4)); 1462b8021494Sopenharmony_ci temps.Include(VRegister(v5.V8B())); 1463b8021494Sopenharmony_ci temps.Include(CPURegister(d6)); 1464b8021494Sopenharmony_ci temps.Include(CPURegister(v7.S4B())); 1465b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0xff); 1466b8021494Sopenharmony_ci // Multiple registers can be included at once. 1467b8021494Sopenharmony_ci temps.Include(b8, h9, s10); 1468b8021494Sopenharmony_ci temps.Include(VRegister(d12), VRegister(d13), VRegister(d14)); 1469b8021494Sopenharmony_ci temps.Include(QRegister(16), QRegister(17), QRegister(18)); 1470b8021494Sopenharmony_ci temps.Include(BRegister(20), BRegister(21), BRegister(22)); 1471b8021494Sopenharmony_ci temps.Include(CPURegList(s24, s25, s26)); 1472b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x7777700); 1473b8021494Sopenharmony_ci // Including a register again has no effect. 1474b8021494Sopenharmony_ci temps.Include(VRegister(b26)); 1475b8021494Sopenharmony_ci temps.Include(VRegister(h25)); 1476b8021494Sopenharmony_ci temps.Include(CPURegister(s24)); 1477b8021494Sopenharmony_ci temps.Include(CPURegister(v22.V4H())); 1478b8021494Sopenharmony_ci temps.Include(q21, d20, s18, h17); 1479b8021494Sopenharmony_ci temps.Include(CPURegList(h16, h14, h13, h12)); 1480b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x7777700); 1481b8021494Sopenharmony_ci } 1482b8021494Sopenharmony_ci} 1483b8021494Sopenharmony_ci 1484b8021494Sopenharmony_ciTEST(scratch_scope_exclude_v) { 1485b8021494Sopenharmony_ci MacroAssembler masm; 1486b8021494Sopenharmony_ci { 1487b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1488b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1489b8021494Sopenharmony_ci ScratchScopeHelper::kExclude, 1490b8021494Sopenharmony_ci CPURegister::kVRegister); 1491b8021494Sopenharmony_ci 1492b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be excluded. 1493b8021494Sopenharmony_ci temps.Exclude(b0); 1494b8021494Sopenharmony_ci temps.Exclude(h1); 1495b8021494Sopenharmony_ci temps.Exclude(SRegister(2)); 1496b8021494Sopenharmony_ci temps.Exclude(DRegister(3)); 1497b8021494Sopenharmony_ci temps.Exclude(VRegister(q4)); 1498b8021494Sopenharmony_ci temps.Exclude(VRegister(v5.V8B())); 1499b8021494Sopenharmony_ci temps.Exclude(CPURegister(d6)); 1500b8021494Sopenharmony_ci temps.Exclude(CPURegister(v7.S4B())); 1501b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0xff); 1502b8021494Sopenharmony_ci // Multiple registers can be excluded at once. 1503b8021494Sopenharmony_ci temps.Exclude(b8, h9, s10); 1504b8021494Sopenharmony_ci temps.Exclude(VRegister(d12), VRegister(d13), VRegister(d14)); 1505b8021494Sopenharmony_ci temps.Exclude(QRegister(16), QRegister(17), QRegister(18)); 1506b8021494Sopenharmony_ci temps.Exclude(BRegister(20), BRegister(21), BRegister(22)); 1507b8021494Sopenharmony_ci temps.Exclude(CPURegList(s24, s25, s26)); 1508b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x7777700); 1509b8021494Sopenharmony_ci // Excluding a register again has no effect. 1510b8021494Sopenharmony_ci temps.Exclude(VRegister(b26)); 1511b8021494Sopenharmony_ci temps.Exclude(VRegister(h25)); 1512b8021494Sopenharmony_ci temps.Exclude(CPURegister(s24)); 1513b8021494Sopenharmony_ci temps.Exclude(CPURegister(v22.V4H())); 1514b8021494Sopenharmony_ci temps.Exclude(q21, d20, s18, h17); 1515b8021494Sopenharmony_ci temps.Exclude(CPURegList(h16, h14, h13, h12)); 1516b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x7777700); 1517b8021494Sopenharmony_ci } 1518b8021494Sopenharmony_ci} 1519b8021494Sopenharmony_ci 1520b8021494Sopenharmony_ciTEST(scratch_scope_release_v) { 1521b8021494Sopenharmony_ci MacroAssembler masm; 1522b8021494Sopenharmony_ci { 1523b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1524b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1525b8021494Sopenharmony_ci ScratchScopeHelper::kRelease, 1526b8021494Sopenharmony_ci CPURegister::kVRegister); 1527b8021494Sopenharmony_ci 1528b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be released. 1529b8021494Sopenharmony_ci temps.Release(b0); 1530b8021494Sopenharmony_ci temps.Release(h1); 1531b8021494Sopenharmony_ci temps.Release(SRegister(2)); 1532b8021494Sopenharmony_ci temps.Release(DRegister(3)); 1533b8021494Sopenharmony_ci temps.Release(VRegister(q4)); 1534b8021494Sopenharmony_ci temps.Release(VRegister(v5.V8B())); 1535b8021494Sopenharmony_ci temps.Release(CPURegister(d6)); 1536b8021494Sopenharmony_ci temps.Release(CPURegister(v7.S4B())); 1537b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0xff); 1538b8021494Sopenharmony_ci // It is not possible to release more than one register at a time, and it is 1539b8021494Sopenharmony_ci // invalid to release a register that is already available. 1540b8021494Sopenharmony_ci } 1541b8021494Sopenharmony_ci} 1542b8021494Sopenharmony_ci 1543b8021494Sopenharmony_ciTEST(scratch_scope_include_z) { 1544b8021494Sopenharmony_ci MacroAssembler masm; 1545b8021494Sopenharmony_ci { 1546b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1547b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1548b8021494Sopenharmony_ci ScratchScopeHelper::kInclude, 1549b8021494Sopenharmony_ci CPURegister::kZRegister); 1550b8021494Sopenharmony_ci 1551b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be included. 1552b8021494Sopenharmony_ci temps.Include(z0); 1553b8021494Sopenharmony_ci temps.Include(z1.VnB()); 1554b8021494Sopenharmony_ci temps.Include(ZRegister(2)); 1555b8021494Sopenharmony_ci temps.Include(ZRegister(3, kFormatVnD)); 1556b8021494Sopenharmony_ci temps.Include(CPURegister(z4)); 1557b8021494Sopenharmony_ci temps.Include(CPURegister(z5.VnH())); 1558b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x3f); 1559b8021494Sopenharmony_ci // Multiple registers can be included at once. 1560b8021494Sopenharmony_ci temps.Include(z8, z9, z10.VnS()); 1561b8021494Sopenharmony_ci temps.Include(ZRegister(12), ZRegister(13, kHRegSize), z14); 1562b8021494Sopenharmony_ci temps.Include(CPURegList(z16, z17, z18)); 1563b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x77700); 1564b8021494Sopenharmony_ci // Including a register again has no effect. 1565b8021494Sopenharmony_ci temps.Include(ZRegister(18)); 1566b8021494Sopenharmony_ci temps.Include(ZRegister(17, kFormatVnB)); 1567b8021494Sopenharmony_ci temps.Include(CPURegister(z16)); 1568b8021494Sopenharmony_ci temps.Include(CPURegister(z13.VnD())); 1569b8021494Sopenharmony_ci temps.Include(z12, z10, z9.VnB(), z8); 1570b8021494Sopenharmony_ci temps.Include(CPURegList(z5, z4, z3, z2)); 1571b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x77700); 1572b8021494Sopenharmony_ci } 1573b8021494Sopenharmony_ci} 1574b8021494Sopenharmony_ci 1575b8021494Sopenharmony_ciTEST(scratch_scope_exclude_z) { 1576b8021494Sopenharmony_ci MacroAssembler masm; 1577b8021494Sopenharmony_ci { 1578b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1579b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1580b8021494Sopenharmony_ci ScratchScopeHelper::kExclude, 1581b8021494Sopenharmony_ci CPURegister::kZRegister); 1582b8021494Sopenharmony_ci 1583b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be excluded. 1584b8021494Sopenharmony_ci temps.Exclude(z0); 1585b8021494Sopenharmony_ci temps.Exclude(z1.VnB()); 1586b8021494Sopenharmony_ci temps.Exclude(ZRegister(2)); 1587b8021494Sopenharmony_ci temps.Exclude(ZRegister(3, kFormatVnD)); 1588b8021494Sopenharmony_ci temps.Exclude(CPURegister(z4)); 1589b8021494Sopenharmony_ci temps.Exclude(CPURegister(z5.VnH())); 1590b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x3f); 1591b8021494Sopenharmony_ci // Multiple registers can be excluded at once. 1592b8021494Sopenharmony_ci temps.Exclude(z8, z9, z10.VnS()); 1593b8021494Sopenharmony_ci temps.Exclude(ZRegister(12), ZRegister(13, kHRegSize), z14); 1594b8021494Sopenharmony_ci temps.Exclude(CPURegList(z16, z17, z18)); 1595b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x77700); 1596b8021494Sopenharmony_ci // Excluding a register again has no effect. 1597b8021494Sopenharmony_ci temps.Exclude(ZRegister(18)); 1598b8021494Sopenharmony_ci temps.Exclude(ZRegister(17, kFormatVnB)); 1599b8021494Sopenharmony_ci temps.Exclude(CPURegister(z16)); 1600b8021494Sopenharmony_ci temps.Exclude(CPURegister(z13.VnD())); 1601b8021494Sopenharmony_ci temps.Exclude(z12, z10, z9.VnB(), z8); 1602b8021494Sopenharmony_ci temps.Exclude(CPURegList(z5, z4, z3, z2)); 1603b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x77700); 1604b8021494Sopenharmony_ci } 1605b8021494Sopenharmony_ci} 1606b8021494Sopenharmony_ci 1607b8021494Sopenharmony_ciTEST(scratch_scope_release_z) { 1608b8021494Sopenharmony_ci MacroAssembler masm; 1609b8021494Sopenharmony_ci { 1610b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1611b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1612b8021494Sopenharmony_ci ScratchScopeHelper::kRelease, 1613b8021494Sopenharmony_ci CPURegister::kZRegister); 1614b8021494Sopenharmony_ci 1615b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be released. 1616b8021494Sopenharmony_ci temps.Release(z0); 1617b8021494Sopenharmony_ci temps.Release(z1.VnB()); 1618b8021494Sopenharmony_ci temps.Release(ZRegister(2)); 1619b8021494Sopenharmony_ci temps.Release(ZRegister(3, kFormatVnD)); 1620b8021494Sopenharmony_ci temps.Release(CPURegister(z4)); 1621b8021494Sopenharmony_ci temps.Release(CPURegister(z5.VnH())); 1622b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x3f); 1623b8021494Sopenharmony_ci // It is not possible to release more than one register at a time, and it is 1624b8021494Sopenharmony_ci // invalid to release a register that is already available. 1625b8021494Sopenharmony_ci } 1626b8021494Sopenharmony_ci} 1627b8021494Sopenharmony_ci 1628b8021494Sopenharmony_ciTEST(scratch_scope_include_p) { 1629b8021494Sopenharmony_ci MacroAssembler masm; 1630b8021494Sopenharmony_ci { 1631b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1632b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1633b8021494Sopenharmony_ci ScratchScopeHelper::kInclude, 1634b8021494Sopenharmony_ci CPURegister::kPRegister); 1635b8021494Sopenharmony_ci 1636b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be included. 1637b8021494Sopenharmony_ci temps.Include(p0); 1638b8021494Sopenharmony_ci temps.Include(PRegister(1)); 1639b8021494Sopenharmony_ci temps.Include(PRegisterWithLaneSize(2, kFormatVnD)); 1640b8021494Sopenharmony_ci temps.Include(PRegisterM(3)); 1641b8021494Sopenharmony_ci temps.Include(CPURegister(PRegister(4))); 1642b8021494Sopenharmony_ci temps.Include(CPURegister(PRegisterZ(5))); 1643b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x3f); 1644b8021494Sopenharmony_ci // Multiple registers can be included at once. 1645b8021494Sopenharmony_ci temps.Include(p7, p8.Merging(), p9.VnS()); 1646b8021494Sopenharmony_ci temps.Include(PRegister(11), PRegisterWithLaneSize(12, kHRegSize)); 1647b8021494Sopenharmony_ci temps.Include(CPURegList(p15)); 1648b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x9b80); 1649b8021494Sopenharmony_ci // Including a register again has no effect. 1650b8021494Sopenharmony_ci temps.Include(PRegister(15)); 1651b8021494Sopenharmony_ci temps.Include(PRegisterWithLaneSize(12, kFormatVnB)); 1652b8021494Sopenharmony_ci temps.Include(CPURegister(p11)); 1653b8021494Sopenharmony_ci temps.Include(CPURegister(p9.VnD())); 1654b8021494Sopenharmony_ci temps.Include(p8.Merging(), p7.Zeroing(), p5.VnB(), p4); 1655b8021494Sopenharmony_ci temps.Include(CPURegList(p3, p2, p1, p0)); 1656b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x9b80); 1657b8021494Sopenharmony_ci } 1658b8021494Sopenharmony_ci} 1659b8021494Sopenharmony_ci 1660b8021494Sopenharmony_ciTEST(scratch_scope_exclude_p) { 1661b8021494Sopenharmony_ci MacroAssembler masm; 1662b8021494Sopenharmony_ci { 1663b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1664b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1665b8021494Sopenharmony_ci ScratchScopeHelper::kExclude, 1666b8021494Sopenharmony_ci CPURegister::kPRegister); 1667b8021494Sopenharmony_ci 1668b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be excluded. 1669b8021494Sopenharmony_ci temps.Exclude(p0); 1670b8021494Sopenharmony_ci temps.Exclude(PRegister(1)); 1671b8021494Sopenharmony_ci temps.Exclude(PRegisterWithLaneSize(2, kFormatVnD)); 1672b8021494Sopenharmony_ci temps.Exclude(PRegisterM(3)); 1673b8021494Sopenharmony_ci temps.Exclude(CPURegister(PRegister(4))); 1674b8021494Sopenharmony_ci temps.Exclude(CPURegister(PRegisterZ(5))); 1675b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x3f); 1676b8021494Sopenharmony_ci // Multiple registers can be excluded at once. 1677b8021494Sopenharmony_ci temps.Exclude(p7, p8.Merging(), p9.VnS()); 1678b8021494Sopenharmony_ci temps.Exclude(PRegister(11), PRegisterWithLaneSize(12, kHRegSize)); 1679b8021494Sopenharmony_ci temps.Exclude(CPURegList(p15)); 1680b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x9b80); 1681b8021494Sopenharmony_ci // Excluding a register again has no effect. 1682b8021494Sopenharmony_ci temps.Exclude(PRegister(15)); 1683b8021494Sopenharmony_ci temps.Exclude(PRegisterWithLaneSize(12, kFormatVnB)); 1684b8021494Sopenharmony_ci temps.Exclude(CPURegister(p11)); 1685b8021494Sopenharmony_ci temps.Exclude(CPURegister(p9.VnD())); 1686b8021494Sopenharmony_ci temps.Exclude(p8.Merging(), p7.Zeroing(), p5.VnB(), p4); 1687b8021494Sopenharmony_ci temps.Exclude(CPURegList(p3, p2, p1, p0)); 1688b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x9b80); 1689b8021494Sopenharmony_ci } 1690b8021494Sopenharmony_ci} 1691b8021494Sopenharmony_ci 1692b8021494Sopenharmony_ciTEST(scratch_scope_release_p) { 1693b8021494Sopenharmony_ci MacroAssembler masm; 1694b8021494Sopenharmony_ci { 1695b8021494Sopenharmony_ci UseScratchRegisterScope temps(&masm); 1696b8021494Sopenharmony_ci ScratchScopeHelper helper(&masm, 1697b8021494Sopenharmony_ci ScratchScopeHelper::kRelease, 1698b8021494Sopenharmony_ci CPURegister::kPRegister); 1699b8021494Sopenharmony_ci 1700b8021494Sopenharmony_ci // Any suitable register type deriving from CPURegister can be excluded. 1701b8021494Sopenharmony_ci temps.Release(p0); 1702b8021494Sopenharmony_ci temps.Release(PRegister(1)); 1703b8021494Sopenharmony_ci temps.Release(PRegisterWithLaneSize(2, kFormatVnD)); 1704b8021494Sopenharmony_ci temps.Release(PRegisterM(3)); 1705b8021494Sopenharmony_ci temps.Release(CPURegister(PRegister(4))); 1706b8021494Sopenharmony_ci temps.Release(CPURegister(PRegisterZ(5))); 1707b8021494Sopenharmony_ci helper.RecordActionsAndCheck(0x3f); 1708b8021494Sopenharmony_ci // It is not possible to release more than one register at a time, and it is 1709b8021494Sopenharmony_ci // invalid to release a register that is already available. 1710b8021494Sopenharmony_ci } 1711b8021494Sopenharmony_ci} 1712b8021494Sopenharmony_ci 1713b8021494Sopenharmony_ci#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 1714b8021494Sopenharmony_ciTEST(sim_stack_default) { 1715b8021494Sopenharmony_ci SimStack::Allocated s = SimStack().Allocate(); 1716b8021494Sopenharmony_ci 1717b8021494Sopenharmony_ci // The default stack is at least 16-byte aligned. 1718b8021494Sopenharmony_ci VIXL_CHECK(IsAligned<16>(s.GetBase())); 1719b8021494Sopenharmony_ci VIXL_CHECK(IsAligned<16>(s.GetLimit() + 1)); 1720b8021494Sopenharmony_ci 1721b8021494Sopenharmony_ci VIXL_CHECK(s.GetBase() > s.GetLimit()); 1722b8021494Sopenharmony_ci 1723b8021494Sopenharmony_ci // The default guard regions are sufficient to detect at least off-by-one 1724b8021494Sopenharmony_ci // errors. 1725b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetBase(), 1)); 1726b8021494Sopenharmony_ci VIXL_CHECK(!s.IsAccessInGuardRegion(s.GetBase() - 1, 1)); 1727b8021494Sopenharmony_ci // The limit is one below the lowest address on the stack. 1728b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetLimit(), 1)); 1729b8021494Sopenharmony_ci VIXL_CHECK(!s.IsAccessInGuardRegion(s.GetLimit() + 1, 1)); 1730b8021494Sopenharmony_ci 1731b8021494Sopenharmony_ci // We need to be able to access 16-byte granules at both extremes. 1732b8021494Sopenharmony_ci VIXL_CHECK(!s.IsAccessInGuardRegion(s.GetBase() - 16, 16)); 1733b8021494Sopenharmony_ci VIXL_CHECK(!s.IsAccessInGuardRegion(s.GetLimit() + 1, 16)); 1734b8021494Sopenharmony_ci} 1735b8021494Sopenharmony_ci 1736b8021494Sopenharmony_ciTEST(sim_stack) { 1737b8021494Sopenharmony_ci SimStack builder; 1738b8021494Sopenharmony_ci builder.AlignToBytesLog2(WhichPowerOf2(1024)); 1739b8021494Sopenharmony_ci builder.SetBaseGuardSize(42); 1740b8021494Sopenharmony_ci builder.SetLimitGuardSize(2049); 1741b8021494Sopenharmony_ci builder.SetUsableSize(2048); 1742b8021494Sopenharmony_ci SimStack::Allocated s = builder.Allocate(); 1743b8021494Sopenharmony_ci 1744b8021494Sopenharmony_ci VIXL_CHECK(IsAligned<1024>(s.GetBase())); 1745b8021494Sopenharmony_ci VIXL_CHECK(IsAligned<1024>(s.GetLimit() + 1)); 1746b8021494Sopenharmony_ci 1747b8021494Sopenharmony_ci // The stack is accessible for (limit, base), both exclusive. 1748b8021494Sopenharmony_ci // This is checked precisely, using the base and limit modified to respect 1749b8021494Sopenharmony_ci // alignment, so we can test the exact boundary condition. 1750b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetBase(), 1)); 1751b8021494Sopenharmony_ci VIXL_CHECK(!s.IsAccessInGuardRegion(s.GetBase() - 1, 1)); 1752b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetLimit(), 1)); 1753b8021494Sopenharmony_ci VIXL_CHECK(!s.IsAccessInGuardRegion(s.GetLimit() + 1, 1)); 1754b8021494Sopenharmony_ci VIXL_CHECK((s.GetBase() - s.GetLimit() - 1) == 2048); 1755b8021494Sopenharmony_ci 1756b8021494Sopenharmony_ci // We can access the whole range (limit, base), both exclusive. 1757b8021494Sopenharmony_ci VIXL_CHECK(!s.IsAccessInGuardRegion(s.GetLimit() + 1, 2048)); 1758b8021494Sopenharmony_ci // Off-by-one. 1759b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetLimit(), 2048)); 1760b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetLimit() + 1, 2049)); 1761b8021494Sopenharmony_ci // Accesses spanning whole guard regions. 1762b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetBase() - 42, 4096)); 1763b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetLimit() - 1280, 2048)); 1764b8021494Sopenharmony_ci VIXL_CHECK(s.IsAccessInGuardRegion(s.GetLimit() - 1280, 10000)); 1765b8021494Sopenharmony_ci} 1766b8021494Sopenharmony_ci#endif 1767b8021494Sopenharmony_ci 1768b8021494Sopenharmony_ci} // namespace aarch64 1769b8021494Sopenharmony_ci} // namespace vixl 1770