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