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