1 // Copyright 2017, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright notice,
8 // this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright notice,
10 // this list of conditions and the following disclaimer in the documentation
11 // and/or other materials provided with the distribution.
12 // * Neither the name of ARM Limited nor the names of its contributors may be
13 // used to endorse or promote products derived from this software without
14 // specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 #include <cstdio>
28 #include <cstring>
29 #include <string>
30
31 #include "test-runner.h"
32 #include "test-utils.h"
33 #include "aarch64/test-utils-aarch64.h"
34
35 #include "aarch64/macro-assembler-aarch64.h"
36
37 #define __ masm.
38 #define TEST(name) TEST_(AARCH64_API_##name)
39
40
41 namespace vixl {
42 namespace aarch64 {
43
44
TEST(register_bit)45 TEST(register_bit) {
46 VIXL_CHECK(x0.GetBit() == (UINT64_C(1) << 0));
47 VIXL_CHECK(x1.GetBit() == (UINT64_C(1) << 1));
48 VIXL_CHECK(x10.GetBit() == (UINT64_C(1) << 10));
49
50 // AAPCS64 definitions.
51 VIXL_CHECK(lr.GetBit() == (UINT64_C(1) << kLinkRegCode));
52
53 // Fixed (hardware) definitions.
54 VIXL_CHECK(xzr.GetBit() == (UINT64_C(1) << kZeroRegCode));
55
56 // Internal ABI definitions.
57 VIXL_CHECK(sp.GetBit() == (UINT64_C(1) << kSPRegInternalCode));
58 VIXL_CHECK(sp.GetBit() != xzr.GetBit());
59
60 // xn.GetBit() == wn.GetBit() at all times, for the same n.
61 VIXL_CHECK(x0.GetBit() == w0.GetBit());
62 VIXL_CHECK(x1.GetBit() == w1.GetBit());
63 VIXL_CHECK(x10.GetBit() == w10.GetBit());
64 VIXL_CHECK(xzr.GetBit() == wzr.GetBit());
65 VIXL_CHECK(sp.GetBit() == wsp.GetBit());
66 }
67
68
TEST(noreg)69 TEST(noreg) {
70 VIXL_CHECK(NoReg.Is(NoFPReg));
71 VIXL_CHECK(NoFPReg.Is(NoReg));
72
73 VIXL_CHECK(NoVReg.Is(NoReg));
74 VIXL_CHECK(NoReg.Is(NoVReg));
75
76 VIXL_CHECK(NoReg.Is(NoCPUReg));
77 VIXL_CHECK(NoCPUReg.Is(NoReg));
78
79 VIXL_CHECK(NoFPReg.Is(NoCPUReg));
80 VIXL_CHECK(NoCPUReg.Is(NoFPReg));
81
82 VIXL_CHECK(NoVReg.Is(NoCPUReg));
83 VIXL_CHECK(NoCPUReg.Is(NoVReg));
84
85 VIXL_CHECK(NoReg.IsNone());
86 VIXL_CHECK(NoFPReg.IsNone());
87 VIXL_CHECK(NoVReg.IsNone());
88 VIXL_CHECK(NoCPUReg.IsNone());
89 }
90
91
TEST(isvalid)92 TEST(isvalid) {
93 VIXL_CHECK(!NoReg.IsValid());
94 VIXL_CHECK(!NoFPReg.IsValid());
95 VIXL_CHECK(!NoVReg.IsValid());
96 VIXL_CHECK(!NoCPUReg.IsValid());
97
98 VIXL_CHECK(x0.IsValid());
99 VIXL_CHECK(w0.IsValid());
100 VIXL_CHECK(x30.IsValid());
101 VIXL_CHECK(w30.IsValid());
102 VIXL_CHECK(xzr.IsValid());
103 VIXL_CHECK(wzr.IsValid());
104
105 VIXL_CHECK(sp.IsValid());
106 VIXL_CHECK(wsp.IsValid());
107
108 VIXL_CHECK(d0.IsValid());
109 VIXL_CHECK(s0.IsValid());
110 VIXL_CHECK(d31.IsValid());
111 VIXL_CHECK(s31.IsValid());
112
113 VIXL_CHECK(x0.IsValidRegister());
114 VIXL_CHECK(w0.IsValidRegister());
115 VIXL_CHECK(xzr.IsValidRegister());
116 VIXL_CHECK(wzr.IsValidRegister());
117 VIXL_CHECK(sp.IsValidRegister());
118 VIXL_CHECK(wsp.IsValidRegister());
119 VIXL_CHECK(!x0.IsValidFPRegister());
120 VIXL_CHECK(!w0.IsValidFPRegister());
121 VIXL_CHECK(!xzr.IsValidFPRegister());
122 VIXL_CHECK(!wzr.IsValidFPRegister());
123 VIXL_CHECK(!sp.IsValidFPRegister());
124 VIXL_CHECK(!wsp.IsValidFPRegister());
125
126 VIXL_CHECK(d0.IsValidFPRegister());
127 VIXL_CHECK(s0.IsValidFPRegister());
128 VIXL_CHECK(!d0.IsValidRegister());
129 VIXL_CHECK(!s0.IsValidRegister());
130
131 // Test the same as before, but using CPURegister types. This shouldn't make
132 // any difference.
133 VIXL_CHECK(static_cast<CPURegister>(x0).IsValid());
134 VIXL_CHECK(static_cast<CPURegister>(w0).IsValid());
135 VIXL_CHECK(static_cast<CPURegister>(x30).IsValid());
136 VIXL_CHECK(static_cast<CPURegister>(w30).IsValid());
137 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValid());
138 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValid());
139
140 VIXL_CHECK(static_cast<CPURegister>(sp).IsValid());
141 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValid());
142
143 VIXL_CHECK(static_cast<CPURegister>(d0).IsValid());
144 VIXL_CHECK(static_cast<CPURegister>(s0).IsValid());
145 VIXL_CHECK(static_cast<CPURegister>(d31).IsValid());
146 VIXL_CHECK(static_cast<CPURegister>(s31).IsValid());
147
148 VIXL_CHECK(static_cast<CPURegister>(x0).IsValidRegister());
149 VIXL_CHECK(static_cast<CPURegister>(w0).IsValidRegister());
150 VIXL_CHECK(static_cast<CPURegister>(xzr).IsValidRegister());
151 VIXL_CHECK(static_cast<CPURegister>(wzr).IsValidRegister());
152 VIXL_CHECK(static_cast<CPURegister>(sp).IsValidRegister());
153 VIXL_CHECK(static_cast<CPURegister>(wsp).IsValidRegister());
154 VIXL_CHECK(!static_cast<CPURegister>(x0).IsValidFPRegister());
155 VIXL_CHECK(!static_cast<CPURegister>(w0).IsValidFPRegister());
156 VIXL_CHECK(!static_cast<CPURegister>(xzr).IsValidFPRegister());
157 VIXL_CHECK(!static_cast<CPURegister>(wzr).IsValidFPRegister());
158 VIXL_CHECK(!static_cast<CPURegister>(sp).IsValidFPRegister());
159 VIXL_CHECK(!static_cast<CPURegister>(wsp).IsValidFPRegister());
160
161 VIXL_CHECK(static_cast<CPURegister>(d0).IsValidFPRegister());
162 VIXL_CHECK(static_cast<CPURegister>(s0).IsValidFPRegister());
163 VIXL_CHECK(!static_cast<CPURegister>(d0).IsValidRegister());
164 VIXL_CHECK(!static_cast<CPURegister>(s0).IsValidRegister());
165 }
166
167
TEST(areconsecutive)168 TEST(areconsecutive) {
169 VIXL_CHECK(AreConsecutive(b0, NoVReg));
170 VIXL_CHECK(AreConsecutive(b1, b2));
171 VIXL_CHECK(AreConsecutive(b3, b4, b5));
172 VIXL_CHECK(AreConsecutive(b6, b7, b8, b9));
173 VIXL_CHECK(AreConsecutive(h10, NoVReg));
174 VIXL_CHECK(AreConsecutive(h11, h12));
175 VIXL_CHECK(AreConsecutive(h13, h14, h15));
176 VIXL_CHECK(AreConsecutive(h16, h17, h18, h19));
177 VIXL_CHECK(AreConsecutive(s20, NoVReg));
178 VIXL_CHECK(AreConsecutive(s21, s22));
179 VIXL_CHECK(AreConsecutive(s23, s24, s25));
180 VIXL_CHECK(AreConsecutive(s26, s27, s28, s29));
181 VIXL_CHECK(AreConsecutive(d30, NoVReg));
182 VIXL_CHECK(AreConsecutive(d31, d0));
183 VIXL_CHECK(AreConsecutive(d1, d2, d3));
184 VIXL_CHECK(AreConsecutive(d4, d5, d6, d7));
185 VIXL_CHECK(AreConsecutive(q8, NoVReg));
186 VIXL_CHECK(AreConsecutive(q9, q10));
187 VIXL_CHECK(AreConsecutive(q11, q12, q13));
188 VIXL_CHECK(AreConsecutive(q14, q15, q16, q17));
189 VIXL_CHECK(AreConsecutive(v18, NoVReg));
190 VIXL_CHECK(AreConsecutive(v19, v20));
191 VIXL_CHECK(AreConsecutive(v21, v22, v23));
192 VIXL_CHECK(AreConsecutive(v24, v25, v26, v27));
193 VIXL_CHECK(AreConsecutive(b29, h30));
194 VIXL_CHECK(AreConsecutive(s31, d0, q1));
195 VIXL_CHECK(AreConsecutive(v2, b3, h4, s5));
196
197 VIXL_CHECK(!AreConsecutive(b0, b2));
198 VIXL_CHECK(!AreConsecutive(h1, h0));
199 VIXL_CHECK(!AreConsecutive(s31, s1));
200 VIXL_CHECK(!AreConsecutive(d12, d12));
201 VIXL_CHECK(!AreConsecutive(q31, q1));
202
203 VIXL_CHECK(!AreConsecutive(b0, b1, b3));
204 VIXL_CHECK(!AreConsecutive(h4, h5, h6, h6));
205 VIXL_CHECK(!AreConsecutive(d11, d13, NoVReg, d14));
206 VIXL_CHECK(!AreConsecutive(d15, d16, d18, NoVReg));
207 VIXL_CHECK(!AreConsecutive(b26, b28, NoVReg, b29));
208 VIXL_CHECK(!AreConsecutive(s28, s30, NoVReg, NoVReg));
209
210 VIXL_CHECK(AreConsecutive(q19, NoVReg, NoVReg, q22));
211 VIXL_CHECK(AreConsecutive(v23, NoVReg, v25, NoVReg));
212 VIXL_CHECK(AreConsecutive(b26, b27, NoVReg, NoVReg));
213 VIXL_CHECK(AreConsecutive(h28, NoVReg, NoVReg, NoVReg));
214 VIXL_CHECK(AreConsecutive(s30, s31, NoVReg, s2));
215 VIXL_CHECK(AreConsecutive(d3, NoVReg, d6, d7));
216 }
217
218
TEST(move_immediate_helpers)219 TEST(move_immediate_helpers) {
220 // Using these helpers to query information (without generating code) should
221 // not crash.
222 MacroAssembler::MoveImmediateHelper(NULL, x0, 0x12345678);
223 MacroAssembler::OneInstrMoveImmediateHelper(NULL, x1, 0xabcdef);
224 }
225
226
TEST(generic_operand_helpers)227 TEST(generic_operand_helpers) {
228 GenericOperand invalid_1;
229 GenericOperand invalid_2;
230 GenericOperand reg(x3);
231 GenericOperand mem(MemOperand(sp, 8), kXRegSizeInBytes);
232
233 VIXL_CHECK(!invalid_1.IsValid());
234 VIXL_CHECK(!invalid_2.IsValid());
235
236 VIXL_CHECK(invalid_1.Equals(invalid_1));
237 VIXL_CHECK(invalid_2.Equals(invalid_2));
238 VIXL_CHECK(reg.Equals(reg));
239 VIXL_CHECK(mem.Equals(mem));
240
241 VIXL_CHECK(invalid_1.Equals(invalid_2));
242 VIXL_CHECK(invalid_2.Equals(invalid_1));
243
244 VIXL_CHECK(!invalid_1.Equals(reg));
245 VIXL_CHECK(!invalid_1.Equals(mem));
246 VIXL_CHECK(!reg.Equals(invalid_1));
247 VIXL_CHECK(!reg.Equals(invalid_2));
248 VIXL_CHECK(!reg.Equals(mem));
249 VIXL_CHECK(!mem.Equals(invalid_1));
250 VIXL_CHECK(!mem.Equals(reg));
251 }
252
253
TEST(static_register_types)254 TEST(static_register_types) {
255 // [WX]Register implicitly casts to Register.
256 XRegister x_x0(0);
257 WRegister w_w0(0);
258 Register r_x0 = x_x0;
259 Register r_w0 = w_w0;
260 VIXL_CHECK(r_x0.Is(x_x0));
261 VIXL_CHECK(x_x0.Is(r_x0));
262 VIXL_CHECK(r_w0.Is(w_w0));
263 VIXL_CHECK(w_w0.Is(r_w0));
264
265 // Register explicitly casts to [WX]Register.
266 Register r_x1(1, kXRegSize);
267 Register r_w1(1, kWRegSize);
268 XRegister x_x1(r_x1);
269 WRegister w_w1(r_w1);
270 VIXL_CHECK(r_x1.Is(x_x1));
271 VIXL_CHECK(x_x1.Is(r_x1));
272 VIXL_CHECK(r_w1.Is(w_w1));
273 VIXL_CHECK(w_w1.Is(r_w1));
274
275 // [WX]Register implicitly casts to CPURegister.
276 XRegister x_x2(2);
277 WRegister w_w2(2);
278 CPURegister cpu_x2 = x_x2;
279 CPURegister cpu_w2 = w_w2;
280 VIXL_CHECK(cpu_x2.Is(x_x2));
281 VIXL_CHECK(x_x2.Is(cpu_x2));
282 VIXL_CHECK(cpu_w2.Is(w_w2));
283 VIXL_CHECK(w_w2.Is(cpu_w2));
284 }
285
286
TEST(is_plain_register)287 TEST(is_plain_register) {
288 VIXL_CHECK(Operand(x0).IsPlainRegister());
289 VIXL_CHECK(Operand(x1, LSL, 0).IsPlainRegister());
290 VIXL_CHECK(Operand(x2, LSR, 0).IsPlainRegister());
291 VIXL_CHECK(Operand(x3, ASR, 0).IsPlainRegister());
292 VIXL_CHECK(Operand(x4, ROR, 0).IsPlainRegister());
293 VIXL_CHECK(Operand(x5, UXTX).IsPlainRegister());
294 VIXL_CHECK(Operand(x6, SXTX).IsPlainRegister());
295 VIXL_CHECK(Operand(w7).IsPlainRegister());
296 VIXL_CHECK(Operand(w8, LSL, 0).IsPlainRegister());
297 VIXL_CHECK(Operand(w9, LSR, 0).IsPlainRegister());
298 VIXL_CHECK(Operand(w10, ASR, 0).IsPlainRegister());
299 VIXL_CHECK(Operand(w11, ROR, 0).IsPlainRegister());
300
301 VIXL_CHECK(!Operand(x0, LSL, 1).IsPlainRegister());
302 VIXL_CHECK(!Operand(x1, LSR, 2).IsPlainRegister());
303 VIXL_CHECK(!Operand(x2, ASR, 3).IsPlainRegister());
304 VIXL_CHECK(!Operand(x3, ROR, 4).IsPlainRegister());
305 VIXL_CHECK(!Operand(x5, UXTX, 1).IsPlainRegister());
306 VIXL_CHECK(!Operand(x6, SXTX, 2).IsPlainRegister());
307 VIXL_CHECK(!Operand(w7, LSL, 1).IsPlainRegister());
308 VIXL_CHECK(!Operand(w8, LSR, 2).IsPlainRegister());
309 VIXL_CHECK(!Operand(w9, ASR, 3).IsPlainRegister());
310 VIXL_CHECK(!Operand(w10, ROR, 4).IsPlainRegister());
311 VIXL_CHECK(!Operand(w11, UXTB).IsPlainRegister());
312 VIXL_CHECK(!Operand(w12, SXTB).IsPlainRegister());
313 VIXL_CHECK(!Operand(w13, UXTH).IsPlainRegister());
314 VIXL_CHECK(!Operand(w14, SXTH).IsPlainRegister());
315 // UXTW and SXTW could be treated as plain registers in 32-bit contexts, but
316 // the Operand class doesn't know the context so it has to return false.
317 VIXL_CHECK(!Operand(w15, UXTW).IsPlainRegister());
318 VIXL_CHECK(!Operand(w16, SXTW).IsPlainRegister());
319 }
320
321
322 } // namespace aarch64
323 } // namespace vixl
324