1 // Copyright 2015, 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 "test-assembler-aarch64.h"
28 
29 #include <cfloat>
30 #include <cmath>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <cstring>
34 #include <sys/mman.h>
35 
36 #include "test-runner.h"
37 #include "test-utils.h"
38 
39 #include "aarch64/cpu-aarch64.h"
40 #include "aarch64/disasm-aarch64.h"
41 #include "aarch64/macro-assembler-aarch64.h"
42 #include "aarch64/simulator-aarch64.h"
43 #include "aarch64/test-utils-aarch64.h"
44 
45 namespace vixl {
46 namespace aarch64 {
47 
TEST(preshift_immediates)48 TEST(preshift_immediates) {
49   SETUP();
50 
51   START();
52   // Test operations involving immediates that could be generated using a
53   // pre-shifted encodable immediate followed by a post-shift applied to
54   // the arithmetic or logical operation.
55 
56   // Save sp.
57   __ Mov(x29, sp);
58 
59   // Set the registers to known values.
60   __ Mov(x0, 0x1000);
61   __ Mov(sp, 0x1004);
62 
63   // Arithmetic ops.
64   __ Add(x1, x0, 0x1f7de);
65   __ Add(w2, w0, 0xffffff1);
66   __ Adds(x3, x0, 0x18001);
67   __ Adds(w4, w0, 0xffffff1);
68   __ Sub(x5, x0, 0x1f7de);
69   __ Sub(w6, w0, 0xffffff1);
70   __ Subs(x7, x0, 0x18001);
71   __ Subs(w8, w0, 0xffffff1);
72 
73   // Logical ops.
74   __ And(x9, x0, 0x1f7de);
75   __ Orr(w10, w0, 0xffffff1);
76   __ Eor(x11, x0, 0x18001);
77 
78   // Ops using the stack pointer.
79   __ Add(sp, sp, 0x18001);
80   __ Mov(x12, sp);
81   __ Mov(sp, 0x1004);
82 
83   __ Add(sp, sp, 0x1f7de);
84   __ Mov(x13, sp);
85   __ Mov(sp, 0x1004);
86 
87   __ Adds(x14, sp, 0x1f7de);
88 
89   __ Orr(sp, x0, 0x1f7de);
90   __ Mov(x15, sp);
91 
92   //  Restore sp.
93   __ Mov(sp, x29);
94   END();
95 
96   if (CAN_RUN()) {
97     RUN();
98 
99     ASSERT_EQUAL_64(0x1000, x0);
100     ASSERT_EQUAL_64(0x207de, x1);
101     ASSERT_EQUAL_64(0x10000ff1, x2);
102     ASSERT_EQUAL_64(0x19001, x3);
103     ASSERT_EQUAL_64(0x10000ff1, x4);
104     ASSERT_EQUAL_64(0xfffffffffffe1822, x5);
105     ASSERT_EQUAL_64(0xf000100f, x6);
106     ASSERT_EQUAL_64(0xfffffffffffe8fff, x7);
107     ASSERT_EQUAL_64(0xf000100f, x8);
108     ASSERT_EQUAL_64(0x1000, x9);
109     ASSERT_EQUAL_64(0xffffff1, x10);
110     ASSERT_EQUAL_64(0x19001, x11);
111     ASSERT_EQUAL_64(0x19005, x12);
112     ASSERT_EQUAL_64(0x207e2, x13);
113     ASSERT_EQUAL_64(0x207e2, x14);
114     ASSERT_EQUAL_64(0x1f7de, x15);
115   }
116 }
117 
118 
TEST(stack_ops)119 TEST(stack_ops) {
120   SETUP();
121 
122   START();
123   // save sp.
124   __ Mov(x29, sp);
125 
126   // Set the sp to a known value.
127   __ Mov(sp, 0x1004);
128   __ Mov(x0, sp);
129 
130   // Add immediate to the sp, and move the result to a normal register.
131   __ Add(sp, sp, 0x50);
132   __ Mov(x1, sp);
133 
134   // Add extended to the sp, and move the result to a normal register.
135   __ Mov(x17, 0xfff);
136   __ Add(sp, sp, Operand(x17, SXTB));
137   __ Mov(x2, sp);
138 
139   // Create an sp using a logical instruction, and move to normal register.
140   __ Orr(sp, xzr, 0x1fff);
141   __ Mov(x3, sp);
142 
143   // Write wsp using a logical instruction.
144   __ Orr(wsp, wzr, 0xfffffff8);
145   __ Mov(x4, sp);
146 
147   // Write sp, and read back wsp.
148   __ Orr(sp, xzr, 0xfffffff8);
149   __ Mov(w5, wsp);
150 
151   // Test writing into wsp in cases where the immediate isn't encodable.
152   VIXL_ASSERT(!Assembler::IsImmLogical(0x1234, kWRegSize));
153   __ Orr(wsp, w5, 0x1234);
154   __ Mov(w6, wsp);
155 
156   //  restore sp.
157   __ Mov(sp, x29);
158   END();
159 
160   if (CAN_RUN()) {
161     RUN();
162 
163     ASSERT_EQUAL_64(0x1004, x0);
164     ASSERT_EQUAL_64(0x1054, x1);
165     ASSERT_EQUAL_64(0x1053, x2);
166     ASSERT_EQUAL_64(0x1fff, x3);
167     ASSERT_EQUAL_64(0xfffffff8, x4);
168     ASSERT_EQUAL_64(0xfffffff8, x5);
169     ASSERT_EQUAL_64(0xfffffffc, x6);
170   }
171 }
172 
173 
TEST(mvn)174 TEST(mvn) {
175   SETUP();
176 
177   START();
178   __ Mvn(w0, 0xfff);
179   __ Mvn(x1, 0xfff);
180   __ Mvn(w2, Operand(w0, LSL, 1));
181   __ Mvn(x3, Operand(x1, LSL, 2));
182   __ Mvn(w4, Operand(w0, LSR, 3));
183   __ Mvn(x5, Operand(x1, LSR, 4));
184   __ Mvn(w6, Operand(w0, ASR, 11));
185   __ Mvn(x7, Operand(x1, ASR, 12));
186   __ Mvn(w8, Operand(w0, ROR, 13));
187   __ Mvn(x9, Operand(x1, ROR, 14));
188   __ Mvn(w10, Operand(w2, UXTB));
189   __ Mvn(x11, Operand(x2, SXTB, 1));
190   __ Mvn(w12, Operand(w2, UXTH, 2));
191   __ Mvn(x13, Operand(x2, SXTH, 3));
192   __ Mvn(x14, Operand(w2, UXTW, 4));
193   __ Mvn(x15, Operand(w2, SXTW, 4));
194   END();
195 
196   if (CAN_RUN()) {
197     RUN();
198 
199     ASSERT_EQUAL_64(0xfffff000, x0);
200     ASSERT_EQUAL_64(0xfffffffffffff000, x1);
201     ASSERT_EQUAL_64(0x00001fff, x2);
202     ASSERT_EQUAL_64(0x0000000000003fff, x3);
203     ASSERT_EQUAL_64(0xe00001ff, x4);
204     ASSERT_EQUAL_64(0xf0000000000000ff, x5);
205     ASSERT_EQUAL_64(0x00000001, x6);
206     ASSERT_EQUAL_64(0x0000000000000000, x7);
207     ASSERT_EQUAL_64(0x7ff80000, x8);
208     ASSERT_EQUAL_64(0x3ffc000000000000, x9);
209     ASSERT_EQUAL_64(0xffffff00, x10);
210     ASSERT_EQUAL_64(0x0000000000000001, x11);
211     ASSERT_EQUAL_64(0xffff8003, x12);
212     ASSERT_EQUAL_64(0xffffffffffff0007, x13);
213     ASSERT_EQUAL_64(0xfffffffffffe000f, x14);
214     ASSERT_EQUAL_64(0xfffffffffffe000f, x15);
215   }
216 }
217 
218 
TEST(mov_imm_w)219 TEST(mov_imm_w) {
220   SETUP();
221 
222   START();
223   __ Mov(w0, 0xffffffff);
224   __ Mov(w1, 0xffff1234);
225   __ Mov(w2, 0x1234ffff);
226   __ Mov(w3, 0x00000000);
227   __ Mov(w4, 0x00001234);
228   __ Mov(w5, 0x12340000);
229   __ Mov(w6, 0x12345678);
230   __ Mov(w7, (int32_t)0x80000000);
231   __ Mov(w8, (int32_t)0xffff0000);
232   __ Mov(w9, kWMinInt);
233   END();
234 
235   if (CAN_RUN()) {
236     RUN();
237 
238     ASSERT_EQUAL_64(0xffffffff, x0);
239     ASSERT_EQUAL_64(0xffff1234, x1);
240     ASSERT_EQUAL_64(0x1234ffff, x2);
241     ASSERT_EQUAL_64(0x00000000, x3);
242     ASSERT_EQUAL_64(0x00001234, x4);
243     ASSERT_EQUAL_64(0x12340000, x5);
244     ASSERT_EQUAL_64(0x12345678, x6);
245     ASSERT_EQUAL_64(0x80000000, x7);
246     ASSERT_EQUAL_64(0xffff0000, x8);
247     ASSERT_EQUAL_32(kWMinInt, w9);
248   }
249 }
250 
251 
TEST(mov_imm_x)252 TEST(mov_imm_x) {
253   SETUP();
254 
255   START();
256   __ Mov(x0, 0xffffffffffffffff);
257   __ Mov(x1, 0xffffffffffff1234);
258   __ Mov(x2, 0xffffffff12345678);
259   __ Mov(x3, 0xffff1234ffff5678);
260   __ Mov(x4, 0x1234ffffffff5678);
261   __ Mov(x5, 0x1234ffff5678ffff);
262   __ Mov(x6, 0x12345678ffffffff);
263   __ Mov(x7, 0x1234ffffffffffff);
264   __ Mov(x8, 0x123456789abcffff);
265   __ Mov(x9, 0x12345678ffff9abc);
266   __ Mov(x10, 0x1234ffff56789abc);
267   __ Mov(x11, 0xffff123456789abc);
268   __ Mov(x12, 0x0000000000000000);
269   __ Mov(x13, 0x0000000000001234);
270   __ Mov(x14, 0x0000000012345678);
271   __ Mov(x15, 0x0000123400005678);
272   __ Mov(x18, 0x1234000000005678);
273   __ Mov(x19, 0x1234000056780000);
274   __ Mov(x20, 0x1234567800000000);
275   __ Mov(x21, 0x1234000000000000);
276   __ Mov(x22, 0x123456789abc0000);
277   __ Mov(x23, 0x1234567800009abc);
278   __ Mov(x24, 0x1234000056789abc);
279   __ Mov(x25, 0x0000123456789abc);
280   __ Mov(x26, 0x123456789abcdef0);
281   __ Mov(x27, 0xffff000000000001);
282   __ Mov(x28, 0x8000ffff00000000);
283   END();
284 
285   if (CAN_RUN()) {
286     RUN();
287 
288     ASSERT_EQUAL_64(0xffffffffffff1234, x1);
289     ASSERT_EQUAL_64(0xffffffff12345678, x2);
290     ASSERT_EQUAL_64(0xffff1234ffff5678, x3);
291     ASSERT_EQUAL_64(0x1234ffffffff5678, x4);
292     ASSERT_EQUAL_64(0x1234ffff5678ffff, x5);
293     ASSERT_EQUAL_64(0x12345678ffffffff, x6);
294     ASSERT_EQUAL_64(0x1234ffffffffffff, x7);
295     ASSERT_EQUAL_64(0x123456789abcffff, x8);
296     ASSERT_EQUAL_64(0x12345678ffff9abc, x9);
297     ASSERT_EQUAL_64(0x1234ffff56789abc, x10);
298     ASSERT_EQUAL_64(0xffff123456789abc, x11);
299     ASSERT_EQUAL_64(0x0000000000000000, x12);
300     ASSERT_EQUAL_64(0x0000000000001234, x13);
301     ASSERT_EQUAL_64(0x0000000012345678, x14);
302     ASSERT_EQUAL_64(0x0000123400005678, x15);
303     ASSERT_EQUAL_64(0x1234000000005678, x18);
304     ASSERT_EQUAL_64(0x1234000056780000, x19);
305     ASSERT_EQUAL_64(0x1234567800000000, x20);
306     ASSERT_EQUAL_64(0x1234000000000000, x21);
307     ASSERT_EQUAL_64(0x123456789abc0000, x22);
308     ASSERT_EQUAL_64(0x1234567800009abc, x23);
309     ASSERT_EQUAL_64(0x1234000056789abc, x24);
310     ASSERT_EQUAL_64(0x0000123456789abc, x25);
311     ASSERT_EQUAL_64(0x123456789abcdef0, x26);
312     ASSERT_EQUAL_64(0xffff000000000001, x27);
313     ASSERT_EQUAL_64(0x8000ffff00000000, x28);
314   }
315 }
316 
317 
TEST(mov)318 TEST(mov) {
319   SETUP();
320 
321   START();
322   __ Mov(x0, 0xffffffffffffffff);
323   __ Mov(x1, 0xffffffffffffffff);
324   __ Mov(x2, 0xffffffffffffffff);
325   __ Mov(x3, 0xffffffffffffffff);
326 
327   __ Mov(x0, 0x0123456789abcdef);
328 
329   {
330     ExactAssemblyScope scope(&masm, 3 * kInstructionSize);
331     __ movz(x1, UINT64_C(0xabcd) << 16);
332     __ movk(x2, UINT64_C(0xabcd) << 32);
333     __ movn(x3, UINT64_C(0xabcd) << 48);
334   }
335 
336   __ Mov(x4, 0x0123456789abcdef);
337   __ Mov(x5, x4);
338 
339   __ Mov(w6, -1);
340 
341   // Test that moves back to the same register have the desired effect. This
342   // is a no-op for X registers, and a truncation for W registers.
343   __ Mov(x7, 0x0123456789abcdef);
344   __ Mov(x7, x7);
345   __ Mov(x8, 0x0123456789abcdef);
346   __ Mov(w8, w8);
347   __ Mov(x9, 0x0123456789abcdef);
348   __ Mov(x9, Operand(x9));
349   __ Mov(x10, 0x0123456789abcdef);
350   __ Mov(w10, Operand(w10));
351 
352   __ Mov(w11, 0xfff);
353   __ Mov(x12, 0xfff);
354   __ Mov(w13, Operand(w11, LSL, 1));
355   __ Mov(x14, Operand(x12, LSL, 2));
356   __ Mov(w15, Operand(w11, LSR, 3));
357   __ Mov(x18, Operand(x12, LSR, 4));
358   __ Mov(w19, Operand(w11, ASR, 11));
359   __ Mov(x20, Operand(x12, ASR, 12));
360   __ Mov(w21, Operand(w11, ROR, 13));
361   __ Mov(x22, Operand(x12, ROR, 14));
362   __ Mov(w23, Operand(w13, UXTB));
363   __ Mov(x24, Operand(x13, SXTB, 1));
364   __ Mov(w25, Operand(w13, UXTH, 2));
365   __ Mov(x26, Operand(x13, SXTH, 3));
366   __ Mov(x27, Operand(w13, UXTW, 4));
367 
368   __ Mov(x28, 0x0123456789abcdef);
369   __ Mov(w28, w28, kDiscardForSameWReg);
370   END();
371 
372   if (CAN_RUN()) {
373     RUN();
374 
375     ASSERT_EQUAL_64(0x0123456789abcdef, x0);
376     ASSERT_EQUAL_64(0x00000000abcd0000, x1);
377     ASSERT_EQUAL_64(0xffffabcdffffffff, x2);
378     ASSERT_EQUAL_64(0x5432ffffffffffff, x3);
379     ASSERT_EQUAL_64(x4, x5);
380     ASSERT_EQUAL_32(-1, w6);
381     ASSERT_EQUAL_64(0x0123456789abcdef, x7);
382     ASSERT_EQUAL_32(0x89abcdef, w8);
383     ASSERT_EQUAL_64(0x0123456789abcdef, x9);
384     ASSERT_EQUAL_32(0x89abcdef, w10);
385     ASSERT_EQUAL_64(0x00000fff, x11);
386     ASSERT_EQUAL_64(0x0000000000000fff, x12);
387     ASSERT_EQUAL_64(0x00001ffe, x13);
388     ASSERT_EQUAL_64(0x0000000000003ffc, x14);
389     ASSERT_EQUAL_64(0x000001ff, x15);
390     ASSERT_EQUAL_64(0x00000000000000ff, x18);
391     ASSERT_EQUAL_64(0x00000001, x19);
392     ASSERT_EQUAL_64(0x0000000000000000, x20);
393     ASSERT_EQUAL_64(0x7ff80000, x21);
394     ASSERT_EQUAL_64(0x3ffc000000000000, x22);
395     ASSERT_EQUAL_64(0x000000fe, x23);
396     ASSERT_EQUAL_64(0xfffffffffffffffc, x24);
397     ASSERT_EQUAL_64(0x00007ff8, x25);
398     ASSERT_EQUAL_64(0x000000000000fff0, x26);
399     ASSERT_EQUAL_64(0x000000000001ffe0, x27);
400     ASSERT_EQUAL_64(0x0123456789abcdef, x28);
401   }
402 }
403 
404 
TEST(mov_negative)405 TEST(mov_negative) {
406   SETUP();
407 
408   START();
409   __ Mov(w11, 0xffffffff);
410   __ Mov(x12, 0xffffffffffffffff);
411 
412   __ Mov(w13, Operand(w11, LSL, 1));
413   __ Mov(w14, Operand(w11, LSR, 1));
414   __ Mov(w15, Operand(w11, ASR, 1));
415   __ Mov(w18, Operand(w11, ROR, 1));
416   __ Mov(w19, Operand(w11, UXTB, 1));
417   __ Mov(w20, Operand(w11, SXTB, 1));
418   __ Mov(w21, Operand(w11, UXTH, 1));
419   __ Mov(w22, Operand(w11, SXTH, 1));
420 
421   __ Mov(x23, Operand(x12, LSL, 1));
422   __ Mov(x24, Operand(x12, LSR, 1));
423   __ Mov(x25, Operand(x12, ASR, 1));
424   __ Mov(x26, Operand(x12, ROR, 1));
425   __ Mov(x27, Operand(x12, UXTH, 1));
426   __ Mov(x28, Operand(x12, SXTH, 1));
427   __ Mov(x29, Operand(x12, UXTW, 1));
428   __ Mov(x30, Operand(x12, SXTW, 1));
429   END();
430 
431   if (CAN_RUN()) {
432     RUN();
433 
434     ASSERT_EQUAL_64(0xfffffffe, x13);
435     ASSERT_EQUAL_64(0x7fffffff, x14);
436     ASSERT_EQUAL_64(0xffffffff, x15);
437     ASSERT_EQUAL_64(0xffffffff, x18);
438     ASSERT_EQUAL_64(0x000001fe, x19);
439     ASSERT_EQUAL_64(0xfffffffe, x20);
440     ASSERT_EQUAL_64(0x0001fffe, x21);
441     ASSERT_EQUAL_64(0xfffffffe, x22);
442 
443     ASSERT_EQUAL_64(0xfffffffffffffffe, x23);
444     ASSERT_EQUAL_64(0x7fffffffffffffff, x24);
445     ASSERT_EQUAL_64(0xffffffffffffffff, x25);
446     ASSERT_EQUAL_64(0xffffffffffffffff, x26);
447     ASSERT_EQUAL_64(0x000000000001fffe, x27);
448     ASSERT_EQUAL_64(0xfffffffffffffffe, x28);
449     ASSERT_EQUAL_64(0x00000001fffffffe, x29);
450     ASSERT_EQUAL_64(0xfffffffffffffffe, x30);
451   }
452 }
453 
454 
TEST(orr)455 TEST(orr) {
456   SETUP();
457 
458   START();
459   __ Mov(x0, 0xf0f0);
460   __ Mov(x1, 0xf00000ff);
461 
462   __ Orr(x2, x0, Operand(x1));
463   __ Orr(w3, w0, Operand(w1, LSL, 28));
464   __ Orr(x4, x0, Operand(x1, LSL, 32));
465   __ Orr(x5, x0, Operand(x1, LSR, 4));
466   __ Orr(w6, w0, Operand(w1, ASR, 4));
467   __ Orr(x7, x0, Operand(x1, ASR, 4));
468   __ Orr(w8, w0, Operand(w1, ROR, 12));
469   __ Orr(x9, x0, Operand(x1, ROR, 12));
470   __ Orr(w10, w0, 0xf);
471   __ Orr(x11, x0, 0xf0000000f0000000);
472   END();
473 
474   if (CAN_RUN()) {
475     RUN();
476 
477     ASSERT_EQUAL_64(0x00000000f000f0ff, x2);
478     ASSERT_EQUAL_64(0xf000f0f0, x3);
479     ASSERT_EQUAL_64(0xf00000ff0000f0f0, x4);
480     ASSERT_EQUAL_64(0x000000000f00f0ff, x5);
481     ASSERT_EQUAL_64(0xff00f0ff, x6);
482     ASSERT_EQUAL_64(0x000000000f00f0ff, x7);
483     ASSERT_EQUAL_64(0x0ffff0f0, x8);
484     ASSERT_EQUAL_64(0x0ff00000000ff0f0, x9);
485     ASSERT_EQUAL_64(0x0000f0ff, x10);
486     ASSERT_EQUAL_64(0xf0000000f000f0f0, x11);
487   }
488 }
489 
490 
TEST(orr_extend)491 TEST(orr_extend) {
492   SETUP();
493 
494   START();
495   __ Mov(x0, 1);
496   __ Mov(x1, 0x8000000080008080);
497   __ Orr(w6, w0, Operand(w1, UXTB));
498   __ Orr(x7, x0, Operand(x1, UXTH, 1));
499   __ Orr(w8, w0, Operand(w1, UXTW, 2));
500   __ Orr(x9, x0, Operand(x1, UXTX, 3));
501   __ Orr(w10, w0, Operand(w1, SXTB));
502   __ Orr(x11, x0, Operand(x1, SXTH, 1));
503   __ Orr(x12, x0, Operand(x1, SXTW, 2));
504   __ Orr(x13, x0, Operand(x1, SXTX, 3));
505   END();
506 
507   if (CAN_RUN()) {
508     RUN();
509 
510     ASSERT_EQUAL_64(0x00000081, x6);
511     ASSERT_EQUAL_64(0x0000000000010101, x7);
512     ASSERT_EQUAL_64(0x00020201, x8);
513     ASSERT_EQUAL_64(0x0000000400040401, x9);
514     ASSERT_EQUAL_64(0xffffff81, x10);
515     ASSERT_EQUAL_64(0xffffffffffff0101, x11);
516     ASSERT_EQUAL_64(0xfffffffe00020201, x12);
517     ASSERT_EQUAL_64(0x0000000400040401, x13);
518   }
519 }
520 
521 
TEST(bitwise_wide_imm)522 TEST(bitwise_wide_imm) {
523   SETUP();
524 
525   START();
526   __ Mov(x0, 0);
527   __ Mov(x1, 0xf0f0f0f0f0f0f0f0);
528 
529   __ Orr(x10, x0, 0x1234567890abcdef);
530   __ Orr(w11, w1, 0x90abcdef);
531 
532   __ Orr(w12, w0, kWMinInt);
533   __ Eor(w13, w0, kWMinInt);
534   END();
535 
536   if (CAN_RUN()) {
537     RUN();
538 
539     ASSERT_EQUAL_64(0, x0);
540     ASSERT_EQUAL_64(0xf0f0f0f0f0f0f0f0, x1);
541     ASSERT_EQUAL_64(0x1234567890abcdef, x10);
542     ASSERT_EQUAL_64(0x00000000f0fbfdff, x11);
543     ASSERT_EQUAL_32(kWMinInt, w12);
544     ASSERT_EQUAL_32(kWMinInt, w13);
545   }
546 }
547 
548 
TEST(orn)549 TEST(orn) {
550   SETUP();
551 
552   START();
553   __ Mov(x0, 0xf0f0);
554   __ Mov(x1, 0xf00000ff);
555 
556   __ Orn(x2, x0, Operand(x1));
557   __ Orn(w3, w0, Operand(w1, LSL, 4));
558   __ Orn(x4, x0, Operand(x1, LSL, 4));
559   __ Orn(x5, x0, Operand(x1, LSR, 1));
560   __ Orn(w6, w0, Operand(w1, ASR, 1));
561   __ Orn(x7, x0, Operand(x1, ASR, 1));
562   __ Orn(w8, w0, Operand(w1, ROR, 16));
563   __ Orn(x9, x0, Operand(x1, ROR, 16));
564   __ Orn(w10, w0, 0x0000ffff);
565   __ Orn(x11, x0, 0x0000ffff0000ffff);
566   END();
567 
568   if (CAN_RUN()) {
569     RUN();
570 
571     ASSERT_EQUAL_64(0xffffffff0ffffff0, x2);
572     ASSERT_EQUAL_64(0xfffff0ff, x3);
573     ASSERT_EQUAL_64(0xfffffff0fffff0ff, x4);
574     ASSERT_EQUAL_64(0xffffffff87fffff0, x5);
575     ASSERT_EQUAL_64(0x07fffff0, x6);
576     ASSERT_EQUAL_64(0xffffffff87fffff0, x7);
577     ASSERT_EQUAL_64(0xff00ffff, x8);
578     ASSERT_EQUAL_64(0xff00ffffffffffff, x9);
579     ASSERT_EQUAL_64(0xfffff0f0, x10);
580     ASSERT_EQUAL_64(0xffff0000fffff0f0, x11);
581   }
582 }
583 
584 
TEST(orn_extend)585 TEST(orn_extend) {
586   SETUP();
587 
588   START();
589   __ Mov(x0, 1);
590   __ Mov(x1, 0x8000000080008081);
591   __ Orn(w6, w0, Operand(w1, UXTB));
592   __ Orn(x7, x0, Operand(x1, UXTH, 1));
593   __ Orn(w8, w0, Operand(w1, UXTW, 2));
594   __ Orn(x9, x0, Operand(x1, UXTX, 3));
595   __ Orn(w10, w0, Operand(w1, SXTB));
596   __ Orn(x11, x0, Operand(x1, SXTH, 1));
597   __ Orn(x12, x0, Operand(x1, SXTW, 2));
598   __ Orn(x13, x0, Operand(x1, SXTX, 3));
599   END();
600 
601   if (CAN_RUN()) {
602     RUN();
603 
604     ASSERT_EQUAL_64(0xffffff7f, x6);
605     ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
606     ASSERT_EQUAL_64(0xfffdfdfb, x8);
607     ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
608     ASSERT_EQUAL_64(0x0000007f, x10);
609     ASSERT_EQUAL_64(0x000000000000fefd, x11);
610     ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
611     ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
612   }
613 }
614 
615 
TEST(and_)616 TEST(and_) {
617   SETUP();
618 
619   START();
620   __ Mov(x0, 0xfff0);
621   __ Mov(x1, 0xf00000ff);
622 
623   __ And(x2, x0, Operand(x1));
624   __ And(w3, w0, Operand(w1, LSL, 4));
625   __ And(x4, x0, Operand(x1, LSL, 4));
626   __ And(x5, x0, Operand(x1, LSR, 1));
627   __ And(w6, w0, Operand(w1, ASR, 20));
628   __ And(x7, x0, Operand(x1, ASR, 20));
629   __ And(w8, w0, Operand(w1, ROR, 28));
630   __ And(x9, x0, Operand(x1, ROR, 28));
631   __ And(w10, w0, Operand(0xff00));
632   __ And(x11, x0, Operand(0xff));
633   END();
634 
635   if (CAN_RUN()) {
636     RUN();
637 
638     ASSERT_EQUAL_64(0x000000f0, x2);
639     ASSERT_EQUAL_64(0x00000ff0, x3);
640     ASSERT_EQUAL_64(0x00000ff0, x4);
641     ASSERT_EQUAL_64(0x00000070, x5);
642     ASSERT_EQUAL_64(0x0000ff00, x6);
643     ASSERT_EQUAL_64(0x00000f00, x7);
644     ASSERT_EQUAL_64(0x00000ff0, x8);
645     ASSERT_EQUAL_64(0x00000000, x9);
646     ASSERT_EQUAL_64(0x0000ff00, x10);
647     ASSERT_EQUAL_64(0x000000f0, x11);
648   }
649 }
650 
651 
TEST(and_extend)652 TEST(and_extend) {
653   SETUP();
654 
655   START();
656   __ Mov(x0, 0xffffffffffffffff);
657   __ Mov(x1, 0x8000000080008081);
658   __ And(w6, w0, Operand(w1, UXTB));
659   __ And(x7, x0, Operand(x1, UXTH, 1));
660   __ And(w8, w0, Operand(w1, UXTW, 2));
661   __ And(x9, x0, Operand(x1, UXTX, 3));
662   __ And(w10, w0, Operand(w1, SXTB));
663   __ And(x11, x0, Operand(x1, SXTH, 1));
664   __ And(x12, x0, Operand(x1, SXTW, 2));
665   __ And(x13, x0, Operand(x1, SXTX, 3));
666   END();
667 
668   if (CAN_RUN()) {
669     RUN();
670 
671     ASSERT_EQUAL_64(0x00000081, x6);
672     ASSERT_EQUAL_64(0x0000000000010102, x7);
673     ASSERT_EQUAL_64(0x00020204, x8);
674     ASSERT_EQUAL_64(0x0000000400040408, x9);
675     ASSERT_EQUAL_64(0xffffff81, x10);
676     ASSERT_EQUAL_64(0xffffffffffff0102, x11);
677     ASSERT_EQUAL_64(0xfffffffe00020204, x12);
678     ASSERT_EQUAL_64(0x0000000400040408, x13);
679   }
680 }
681 
682 
TEST(ands)683 TEST(ands) {
684   SETUP();
685 
686   START();
687   __ Mov(x1, 0xf00000ff);
688   __ Ands(w0, w1, Operand(w1));
689   END();
690 
691   if (CAN_RUN()) {
692     RUN();
693 
694     ASSERT_EQUAL_NZCV(NFlag);
695     ASSERT_EQUAL_64(0xf00000ff, x0);
696   }
697 
698   START();
699   __ Mov(x0, 0xfff0);
700   __ Mov(x1, 0xf00000ff);
701   __ Ands(w0, w0, Operand(w1, LSR, 4));
702   END();
703 
704   if (CAN_RUN()) {
705     RUN();
706 
707     ASSERT_EQUAL_NZCV(ZFlag);
708     ASSERT_EQUAL_64(0x00000000, x0);
709   }
710 
711   START();
712   __ Mov(x0, 0x8000000000000000);
713   __ Mov(x1, 0x00000001);
714   __ Ands(x0, x0, Operand(x1, ROR, 1));
715   END();
716 
717   if (CAN_RUN()) {
718     RUN();
719 
720     ASSERT_EQUAL_NZCV(NFlag);
721     ASSERT_EQUAL_64(0x8000000000000000, x0);
722   }
723 
724   START();
725   __ Mov(x0, 0xfff0);
726   __ Ands(w0, w0, Operand(0xf));
727   END();
728 
729   if (CAN_RUN()) {
730     RUN();
731 
732     ASSERT_EQUAL_NZCV(ZFlag);
733     ASSERT_EQUAL_64(0x00000000, x0);
734   }
735 
736   START();
737   __ Mov(x0, 0xff000000);
738   __ Ands(w0, w0, Operand(0x80000000));
739   END();
740 
741   if (CAN_RUN()) {
742     RUN();
743 
744     ASSERT_EQUAL_NZCV(NFlag);
745     ASSERT_EQUAL_64(0x80000000, x0);
746   }
747 }
748 
749 
TEST(bic)750 TEST(bic) {
751   SETUP();
752 
753   START();
754   __ Mov(x0, 0xfff0);
755   __ Mov(x1, 0xf00000ff);
756 
757   __ Bic(x2, x0, Operand(x1));
758   __ Bic(w3, w0, Operand(w1, LSL, 4));
759   __ Bic(x4, x0, Operand(x1, LSL, 4));
760   __ Bic(x5, x0, Operand(x1, LSR, 1));
761   __ Bic(w6, w0, Operand(w1, ASR, 20));
762   __ Bic(x7, x0, Operand(x1, ASR, 20));
763   __ Bic(w8, w0, Operand(w1, ROR, 28));
764   __ Bic(x9, x0, Operand(x1, ROR, 24));
765   __ Bic(x10, x0, Operand(0x1f));
766   __ Bic(x11, x0, Operand(0x100));
767 
768   // Test bic into sp when the constant cannot be encoded in the immediate
769   // field.
770   // Use x20 to preserve sp. We check for the result via x21 because the
771   // test infrastructure requires that sp be restored to its original value.
772   __ Mov(x20, sp);
773   __ Mov(x0, 0xffffff);
774   __ Bic(sp, x0, Operand(0xabcdef));
775   __ Mov(x21, sp);
776   __ Mov(sp, x20);
777   END();
778 
779   if (CAN_RUN()) {
780     RUN();
781 
782     ASSERT_EQUAL_64(0x0000ff00, x2);
783     ASSERT_EQUAL_64(0x0000f000, x3);
784     ASSERT_EQUAL_64(0x0000f000, x4);
785     ASSERT_EQUAL_64(0x0000ff80, x5);
786     ASSERT_EQUAL_64(0x000000f0, x6);
787     ASSERT_EQUAL_64(0x0000f0f0, x7);
788     ASSERT_EQUAL_64(0x0000f000, x8);
789     ASSERT_EQUAL_64(0x0000ff00, x9);
790     ASSERT_EQUAL_64(0x0000ffe0, x10);
791     ASSERT_EQUAL_64(0x0000fef0, x11);
792 
793     ASSERT_EQUAL_64(0x543210, x21);
794   }
795 }
796 
797 
TEST(bic_extend)798 TEST(bic_extend) {
799   SETUP();
800 
801   START();
802   __ Mov(x0, 0xffffffffffffffff);
803   __ Mov(x1, 0x8000000080008081);
804   __ Bic(w6, w0, Operand(w1, UXTB));
805   __ Bic(x7, x0, Operand(x1, UXTH, 1));
806   __ Bic(w8, w0, Operand(w1, UXTW, 2));
807   __ Bic(x9, x0, Operand(x1, UXTX, 3));
808   __ Bic(w10, w0, Operand(w1, SXTB));
809   __ Bic(x11, x0, Operand(x1, SXTH, 1));
810   __ Bic(x12, x0, Operand(x1, SXTW, 2));
811   __ Bic(x13, x0, Operand(x1, SXTX, 3));
812   END();
813 
814   if (CAN_RUN()) {
815     RUN();
816 
817     ASSERT_EQUAL_64(0xffffff7e, x6);
818     ASSERT_EQUAL_64(0xfffffffffffefefd, x7);
819     ASSERT_EQUAL_64(0xfffdfdfb, x8);
820     ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x9);
821     ASSERT_EQUAL_64(0x0000007e, x10);
822     ASSERT_EQUAL_64(0x000000000000fefd, x11);
823     ASSERT_EQUAL_64(0x00000001fffdfdfb, x12);
824     ASSERT_EQUAL_64(0xfffffffbfffbfbf7, x13);
825   }
826 }
827 
828 
TEST(bics)829 TEST(bics) {
830   SETUP();
831 
832   START();
833   __ Mov(x1, 0xffff);
834   __ Bics(w0, w1, Operand(w1));
835   END();
836 
837   if (CAN_RUN()) {
838     RUN();
839 
840     ASSERT_EQUAL_NZCV(ZFlag);
841     ASSERT_EQUAL_64(0x00000000, x0);
842   }
843 
844   START();
845   __ Mov(x0, 0xffffffff);
846   __ Bics(w0, w0, Operand(w0, LSR, 1));
847   END();
848 
849   if (CAN_RUN()) {
850     RUN();
851 
852     ASSERT_EQUAL_NZCV(NFlag);
853     ASSERT_EQUAL_64(0x80000000, x0);
854   }
855 
856   START();
857   __ Mov(x0, 0x8000000000000000);
858   __ Mov(x1, 0x00000001);
859   __ Bics(x0, x0, Operand(x1, ROR, 1));
860   END();
861 
862   if (CAN_RUN()) {
863     RUN();
864 
865     ASSERT_EQUAL_NZCV(ZFlag);
866     ASSERT_EQUAL_64(0x00000000, x0);
867   }
868 
869   START();
870   __ Mov(x0, 0xffffffffffffffff);
871   __ Bics(x0, x0, 0x7fffffffffffffff);
872   END();
873 
874   if (CAN_RUN()) {
875     RUN();
876 
877     ASSERT_EQUAL_NZCV(NFlag);
878     ASSERT_EQUAL_64(0x8000000000000000, x0);
879   }
880 
881   START();
882   __ Mov(w0, 0xffff0000);
883   __ Bics(w0, w0, 0xfffffff0);
884   END();
885 
886   if (CAN_RUN()) {
887     RUN();
888 
889     ASSERT_EQUAL_NZCV(ZFlag);
890     ASSERT_EQUAL_64(0x00000000, x0);
891   }
892 }
893 
894 
TEST(eor)895 TEST(eor) {
896   SETUP();
897 
898   START();
899   __ Mov(x0, 0xfff0);
900   __ Mov(x1, 0xf00000ff);
901 
902   __ Eor(x2, x0, Operand(x1));
903   __ Eor(w3, w0, Operand(w1, LSL, 4));
904   __ Eor(x4, x0, Operand(x1, LSL, 4));
905   __ Eor(x5, x0, Operand(x1, LSR, 1));
906   __ Eor(w6, w0, Operand(w1, ASR, 20));
907   __ Eor(x7, x0, Operand(x1, ASR, 20));
908   __ Eor(w8, w0, Operand(w1, ROR, 28));
909   __ Eor(x9, x0, Operand(x1, ROR, 28));
910   __ Eor(w10, w0, 0xff00ff00);
911   __ Eor(x11, x0, 0xff00ff00ff00ff00);
912   END();
913 
914   if (CAN_RUN()) {
915     RUN();
916 
917     ASSERT_EQUAL_64(0x00000000f000ff0f, x2);
918     ASSERT_EQUAL_64(0x0000f000, x3);
919     ASSERT_EQUAL_64(0x0000000f0000f000, x4);
920     ASSERT_EQUAL_64(0x000000007800ff8f, x5);
921     ASSERT_EQUAL_64(0xffff00f0, x6);
922     ASSERT_EQUAL_64(0x000000000000f0f0, x7);
923     ASSERT_EQUAL_64(0x0000f00f, x8);
924     ASSERT_EQUAL_64(0x00000ff00000ffff, x9);
925     ASSERT_EQUAL_64(0xff0000f0, x10);
926     ASSERT_EQUAL_64(0xff00ff00ff0000f0, x11);
927   }
928 }
929 
TEST(eor_extend)930 TEST(eor_extend) {
931   SETUP();
932 
933   START();
934   __ Mov(x0, 0x1111111111111111);
935   __ Mov(x1, 0x8000000080008081);
936   __ Eor(w6, w0, Operand(w1, UXTB));
937   __ Eor(x7, x0, Operand(x1, UXTH, 1));
938   __ Eor(w8, w0, Operand(w1, UXTW, 2));
939   __ Eor(x9, x0, Operand(x1, UXTX, 3));
940   __ Eor(w10, w0, Operand(w1, SXTB));
941   __ Eor(x11, x0, Operand(x1, SXTH, 1));
942   __ Eor(x12, x0, Operand(x1, SXTW, 2));
943   __ Eor(x13, x0, Operand(x1, SXTX, 3));
944   END();
945 
946   if (CAN_RUN()) {
947     RUN();
948 
949     ASSERT_EQUAL_64(0x11111190, x6);
950     ASSERT_EQUAL_64(0x1111111111101013, x7);
951     ASSERT_EQUAL_64(0x11131315, x8);
952     ASSERT_EQUAL_64(0x1111111511151519, x9);
953     ASSERT_EQUAL_64(0xeeeeee90, x10);
954     ASSERT_EQUAL_64(0xeeeeeeeeeeee1013, x11);
955     ASSERT_EQUAL_64(0xeeeeeeef11131315, x12);
956     ASSERT_EQUAL_64(0x1111111511151519, x13);
957   }
958 }
959 
960 
TEST(eon)961 TEST(eon) {
962   SETUP();
963 
964   START();
965   __ Mov(x0, 0xfff0);
966   __ Mov(x1, 0xf00000ff);
967 
968   __ Eon(x2, x0, Operand(x1));
969   __ Eon(w3, w0, Operand(w1, LSL, 4));
970   __ Eon(x4, x0, Operand(x1, LSL, 4));
971   __ Eon(x5, x0, Operand(x1, LSR, 1));
972   __ Eon(w6, w0, Operand(w1, ASR, 20));
973   __ Eon(x7, x0, Operand(x1, ASR, 20));
974   __ Eon(w8, w0, Operand(w1, ROR, 28));
975   __ Eon(x9, x0, Operand(x1, ROR, 28));
976   __ Eon(w10, w0, 0x03c003c0);
977   __ Eon(x11, x0, 0x0000100000001000);
978   END();
979 
980   if (CAN_RUN()) {
981     RUN();
982 
983     ASSERT_EQUAL_64(0xffffffff0fff00f0, x2);
984     ASSERT_EQUAL_64(0xffff0fff, x3);
985     ASSERT_EQUAL_64(0xfffffff0ffff0fff, x4);
986     ASSERT_EQUAL_64(0xffffffff87ff0070, x5);
987     ASSERT_EQUAL_64(0x0000ff0f, x6);
988     ASSERT_EQUAL_64(0xffffffffffff0f0f, x7);
989     ASSERT_EQUAL_64(0xffff0ff0, x8);
990     ASSERT_EQUAL_64(0xfffff00fffff0000, x9);
991     ASSERT_EQUAL_64(0xfc3f03cf, x10);
992     ASSERT_EQUAL_64(0xffffefffffff100f, x11);
993   }
994 }
995 
996 
TEST(eon_extend)997 TEST(eon_extend) {
998   SETUP();
999 
1000   START();
1001   __ Mov(x0, 0x1111111111111111);
1002   __ Mov(x1, 0x8000000080008081);
1003   __ Eon(w6, w0, Operand(w1, UXTB));
1004   __ Eon(x7, x0, Operand(x1, UXTH, 1));
1005   __ Eon(w8, w0, Operand(w1, UXTW, 2));
1006   __ Eon(x9, x0, Operand(x1, UXTX, 3));
1007   __ Eon(w10, w0, Operand(w1, SXTB));
1008   __ Eon(x11, x0, Operand(x1, SXTH, 1));
1009   __ Eon(x12, x0, Operand(x1, SXTW, 2));
1010   __ Eon(x13, x0, Operand(x1, SXTX, 3));
1011   END();
1012 
1013   if (CAN_RUN()) {
1014     RUN();
1015 
1016     ASSERT_EQUAL_64(0xeeeeee6f, x6);
1017     ASSERT_EQUAL_64(0xeeeeeeeeeeefefec, x7);
1018     ASSERT_EQUAL_64(0xeeececea, x8);
1019     ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x9);
1020     ASSERT_EQUAL_64(0x1111116f, x10);
1021     ASSERT_EQUAL_64(0x111111111111efec, x11);
1022     ASSERT_EQUAL_64(0x11111110eeececea, x12);
1023     ASSERT_EQUAL_64(0xeeeeeeeaeeeaeae6, x13);
1024   }
1025 }
1026 
1027 
TEST(mul)1028 TEST(mul) {
1029   SETUP();
1030 
1031   START();
1032   __ Mov(x25, 0);
1033   __ Mov(x26, 1);
1034   __ Mov(x18, 0xffffffff);
1035   __ Mov(x19, 0xffffffffffffffff);
1036 
1037   __ Mul(w0, w25, w25);
1038   __ Mul(w1, w25, w26);
1039   __ Mul(w2, w26, w18);
1040   __ Mul(w3, w18, w19);
1041   __ Mul(x4, x25, x25);
1042   __ Mul(x5, x26, x18);
1043   __ Mul(x6, x18, x19);
1044   __ Mul(x7, x19, x19);
1045   __ Smull(x8, w26, w18);
1046   __ Smull(x9, w18, w18);
1047   __ Smull(x10, w19, w19);
1048   __ Mneg(w11, w25, w25);
1049   __ Mneg(w12, w25, w26);
1050   __ Mneg(w13, w26, w18);
1051   __ Mneg(w14, w18, w19);
1052   __ Mneg(x20, x25, x25);
1053   __ Mneg(x21, x26, x18);
1054   __ Mneg(x22, x18, x19);
1055   __ Mneg(x23, x19, x19);
1056   END();
1057 
1058   if (CAN_RUN()) {
1059     RUN();
1060 
1061     ASSERT_EQUAL_64(0, x0);
1062     ASSERT_EQUAL_64(0, x1);
1063     ASSERT_EQUAL_64(0xffffffff, x2);
1064     ASSERT_EQUAL_64(1, x3);
1065     ASSERT_EQUAL_64(0, x4);
1066     ASSERT_EQUAL_64(0xffffffff, x5);
1067     ASSERT_EQUAL_64(0xffffffff00000001, x6);
1068     ASSERT_EQUAL_64(1, x7);
1069     ASSERT_EQUAL_64(0xffffffffffffffff, x8);
1070     ASSERT_EQUAL_64(1, x9);
1071     ASSERT_EQUAL_64(1, x10);
1072     ASSERT_EQUAL_64(0, x11);
1073     ASSERT_EQUAL_64(0, x12);
1074     ASSERT_EQUAL_64(1, x13);
1075     ASSERT_EQUAL_64(0xffffffff, x14);
1076     ASSERT_EQUAL_64(0, x20);
1077     ASSERT_EQUAL_64(0xffffffff00000001, x21);
1078     ASSERT_EQUAL_64(0xffffffff, x22);
1079     ASSERT_EQUAL_64(0xffffffffffffffff, x23);
1080   }
1081 }
1082 
1083 
SmullHelper(int64_t expected, int64_t a, int64_t b)1084 static void SmullHelper(int64_t expected, int64_t a, int64_t b) {
1085   SETUP();
1086   START();
1087   __ Mov(w0, a);
1088   __ Mov(w1, b);
1089   __ Smull(x2, w0, w1);
1090   END();
1091   if (CAN_RUN()) {
1092     RUN();
1093     ASSERT_EQUAL_64(expected, x2);
1094   }
1095 }
1096 
1097 
TEST(smull)1098 TEST(smull) {
1099   SmullHelper(0, 0, 0);
1100   SmullHelper(1, 1, 1);
1101   SmullHelper(-1, -1, 1);
1102   SmullHelper(1, -1, -1);
1103   SmullHelper(0xffffffff80000000, 0x80000000, 1);
1104   SmullHelper(0x0000000080000000, 0x00010000, 0x00008000);
1105 }
1106 
1107 
TEST(madd)1108 TEST(madd) {
1109   SETUP();
1110 
1111   START();
1112   __ Mov(x16, 0);
1113   __ Mov(x17, 1);
1114   __ Mov(x18, 0xffffffff);
1115   __ Mov(x19, 0xffffffffffffffff);
1116 
1117   __ Madd(w0, w16, w16, w16);
1118   __ Madd(w1, w16, w16, w17);
1119   __ Madd(w2, w16, w16, w18);
1120   __ Madd(w3, w16, w16, w19);
1121   __ Madd(w4, w16, w17, w17);
1122   __ Madd(w5, w17, w17, w18);
1123   __ Madd(w6, w17, w17, w19);
1124   __ Madd(w7, w17, w18, w16);
1125   __ Madd(w8, w17, w18, w18);
1126   __ Madd(w9, w18, w18, w17);
1127   __ Madd(w10, w18, w19, w18);
1128   __ Madd(w11, w19, w19, w19);
1129 
1130   __ Madd(x12, x16, x16, x16);
1131   __ Madd(x13, x16, x16, x17);
1132   __ Madd(x14, x16, x16, x18);
1133   __ Madd(x15, x16, x16, x19);
1134   __ Madd(x20, x16, x17, x17);
1135   __ Madd(x21, x17, x17, x18);
1136   __ Madd(x22, x17, x17, x19);
1137   __ Madd(x23, x17, x18, x16);
1138   __ Madd(x24, x17, x18, x18);
1139   __ Madd(x25, x18, x18, x17);
1140   __ Madd(x26, x18, x19, x18);
1141   __ Madd(x27, x19, x19, x19);
1142 
1143   END();
1144 
1145   if (CAN_RUN()) {
1146     RUN();
1147 
1148     ASSERT_EQUAL_64(0, x0);
1149     ASSERT_EQUAL_64(1, x1);
1150     ASSERT_EQUAL_64(0xffffffff, x2);
1151     ASSERT_EQUAL_64(0xffffffff, x3);
1152     ASSERT_EQUAL_64(1, x4);
1153     ASSERT_EQUAL_64(0, x5);
1154     ASSERT_EQUAL_64(0, x6);
1155     ASSERT_EQUAL_64(0xffffffff, x7);
1156     ASSERT_EQUAL_64(0xfffffffe, x8);
1157     ASSERT_EQUAL_64(2, x9);
1158     ASSERT_EQUAL_64(0, x10);
1159     ASSERT_EQUAL_64(0, x11);
1160 
1161     ASSERT_EQUAL_64(0, x12);
1162     ASSERT_EQUAL_64(1, x13);
1163     ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1164     ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1165     ASSERT_EQUAL_64(1, x20);
1166     ASSERT_EQUAL_64(0x0000000100000000, x21);
1167     ASSERT_EQUAL_64(0, x22);
1168     ASSERT_EQUAL_64(0x00000000ffffffff, x23);
1169     ASSERT_EQUAL_64(0x00000001fffffffe, x24);
1170     ASSERT_EQUAL_64(0xfffffffe00000002, x25);
1171     ASSERT_EQUAL_64(0, x26);
1172     ASSERT_EQUAL_64(0, x27);
1173   }
1174 }
1175 
1176 
TEST(msub)1177 TEST(msub) {
1178   SETUP();
1179 
1180   START();
1181   __ Mov(x16, 0);
1182   __ Mov(x17, 1);
1183   __ Mov(x18, 0xffffffff);
1184   __ Mov(x19, 0xffffffffffffffff);
1185 
1186   __ Msub(w0, w16, w16, w16);
1187   __ Msub(w1, w16, w16, w17);
1188   __ Msub(w2, w16, w16, w18);
1189   __ Msub(w3, w16, w16, w19);
1190   __ Msub(w4, w16, w17, w17);
1191   __ Msub(w5, w17, w17, w18);
1192   __ Msub(w6, w17, w17, w19);
1193   __ Msub(w7, w17, w18, w16);
1194   __ Msub(w8, w17, w18, w18);
1195   __ Msub(w9, w18, w18, w17);
1196   __ Msub(w10, w18, w19, w18);
1197   __ Msub(w11, w19, w19, w19);
1198 
1199   __ Msub(x12, x16, x16, x16);
1200   __ Msub(x13, x16, x16, x17);
1201   __ Msub(x14, x16, x16, x18);
1202   __ Msub(x15, x16, x16, x19);
1203   __ Msub(x20, x16, x17, x17);
1204   __ Msub(x21, x17, x17, x18);
1205   __ Msub(x22, x17, x17, x19);
1206   __ Msub(x23, x17, x18, x16);
1207   __ Msub(x24, x17, x18, x18);
1208   __ Msub(x25, x18, x18, x17);
1209   __ Msub(x26, x18, x19, x18);
1210   __ Msub(x27, x19, x19, x19);
1211 
1212   END();
1213 
1214   if (CAN_RUN()) {
1215     RUN();
1216 
1217     ASSERT_EQUAL_64(0, x0);
1218     ASSERT_EQUAL_64(1, x1);
1219     ASSERT_EQUAL_64(0xffffffff, x2);
1220     ASSERT_EQUAL_64(0xffffffff, x3);
1221     ASSERT_EQUAL_64(1, x4);
1222     ASSERT_EQUAL_64(0xfffffffe, x5);
1223     ASSERT_EQUAL_64(0xfffffffe, x6);
1224     ASSERT_EQUAL_64(1, x7);
1225     ASSERT_EQUAL_64(0, x8);
1226     ASSERT_EQUAL_64(0, x9);
1227     ASSERT_EQUAL_64(0xfffffffe, x10);
1228     ASSERT_EQUAL_64(0xfffffffe, x11);
1229 
1230     ASSERT_EQUAL_64(0, x12);
1231     ASSERT_EQUAL_64(1, x13);
1232     ASSERT_EQUAL_64(0x00000000ffffffff, x14);
1233     ASSERT_EQUAL_64(0xffffffffffffffff, x15);
1234     ASSERT_EQUAL_64(1, x20);
1235     ASSERT_EQUAL_64(0x00000000fffffffe, x21);
1236     ASSERT_EQUAL_64(0xfffffffffffffffe, x22);
1237     ASSERT_EQUAL_64(0xffffffff00000001, x23);
1238     ASSERT_EQUAL_64(0, x24);
1239     ASSERT_EQUAL_64(0x0000000200000000, x25);
1240     ASSERT_EQUAL_64(0x00000001fffffffe, x26);
1241     ASSERT_EQUAL_64(0xfffffffffffffffe, x27);
1242   }
1243 }
1244 
1245 
TEST(smulh)1246 TEST(smulh) {
1247   SETUP();
1248 
1249   START();
1250   __ Mov(x20, 0);
1251   __ Mov(x21, 1);
1252   __ Mov(x22, 0x0000000100000000);
1253   __ Mov(x23, 0x0000000012345678);
1254   __ Mov(x24, 0x0123456789abcdef);
1255   __ Mov(x25, 0x0000000200000000);
1256   __ Mov(x26, 0x8000000000000000);
1257   __ Mov(x27, 0xffffffffffffffff);
1258   __ Mov(x28, 0x5555555555555555);
1259   __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
1260 
1261   __ Smulh(x0, x20, x24);
1262   __ Smulh(x1, x21, x24);
1263   __ Smulh(x2, x22, x23);
1264   __ Smulh(x3, x22, x24);
1265   __ Smulh(x4, x24, x25);
1266   __ Smulh(x5, x23, x27);
1267   __ Smulh(x6, x26, x26);
1268   __ Smulh(x7, x26, x27);
1269   __ Smulh(x8, x27, x27);
1270   __ Smulh(x9, x28, x28);
1271   __ Smulh(x10, x28, x29);
1272   __ Smulh(x11, x29, x29);
1273   END();
1274 
1275   if (CAN_RUN()) {
1276     RUN();
1277 
1278     ASSERT_EQUAL_64(0, x0);
1279     ASSERT_EQUAL_64(0, x1);
1280     ASSERT_EQUAL_64(0, x2);
1281     ASSERT_EQUAL_64(0x0000000001234567, x3);
1282     ASSERT_EQUAL_64(0x0000000002468acf, x4);
1283     ASSERT_EQUAL_64(0xffffffffffffffff, x5);
1284     ASSERT_EQUAL_64(0x4000000000000000, x6);
1285     ASSERT_EQUAL_64(0, x7);
1286     ASSERT_EQUAL_64(0, x8);
1287     ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1288     ASSERT_EQUAL_64(0xe38e38e38e38e38e, x10);
1289     ASSERT_EQUAL_64(0x1c71c71c71c71c72, x11);
1290   }
1291 }
1292 
1293 
TEST(umulh)1294 TEST(umulh) {
1295   SETUP();
1296 
1297   START();
1298   __ Mov(x20, 0);
1299   __ Mov(x21, 1);
1300   __ Mov(x22, 0x0000000100000000);
1301   __ Mov(x23, 0x0000000012345678);
1302   __ Mov(x24, 0x0123456789abcdef);
1303   __ Mov(x25, 0x0000000200000000);
1304   __ Mov(x26, 0x8000000000000000);
1305   __ Mov(x27, 0xffffffffffffffff);
1306   __ Mov(x28, 0x5555555555555555);
1307   __ Mov(x29, 0xaaaaaaaaaaaaaaaa);
1308 
1309   __ Umulh(x0, x20, x24);
1310   __ Umulh(x1, x21, x24);
1311   __ Umulh(x2, x22, x23);
1312   __ Umulh(x3, x22, x24);
1313   __ Umulh(x4, x24, x25);
1314   __ Umulh(x5, x23, x27);
1315   __ Umulh(x6, x26, x26);
1316   __ Umulh(x7, x26, x27);
1317   __ Umulh(x8, x27, x27);
1318   __ Umulh(x9, x28, x28);
1319   __ Umulh(x10, x28, x29);
1320   __ Umulh(x11, x29, x29);
1321   END();
1322 
1323   if (CAN_RUN()) {
1324     RUN();
1325 
1326     ASSERT_EQUAL_64(0, x0);
1327     ASSERT_EQUAL_64(0, x1);
1328     ASSERT_EQUAL_64(0, x2);
1329     ASSERT_EQUAL_64(0x0000000001234567, x3);
1330     ASSERT_EQUAL_64(0x0000000002468acf, x4);
1331     ASSERT_EQUAL_64(0x0000000012345677, x5);
1332     ASSERT_EQUAL_64(0x4000000000000000, x6);
1333     ASSERT_EQUAL_64(0x7fffffffffffffff, x7);
1334     ASSERT_EQUAL_64(0xfffffffffffffffe, x8);
1335     ASSERT_EQUAL_64(0x1c71c71c71c71c71, x9);
1336     ASSERT_EQUAL_64(0x38e38e38e38e38e3, x10);
1337     ASSERT_EQUAL_64(0x71c71c71c71c71c6, x11);
1338   }
1339 }
1340 
1341 
TEST(smaddl_umaddl_umull)1342 TEST(smaddl_umaddl_umull) {
1343   SETUP();
1344 
1345   START();
1346   __ Mov(x17, 1);
1347   __ Mov(x18, 0x00000000ffffffff);
1348   __ Mov(x19, 0xffffffffffffffff);
1349   __ Mov(x20, 4);
1350   __ Mov(x21, 0x0000000200000000);
1351 
1352   __ Smaddl(x9, w17, w18, x20);
1353   __ Smaddl(x10, w18, w18, x20);
1354   __ Smaddl(x11, w19, w19, x20);
1355   __ Smaddl(x12, w19, w19, x21);
1356   __ Umaddl(x13, w17, w18, x20);
1357   __ Umaddl(x14, w18, w18, x20);
1358   __ Umaddl(x15, w19, w19, x20);
1359   __ Umaddl(x22, w19, w19, x21);
1360   __ Umull(x24, w19, w19);
1361   __ Umull(x25, w17, w18);
1362   END();
1363 
1364   if (CAN_RUN()) {
1365     RUN();
1366 
1367     ASSERT_EQUAL_64(3, x9);
1368     ASSERT_EQUAL_64(5, x10);
1369     ASSERT_EQUAL_64(5, x11);
1370     ASSERT_EQUAL_64(0x0000000200000001, x12);
1371     ASSERT_EQUAL_64(0x0000000100000003, x13);
1372     ASSERT_EQUAL_64(0xfffffffe00000005, x14);
1373     ASSERT_EQUAL_64(0xfffffffe00000005, x15);
1374     ASSERT_EQUAL_64(1, x22);
1375     ASSERT_EQUAL_64(0xfffffffe00000001, x24);
1376     ASSERT_EQUAL_64(0x00000000ffffffff, x25);
1377   }
1378 }
1379 
1380 
TEST(smsubl_umsubl)1381 TEST(smsubl_umsubl) {
1382   SETUP();
1383 
1384   START();
1385   __ Mov(x17, 1);
1386   __ Mov(x18, 0x00000000ffffffff);
1387   __ Mov(x19, 0xffffffffffffffff);
1388   __ Mov(x20, 4);
1389   __ Mov(x21, 0x0000000200000000);
1390 
1391   __ Smsubl(x9, w17, w18, x20);
1392   __ Smsubl(x10, w18, w18, x20);
1393   __ Smsubl(x11, w19, w19, x20);
1394   __ Smsubl(x12, w19, w19, x21);
1395   __ Umsubl(x13, w17, w18, x20);
1396   __ Umsubl(x14, w18, w18, x20);
1397   __ Umsubl(x15, w19, w19, x20);
1398   __ Umsubl(x22, w19, w19, x21);
1399   END();
1400 
1401   if (CAN_RUN()) {
1402     RUN();
1403 
1404     ASSERT_EQUAL_64(5, x9);
1405     ASSERT_EQUAL_64(3, x10);
1406     ASSERT_EQUAL_64(3, x11);
1407     ASSERT_EQUAL_64(0x00000001ffffffff, x12);
1408     ASSERT_EQUAL_64(0xffffffff00000005, x13);
1409     ASSERT_EQUAL_64(0x0000000200000003, x14);
1410     ASSERT_EQUAL_64(0x0000000200000003, x15);
1411     ASSERT_EQUAL_64(0x00000003ffffffff, x22);
1412   }
1413 }
1414 
1415 
TEST(div)1416 TEST(div) {
1417   SETUP();
1418 
1419   START();
1420   __ Mov(x16, 1);
1421   __ Mov(x17, 0xffffffff);
1422   __ Mov(x18, 0xffffffffffffffff);
1423   __ Mov(x19, 0x80000000);
1424   __ Mov(x20, 0x8000000000000000);
1425   __ Mov(x21, 2);
1426 
1427   __ Udiv(w0, w16, w16);
1428   __ Udiv(w1, w17, w16);
1429   __ Sdiv(w2, w16, w16);
1430   __ Sdiv(w3, w16, w17);
1431   __ Sdiv(w4, w17, w18);
1432 
1433   __ Udiv(x5, x16, x16);
1434   __ Udiv(x6, x17, x18);
1435   __ Sdiv(x7, x16, x16);
1436   __ Sdiv(x8, x16, x17);
1437   __ Sdiv(x9, x17, x18);
1438 
1439   __ Udiv(w10, w19, w21);
1440   __ Sdiv(w11, w19, w21);
1441   __ Udiv(x12, x19, x21);
1442   __ Sdiv(x13, x19, x21);
1443   __ Udiv(x14, x20, x21);
1444   __ Sdiv(x15, x20, x21);
1445 
1446   __ Udiv(w22, w19, w17);
1447   __ Sdiv(w23, w19, w17);
1448   __ Udiv(x24, x20, x18);
1449   __ Sdiv(x25, x20, x18);
1450 
1451   __ Udiv(x26, x16, x21);
1452   __ Sdiv(x27, x16, x21);
1453   __ Udiv(x28, x18, x21);
1454   __ Sdiv(x29, x18, x21);
1455 
1456   __ Mov(x17, 0);
1457   __ Udiv(w18, w16, w17);
1458   __ Sdiv(w19, w16, w17);
1459   __ Udiv(x20, x16, x17);
1460   __ Sdiv(x21, x16, x17);
1461   END();
1462 
1463   if (CAN_RUN()) {
1464     RUN();
1465 
1466     ASSERT_EQUAL_64(1, x0);
1467     ASSERT_EQUAL_64(0xffffffff, x1);
1468     ASSERT_EQUAL_64(1, x2);
1469     ASSERT_EQUAL_64(0xffffffff, x3);
1470     ASSERT_EQUAL_64(1, x4);
1471     ASSERT_EQUAL_64(1, x5);
1472     ASSERT_EQUAL_64(0, x6);
1473     ASSERT_EQUAL_64(1, x7);
1474     ASSERT_EQUAL_64(0, x8);
1475     ASSERT_EQUAL_64(0xffffffff00000001, x9);
1476     ASSERT_EQUAL_64(0x40000000, x10);
1477     ASSERT_EQUAL_64(0xc0000000, x11);
1478     ASSERT_EQUAL_64(0x0000000040000000, x12);
1479     ASSERT_EQUAL_64(0x0000000040000000, x13);
1480     ASSERT_EQUAL_64(0x4000000000000000, x14);
1481     ASSERT_EQUAL_64(0xc000000000000000, x15);
1482     ASSERT_EQUAL_64(0, x22);
1483     ASSERT_EQUAL_64(0x80000000, x23);
1484     ASSERT_EQUAL_64(0, x24);
1485     ASSERT_EQUAL_64(0x8000000000000000, x25);
1486     ASSERT_EQUAL_64(0, x26);
1487     ASSERT_EQUAL_64(0, x27);
1488     ASSERT_EQUAL_64(0x7fffffffffffffff, x28);
1489     ASSERT_EQUAL_64(0, x29);
1490     ASSERT_EQUAL_64(0, x18);
1491     ASSERT_EQUAL_64(0, x19);
1492     ASSERT_EQUAL_64(0, x20);
1493     ASSERT_EQUAL_64(0, x21);
1494   }
1495 }
1496 
1497 
TEST(rbit_rev)1498 TEST(rbit_rev) {
1499   SETUP();
1500 
1501   START();
1502   __ Mov(x24, 0xfedcba9876543210);
1503   __ Rbit(w0, w24);
1504   __ Rbit(x1, x24);
1505   __ Rev16(w2, w24);
1506   __ Rev16(x3, x24);
1507   __ Rev(w4, w24);
1508   __ Rev32(x5, x24);
1509   __ Rev64(x6, x24);
1510   __ Rev(x7, x24);
1511   END();
1512 
1513   if (CAN_RUN()) {
1514     RUN();
1515 
1516     ASSERT_EQUAL_64(0x084c2a6e, x0);
1517     ASSERT_EQUAL_64(0x084c2a6e195d3b7f, x1);
1518     ASSERT_EQUAL_64(0x54761032, x2);
1519     ASSERT_EQUAL_64(0xdcfe98ba54761032, x3);
1520     ASSERT_EQUAL_64(0x10325476, x4);
1521     ASSERT_EQUAL_64(0x98badcfe10325476, x5);
1522     ASSERT_EQUAL_64(0x1032547698badcfe, x6);
1523     ASSERT_EQUAL_64(0x1032547698badcfe, x7);
1524   }
1525 }
1526 
1527 typedef void (MacroAssembler::*TestBranchSignature)(const Register& rt,
1528                                                     unsigned bit_pos,
1529                                                     Label* label);
1530 
TbzRangePoolLimitHelper(TestBranchSignature test_branch)1531 static void TbzRangePoolLimitHelper(TestBranchSignature test_branch) {
1532   const int kTbzRange = 32768;
1533   const int kNumLdrLiteral = kTbzRange / 4;
1534   const int fuzz_range = 2;
1535   for (int n = kNumLdrLiteral - fuzz_range; n <= kNumLdrLiteral + fuzz_range;
1536        ++n) {
1537     for (int margin = -32; margin < 32; margin += 4) {
1538       SETUP();
1539 
1540       START();
1541 
1542       // Emit 32KB of literals (equal to the range of TBZ).
1543       for (int i = 0; i < n; ++i) {
1544         __ Ldr(w0, 0x12345678);
1545       }
1546 
1547       const int kLiteralMargin = 128 * KBytes;
1548 
1549       // Emit enough NOPs to be just about to emit the literal pool.
1550       ptrdiff_t end =
1551           masm.GetCursorOffset() + (kLiteralMargin - n * 4 + margin);
1552       while (masm.GetCursorOffset() < end) {
1553         __ Nop();
1554       }
1555 
1556       // Add a TBZ instruction.
1557       Label label;
1558 
1559       (masm.*test_branch)(x0, 2, &label);
1560 
1561       // Add enough NOPs to surpass its range, to make sure we can encode the
1562       // veneer.
1563       end = masm.GetCursorOffset() + (kTbzRange - 4);
1564       {
1565         ExactAssemblyScope scope(&masm,
1566                                  kTbzRange,
1567                                  ExactAssemblyScope::kMaximumSize);
1568         while (masm.GetCursorOffset() < end) __ nop();
1569       }
1570 
1571       // Finally, bind the label.
1572       __ Bind(&label);
1573 
1574       END();
1575 
1576       if (CAN_RUN()) {
1577         RUN();
1578       }
1579     }
1580   }
1581 }
1582 
TEST(test_branch_limits_literal_pool_size_tbz)1583 TEST(test_branch_limits_literal_pool_size_tbz) {
1584   TbzRangePoolLimitHelper(&MacroAssembler::Tbz);
1585 }
1586 
TEST(test_branch_limits_literal_pool_size_tbnz)1587 TEST(test_branch_limits_literal_pool_size_tbnz) {
1588   TbzRangePoolLimitHelper(&MacroAssembler::Tbnz);
1589 }
1590 
TEST(clz_cls)1591 TEST(clz_cls) {
1592   SETUP();
1593 
1594   START();
1595   __ Mov(x24, 0x0008000000800000);
1596   __ Mov(x25, 0xff800000fff80000);
1597   __ Mov(x26, 0);
1598   __ Clz(w0, w24);
1599   __ Clz(x1, x24);
1600   __ Clz(w2, w25);
1601   __ Clz(x3, x25);
1602   __ Clz(w4, w26);
1603   __ Clz(x5, x26);
1604   __ Cls(w6, w24);
1605   __ Cls(x7, x24);
1606   __ Cls(w8, w25);
1607   __ Cls(x9, x25);
1608   __ Cls(w10, w26);
1609   __ Cls(x11, x26);
1610   END();
1611 
1612   if (CAN_RUN()) {
1613     RUN();
1614 
1615     ASSERT_EQUAL_64(8, x0);
1616     ASSERT_EQUAL_64(12, x1);
1617     ASSERT_EQUAL_64(0, x2);
1618     ASSERT_EQUAL_64(0, x3);
1619     ASSERT_EQUAL_64(32, x4);
1620     ASSERT_EQUAL_64(64, x5);
1621     ASSERT_EQUAL_64(7, x6);
1622     ASSERT_EQUAL_64(11, x7);
1623     ASSERT_EQUAL_64(12, x8);
1624     ASSERT_EQUAL_64(8, x9);
1625     ASSERT_EQUAL_64(31, x10);
1626     ASSERT_EQUAL_64(63, x11);
1627   }
1628 }
1629 
1630 
TEST(pacia_pacib_autia_autib)1631 TEST(pacia_pacib_autia_autib) {
1632   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
1633 
1634   START();
1635 
1636   Register pointer = x24;
1637   Register modifier = x25;
1638 
1639   __ Mov(pointer, 0x0000000012345678);
1640   __ Mov(modifier, 0x477d469dec0b8760);
1641 
1642   // Generate PACs using keys A and B.
1643   __ Mov(x0, pointer);
1644   __ Pacia(x0, modifier);
1645 
1646   __ Mov(x1, pointer);
1647   __ Pacib(x1, modifier);
1648 
1649   // Authenticate the pointers above.
1650   __ Mov(x2, x0);
1651   __ Autia(x2, modifier);
1652 
1653   __ Mov(x3, x1);
1654   __ Autib(x3, modifier);
1655 
1656   // Attempt to authenticate incorrect pointers.
1657   __ Mov(x4, x1);
1658   __ Autia(x4, modifier);
1659 
1660   __ Mov(x5, x0);
1661   __ Autib(x5, modifier);
1662 
1663   // Mask out just the PAC code bits.
1664   // TODO: use Simulator::CalculatePACMask in a nice way.
1665   __ And(x0, x0, 0x007f000000000000);
1666   __ And(x1, x1, 0x007f000000000000);
1667 
1668   END();
1669 
1670   if (CAN_RUN()) {
1671     RUN();
1672 
1673     // Check PAC codes have been generated and aren't equal.
1674     // NOTE: with a different ComputePAC implementation, there may be a
1675     // collision.
1676     ASSERT_NOT_EQUAL_64(0, x0);
1677     ASSERT_NOT_EQUAL_64(0, x1);
1678     ASSERT_NOT_EQUAL_64(x0, x1);
1679 
1680     // Pointers correctly authenticated.
1681     ASSERT_EQUAL_64(pointer, x2);
1682     ASSERT_EQUAL_64(pointer, x3);
1683 
1684     // Pointers corrupted after failing to authenticate.
1685     ASSERT_EQUAL_64(0x0020000012345678, x4);
1686     ASSERT_EQUAL_64(0x0040000012345678, x5);
1687   }
1688 }
1689 
1690 
TEST(paciza_pacizb_autiza_autizb)1691 TEST(paciza_pacizb_autiza_autizb) {
1692   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
1693 
1694   START();
1695 
1696   Register pointer = x24;
1697 
1698   __ Mov(pointer, 0x0000000012345678);
1699 
1700   // Generate PACs using keys A and B.
1701   __ Mov(x0, pointer);
1702   __ Paciza(x0);
1703 
1704   __ Mov(x1, pointer);
1705   __ Pacizb(x1);
1706 
1707   // Authenticate the pointers above.
1708   __ Mov(x2, x0);
1709   __ Autiza(x2);
1710 
1711   __ Mov(x3, x1);
1712   __ Autizb(x3);
1713 
1714   // Attempt to authenticate incorrect pointers.
1715   __ Mov(x4, x1);
1716   __ Autiza(x4);
1717 
1718   __ Mov(x5, x0);
1719   __ Autizb(x5);
1720 
1721   // Mask out just the PAC code bits.
1722   // TODO: use Simulator::CalculatePACMask in a nice way.
1723   __ And(x0, x0, 0x007f000000000000);
1724   __ And(x1, x1, 0x007f000000000000);
1725 
1726   END();
1727 
1728   if (CAN_RUN()) {
1729     RUN();
1730 
1731     // Check PAC codes have been generated and aren't equal.
1732     // NOTE: with a different ComputePAC implementation, there may be a
1733     // collision.
1734     ASSERT_NOT_EQUAL_64(0, x0);
1735     ASSERT_NOT_EQUAL_64(0, x1);
1736     ASSERT_NOT_EQUAL_64(x0, x1);
1737 
1738     // Pointers correctly authenticated.
1739     ASSERT_EQUAL_64(pointer, x2);
1740     ASSERT_EQUAL_64(pointer, x3);
1741 
1742     // Pointers corrupted after failing to authenticate.
1743     ASSERT_EQUAL_64(0x0020000012345678, x4);
1744     ASSERT_EQUAL_64(0x0040000012345678, x5);
1745   }
1746 }
1747 
1748 
TEST(pacda_pacdb_autda_autdb)1749 TEST(pacda_pacdb_autda_autdb) {
1750   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
1751 
1752   START();
1753 
1754   Register pointer = x24;
1755   Register modifier = x25;
1756 
1757   __ Mov(pointer, 0x0000000012345678);
1758   __ Mov(modifier, 0x477d469dec0b8760);
1759 
1760   // Generate PACs using keys A and B.
1761   __ Mov(x0, pointer);
1762   __ Pacda(x0, modifier);
1763 
1764   __ Mov(x1, pointer);
1765   __ Pacdb(x1, modifier);
1766 
1767   // Authenticate the pointers above.
1768   __ Mov(x2, x0);
1769   __ Autda(x2, modifier);
1770 
1771   __ Mov(x3, x1);
1772   __ Autdb(x3, modifier);
1773 
1774   // Attempt to authenticate incorrect pointers.
1775   __ Mov(x4, x1);
1776   __ Autda(x4, modifier);
1777 
1778   __ Mov(x5, x0);
1779   __ Autdb(x5, modifier);
1780 
1781   // Mask out just the PAC code bits.
1782   // TODO: use Simulator::CalculatePACMask in a nice way.
1783   __ And(x0, x0, 0x007f000000000000);
1784   __ And(x1, x1, 0x007f000000000000);
1785 
1786   END();
1787 
1788   if (CAN_RUN()) {
1789     RUN();
1790 
1791     // Check PAC codes have been generated and aren't equal.
1792     // NOTE: with a different ComputePAC implementation, there may be a
1793     // collision.
1794     ASSERT_NOT_EQUAL_64(0, x0);
1795     ASSERT_NOT_EQUAL_64(0, x1);
1796     ASSERT_NOT_EQUAL_64(x0, x1);
1797 
1798     // Pointers correctly authenticated.
1799     ASSERT_EQUAL_64(pointer, x2);
1800     ASSERT_EQUAL_64(pointer, x3);
1801 
1802     // Pointers corrupted after failing to authenticate.
1803     ASSERT_EQUAL_64(0x0020000012345678, x4);
1804     ASSERT_EQUAL_64(0x0040000012345678, x5);
1805   }
1806 }
1807 
1808 
TEST(pacdza_pacdzb_autdza_autdzb)1809 TEST(pacdza_pacdzb_autdza_autdzb) {
1810   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
1811 
1812   START();
1813 
1814   Register pointer = x24;
1815 
1816   __ Mov(pointer, 0x0000000012345678);
1817 
1818   // Generate PACs using keys A and B.
1819   __ Mov(x0, pointer);
1820   __ Pacdza(x0);
1821 
1822   __ Mov(x1, pointer);
1823   __ Pacdzb(x1);
1824 
1825   // Authenticate the pointers above.
1826   __ Mov(x2, x0);
1827   __ Autdza(x2);
1828 
1829   __ Mov(x3, x1);
1830   __ Autdzb(x3);
1831 
1832   // Attempt to authenticate incorrect pointers.
1833   __ Mov(x4, x1);
1834   __ Autdza(x4);
1835 
1836   __ Mov(x5, x0);
1837   __ Autdzb(x5);
1838 
1839   // Mask out just the PAC code bits.
1840   // TODO: use Simulator::CalculatePACMask in a nice way.
1841   __ And(x0, x0, 0x007f000000000000);
1842   __ And(x1, x1, 0x007f000000000000);
1843 
1844   END();
1845 
1846   if (CAN_RUN()) {
1847     RUN();
1848 
1849     // Check PAC codes have been generated and aren't equal.
1850     // NOTE: with a different ComputePAC implementation, there may be a
1851     // collision.
1852     ASSERT_NOT_EQUAL_64(0, x0);
1853     ASSERT_NOT_EQUAL_64(0, x1);
1854     ASSERT_NOT_EQUAL_64(x0, x1);
1855 
1856     // Pointers correctly authenticated.
1857     ASSERT_EQUAL_64(pointer, x2);
1858     ASSERT_EQUAL_64(pointer, x3);
1859 
1860     // Pointers corrupted after failing to authenticate.
1861     ASSERT_EQUAL_64(0x0020000012345678, x4);
1862     ASSERT_EQUAL_64(0x0040000012345678, x5);
1863   }
1864 }
1865 
1866 
TEST(pacga_xpaci_xpacd)1867 TEST(pacga_xpaci_xpacd) {
1868   SETUP_WITH_FEATURES(CPUFeatures::kPAuth, CPUFeatures::kPAuthGeneric);
1869 
1870   START();
1871 
1872   Register pointer = x24;
1873   Register modifier = x25;
1874 
1875   __ Mov(pointer, 0x0000000012345678);
1876   __ Mov(modifier, 0x477d469dec0b8760);
1877 
1878   // Generate generic PAC.
1879   __ Pacga(x0, pointer, modifier);
1880 
1881   // Generate PACs using key A.
1882   __ Mov(x1, pointer);
1883   __ Mov(x2, pointer);
1884   __ Pacia(x1, modifier);
1885   __ Pacda(x2, modifier);
1886 
1887   // Strip PACs.
1888   __ Mov(x3, x1);
1889   __ Mov(x4, x2);
1890   __ Xpaci(x3);
1891   __ Xpacd(x4);
1892 
1893   // Mask out just the PAC code bits.
1894   // TODO: use Simulator::CalculatePACMask in a nice way.
1895   __ And(x0, x0, 0xffffffff00000000);
1896   __ And(x1, x1, 0x007f000000000000);
1897   __ And(x2, x2, 0x007f000000000000);
1898 
1899   END();
1900 
1901   if (CAN_RUN()) {
1902     RUN();
1903 
1904 
1905     // Check PAC codes have been generated and aren't equal.
1906     // NOTE: with a different ComputePAC implementation, there may be a
1907     // collision.
1908     ASSERT_NOT_EQUAL_64(0, x0);
1909 
1910     ASSERT_NOT_EQUAL_64(0, x1);
1911     ASSERT_NOT_EQUAL_64(0, x2);
1912     ASSERT_NOT_EQUAL_64(x1, x2);
1913 
1914     ASSERT_EQUAL_64(pointer, x3);
1915     ASSERT_EQUAL_64(pointer, x4);
1916   }
1917 }
1918 
TEST(pac_sp_modifier)1919 TEST(pac_sp_modifier) {
1920   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
1921 
1922   START();
1923 
1924   __ Mov(x0, 0x0000000012345678);
1925   __ Mov(x1, x0);
1926   __ Mov(x10, sp);
1927 
1928   // Generate PACs using sp and register containing a copy of sp.
1929   __ Pacia(x0, x10);
1930   __ Pacia(x1, sp);
1931 
1932   // Authenticate the pointers, exchanging (equal) modifiers.
1933   __ Mov(x2, x0);
1934   __ Mov(x3, x1);
1935   __ Autia(x2, sp);
1936   __ Autia(x3, x10);
1937 
1938   END();
1939 
1940   if (CAN_RUN()) {
1941     RUN();
1942 
1943     ASSERT_EQUAL_64(x0, x1);
1944     ASSERT_EQUAL_64(x2, x3);
1945   }
1946 }
1947 
TEST(label)1948 TEST(label) {
1949   SETUP();
1950 
1951   Label label_1, label_2, label_3, label_4;
1952 
1953   START();
1954   __ Mov(x0, 0x1);
1955   __ Mov(x1, 0x0);
1956   __ Mov(x22, lr);  // Save lr.
1957 
1958   __ B(&label_1);
1959   __ B(&label_1);
1960   __ B(&label_1);  // Multiple branches to the same label.
1961   __ Mov(x0, 0x0);
1962   __ Bind(&label_2);
1963   __ B(&label_3);  // Forward branch.
1964   __ Mov(x0, 0x0);
1965   __ Bind(&label_1);
1966   __ B(&label_2);  // Backward branch.
1967   __ Mov(x0, 0x0);
1968   __ Bind(&label_3);
1969   __ Bl(&label_4);
1970   END();
1971 
1972   __ Bind(&label_4);
1973   __ Mov(x1, 0x1);
1974   __ Mov(lr, x22);
1975   END();
1976 
1977   if (CAN_RUN()) {
1978     RUN();
1979 
1980     ASSERT_EQUAL_64(0x1, x0);
1981     ASSERT_EQUAL_64(0x1, x1);
1982   }
1983 }
1984 
1985 
TEST(label_2)1986 TEST(label_2) {
1987   SETUP();
1988 
1989   Label label_1, label_2, label_3;
1990   Label first_jump_to_3;
1991 
1992   START();
1993   __ Mov(x0, 0x0);
1994 
1995   __ B(&label_1);
1996   ptrdiff_t offset_2 = masm.GetCursorOffset();
1997   __ Orr(x0, x0, 1 << 1);
1998   __ B(&label_3);
1999   ptrdiff_t offset_1 = masm.GetCursorOffset();
2000   __ Orr(x0, x0, 1 << 0);
2001   __ B(&label_2);
2002   ptrdiff_t offset_3 = masm.GetCursorOffset();
2003   __ Tbz(x0, 2, &first_jump_to_3);
2004   __ Orr(x0, x0, 1 << 3);
2005   __ Bind(&first_jump_to_3);
2006   __ Orr(x0, x0, 1 << 2);
2007   __ Tbz(x0, 3, &label_3);
2008 
2009   // Labels 1, 2, and 3 are bound before the current buffer offset. Branches to
2010   // label_1 and label_2 branch respectively forward and backward. Branches to
2011   // label 3 include both forward and backward branches.
2012   masm.BindToOffset(&label_1, offset_1);
2013   masm.BindToOffset(&label_2, offset_2);
2014   masm.BindToOffset(&label_3, offset_3);
2015 
2016   END();
2017 
2018   if (CAN_RUN()) {
2019     RUN();
2020 
2021     ASSERT_EQUAL_64(0xf, x0);
2022   }
2023 }
2024 
2025 
TEST(adr)2026 TEST(adr) {
2027   SETUP();
2028 
2029   Label label_1, label_2, label_3, label_4;
2030 
2031   START();
2032   __ Mov(x0, 0x0);       // Set to non-zero to indicate failure.
2033   __ Adr(x1, &label_3);  // Set to zero to indicate success.
2034 
2035   __ Adr(x2, &label_1);  // Multiple forward references to the same label.
2036   __ Adr(x3, &label_1);
2037   __ Adr(x4, &label_1);
2038 
2039   __ Bind(&label_2);
2040   __ Eor(x5, x2, Operand(x3));  // Ensure that x2,x3 and x4 are identical.
2041   __ Eor(x6, x2, Operand(x4));
2042   __ Orr(x0, x0, Operand(x5));
2043   __ Orr(x0, x0, Operand(x6));
2044   __ Br(x2);  // label_1, label_3
2045 
2046   __ Bind(&label_3);
2047   __ Adr(x2, &label_3);  // Self-reference (offset 0).
2048   __ Eor(x1, x1, Operand(x2));
2049   __ Adr(x2, &label_4);  // Simple forward reference.
2050   __ Br(x2);             // label_4
2051 
2052   __ Bind(&label_1);
2053   __ Adr(x2, &label_3);  // Multiple reverse references to the same label.
2054   __ Adr(x3, &label_3);
2055   __ Adr(x4, &label_3);
2056   __ Adr(x5, &label_2);  // Simple reverse reference.
2057   __ Br(x5);             // label_2
2058 
2059   __ Bind(&label_4);
2060   END();
2061 
2062   if (CAN_RUN()) {
2063     RUN();
2064 
2065     ASSERT_EQUAL_64(0x0, x0);
2066     ASSERT_EQUAL_64(0x0, x1);
2067   }
2068 }
2069 
2070 
2071 // Simple adrp tests: check that labels are linked and handled properly.
2072 // This is similar to the adr test, but all the adrp instructions are put on the
2073 // same page so that they return the same value.
TEST(adrp)2074 TEST(adrp) {
2075   Label start;
2076   Label label_1, label_2, label_3;
2077 
2078   SETUP_CUSTOM(2 * kPageSize, PageOffsetDependentCode);
2079   START();
2080 
2081   // Waste space until the start of a page.
2082   {
2083     ExactAssemblyScope scope(&masm,
2084                              kPageSize,
2085                              ExactAssemblyScope::kMaximumSize);
2086     const uintptr_t kPageOffsetMask = kPageSize - 1;
2087     while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
2088       __ b(&start);
2089     }
2090     __ bind(&start);
2091   }
2092 
2093   // Simple forward reference.
2094   __ Adrp(x0, &label_2);
2095 
2096   __ Bind(&label_1);
2097 
2098   // Multiple forward references to the same label.
2099   __ Adrp(x1, &label_3);
2100   __ Adrp(x2, &label_3);
2101   __ Adrp(x3, &label_3);
2102 
2103   __ Bind(&label_2);
2104 
2105   // Self-reference (offset 0).
2106   __ Adrp(x4, &label_2);
2107 
2108   __ Bind(&label_3);
2109 
2110   // Simple reverse reference.
2111   __ Adrp(x5, &label_1);
2112 
2113   // Multiple reverse references to the same label.
2114   __ Adrp(x6, &label_2);
2115   __ Adrp(x7, &label_2);
2116   __ Adrp(x8, &label_2);
2117 
2118   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&start) < kPageSize);
2119   END();
2120   if (CAN_RUN()) {
2121     RUN();
2122 
2123     uint64_t expected = reinterpret_cast<uint64_t>(
2124         AlignDown(masm.GetLabelAddress<uint64_t*>(&start), kPageSize));
2125     ASSERT_EQUAL_64(expected, x0);
2126     ASSERT_EQUAL_64(expected, x1);
2127     ASSERT_EQUAL_64(expected, x2);
2128     ASSERT_EQUAL_64(expected, x3);
2129     ASSERT_EQUAL_64(expected, x4);
2130     ASSERT_EQUAL_64(expected, x5);
2131     ASSERT_EQUAL_64(expected, x6);
2132     ASSERT_EQUAL_64(expected, x7);
2133     ASSERT_EQUAL_64(expected, x8);
2134   }
2135 }
2136 
2137 
AdrpPageBoundaryHelper(unsigned offset_into_page)2138 static void AdrpPageBoundaryHelper(unsigned offset_into_page) {
2139   VIXL_ASSERT(offset_into_page < kPageSize);
2140   VIXL_ASSERT((offset_into_page % kInstructionSize) == 0);
2141 
2142   const uintptr_t kPageOffsetMask = kPageSize - 1;
2143 
2144   // The test label is always bound on page 0. Adrp instructions are generated
2145   // on pages from kStartPage to kEndPage (inclusive).
2146   const int kStartPage = -16;
2147   const int kEndPage = 16;
2148   const int kMaxCodeSize = (kEndPage - kStartPage + 2) * kPageSize;
2149 
2150   SETUP_CUSTOM(kMaxCodeSize, PageOffsetDependentCode);
2151   START();
2152 
2153   Label test;
2154   Label start;
2155 
2156   {
2157     ExactAssemblyScope scope(&masm,
2158                              kMaxCodeSize,
2159                              ExactAssemblyScope::kMaximumSize);
2160     // Initialize NZCV with `eq` flags.
2161     __ cmp(wzr, wzr);
2162     // Waste space until the start of a page.
2163     while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
2164       __ b(&start);
2165     }
2166 
2167     // The first page.
2168     VIXL_STATIC_ASSERT(kStartPage < 0);
2169     {
2170       ExactAssemblyScope scope_page(&masm, kPageSize);
2171       __ bind(&start);
2172       __ adrp(x0, &test);
2173       __ adrp(x1, &test);
2174       for (size_t i = 2; i < (kPageSize / kInstructionSize); i += 2) {
2175         __ ccmp(x0, x1, NoFlag, eq);
2176         __ adrp(x1, &test);
2177       }
2178     }
2179 
2180     // Subsequent pages.
2181     VIXL_STATIC_ASSERT(kEndPage >= 0);
2182     for (int page = (kStartPage + 1); page <= kEndPage; page++) {
2183       ExactAssemblyScope scope_page(&masm, kPageSize);
2184       if (page == 0) {
2185         for (size_t i = 0; i < (kPageSize / kInstructionSize);) {
2186           if (i++ == (offset_into_page / kInstructionSize)) __ bind(&test);
2187           __ ccmp(x0, x1, NoFlag, eq);
2188           if (i++ == (offset_into_page / kInstructionSize)) __ bind(&test);
2189           __ adrp(x1, &test);
2190         }
2191       } else {
2192         for (size_t i = 0; i < (kPageSize / kInstructionSize); i += 2) {
2193           __ ccmp(x0, x1, NoFlag, eq);
2194           __ adrp(x1, &test);
2195         }
2196       }
2197     }
2198   }
2199 
2200   // Every adrp instruction pointed to the same label (`test`), so they should
2201   // all have produced the same result.
2202 
2203   END();
2204   if (CAN_RUN()) {
2205     RUN();
2206 
2207     uintptr_t expected =
2208         AlignDown(masm.GetLabelAddress<uintptr_t>(&test), kPageSize);
2209     ASSERT_EQUAL_64(expected, x0);
2210     ASSERT_EQUAL_64(expected, x1);
2211     ASSERT_EQUAL_NZCV(ZCFlag);
2212   }
2213 }
2214 
2215 
2216 // Test that labels are correctly referenced by adrp across page boundaries.
2217 TEST(adrp_page_boundaries) {
2218   VIXL_STATIC_ASSERT(kPageSize == 4096);
2219   AdrpPageBoundaryHelper(kInstructionSize * 0);
2220   AdrpPageBoundaryHelper(kInstructionSize * 1);
2221   AdrpPageBoundaryHelper(kInstructionSize * 512);
2222   AdrpPageBoundaryHelper(kInstructionSize * 1022);
2223   AdrpPageBoundaryHelper(kInstructionSize * 1023);
2224 }
2225 
2226 
2227 static void AdrpOffsetHelper(int64_t offset) {
2228   const size_t kPageOffsetMask = kPageSize - 1;
2229   const int kMaxCodeSize = 2 * kPageSize;
2230 
2231   SETUP_CUSTOM(kMaxCodeSize, PageOffsetDependentCode);
2232   START();
2233 
2234   Label page;
2235 
2236   {
2237     ExactAssemblyScope scope(&masm,
2238                              kMaxCodeSize,
2239                              ExactAssemblyScope::kMaximumSize);
2240     // Initialize NZCV with `eq` flags.
2241     __ cmp(wzr, wzr);
2242     // Waste space until the start of a page.
2243     while ((masm.GetCursorAddress<uintptr_t>() & kPageOffsetMask) != 0) {
2244       __ b(&page);
2245     }
2246     __ bind(&page);
2247 
2248     {
2249       ExactAssemblyScope scope_page(&masm, kPageSize);
2250       // Every adrp instruction on this page should return the same value.
2251       __ adrp(x0, offset);
2252       __ adrp(x1, offset);
2253       for (size_t i = 2; i < kPageSize / kInstructionSize; i += 2) {
2254         __ ccmp(x0, x1, NoFlag, eq);
2255         __ adrp(x1, offset);
2256       }
2257     }
2258   }
2259 
2260   END();
2261   if (CAN_RUN()) {
2262     RUN();
2263 
2264     uintptr_t expected =
2265         masm.GetLabelAddress<uintptr_t>(&page) + (kPageSize * offset);
2266     ASSERT_EQUAL_64(expected, x0);
2267     ASSERT_EQUAL_64(expected, x1);
2268     ASSERT_EQUAL_NZCV(ZCFlag);
2269   }
2270 }
2271 
2272 
2273 // Check that adrp produces the correct result for a specific offset.
2274 TEST(adrp_offset) {
2275   AdrpOffsetHelper(0);
2276   AdrpOffsetHelper(1);
2277   AdrpOffsetHelper(-1);
2278   AdrpOffsetHelper(4);
2279   AdrpOffsetHelper(-4);
2280   AdrpOffsetHelper(0x000fffff);
2281   AdrpOffsetHelper(-0x000fffff);
2282   AdrpOffsetHelper(-0x00100000);
2283 }
2284 
2285 
2286 TEST(branch_cond) {
2287   SETUP();
2288 
2289   Label done, wrong;
2290 
2291   START();
2292   __ Mov(x0, 0x1);
2293   __ Mov(x1, 0x1);
2294   __ Mov(x2, 0x8000000000000000);
2295 
2296   // For each 'cmp' instruction below, condition codes other than the ones
2297   // following it would branch.
2298 
2299   __ Cmp(x1, 0);
2300   __ B(&wrong, eq);
2301   __ B(&wrong, lo);
2302   __ B(&wrong, mi);
2303   __ B(&wrong, vs);
2304   __ B(&wrong, ls);
2305   __ B(&wrong, lt);
2306   __ B(&wrong, le);
2307   Label ok_1;
2308   __ B(&ok_1, ne);
2309   __ Mov(x0, 0x0);
2310   __ Bind(&ok_1);
2311 
2312   __ Cmp(x1, 1);
2313   __ B(&wrong, ne);
2314   __ B(&wrong, lo);
2315   __ B(&wrong, mi);
2316   __ B(&wrong, vs);
2317   __ B(&wrong, hi);
2318   __ B(&wrong, lt);
2319   __ B(&wrong, gt);
2320   Label ok_2;
2321   __ B(&ok_2, pl);
2322   __ Mov(x0, 0x0);
2323   __ Bind(&ok_2);
2324 
2325   __ Cmp(x1, 2);
2326   __ B(&wrong, eq);
2327   __ B(&wrong, hs);
2328   __ B(&wrong, pl);
2329   __ B(&wrong, vs);
2330   __ B(&wrong, hi);
2331   __ B(&wrong, ge);
2332   __ B(&wrong, gt);
2333   Label ok_3;
2334   __ B(&ok_3, vc);
2335   __ Mov(x0, 0x0);
2336   __ Bind(&ok_3);
2337 
2338   __ Cmp(x2, 1);
2339   __ B(&wrong, eq);
2340   __ B(&wrong, lo);
2341   __ B(&wrong, mi);
2342   __ B(&wrong, vc);
2343   __ B(&wrong, ls);
2344   __ B(&wrong, ge);
2345   __ B(&wrong, gt);
2346   Label ok_4;
2347   __ B(&ok_4, le);
2348   __ Mov(x0, 0x0);
2349   __ Bind(&ok_4);
2350 
2351   // The MacroAssembler does not allow al as a branch condition.
2352   Label ok_5;
2353   {
2354     ExactAssemblyScope scope(&masm, kInstructionSize);
2355     __ b(&ok_5, al);
2356   }
2357   __ Mov(x0, 0x0);
2358   __ Bind(&ok_5);
2359 
2360   // The MacroAssembler does not allow nv as a branch condition.
2361   Label ok_6;
2362   {
2363     ExactAssemblyScope scope(&masm, kInstructionSize);
2364     __ b(&ok_6, nv);
2365   }
2366   __ Mov(x0, 0x0);
2367   __ Bind(&ok_6);
2368 
2369   __ B(&done);
2370 
2371   __ Bind(&wrong);
2372   __ Mov(x0, 0x0);
2373 
2374   __ Bind(&done);
2375   END();
2376 
2377   if (CAN_RUN()) {
2378     RUN();
2379 
2380     ASSERT_EQUAL_64(0x1, x0);
2381   }
2382 }
2383 
2384 
2385 TEST(branch_to_reg) {
2386   SETUP();
2387 
2388   // Test br.
2389   Label fn1, after_fn1;
2390 
2391   START();
2392   __ Mov(x29, lr);
2393 
2394   __ Mov(x1, 0);
2395   __ B(&after_fn1);
2396 
2397   __ Bind(&fn1);
2398   __ Mov(x0, lr);
2399   __ Mov(x1, 42);
2400   __ Br(x0);
2401 
2402   __ Bind(&after_fn1);
2403   __ Bl(&fn1);
2404 
2405   // Test blr.
2406   Label fn2, after_fn2, after_bl2;
2407 
2408   __ Mov(x2, 0);
2409   __ B(&after_fn2);
2410 
2411   __ Bind(&fn2);
2412   __ Mov(x0, lr);
2413   __ Mov(x2, 84);
2414   __ Blr(x0);
2415 
2416   __ Bind(&after_fn2);
2417   __ Bl(&fn2);
2418   __ Bind(&after_bl2);
2419   __ Mov(x3, lr);
2420   __ Adr(x4, &after_bl2);
2421   __ Adr(x5, &after_fn2);
2422 
2423   __ Mov(lr, x29);
2424   END();
2425 
2426   if (CAN_RUN()) {
2427     RUN();
2428 
2429     ASSERT_EQUAL_64(x4, x0);
2430     ASSERT_EQUAL_64(x5, x3);
2431     ASSERT_EQUAL_64(42, x1);
2432     ASSERT_EQUAL_64(84, x2);
2433   }
2434 }
2435 
2436 TEST(branch_to_reg_auth_a) {
2437   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
2438 
2439   START();
2440 
2441   Label fn1, after_fn1;
2442 
2443   __ Mov(x28, 0x477d469dec0b8760);
2444   __ Mov(x29, lr);
2445 
2446   __ Mov(x1, 0);
2447   __ B(&after_fn1);
2448 
2449   __ Bind(&fn1);
2450   __ Mov(x0, lr);
2451   __ Mov(x1, 42);
2452   __ Pacia(x0, x28);
2453   __ Braa(x0, x28);
2454 
2455   __ Bind(&after_fn1);
2456   __ Bl(&fn1);
2457 
2458   Label fn2, after_fn2, after_bl2;
2459 
2460   __ Mov(x2, 0);
2461   __ B(&after_fn2);
2462 
2463   __ Bind(&fn2);
2464   __ Mov(x0, lr);
2465   __ Mov(x2, 84);
2466   __ Pacia(x0, x28);
2467   __ Blraa(x0, x28);
2468 
2469   __ Bind(&after_fn2);
2470   __ Bl(&fn2);
2471   __ Bind(&after_bl2);
2472   __ Mov(x3, lr);
2473   __ Adr(x4, &after_bl2);
2474   __ Adr(x5, &after_fn2);
2475 
2476   __ Xpaci(x0);
2477   __ Mov(lr, x29);
2478   END();
2479 
2480   if (CAN_RUN()) {
2481     RUN();
2482 
2483     ASSERT_EQUAL_64(x4, x0);
2484     ASSERT_EQUAL_64(x5, x3);
2485     ASSERT_EQUAL_64(42, x1);
2486     ASSERT_EQUAL_64(84, x2);
2487   }
2488 }
2489 
2490 TEST(return_to_reg_auth) {
2491   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
2492 
2493   START();
2494 
2495   Label fn1, after_fn1;
2496 
2497   __ Mov(x28, sp);
2498   __ Mov(x29, lr);
2499   __ Mov(sp, 0x477d469dec0b8760);
2500 
2501   __ Mov(x0, 0);
2502   __ B(&after_fn1);
2503 
2504   __ Bind(&fn1);
2505   __ Mov(x0, 42);
2506   __ Paciasp();
2507   __ Retaa();
2508 
2509   __ Bind(&after_fn1);
2510   __ Bl(&fn1);
2511 
2512   Label fn2, after_fn2;
2513 
2514   __ Mov(x1, 0);
2515   __ B(&after_fn2);
2516 
2517   __ Bind(&fn2);
2518   __ Mov(x1, 84);
2519   __ Pacibsp();
2520   __ Retab();
2521 
2522   __ Bind(&after_fn2);
2523   __ Bl(&fn2);
2524 
2525   __ Mov(sp, x28);
2526   __ Mov(lr, x29);
2527   END();
2528 
2529   if (CAN_RUN()) {
2530     RUN();
2531 
2532     ASSERT_EQUAL_64(42, x0);
2533     ASSERT_EQUAL_64(84, x1);
2534   }
2535 }
2536 
2537 TEST(return_to_reg_auth_guarded) {
2538   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
2539 
2540   START();
2541 
2542   Label fn1, after_fn1;
2543 
2544   __ Mov(x28, sp);
2545   __ Mov(x29, lr);
2546   __ Mov(sp, 0x477d469dec0b8760);
2547 
2548   __ Mov(x0, 0);
2549   __ B(&after_fn1);
2550 
2551   __ Bind(&fn1, EmitPACIASP);
2552   __ Mov(x0, 42);
2553   __ Retaa();
2554 
2555   __ Bind(&after_fn1);
2556   __ Adr(x2, &fn1);
2557   __ Blr(x2);
2558 
2559   Label fn2, after_fn2;
2560 
2561   __ Mov(x1, 0);
2562   __ B(&after_fn2);
2563 
2564   __ Bind(&fn2, EmitPACIBSP);
2565   __ Mov(x1, 84);
2566   __ Retab();
2567 
2568   __ Bind(&after_fn2);
2569   __ Adr(x2, &fn2);
2570   __ Blr(x2);
2571 
2572   __ Mov(sp, x28);
2573   __ Mov(lr, x29);
2574   END();
2575 
2576   if (CAN_RUN()) {
2577 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
2578     simulator.SetGuardedPages(true);
2579 #else
2580     VIXL_UNIMPLEMENTED();
2581 #endif
2582     RUN();
2583 
2584     ASSERT_EQUAL_64(42, x0);
2585     ASSERT_EQUAL_64(84, x1);
2586   }
2587 }
2588 
2589 #ifdef VIXL_NEGATIVE_TESTING
2590 TEST(branch_to_reg_auth_fail) {
2591   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
2592 
2593   START();
2594 
2595   Label fn1, after_fn1;
2596 
2597   __ Mov(x29, lr);
2598 
2599   __ B(&after_fn1);
2600 
2601   __ Bind(&fn1);
2602   __ Mov(x0, lr);
2603   __ Pacizb(x0);
2604   __ Blraaz(x0);
2605 
2606   __ Bind(&after_fn1);
2607   // There is a small but not negligible chance (1 in 127 runs) that the PAC
2608   // codes for keys A and B will collide and BLRAAZ won't abort. To mitigate
2609   // this, we simply repeat the test a few more times.
2610   for (unsigned i = 0; i < 32; i++) {
2611     __ Bl(&fn1);
2612   }
2613 
2614   __ Mov(lr, x29);
2615   END();
2616 
2617   if (CAN_RUN()) {
2618     MUST_FAIL_WITH_MESSAGE(RUN(), "Failed to authenticate pointer.");
2619   }
2620 }
2621 #endif  // VIXL_NEGATIVE_TESTING
2622 
2623 #ifdef VIXL_NEGATIVE_TESTING
2624 TEST(return_to_reg_auth_fail) {
2625   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
2626 
2627   START();
2628 
2629   Label fn1, after_fn1;
2630 
2631   __ Mov(x28, sp);
2632   __ Mov(x29, lr);
2633   __ Mov(sp, 0x477d469dec0b8760);
2634 
2635   __ B(&after_fn1);
2636 
2637   __ Bind(&fn1);
2638   __ Paciasp();
2639   __ Retab();
2640 
2641   __ Bind(&after_fn1);
2642   // There is a small but not negligible chance (1 in 127 runs) that the PAC
2643   // codes for keys A and B will collide and RETAB won't abort. To mitigate
2644   // this, we simply repeat the test a few more times.
2645   for (unsigned i = 0; i < 32; i++) {
2646     __ Bl(&fn1);
2647   }
2648 
2649   __ Mov(sp, x28);
2650   __ Mov(lr, x29);
2651   END();
2652 
2653   if (CAN_RUN()) {
2654     MUST_FAIL_WITH_MESSAGE(RUN(), "Failed to authenticate pointer.");
2655   }
2656 }
2657 #endif  // VIXL_NEGATIVE_TESTING
2658 
2659 TEST(branch_to_reg_auth_a_zero) {
2660   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
2661 
2662   START();
2663 
2664   Label fn1, after_fn1;
2665 
2666   __ Mov(x29, lr);
2667 
2668   __ Mov(x1, 0);
2669   __ B(&after_fn1);
2670 
2671   __ Bind(&fn1);
2672   __ Mov(x0, lr);
2673   __ Mov(x1, 42);
2674   __ Paciza(x0);
2675   __ Braaz(x0);
2676 
2677   __ Bind(&after_fn1);
2678   __ Bl(&fn1);
2679 
2680   Label fn2, after_fn2, after_bl2;
2681 
2682   __ Mov(x2, 0);
2683   __ B(&after_fn2);
2684 
2685   __ Bind(&fn2);
2686   __ Mov(x0, lr);
2687   __ Mov(x2, 84);
2688   __ Paciza(x0);
2689   __ Blraaz(x0);
2690 
2691   __ Bind(&after_fn2);
2692   __ Bl(&fn2);
2693   __ Bind(&after_bl2);
2694   __ Mov(x3, lr);
2695   __ Adr(x4, &after_bl2);
2696   __ Adr(x5, &after_fn2);
2697 
2698   __ Xpaci(x0);
2699   __ Mov(lr, x29);
2700   END();
2701 
2702   if (CAN_RUN()) {
2703     RUN();
2704 
2705     ASSERT_EQUAL_64(x4, x0);
2706     ASSERT_EQUAL_64(x5, x3);
2707     ASSERT_EQUAL_64(42, x1);
2708     ASSERT_EQUAL_64(84, x2);
2709   }
2710 }
2711 
2712 
2713 TEST(compare_branch) {
2714   SETUP();
2715 
2716   START();
2717   __ Mov(x0, 0);
2718   __ Mov(x1, 0);
2719   __ Mov(x2, 0);
2720   __ Mov(x3, 0);
2721   __ Mov(x4, 0);
2722   __ Mov(x5, 0);
2723   __ Mov(x16, 0);
2724   __ Mov(x17, 42);
2725 
2726   Label zt, zt_end;
2727   __ Cbz(w16, &zt);
2728   __ B(&zt_end);
2729   __ Bind(&zt);
2730   __ Mov(x0, 1);
2731   __ Bind(&zt_end);
2732 
2733   Label zf, zf_end;
2734   __ Cbz(x17, &zf);
2735   __ B(&zf_end);
2736   __ Bind(&zf);
2737   __ Mov(x1, 1);
2738   __ Bind(&zf_end);
2739 
2740   Label nzt, nzt_end;
2741   __ Cbnz(w17, &nzt);
2742   __ B(&nzt_end);
2743   __ Bind(&nzt);
2744   __ Mov(x2, 1);
2745   __ Bind(&nzt_end);
2746 
2747   Label nzf, nzf_end;
2748   __ Cbnz(x16, &nzf);
2749   __ B(&nzf_end);
2750   __ Bind(&nzf);
2751   __ Mov(x3, 1);
2752   __ Bind(&nzf_end);
2753 
2754   __ Mov(x18, 0xffffffff00000000);
2755 
2756   Label a, a_end;
2757   __ Cbz(w18, &a);
2758   __ B(&a_end);
2759   __ Bind(&a);
2760   __ Mov(x4, 1);
2761   __ Bind(&a_end);
2762 
2763   Label b, b_end;
2764   __ Cbnz(w18, &b);
2765   __ B(&b_end);
2766   __ Bind(&b);
2767   __ Mov(x5, 1);
2768   __ Bind(&b_end);
2769 
2770   END();
2771 
2772   if (CAN_RUN()) {
2773     RUN();
2774 
2775     ASSERT_EQUAL_64(1, x0);
2776     ASSERT_EQUAL_64(0, x1);
2777     ASSERT_EQUAL_64(1, x2);
2778     ASSERT_EQUAL_64(0, x3);
2779     ASSERT_EQUAL_64(1, x4);
2780     ASSERT_EQUAL_64(0, x5);
2781   }
2782 }
2783 
2784 
2785 TEST(test_branch) {
2786   SETUP();
2787 
2788   START();
2789   __ Mov(x0, 0);
2790   __ Mov(x1, 0);
2791   __ Mov(x2, 0);
2792   __ Mov(x3, 0);
2793   __ Mov(x16, 0xaaaaaaaaaaaaaaaa);
2794 
2795   Label bz, bz_end;
2796   __ Tbz(w16, 0, &bz);
2797   __ B(&bz_end);
2798   __ Bind(&bz);
2799   __ Mov(x0, 1);
2800   __ Bind(&bz_end);
2801 
2802   Label bo, bo_end;
2803   __ Tbz(x16, 63, &bo);
2804   __ B(&bo_end);
2805   __ Bind(&bo);
2806   __ Mov(x1, 1);
2807   __ Bind(&bo_end);
2808 
2809   Label nbz, nbz_end;
2810   __ Tbnz(x16, 61, &nbz);
2811   __ B(&nbz_end);
2812   __ Bind(&nbz);
2813   __ Mov(x2, 1);
2814   __ Bind(&nbz_end);
2815 
2816   Label nbo, nbo_end;
2817   __ Tbnz(w16, 2, &nbo);
2818   __ B(&nbo_end);
2819   __ Bind(&nbo);
2820   __ Mov(x3, 1);
2821   __ Bind(&nbo_end);
2822   END();
2823 
2824   if (CAN_RUN()) {
2825     RUN();
2826 
2827     ASSERT_EQUAL_64(1, x0);
2828     ASSERT_EQUAL_64(0, x1);
2829     ASSERT_EQUAL_64(1, x2);
2830     ASSERT_EQUAL_64(0, x3);
2831   }
2832 }
2833 
2834 
2835 TEST(branch_type) {
2836   SETUP();
2837 
2838   Label fail, done;
2839 
2840   START();
2841   __ Mov(x0, 0x0);
2842   __ Mov(x10, 0x7);
2843   __ Mov(x11, 0x0);
2844 
2845   // Test non taken branches.
2846   __ Cmp(x10, 0x7);
2847   __ B(&fail, ne);
2848   __ B(&fail, never);
2849   __ B(&fail, reg_zero, x10);
2850   __ B(&fail, reg_not_zero, x11);
2851   __ B(&fail, reg_bit_clear, x10, 0);
2852   __ B(&fail, reg_bit_set, x10, 3);
2853 
2854   // Test taken branches.
2855   Label l1, l2, l3, l4, l5;
2856   __ Cmp(x10, 0x7);
2857   __ B(&l1, eq);
2858   __ B(&fail);
2859   __ Bind(&l1);
2860   __ B(&l2, always);
2861   __ B(&fail);
2862   __ Bind(&l2);
2863   __ B(&l3, reg_not_zero, x10);
2864   __ B(&fail);
2865   __ Bind(&l3);
2866   __ B(&l4, reg_bit_clear, x10, 15);
2867   __ B(&fail);
2868   __ Bind(&l4);
2869   __ B(&l5, reg_bit_set, x10, 1);
2870   __ B(&fail);
2871   __ Bind(&l5);
2872 
2873   __ B(&done);
2874 
2875   __ Bind(&fail);
2876   __ Mov(x0, 0x1);
2877 
2878   __ Bind(&done);
2879 
2880   END();
2881 
2882   if (CAN_RUN()) {
2883     RUN();
2884 
2885     ASSERT_EQUAL_64(0x0, x0);
2886   }
2887 }
2888 
2889 enum MTEStgAttribute {
2890   StgNoSideEffect = 0,
2891   StgPairTag = 1,
2892   StgZeroing = 2,
2893   StgPairReg = 4
2894 };
2895 
2896 // Support st2g, stg, stz2g and stzg.
2897 template <typename Op>
2898 static void MTEStoreTagHelper(Op op,
2899                               AddrMode addr_mode,
2900                               int attr = StgNoSideEffect) {
2901   SETUP_WITH_FEATURES(CPUFeatures::kMTE);
2902   START();
2903 
2904   // This method does nothing when the size is zero. i.e. stg and st2g.
2905   // Reserve x9 and x10.
2906   auto LoadDataAndSum = [&](Register reg, int off, unsigned size_in_bytes) {
2907     for (unsigned j = 0; j < size_in_bytes / kXRegSizeInBytes; j++) {
2908       __ Ldr(x9, MemOperand(reg, off));
2909       __ Add(x10, x9, x10);
2910       off += kXRegSizeInBytes;
2911     }
2912   };
2913 
2914   // Initialize registers to zero.
2915   for (int i = 0; i < 29; i++) {
2916     __ Mov(XRegister(i), 0);
2917   }
2918 
2919   Register base = x28;
2920   Register base_tag = x27;
2921   uint32_t* data_ptr = nullptr;
2922   const int data_size = 640;
2923 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
2924   data_ptr = reinterpret_cast<uint32_t*>(
2925       simulator.Mmap(NULL,
2926                      data_size * sizeof(uint32_t),
2927                      PROT_READ | PROT_WRITE | PROT_MTE,
2928                      MAP_PRIVATE | MAP_ANONYMOUS,
2929                      -1,
2930                      0));
2931 
2932   VIXL_ASSERT(data_ptr != nullptr);
2933   uint32_t* untagged_ptr = AddressUntag(data_ptr);
2934   memset(untagged_ptr, 0xae, data_size * sizeof(uint32_t));
2935 #else
2936 // TODO: Port the memory allocation to work on MTE supported platform natively.
2937 // Note that `CAN_RUN` prevents running in MTE-unsupported environments.
2938 #endif
2939 
2940   __ Mov(base, reinterpret_cast<uint64_t>(&data_ptr[data_size / 2]));
2941 
2942   VIXL_STATIC_ASSERT(kMTETagGranuleInBytes == 16);
2943   const int tag_granule = kMTETagGranuleInBytes;
2944   int size = ((attr & StgZeroing) != 0) ? tag_granule : 0;
2945   // lsb of MTE tag field.
2946   const int tag_lsb = 56;
2947 
2948   for (int i = 1; i < 7; i++) {
2949     uint64_t tag = static_cast<uint64_t>(i) << tag_lsb;
2950     int offset = 2 * i * tag_granule;
2951     __ Mov(XRegister(i), tag);
2952     (masm.*op)(XRegister(i), MemOperand(base, offset, addr_mode));
2953 
2954     // The address tag has been changed after the execution of store tag
2955     // instructions, so update the pointer tag as well.
2956     __ Bic(base_tag, base, 0x0f00000000000000);
2957     __ Orr(base_tag, base_tag, XRegister(i));
2958 
2959     switch (addr_mode) {
2960       case Offset:
2961         __ Ldg(XRegister(i + 10), MemOperand(base_tag, offset));
2962         LoadDataAndSum(base_tag, offset, size);
2963         if ((attr & StgPairTag) != 0) {
2964           __ Ldg(XRegister(i + 20), MemOperand(base_tag, offset + tag_granule));
2965           LoadDataAndSum(base_tag, offset + tag_granule, size);
2966         }
2967         break;
2968 
2969       case PreIndex:
2970         __ Ldg(XRegister(i + 10), MemOperand(base_tag));
2971         LoadDataAndSum(base_tag, 0, size);
2972         if ((attr & StgPairTag) != 0) {
2973           __ Ldg(XRegister(i + 20), MemOperand(base_tag, tag_granule));
2974           LoadDataAndSum(base_tag, tag_granule, size);
2975         }
2976         break;
2977 
2978       case PostIndex:
2979         __ Ldg(XRegister(i + 10), MemOperand(base_tag, -offset));
2980         LoadDataAndSum(base_tag, -offset, size);
2981         if ((attr & StgPairTag) != 0) {
2982           __ Ldg(XRegister(i + 20),
2983                  MemOperand(base_tag, -offset + tag_granule));
2984           LoadDataAndSum(base_tag, -offset + tag_granule, size);
2985         }
2986         break;
2987 
2988       default:
2989         VIXL_UNIMPLEMENTED();
2990         break;
2991     }
2992 
2993     // Switch the sign to test both positive and negative offsets.
2994     offset = -offset;
2995   }
2996 
2997   int pos_offset = 304;
2998   int neg_offset = -256;
2999 
3000   // Backup stack pointer and others.
3001   __ Mov(x7, sp);
3002   __ Mov(base_tag, base);
3003 
3004   // Test the cases where operand is the stack pointer.
3005   __ Mov(x8, 11UL << tag_lsb);
3006   __ Mov(sp, x8);
3007   (masm.*op)(sp, MemOperand(base, neg_offset, addr_mode));
3008 
3009   // Synthesise a new address with new tag and assign to the stack pointer.
3010   __ Add(sp, base_tag, 32);
3011   (masm.*op)(x8, MemOperand(sp, pos_offset, addr_mode));
3012 
3013   switch (addr_mode) {
3014     case Offset:
3015       __ Ldg(x17, MemOperand(base, neg_offset));
3016       __ Ldg(x19, MemOperand(sp, pos_offset));
3017       if ((attr & StgPairTag) != 0) {
3018         __ Ldg(x18, MemOperand(base, neg_offset + tag_granule));
3019         __ Ldg(x20, MemOperand(sp, pos_offset + tag_granule));
3020       }
3021       break;
3022     case PreIndex:
3023       __ Ldg(x17, MemOperand(base));
3024       __ Ldg(x19, MemOperand(sp));
3025       if ((attr & StgPairTag) != 0) {
3026         __ Ldg(x18, MemOperand(base, tag_granule));
3027         __ Ldg(x20, MemOperand(sp, tag_granule));
3028       }
3029       break;
3030     case PostIndex:
3031       __ Ldg(x17, MemOperand(base, -neg_offset));
3032       __ Ldg(x19, MemOperand(sp, -pos_offset));
3033       if ((attr & StgPairTag) != 0) {
3034         __ Ldg(x18, MemOperand(base, -neg_offset + tag_granule));
3035         __ Ldg(x20, MemOperand(sp, -pos_offset + tag_granule));
3036       }
3037       break;
3038     default:
3039       VIXL_UNIMPLEMENTED();
3040       break;
3041   }
3042 
3043   // Restore stack pointer.
3044   __ Mov(sp, x7);
3045 
3046   END();
3047 
3048   if (CAN_RUN()) {
3049 #ifndef VIXL_INCLUDE_SIMULATOR_AARCH64
3050     VIXL_UNIMPLEMENTED();
3051 #endif
3052     RUN();
3053 
3054     ASSERT_EQUAL_64(1UL << tag_lsb, x11);
3055     ASSERT_EQUAL_64(2UL << tag_lsb, x12);
3056     ASSERT_EQUAL_64(3UL << tag_lsb, x13);
3057     ASSERT_EQUAL_64(4UL << tag_lsb, x14);
3058     ASSERT_EQUAL_64(5UL << tag_lsb, x15);
3059     ASSERT_EQUAL_64(6UL << tag_lsb, x16);
3060     ASSERT_EQUAL_64(11UL << tag_lsb, x17);
3061     ASSERT_EQUAL_64(11UL << tag_lsb, x19);
3062 
3063     if ((attr & StgPairTag) != 0) {
3064       ASSERT_EQUAL_64(1UL << tag_lsb, x21);
3065       ASSERT_EQUAL_64(2UL << tag_lsb, x22);
3066       ASSERT_EQUAL_64(3UL << tag_lsb, x23);
3067       ASSERT_EQUAL_64(4UL << tag_lsb, x24);
3068       ASSERT_EQUAL_64(5UL << tag_lsb, x25);
3069       ASSERT_EQUAL_64(6UL << tag_lsb, x26);
3070       ASSERT_EQUAL_64(11UL << tag_lsb, x18);
3071       ASSERT_EQUAL_64(11UL << tag_lsb, x20);
3072     }
3073 
3074     if ((attr & StgZeroing) != 0) {
3075       ASSERT_EQUAL_64(0, x10);
3076     }
3077   }
3078 
3079 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
3080   simulator.Munmap(data_ptr, data_size, PROT_MTE);
3081 #endif
3082 }
3083 
3084 TEST(st2g_ldg) {
3085   MTEStoreTagHelper(&MacroAssembler::St2g, Offset, StgPairTag);
3086   MTEStoreTagHelper(&MacroAssembler::St2g, PreIndex, StgPairTag);
3087   MTEStoreTagHelper(&MacroAssembler::St2g, PostIndex, StgPairTag);
3088 }
3089 
3090 TEST(stg_ldg) {
3091   MTEStoreTagHelper(&MacroAssembler::Stg, Offset);
3092   MTEStoreTagHelper(&MacroAssembler::Stg, PreIndex);
3093   MTEStoreTagHelper(&MacroAssembler::Stg, PostIndex);
3094 }
3095 
3096 TEST(stz2g_ldg) {
3097   MTEStoreTagHelper(&MacroAssembler::Stz2g, Offset, StgPairTag | StgZeroing);
3098   MTEStoreTagHelper(&MacroAssembler::Stz2g, PreIndex, StgPairTag | StgZeroing);
3099   MTEStoreTagHelper(&MacroAssembler::Stz2g, PostIndex, StgPairTag | StgZeroing);
3100 }
3101 
3102 TEST(stzg_ldg) {
3103   MTEStoreTagHelper(&MacroAssembler::Stzg, Offset, StgZeroing);
3104   MTEStoreTagHelper(&MacroAssembler::Stzg, PreIndex, StgZeroing);
3105   MTEStoreTagHelper(&MacroAssembler::Stzg, PostIndex, StgZeroing);
3106 }
3107 
3108 TEST(stgp_ldg) {
3109   SETUP_WITH_FEATURES(CPUFeatures::kMTE);
3110   START();
3111 
3112   // Initialize registers to zero.
3113   for (int i = 0; i < 29; i++) {
3114     __ Mov(XRegister(i), 0);
3115   }
3116 
3117   // Reserve x14 and x15.
3118   auto LoadDataAndSum = [&](Register reg, int off) {
3119     __ Ldr(x14, MemOperand(reg, off));
3120     __ Add(x15, x14, x15);
3121     __ Ldr(x14, MemOperand(reg, off + static_cast<int>(kXRegSizeInBytes)));
3122     __ Add(x15, x14, x15);
3123   };
3124 
3125   Register base = x28;
3126   uint32_t* data_ptr = nullptr;
3127   const int data_size = 640;
3128   uint64_t init_tag = 17;
3129 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
3130   data_ptr = reinterpret_cast<uint32_t*>(
3131       simulator.Mmap(NULL,
3132                      data_size * sizeof(uint32_t),
3133                      PROT_READ | PROT_WRITE | PROT_MTE,
3134                      MAP_PRIVATE | MAP_ANONYMOUS,
3135                      -1,
3136                      0));
3137 
3138   VIXL_ASSERT(data_ptr != nullptr);
3139   init_tag = CPU::GetPointerTag(data_ptr);
3140   uint32_t* untagged_ptr = AddressUntag(data_ptr);
3141   memset(untagged_ptr, 0xc9, data_size * sizeof(uint32_t));
3142 #else
3143 // TODO: Port the memory allocation to work on MTE supported platform natively.
3144 // Note that `CAN_RUN` prevents running in MTE-unsupported environments.
3145 #endif
3146 
3147   __ Mov(base, reinterpret_cast<uint64_t>(&data_ptr[data_size / 2]));
3148 
3149   // lsb of MTE tag field.
3150   const int tag_lsb = 56;
3151   for (int i = 0; i < 11; i++) {
3152     // <63..60> <59..56> <55........5> <4..0>
3153     //        0       i             0      i
3154     __ Mov(XRegister(i), i | (static_cast<uint64_t>(i) << tag_lsb));
3155   }
3156 
3157   // Backup stack pointer.
3158   __ Mov(x0, sp);
3159 
3160   int offset = -16;
3161   __ Addg(base, base, 0, 1);
3162   __ Stgp(x1, x2, MemOperand(base, offset, Offset));
3163   // Make sure `ldg` works well with address that isn't tag-granule aligned.
3164   __ Add(x29, base, 8);
3165   __ Ldg(x18, MemOperand(x29, offset));
3166   LoadDataAndSum(base, offset);
3167 
3168   offset = -304;
3169   __ Addg(base, base, 0, 1);
3170   __ Stgp(x2, x3, MemOperand(base, offset, Offset));
3171   __ Add(x29, base, 4);
3172   __ Ldg(x19, MemOperand(x29, offset));
3173   LoadDataAndSum(base, offset);
3174 
3175   offset = 128;
3176   __ Addg(base, base, 0, 1);
3177   __ Stgp(x3, x4, MemOperand(base, offset, Offset));
3178   __ Mov(sp, base);
3179   __ Ldg(x20, MemOperand(sp, offset));
3180   LoadDataAndSum(base, offset);
3181 
3182   offset = -48;
3183   __ Addg(base, base, 0, 1);
3184   __ Stgp(x4, x5, MemOperand(base, offset, PreIndex));
3185   __ Add(x29, base, 8);
3186   __ Ldg(x21, MemOperand(x29));
3187   LoadDataAndSum(base, 0);
3188 
3189   offset = 64;
3190   __ Addg(base, base, 0, 1);
3191   __ Stgp(x5, x6, MemOperand(base, offset, PreIndex));
3192   __ Add(x29, base, 4);
3193   __ Ldg(x22, MemOperand(x29));
3194   LoadDataAndSum(base, 0);
3195 
3196   offset = -288;
3197   __ Addg(base, base, 0, 1);
3198   __ Stgp(x6, x7, MemOperand(base, offset, PreIndex));
3199   __ Mov(sp, base);
3200   __ Ldg(x23, MemOperand(sp));
3201   LoadDataAndSum(base, 0);
3202 
3203   offset = -96;
3204   __ Addg(base, base, 0, 1);
3205   __ Stgp(x7, x8, MemOperand(base, offset, PostIndex));
3206   __ Add(x29, base, 8);
3207   __ Ldg(x24, MemOperand(x29, -offset));
3208   LoadDataAndSum(base, -offset);
3209 
3210   offset = 80;
3211   __ Addg(base, base, 0, 1);
3212   __ Stgp(x8, x9, MemOperand(base, offset, PostIndex));
3213   __ Add(x29, base, 4);
3214   __ Ldg(x25, MemOperand(x29, -offset));
3215   LoadDataAndSum(base, -offset);
3216 
3217   offset = -224;
3218   __ Addg(base, base, 0, 1);
3219   __ Stgp(x9, x10, MemOperand(base, offset, PostIndex));
3220   __ Mov(sp, base);
3221   __ Ldg(x26, MemOperand(sp, -offset));
3222   LoadDataAndSum(base, -offset);
3223 
3224   __ Mov(sp, x0);
3225 
3226   END();
3227 
3228   if (CAN_RUN()) {
3229 #ifndef VIXL_INCLUDE_SIMULATOR_AARCH64
3230     VIXL_UNIMPLEMENTED();
3231 #endif
3232     RUN();
3233 
3234     const uint64_t k = kMTETagGranuleInBytes;
3235     USE(k);
3236     ASSERT_EQUAL_64(((init_tag + 1) % k) << tag_lsb, x18);
3237     ASSERT_EQUAL_64(((init_tag + 2) % k) << tag_lsb, x19);
3238     ASSERT_EQUAL_64(((init_tag + 3) % k) << tag_lsb, x20);
3239     ASSERT_EQUAL_64(((init_tag + 4) % k) << tag_lsb, x21);
3240     ASSERT_EQUAL_64(((init_tag + 5) % k) << tag_lsb, x22);
3241     ASSERT_EQUAL_64(((init_tag + 6) % k) << tag_lsb, x23);
3242     ASSERT_EQUAL_64(((init_tag + 7) % k) << tag_lsb, x24);
3243     ASSERT_EQUAL_64(((init_tag + 8) % k) << tag_lsb, x25);
3244     ASSERT_EQUAL_64(((init_tag + 9) % k) << tag_lsb, x26);
3245 
3246     // We store 1, 2, 2, 3, 3, 4, ....9, 9, 10 to memory, so the total sum of
3247     // these values is 1 + (2 * (2 + 9) * 8 / 2) + 10 = 99.
3248     ASSERT_EQUAL_64((99UL << tag_lsb | 99UL), x15);
3249   }
3250 
3251 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
3252   simulator.Munmap(data_ptr, data_size, PROT_MTE);
3253 #endif
3254 }
3255 
3256 TEST(ldr_str_offset) {
3257   SETUP();
3258 
3259   uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
3260   uint64_t dst[5] = {0, 0, 0, 0, 0};
3261   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3262   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3263 
3264   START();
3265   __ Mov(x17, src_base);
3266   __ Mov(x18, dst_base);
3267   __ Ldr(w0, MemOperand(x17));
3268   __ Str(w0, MemOperand(x18));
3269   __ Ldr(w1, MemOperand(x17, 4));
3270   __ Str(w1, MemOperand(x18, 12));
3271   __ Ldr(x2, MemOperand(x17, 8));
3272   __ Str(x2, MemOperand(x18, 16));
3273   __ Ldrb(w3, MemOperand(x17, 1));
3274   __ Strb(w3, MemOperand(x18, 25));
3275   __ Ldrh(w4, MemOperand(x17, 2));
3276   __ Strh(w4, MemOperand(x18, 33));
3277   END();
3278 
3279   if (CAN_RUN()) {
3280     RUN();
3281 
3282     ASSERT_EQUAL_64(0x76543210, x0);
3283     ASSERT_EQUAL_64(0x76543210, dst[0]);
3284     ASSERT_EQUAL_64(0xfedcba98, x1);
3285     ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
3286     ASSERT_EQUAL_64(0x0123456789abcdef, x2);
3287     ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
3288     ASSERT_EQUAL_64(0x32, x3);
3289     ASSERT_EQUAL_64(0x3200, dst[3]);
3290     ASSERT_EQUAL_64(0x7654, x4);
3291     ASSERT_EQUAL_64(0x765400, dst[4]);
3292     ASSERT_EQUAL_64(src_base, x17);
3293     ASSERT_EQUAL_64(dst_base, x18);
3294   }
3295 }
3296 
3297 
3298 TEST(ldr_str_wide) {
3299   SETUP();
3300 
3301   uint32_t src[8192];
3302   uint32_t dst[8192];
3303   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3304   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3305   memset(src, 0xaa, 8192 * sizeof(src[0]));
3306   memset(dst, 0xaa, 8192 * sizeof(dst[0]));
3307   src[0] = 0;
3308   src[6144] = 6144;
3309   src[8191] = 8191;
3310 
3311   START();
3312   __ Mov(x22, src_base);
3313   __ Mov(x23, dst_base);
3314   __ Mov(x24, src_base);
3315   __ Mov(x25, dst_base);
3316   __ Mov(x26, src_base);
3317   __ Mov(x27, dst_base);
3318 
3319   __ Ldr(w0, MemOperand(x22, 8191 * sizeof(src[0])));
3320   __ Str(w0, MemOperand(x23, 8191 * sizeof(dst[0])));
3321   __ Ldr(w1, MemOperand(x24, 4096 * sizeof(src[0]), PostIndex));
3322   __ Str(w1, MemOperand(x25, 4096 * sizeof(dst[0]), PostIndex));
3323   __ Ldr(w2, MemOperand(x26, 6144 * sizeof(src[0]), PreIndex));
3324   __ Str(w2, MemOperand(x27, 6144 * sizeof(dst[0]), PreIndex));
3325   END();
3326 
3327   if (CAN_RUN()) {
3328     RUN();
3329 
3330     ASSERT_EQUAL_32(8191, w0);
3331     ASSERT_EQUAL_32(8191, dst[8191]);
3332     ASSERT_EQUAL_64(src_base, x22);
3333     ASSERT_EQUAL_64(dst_base, x23);
3334     ASSERT_EQUAL_32(0, w1);
3335     ASSERT_EQUAL_32(0, dst[0]);
3336     ASSERT_EQUAL_64(src_base + 4096 * sizeof(src[0]), x24);
3337     ASSERT_EQUAL_64(dst_base + 4096 * sizeof(dst[0]), x25);
3338     ASSERT_EQUAL_32(6144, w2);
3339     ASSERT_EQUAL_32(6144, dst[6144]);
3340     ASSERT_EQUAL_64(src_base + 6144 * sizeof(src[0]), x26);
3341     ASSERT_EQUAL_64(dst_base + 6144 * sizeof(dst[0]), x27);
3342   }
3343 }
3344 
3345 
3346 TEST(ldr_str_preindex) {
3347   SETUP();
3348 
3349   uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
3350   uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
3351   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3352   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3353 
3354   START();
3355   __ Mov(x17, src_base);
3356   __ Mov(x18, dst_base);
3357   __ Mov(x19, src_base);
3358   __ Mov(x20, dst_base);
3359   __ Mov(x21, src_base + 16);
3360   __ Mov(x22, dst_base + 40);
3361   __ Mov(x23, src_base);
3362   __ Mov(x24, dst_base);
3363   __ Mov(x25, src_base);
3364   __ Mov(x26, dst_base);
3365   __ Ldr(w0, MemOperand(x17, 4, PreIndex));
3366   __ Str(w0, MemOperand(x18, 12, PreIndex));
3367   __ Ldr(x1, MemOperand(x19, 8, PreIndex));
3368   __ Str(x1, MemOperand(x20, 16, PreIndex));
3369   __ Ldr(w2, MemOperand(x21, -4, PreIndex));
3370   __ Str(w2, MemOperand(x22, -4, PreIndex));
3371   __ Ldrb(w3, MemOperand(x23, 1, PreIndex));
3372   __ Strb(w3, MemOperand(x24, 25, PreIndex));
3373   __ Ldrh(w4, MemOperand(x25, 3, PreIndex));
3374   __ Strh(w4, MemOperand(x26, 41, PreIndex));
3375   END();
3376 
3377   if (CAN_RUN()) {
3378     RUN();
3379 
3380     ASSERT_EQUAL_64(0xfedcba98, x0);
3381     ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
3382     ASSERT_EQUAL_64(0x0123456789abcdef, x1);
3383     ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
3384     ASSERT_EQUAL_64(0x01234567, x2);
3385     ASSERT_EQUAL_64(0x0123456700000000, dst[4]);
3386     ASSERT_EQUAL_64(0x32, x3);
3387     ASSERT_EQUAL_64(0x3200, dst[3]);
3388     ASSERT_EQUAL_64(0x9876, x4);
3389     ASSERT_EQUAL_64(0x987600, dst[5]);
3390     ASSERT_EQUAL_64(src_base + 4, x17);
3391     ASSERT_EQUAL_64(dst_base + 12, x18);
3392     ASSERT_EQUAL_64(src_base + 8, x19);
3393     ASSERT_EQUAL_64(dst_base + 16, x20);
3394     ASSERT_EQUAL_64(src_base + 12, x21);
3395     ASSERT_EQUAL_64(dst_base + 36, x22);
3396     ASSERT_EQUAL_64(src_base + 1, x23);
3397     ASSERT_EQUAL_64(dst_base + 25, x24);
3398     ASSERT_EQUAL_64(src_base + 3, x25);
3399     ASSERT_EQUAL_64(dst_base + 41, x26);
3400   }
3401 }
3402 
3403 
3404 TEST(ldr_str_postindex) {
3405   SETUP();
3406 
3407   uint64_t src[2] = {0xfedcba9876543210, 0x0123456789abcdef};
3408   uint64_t dst[6] = {0, 0, 0, 0, 0, 0};
3409   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3410   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3411 
3412   START();
3413   __ Mov(x17, src_base + 4);
3414   __ Mov(x18, dst_base + 12);
3415   __ Mov(x19, src_base + 8);
3416   __ Mov(x20, dst_base + 16);
3417   __ Mov(x21, src_base + 8);
3418   __ Mov(x22, dst_base + 32);
3419   __ Mov(x23, src_base + 1);
3420   __ Mov(x24, dst_base + 25);
3421   __ Mov(x25, src_base + 3);
3422   __ Mov(x26, dst_base + 41);
3423   __ Ldr(w0, MemOperand(x17, 4, PostIndex));
3424   __ Str(w0, MemOperand(x18, 12, PostIndex));
3425   __ Ldr(x1, MemOperand(x19, 8, PostIndex));
3426   __ Str(x1, MemOperand(x20, 16, PostIndex));
3427   __ Ldr(x2, MemOperand(x21, -8, PostIndex));
3428   __ Str(x2, MemOperand(x22, -32, PostIndex));
3429   __ Ldrb(w3, MemOperand(x23, 1, PostIndex));
3430   __ Strb(w3, MemOperand(x24, 5, PostIndex));
3431   __ Ldrh(w4, MemOperand(x25, -3, PostIndex));
3432   __ Strh(w4, MemOperand(x26, -41, PostIndex));
3433   END();
3434 
3435   if (CAN_RUN()) {
3436     RUN();
3437 
3438     ASSERT_EQUAL_64(0xfedcba98, x0);
3439     ASSERT_EQUAL_64(0xfedcba9800000000, dst[1]);
3440     ASSERT_EQUAL_64(0x0123456789abcdef, x1);
3441     ASSERT_EQUAL_64(0x0123456789abcdef, dst[2]);
3442     ASSERT_EQUAL_64(0x0123456789abcdef, x2);
3443     ASSERT_EQUAL_64(0x0123456789abcdef, dst[4]);
3444     ASSERT_EQUAL_64(0x32, x3);
3445     ASSERT_EQUAL_64(0x3200, dst[3]);
3446     ASSERT_EQUAL_64(0x9876, x4);
3447     ASSERT_EQUAL_64(0x987600, dst[5]);
3448     ASSERT_EQUAL_64(src_base + 8, x17);
3449     ASSERT_EQUAL_64(dst_base + 24, x18);
3450     ASSERT_EQUAL_64(src_base + 16, x19);
3451     ASSERT_EQUAL_64(dst_base + 32, x20);
3452     ASSERT_EQUAL_64(src_base, x21);
3453     ASSERT_EQUAL_64(dst_base, x22);
3454     ASSERT_EQUAL_64(src_base + 2, x23);
3455     ASSERT_EQUAL_64(dst_base + 30, x24);
3456     ASSERT_EQUAL_64(src_base, x25);
3457     ASSERT_EQUAL_64(dst_base, x26);
3458   }
3459 }
3460 
3461 
3462 TEST(ldr_str_largeindex) {
3463   SETUP();
3464 
3465   // This value won't fit in the immediate offset field of ldr/str instructions.
3466   int largeoffset = 0xabcdef;
3467 
3468   int64_t data[3] = {0x1122334455667788, 0, 0};
3469   uint64_t base_addr = reinterpret_cast<uintptr_t>(data);
3470   uint64_t drifted_addr = base_addr - largeoffset;
3471 
3472   // This test checks that we we can use large immediate offsets when
3473   // using PreIndex or PostIndex addressing mode of the MacroAssembler
3474   // Ldr/Str instructions.
3475 
3476   START();
3477   __ Mov(x19, drifted_addr);
3478   __ Ldr(x0, MemOperand(x19, largeoffset, PreIndex));
3479 
3480   __ Mov(x20, base_addr);
3481   __ Ldr(x1, MemOperand(x20, largeoffset, PostIndex));
3482 
3483   __ Mov(x21, drifted_addr);
3484   __ Str(x0, MemOperand(x21, largeoffset + 8, PreIndex));
3485 
3486   __ Mov(x22, base_addr + 16);
3487   __ Str(x0, MemOperand(x22, largeoffset, PostIndex));
3488   END();
3489 
3490   if (CAN_RUN()) {
3491     RUN();
3492 
3493     ASSERT_EQUAL_64(0x1122334455667788, data[0]);
3494     ASSERT_EQUAL_64(0x1122334455667788, data[1]);
3495     ASSERT_EQUAL_64(0x1122334455667788, data[2]);
3496     ASSERT_EQUAL_64(0x1122334455667788, x0);
3497     ASSERT_EQUAL_64(0x1122334455667788, x1);
3498 
3499     ASSERT_EQUAL_64(base_addr, x19);
3500     ASSERT_EQUAL_64(base_addr + largeoffset, x20);
3501     ASSERT_EQUAL_64(base_addr + 8, x21);
3502     ASSERT_EQUAL_64(base_addr + 16 + largeoffset, x22);
3503   }
3504 }
3505 
3506 
3507 TEST(load_signed) {
3508   SETUP();
3509 
3510   uint32_t src[2] = {0x80008080, 0x7fff7f7f};
3511   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3512 
3513   START();
3514   __ Mov(x24, src_base);
3515   __ Ldrsb(w0, MemOperand(x24));
3516   __ Ldrsb(w1, MemOperand(x24, 4));
3517   __ Ldrsh(w2, MemOperand(x24));
3518   __ Ldrsh(w3, MemOperand(x24, 4));
3519   __ Ldrsb(x4, MemOperand(x24));
3520   __ Ldrsb(x5, MemOperand(x24, 4));
3521   __ Ldrsh(x6, MemOperand(x24));
3522   __ Ldrsh(x7, MemOperand(x24, 4));
3523   __ Ldrsw(x8, MemOperand(x24));
3524   __ Ldrsw(x9, MemOperand(x24, 4));
3525   END();
3526 
3527   if (CAN_RUN()) {
3528     RUN();
3529 
3530     ASSERT_EQUAL_64(0xffffff80, x0);
3531     ASSERT_EQUAL_64(0x0000007f, x1);
3532     ASSERT_EQUAL_64(0xffff8080, x2);
3533     ASSERT_EQUAL_64(0x00007f7f, x3);
3534     ASSERT_EQUAL_64(0xffffffffffffff80, x4);
3535     ASSERT_EQUAL_64(0x000000000000007f, x5);
3536     ASSERT_EQUAL_64(0xffffffffffff8080, x6);
3537     ASSERT_EQUAL_64(0x0000000000007f7f, x7);
3538     ASSERT_EQUAL_64(0xffffffff80008080, x8);
3539     ASSERT_EQUAL_64(0x000000007fff7f7f, x9);
3540   }
3541 }
3542 
3543 
3544 TEST(load_store_regoffset) {
3545   SETUP();
3546 
3547   uint32_t src[3] = {1, 2, 3};
3548   uint32_t dst[4] = {0, 0, 0, 0};
3549   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3550   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3551 
3552   START();
3553   __ Mov(x16, src_base);
3554   __ Mov(x17, dst_base);
3555   __ Mov(x18, src_base + 3 * sizeof(src[0]));
3556   __ Mov(x19, dst_base + 3 * sizeof(dst[0]));
3557   __ Mov(x20, dst_base + 4 * sizeof(dst[0]));
3558   __ Mov(x24, 0);
3559   __ Mov(x25, 4);
3560   __ Mov(x26, -4);
3561   __ Mov(x27, 0xfffffffc);  // 32-bit -4.
3562   __ Mov(x28, 0xfffffffe);  // 32-bit -2.
3563   __ Mov(x29, 0xffffffff);  // 32-bit -1.
3564 
3565   __ Ldr(w0, MemOperand(x16, x24));
3566   __ Ldr(x1, MemOperand(x16, x25));
3567   __ Ldr(w2, MemOperand(x18, x26));
3568   __ Ldr(w3, MemOperand(x18, x27, SXTW));
3569   __ Ldr(w4, MemOperand(x18, x28, SXTW, 2));
3570   __ Str(w0, MemOperand(x17, x24));
3571   __ Str(x1, MemOperand(x17, x25));
3572   __ Str(w2, MemOperand(x20, x29, SXTW, 2));
3573   END();
3574 
3575   if (CAN_RUN()) {
3576     RUN();
3577 
3578     ASSERT_EQUAL_64(1, x0);
3579     ASSERT_EQUAL_64(0x0000000300000002, x1);
3580     ASSERT_EQUAL_64(3, x2);
3581     ASSERT_EQUAL_64(3, x3);
3582     ASSERT_EQUAL_64(2, x4);
3583     ASSERT_EQUAL_32(1, dst[0]);
3584     ASSERT_EQUAL_32(2, dst[1]);
3585     ASSERT_EQUAL_32(3, dst[2]);
3586     ASSERT_EQUAL_32(3, dst[3]);
3587   }
3588 }
3589 
3590 
3591 TEST(load_pauth) {
3592   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
3593 
3594   uint64_t src[4] = {1, 2, 3, 4};
3595   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3596 
3597   START();
3598   __ Mov(x16, src_base);
3599   __ Mov(x17, src_base);
3600   __ Mov(x18, src_base + 4 * sizeof(src[0]));
3601   __ Mov(x19, src_base + 4 * sizeof(src[0]));
3602 
3603   // Add PAC codes to addresses
3604   __ Pacdza(x16);
3605   __ Pacdzb(x17);
3606   __ Pacdza(x18);
3607   __ Pacdzb(x19);
3608 
3609   __ Ldraa(x0, MemOperand(x16));
3610   __ Ldraa(x1, MemOperand(x16, sizeof(src[0])));
3611   __ Ldraa(x2, MemOperand(x16, 2 * sizeof(src[0]), PreIndex));
3612   __ Ldraa(x3, MemOperand(x18, -sizeof(src[0])));
3613   __ Ldrab(x4, MemOperand(x17));
3614   __ Ldrab(x5, MemOperand(x17, sizeof(src[0])));
3615   __ Ldrab(x6, MemOperand(x17, 2 * sizeof(src[0]), PreIndex));
3616   __ Ldrab(x7, MemOperand(x19, -sizeof(src[0])));
3617   END();
3618 
3619   if (CAN_RUN()) {
3620     RUN();
3621 
3622     ASSERT_EQUAL_64(1, x0);
3623     ASSERT_EQUAL_64(2, x1);
3624     ASSERT_EQUAL_64(3, x2);
3625     ASSERT_EQUAL_64(4, x3);
3626     ASSERT_EQUAL_64(1, x4);
3627     ASSERT_EQUAL_64(2, x5);
3628     ASSERT_EQUAL_64(3, x6);
3629     ASSERT_EQUAL_64(4, x7);
3630     ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
3631     ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x17);
3632   }
3633 }
3634 
3635 
3636 #ifdef VIXL_NEGATIVE_TESTING
3637 TEST(load_pauth_negative_test) {
3638   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
3639 
3640   uint64_t src[4] = {1, 2, 3, 4};
3641   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3642 
3643   START();
3644   __ Mov(x16, src_base);
3645 
3646   // There is a small but not negligible chance (1 in 127 runs) that the PAC
3647   // codes for keys A and B will collide and LDRAB won't abort. To mitigate
3648   // this, we simply repeat the test a few more times.
3649   for (unsigned i = 0; i < 32; i++) {
3650     __ Add(x17, x16, i);
3651     __ Pacdza(x17);
3652     __ Ldrab(x0, MemOperand(x17));
3653   }
3654   END();
3655 
3656   if (CAN_RUN()) {
3657     MUST_FAIL_WITH_MESSAGE(RUN(), "Failed to authenticate pointer.");
3658   }
3659 }
3660 #endif  // VIXL_NEGATIVE_TESTING
3661 
3662 
3663 TEST(ldp_stp_offset) {
3664   SETUP();
3665 
3666   uint64_t src[3] = {0x0011223344556677,
3667                      0x8899aabbccddeeff,
3668                      0xffeeddccbbaa9988};
3669   uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
3670   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3671   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3672 
3673   START();
3674   __ Mov(x16, src_base);
3675   __ Mov(x17, dst_base);
3676   __ Mov(x18, src_base + 24);
3677   __ Mov(x19, dst_base + 56);
3678   __ Ldp(w0, w1, MemOperand(x16));
3679   __ Ldp(w2, w3, MemOperand(x16, 4));
3680   __ Ldp(x4, x5, MemOperand(x16, 8));
3681   __ Ldp(w6, w7, MemOperand(x18, -12));
3682   __ Ldp(x8, x9, MemOperand(x18, -16));
3683   __ Stp(w0, w1, MemOperand(x17));
3684   __ Stp(w2, w3, MemOperand(x17, 8));
3685   __ Stp(x4, x5, MemOperand(x17, 16));
3686   __ Stp(w6, w7, MemOperand(x19, -24));
3687   __ Stp(x8, x9, MemOperand(x19, -16));
3688   END();
3689 
3690   if (CAN_RUN()) {
3691     RUN();
3692 
3693     ASSERT_EQUAL_64(0x44556677, x0);
3694     ASSERT_EQUAL_64(0x00112233, x1);
3695     ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
3696     ASSERT_EQUAL_64(0x00112233, x2);
3697     ASSERT_EQUAL_64(0xccddeeff, x3);
3698     ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
3699     ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
3700     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
3701     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
3702     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
3703     ASSERT_EQUAL_64(0x8899aabb, x6);
3704     ASSERT_EQUAL_64(0xbbaa9988, x7);
3705     ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
3706     ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
3707     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
3708     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
3709     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
3710     ASSERT_EQUAL_64(src_base, x16);
3711     ASSERT_EQUAL_64(dst_base, x17);
3712     ASSERT_EQUAL_64(src_base + 24, x18);
3713     ASSERT_EQUAL_64(dst_base + 56, x19);
3714   }
3715 }
3716 
3717 
3718 TEST(ldp_stp_offset_wide) {
3719   SETUP();
3720 
3721   uint64_t src[3] = {0x0011223344556677,
3722                      0x8899aabbccddeeff,
3723                      0xffeeddccbbaa9988};
3724   uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0};
3725   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3726   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3727   // Move base too far from the array to force multiple instructions
3728   // to be emitted.
3729   const int64_t base_offset = 1024;
3730 
3731   START();
3732   __ Mov(x20, src_base - base_offset);
3733   __ Mov(x21, dst_base - base_offset);
3734   __ Mov(x18, src_base + base_offset + 24);
3735   __ Mov(x19, dst_base + base_offset + 56);
3736   __ Ldp(w0, w1, MemOperand(x20, base_offset));
3737   __ Ldp(w2, w3, MemOperand(x20, base_offset + 4));
3738   __ Ldp(x4, x5, MemOperand(x20, base_offset + 8));
3739   __ Ldp(w6, w7, MemOperand(x18, -12 - base_offset));
3740   __ Ldp(x8, x9, MemOperand(x18, -16 - base_offset));
3741   __ Stp(w0, w1, MemOperand(x21, base_offset));
3742   __ Stp(w2, w3, MemOperand(x21, base_offset + 8));
3743   __ Stp(x4, x5, MemOperand(x21, base_offset + 16));
3744   __ Stp(w6, w7, MemOperand(x19, -24 - base_offset));
3745   __ Stp(x8, x9, MemOperand(x19, -16 - base_offset));
3746   END();
3747 
3748   if (CAN_RUN()) {
3749     RUN();
3750 
3751     ASSERT_EQUAL_64(0x44556677, x0);
3752     ASSERT_EQUAL_64(0x00112233, x1);
3753     ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
3754     ASSERT_EQUAL_64(0x00112233, x2);
3755     ASSERT_EQUAL_64(0xccddeeff, x3);
3756     ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
3757     ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
3758     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
3759     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
3760     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
3761     ASSERT_EQUAL_64(0x8899aabb, x6);
3762     ASSERT_EQUAL_64(0xbbaa9988, x7);
3763     ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
3764     ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
3765     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
3766     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
3767     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
3768     ASSERT_EQUAL_64(src_base - base_offset, x20);
3769     ASSERT_EQUAL_64(dst_base - base_offset, x21);
3770     ASSERT_EQUAL_64(src_base + base_offset + 24, x18);
3771     ASSERT_EQUAL_64(dst_base + base_offset + 56, x19);
3772   }
3773 }
3774 
3775 
3776 TEST(ldnp_stnp_offset) {
3777   SETUP_WITH_FEATURES(CPUFeatures::kNEON);
3778 
3779   uint64_t src[4] = {0x0011223344556677,
3780                      0x8899aabbccddeeff,
3781                      0xffeeddccbbaa9988,
3782                      0x7766554433221100};
3783   uint64_t dst[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3784   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3785   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3786 
3787   START();
3788   __ Mov(x16, src_base);
3789   __ Mov(x17, dst_base);
3790   __ Mov(x18, src_base + 24);
3791   __ Mov(x19, dst_base + 64);
3792   __ Mov(x20, src_base + 32);
3793 
3794   // Ensure address set up has happened before executing non-temporal ops.
3795   __ Dmb(InnerShareable, BarrierAll);
3796 
3797   __ Ldnp(w0, w1, MemOperand(x16));
3798   __ Ldnp(w2, w3, MemOperand(x16, 4));
3799   __ Ldnp(x4, x5, MemOperand(x16, 8));
3800   __ Ldnp(w6, w7, MemOperand(x18, -12));
3801   __ Ldnp(x8, x9, MemOperand(x18, -16));
3802   __ Ldnp(q16, q17, MemOperand(x16));
3803   __ Ldnp(q19, q18, MemOperand(x20, -32));
3804   __ Stnp(w0, w1, MemOperand(x17));
3805   __ Stnp(w2, w3, MemOperand(x17, 8));
3806   __ Stnp(x4, x5, MemOperand(x17, 16));
3807   __ Stnp(w6, w7, MemOperand(x19, -32));
3808   __ Stnp(x8, x9, MemOperand(x19, -24));
3809   __ Stnp(q17, q16, MemOperand(x19));
3810   __ Stnp(q18, q19, MemOperand(x19, 32));
3811   END();
3812 
3813   if (CAN_RUN()) {
3814     RUN();
3815 
3816     ASSERT_EQUAL_64(0x44556677, x0);
3817     ASSERT_EQUAL_64(0x00112233, x1);
3818     ASSERT_EQUAL_64(0x0011223344556677, dst[0]);
3819     ASSERT_EQUAL_64(0x00112233, x2);
3820     ASSERT_EQUAL_64(0xccddeeff, x3);
3821     ASSERT_EQUAL_64(0xccddeeff00112233, dst[1]);
3822     ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
3823     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[2]);
3824     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
3825     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[3]);
3826     ASSERT_EQUAL_64(0x8899aabb, x6);
3827     ASSERT_EQUAL_64(0xbbaa9988, x7);
3828     ASSERT_EQUAL_64(0xbbaa99888899aabb, dst[4]);
3829     ASSERT_EQUAL_64(0x8899aabbccddeeff, x8);
3830     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[5]);
3831     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x9);
3832     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[6]);
3833     ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q16);
3834     ASSERT_EQUAL_128(0x7766554433221100, 0xffeeddccbbaa9988, q17);
3835     ASSERT_EQUAL_128(0x7766554433221100, 0xffeeddccbbaa9988, q18);
3836     ASSERT_EQUAL_128(0x8899aabbccddeeff, 0x0011223344556677, q19);
3837     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[8]);
3838     ASSERT_EQUAL_64(0x7766554433221100, dst[9]);
3839     ASSERT_EQUAL_64(0x0011223344556677, dst[10]);
3840     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[11]);
3841     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[12]);
3842     ASSERT_EQUAL_64(0x7766554433221100, dst[13]);
3843     ASSERT_EQUAL_64(0x0011223344556677, dst[14]);
3844     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[15]);
3845     ASSERT_EQUAL_64(src_base, x16);
3846     ASSERT_EQUAL_64(dst_base, x17);
3847     ASSERT_EQUAL_64(src_base + 24, x18);
3848     ASSERT_EQUAL_64(dst_base + 64, x19);
3849     ASSERT_EQUAL_64(src_base + 32, x20);
3850   }
3851 }
3852 
3853 TEST(ldp_stp_preindex) {
3854   SETUP();
3855 
3856   uint64_t src[3] = {0x0011223344556677,
3857                      0x8899aabbccddeeff,
3858                      0xffeeddccbbaa9988};
3859   uint64_t dst[5] = {0, 0, 0, 0, 0};
3860   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3861   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3862 
3863   START();
3864   __ Mov(x16, src_base);
3865   __ Mov(x17, dst_base);
3866   __ Mov(x18, dst_base + 16);
3867   __ Ldp(w0, w1, MemOperand(x16, 4, PreIndex));
3868   __ Mov(x19, x16);
3869   __ Ldp(w2, w3, MemOperand(x16, -4, PreIndex));
3870   __ Stp(w2, w3, MemOperand(x17, 4, PreIndex));
3871   __ Mov(x20, x17);
3872   __ Stp(w0, w1, MemOperand(x17, -4, PreIndex));
3873   __ Ldp(x4, x5, MemOperand(x16, 8, PreIndex));
3874   __ Mov(x21, x16);
3875   __ Ldp(x6, x7, MemOperand(x16, -8, PreIndex));
3876   __ Stp(x7, x6, MemOperand(x18, 8, PreIndex));
3877   __ Mov(x22, x18);
3878   __ Stp(x5, x4, MemOperand(x18, -8, PreIndex));
3879   END();
3880 
3881   if (CAN_RUN()) {
3882     RUN();
3883 
3884     ASSERT_EQUAL_64(0x00112233, x0);
3885     ASSERT_EQUAL_64(0xccddeeff, x1);
3886     ASSERT_EQUAL_64(0x44556677, x2);
3887     ASSERT_EQUAL_64(0x00112233, x3);
3888     ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
3889     ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
3890     ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
3891     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
3892     ASSERT_EQUAL_64(0x0011223344556677, x6);
3893     ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
3894     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
3895     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
3896     ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
3897     ASSERT_EQUAL_64(src_base, x16);
3898     ASSERT_EQUAL_64(dst_base, x17);
3899     ASSERT_EQUAL_64(dst_base + 16, x18);
3900     ASSERT_EQUAL_64(src_base + 4, x19);
3901     ASSERT_EQUAL_64(dst_base + 4, x20);
3902     ASSERT_EQUAL_64(src_base + 8, x21);
3903     ASSERT_EQUAL_64(dst_base + 24, x22);
3904   }
3905 }
3906 
3907 
3908 TEST(ldp_stp_preindex_wide) {
3909   SETUP();
3910 
3911   uint64_t src[3] = {0x0011223344556677,
3912                      0x8899aabbccddeeff,
3913                      0xffeeddccbbaa9988};
3914   uint64_t dst[5] = {0, 0, 0, 0, 0};
3915   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3916   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3917   // Move base too far from the array to force multiple instructions
3918   // to be emitted.
3919   const int64_t base_offset = 1024;
3920 
3921   START();
3922   __ Mov(x24, src_base - base_offset);
3923   __ Mov(x25, dst_base + base_offset);
3924   __ Mov(x18, dst_base + base_offset + 16);
3925   __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PreIndex));
3926   __ Mov(x19, x24);
3927   __ Mov(x24, src_base - base_offset + 4);
3928   __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PreIndex));
3929   __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PreIndex));
3930   __ Mov(x20, x25);
3931   __ Mov(x25, dst_base + base_offset + 4);
3932   __ Mov(x24, src_base - base_offset);
3933   __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PreIndex));
3934   __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PreIndex));
3935   __ Mov(x21, x24);
3936   __ Mov(x24, src_base - base_offset + 8);
3937   __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PreIndex));
3938   __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PreIndex));
3939   __ Mov(x22, x18);
3940   __ Mov(x18, dst_base + base_offset + 16 + 8);
3941   __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PreIndex));
3942   END();
3943 
3944   if (CAN_RUN()) {
3945     RUN();
3946 
3947     ASSERT_EQUAL_64(0x00112233, x0);
3948     ASSERT_EQUAL_64(0xccddeeff, x1);
3949     ASSERT_EQUAL_64(0x44556677, x2);
3950     ASSERT_EQUAL_64(0x00112233, x3);
3951     ASSERT_EQUAL_64(0xccddeeff00112233, dst[0]);
3952     ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
3953     ASSERT_EQUAL_64(0x8899aabbccddeeff, x4);
3954     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
3955     ASSERT_EQUAL_64(0x0011223344556677, x6);
3956     ASSERT_EQUAL_64(0x8899aabbccddeeff, x7);
3957     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
3958     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
3959     ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
3960     ASSERT_EQUAL_64(src_base, x24);
3961     ASSERT_EQUAL_64(dst_base, x25);
3962     ASSERT_EQUAL_64(dst_base + 16, x18);
3963     ASSERT_EQUAL_64(src_base + 4, x19);
3964     ASSERT_EQUAL_64(dst_base + 4, x20);
3965     ASSERT_EQUAL_64(src_base + 8, x21);
3966     ASSERT_EQUAL_64(dst_base + 24, x22);
3967   }
3968 }
3969 
3970 
3971 TEST(ldp_stp_postindex) {
3972   SETUP();
3973 
3974   uint64_t src[4] = {0x0011223344556677,
3975                      0x8899aabbccddeeff,
3976                      0xffeeddccbbaa9988,
3977                      0x7766554433221100};
3978   uint64_t dst[5] = {0, 0, 0, 0, 0};
3979   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
3980   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
3981 
3982   START();
3983   __ Mov(x16, src_base);
3984   __ Mov(x17, dst_base);
3985   __ Mov(x18, dst_base + 16);
3986   __ Ldp(w0, w1, MemOperand(x16, 4, PostIndex));
3987   __ Mov(x19, x16);
3988   __ Ldp(w2, w3, MemOperand(x16, -4, PostIndex));
3989   __ Stp(w2, w3, MemOperand(x17, 4, PostIndex));
3990   __ Mov(x20, x17);
3991   __ Stp(w0, w1, MemOperand(x17, -4, PostIndex));
3992   __ Ldp(x4, x5, MemOperand(x16, 8, PostIndex));
3993   __ Mov(x21, x16);
3994   __ Ldp(x6, x7, MemOperand(x16, -8, PostIndex));
3995   __ Stp(x7, x6, MemOperand(x18, 8, PostIndex));
3996   __ Mov(x22, x18);
3997   __ Stp(x5, x4, MemOperand(x18, -8, PostIndex));
3998   END();
3999 
4000   if (CAN_RUN()) {
4001     RUN();
4002 
4003     ASSERT_EQUAL_64(0x44556677, x0);
4004     ASSERT_EQUAL_64(0x00112233, x1);
4005     ASSERT_EQUAL_64(0x00112233, x2);
4006     ASSERT_EQUAL_64(0xccddeeff, x3);
4007     ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
4008     ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
4009     ASSERT_EQUAL_64(0x0011223344556677, x4);
4010     ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
4011     ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
4012     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
4013     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
4014     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
4015     ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
4016     ASSERT_EQUAL_64(src_base, x16);
4017     ASSERT_EQUAL_64(dst_base, x17);
4018     ASSERT_EQUAL_64(dst_base + 16, x18);
4019     ASSERT_EQUAL_64(src_base + 4, x19);
4020     ASSERT_EQUAL_64(dst_base + 4, x20);
4021     ASSERT_EQUAL_64(src_base + 8, x21);
4022     ASSERT_EQUAL_64(dst_base + 24, x22);
4023   }
4024 }
4025 
4026 
4027 TEST(ldp_stp_postindex_wide) {
4028   SETUP();
4029 
4030   uint64_t src[4] = {0x0011223344556677,
4031                      0x8899aabbccddeeff,
4032                      0xffeeddccbbaa9988,
4033                      0x7766554433221100};
4034   uint64_t dst[5] = {0, 0, 0, 0, 0};
4035   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4036   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4037   // Move base too far from the array to force multiple instructions
4038   // to be emitted.
4039   const int64_t base_offset = 1024;
4040 
4041   START();
4042   __ Mov(x24, src_base);
4043   __ Mov(x25, dst_base);
4044   __ Mov(x18, dst_base + 16);
4045   __ Ldp(w0, w1, MemOperand(x24, base_offset + 4, PostIndex));
4046   __ Mov(x19, x24);
4047   __ Sub(x24, x24, base_offset);
4048   __ Ldp(w2, w3, MemOperand(x24, base_offset - 4, PostIndex));
4049   __ Stp(w2, w3, MemOperand(x25, 4 - base_offset, PostIndex));
4050   __ Mov(x20, x25);
4051   __ Sub(x24, x24, base_offset);
4052   __ Add(x25, x25, base_offset);
4053   __ Stp(w0, w1, MemOperand(x25, -4 - base_offset, PostIndex));
4054   __ Ldp(x4, x5, MemOperand(x24, base_offset + 8, PostIndex));
4055   __ Mov(x21, x24);
4056   __ Sub(x24, x24, base_offset);
4057   __ Ldp(x6, x7, MemOperand(x24, base_offset - 8, PostIndex));
4058   __ Stp(x7, x6, MemOperand(x18, 8 - base_offset, PostIndex));
4059   __ Mov(x22, x18);
4060   __ Add(x18, x18, base_offset);
4061   __ Stp(x5, x4, MemOperand(x18, -8 - base_offset, PostIndex));
4062   END();
4063 
4064   if (CAN_RUN()) {
4065     RUN();
4066 
4067     ASSERT_EQUAL_64(0x44556677, x0);
4068     ASSERT_EQUAL_64(0x00112233, x1);
4069     ASSERT_EQUAL_64(0x00112233, x2);
4070     ASSERT_EQUAL_64(0xccddeeff, x3);
4071     ASSERT_EQUAL_64(0x4455667700112233, dst[0]);
4072     ASSERT_EQUAL_64(0x0000000000112233, dst[1]);
4073     ASSERT_EQUAL_64(0x0011223344556677, x4);
4074     ASSERT_EQUAL_64(0x8899aabbccddeeff, x5);
4075     ASSERT_EQUAL_64(0x8899aabbccddeeff, x6);
4076     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x7);
4077     ASSERT_EQUAL_64(0xffeeddccbbaa9988, dst[2]);
4078     ASSERT_EQUAL_64(0x8899aabbccddeeff, dst[3]);
4079     ASSERT_EQUAL_64(0x0011223344556677, dst[4]);
4080     ASSERT_EQUAL_64(src_base + base_offset, x24);
4081     ASSERT_EQUAL_64(dst_base - base_offset, x25);
4082     ASSERT_EQUAL_64(dst_base - base_offset + 16, x18);
4083     ASSERT_EQUAL_64(src_base + base_offset + 4, x19);
4084     ASSERT_EQUAL_64(dst_base - base_offset + 4, x20);
4085     ASSERT_EQUAL_64(src_base + base_offset + 8, x21);
4086     ASSERT_EQUAL_64(dst_base - base_offset + 24, x22);
4087   }
4088 }
4089 
4090 
4091 TEST(ldp_sign_extend) {
4092   SETUP();
4093 
4094   uint32_t src[2] = {0x80000000, 0x7fffffff};
4095   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4096 
4097   START();
4098   __ Mov(x24, src_base);
4099   __ Ldpsw(x0, x1, MemOperand(x24));
4100   END();
4101 
4102   if (CAN_RUN()) {
4103     RUN();
4104 
4105     ASSERT_EQUAL_64(0xffffffff80000000, x0);
4106     ASSERT_EQUAL_64(0x000000007fffffff, x1);
4107   }
4108 }
4109 
4110 
4111 TEST(ldur_stur) {
4112   SETUP();
4113 
4114   int64_t src[2] = {0x0123456789abcdef, 0x0123456789abcdef};
4115   int64_t dst[5] = {0, 0, 0, 0, 0};
4116   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4117   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4118 
4119   START();
4120   __ Mov(x17, src_base);
4121   __ Mov(x18, dst_base);
4122   __ Mov(x19, src_base + 16);
4123   __ Mov(x20, dst_base + 32);
4124   __ Mov(x21, dst_base + 40);
4125   __ Ldr(w0, MemOperand(x17, 1));
4126   __ Str(w0, MemOperand(x18, 2));
4127   __ Ldr(x1, MemOperand(x17, 3));
4128   __ Str(x1, MemOperand(x18, 9));
4129   __ Ldr(w2, MemOperand(x19, -9));
4130   __ Str(w2, MemOperand(x20, -5));
4131   __ Ldrb(w3, MemOperand(x19, -1));
4132   __ Strb(w3, MemOperand(x21, -1));
4133   END();
4134 
4135   if (CAN_RUN()) {
4136     RUN();
4137 
4138     ASSERT_EQUAL_64(0x6789abcd, x0);
4139     ASSERT_EQUAL_64(0x00006789abcd0000, dst[0]);
4140     ASSERT_EQUAL_64(0xabcdef0123456789, x1);
4141     ASSERT_EQUAL_64(0xcdef012345678900, dst[1]);
4142     ASSERT_EQUAL_64(0x000000ab, dst[2]);
4143     ASSERT_EQUAL_64(0xabcdef01, x2);
4144     ASSERT_EQUAL_64(0x00abcdef01000000, dst[3]);
4145     ASSERT_EQUAL_64(0x00000001, x3);
4146     ASSERT_EQUAL_64(0x0100000000000000, dst[4]);
4147     ASSERT_EQUAL_64(src_base, x17);
4148     ASSERT_EQUAL_64(dst_base, x18);
4149     ASSERT_EQUAL_64(src_base + 16, x19);
4150     ASSERT_EQUAL_64(dst_base + 32, x20);
4151   }
4152 }
4153 
4154 
4155 TEST(ldur_stur_neon) {
4156   SETUP_WITH_FEATURES(CPUFeatures::kNEON);
4157 
4158   int64_t src[3] = {0x0123456789abcdef, 0x0123456789abcdef, 0x0123456789abcdef};
4159   int64_t dst[5] = {0, 0, 0, 0, 0};
4160   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
4161   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
4162 
4163   START();
4164   __ Mov(x17, src_base);
4165   __ Mov(x18, dst_base);
4166   __ Ldr(b0, MemOperand(x17));
4167   __ Str(b0, MemOperand(x18));
4168   __ Ldr(h1, MemOperand(x17, 1));
4169   __ Str(h1, MemOperand(x18, 1));
4170   __ Ldr(s2, MemOperand(x17, 2));
4171   __ Str(s2, MemOperand(x18, 3));
4172   __ Ldr(d3, MemOperand(x17, 3));
4173   __ Str(d3, MemOperand(x18, 7));
4174   __ Ldr(q4, MemOperand(x17, 4));
4175   __ Str(q4, MemOperand(x18, 15));
4176   END();
4177 
4178   if (CAN_RUN()) {
4179     RUN();
4180 
4181     ASSERT_EQUAL_128(0, 0xef, q0);
4182     ASSERT_EQUAL_128(0, 0xabcd, q1);
4183     ASSERT_EQUAL_128(0, 0x456789ab, q2);
4184     ASSERT_EQUAL_128(0, 0xabcdef0123456789, q3);
4185     ASSERT_EQUAL_128(0x89abcdef01234567, 0x89abcdef01234567, q4);
4186     ASSERT_EQUAL_64(0x89456789ababcdef, dst[0]);
4187     ASSERT_EQUAL_64(0x67abcdef01234567, dst[1]);
4188     ASSERT_EQUAL_64(0x6789abcdef012345, dst[2]);
4189     ASSERT_EQUAL_64(0x0089abcdef012345, dst[3]);
4190   }
4191 }
4192 
4193 
4194 TEST(ldr_literal) {
4195   SETUP_WITH_FEATURES(CPUFeatures::kNEON);
4196 
4197   START();
4198   __ Ldr(x2, 0x1234567890abcdef);
4199   __ Ldr(w3, 0xfedcba09);
4200   __ Ldrsw(x4, 0x7fffffff);
4201   __ Ldrsw(x5, 0x80000000);
4202   __ Ldr(q11, 0x1234000056780000, 0xabcd0000ef000000);
4203   __ Ldr(d13, 1.234);
4204   __ Ldr(s25, 2.5);
4205   END();
4206 
4207   if (CAN_RUN()) {
4208     RUN();
4209 
4210     ASSERT_EQUAL_64(0x1234567890abcdef, x2);
4211     ASSERT_EQUAL_64(0xfedcba09, x3);
4212     ASSERT_EQUAL_64(0x7fffffff, x4);
4213     ASSERT_EQUAL_64(0xffffffff80000000, x5);
4214     ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
4215     ASSERT_EQUAL_FP64(1.234, d13);
4216     ASSERT_EQUAL_FP32(2.5, s25);
4217   }
4218 }
4219 
4220 
4221 TEST(ldr_literal_range) {
4222   SETUP_WITH_FEATURES(CPUFeatures::kNEON);
4223 
4224   START();
4225   // Make sure the pool is empty;
4226   masm.EmitLiteralPool(LiteralPool::kBranchRequired);
4227   ASSERT_LITERAL_POOL_SIZE(0);
4228 
4229   // Create some literal pool entries.
4230   __ Ldr(x0, 0x1234567890abcdef);
4231   __ Ldr(w1, 0xfedcba09);
4232   __ Ldrsw(x2, 0x7fffffff);
4233   __ Ldrsw(x3, 0x80000000);
4234   __ Ldr(q2, 0x1234000056780000, 0xabcd0000ef000000);
4235   __ Ldr(d0, 1.234);
4236   __ Ldr(s1, 2.5);
4237   ASSERT_LITERAL_POOL_SIZE(48);
4238 
4239   // Emit more code than the maximum literal load range to ensure the pool
4240   // should be emitted.
4241   const ptrdiff_t end = masm.GetCursorOffset() + 2 * kMaxLoadLiteralRange;
4242   while (masm.GetCursorOffset() < end) {
4243     __ Nop();
4244   }
4245 
4246   // The pool should have been emitted.
4247   ASSERT_LITERAL_POOL_SIZE(0);
4248 
4249   // These loads should be after the pool (and will require a new one).
4250   __ Ldr(x4, 0x34567890abcdef12);
4251   __ Ldr(w5, 0xdcba09fe);
4252   __ Ldrsw(x6, 0x7fffffff);
4253   __ Ldrsw(x7, 0x80000000);
4254   __ Ldr(q6, 0x1234000056780000, 0xabcd0000ef000000);
4255   __ Ldr(d4, 123.4);
4256   __ Ldr(s5, 250.0);
4257   ASSERT_LITERAL_POOL_SIZE(48);
4258   END();
4259 
4260   if (CAN_RUN()) {
4261     RUN();
4262 
4263     // Check that the literals loaded correctly.
4264     ASSERT_EQUAL_64(0x1234567890abcdef, x0);
4265     ASSERT_EQUAL_64(0xfedcba09, x1);
4266     ASSERT_EQUAL_64(0x7fffffff, x2);
4267     ASSERT_EQUAL_64(0xffffffff80000000, x3);
4268     ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q2);
4269     ASSERT_EQUAL_FP64(1.234, d0);
4270     ASSERT_EQUAL_FP32(2.5, s1);
4271     ASSERT_EQUAL_64(0x34567890abcdef12, x4);
4272     ASSERT_EQUAL_64(0xdcba09fe, x5);
4273     ASSERT_EQUAL_64(0x7fffffff, x6);
4274     ASSERT_EQUAL_64(0xffffffff80000000, x7);
4275     ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q6);
4276     ASSERT_EQUAL_FP64(123.4, d4);
4277     ASSERT_EQUAL_FP32(250.0, s5);
4278   }
4279 }
4280 
4281 
4282 template <typename T>
4283 void LoadIntValueHelper(T values[], int card) {
4284   SETUP();
4285 
4286   const bool is_32bit = (sizeof(T) == 4);
4287   Register tgt1 = is_32bit ? Register(w1) : Register(x1);
4288   Register tgt2 = is_32bit ? Register(w2) : Register(x2);
4289 
4290   START();
4291   __ Mov(x0, 0);
4292 
4293   // If one of the values differ then x0 will be one.
4294   for (int i = 0; i < card; ++i) {
4295     __ Mov(tgt1, values[i]);
4296     __ Ldr(tgt2, values[i]);
4297     __ Cmp(tgt1, tgt2);
4298     __ Cset(x0, ne);
4299   }
4300   END();
4301 
4302   if (CAN_RUN()) {
4303     RUN();
4304 
4305     // If one of the values differs, the trace can be used to identify which
4306     // one.
4307     ASSERT_EQUAL_64(0, x0);
4308   }
4309 }
4310 
4311 
4312 TEST(ldr_literal_values_x) {
4313   static const uint64_t kValues[] = {0x8000000000000000,
4314                                      0x7fffffffffffffff,
4315                                      0x0000000000000000,
4316                                      0xffffffffffffffff,
4317                                      0x00ff00ff00ff00ff,
4318                                      0x1234567890abcdef};
4319 
4320   LoadIntValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
4321 }
4322 
4323 
4324 TEST(ldr_literal_values_w) {
4325   static const uint32_t kValues[] = {0x80000000,
4326                                      0x7fffffff,
4327                                      0x00000000,
4328                                      0xffffffff,
4329                                      0x00ff00ff,
4330                                      0x12345678,
4331                                      0x90abcdef};
4332 
4333   LoadIntValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
4334 }
4335 
4336 TEST(ldr_literal_custom) {
4337   SETUP_WITH_FEATURES(CPUFeatures::kNEON);
4338 
4339   Label end_of_pool_before;
4340   Label end_of_pool_after;
4341 
4342   const size_t kSizeOfPoolInBytes = 44;
4343 
4344   Literal<uint64_t> before_x(0x1234567890abcdef);
4345   Literal<uint32_t> before_w(0xfedcba09);
4346   Literal<uint32_t> before_sx(0x80000000);
4347   Literal<uint64_t> before_q(0x1234000056780000, 0xabcd0000ef000000);
4348   Literal<double> before_d(1.234);
4349   Literal<float> before_s(2.5);
4350 
4351   Literal<uint64_t> after_x(0x1234567890abcdef);
4352   Literal<uint32_t> after_w(0xfedcba09);
4353   Literal<uint32_t> after_sx(0x80000000);
4354   Literal<uint64_t> after_q(0x1234000056780000, 0xabcd0000ef000000);
4355   Literal<double> after_d(1.234);
4356   Literal<float> after_s(2.5);
4357 
4358   START();
4359 
4360   // Manually generate a pool.
4361   __ B(&end_of_pool_before);
4362   {
4363     ExactAssemblyScope scope(&masm, kSizeOfPoolInBytes);
4364     __ place(&before_x);
4365     __ place(&before_w);
4366     __ place(&before_sx);
4367     __ place(&before_q);
4368     __ place(&before_d);
4369     __ place(&before_s);
4370   }
4371   __ Bind(&end_of_pool_before);
4372 
4373   {
4374     ExactAssemblyScope scope(&masm, 12 * kInstructionSize);
4375     __ ldr(x2, &before_x);
4376     __ ldr(w3, &before_w);
4377     __ ldrsw(x5, &before_sx);
4378     __ ldr(q11, &before_q);
4379     __ ldr(d13, &before_d);
4380     __ ldr(s25, &before_s);
4381 
4382     __ ldr(x6, &after_x);
4383     __ ldr(w7, &after_w);
4384     __ ldrsw(x8, &after_sx);
4385     __ ldr(q18, &after_q);
4386     __ ldr(d14, &after_d);
4387     __ ldr(s26, &after_s);
4388   }
4389 
4390   // Manually generate a pool.
4391   __ B(&end_of_pool_after);
4392   {
4393     ExactAssemblyScope scope(&masm, kSizeOfPoolInBytes);
4394     __ place(&after_x);
4395     __ place(&after_w);
4396     __ place(&after_sx);
4397     __ place(&after_q);
4398     __ place(&after_d);
4399     __ place(&after_s);
4400   }
4401   __ Bind(&end_of_pool_after);
4402 
4403   END();
4404 
4405   if (CAN_RUN()) {
4406     RUN();
4407 
4408     ASSERT_EQUAL_64(0x1234567890abcdef, x2);
4409     ASSERT_EQUAL_64(0xfedcba09, x3);
4410     ASSERT_EQUAL_64(0xffffffff80000000, x5);
4411     ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
4412     ASSERT_EQUAL_FP64(1.234, d13);
4413     ASSERT_EQUAL_FP32(2.5, s25);
4414 
4415     ASSERT_EQUAL_64(0x1234567890abcdef, x6);
4416     ASSERT_EQUAL_64(0xfedcba09, x7);
4417     ASSERT_EQUAL_64(0xffffffff80000000, x8);
4418     ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q18);
4419     ASSERT_EQUAL_FP64(1.234, d14);
4420     ASSERT_EQUAL_FP32(2.5, s26);
4421   }
4422 }
4423 
4424 
4425 TEST(ldr_literal_custom_shared) {
4426   SETUP_WITH_FEATURES(CPUFeatures::kNEON);
4427 
4428   Label end_of_pool_before;
4429   Label end_of_pool_after;
4430 
4431   const size_t kSizeOfPoolInBytes = 40;
4432 
4433   Literal<uint64_t> before_x(0x1234567890abcdef);
4434   Literal<uint32_t> before_w(0xfedcba09);
4435   Literal<uint64_t> before_q(0x1234000056780000, 0xabcd0000ef000000);
4436   Literal<double> before_d(1.234);
4437   Literal<float> before_s(2.5);
4438 
4439   Literal<uint64_t> after_x(0x1234567890abcdef);
4440   Literal<uint32_t> after_w(0xfedcba09);
4441   Literal<uint64_t> after_q(0x1234000056780000, 0xabcd0000ef000000);
4442   Literal<double> after_d(1.234);
4443   Literal<float> after_s(2.5);
4444 
4445   START();
4446 
4447   // Manually generate a pool.
4448   __ B(&end_of_pool_before);
4449   {
4450     ExactAssemblyScope scope(&masm, kSizeOfPoolInBytes);
4451     __ place(&before_x);
4452     __ place(&before_w);
4453     __ place(&before_q);
4454     __ place(&before_d);
4455     __ place(&before_s);
4456   }
4457   __ Bind(&end_of_pool_before);
4458 
4459   // Load the entries several times to test that literals can be shared.
4460   for (int i = 0; i < 50; i++) {
4461     ExactAssemblyScope scope(&masm, 12 * kInstructionSize);
4462     __ ldr(x2, &before_x);
4463     __ ldr(w3, &before_w);
4464     __ ldrsw(x5, &before_w);  // Re-use before_w.
4465     __ ldr(q11, &before_q);
4466     __ ldr(d13, &before_d);
4467     __ ldr(s25, &before_s);
4468 
4469     __ ldr(x6, &after_x);
4470     __ ldr(w7, &after_w);
4471     __ ldrsw(x8, &after_w);  // Re-use after_w.
4472     __ ldr(q18, &after_q);
4473     __ ldr(d14, &after_d);
4474     __ ldr(s26, &after_s);
4475   }
4476 
4477   // Manually generate a pool.
4478   __ B(&end_of_pool_after);
4479   {
4480     ExactAssemblyScope scope(&masm, kSizeOfPoolInBytes);
4481     __ place(&after_x);
4482     __ place(&after_w);
4483     __ place(&after_q);
4484     __ place(&after_d);
4485     __ place(&after_s);
4486   }
4487   __ Bind(&end_of_pool_after);
4488 
4489   END();
4490 
4491   if (CAN_RUN()) {
4492     RUN();
4493 
4494     ASSERT_EQUAL_64(0x1234567890abcdef, x2);
4495     ASSERT_EQUAL_64(0xfedcba09, x3);
4496     ASSERT_EQUAL_64(0xfffffffffedcba09, x5);
4497     ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q11);
4498     ASSERT_EQUAL_FP64(1.234, d13);
4499     ASSERT_EQUAL_FP32(2.5, s25);
4500 
4501     ASSERT_EQUAL_64(0x1234567890abcdef, x6);
4502     ASSERT_EQUAL_64(0xfedcba09, x7);
4503     ASSERT_EQUAL_64(0xfffffffffedcba09, x8);
4504     ASSERT_EQUAL_128(0x1234000056780000, 0xabcd0000ef000000, q18);
4505     ASSERT_EQUAL_FP64(1.234, d14);
4506     ASSERT_EQUAL_FP32(2.5, s26);
4507   }
4508 }
4509 
4510 static const PrefetchOperation kPrfmOperations[] = {PLDL1KEEP,
4511                                                     PLDL1STRM,
4512                                                     PLDL2KEEP,
4513                                                     PLDL2STRM,
4514                                                     PLDL3KEEP,
4515                                                     PLDL3STRM,
4516 
4517                                                     PLIL1KEEP,
4518                                                     PLIL1STRM,
4519                                                     PLIL2KEEP,
4520                                                     PLIL2STRM,
4521                                                     PLIL3KEEP,
4522                                                     PLIL3STRM,
4523 
4524                                                     PSTL1KEEP,
4525                                                     PSTL1STRM,
4526                                                     PSTL2KEEP,
4527                                                     PSTL2STRM,
4528                                                     PSTL3KEEP,
4529                                                     PSTL3STRM};
4530 
4531 TEST(prfm_offset) {
4532   SETUP();
4533 
4534   START();
4535   // The address used in prfm doesn't have to be valid.
4536   __ Mov(x0, 0x0123456789abcdef);
4537 
4538   for (int op = 0; op < (1 << ImmPrefetchOperation_width); op++) {
4539     // Unallocated prefetch operations are ignored, so test all of them.
4540     // We have to use the Assembler directly for this.
4541     ExactAssemblyScope guard(&masm, 3 * kInstructionSize);
4542     __ prfm(op, MemOperand(x0));
4543     __ prfm(op, MemOperand(x0, 8));
4544     __ prfm(op, MemOperand(x0, 32760));
4545   }
4546 
4547   for (PrefetchOperation op : kPrfmOperations) {
4548     // Also test named operations.
4549     __ Prfm(op, MemOperand(x0, 32768));
4550     __ Prfm(op, MemOperand(x0, 1));
4551     __ Prfm(op, MemOperand(x0, 9));
4552     __ Prfm(op, MemOperand(x0, 255));
4553     __ Prfm(op, MemOperand(x0, 257));
4554     __ Prfm(op, MemOperand(x0, -1));
4555     __ Prfm(op, MemOperand(x0, -9));
4556     __ Prfm(op, MemOperand(x0, -255));
4557     __ Prfm(op, MemOperand(x0, -257));
4558 
4559     __ Prfm(op, MemOperand(x0, 0xfedcba9876543210));
4560   }
4561 
4562   END();
4563   if (CAN_RUN()) {
4564     RUN();
4565   }
4566 }
4567 
4568 
4569 TEST(prfm_regoffset) {
4570   SETUP();
4571 
4572   START();
4573   // The address used in prfm doesn't have to be valid.
4574   __ Mov(x0, 0x0123456789abcdef);
4575 
4576   CPURegList inputs(CPURegister::kRegister, kXRegSize, 10, 18);
4577   __ Mov(x10, 0);
4578   __ Mov(x11, 1);
4579   __ Mov(x12, 8);
4580   __ Mov(x13, 255);
4581   __ Mov(x14, -0);
4582   __ Mov(x15, -1);
4583   __ Mov(x16, -8);
4584   __ Mov(x17, -255);
4585   __ Mov(x18, 0xfedcba9876543210);
4586 
4587   for (int op = 0; op < (1 << ImmPrefetchOperation_width); op++) {
4588     // Unallocated prefetch operations are ignored, so test all of them.
4589     // We have to use the Assembler directly for this.
4590 
4591     // Prefetch operations of the form 0b11xxx are allocated to another
4592     // instruction.
4593     if (op >= 0b11000) continue;
4594 
4595     ExactAssemblyScope guard(&masm, inputs.GetCount() * kInstructionSize);
4596     CPURegList loop = inputs;
4597     while (!loop.IsEmpty()) {
4598       __ prfm(op, MemOperand(x0, Register(loop.PopLowestIndex())));
4599     }
4600   }
4601 
4602   for (PrefetchOperation op : kPrfmOperations) {
4603     // Also test named operations.
4604     CPURegList loop = inputs;
4605     while (!loop.IsEmpty()) {
4606       Register input(loop.PopLowestIndex());
4607       __ Prfm(op, MemOperand(x0, input, UXTW));
4608       __ Prfm(op, MemOperand(x0, input, UXTW, 3));
4609       __ Prfm(op, MemOperand(x0, input, LSL));
4610       __ Prfm(op, MemOperand(x0, input, LSL, 3));
4611       __ Prfm(op, MemOperand(x0, input, SXTW));
4612       __ Prfm(op, MemOperand(x0, input, SXTW, 3));
4613       __ Prfm(op, MemOperand(x0, input, SXTX));
4614       __ Prfm(op, MemOperand(x0, input, SXTX, 3));
4615     }
4616   }
4617 
4618   END();
4619   if (CAN_RUN()) {
4620     RUN();
4621   }
4622 }
4623 
4624 
4625 TEST(prfm_literal_imm19) {
4626   SETUP();
4627   START();
4628 
4629   for (int op = 0; op < (1 << ImmPrefetchOperation_width); op++) {
4630     // Unallocated prefetch operations are ignored, so test all of them.
4631     // We have to use the Assembler directly for this.
4632     ExactAssemblyScope guard(&masm, 3 * kInstructionSize);
4633     __ prfm(op, INT64_C(0));
4634     __ prfm(op, 1);
4635     __ prfm(op, -1);
4636   }
4637 
4638   for (PrefetchOperation op : kPrfmOperations) {
4639     // Also test named operations.
4640     ExactAssemblyScope guard(&masm, 4 * kInstructionSize);
4641     // The address used in prfm doesn't have to be valid.
4642     __ prfm(op, 1000);
4643     __ prfm(op, -1000);
4644     __ prfm(op, 0x3ffff);
4645     __ prfm(op, -0x40000);
4646   }
4647 
4648   END();
4649   if (CAN_RUN()) {
4650     RUN();
4651   }
4652 }
4653 
4654 
4655 TEST(prfm_literal) {
4656   SETUP();
4657 
4658   Label end_of_pool_before;
4659   Label end_of_pool_after;
4660   Literal<uint64_t> before(0);
4661   Literal<uint64_t> after(0);
4662 
4663   START();
4664 
4665   // Manually generate a pool.
4666   __ B(&end_of_pool_before);
4667   {
4668     ExactAssemblyScope scope(&masm, before.GetSize());
4669     __ place(&before);
4670   }
4671   __ Bind(&end_of_pool_before);
4672 
4673   for (int op = 0; op < (1 << ImmPrefetchOperation_width); op++) {
4674     // Unallocated prefetch operations are ignored, so test all of them.
4675     // We have to use the Assembler directly for this.
4676     ExactAssemblyScope guard(&masm, 2 * kInstructionSize);
4677     __ prfm(op, &before);
4678     __ prfm(op, &after);
4679   }
4680 
4681   for (PrefetchOperation op : kPrfmOperations) {
4682     // Also test named operations.
4683     ExactAssemblyScope guard(&masm, 2 * kInstructionSize);
4684     __ prfm(op, &before);
4685     __ prfm(op, &after);
4686   }
4687 
4688   // Manually generate a pool.
4689   __ B(&end_of_pool_after);
4690   {
4691     ExactAssemblyScope scope(&masm, after.GetSize());
4692     __ place(&after);
4693   }
4694   __ Bind(&end_of_pool_after);
4695 
4696   END();
4697   if (CAN_RUN()) {
4698     RUN();
4699   }
4700 }
4701 
4702 
4703 TEST(prfm_wide) {
4704   SETUP();
4705 
4706   START();
4707   // The address used in prfm doesn't have to be valid.
4708   __ Mov(x0, 0x0123456789abcdef);
4709 
4710   for (PrefetchOperation op : kPrfmOperations) {
4711     __ Prfm(op, MemOperand(x0, 0x40000));
4712     __ Prfm(op, MemOperand(x0, -0x40001));
4713     __ Prfm(op, MemOperand(x0, UINT64_C(0x5555555555555555)));
4714     __ Prfm(op, MemOperand(x0, UINT64_C(0xfedcba9876543210)));
4715   }
4716 
4717   END();
4718   if (CAN_RUN()) {
4719     RUN();
4720   }
4721 }
4722 
4723 
4724 TEST(load_prfm_literal) {
4725   // Test literals shared between both prfm and ldr.
4726   SETUP_WITH_FEATURES(CPUFeatures::kFP);
4727 
4728   Label end_of_pool_before;
4729   Label end_of_pool_after;
4730 
4731   const size_t kSizeOfPoolInBytes = 28;
4732 
4733   Literal<uint64_t> before_x(0x1234567890abcdef);
4734   Literal<uint32_t> before_w(0xfedcba09);
4735   Literal<uint32_t> before_sx(0x80000000);
4736   Literal<double> before_d(1.234);
4737   Literal<float> before_s(2.5);
4738   Literal<uint64_t> after_x(0x1234567890abcdef);
4739   Literal<uint32_t> after_w(0xfedcba09);
4740   Literal<uint32_t> after_sx(0x80000000);
4741   Literal<double> after_d(1.234);
4742   Literal<float> after_s(2.5);
4743 
4744   START();
4745 
4746   // Manually generate a pool.
4747   __ B(&end_of_pool_before);
4748   {
4749     ExactAssemblyScope scope(&masm, kSizeOfPoolInBytes);
4750     __ place(&before_x);
4751     __ place(&before_w);
4752     __ place(&before_sx);
4753     __ place(&before_d);
4754     __ place(&before_s);
4755   }
4756   __ Bind(&end_of_pool_before);
4757 
4758   for (int op = 0; op < (1 << ImmPrefetchOperation_width); op++) {
4759     // Unallocated prefetch operations are ignored, so test all of them.
4760     ExactAssemblyScope scope(&masm, 10 * kInstructionSize);
4761 
4762     __ prfm(op, &before_x);
4763     __ prfm(op, &before_w);
4764     __ prfm(op, &before_sx);
4765     __ prfm(op, &before_d);
4766     __ prfm(op, &before_s);
4767 
4768     __ prfm(op, &after_x);
4769     __ prfm(op, &after_w);
4770     __ prfm(op, &after_sx);
4771     __ prfm(op, &after_d);
4772     __ prfm(op, &after_s);
4773   }
4774 
4775   for (PrefetchOperation op : kPrfmOperations) {
4776     // Also test named operations.
4777     ExactAssemblyScope scope(&masm, 10 * kInstructionSize);
4778 
4779     __ prfm(op, &before_x);
4780     __ prfm(op, &before_w);
4781     __ prfm(op, &before_sx);
4782     __ prfm(op, &before_d);
4783     __ prfm(op, &before_s);
4784 
4785     __ prfm(op, &after_x);
4786     __ prfm(op, &after_w);
4787     __ prfm(op, &after_sx);
4788     __ prfm(op, &after_d);
4789     __ prfm(op, &after_s);
4790   }
4791 
4792   {
4793     ExactAssemblyScope scope(&masm, 10 * kInstructionSize);
4794     __ ldr(x2, &before_x);
4795     __ ldr(w3, &before_w);
4796     __ ldrsw(x5, &before_sx);
4797     __ ldr(d13, &before_d);
4798     __ ldr(s25, &before_s);
4799 
4800     __ ldr(x6, &after_x);
4801     __ ldr(w7, &after_w);
4802     __ ldrsw(x8, &after_sx);
4803     __ ldr(d14, &after_d);
4804     __ ldr(s26, &after_s);
4805   }
4806 
4807   // Manually generate a pool.
4808   __ B(&end_of_pool_after);
4809   {
4810     ExactAssemblyScope scope(&masm, kSizeOfPoolInBytes);
4811     __ place(&after_x);
4812     __ place(&after_w);
4813     __ place(&after_sx);
4814     __ place(&after_d);
4815     __ place(&after_s);
4816   }
4817   __ Bind(&end_of_pool_after);
4818 
4819   END();
4820 
4821   if (CAN_RUN()) {
4822     RUN();
4823 
4824     ASSERT_EQUAL_64(0x1234567890abcdef, x2);
4825     ASSERT_EQUAL_64(0xfedcba09, x3);
4826     ASSERT_EQUAL_64(0xffffffff80000000, x5);
4827     ASSERT_EQUAL_FP64(1.234, d13);
4828     ASSERT_EQUAL_FP32(2.5, s25);
4829 
4830     ASSERT_EQUAL_64(0x1234567890abcdef, x6);
4831     ASSERT_EQUAL_64(0xfedcba09, x7);
4832     ASSERT_EQUAL_64(0xffffffff80000000, x8);
4833     ASSERT_EQUAL_FP64(1.234, d14);
4834     ASSERT_EQUAL_FP32(2.5, s26);
4835   }
4836 }
4837 
4838 
4839 TEST(add_sub_imm) {
4840   SETUP();
4841 
4842   START();
4843   __ Mov(x0, 0x0);
4844   __ Mov(x1, 0x1111);
4845   __ Mov(x2, 0xffffffffffffffff);
4846   __ Mov(x3, 0x8000000000000000);
4847 
4848   __ Add(x10, x0, Operand(0x123));
4849   __ Add(x11, x1, Operand(0x122000));
4850   __ Add(x12, x0, Operand(0xabc << 12));
4851   __ Add(x13, x2, Operand(1));
4852 
4853   __ Add(w14, w0, Operand(0x123));
4854   __ Add(w15, w1, Operand(0x122000));
4855   __ Add(w16, w0, Operand(0xabc << 12));
4856   __ Add(w17, w2, Operand(1));
4857 
4858   __ Sub(x20, x0, Operand(0x1));
4859   __ Sub(x21, x1, Operand(0x111));
4860   __ Sub(x22, x1, Operand(0x1 << 12));
4861   __ Sub(x23, x3, Operand(1));
4862 
4863   __ Sub(w24, w0, Operand(0x1));
4864   __ Sub(w25, w1, Operand(0x111));
4865   __ Sub(w26, w1, Operand(0x1 << 12));
4866   __ Sub(w27, w3, Operand(1));
4867   END();
4868 
4869   if (CAN_RUN()) {
4870     RUN();
4871 
4872     ASSERT_EQUAL_64(0x123, x10);
4873     ASSERT_EQUAL_64(0x123111, x11);
4874     ASSERT_EQUAL_64(0xabc000, x12);
4875     ASSERT_EQUAL_64(0x0, x13);
4876 
4877     ASSERT_EQUAL_32(0x123, w14);
4878     ASSERT_EQUAL_32(0x123111, w15);
4879     ASSERT_EQUAL_32(0xabc000, w16);
4880     ASSERT_EQUAL_32(0x0, w17);
4881 
4882     ASSERT_EQUAL_64(0xffffffffffffffff, x20);
4883     ASSERT_EQUAL_64(0x1000, x21);
4884     ASSERT_EQUAL_64(0x111, x22);
4885     ASSERT_EQUAL_64(0x7fffffffffffffff, x23);
4886 
4887     ASSERT_EQUAL_32(0xffffffff, w24);
4888     ASSERT_EQUAL_32(0x1000, w25);
4889     ASSERT_EQUAL_32(0x111, w26);
4890     ASSERT_EQUAL_32(0xffffffff, w27);
4891   }
4892 }
4893 
4894 
4895 TEST(add_sub_wide_imm) {
4896   SETUP();
4897 
4898   START();
4899   __ Mov(x0, 0x0);
4900   __ Mov(x1, 0x1);
4901 
4902   __ Add(x10, x0, Operand(0x1234567890abcdef));
4903   __ Add(x11, x1, Operand(0xffffffff));
4904 
4905   __ Add(w12, w0, Operand(0x12345678));
4906   __ Add(w13, w1, Operand(0xffffffff));
4907 
4908   __ Add(w18, w0, Operand(kWMinInt));
4909   __ Sub(w19, w0, Operand(kWMinInt));
4910 
4911   __ Sub(x20, x0, Operand(0x1234567890abcdef));
4912   __ Sub(w21, w0, Operand(0x12345678));
4913 
4914   END();
4915 
4916   if (CAN_RUN()) {
4917     RUN();
4918 
4919     ASSERT_EQUAL_64(0x1234567890abcdef, x10);
4920     ASSERT_EQUAL_64(0x100000000, x11);
4921 
4922     ASSERT_EQUAL_32(0x12345678, w12);
4923     ASSERT_EQUAL_64(0x0, x13);
4924 
4925     ASSERT_EQUAL_32(kWMinInt, w18);
4926     ASSERT_EQUAL_32(kWMinInt, w19);
4927 
4928     ASSERT_EQUAL_64(-0x1234567890abcdef, x20);
4929     ASSERT_EQUAL_32(-0x12345678, w21);
4930   }
4931 }
4932 
4933 
4934 TEST(add_sub_shifted) {
4935   SETUP();
4936 
4937   START();
4938   __ Mov(x0, 0);
4939   __ Mov(x1, 0x0123456789abcdef);
4940   __ Mov(x2, 0xfedcba9876543210);
4941   __ Mov(x3, 0xffffffffffffffff);
4942 
4943   __ Add(x10, x1, Operand(x2));
4944   __ Add(x11, x0, Operand(x1, LSL, 8));
4945   __ Add(x12, x0, Operand(x1, LSR, 8));
4946   __ Add(x13, x0, Operand(x1, ASR, 8));
4947   __ Add(x14, x0, Operand(x2, ASR, 8));
4948   __ Add(w15, w0, Operand(w1, ASR, 8));
4949   __ Add(w18, w3, Operand(w1, ROR, 8));
4950   __ Add(x19, x3, Operand(x1, ROR, 8));
4951 
4952   __ Sub(x20, x3, Operand(x2));
4953   __ Sub(x21, x3, Operand(x1, LSL, 8));
4954   __ Sub(x22, x3, Operand(x1, LSR, 8));
4955   __ Sub(x23, x3, Operand(x1, ASR, 8));
4956   __ Sub(x24, x3, Operand(x2, ASR, 8));
4957   __ Sub(w25, w3, Operand(w1, ASR, 8));
4958   __ Sub(w26, w3, Operand(w1, ROR, 8));
4959   __ Sub(x27, x3, Operand(x1, ROR, 8));
4960   END();
4961 
4962   if (CAN_RUN()) {
4963     RUN();
4964 
4965     ASSERT_EQUAL_64(0xffffffffffffffff, x10);
4966     ASSERT_EQUAL_64(0x23456789abcdef00, x11);
4967     ASSERT_EQUAL_64(0x000123456789abcd, x12);
4968     ASSERT_EQUAL_64(0x000123456789abcd, x13);
4969     ASSERT_EQUAL_64(0xfffedcba98765432, x14);
4970     ASSERT_EQUAL_64(0xff89abcd, x15);
4971     ASSERT_EQUAL_64(0xef89abcc, x18);
4972     ASSERT_EQUAL_64(0xef0123456789abcc, x19);
4973 
4974     ASSERT_EQUAL_64(0x0123456789abcdef, x20);
4975     ASSERT_EQUAL_64(0xdcba9876543210ff, x21);
4976     ASSERT_EQUAL_64(0xfffedcba98765432, x22);
4977     ASSERT_EQUAL_64(0xfffedcba98765432, x23);
4978     ASSERT_EQUAL_64(0x000123456789abcd, x24);
4979     ASSERT_EQUAL_64(0x00765432, x25);
4980     ASSERT_EQUAL_64(0x10765432, x26);
4981     ASSERT_EQUAL_64(0x10fedcba98765432, x27);
4982   }
4983 }
4984 
4985 
4986 TEST(add_sub_extended) {
4987   SETUP();
4988 
4989   START();
4990   __ Mov(x0, 0);
4991   __ Mov(x1, 0x0123456789abcdef);
4992   __ Mov(x2, 0xfedcba9876543210);
4993   __ Mov(w3, 0x80);
4994 
4995   __ Add(x10, x0, Operand(x1, UXTB, 0));
4996   __ Add(x11, x0, Operand(x1, UXTB, 1));
4997   __ Add(x12, x0, Operand(x1, UXTH, 2));
4998   __ Add(x13, x0, Operand(x1, UXTW, 4));
4999 
5000   __ Add(x14, x0, Operand(x1, SXTB, 0));
5001   __ Add(x15, x0, Operand(x1, SXTB, 1));
5002   __ Add(x16, x0, Operand(x1, SXTH, 2));
5003   __ Add(x17, x0, Operand(x1, SXTW, 3));
5004   __ Add(x18, x0, Operand(x2, SXTB, 0));
5005   __ Add(x19, x0, Operand(x2, SXTB, 1));
5006   __ Add(x20, x0, Operand(x2, SXTH, 2));
5007   __ Add(x21, x0, Operand(x2, SXTW, 3));
5008 
5009   __ Add(x22, x1, Operand(x2, SXTB, 1));
5010   __ Sub(x23, x1, Operand(x2, SXTB, 1));
5011 
5012   __ Add(w24, w1, Operand(w2, UXTB, 2));
5013   __ Add(w25, w0, Operand(w1, SXTB, 0));
5014   __ Add(w26, w0, Operand(w1, SXTB, 1));
5015   __ Add(w27, w2, Operand(w1, SXTW, 3));
5016 
5017   __ Add(w28, w0, Operand(w1, SXTW, 3));
5018   __ Add(x29, x0, Operand(w1, SXTW, 3));
5019 
5020   __ Sub(x30, x0, Operand(w3, SXTB, 1));
5021   END();
5022 
5023   if (CAN_RUN()) {
5024     RUN();
5025 
5026     ASSERT_EQUAL_64(0xef, x10);
5027     ASSERT_EQUAL_64(0x1de, x11);
5028     ASSERT_EQUAL_64(0x337bc, x12);
5029     ASSERT_EQUAL_64(0x89abcdef0, x13);
5030 
5031     ASSERT_EQUAL_64(0xffffffffffffffef, x14);
5032     ASSERT_EQUAL_64(0xffffffffffffffde, x15);
5033     ASSERT_EQUAL_64(0xffffffffffff37bc, x16);
5034     ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x17);
5035     ASSERT_EQUAL_64(0x10, x18);
5036     ASSERT_EQUAL_64(0x20, x19);
5037     ASSERT_EQUAL_64(0xc840, x20);
5038     ASSERT_EQUAL_64(0x3b2a19080, x21);
5039 
5040     ASSERT_EQUAL_64(0x0123456789abce0f, x22);
5041     ASSERT_EQUAL_64(0x0123456789abcdcf, x23);
5042 
5043     ASSERT_EQUAL_32(0x89abce2f, w24);
5044     ASSERT_EQUAL_32(0xffffffef, w25);
5045     ASSERT_EQUAL_32(0xffffffde, w26);
5046     ASSERT_EQUAL_32(0xc3b2a188, w27);
5047 
5048     ASSERT_EQUAL_32(0x4d5e6f78, w28);
5049     ASSERT_EQUAL_64(0xfffffffc4d5e6f78, x29);
5050 
5051     ASSERT_EQUAL_64(256, x30);
5052   }
5053 }
5054 
5055 
5056 TEST(add_sub_negative) {
5057   SETUP();
5058 
5059   START();
5060   __ Mov(x0, 0);
5061   __ Mov(x1, 4687);
5062   __ Mov(x2, 0x1122334455667788);
5063   __ Mov(w3, 0x11223344);
5064   __ Mov(w4, 400000);
5065 
5066   __ Add(x10, x0, -42);
5067   __ Add(x11, x1, -687);
5068   __ Add(x12, x2, -0x88);
5069 
5070   __ Sub(x13, x0, -600);
5071   __ Sub(x14, x1, -313);
5072   __ Sub(x15, x2, -0x555);
5073 
5074   __ Add(w19, w3, -0x344);
5075   __ Add(w20, w4, -2000);
5076 
5077   __ Sub(w21, w3, -0xbc);
5078   __ Sub(w22, w4, -2000);
5079   END();
5080 
5081   if (CAN_RUN()) {
5082     RUN();
5083 
5084     ASSERT_EQUAL_64(-42, x10);
5085     ASSERT_EQUAL_64(4000, x11);
5086     ASSERT_EQUAL_64(0x1122334455667700, x12);
5087 
5088     ASSERT_EQUAL_64(600, x13);
5089     ASSERT_EQUAL_64(5000, x14);
5090     ASSERT_EQUAL_64(0x1122334455667cdd, x15);
5091 
5092     ASSERT_EQUAL_32(0x11223000, w19);
5093     ASSERT_EQUAL_32(398000, w20);
5094 
5095     ASSERT_EQUAL_32(0x11223400, w21);
5096     ASSERT_EQUAL_32(402000, w22);
5097   }
5098 }
5099 
5100 
5101 TEST(add_sub_zero) {
5102   SETUP();
5103 
5104   START();
5105   __ Mov(x0, 0);
5106   __ Mov(x1, 0);
5107   __ Mov(x2, 0);
5108 
5109   Label blob1;
5110   __ Bind(&blob1);
5111   __ Add(x0, x0, 0);
5112   __ Sub(x1, x1, 0);
5113   __ Sub(x2, x2, xzr);
5114   VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&blob1) == 0);
5115 
5116   Label blob2;
5117   __ Bind(&blob2);
5118   __ Add(w3, w3, 0);
5119   VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&blob2) != 0);
5120 
5121   Label blob3;
5122   __ Bind(&blob3);
5123   __ Sub(w3, w3, wzr);
5124   VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&blob3) != 0);
5125 
5126   END();
5127 
5128   if (CAN_RUN()) {
5129     RUN();
5130 
5131     ASSERT_EQUAL_64(0, x0);
5132     ASSERT_EQUAL_64(0, x1);
5133     ASSERT_EQUAL_64(0, x2);
5134   }
5135 }
5136 
5137 
5138 TEST(claim_drop_zero) {
5139   SETUP();
5140 
5141   START();
5142 
5143   Label start;
5144   __ Bind(&start);
5145   __ Claim(Operand(0));
5146   __ Drop(Operand(0));
5147   __ Claim(Operand(xzr));
5148   __ Drop(Operand(xzr));
5149   VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&start) == 0);
5150 
5151   END();
5152 
5153   if (CAN_RUN()) {
5154     RUN();
5155   }
5156 }
5157 
5158 
5159 TEST(neg) {
5160   SETUP();
5161 
5162   START();
5163   __ Mov(x0, 0xf123456789abcdef);
5164 
5165   // Immediate.
5166   __ Neg(x1, 0x123);
5167   __ Neg(w2, 0x123);
5168 
5169   // Shifted.
5170   __ Neg(x3, Operand(x0, LSL, 1));
5171   __ Neg(w4, Operand(w0, LSL, 2));
5172   __ Neg(x5, Operand(x0, LSR, 3));
5173   __ Neg(w6, Operand(w0, LSR, 4));
5174   __ Neg(x7, Operand(x0, ASR, 5));
5175   __ Neg(w8, Operand(w0, ASR, 6));
5176 
5177   // Extended.
5178   __ Neg(w9, Operand(w0, UXTB));
5179   __ Neg(x10, Operand(x0, SXTB, 1));
5180   __ Neg(w11, Operand(w0, UXTH, 2));
5181   __ Neg(x12, Operand(x0, SXTH, 3));
5182   __ Neg(w13, Operand(w0, UXTW, 4));
5183   __ Neg(x14, Operand(x0, SXTW, 4));
5184   END();
5185 
5186   if (CAN_RUN()) {
5187     RUN();
5188 
5189     ASSERT_EQUAL_64(0xfffffffffffffedd, x1);
5190     ASSERT_EQUAL_64(0xfffffedd, x2);
5191     ASSERT_EQUAL_64(0x1db97530eca86422, x3);
5192     ASSERT_EQUAL_64(0xd950c844, x4);
5193     ASSERT_EQUAL_64(0xe1db97530eca8643, x5);
5194     ASSERT_EQUAL_64(0xf7654322, x6);
5195     ASSERT_EQUAL_64(0x0076e5d4c3b2a191, x7);
5196     ASSERT_EQUAL_64(0x01d950c9, x8);
5197     ASSERT_EQUAL_64(0xffffff11, x9);
5198     ASSERT_EQUAL_64(0x0000000000000022, x10);
5199     ASSERT_EQUAL_64(0xfffcc844, x11);
5200     ASSERT_EQUAL_64(0x0000000000019088, x12);
5201     ASSERT_EQUAL_64(0x65432110, x13);
5202     ASSERT_EQUAL_64(0x0000000765432110, x14);
5203   }
5204 }
5205 
5206 
5207 template <typename T, typename Op>
5208 static void AdcsSbcsHelper(
5209     Op op, T left, T right, int carry, T expected, StatusFlags expected_flags) {
5210   int reg_size = sizeof(T) * 8;
5211   Register left_reg(0, reg_size);
5212   Register right_reg(1, reg_size);
5213   Register result_reg(2, reg_size);
5214 
5215   SETUP();
5216   START();
5217 
5218   __ Mov(left_reg, left);
5219   __ Mov(right_reg, right);
5220   __ Mov(x10, (carry ? CFlag : NoFlag));
5221 
5222   __ Msr(NZCV, x10);
5223   (masm.*op)(result_reg, left_reg, right_reg);
5224 
5225   END();
5226   if (CAN_RUN()) {
5227     RUN();
5228 
5229     ASSERT_EQUAL_64(left, left_reg.X());
5230     ASSERT_EQUAL_64(right, right_reg.X());
5231     ASSERT_EQUAL_64(expected, result_reg.X());
5232     ASSERT_EQUAL_NZCV(expected_flags);
5233   }
5234 }
5235 
5236 
5237 TEST(adcs_sbcs_x) {
5238   uint64_t inputs[] = {
5239       0x0000000000000000,
5240       0x0000000000000001,
5241       0x7ffffffffffffffe,
5242       0x7fffffffffffffff,
5243       0x8000000000000000,
5244       0x8000000000000001,
5245       0xfffffffffffffffe,
5246       0xffffffffffffffff,
5247   };
5248   static const size_t input_count = sizeof(inputs) / sizeof(inputs[0]);
5249 
5250   struct Expected {
5251     uint64_t carry0_result;
5252     StatusFlags carry0_flags;
5253     uint64_t carry1_result;
5254     StatusFlags carry1_flags;
5255   };
5256 
5257   static const Expected expected_adcs_x[input_count][input_count] =
5258       {{{0x0000000000000000, ZFlag, 0x0000000000000001, NoFlag},
5259         {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
5260         {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
5261         {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
5262         {0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
5263         {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
5264         {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
5265         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag}},
5266        {{0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
5267         {0x0000000000000002, NoFlag, 0x0000000000000003, NoFlag},
5268         {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
5269         {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
5270         {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
5271         {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
5272         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5273         {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag}},
5274        {{0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
5275         {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
5276         {0xfffffffffffffffc, NVFlag, 0xfffffffffffffffd, NVFlag},
5277         {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
5278         {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
5279         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5280         {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
5281         {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag}},
5282        {{0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
5283         {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
5284         {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
5285         {0xfffffffffffffffe, NVFlag, 0xffffffffffffffff, NVFlag},
5286         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5287         {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
5288         {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
5289         {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag}},
5290        {{0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
5291         {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
5292         {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
5293         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5294         {0x0000000000000000, ZCVFlag, 0x0000000000000001, CVFlag},
5295         {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
5296         {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
5297         {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag}},
5298        {{0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
5299         {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
5300         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5301         {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
5302         {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
5303         {0x0000000000000002, CVFlag, 0x0000000000000003, CVFlag},
5304         {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
5305         {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag}},
5306        {{0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
5307         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5308         {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
5309         {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
5310         {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
5311         {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
5312         {0xfffffffffffffffc, NCFlag, 0xfffffffffffffffd, NCFlag},
5313         {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag}},
5314        {{0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5315         {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
5316         {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
5317         {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
5318         {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
5319         {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
5320         {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
5321         {0xfffffffffffffffe, NCFlag, 0xffffffffffffffff, NCFlag}}};
5322 
5323   static const Expected expected_sbcs_x[input_count][input_count] =
5324       {{{0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5325         {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
5326         {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
5327         {0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
5328         {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
5329         {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
5330         {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
5331         {0x0000000000000000, ZFlag, 0x0000000000000001, NoFlag}},
5332        {{0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
5333         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5334         {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
5335         {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
5336         {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
5337         {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
5338         {0x0000000000000002, NoFlag, 0x0000000000000003, NoFlag},
5339         {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag}},
5340        {{0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
5341         {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
5342         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5343         {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
5344         {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
5345         {0xfffffffffffffffc, NVFlag, 0xfffffffffffffffd, NVFlag},
5346         {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
5347         {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag}},
5348        {{0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
5349         {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
5350         {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
5351         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5352         {0xfffffffffffffffe, NVFlag, 0xffffffffffffffff, NVFlag},
5353         {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
5354         {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
5355         {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag}},
5356        {{0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
5357         {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
5358         {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
5359         {0x0000000000000000, ZCVFlag, 0x0000000000000001, CVFlag},
5360         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5361         {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
5362         {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
5363         {0x8000000000000000, NFlag, 0x8000000000000001, NFlag}},
5364        {{0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
5365         {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
5366         {0x0000000000000002, CVFlag, 0x0000000000000003, CVFlag},
5367         {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
5368         {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
5369         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5370         {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
5371         {0x8000000000000001, NFlag, 0x8000000000000002, NFlag}},
5372        {{0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
5373         {0xfffffffffffffffc, NCFlag, 0xfffffffffffffffd, NCFlag},
5374         {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
5375         {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
5376         {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
5377         {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
5378         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
5379         {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag}},
5380        {{0xfffffffffffffffe, NCFlag, 0xffffffffffffffff, NCFlag},
5381         {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
5382         {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
5383         {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
5384         {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
5385         {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
5386         {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
5387         {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag}}};
5388 
5389   for (size_t left = 0; left < input_count; left++) {
5390     for (size_t right = 0; right < input_count; right++) {
5391       const Expected& expected = expected_adcs_x[left][right];
5392       AdcsSbcsHelper(&MacroAssembler::Adcs,
5393                      inputs[left],
5394                      inputs[right],
5395                      0,
5396                      expected.carry0_result,
5397                      expected.carry0_flags);
5398       AdcsSbcsHelper(&MacroAssembler::Adcs,
5399                      inputs[left],
5400                      inputs[right],
5401                      1,
5402                      expected.carry1_result,
5403                      expected.carry1_flags);
5404     }
5405   }
5406 
5407   for (size_t left = 0; left < input_count; left++) {
5408     for (size_t right = 0; right < input_count; right++) {
5409       const Expected& expected = expected_sbcs_x[left][right];
5410       AdcsSbcsHelper(&MacroAssembler::Sbcs,
5411                      inputs[left],
5412                      inputs[right],
5413                      0,
5414                      expected.carry0_result,
5415                      expected.carry0_flags);
5416       AdcsSbcsHelper(&MacroAssembler::Sbcs,
5417                      inputs[left],
5418                      inputs[right],
5419                      1,
5420                      expected.carry1_result,
5421                      expected.carry1_flags);
5422     }
5423   }
5424 }
5425 
5426 
5427 TEST(adcs_sbcs_w) {
5428   uint32_t inputs[] = {
5429       0x00000000,
5430       0x00000001,
5431       0x7ffffffe,
5432       0x7fffffff,
5433       0x80000000,
5434       0x80000001,
5435       0xfffffffe,
5436       0xffffffff,
5437   };
5438   static const size_t input_count = sizeof(inputs) / sizeof(inputs[0]);
5439 
5440   struct Expected {
5441     uint32_t carry0_result;
5442     StatusFlags carry0_flags;
5443     uint32_t carry1_result;
5444     StatusFlags carry1_flags;
5445   };
5446 
5447   static const Expected expected_adcs_w[input_count][input_count] =
5448       {{{0x00000000, ZFlag, 0x00000001, NoFlag},
5449         {0x00000001, NoFlag, 0x00000002, NoFlag},
5450         {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
5451         {0x7fffffff, NoFlag, 0x80000000, NVFlag},
5452         {0x80000000, NFlag, 0x80000001, NFlag},
5453         {0x80000001, NFlag, 0x80000002, NFlag},
5454         {0xfffffffe, NFlag, 0xffffffff, NFlag},
5455         {0xffffffff, NFlag, 0x00000000, ZCFlag}},
5456        {{0x00000001, NoFlag, 0x00000002, NoFlag},
5457         {0x00000002, NoFlag, 0x00000003, NoFlag},
5458         {0x7fffffff, NoFlag, 0x80000000, NVFlag},
5459         {0x80000000, NVFlag, 0x80000001, NVFlag},
5460         {0x80000001, NFlag, 0x80000002, NFlag},
5461         {0x80000002, NFlag, 0x80000003, NFlag},
5462         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5463         {0x00000000, ZCFlag, 0x00000001, CFlag}},
5464        {{0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
5465         {0x7fffffff, NoFlag, 0x80000000, NVFlag},
5466         {0xfffffffc, NVFlag, 0xfffffffd, NVFlag},
5467         {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
5468         {0xfffffffe, NFlag, 0xffffffff, NFlag},
5469         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5470         {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
5471         {0x7ffffffd, CFlag, 0x7ffffffe, CFlag}},
5472        {{0x7fffffff, NoFlag, 0x80000000, NVFlag},
5473         {0x80000000, NVFlag, 0x80000001, NVFlag},
5474         {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
5475         {0xfffffffe, NVFlag, 0xffffffff, NVFlag},
5476         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5477         {0x00000000, ZCFlag, 0x00000001, CFlag},
5478         {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
5479         {0x7ffffffe, CFlag, 0x7fffffff, CFlag}},
5480        {{0x80000000, NFlag, 0x80000001, NFlag},
5481         {0x80000001, NFlag, 0x80000002, NFlag},
5482         {0xfffffffe, NFlag, 0xffffffff, NFlag},
5483         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5484         {0x00000000, ZCVFlag, 0x00000001, CVFlag},
5485         {0x00000001, CVFlag, 0x00000002, CVFlag},
5486         {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
5487         {0x7fffffff, CVFlag, 0x80000000, NCFlag}},
5488        {{0x80000001, NFlag, 0x80000002, NFlag},
5489         {0x80000002, NFlag, 0x80000003, NFlag},
5490         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5491         {0x00000000, ZCFlag, 0x00000001, CFlag},
5492         {0x00000001, CVFlag, 0x00000002, CVFlag},
5493         {0x00000002, CVFlag, 0x00000003, CVFlag},
5494         {0x7fffffff, CVFlag, 0x80000000, NCFlag},
5495         {0x80000000, NCFlag, 0x80000001, NCFlag}},
5496        {{0xfffffffe, NFlag, 0xffffffff, NFlag},
5497         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5498         {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
5499         {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
5500         {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
5501         {0x7fffffff, CVFlag, 0x80000000, NCFlag},
5502         {0xfffffffc, NCFlag, 0xfffffffd, NCFlag},
5503         {0xfffffffd, NCFlag, 0xfffffffe, NCFlag}},
5504        {{0xffffffff, NFlag, 0x00000000, ZCFlag},
5505         {0x00000000, ZCFlag, 0x00000001, CFlag},
5506         {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
5507         {0x7ffffffe, CFlag, 0x7fffffff, CFlag},
5508         {0x7fffffff, CVFlag, 0x80000000, NCFlag},
5509         {0x80000000, NCFlag, 0x80000001, NCFlag},
5510         {0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
5511         {0xfffffffe, NCFlag, 0xffffffff, NCFlag}}};
5512 
5513   static const Expected expected_sbcs_w[input_count][input_count] =
5514       {{{0xffffffff, NFlag, 0x00000000, ZCFlag},
5515         {0xfffffffe, NFlag, 0xffffffff, NFlag},
5516         {0x80000001, NFlag, 0x80000002, NFlag},
5517         {0x80000000, NFlag, 0x80000001, NFlag},
5518         {0x7fffffff, NoFlag, 0x80000000, NVFlag},
5519         {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
5520         {0x00000001, NoFlag, 0x00000002, NoFlag},
5521         {0x00000000, ZFlag, 0x00000001, NoFlag}},
5522        {{0x00000000, ZCFlag, 0x00000001, CFlag},
5523         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5524         {0x80000002, NFlag, 0x80000003, NFlag},
5525         {0x80000001, NFlag, 0x80000002, NFlag},
5526         {0x80000000, NVFlag, 0x80000001, NVFlag},
5527         {0x7fffffff, NoFlag, 0x80000000, NVFlag},
5528         {0x00000002, NoFlag, 0x00000003, NoFlag},
5529         {0x00000001, NoFlag, 0x00000002, NoFlag}},
5530        {{0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
5531         {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
5532         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5533         {0xfffffffe, NFlag, 0xffffffff, NFlag},
5534         {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
5535         {0xfffffffc, NVFlag, 0xfffffffd, NVFlag},
5536         {0x7fffffff, NoFlag, 0x80000000, NVFlag},
5537         {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag}},
5538        {{0x7ffffffe, CFlag, 0x7fffffff, CFlag},
5539         {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
5540         {0x00000000, ZCFlag, 0x00000001, CFlag},
5541         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5542         {0xfffffffe, NVFlag, 0xffffffff, NVFlag},
5543         {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
5544         {0x80000000, NVFlag, 0x80000001, NVFlag},
5545         {0x7fffffff, NoFlag, 0x80000000, NVFlag}},
5546        {{0x7fffffff, CVFlag, 0x80000000, NCFlag},
5547         {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
5548         {0x00000001, CVFlag, 0x00000002, CVFlag},
5549         {0x00000000, ZCVFlag, 0x00000001, CVFlag},
5550         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5551         {0xfffffffe, NFlag, 0xffffffff, NFlag},
5552         {0x80000001, NFlag, 0x80000002, NFlag},
5553         {0x80000000, NFlag, 0x80000001, NFlag}},
5554        {{0x80000000, NCFlag, 0x80000001, NCFlag},
5555         {0x7fffffff, CVFlag, 0x80000000, NCFlag},
5556         {0x00000002, CVFlag, 0x00000003, CVFlag},
5557         {0x00000001, CVFlag, 0x00000002, CVFlag},
5558         {0x00000000, ZCFlag, 0x00000001, CFlag},
5559         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5560         {0x80000002, NFlag, 0x80000003, NFlag},
5561         {0x80000001, NFlag, 0x80000002, NFlag}},
5562        {{0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
5563         {0xfffffffc, NCFlag, 0xfffffffd, NCFlag},
5564         {0x7fffffff, CVFlag, 0x80000000, NCFlag},
5565         {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
5566         {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
5567         {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
5568         {0xffffffff, NFlag, 0x00000000, ZCFlag},
5569         {0xfffffffe, NFlag, 0xffffffff, NFlag}},
5570        {{0xfffffffe, NCFlag, 0xffffffff, NCFlag},
5571         {0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
5572         {0x80000000, NCFlag, 0x80000001, NCFlag},
5573         {0x7fffffff, CVFlag, 0x80000000, NCFlag},
5574         {0x7ffffffe, CFlag, 0x7fffffff, CFlag},
5575         {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
5576         {0x00000000, ZCFlag, 0x00000001, CFlag},
5577         {0xffffffff, NFlag, 0x00000000, ZCFlag}}};
5578 
5579   for (size_t left = 0; left < input_count; left++) {
5580     for (size_t right = 0; right < input_count; right++) {
5581       const Expected& expected = expected_adcs_w[left][right];
5582       AdcsSbcsHelper(&MacroAssembler::Adcs,
5583                      inputs[left],
5584                      inputs[right],
5585                      0,
5586                      expected.carry0_result,
5587                      expected.carry0_flags);
5588       AdcsSbcsHelper(&MacroAssembler::Adcs,
5589                      inputs[left],
5590                      inputs[right],
5591                      1,
5592                      expected.carry1_result,
5593                      expected.carry1_flags);
5594     }
5595   }
5596 
5597   for (size_t left = 0; left < input_count; left++) {
5598     for (size_t right = 0; right < input_count; right++) {
5599       const Expected& expected = expected_sbcs_w[left][right];
5600       AdcsSbcsHelper(&MacroAssembler::Sbcs,
5601                      inputs[left],
5602                      inputs[right],
5603                      0,
5604                      expected.carry0_result,
5605                      expected.carry0_flags);
5606       AdcsSbcsHelper(&MacroAssembler::Sbcs,
5607                      inputs[left],
5608                      inputs[right],
5609                      1,
5610                      expected.carry1_result,
5611                      expected.carry1_flags);
5612     }
5613   }
5614 }
5615 
5616 
5617 TEST(adc_sbc_shift) {
5618   SETUP();
5619 
5620   START();
5621   __ Mov(x0, 0);
5622   __ Mov(x1, 1);
5623   __ Mov(x2, 0x0123456789abcdef);
5624   __ Mov(x3, 0xfedcba9876543210);
5625   __ Mov(x4, 0xffffffffffffffff);
5626 
5627   // Clear the C flag.
5628   __ Adds(x0, x0, Operand(0));
5629 
5630   __ Adc(x5, x2, Operand(x3));
5631   __ Adc(x6, x0, Operand(x1, LSL, 60));
5632   __ Sbc(x7, x4, Operand(x3, LSR, 4));
5633   __ Adc(x8, x2, Operand(x3, ASR, 4));
5634   __ Adc(x9, x2, Operand(x3, ROR, 8));
5635 
5636   __ Adc(w10, w2, Operand(w3));
5637   __ Adc(w11, w0, Operand(w1, LSL, 30));
5638   __ Sbc(w12, w4, Operand(w3, LSR, 4));
5639   __ Adc(w13, w2, Operand(w3, ASR, 4));
5640   __ Adc(w14, w2, Operand(w3, ROR, 8));
5641 
5642   // Set the C flag.
5643   __ Cmp(w0, Operand(w0));
5644 
5645   __ Adc(x18, x2, Operand(x3));
5646   __ Adc(x19, x0, Operand(x1, LSL, 60));
5647   __ Sbc(x20, x4, Operand(x3, LSR, 4));
5648   __ Adc(x21, x2, Operand(x3, ASR, 4));
5649   __ Adc(x22, x2, Operand(x3, ROR, 8));
5650 
5651   __ Adc(w23, w2, Operand(w3));
5652   __ Adc(w24, w0, Operand(w1, LSL, 30));
5653   __ Sbc(w25, w4, Operand(w3, LSR, 4));
5654   __ Adc(w26, w2, Operand(w3, ASR, 4));
5655   __ Adc(w27, w2, Operand(w3, ROR, 8));
5656   END();
5657 
5658   if (CAN_RUN()) {
5659     RUN();
5660 
5661     ASSERT_EQUAL_64(0xffffffffffffffff, x5);
5662     ASSERT_EQUAL_64(INT64_C(1) << 60, x6);
5663     ASSERT_EQUAL_64(0xf0123456789abcdd, x7);
5664     ASSERT_EQUAL_64(0x0111111111111110, x8);
5665     ASSERT_EQUAL_64(0x1222222222222221, x9);
5666 
5667     ASSERT_EQUAL_32(0xffffffff, w10);
5668     ASSERT_EQUAL_32(INT32_C(1) << 30, w11);
5669     ASSERT_EQUAL_32(0xf89abcdd, w12);
5670     ASSERT_EQUAL_32(0x91111110, w13);
5671     ASSERT_EQUAL_32(0x9a222221, w14);
5672 
5673     ASSERT_EQUAL_64(0xffffffffffffffff + 1, x18);
5674     ASSERT_EQUAL_64((INT64_C(1) << 60) + 1, x19);
5675     ASSERT_EQUAL_64(0xf0123456789abcdd + 1, x20);
5676     ASSERT_EQUAL_64(0x0111111111111110 + 1, x21);
5677     ASSERT_EQUAL_64(0x1222222222222221 + 1, x22);
5678 
5679     ASSERT_EQUAL_32(0xffffffff + 1, w23);
5680     ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, w24);
5681     ASSERT_EQUAL_32(0xf89abcdd + 1, w25);
5682     ASSERT_EQUAL_32(0x91111110 + 1, w26);
5683     ASSERT_EQUAL_32(0x9a222221 + 1, w27);
5684   }
5685 }
5686 
5687 
5688 TEST(adc_sbc_extend) {
5689   SETUP();
5690 
5691   START();
5692   // Clear the C flag.
5693   __ Adds(x0, x0, Operand(0));
5694 
5695   __ Mov(x0, 0);
5696   __ Mov(x1, 1);
5697   __ Mov(x2, 0x0123456789abcdef);
5698 
5699   __ Adc(x10, x1, Operand(w2, UXTB, 1));
5700   __ Adc(x11, x1, Operand(x2, SXTH, 2));
5701   __ Sbc(x12, x1, Operand(w2, UXTW, 4));
5702   __ Adc(x13, x1, Operand(x2, UXTX, 4));
5703 
5704   __ Adc(w14, w1, Operand(w2, UXTB, 1));
5705   __ Adc(w15, w1, Operand(w2, SXTH, 2));
5706   __ Adc(w9, w1, Operand(w2, UXTW, 4));
5707 
5708   // Set the C flag.
5709   __ Cmp(w0, Operand(w0));
5710 
5711   __ Adc(x20, x1, Operand(w2, UXTB, 1));
5712   __ Adc(x21, x1, Operand(x2, SXTH, 2));
5713   __ Sbc(x22, x1, Operand(w2, UXTW, 4));
5714   __ Adc(x23, x1, Operand(x2, UXTX, 4));
5715 
5716   __ Adc(w24, w1, Operand(w2, UXTB, 1));
5717   __ Adc(w25, w1, Operand(w2, SXTH, 2));
5718   __ Adc(w26, w1, Operand(w2, UXTW, 4));
5719   END();
5720 
5721   if (CAN_RUN()) {
5722     RUN();
5723 
5724     ASSERT_EQUAL_64(0x1df, x10);
5725     ASSERT_EQUAL_64(0xffffffffffff37bd, x11);
5726     ASSERT_EQUAL_64(0xfffffff765432110, x12);
5727     ASSERT_EQUAL_64(0x123456789abcdef1, x13);
5728 
5729     ASSERT_EQUAL_32(0x1df, w14);
5730     ASSERT_EQUAL_32(0xffff37bd, w15);
5731     ASSERT_EQUAL_32(0x9abcdef1, w9);
5732 
5733     ASSERT_EQUAL_64(0x1df + 1, x20);
5734     ASSERT_EQUAL_64(0xffffffffffff37bd + 1, x21);
5735     ASSERT_EQUAL_64(0xfffffff765432110 + 1, x22);
5736     ASSERT_EQUAL_64(0x123456789abcdef1 + 1, x23);
5737 
5738     ASSERT_EQUAL_32(0x1df + 1, w24);
5739     ASSERT_EQUAL_32(0xffff37bd + 1, w25);
5740     ASSERT_EQUAL_32(0x9abcdef1 + 1, w26);
5741   }
5742 
5743   // Check that adc correctly sets the condition flags.
5744   START();
5745   __ Mov(x0, 0xff);
5746   __ Mov(x1, 0xffffffffffffffff);
5747   // Clear the C flag.
5748   __ Adds(x0, x0, Operand(0));
5749   __ Adcs(x10, x0, Operand(x1, SXTX, 1));
5750   END();
5751 
5752   if (CAN_RUN()) {
5753     RUN();
5754 
5755     ASSERT_EQUAL_NZCV(CFlag);
5756   }
5757 
5758   START();
5759   __ Mov(x0, 0x7fffffffffffffff);
5760   __ Mov(x1, 1);
5761   // Clear the C flag.
5762   __ Adds(x0, x0, Operand(0));
5763   __ Adcs(x10, x0, Operand(x1, UXTB, 2));
5764   END();
5765 
5766   if (CAN_RUN()) {
5767     RUN();
5768 
5769     ASSERT_EQUAL_NZCV(NVFlag);
5770   }
5771 
5772   START();
5773   __ Mov(x0, 0x7fffffffffffffff);
5774   // Clear the C flag.
5775   __ Adds(x0, x0, Operand(0));
5776   __ Adcs(x10, x0, Operand(1));
5777   END();
5778 
5779   if (CAN_RUN()) {
5780     RUN();
5781 
5782     ASSERT_EQUAL_NZCV(NVFlag);
5783   }
5784 }
5785 
5786 
5787 TEST(adc_sbc_wide_imm) {
5788   SETUP();
5789 
5790   START();
5791   __ Mov(x0, 0);
5792 
5793   // Clear the C flag.
5794   __ Adds(x0, x0, Operand(0));
5795 
5796   __ Adc(x7, x0, Operand(0x1234567890abcdef));
5797   __ Adc(w8, w0, Operand(0xffffffff));
5798   __ Sbc(x9, x0, Operand(0x1234567890abcdef));
5799   __ Sbc(w10, w0, Operand(0xffffffff));
5800   __ Ngc(x11, Operand(0xffffffff00000000));
5801   __ Ngc(w12, Operand(0xffff0000));
5802 
5803   // Set the C flag.
5804   __ Cmp(w0, Operand(w0));
5805 
5806   __ Adc(x18, x0, Operand(0x1234567890abcdef));
5807   __ Adc(w19, w0, Operand(0xffffffff));
5808   __ Sbc(x20, x0, Operand(0x1234567890abcdef));
5809   __ Sbc(w21, w0, Operand(0xffffffff));
5810   __ Ngc(x22, Operand(0xffffffff00000000));
5811   __ Ngc(w23, Operand(0xffff0000));
5812   END();
5813 
5814   if (CAN_RUN()) {
5815     RUN();
5816 
5817     ASSERT_EQUAL_64(0x1234567890abcdef, x7);
5818     ASSERT_EQUAL_64(0xffffffff, x8);
5819     ASSERT_EQUAL_64(0xedcba9876f543210, x9);
5820     ASSERT_EQUAL_64(0, x10);
5821     ASSERT_EQUAL_64(0xffffffff, x11);
5822     ASSERT_EQUAL_64(0xffff, x12);
5823 
5824     ASSERT_EQUAL_64(0x1234567890abcdef + 1, x18);
5825     ASSERT_EQUAL_64(0, x19);
5826     ASSERT_EQUAL_64(0xedcba9876f543211, x20);
5827     ASSERT_EQUAL_64(1, x21);
5828     ASSERT_EQUAL_64(0x0000000100000000, x22);
5829     ASSERT_EQUAL_64(0x0000000000010000, x23);
5830   }
5831 }
5832 
5833 
5834 TEST(rmif) {
5835   SETUP_WITH_FEATURES(CPUFeatures::kFlagM);
5836 
5837   START();
5838   __ Mov(x0, 0x0123456789abcdef);
5839 
5840   // Set NZCV to 0b1011 (0xb)
5841   __ Rmif(x0, 0, NCVFlag);
5842   __ Mrs(x1, NZCV);
5843 
5844   // Set NZCV to 0b0111 (0x7)
5845   __ Rmif(x0, 6, NZCVFlag);
5846   __ Mrs(x2, NZCV);
5847 
5848   // Set Z to 0, NZCV = 0b0011 (0x3)
5849   __ Rmif(x0, 60, ZFlag);
5850   __ Mrs(x3, NZCV);
5851 
5852   // Set N to 1 and C to 0, NZCV = 0b1001 (0x9)
5853   __ Rmif(x0, 62, NCFlag);
5854   __ Mrs(x4, NZCV);
5855 
5856   // No change to NZCV
5857   __ Rmif(x0, 0, NoFlag);
5858   __ Mrs(x5, NZCV);
5859   END();
5860 
5861   if (CAN_RUN()) {
5862     RUN();
5863     ASSERT_EQUAL_32(NCVFlag, w1);
5864     ASSERT_EQUAL_32(ZCVFlag, w2);
5865     ASSERT_EQUAL_32(CVFlag, w3);
5866     ASSERT_EQUAL_32(NVFlag, w4);
5867     ASSERT_EQUAL_32(NVFlag, w5);
5868   }
5869 }
5870 
5871 
5872 TEST(setf8_setf16) {
5873   SETUP_WITH_FEATURES(CPUFeatures::kFlagM);
5874 
5875   START();
5876   __ Mov(x0, 0x0);
5877   __ Mov(x1, 0x1);
5878   __ Mov(x2, 0xff);
5879   __ Mov(x3, 0x100);
5880   __ Mov(x4, 0x101);
5881   __ Mov(x5, 0xffff);
5882   __ Mov(x6, 0x10000);
5883   __ Mov(x7, 0x10001);
5884   __ Mov(x8, 0xfffffffff);
5885 
5886   __ Setf8(w0);
5887   __ Mrs(x9, NZCV);
5888   __ Setf8(w1);
5889   __ Mrs(x10, NZCV);
5890   __ Setf8(w2);
5891   __ Mrs(x11, NZCV);
5892   __ Setf8(w3);
5893   __ Mrs(x12, NZCV);
5894   __ Setf8(w4);
5895   __ Mrs(x13, NZCV);
5896   __ Setf8(w8);
5897   __ Mrs(x14, NZCV);
5898 
5899   __ Setf16(w0);
5900   __ Mrs(x15, NZCV);
5901   __ Setf16(w1);
5902   __ Mrs(x16, NZCV);
5903   __ Setf16(w5);
5904   __ Mrs(x17, NZCV);
5905   __ Setf16(w6);
5906   __ Mrs(x18, NZCV);
5907   __ Setf16(w7);
5908   __ Mrs(x19, NZCV);
5909   __ Setf16(w8);
5910   __ Mrs(x20, NZCV);
5911   END();
5912 
5913   if (CAN_RUN()) {
5914     RUN();
5915 
5916     ASSERT_EQUAL_32(ZFlag, w9);    // Zero
5917     ASSERT_EQUAL_32(NoFlag, w10);  // Regular int8
5918     ASSERT_EQUAL_32(NVFlag, w11);  // Negative but not sign-extended (overflow)
5919     ASSERT_EQUAL_32(ZVFlag, w12);  // Overflow with zero remainder
5920     ASSERT_EQUAL_32(VFlag, w13);   // Overflow with non-zero remainder
5921     ASSERT_EQUAL_32(NFlag, w14);   // Negative and sign-extended
5922 
5923     ASSERT_EQUAL_32(ZFlag, w15);   // Zero
5924     ASSERT_EQUAL_32(NoFlag, w16);  // Regular int16
5925     ASSERT_EQUAL_32(NVFlag, w17);  // Negative but not sign-extended (overflow)
5926     ASSERT_EQUAL_32(ZVFlag, w18);  // Overflow with zero remainder
5927     ASSERT_EQUAL_32(VFlag, w19);   // Overflow with non-zero remainder
5928     ASSERT_EQUAL_32(NFlag, w20);   // Negative and sign-extended
5929   }
5930 }
5931 
5932 
5933 TEST(flags) {
5934   SETUP();
5935 
5936   START();
5937   __ Mov(x0, 0);
5938   __ Mov(x1, 0x1111111111111111);
5939   __ Neg(x10, Operand(x0));
5940   __ Neg(x11, Operand(x1));
5941   __ Neg(w12, Operand(w1));
5942   // Clear the C flag.
5943   __ Adds(x0, x0, Operand(0));
5944   __ Ngc(x13, Operand(x0));
5945   // Set the C flag.
5946   __ Cmp(x0, Operand(x0));
5947   __ Ngc(w14, Operand(w0));
5948   END();
5949 
5950   if (CAN_RUN()) {
5951     RUN();
5952 
5953     ASSERT_EQUAL_64(0, x10);
5954     ASSERT_EQUAL_64(-0x1111111111111111, x11);
5955     ASSERT_EQUAL_32(-0x11111111, w12);
5956     ASSERT_EQUAL_64(-1, x13);
5957     ASSERT_EQUAL_32(0, w14);
5958   }
5959 
5960   START();
5961   __ Mov(x0, 0);
5962   __ Cmp(x0, Operand(x0));
5963   END();
5964 
5965   if (CAN_RUN()) {
5966     RUN();
5967 
5968     ASSERT_EQUAL_NZCV(ZCFlag);
5969   }
5970 
5971   START();
5972   __ Mov(w0, 0);
5973   __ Cmp(w0, Operand(w0));
5974   END();
5975 
5976   if (CAN_RUN()) {
5977     RUN();
5978 
5979     ASSERT_EQUAL_NZCV(ZCFlag);
5980   }
5981 
5982   START();
5983   __ Mov(x0, 0);
5984   __ Mov(x1, 0x1111111111111111);
5985   __ Cmp(x0, Operand(x1));
5986   END();
5987 
5988   if (CAN_RUN()) {
5989     RUN();
5990 
5991     ASSERT_EQUAL_NZCV(NFlag);
5992   }
5993 
5994   START();
5995   __ Mov(w0, 0);
5996   __ Mov(w1, 0x11111111);
5997   __ Cmp(w0, Operand(w1));
5998   END();
5999 
6000   if (CAN_RUN()) {
6001     RUN();
6002 
6003     ASSERT_EQUAL_NZCV(NFlag);
6004   }
6005 
6006   START();
6007   __ Mov(x1, 0x1111111111111111);
6008   __ Cmp(x1, Operand(0));
6009   END();
6010 
6011   if (CAN_RUN()) {
6012     RUN();
6013 
6014     ASSERT_EQUAL_NZCV(CFlag);
6015   }
6016 
6017   START();
6018   __ Mov(w1, 0x11111111);
6019   __ Cmp(w1, Operand(0));
6020   END();
6021 
6022   if (CAN_RUN()) {
6023     RUN();
6024 
6025     ASSERT_EQUAL_NZCV(CFlag);
6026   }
6027 
6028   START();
6029   __ Mov(x0, 1);
6030   __ Mov(x1, 0x7fffffffffffffff);
6031   __ Cmn(x1, Operand(x0));
6032   END();
6033 
6034   if (CAN_RUN()) {
6035     RUN();
6036 
6037     ASSERT_EQUAL_NZCV(NVFlag);
6038   }
6039 
6040   START();
6041   __ Mov(w0, 1);
6042   __ Mov(w1, 0x7fffffff);
6043   __ Cmn(w1, Operand(w0));
6044   END();
6045 
6046   if (CAN_RUN()) {
6047     RUN();
6048 
6049     ASSERT_EQUAL_NZCV(NVFlag);
6050   }
6051 
6052   START();
6053   __ Mov(x0, 1);
6054   __ Mov(x1, 0xffffffffffffffff);
6055   __ Cmn(x1, Operand(x0));
6056   END();
6057 
6058   if (CAN_RUN()) {
6059     RUN();
6060 
6061     ASSERT_EQUAL_NZCV(ZCFlag);
6062   }
6063 
6064   START();
6065   __ Mov(w0, 1);
6066   __ Mov(w1, 0xffffffff);
6067   __ Cmn(w1, Operand(w0));
6068   END();
6069 
6070   if (CAN_RUN()) {
6071     RUN();
6072 
6073     ASSERT_EQUAL_NZCV(ZCFlag);
6074   }
6075 
6076   START();
6077   __ Mov(w0, 0);
6078   __ Mov(w1, 1);
6079   // Clear the C flag.
6080   __ Adds(w0, w0, Operand(0));
6081   __ Ngcs(w0, Operand(w1));
6082   END();
6083 
6084   if (CAN_RUN()) {
6085     RUN();
6086 
6087     ASSERT_EQUAL_NZCV(NFlag);
6088   }
6089 
6090   START();
6091   __ Mov(w0, 0);
6092   __ Mov(w1, 0);
6093   // Set the C flag.
6094   __ Cmp(w0, Operand(w0));
6095   __ Ngcs(w0, Operand(w1));
6096   END();
6097 
6098   if (CAN_RUN()) {
6099     RUN();
6100 
6101     ASSERT_EQUAL_NZCV(ZCFlag);
6102   }
6103 }
6104 
6105 
6106 TEST(cmp_shift) {
6107   SETUP();
6108 
6109   START();
6110   __ Mov(x18, 0xf0000000);
6111   __ Mov(x19, 0xf000000010000000);
6112   __ Mov(x20, 0xf0000000f0000000);
6113   __ Mov(x21, 0x7800000078000000);
6114   __ Mov(x22, 0x3c0000003c000000);
6115   __ Mov(x23, 0x8000000780000000);
6116   __ Mov(x24, 0x0000000f00000000);
6117   __ Mov(x25, 0x00000003c0000000);
6118   __ Mov(x26, 0x8000000780000000);
6119   __ Mov(x27, 0xc0000003);
6120 
6121   __ Cmp(w20, Operand(w21, LSL, 1));
6122   __ Mrs(x0, NZCV);
6123 
6124   __ Cmp(x20, Operand(x22, LSL, 2));
6125   __ Mrs(x1, NZCV);
6126 
6127   __ Cmp(w19, Operand(w23, LSR, 3));
6128   __ Mrs(x2, NZCV);
6129 
6130   __ Cmp(x18, Operand(x24, LSR, 4));
6131   __ Mrs(x3, NZCV);
6132 
6133   __ Cmp(w20, Operand(w25, ASR, 2));
6134   __ Mrs(x4, NZCV);
6135 
6136   __ Cmp(x20, Operand(x26, ASR, 3));
6137   __ Mrs(x5, NZCV);
6138 
6139   __ Cmp(w27, Operand(w22, ROR, 28));
6140   __ Mrs(x6, NZCV);
6141 
6142   __ Cmp(x20, Operand(x21, ROR, 31));
6143   __ Mrs(x7, NZCV);
6144   END();
6145 
6146   if (CAN_RUN()) {
6147     RUN();
6148 
6149     ASSERT_EQUAL_32(ZCFlag, w0);
6150     ASSERT_EQUAL_32(ZCFlag, w1);
6151     ASSERT_EQUAL_32(ZCFlag, w2);
6152     ASSERT_EQUAL_32(ZCFlag, w3);
6153     ASSERT_EQUAL_32(ZCFlag, w4);
6154     ASSERT_EQUAL_32(ZCFlag, w5);
6155     ASSERT_EQUAL_32(ZCFlag, w6);
6156     ASSERT_EQUAL_32(ZCFlag, w7);
6157   }
6158 }
6159 
6160 
6161 TEST(cmp_extend) {
6162   SETUP();
6163 
6164   START();
6165   __ Mov(w20, 0x2);
6166   __ Mov(w21, 0x1);
6167   __ Mov(x22, 0xffffffffffffffff);
6168   __ Mov(x23, 0xff);
6169   __ Mov(x24, 0xfffffffffffffffe);
6170   __ Mov(x25, 0xffff);
6171   __ Mov(x26, 0xffffffff);
6172 
6173   __ Cmp(w20, Operand(w21, LSL, 1));
6174   __ Mrs(x0, NZCV);
6175 
6176   __ Cmp(x22, Operand(x23, SXTB, 0));
6177   __ Mrs(x1, NZCV);
6178 
6179   __ Cmp(x24, Operand(x23, SXTB, 1));
6180   __ Mrs(x2, NZCV);
6181 
6182   __ Cmp(x24, Operand(x23, UXTB, 1));
6183   __ Mrs(x3, NZCV);
6184 
6185   __ Cmp(w22, Operand(w25, UXTH));
6186   __ Mrs(x4, NZCV);
6187 
6188   __ Cmp(x22, Operand(x25, SXTH));
6189   __ Mrs(x5, NZCV);
6190 
6191   __ Cmp(x22, Operand(x26, UXTW));
6192   __ Mrs(x6, NZCV);
6193 
6194   __ Cmp(x24, Operand(x26, SXTW, 1));
6195   __ Mrs(x7, NZCV);
6196   END();
6197 
6198   if (CAN_RUN()) {
6199     RUN();
6200 
6201     ASSERT_EQUAL_32(ZCFlag, w0);
6202     ASSERT_EQUAL_32(ZCFlag, w1);
6203     ASSERT_EQUAL_32(ZCFlag, w2);
6204     ASSERT_EQUAL_32(NCFlag, w3);
6205     ASSERT_EQUAL_32(NCFlag, w4);
6206     ASSERT_EQUAL_32(ZCFlag, w5);
6207     ASSERT_EQUAL_32(NCFlag, w6);
6208     ASSERT_EQUAL_32(ZCFlag, w7);
6209   }
6210 }
6211 
6212 
6213 TEST(ccmp) {
6214   SETUP();
6215 
6216   START();
6217   __ Mov(w16, 0);
6218   __ Mov(w17, 1);
6219   __ Cmp(w16, w16);
6220   __ Ccmp(w16, w17, NCFlag, eq);
6221   __ Mrs(x0, NZCV);
6222 
6223   __ Cmp(w16, w16);
6224   __ Ccmp(w16, w17, NCFlag, ne);
6225   __ Mrs(x1, NZCV);
6226 
6227   __ Cmp(x16, x16);
6228   __ Ccmn(x16, 2, NZCVFlag, eq);
6229   __ Mrs(x2, NZCV);
6230 
6231   __ Cmp(x16, x16);
6232   __ Ccmn(x16, 2, NZCVFlag, ne);
6233   __ Mrs(x3, NZCV);
6234 
6235   // The MacroAssembler does not allow al as a condition.
6236   {
6237     ExactAssemblyScope scope(&masm, kInstructionSize);
6238     __ ccmp(x16, x16, NZCVFlag, al);
6239   }
6240   __ Mrs(x4, NZCV);
6241 
6242   // The MacroAssembler does not allow nv as a condition.
6243   {
6244     ExactAssemblyScope scope(&masm, kInstructionSize);
6245     __ ccmp(x16, x16, NZCVFlag, nv);
6246   }
6247   __ Mrs(x5, NZCV);
6248 
6249   END();
6250 
6251   if (CAN_RUN()) {
6252     RUN();
6253 
6254     ASSERT_EQUAL_32(NFlag, w0);
6255     ASSERT_EQUAL_32(NCFlag, w1);
6256     ASSERT_EQUAL_32(NoFlag, w2);
6257     ASSERT_EQUAL_32(NZCVFlag, w3);
6258     ASSERT_EQUAL_32(ZCFlag, w4);
6259     ASSERT_EQUAL_32(ZCFlag, w5);
6260   }
6261 }
6262 
6263 
6264 TEST(ccmp_wide_imm) {
6265   SETUP();
6266 
6267   START();
6268   __ Mov(w20, 0);
6269 
6270   __ Cmp(w20, Operand(w20));
6271   __ Ccmp(w20, Operand(0x12345678), NZCVFlag, eq);
6272   __ Mrs(x0, NZCV);
6273 
6274   __ Cmp(w20, Operand(w20));
6275   __ Ccmp(x20, Operand(0xffffffffffffffff), NZCVFlag, eq);
6276   __ Mrs(x1, NZCV);
6277   END();
6278 
6279   if (CAN_RUN()) {
6280     RUN();
6281 
6282     ASSERT_EQUAL_32(NFlag, w0);
6283     ASSERT_EQUAL_32(NoFlag, w1);
6284   }
6285 }
6286 
6287 
6288 TEST(ccmp_shift_extend) {
6289   SETUP();
6290 
6291   START();
6292   __ Mov(w20, 0x2);
6293   __ Mov(w21, 0x1);
6294   __ Mov(x22, 0xffffffffffffffff);
6295   __ Mov(x23, 0xff);
6296   __ Mov(x24, 0xfffffffffffffffe);
6297 
6298   __ Cmp(w20, Operand(w20));
6299   __ Ccmp(w20, Operand(w21, LSL, 1), NZCVFlag, eq);
6300   __ Mrs(x0, NZCV);
6301 
6302   __ Cmp(w20, Operand(w20));
6303   __ Ccmp(x22, Operand(x23, SXTB, 0), NZCVFlag, eq);
6304   __ Mrs(x1, NZCV);
6305 
6306   __ Cmp(w20, Operand(w20));
6307   __ Ccmp(x24, Operand(x23, SXTB, 1), NZCVFlag, eq);
6308   __ Mrs(x2, NZCV);
6309 
6310   __ Cmp(w20, Operand(w20));
6311   __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, eq);
6312   __ Mrs(x3, NZCV);
6313 
6314   __ Cmp(w20, Operand(w20));
6315   __ Ccmp(x24, Operand(x23, UXTB, 1), NZCVFlag, ne);
6316   __ Mrs(x4, NZCV);
6317   END();
6318 
6319   if (CAN_RUN()) {
6320     RUN();
6321 
6322     ASSERT_EQUAL_32(ZCFlag, w0);
6323     ASSERT_EQUAL_32(ZCFlag, w1);
6324     ASSERT_EQUAL_32(ZCFlag, w2);
6325     ASSERT_EQUAL_32(NCFlag, w3);
6326     ASSERT_EQUAL_32(NZCVFlag, w4);
6327   }
6328 }
6329 
6330 
6331 TEST(csel_reg) {
6332   SETUP();
6333 
6334   START();
6335   __ Mov(x16, 0);
6336   __ Mov(x24, 0x0000000f0000000f);
6337   __ Mov(x25, 0x0000001f0000001f);
6338 
6339   __ Cmp(w16, Operand(0));
6340   __ Csel(w0, w24, w25, eq);
6341   __ Csel(w1, w24, w25, ne);
6342   __ Csinc(w2, w24, w25, mi);
6343   __ Csinc(w3, w24, w25, pl);
6344 
6345   // The MacroAssembler does not allow al or nv as a condition.
6346   {
6347     ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
6348     __ csel(w13, w24, w25, al);
6349     __ csel(x14, x24, x25, nv);
6350   }
6351 
6352   __ Cmp(x16, Operand(1));
6353   __ Csinv(x4, x24, x25, gt);
6354   __ Csinv(x5, x24, x25, le);
6355   __ Csneg(x6, x24, x25, hs);
6356   __ Csneg(x7, x24, x25, lo);
6357 
6358   __ Cset(w8, ne);
6359   __ Csetm(w9, ne);
6360   __ Cinc(x10, x25, ne);
6361   __ Cinv(x11, x24, ne);
6362   __ Cneg(x12, x24, ne);
6363 
6364   // The MacroAssembler does not allow al or nv as a condition.
6365   {
6366     ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
6367     __ csel(w15, w24, w25, al);
6368     __ csel(x17, x24, x25, nv);
6369   }
6370 
6371   END();
6372 
6373   if (CAN_RUN()) {
6374     RUN();
6375 
6376     ASSERT_EQUAL_64(0x0000000f, x0);
6377     ASSERT_EQUAL_64(0x0000001f, x1);
6378     ASSERT_EQUAL_64(0x00000020, x2);
6379     ASSERT_EQUAL_64(0x0000000f, x3);
6380     ASSERT_EQUAL_64(0xffffffe0ffffffe0, x4);
6381     ASSERT_EQUAL_64(0x0000000f0000000f, x5);
6382     ASSERT_EQUAL_64(0xffffffe0ffffffe1, x6);
6383     ASSERT_EQUAL_64(0x0000000f0000000f, x7);
6384     ASSERT_EQUAL_64(0x00000001, x8);
6385     ASSERT_EQUAL_64(0xffffffff, x9);
6386     ASSERT_EQUAL_64(0x0000001f00000020, x10);
6387     ASSERT_EQUAL_64(0xfffffff0fffffff0, x11);
6388     ASSERT_EQUAL_64(0xfffffff0fffffff1, x12);
6389     ASSERT_EQUAL_64(0x0000000f, x13);
6390     ASSERT_EQUAL_64(0x0000000f0000000f, x14);
6391     ASSERT_EQUAL_64(0x0000000f, x15);
6392     ASSERT_EQUAL_64(0x0000000f0000000f, x17);
6393   }
6394 }
6395 
6396 TEST(csel_zero) {
6397   SETUP();
6398 
6399   START();
6400 
6401   __ Mov(x15, 0x0);
6402   __ Mov(x16, 0x0000001f0000002f);
6403 
6404   // Check results when zero registers are used as inputs
6405   // for Csinc, Csinv and Csneg for both true and false conditions.
6406   __ Cmp(x15, 0);
6407   __ Csinc(x0, x16, xzr, eq);
6408   __ Csinc(x1, xzr, x16, eq);
6409   __ Cmp(x15, 1);
6410   __ Csinc(w2, w16, wzr, eq);
6411   __ Csinc(w3, wzr, w16, eq);
6412 
6413   __ Csinc(x4, xzr, xzr, eq);
6414 
6415   __ Cmp(x15, 0);
6416   __ Csinv(x5, x16, xzr, eq);
6417   __ Csinv(x6, xzr, x16, eq);
6418   __ Cmp(x15, 1);
6419   __ Csinv(w7, w16, wzr, eq);
6420   __ Csinv(w8, wzr, w16, eq);
6421 
6422   __ Csinv(x9, xzr, xzr, eq);
6423 
6424   __ Cmp(x15, 0);
6425   __ Csneg(x10, x16, xzr, eq);
6426   __ Csneg(x11, xzr, x16, eq);
6427   __ Cmp(x15, 1);
6428   __ Csneg(w12, w16, wzr, eq);
6429   __ Csneg(w13, wzr, w16, eq);
6430 
6431   __ Csneg(x14, xzr, xzr, eq);
6432 
6433   END();
6434 
6435   if (CAN_RUN()) {
6436     RUN();
6437 
6438     ASSERT_EQUAL_64(0x0000001f0000002f, x0);
6439     ASSERT_EQUAL_64(0x0, x1);
6440     ASSERT_EQUAL_32(0x1, w2);
6441     ASSERT_EQUAL_32(0x30, w3);
6442     ASSERT_EQUAL_64(0x1, x4);
6443     ASSERT_EQUAL_64(0x0000001f0000002f, x5);
6444     ASSERT_EQUAL_64(0x0, x6);
6445     ASSERT_EQUAL_32(0xffffffff, w7);
6446     ASSERT_EQUAL_32(0xffffffd0, w8);
6447     ASSERT_EQUAL_64(0xffffffffffffffff, x9);
6448     ASSERT_EQUAL_64(0x0000001f0000002f, x10);
6449     ASSERT_EQUAL_64(0x0, x11);
6450     ASSERT_EQUAL_32(0x0, w12);
6451     ASSERT_EQUAL_32(0xffffffd1, w13);
6452     ASSERT_EQUAL_64(0x0, x14);
6453   }
6454 }
6455 
6456 
6457 TEST(csel_imm) {
6458   SETUP();
6459 
6460   int values[] = {-123, -2, -1, 0, 1, 2, 123};
6461   int n_values = sizeof(values) / sizeof(values[0]);
6462 
6463   for (int i = 0; i < n_values; i++) {
6464     for (int j = 0; j < n_values; j++) {
6465       int left = values[i];
6466       int right = values[j];
6467 
6468       START();
6469       __ Mov(x10, 0);
6470       __ Cmp(x10, 0);
6471       __ Csel(w0, left, right, eq);
6472       __ Csel(w1, left, right, ne);
6473       __ Csel(x2, left, right, eq);
6474       __ Csel(x3, left, right, ne);
6475 
6476       END();
6477 
6478       if (CAN_RUN()) {
6479         RUN();
6480 
6481         ASSERT_EQUAL_32(left, w0);
6482         ASSERT_EQUAL_32(right, w1);
6483         ASSERT_EQUAL_64(left, x2);
6484         ASSERT_EQUAL_64(right, x3);
6485       }
6486     }
6487   }
6488 }
6489 
6490 
6491 TEST(csel_mixed) {
6492   SETUP();
6493 
6494   START();
6495   __ Mov(x18, 0);
6496   __ Mov(x19, 0x80000000);
6497   __ Mov(x20, 0x8000000000000000);
6498 
6499   __ Cmp(x18, Operand(0));
6500   __ Csel(w0, w19, -2, ne);
6501   __ Csel(w1, w19, -1, ne);
6502   __ Csel(w2, w19, 0, ne);
6503   __ Csel(w3, w19, 1, ne);
6504   __ Csel(w4, w19, 2, ne);
6505   __ Csel(w5, w19, Operand(w19, ASR, 31), ne);
6506   __ Csel(w6, w19, Operand(w19, ROR, 1), ne);
6507   __ Csel(w7, w19, 3, eq);
6508 
6509   __ Csel(x8, x20, -2, ne);
6510   __ Csel(x9, x20, -1, ne);
6511   __ Csel(x10, x20, 0, ne);
6512   __ Csel(x11, x20, 1, ne);
6513   __ Csel(x12, x20, 2, ne);
6514   __ Csel(x13, x20, Operand(x20, ASR, 63), ne);
6515   __ Csel(x14, x20, Operand(x20, ROR, 1), ne);
6516   __ Csel(x15, x20, 3, eq);
6517 
6518   END();
6519 
6520   if (CAN_RUN()) {
6521     RUN();
6522 
6523     ASSERT_EQUAL_32(-2, w0);
6524     ASSERT_EQUAL_32(-1, w1);
6525     ASSERT_EQUAL_32(0, w2);
6526     ASSERT_EQUAL_32(1, w3);
6527     ASSERT_EQUAL_32(2, w4);
6528     ASSERT_EQUAL_32(-1, w5);
6529     ASSERT_EQUAL_32(0x40000000, w6);
6530     ASSERT_EQUAL_32(0x80000000, w7);
6531 
6532     ASSERT_EQUAL_64(-2, x8);
6533     ASSERT_EQUAL_64(-1, x9);
6534     ASSERT_EQUAL_64(0, x10);
6535     ASSERT_EQUAL_64(1, x11);
6536     ASSERT_EQUAL_64(2, x12);
6537     ASSERT_EQUAL_64(-1, x13);
6538     ASSERT_EQUAL_64(0x4000000000000000, x14);
6539     ASSERT_EQUAL_64(0x8000000000000000, x15);
6540   }
6541 }
6542 
6543 
6544 TEST(lslv) {
6545   SETUP();
6546 
6547   uint64_t value = 0x0123456789abcdef;
6548   int shift[] = {1, 3, 5, 9, 17, 33};
6549 
6550   START();
6551   __ Mov(x0, value);
6552   __ Mov(w1, shift[0]);
6553   __ Mov(w2, shift[1]);
6554   __ Mov(w3, shift[2]);
6555   __ Mov(w4, shift[3]);
6556   __ Mov(w5, shift[4]);
6557   __ Mov(w6, shift[5]);
6558 
6559   // The MacroAssembler does not allow zr as an argument.
6560   {
6561     ExactAssemblyScope scope(&masm, kInstructionSize);
6562     __ lslv(x0, x0, xzr);
6563   }
6564 
6565   __ Lsl(x16, x0, x1);
6566   __ Lsl(x17, x0, x2);
6567   __ Lsl(x18, x0, x3);
6568   __ Lsl(x19, x0, x4);
6569   __ Lsl(x20, x0, x5);
6570   __ Lsl(x21, x0, x6);
6571 
6572   __ Lsl(w22, w0, w1);
6573   __ Lsl(w23, w0, w2);
6574   __ Lsl(w24, w0, w3);
6575   __ Lsl(w25, w0, w4);
6576   __ Lsl(w26, w0, w5);
6577   __ Lsl(w27, w0, w6);
6578   END();
6579 
6580   if (CAN_RUN()) {
6581     RUN();
6582 
6583     ASSERT_EQUAL_64(value, x0);
6584     ASSERT_EQUAL_64(value << (shift[0] & 63), x16);
6585     ASSERT_EQUAL_64(value << (shift[1] & 63), x17);
6586     ASSERT_EQUAL_64(value << (shift[2] & 63), x18);
6587     ASSERT_EQUAL_64(value << (shift[3] & 63), x19);
6588     ASSERT_EQUAL_64(value << (shift[4] & 63), x20);
6589     ASSERT_EQUAL_64(value << (shift[5] & 63), x21);
6590     ASSERT_EQUAL_32(value << (shift[0] & 31), w22);
6591     ASSERT_EQUAL_32(value << (shift[1] & 31), w23);
6592     ASSERT_EQUAL_32(value << (shift[2] & 31), w24);
6593     ASSERT_EQUAL_32(value << (shift[3] & 31), w25);
6594     ASSERT_EQUAL_32(value << (shift[4] & 31), w26);
6595     ASSERT_EQUAL_32(value << (shift[5] & 31), w27);
6596   }
6597 }
6598 
6599 
6600 TEST(lsrv) {
6601   SETUP();
6602 
6603   uint64_t value = 0x0123456789abcdef;
6604   int shift[] = {1, 3, 5, 9, 17, 33};
6605 
6606   START();
6607   __ Mov(x0, value);
6608   __ Mov(w1, shift[0]);
6609   __ Mov(w2, shift[1]);
6610   __ Mov(w3, shift[2]);
6611   __ Mov(w4, shift[3]);
6612   __ Mov(w5, shift[4]);
6613   __ Mov(w6, shift[5]);
6614 
6615   // The MacroAssembler does not allow zr as an argument.
6616   {
6617     ExactAssemblyScope scope(&masm, kInstructionSize);
6618     __ lsrv(x0, x0, xzr);
6619   }
6620 
6621   __ Lsr(x16, x0, x1);
6622   __ Lsr(x17, x0, x2);
6623   __ Lsr(x18, x0, x3);
6624   __ Lsr(x19, x0, x4);
6625   __ Lsr(x20, x0, x5);
6626   __ Lsr(x21, x0, x6);
6627 
6628   __ Lsr(w22, w0, w1);
6629   __ Lsr(w23, w0, w2);
6630   __ Lsr(w24, w0, w3);
6631   __ Lsr(w25, w0, w4);
6632   __ Lsr(w26, w0, w5);
6633   __ Lsr(w27, w0, w6);
6634   END();
6635 
6636   if (CAN_RUN()) {
6637     RUN();
6638 
6639     ASSERT_EQUAL_64(value, x0);
6640     ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
6641     ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
6642     ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
6643     ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
6644     ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
6645     ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
6646 
6647     value &= 0xffffffff;
6648     ASSERT_EQUAL_32(value >> (shift[0] & 31), w22);
6649     ASSERT_EQUAL_32(value >> (shift[1] & 31), w23);
6650     ASSERT_EQUAL_32(value >> (shift[2] & 31), w24);
6651     ASSERT_EQUAL_32(value >> (shift[3] & 31), w25);
6652     ASSERT_EQUAL_32(value >> (shift[4] & 31), w26);
6653     ASSERT_EQUAL_32(value >> (shift[5] & 31), w27);
6654   }
6655 }
6656 
6657 
6658 TEST(asrv) {
6659   SETUP();
6660 
6661   int64_t value = 0xfedcba98fedcba98;
6662   int shift[] = {1, 3, 5, 9, 17, 33};
6663 
6664   START();
6665   __ Mov(x0, value);
6666   __ Mov(w1, shift[0]);
6667   __ Mov(w2, shift[1]);
6668   __ Mov(w3, shift[2]);
6669   __ Mov(w4, shift[3]);
6670   __ Mov(w5, shift[4]);
6671   __ Mov(w6, shift[5]);
6672 
6673   // The MacroAssembler does not allow zr as an argument.
6674   {
6675     ExactAssemblyScope scope(&masm, kInstructionSize);
6676     __ asrv(x0, x0, xzr);
6677   }
6678 
6679   __ Asr(x16, x0, x1);
6680   __ Asr(x17, x0, x2);
6681   __ Asr(x18, x0, x3);
6682   __ Asr(x19, x0, x4);
6683   __ Asr(x20, x0, x5);
6684   __ Asr(x21, x0, x6);
6685 
6686   __ Asr(w22, w0, w1);
6687   __ Asr(w23, w0, w2);
6688   __ Asr(w24, w0, w3);
6689   __ Asr(w25, w0, w4);
6690   __ Asr(w26, w0, w5);
6691   __ Asr(w27, w0, w6);
6692   END();
6693 
6694   if (CAN_RUN()) {
6695     RUN();
6696 
6697     ASSERT_EQUAL_64(value, x0);
6698     ASSERT_EQUAL_64(value >> (shift[0] & 63), x16);
6699     ASSERT_EQUAL_64(value >> (shift[1] & 63), x17);
6700     ASSERT_EQUAL_64(value >> (shift[2] & 63), x18);
6701     ASSERT_EQUAL_64(value >> (shift[3] & 63), x19);
6702     ASSERT_EQUAL_64(value >> (shift[4] & 63), x20);
6703     ASSERT_EQUAL_64(value >> (shift[5] & 63), x21);
6704 
6705     int32_t value32 = static_cast<int32_t>(value & 0xffffffff);
6706     ASSERT_EQUAL_32(value32 >> (shift[0] & 31), w22);
6707     ASSERT_EQUAL_32(value32 >> (shift[1] & 31), w23);
6708     ASSERT_EQUAL_32(value32 >> (shift[2] & 31), w24);
6709     ASSERT_EQUAL_32(value32 >> (shift[3] & 31), w25);
6710     ASSERT_EQUAL_32(value32 >> (shift[4] & 31), w26);
6711     ASSERT_EQUAL_32(value32 >> (shift[5] & 31), w27);
6712   }
6713 }
6714 
6715 
6716 TEST(rorv) {
6717   SETUP();
6718 
6719   uint64_t value = 0x0123456789abcdef;
6720   int shift[] = {4, 8, 12, 16, 24, 36};
6721 
6722   START();
6723   __ Mov(x0, value);
6724   __ Mov(w1, shift[0]);
6725   __ Mov(w2, shift[1]);
6726   __ Mov(w3, shift[2]);
6727   __ Mov(w4, shift[3]);
6728   __ Mov(w5, shift[4]);
6729   __ Mov(w6, shift[5]);
6730 
6731   // The MacroAssembler does not allow zr as an argument.
6732   {
6733     ExactAssemblyScope scope(&masm, kInstructionSize);
6734     __ rorv(x0, x0, xzr);
6735   }
6736 
6737   __ Ror(x16, x0, x1);
6738   __ Ror(x17, x0, x2);
6739   __ Ror(x18, x0, x3);
6740   __ Ror(x19, x0, x4);
6741   __ Ror(x20, x0, x5);
6742   __ Ror(x21, x0, x6);
6743 
6744   __ Ror(w22, w0, w1);
6745   __ Ror(w23, w0, w2);
6746   __ Ror(w24, w0, w3);
6747   __ Ror(w25, w0, w4);
6748   __ Ror(w26, w0, w5);
6749   __ Ror(w27, w0, w6);
6750   END();
6751 
6752   if (CAN_RUN()) {
6753     RUN();
6754 
6755     ASSERT_EQUAL_64(value, x0);
6756     ASSERT_EQUAL_64(0xf0123456789abcde, x16);
6757     ASSERT_EQUAL_64(0xef0123456789abcd, x17);
6758     ASSERT_EQUAL_64(0xdef0123456789abc, x18);
6759     ASSERT_EQUAL_64(0xcdef0123456789ab, x19);
6760     ASSERT_EQUAL_64(0xabcdef0123456789, x20);
6761     ASSERT_EQUAL_64(0x789abcdef0123456, x21);
6762     ASSERT_EQUAL_32(0xf89abcde, w22);
6763     ASSERT_EQUAL_32(0xef89abcd, w23);
6764     ASSERT_EQUAL_32(0xdef89abc, w24);
6765     ASSERT_EQUAL_32(0xcdef89ab, w25);
6766     ASSERT_EQUAL_32(0xabcdef89, w26);
6767     ASSERT_EQUAL_32(0xf89abcde, w27);
6768   }
6769 }
6770 
6771 
6772 TEST(bfm) {
6773   SETUP();
6774 
6775   START();
6776   __ Mov(x1, 0x0123456789abcdef);
6777 
6778   __ Mov(x10, 0x8888888888888888);
6779   __ Mov(x11, 0x8888888888888888);
6780   __ Mov(x12, 0x8888888888888888);
6781   __ Mov(x13, 0x8888888888888888);
6782   __ Mov(x14, 0xffffffffffffffff);
6783   __ Mov(w20, 0x88888888);
6784   __ Mov(w21, 0x88888888);
6785 
6786   __ Bfm(x10, x1, 16, 31);
6787   __ Bfm(x11, x1, 32, 15);
6788 
6789   __ Bfm(w20, w1, 16, 23);
6790   __ Bfm(w21, w1, 24, 15);
6791 
6792   // Aliases.
6793   __ Bfi(x12, x1, 16, 8);
6794   __ Bfxil(x13, x1, 16, 8);
6795   __ Bfc(x14, 16, 8);
6796   END();
6797 
6798   if (CAN_RUN()) {
6799     RUN();
6800 
6801 
6802     ASSERT_EQUAL_64(0x88888888888889ab, x10);
6803     ASSERT_EQUAL_64(0x8888cdef88888888, x11);
6804 
6805     ASSERT_EQUAL_32(0x888888ab, w20);
6806     ASSERT_EQUAL_32(0x88cdef88, w21);
6807 
6808     ASSERT_EQUAL_64(0x8888888888ef8888, x12);
6809     ASSERT_EQUAL_64(0x88888888888888ab, x13);
6810     ASSERT_EQUAL_64(0xffffffffff00ffff, x14);
6811   }
6812 }
6813 
6814 
6815 TEST(sbfm) {
6816   SETUP();
6817 
6818   START();
6819   __ Mov(x1, 0x0123456789abcdef);
6820   __ Mov(x2, 0xfedcba9876543210);
6821 
6822   __ Sbfm(x10, x1, 16, 31);
6823   __ Sbfm(x11, x1, 32, 15);
6824   __ Sbfm(x12, x1, 32, 47);
6825   __ Sbfm(x13, x1, 48, 35);
6826 
6827   __ Sbfm(w14, w1, 16, 23);
6828   __ Sbfm(w15, w1, 24, 15);
6829   __ Sbfm(w16, w2, 16, 23);
6830   __ Sbfm(w17, w2, 24, 15);
6831 
6832   // Aliases.
6833   __ Asr(x18, x1, 32);
6834   __ Asr(x19, x2, 32);
6835   __ Sbfiz(x20, x1, 8, 16);
6836   __ Sbfiz(x21, x2, 8, 16);
6837   __ Sbfx(x22, x1, 8, 16);
6838   __ Sbfx(x23, x2, 8, 16);
6839   __ Sxtb(x24, w1);
6840   __ Sxtb(x25, x2);
6841   __ Sxth(x26, w1);
6842   __ Sxth(x27, x2);
6843   __ Sxtw(x28, w1);
6844   __ Sxtw(x29, x2);
6845   END();
6846 
6847   if (CAN_RUN()) {
6848     RUN();
6849 
6850 
6851     ASSERT_EQUAL_64(0xffffffffffff89ab, x10);
6852     ASSERT_EQUAL_64(0xffffcdef00000000, x11);
6853     ASSERT_EQUAL_64(0x0000000000004567, x12);
6854     ASSERT_EQUAL_64(0x000789abcdef0000, x13);
6855 
6856     ASSERT_EQUAL_32(0xffffffab, w14);
6857     ASSERT_EQUAL_32(0xffcdef00, w15);
6858     ASSERT_EQUAL_32(0x00000054, w16);
6859     ASSERT_EQUAL_32(0x00321000, w17);
6860 
6861     ASSERT_EQUAL_64(0x0000000001234567, x18);
6862     ASSERT_EQUAL_64(0xfffffffffedcba98, x19);
6863     ASSERT_EQUAL_64(0xffffffffffcdef00, x20);
6864     ASSERT_EQUAL_64(0x0000000000321000, x21);
6865     ASSERT_EQUAL_64(0xffffffffffffabcd, x22);
6866     ASSERT_EQUAL_64(0x0000000000005432, x23);
6867     ASSERT_EQUAL_64(0xffffffffffffffef, x24);
6868     ASSERT_EQUAL_64(0x0000000000000010, x25);
6869     ASSERT_EQUAL_64(0xffffffffffffcdef, x26);
6870     ASSERT_EQUAL_64(0x0000000000003210, x27);
6871     ASSERT_EQUAL_64(0xffffffff89abcdef, x28);
6872     ASSERT_EQUAL_64(0x0000000076543210, x29);
6873   }
6874 }
6875 
6876 
6877 TEST(ubfm) {
6878   SETUP();
6879 
6880   START();
6881   __ Mov(x1, 0x0123456789abcdef);
6882   __ Mov(x2, 0xfedcba9876543210);
6883 
6884   __ Mov(x10, 0x8888888888888888);
6885   __ Mov(x11, 0x8888888888888888);
6886 
6887   __ Ubfm(x10, x1, 16, 31);
6888   __ Ubfm(x11, x1, 32, 15);
6889   __ Ubfm(x12, x1, 32, 47);
6890   __ Ubfm(x13, x1, 48, 35);
6891 
6892   __ Ubfm(w25, w1, 16, 23);
6893   __ Ubfm(w26, w1, 24, 15);
6894   __ Ubfm(w27, w2, 16, 23);
6895   __ Ubfm(w28, w2, 24, 15);
6896 
6897   // Aliases
6898   __ Lsl(x15, x1, 63);
6899   __ Lsl(x16, x1, 0);
6900   __ Lsr(x17, x1, 32);
6901   __ Ubfiz(x18, x1, 8, 16);
6902   __ Ubfx(x19, x1, 8, 16);
6903   __ Uxtb(x20, x1);
6904   __ Uxth(x21, x1);
6905   __ Uxtw(x22, x1);
6906   END();
6907 
6908   if (CAN_RUN()) {
6909     RUN();
6910 
6911     ASSERT_EQUAL_64(0x00000000000089ab, x10);
6912     ASSERT_EQUAL_64(0x0000cdef00000000, x11);
6913     ASSERT_EQUAL_64(0x0000000000004567, x12);
6914     ASSERT_EQUAL_64(0x000789abcdef0000, x13);
6915 
6916     ASSERT_EQUAL_32(0x000000ab, w25);
6917     ASSERT_EQUAL_32(0x00cdef00, w26);
6918     ASSERT_EQUAL_32(0x00000054, w27);
6919     ASSERT_EQUAL_32(0x00321000, w28);
6920 
6921     ASSERT_EQUAL_64(0x8000000000000000, x15);
6922     ASSERT_EQUAL_64(0x0123456789abcdef, x16);
6923     ASSERT_EQUAL_64(0x0000000001234567, x17);
6924     ASSERT_EQUAL_64(0x0000000000cdef00, x18);
6925     ASSERT_EQUAL_64(0x000000000000abcd, x19);
6926     ASSERT_EQUAL_64(0x00000000000000ef, x20);
6927     ASSERT_EQUAL_64(0x000000000000cdef, x21);
6928     ASSERT_EQUAL_64(0x0000000089abcdef, x22);
6929   }
6930 }
6931 
6932 
6933 TEST(extr) {
6934   SETUP();
6935 
6936   START();
6937   __ Mov(x1, 0x0123456789abcdef);
6938   __ Mov(x2, 0xfedcba9876543210);
6939 
6940   __ Extr(w10, w1, w2, 0);
6941   __ Extr(w11, w1, w2, 1);
6942   __ Extr(x12, x2, x1, 2);
6943 
6944   __ Ror(w13, w1, 0);
6945   __ Ror(w14, w2, 17);
6946   __ Ror(w15, w1, 31);
6947   __ Ror(x18, x2, 0);
6948   __ Ror(x19, x2, 1);
6949   __ Ror(x20, x1, 63);
6950   END();
6951 
6952   if (CAN_RUN()) {
6953     RUN();
6954 
6955     ASSERT_EQUAL_64(0x76543210, x10);
6956     ASSERT_EQUAL_64(0xbb2a1908, x11);
6957     ASSERT_EQUAL_64(0x0048d159e26af37b, x12);
6958     ASSERT_EQUAL_64(0x89abcdef, x13);
6959     ASSERT_EQUAL_64(0x19083b2a, x14);
6960     ASSERT_EQUAL_64(0x13579bdf, x15);
6961     ASSERT_EQUAL_64(0xfedcba9876543210, x18);
6962     ASSERT_EQUAL_64(0x7f6e5d4c3b2a1908, x19);
6963     ASSERT_EQUAL_64(0x02468acf13579bde, x20);
6964   }
6965 }
6966 
6967 
6968 TEST(system_mrs) {
6969   SETUP();
6970 
6971   START();
6972   __ Mov(w0, 0);
6973   __ Mov(w1, 1);
6974   __ Mov(w2, 0x80000000);
6975 
6976   // Set the Z and C flags.
6977   __ Cmp(w0, w0);
6978   __ Mrs(x3, NZCV);
6979 
6980   // Set the N flag.
6981   __ Cmp(w0, w1);
6982   __ Mrs(x4, NZCV);
6983 
6984   // Set the Z, C and V flags.
6985   __ Adds(w0, w2, w2);
6986   __ Mrs(x5, NZCV);
6987 
6988   // Read the default FPCR.
6989   __ Mrs(x6, FPCR);
6990   END();
6991 
6992   if (CAN_RUN()) {
6993     RUN();
6994 
6995     // NZCV
6996     ASSERT_EQUAL_32(ZCFlag, w3);
6997     ASSERT_EQUAL_32(NFlag, w4);
6998     ASSERT_EQUAL_32(ZCVFlag, w5);
6999 
7000     // FPCR
7001     // The default FPCR on Linux-based platforms is 0.
7002     ASSERT_EQUAL_32(0, w6);
7003   }
7004 }
7005 
7006 TEST(system_rng) {
7007   SETUP_WITH_FEATURES(CPUFeatures::kRNG);
7008 
7009   START();
7010   // Random number.
7011   __ Mrs(x1, RNDR);
7012   // Assume that each generation is successful now.
7013   // TODO: Return failure occasionally.
7014   __ Mrs(x2, NZCV);
7015   __ Mrs(x3, RNDR);
7016   __ Mrs(x4, NZCV);
7017 
7018   // Reseeded random number.
7019   __ Mrs(x5, RNDRRS);
7020   // Assume that each generation is successful now.
7021   // TODO: Return failure occasionally.
7022   __ Mrs(x6, NZCV);
7023   __ Mrs(x7, RNDRRS);
7024   __ Mrs(x8, NZCV);
7025   END();
7026 
7027   if (CAN_RUN()) {
7028     RUN();
7029     // Random number generation series.
7030     // Check random numbers have been generated and aren't equal when reseed has
7031     // happened.
7032     // NOTE: With a different architectural implementation, there may be a
7033     // collison.
7034     // TODO: Return failure occasionally. Set ZFlag and return UNKNOWN value.
7035     ASSERT_NOT_EQUAL_64(x1, x3);
7036     ASSERT_EQUAL_64(NoFlag, x2);
7037     ASSERT_EQUAL_64(NoFlag, x4);
7038     ASSERT_NOT_EQUAL_64(x5, x7);
7039     ASSERT_EQUAL_64(NoFlag, x6);
7040     ASSERT_EQUAL_64(NoFlag, x8);
7041   }
7042 }
7043 
7044 TEST(cfinv) {
7045   SETUP_WITH_FEATURES(CPUFeatures::kFlagM);
7046 
7047   START();
7048   __ Mov(w0, 1);
7049 
7050   // Set the C flag.
7051   __ Cmp(w0, 0);
7052   __ Mrs(x1, NZCV);
7053 
7054   // Invert the C flag.
7055   __ Cfinv();
7056   __ Mrs(x2, NZCV);
7057 
7058   // Invert the C flag again.
7059   __ Cfinv();
7060   __ Mrs(x3, NZCV);
7061   END();
7062 
7063   if (CAN_RUN()) {
7064     RUN();
7065 
7066     ASSERT_EQUAL_32(CFlag, w1);
7067     ASSERT_EQUAL_32(NoFlag, w2);
7068     ASSERT_EQUAL_32(CFlag, w3);
7069   }
7070 }
7071 
7072 
7073 TEST(axflag_xaflag) {
7074   // The AXFLAG and XAFLAG instructions are designed for converting the FP
7075   // conditional flags from Arm format to an alternate format efficiently.
7076   // There are only 4 cases which are relevant for this conversion but we test
7077   // the behaviour for all 16 cases anyway. The 4 important cases are labelled
7078   // below.
7079   StatusFlags expected_x[16] = {NoFlag,
7080                                 ZFlag,
7081                                 CFlag,  // Greater than
7082                                 ZFlag,  // Unordered
7083                                 ZFlag,
7084                                 ZFlag,
7085                                 ZCFlag,  // Equal to
7086                                 ZFlag,
7087                                 NoFlag,  // Less than
7088                                 ZFlag,
7089                                 CFlag,
7090                                 ZFlag,
7091                                 ZFlag,
7092                                 ZFlag,
7093                                 ZCFlag,
7094                                 ZFlag};
7095   StatusFlags expected_a[16] = {NFlag,  // Less than
7096                                 NFlag,
7097                                 CFlag,  // Greater than
7098                                 CFlag,
7099                                 CVFlag,  // Unordered
7100                                 CVFlag,
7101                                 ZCFlag,  // Equal to
7102                                 ZCFlag,
7103                                 NFlag,
7104                                 NFlag,
7105                                 CFlag,
7106                                 CFlag,
7107                                 CVFlag,
7108                                 CVFlag,
7109                                 ZCFlag,
7110                                 ZCFlag};
7111 
7112   for (unsigned i = 0; i < 16; i++) {
7113     SETUP_WITH_FEATURES(CPUFeatures::kAXFlag);
7114 
7115     START();
7116     __ Mov(x0, i << Flags_offset);
7117     __ Msr(NZCV, x0);
7118     __ Axflag();
7119     __ Mrs(x1, NZCV);
7120     __ Msr(NZCV, x0);
7121     __ Xaflag();
7122     __ Mrs(x2, NZCV);
7123     END();
7124 
7125     if (CAN_RUN()) {
7126       RUN();
7127       ASSERT_EQUAL_32(expected_x[i], w1);
7128       ASSERT_EQUAL_32(expected_a[i], w2);
7129     }
7130   }
7131 }
7132 
7133 
7134 TEST(system_msr) {
7135   // All FPCR fields that must be implemented: AHP, DN, FZ, RMode
7136   const uint64_t fpcr_core = (0b1 << 26) |  // AHP
7137                              (0b1 << 25) |  // DN
7138                              (0b1 << 24) |  // FZ
7139                              (0b11 << 22);  // RMode
7140 
7141   SETUP();
7142 
7143   START();
7144   __ Mov(w0, 0);
7145   __ Mov(w1, 0x7fffffff);
7146 
7147   __ Mov(x7, 0);
7148 
7149   __ Mov(x10, NVFlag);
7150   __ Cmp(w0, w0);     // Set Z and C.
7151   __ Msr(NZCV, x10);  // Set N and V.
7152   // The Msr should have overwritten every flag set by the Cmp.
7153   __ Cinc(x7, x7, mi);  // N
7154   __ Cinc(x7, x7, ne);  // !Z
7155   __ Cinc(x7, x7, lo);  // !C
7156   __ Cinc(x7, x7, vs);  // V
7157 
7158   __ Mov(x10, ZCFlag);
7159   __ Cmn(w1, w1);     // Set N and V.
7160   __ Msr(NZCV, x10);  // Set Z and C.
7161   // The Msr should have overwritten every flag set by the Cmn.
7162   __ Cinc(x7, x7, pl);  // !N
7163   __ Cinc(x7, x7, eq);  // Z
7164   __ Cinc(x7, x7, hs);  // C
7165   __ Cinc(x7, x7, vc);  // !V
7166 
7167   Register old_fpcr = x15;
7168   __ Mrs(old_fpcr, FPCR);
7169 
7170   // All core FPCR fields must be writable.
7171   __ Mov(x8, fpcr_core);
7172   __ Msr(FPCR, x8);
7173   __ Mrs(x8, FPCR);
7174 
7175 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7176   // All FPCR fields that aren't `RES0`:
7177   const uint64_t fpcr_all = fpcr_core | (0b11 << 20) |  // Stride
7178                             (0b1 << 19) |               // FZ16
7179                             (0b111 << 16) |             // Len
7180                             (0b1 << 15) |               // IDE
7181                             (0b1 << 12) |               // IXE
7182                             (0b1 << 11) |               // UFE
7183                             (0b1 << 10) |               // OFE
7184                             (0b1 << 9) |                // DZE
7185                             (0b1 << 8);                 // IOE
7186 
7187   // All FPCR fields, including optional ones. This part of the test doesn't
7188   // achieve much other than ensuring that supported fields can be cleared by
7189   // the next test.
7190   __ Mov(x9, fpcr_all);
7191   __ Msr(FPCR, x9);
7192   __ Mrs(x9, FPCR);
7193   __ And(x9, x9, fpcr_core);
7194 
7195   // The undefined bits must ignore writes.
7196   // It's conceivable that a future version of the architecture could use these
7197   // fields (making this test fail), but in the meantime this is a useful test
7198   // for the simulator.
7199   __ Mov(x10, ~fpcr_all);
7200   __ Msr(FPCR, x10);
7201   __ Mrs(x10, FPCR);
7202 #endif
7203 
7204   __ Msr(FPCR, old_fpcr);
7205 
7206   END();
7207 
7208   if (CAN_RUN()) {
7209     RUN();
7210 
7211     // We should have incremented x7 (from 0) exactly 8 times.
7212     ASSERT_EQUAL_64(8, x7);
7213 
7214     ASSERT_EQUAL_64(fpcr_core, x8);
7215 
7216 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7217     ASSERT_EQUAL_64(fpcr_core, x9);
7218     ASSERT_EQUAL_64(0, x10);
7219 #endif
7220   }
7221 }
7222 
7223 
7224 TEST(system_pauth_a) {
7225   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
7226   START();
7227 
7228   // Exclude x16 and x17 from the scratch register list so we can use
7229   // Pac/Autia1716 safely.
7230   UseScratchRegisterScope temps(&masm);
7231   temps.Exclude(x16, x17);
7232   temps.Include(x10, x11);
7233 
7234   // Backup stack pointer.
7235   __ Mov(x20, sp);
7236 
7237   // Modifiers
7238   __ Mov(x16, 0x477d469dec0b8760);
7239   __ Mov(sp, 0x477d469dec0b8760);
7240 
7241   // Generate PACs using the 3 system instructions.
7242   __ Mov(x17, 0x0000000012345678);
7243   __ Pacia1716();
7244   __ Mov(x0, x17);
7245 
7246   __ Mov(lr, 0x0000000012345678);
7247   __ Paciaz();
7248   __ Mov(x1, lr);
7249 
7250   __ Mov(lr, 0x0000000012345678);
7251   __ Paciasp();
7252   __ Mov(x2, lr);
7253 
7254   // Authenticate the pointers above.
7255   __ Mov(x17, x0);
7256   __ Autia1716();
7257   __ Mov(x3, x17);
7258 
7259   __ Mov(lr, x1);
7260   __ Autiaz();
7261   __ Mov(x4, lr);
7262 
7263   __ Mov(lr, x2);
7264   __ Autiasp();
7265   __ Mov(x5, lr);
7266 
7267   // Attempt to authenticate incorrect pointers.
7268   __ Mov(x17, x1);
7269   __ Autia1716();
7270   __ Mov(x6, x17);
7271 
7272   __ Mov(lr, x0);
7273   __ Autiaz();
7274   __ Mov(x7, lr);
7275 
7276   __ Mov(lr, x1);
7277   __ Autiasp();
7278   __ Mov(x8, lr);
7279 
7280   // Strip the pac code from the pointer in x0.
7281   __ Mov(lr, x0);
7282   __ Xpaclri();
7283   __ Mov(x9, lr);
7284 
7285   // Restore stack pointer.
7286   __ Mov(sp, x20);
7287 
7288   // Mask out just the PAC code bits.
7289   // TODO: use Simulator::CalculatePACMask in a nice way.
7290   __ And(x0, x0, 0x007f000000000000);
7291   __ And(x1, x1, 0x007f000000000000);
7292   __ And(x2, x2, 0x007f000000000000);
7293 
7294   END();
7295 
7296   if (CAN_RUN()) {
7297     RUN();
7298 
7299     // Check PAC codes have been generated and aren't equal.
7300     // NOTE: with a different ComputePAC implementation, there may be a
7301     // collision.
7302     ASSERT_NOT_EQUAL_64(0, x0);
7303     ASSERT_NOT_EQUAL_64(0, x1);
7304     ASSERT_NOT_EQUAL_64(0, x2);
7305     ASSERT_NOT_EQUAL_64(x0, x1);
7306     ASSERT_EQUAL_64(x0, x2);
7307 
7308     // Pointers correctly authenticated.
7309     ASSERT_EQUAL_64(0x0000000012345678, x3);
7310     ASSERT_EQUAL_64(0x0000000012345678, x4);
7311     ASSERT_EQUAL_64(0x0000000012345678, x5);
7312 
7313     // Pointers corrupted after failing to authenticate.
7314     ASSERT_EQUAL_64(0x0020000012345678, x6);
7315     ASSERT_EQUAL_64(0x0020000012345678, x7);
7316     ASSERT_EQUAL_64(0x0020000012345678, x8);
7317 
7318     // Pointer with code stripped.
7319     ASSERT_EQUAL_64(0x0000000012345678, x9);
7320   }
7321 }
7322 
7323 
7324 TEST(system_pauth_b) {
7325   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
7326   START();
7327 
7328   // Exclude x16 and x17 from the scratch register list so we can use
7329   // Pac/Autia1716 safely.
7330   UseScratchRegisterScope temps(&masm);
7331   temps.Exclude(x16, x17);
7332   temps.Include(x10, x11);
7333 
7334   // Backup stack pointer.
7335   __ Mov(x20, sp);
7336 
7337   // Modifiers
7338   __ Mov(x16, 0x477d469dec0b8760);
7339   __ Mov(sp, 0x477d469dec0b8760);
7340 
7341   // Generate PACs using the 3 system instructions.
7342   __ Mov(x17, 0x0000000012345678);
7343   __ Pacib1716();
7344   __ Mov(x0, x17);
7345 
7346   __ Mov(lr, 0x0000000012345678);
7347   __ Pacibz();
7348   __ Mov(x1, lr);
7349 
7350   __ Mov(lr, 0x0000000012345678);
7351   __ Pacibsp();
7352   __ Mov(x2, lr);
7353 
7354   // Authenticate the pointers above.
7355   __ Mov(x17, x0);
7356   __ Autib1716();
7357   __ Mov(x3, x17);
7358 
7359   __ Mov(lr, x1);
7360   __ Autibz();
7361   __ Mov(x4, lr);
7362 
7363   __ Mov(lr, x2);
7364   __ Autibsp();
7365   __ Mov(x5, lr);
7366 
7367   // Attempt to authenticate incorrect pointers.
7368   __ Mov(x17, x1);
7369   __ Autib1716();
7370   __ Mov(x6, x17);
7371 
7372   __ Mov(lr, x0);
7373   __ Autibz();
7374   __ Mov(x7, lr);
7375 
7376   __ Mov(lr, x1);
7377   __ Autibsp();
7378   __ Mov(x8, lr);
7379 
7380   // Strip the pac code from the pointer in x0.
7381   __ Mov(lr, x0);
7382   __ Xpaclri();
7383   __ Mov(x9, lr);
7384 
7385   // Restore stack pointer.
7386   __ Mov(sp, x20);
7387 
7388   // Mask out just the PAC code bits.
7389   // TODO: use Simulator::CalculatePACMask in a nice way.
7390   __ And(x0, x0, 0x007f000000000000);
7391   __ And(x1, x1, 0x007f000000000000);
7392   __ And(x2, x2, 0x007f000000000000);
7393 
7394   END();
7395 
7396   if (CAN_RUN()) {
7397     RUN();
7398 
7399     // Check PAC codes have been generated and aren't equal.
7400     // NOTE: with a different ComputePAC implementation, there may be a
7401     // collision.
7402     ASSERT_NOT_EQUAL_64(0, x0);
7403     ASSERT_NOT_EQUAL_64(0, x1);
7404     ASSERT_NOT_EQUAL_64(0, x2);
7405     ASSERT_NOT_EQUAL_64(x0, x1);
7406     ASSERT_EQUAL_64(x0, x2);
7407 
7408     // Pointers correctly authenticated.
7409     ASSERT_EQUAL_64(0x0000000012345678, x3);
7410     ASSERT_EQUAL_64(0x0000000012345678, x4);
7411     ASSERT_EQUAL_64(0x0000000012345678, x5);
7412 
7413     // Pointers corrupted after failing to authenticate.
7414     ASSERT_EQUAL_64(0x0040000012345678, x6);
7415     ASSERT_EQUAL_64(0x0040000012345678, x7);
7416     ASSERT_EQUAL_64(0x0040000012345678, x8);
7417 
7418     // Pointer with code stripped.
7419     ASSERT_EQUAL_64(0x0000000012345678, x9);
7420   }
7421 }
7422 
7423 #ifdef VIXL_NEGATIVE_TESTING
7424 TEST(system_pauth_negative_test) {
7425   SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
7426   START();
7427 
7428   // Test for an assert (independent of order).
7429   MUST_FAIL_WITH_MESSAGE(__ Pacia1716(),
7430                          "Assertion failed "
7431                          "(!GetScratchRegisterList()->IncludesAliasOf(");
7432 
7433   // Test for x16 assert.
7434   {
7435     UseScratchRegisterScope temps(&masm);
7436     temps.Exclude(x17);
7437     temps.Include(x16);
7438     MUST_FAIL_WITH_MESSAGE(__ Pacia1716(),
7439                            "Assertion failed "
7440                            "(!GetScratchRegisterList()->IncludesAliasOf(x16))");
7441   }
7442 
7443   // Test for x17 assert.
7444   {
7445     UseScratchRegisterScope temps(&masm);
7446     temps.Exclude(x16);
7447     temps.Include(x17);
7448     MUST_FAIL_WITH_MESSAGE(__ Pacia1716(),
7449                            "Assertion failed "
7450                            "(!GetScratchRegisterList()->IncludesAliasOf(x17))");
7451   }
7452 
7453   // Repeat first test for other 1716 instructions.
7454   MUST_FAIL_WITH_MESSAGE(__ Pacib1716(),
7455                          "Assertion failed "
7456                          "(!GetScratchRegisterList()->IncludesAliasOf(");
7457   MUST_FAIL_WITH_MESSAGE(__ Autia1716(),
7458                          "Assertion failed "
7459                          "(!GetScratchRegisterList()->IncludesAliasOf(");
7460   MUST_FAIL_WITH_MESSAGE(__ Autib1716(),
7461                          "Assertion failed "
7462                          "(!GetScratchRegisterList()->IncludesAliasOf(");
7463 
7464   END();
7465 }
7466 #endif  // VIXL_NEGATIVE_TESTING
7467 
7468 
7469 TEST(system) {
7470   // RegisterDump::Dump uses NEON.
7471   SETUP_WITH_FEATURES(CPUFeatures::kNEON, CPUFeatures::kRAS);
7472   RegisterDump before;
7473 
7474   START();
7475   before.Dump(&masm);
7476   __ Nop();
7477   __ Esb();
7478   __ Csdb();
7479   END();
7480 
7481   if (CAN_RUN()) {
7482     RUN();
7483 
7484     ASSERT_EQUAL_REGISTERS(before);
7485     ASSERT_EQUAL_NZCV(before.flags_nzcv());
7486   }
7487 }
7488 
7489 static void BtiHelper(Register ipreg) {
7490   SETUP_WITH_FEATURES(CPUFeatures::kBTI);
7491 
7492   Label jump_target, jump_call_target, call_target, done;
7493   START();
7494   UseScratchRegisterScope temps(&masm);
7495   temps.Exclude(ipreg);
7496   __ Adr(x0, &jump_target);
7497   __ Br(x0);
7498   __ Nop();
7499   __ Bind(&jump_target, EmitBTI_j);
7500   __ Adr(x0, &call_target);
7501   __ Blr(x0);
7502   __ Adr(ipreg, &jump_call_target);
7503   __ Blr(ipreg);
7504   __ Adr(lr, &done);  // Make Ret return to done label.
7505   __ Br(ipreg);
7506   __ Bind(&call_target, EmitBTI_c);
7507   __ Ret();
7508   __ Bind(&jump_call_target, EmitBTI_jc);
7509   __ Ret();
7510   __ Bind(&done);
7511   END();
7512 
7513   if (CAN_RUN()) {
7514 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7515     simulator.SetGuardedPages(true);
7516 #else
7517     VIXL_UNIMPLEMENTED();
7518 #endif
7519     RUN();
7520   }
7521 }
7522 
7523 TEST(bti) {
7524   BtiHelper(x16);
7525   BtiHelper(x17);
7526 }
7527 
7528 TEST(unguarded_bti_is_nop) {
7529   SETUP_WITH_FEATURES(CPUFeatures::kBTI);
7530 
7531   Label start, none, c, j, jc;
7532   START();
7533   __ B(&start);
7534   __ Bind(&none, EmitBTI);
7535   __ Bind(&c, EmitBTI_c);
7536   __ Bind(&j, EmitBTI_j);
7537   __ Bind(&jc, EmitBTI_jc);
7538   VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&none) == 4 * kInstructionSize);
7539   __ Ret();
7540 
7541   Label jump_to_c, call_to_j;
7542   __ Bind(&start);
7543   __ Adr(x0, &none);
7544   __ Adr(lr, &jump_to_c);
7545   __ Br(x0);
7546 
7547   __ Bind(&jump_to_c);
7548   __ Adr(x0, &c);
7549   __ Adr(lr, &call_to_j);
7550   __ Br(x0);
7551 
7552   __ Bind(&call_to_j);
7553   __ Adr(x0, &j);
7554   __ Blr(x0);
7555   END();
7556 
7557   if (CAN_RUN()) {
7558 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7559     simulator.SetGuardedPages(false);
7560 #else
7561     VIXL_UNIMPLEMENTED();
7562 #endif
7563     RUN();
7564   }
7565 }
7566 
7567 #ifdef VIXL_NEGATIVE_TESTING
7568 TEST(bti_jump_to_ip_unidentified) {
7569   SETUP_WITH_FEATURES(CPUFeatures::kBTI);
7570 
7571   START();
7572   UseScratchRegisterScope temps(&masm);
7573   temps.Exclude(x17);
7574   Label l;
7575   __ Adr(x17, &l);
7576   __ Br(x17);
7577   __ Nop();
7578   __ Bind(&l);
7579   __ Nop();
7580   END();
7581 
7582   if (CAN_RUN()) {
7583 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7584     simulator.SetGuardedPages(true);
7585 #else
7586     VIXL_UNIMPLEMENTED();
7587 #endif
7588     MUST_FAIL_WITH_MESSAGE(RUN(),
7589                            "Executing non-BTI instruction with wrong "
7590                            "BType.");
7591   }
7592 }
7593 
7594 TEST(bti_jump_to_unidentified) {
7595   SETUP_WITH_FEATURES(CPUFeatures::kBTI);
7596 
7597   START();
7598   Label l;
7599   __ Adr(x0, &l);
7600   __ Br(x0);
7601   __ Nop();
7602   __ Bind(&l);
7603   __ Nop();
7604   END();
7605 
7606   if (CAN_RUN()) {
7607 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7608     simulator.SetGuardedPages(true);
7609 #else
7610     VIXL_UNIMPLEMENTED();
7611 #endif
7612     MUST_FAIL_WITH_MESSAGE(RUN(),
7613                            "Executing non-BTI instruction with wrong "
7614                            "BType.");
7615   }
7616 }
7617 
7618 TEST(bti_call_to_unidentified) {
7619   SETUP_WITH_FEATURES(CPUFeatures::kBTI);
7620 
7621   START();
7622   Label l;
7623   __ Adr(x0, &l);
7624   __ Blr(x0);
7625   __ Nop();
7626   __ Bind(&l);
7627   __ Nop();
7628   END();
7629 
7630   if (CAN_RUN()) {
7631 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7632     simulator.SetGuardedPages(true);
7633 #else
7634     VIXL_UNIMPLEMENTED();
7635 #endif
7636     MUST_FAIL_WITH_MESSAGE(RUN(),
7637                            "Executing non-BTI instruction with wrong "
7638                            "BType.");
7639   }
7640 }
7641 
7642 TEST(bti_jump_to_c) {
7643   SETUP_WITH_FEATURES(CPUFeatures::kBTI);
7644 
7645   START();
7646   // Jumping to a "BTI c" target must fail.
7647   Label jump_target;
7648   __ Adr(x0, &jump_target);
7649   __ Br(x0);
7650   __ Nop();
7651   __ Bind(&jump_target, EmitBTI_c);
7652   __ Nop();
7653   END();
7654 
7655   if (CAN_RUN()) {
7656 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7657     simulator.SetGuardedPages(true);
7658 #else
7659     VIXL_UNIMPLEMENTED();
7660 #endif
7661     MUST_FAIL_WITH_MESSAGE(RUN(), "Executing BTI c with wrong BType.");
7662   }
7663 }
7664 
7665 TEST(bti_call_to_j) {
7666   SETUP_WITH_FEATURES(CPUFeatures::kBTI);
7667 
7668   START();
7669   // Calling a "BTI j" target must fail.
7670   Label call_target;
7671   __ Adr(x0, &call_target);
7672   __ Blr(x0);
7673   __ Nop();
7674   __ Bind(&call_target, EmitBTI_j);
7675   __ Nop();
7676   END();
7677 
7678   if (CAN_RUN()) {
7679 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7680     simulator.SetGuardedPages(true);
7681 #else
7682     VIXL_UNIMPLEMENTED();
7683 #endif
7684     MUST_FAIL_WITH_MESSAGE(RUN(), "Executing BTI j with wrong BType.");
7685   }
7686 }
7687 #endif  // VIXL_NEGATIVE_TESTING
7688 
7689 TEST(fall_through_bti) {
7690   SETUP_WITH_FEATURES(CPUFeatures::kBTI, CPUFeatures::kPAuth);
7691 
7692   START();
7693   Label target, target_j, target_c, target_jc;
7694   __ Mov(x0, 0);  // 'Normal' instruction sets BTYPE to zero.
7695   __ Bind(&target, EmitBTI);
7696   __ Add(x0, x0, 1);
7697   __ Bind(&target_j, EmitBTI_j);
7698   __ Add(x0, x0, 1);
7699   __ Bind(&target_c, EmitBTI_c);
7700   __ Add(x0, x0, 1);
7701   __ Bind(&target_jc, EmitBTI_jc);
7702   __ Add(x0, x0, 1);
7703   __ Paciasp();
7704   END();
7705 
7706   if (CAN_RUN()) {
7707 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
7708     simulator.SetGuardedPages(true);
7709 #else
7710     VIXL_UNIMPLEMENTED();
7711 #endif
7712     RUN();
7713 
7714     ASSERT_EQUAL_64(4, x0);
7715   }
7716 }
7717 
7718 TEST(zero_dest) {
7719   // RegisterDump::Dump uses NEON.
7720   SETUP_WITH_FEATURES(CPUFeatures::kNEON);
7721   RegisterDump before;
7722 
7723   START();
7724   // Preserve the stack pointer, in case we clobber it.
7725   __ Mov(x30, sp);
7726   // Initialize the other registers used in this test.
7727   uint64_t literal_base = 0x0100001000100101;
7728   __ Mov(x0, 0);
7729   __ Mov(x1, literal_base);
7730   for (unsigned i = 2; i < x30.GetCode(); i++) {
7731     __ Add(XRegister(i), XRegister(i - 1), x1);
7732   }
7733   before.Dump(&masm);
7734 
7735   // All of these instructions should be NOPs in these forms, but have
7736   // alternate forms which can write into the stack pointer.
7737   {
7738     ExactAssemblyScope scope(&masm, 3 * 7 * kInstructionSize);
7739     __ add(xzr, x0, x1);
7740     __ add(xzr, x1, xzr);
7741     __ add(xzr, xzr, x1);
7742 
7743     __ and_(xzr, x0, x2);
7744     __ and_(xzr, x2, xzr);
7745     __ and_(xzr, xzr, x2);
7746 
7747     __ bic(xzr, x0, x3);
7748     __ bic(xzr, x3, xzr);
7749     __ bic(xzr, xzr, x3);
7750 
7751     __ eon(xzr, x0, x4);
7752     __ eon(xzr, x4, xzr);
7753     __ eon(xzr, xzr, x4);
7754 
7755     __ eor(xzr, x0, x5);
7756     __ eor(xzr, x5, xzr);
7757     __ eor(xzr, xzr, x5);
7758 
7759     __ orr(xzr, x0, x6);
7760     __ orr(xzr, x6, xzr);
7761     __ orr(xzr, xzr, x6);
7762 
7763     __ sub(xzr, x0, x7);
7764     __ sub(xzr, x7, xzr);
7765     __ sub(xzr, xzr, x7);
7766   }
7767 
7768   // Swap the saved stack pointer with the real one. If sp was written
7769   // during the test, it will show up in x30. This is done because the test
7770   // framework assumes that sp will be valid at the end of the test.
7771   __ Mov(x29, x30);
7772   __ Mov(x30, sp);
7773   __ Mov(sp, x29);
7774   // We used x29 as a scratch register, so reset it to make sure it doesn't
7775   // trigger a test failure.
7776   __ Add(x29, x28, x1);
7777   END();
7778 
7779   if (CAN_RUN()) {
7780     RUN();
7781 
7782     ASSERT_EQUAL_REGISTERS(before);
7783     ASSERT_EQUAL_NZCV(before.flags_nzcv());
7784   }
7785 }
7786 
7787 
7788 TEST(zero_dest_setflags) {
7789   // RegisterDump::Dump uses NEON.
7790   SETUP_WITH_FEATURES(CPUFeatures::kNEON);
7791   RegisterDump before;
7792 
7793   START();
7794   // Preserve the stack pointer, in case we clobber it.
7795   __ Mov(x30, sp);
7796   // Initialize the other registers used in this test.
7797   uint64_t literal_base = 0x0100001000100101;
7798   __ Mov(x0, 0);
7799   __ Mov(x1, literal_base);
7800   for (int i = 2; i < 30; i++) {
7801     __ Add(XRegister(i), XRegister(i - 1), x1);
7802   }
7803   before.Dump(&masm);
7804 
7805   // All of these instructions should only write to the flags in these forms,
7806   // but have alternate forms which can write into the stack pointer.
7807   {
7808     ExactAssemblyScope scope(&masm, 6 * kInstructionSize);
7809     __ adds(xzr, x0, Operand(x1, UXTX));
7810     __ adds(xzr, x1, Operand(xzr, UXTX));
7811     __ adds(xzr, x1, 1234);
7812     __ adds(xzr, x0, x1);
7813     __ adds(xzr, x1, xzr);
7814     __ adds(xzr, xzr, x1);
7815   }
7816 
7817   {
7818     ExactAssemblyScope scope(&masm, 5 * kInstructionSize);
7819     __ ands(xzr, x2, ~0xf);
7820     __ ands(xzr, xzr, ~0xf);
7821     __ ands(xzr, x0, x2);
7822     __ ands(xzr, x2, xzr);
7823     __ ands(xzr, xzr, x2);
7824   }
7825 
7826   {
7827     ExactAssemblyScope scope(&masm, 5 * kInstructionSize);
7828     __ bics(xzr, x3, ~0xf);
7829     __ bics(xzr, xzr, ~0xf);
7830     __ bics(xzr, x0, x3);
7831     __ bics(xzr, x3, xzr);
7832     __ bics(xzr, xzr, x3);
7833   }
7834 
7835   {
7836     ExactAssemblyScope scope(&masm, 6 * kInstructionSize);
7837     __ subs(xzr, x0, Operand(x3, UXTX));
7838     __ subs(xzr, x3, Operand(xzr, UXTX));
7839     __ subs(xzr, x3, 1234);
7840     __ subs(xzr, x0, x3);
7841     __ subs(xzr, x3, xzr);
7842     __ subs(xzr, xzr, x3);
7843   }
7844 
7845   // Swap the saved stack pointer with the real one. If sp was written
7846   // during the test, it will show up in x30. This is done because the test
7847   // framework assumes that sp will be valid at the end of the test.
7848   __ Mov(x29, x30);
7849   __ Mov(x30, sp);
7850   __ Mov(sp, x29);
7851   // We used x29 as a scratch register, so reset it to make sure it doesn't
7852   // trigger a test failure.
7853   __ Add(x29, x28, x1);
7854   END();
7855 
7856   if (CAN_RUN()) {
7857     RUN();
7858 
7859     ASSERT_EQUAL_REGISTERS(before);
7860   }
7861 }
7862 
7863 
7864 TEST(stack_pointer_override) {
7865   // This test generates some stack maintenance code, but the test only checks
7866   // the reported state.
7867   SETUP();
7868   START();
7869 
7870   // The default stack pointer in VIXL is sp.
7871   VIXL_CHECK(sp.Is(__ StackPointer()));
7872   __ SetStackPointer(x0);
7873   VIXL_CHECK(x0.Is(__ StackPointer()));
7874   __ SetStackPointer(x28);
7875   VIXL_CHECK(x28.Is(__ StackPointer()));
7876   __ SetStackPointer(sp);
7877   VIXL_CHECK(sp.Is(__ StackPointer()));
7878 
7879   END();
7880   if (CAN_RUN()) {
7881     RUN();
7882   }
7883 }
7884 
7885 
7886 TEST(peek_poke_simple) {
7887   SETUP();
7888   START();
7889 
7890   static const RegList x0_to_x3 =
7891       x0.GetBit() | x1.GetBit() | x2.GetBit() | x3.GetBit();
7892   static const RegList x10_to_x13 =
7893       x10.GetBit() | x11.GetBit() | x12.GetBit() | x13.GetBit();
7894 
7895   // The literal base is chosen to have two useful properties:
7896   //  * When multiplied by small values (such as a register index), this value
7897   //    is clearly readable in the result.
7898   //  * The value is not formed from repeating fixed-size smaller values, so it
7899   //    can be used to detect endianness-related errors.
7900   uint64_t literal_base = 0x0100001000100101;
7901 
7902   // Initialize the registers.
7903   __ Mov(x0, literal_base);
7904   __ Add(x1, x0, x0);
7905   __ Add(x2, x1, x0);
7906   __ Add(x3, x2, x0);
7907 
7908   __ Claim(32);
7909 
7910   // Simple exchange.
7911   //  After this test:
7912   //    x0-x3 should be unchanged.
7913   //    w10-w13 should contain the lower words of x0-x3.
7914   __ Poke(x0, 0);
7915   __ Poke(x1, 8);
7916   __ Poke(x2, 16);
7917   __ Poke(x3, 24);
7918   Clobber(&masm, x0_to_x3);
7919   __ Peek(x0, 0);
7920   __ Peek(x1, 8);
7921   __ Peek(x2, 16);
7922   __ Peek(x3, 24);
7923 
7924   __ Poke(w0, 0);
7925   __ Poke(w1, 4);
7926   __ Poke(w2, 8);
7927   __ Poke(w3, 12);
7928   Clobber(&masm, x10_to_x13);
7929   __ Peek(w10, 0);
7930   __ Peek(w11, 4);
7931   __ Peek(w12, 8);
7932   __ Peek(w13, 12);
7933 
7934   __ Drop(32);
7935 
7936   END();
7937   if (CAN_RUN()) {
7938     RUN();
7939 
7940     ASSERT_EQUAL_64(literal_base * 1, x0);
7941     ASSERT_EQUAL_64(literal_base * 2, x1);
7942     ASSERT_EQUAL_64(literal_base * 3, x2);
7943     ASSERT_EQUAL_64(literal_base * 4, x3);
7944 
7945     ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
7946     ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
7947     ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
7948     ASSERT_EQUAL_64((literal_base * 4) & 0xffffffff, x13);
7949   }
7950 }
7951 
7952 
7953 TEST(peek_poke_unaligned) {
7954   SETUP();
7955   START();
7956 
7957   // The literal base is chosen to have two useful properties:
7958   //  * When multiplied by small values (such as a register index), this value
7959   //    is clearly readable in the result.
7960   //  * The value is not formed from repeating fixed-size smaller values, so it
7961   //    can be used to detect endianness-related errors.
7962   uint64_t literal_base = 0x0100001000100101;
7963 
7964   // Initialize the registers.
7965   __ Mov(x0, literal_base);
7966   __ Add(x1, x0, x0);
7967   __ Add(x2, x1, x0);
7968   __ Add(x3, x2, x0);
7969   __ Add(x4, x3, x0);
7970   __ Add(x5, x4, x0);
7971   __ Add(x6, x5, x0);
7972 
7973   __ Claim(32);
7974 
7975   // Unaligned exchanges.
7976   //  After this test:
7977   //    x0-x6 should be unchanged.
7978   //    w10-w12 should contain the lower words of x0-x2.
7979   __ Poke(x0, 1);
7980   Clobber(&masm, x0.GetBit());
7981   __ Peek(x0, 1);
7982   __ Poke(x1, 2);
7983   Clobber(&masm, x1.GetBit());
7984   __ Peek(x1, 2);
7985   __ Poke(x2, 3);
7986   Clobber(&masm, x2.GetBit());
7987   __ Peek(x2, 3);
7988   __ Poke(x3, 4);
7989   Clobber(&masm, x3.GetBit());
7990   __ Peek(x3, 4);
7991   __ Poke(x4, 5);
7992   Clobber(&masm, x4.GetBit());
7993   __ Peek(x4, 5);
7994   __ Poke(x5, 6);
7995   Clobber(&masm, x5.GetBit());
7996   __ Peek(x5, 6);
7997   __ Poke(x6, 7);
7998   Clobber(&masm, x6.GetBit());
7999   __ Peek(x6, 7);
8000 
8001   __ Poke(w0, 1);
8002   Clobber(&masm, w10.GetBit());
8003   __ Peek(w10, 1);
8004   __ Poke(w1, 2);
8005   Clobber(&masm, w11.GetBit());
8006   __ Peek(w11, 2);
8007   __ Poke(w2, 3);
8008   Clobber(&masm, w12.GetBit());
8009   __ Peek(w12, 3);
8010 
8011   __ Drop(32);
8012 
8013   END();
8014   if (CAN_RUN()) {
8015     RUN();
8016 
8017     ASSERT_EQUAL_64(literal_base * 1, x0);
8018     ASSERT_EQUAL_64(literal_base * 2, x1);
8019     ASSERT_EQUAL_64(literal_base * 3, x2);
8020     ASSERT_EQUAL_64(literal_base * 4, x3);
8021     ASSERT_EQUAL_64(literal_base * 5, x4);
8022     ASSERT_EQUAL_64(literal_base * 6, x5);
8023     ASSERT_EQUAL_64(literal_base * 7, x6);
8024 
8025     ASSERT_EQUAL_64((literal_base * 1) & 0xffffffff, x10);
8026     ASSERT_EQUAL_64((literal_base * 2) & 0xffffffff, x11);
8027     ASSERT_EQUAL_64((literal_base * 3) & 0xffffffff, x12);
8028   }
8029 }
8030 
8031 
8032 TEST(peek_poke_endianness) {
8033   SETUP();
8034   START();
8035 
8036   // The literal base is chosen to have two useful properties:
8037   //  * When multiplied by small values (such as a register index), this value
8038   //    is clearly readable in the result.
8039   //  * The value is not formed from repeating fixed-size smaller values, so it
8040   //    can be used to detect endianness-related errors.
8041   uint64_t literal_base = 0x0100001000100101;
8042 
8043   // Initialize the registers.
8044   __ Mov(x0, literal_base);
8045   __ Add(x1, x0, x0);
8046 
8047   __ Claim(32);
8048 
8049   // Endianness tests.
8050   //  After this section:
8051   //    x4 should match x0[31:0]:x0[63:32]
8052   //    w5 should match w1[15:0]:w1[31:16]
8053   __ Poke(x0, 0);
8054   __ Poke(x0, 8);
8055   __ Peek(x4, 4);
8056 
8057   __ Poke(w1, 0);
8058   __ Poke(w1, 4);
8059   __ Peek(w5, 2);
8060 
8061   __ Drop(32);
8062 
8063   END();
8064   if (CAN_RUN()) {
8065     RUN();
8066 
8067     uint64_t x0_expected = literal_base * 1;
8068     uint64_t x1_expected = literal_base * 2;
8069     uint64_t x4_expected = (x0_expected << 32) | (x0_expected >> 32);
8070     uint64_t x5_expected =
8071         ((x1_expected << 16) & 0xffff0000) | ((x1_expected >> 16) & 0x0000ffff);
8072 
8073     ASSERT_EQUAL_64(x0_expected, x0);
8074     ASSERT_EQUAL_64(x1_expected, x1);
8075     ASSERT_EQUAL_64(x4_expected, x4);
8076     ASSERT_EQUAL_64(x5_expected, x5);
8077   }
8078 }
8079 
8080 
8081 TEST(peek_poke_mixed) {
8082   SETUP();
8083   START();
8084 
8085   // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
8086   UseScratchRegisterScope temps(&masm);
8087   temps.ExcludeAll();
8088 
8089   // The literal base is chosen to have two useful properties:
8090   //  * When multiplied by small values (such as a register index), this value
8091   //    is clearly readable in the result.
8092   //  * The value is not formed from repeating fixed-size smaller values, so it
8093   //    can be used to detect endianness-related errors.
8094   uint64_t literal_base = 0x0100001000100101;
8095 
8096   // Initialize the registers.
8097   __ Mov(x0, literal_base);
8098   __ Add(x1, x0, x0);
8099   __ Add(x2, x1, x0);
8100   __ Add(x3, x2, x0);
8101 
8102   __ Claim(32);
8103 
8104   // Mix with other stack operations.
8105   //  After this section:
8106   //    x0-x3 should be unchanged.
8107   //    x6 should match x1[31:0]:x0[63:32]
8108   //    w7 should match x1[15:0]:x0[63:48]
8109   __ Poke(x1, 8);
8110   __ Poke(x0, 0);
8111   {
8112     VIXL_ASSERT(__ StackPointer().Is(sp));
8113     __ Mov(x4, __ StackPointer());
8114     __ SetStackPointer(x4);
8115 
8116     __ Poke(wzr, 0);  // Clobber the space we're about to drop.
8117     __ Drop(4);
8118     __ Peek(x6, 0);
8119     __ Claim(8);
8120     __ Peek(w7, 10);
8121     __ Poke(x3, 28);
8122     __ Poke(xzr, 0);  // Clobber the space we're about to drop.
8123     __ Drop(8);
8124     __ Poke(x2, 12);
8125     __ Push(w0);
8126 
8127     __ Mov(sp, __ StackPointer());
8128     __ SetStackPointer(sp);
8129   }
8130 
8131   __ Pop(x0, x1, x2, x3);
8132 
8133   END();
8134   if (CAN_RUN()) {
8135     RUN();
8136 
8137     uint64_t x0_expected = literal_base * 1;
8138     uint64_t x1_expected = literal_base * 2;
8139     uint64_t x2_expected = literal_base * 3;
8140     uint64_t x3_expected = literal_base * 4;
8141     uint64_t x6_expected = (x1_expected << 32) | (x0_expected >> 32);
8142     uint64_t x7_expected =
8143         ((x1_expected << 16) & 0xffff0000) | ((x0_expected >> 48) & 0x0000ffff);
8144 
8145     ASSERT_EQUAL_64(x0_expected, x0);
8146     ASSERT_EQUAL_64(x1_expected, x1);
8147     ASSERT_EQUAL_64(x2_expected, x2);
8148     ASSERT_EQUAL_64(x3_expected, x3);
8149     ASSERT_EQUAL_64(x6_expected, x6);
8150     ASSERT_EQUAL_64(x7_expected, x7);
8151   }
8152 }
8153 
8154 
8155 TEST(peek_poke_reglist) {
8156   SETUP_WITH_FEATURES(CPUFeatures::kFP);
8157 
8158   START();
8159 
8160   // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
8161   UseScratchRegisterScope temps(&masm);
8162   temps.ExcludeAll();
8163 
8164   // The literal base is chosen to have two useful properties:
8165   //  * When multiplied by small values (such as a register index), this value
8166   //    is clearly readable in the result.
8167   //  * The value is not formed from repeating fixed-size smaller values, so it
8168   //    can be used to detect endianness-related errors.
8169   uint64_t base = 0x0100001000100101;
8170 
8171   // Initialize the registers.
8172   __ Mov(x1, base);
8173   __ Add(x2, x1, x1);
8174   __ Add(x3, x2, x1);
8175   __ Add(x4, x3, x1);
8176 
8177   CPURegList list_1(x1, x2, x3, x4);
8178   CPURegList list_2(x11, x12, x13, x14);
8179   int list_1_size = list_1.GetTotalSizeInBytes();
8180 
8181   __ Claim(2 * list_1_size);
8182 
8183   __ PokeCPURegList(list_1, 0);
8184   __ PokeXRegList(list_1.GetList(), list_1_size);
8185   __ PeekCPURegList(list_2, 2 * kXRegSizeInBytes);
8186   __ PeekXRegList(x15.GetBit(), kWRegSizeInBytes);
8187   __ PeekWRegList(w16.GetBit() | w17.GetBit(), 3 * kXRegSizeInBytes);
8188 
8189   __ Drop(2 * list_1_size);
8190 
8191 
8192   uint64_t base_d = 0x1010010001000010;
8193 
8194   // Initialize the registers.
8195   __ Mov(x1, base_d);
8196   __ Add(x2, x1, x1);
8197   __ Add(x3, x2, x1);
8198   __ Add(x4, x3, x1);
8199   __ Fmov(d1, x1);
8200   __ Fmov(d2, x2);
8201   __ Fmov(d3, x3);
8202   __ Fmov(d4, x4);
8203 
8204   CPURegList list_d_1(d1, d2, d3, d4);
8205   CPURegList list_d_2(d11, d12, d13, d14);
8206   int list_d_1_size = list_d_1.GetTotalSizeInBytes();
8207 
8208   __ Claim(2 * list_d_1_size);
8209 
8210   __ PokeCPURegList(list_d_1, 0);
8211   __ PokeDRegList(list_d_1.GetList(), list_d_1_size);
8212   __ PeekCPURegList(list_d_2, 2 * kDRegSizeInBytes);
8213   __ PeekDRegList(d15.GetBit(), kSRegSizeInBytes);
8214   __ PeekSRegList(s16.GetBit() | s17.GetBit(), 3 * kDRegSizeInBytes);
8215 
8216   __ Drop(2 * list_d_1_size);
8217 
8218 
8219   END();
8220   if (CAN_RUN()) {
8221     RUN();
8222 
8223     ASSERT_EQUAL_64(3 * base, x11);
8224     ASSERT_EQUAL_64(4 * base, x12);
8225     ASSERT_EQUAL_64(1 * base, x13);
8226     ASSERT_EQUAL_64(2 * base, x14);
8227     ASSERT_EQUAL_64(((1 * base) >> kWRegSize) | ((2 * base) << kWRegSize), x15);
8228     ASSERT_EQUAL_64(2 * base, x14);
8229     ASSERT_EQUAL_32((4 * base) & kWRegMask, w16);
8230     ASSERT_EQUAL_32((4 * base) >> kWRegSize, w17);
8231 
8232     ASSERT_EQUAL_FP64(RawbitsToDouble(3 * base_d), d11);
8233     ASSERT_EQUAL_FP64(RawbitsToDouble(4 * base_d), d12);
8234     ASSERT_EQUAL_FP64(RawbitsToDouble(1 * base_d), d13);
8235     ASSERT_EQUAL_FP64(RawbitsToDouble(2 * base_d), d14);
8236     ASSERT_EQUAL_FP64(RawbitsToDouble((base_d >> kSRegSize) |
8237                                       ((2 * base_d) << kSRegSize)),
8238                       d15);
8239     ASSERT_EQUAL_FP64(RawbitsToDouble(2 * base_d), d14);
8240     ASSERT_EQUAL_FP32(RawbitsToFloat((4 * base_d) & kSRegMask), s16);
8241     ASSERT_EQUAL_FP32(RawbitsToFloat((4 * base_d) >> kSRegSize), s17);
8242   }
8243 }
8244 
8245 
8246 TEST(load_store_reglist) {
8247   SETUP_WITH_FEATURES(CPUFeatures::kFP);
8248 
8249   START();
8250 
8251   // The literal base is chosen to have two useful properties:
8252   //  * When multiplied by small values (such as a register index), this value
8253   //    is clearly readable in the result.
8254   //  * The value is not formed from repeating fixed-size smaller values, so it
8255   //    can be used to detect endianness-related errors.
8256   uint64_t high_base = UINT32_C(0x01000010);
8257   uint64_t low_base = UINT32_C(0x00100101);
8258   uint64_t base = (high_base << 32) | low_base;
8259   uint64_t array[21];
8260   memset(array, 0, sizeof(array));
8261 
8262   // Initialize the registers.
8263   __ Mov(x1, base);
8264   __ Add(x2, x1, x1);
8265   __ Add(x3, x2, x1);
8266   __ Add(x4, x3, x1);
8267   __ Fmov(d1, x1);
8268   __ Fmov(d2, x2);
8269   __ Fmov(d3, x3);
8270   __ Fmov(d4, x4);
8271   __ Fmov(d5, x1);
8272   __ Fmov(d6, x2);
8273   __ Fmov(d7, x3);
8274   __ Fmov(d8, x4);
8275 
8276   Register reg_base = x20;
8277   Register reg_index = x21;
8278   int size_stored = 0;
8279 
8280   __ Mov(reg_base, reinterpret_cast<uintptr_t>(&array));
8281 
8282   // Test aligned accesses.
8283   CPURegList list_src(w1, w2, w3, w4);
8284   CPURegList list_dst(w11, w12, w13, w14);
8285   CPURegList list_fp_src_1(d1, d2, d3, d4);
8286   CPURegList list_fp_dst_1(d11, d12, d13, d14);
8287 
8288   __ StoreCPURegList(list_src, MemOperand(reg_base, 0 * sizeof(uint64_t)));
8289   __ LoadCPURegList(list_dst, MemOperand(reg_base, 0 * sizeof(uint64_t)));
8290   size_stored += 4 * kWRegSizeInBytes;
8291 
8292   __ Mov(reg_index, size_stored);
8293   __ StoreCPURegList(list_src, MemOperand(reg_base, reg_index));
8294   __ LoadCPURegList(list_dst, MemOperand(reg_base, reg_index));
8295   size_stored += 4 * kWRegSizeInBytes;
8296 
8297   __ StoreCPURegList(list_fp_src_1, MemOperand(reg_base, size_stored));
8298   __ LoadCPURegList(list_fp_dst_1, MemOperand(reg_base, size_stored));
8299   size_stored += 4 * kDRegSizeInBytes;
8300 
8301   __ Mov(reg_index, size_stored);
8302   __ StoreCPURegList(list_fp_src_1, MemOperand(reg_base, reg_index));
8303   __ LoadCPURegList(list_fp_dst_1, MemOperand(reg_base, reg_index));
8304   size_stored += 4 * kDRegSizeInBytes;
8305 
8306   // Test unaligned accesses.
8307   CPURegList list_fp_src_2(d5, d6, d7, d8);
8308   CPURegList list_fp_dst_2(d15, d16, d17, d18);
8309 
8310   __ Str(wzr, MemOperand(reg_base, size_stored));
8311   size_stored += 1 * kWRegSizeInBytes;
8312   __ StoreCPURegList(list_fp_src_2, MemOperand(reg_base, size_stored));
8313   __ LoadCPURegList(list_fp_dst_2, MemOperand(reg_base, size_stored));
8314   size_stored += 4 * kDRegSizeInBytes;
8315 
8316   __ Mov(reg_index, size_stored);
8317   __ StoreCPURegList(list_fp_src_2, MemOperand(reg_base, reg_index));
8318   __ LoadCPURegList(list_fp_dst_2, MemOperand(reg_base, reg_index));
8319 
8320   END();
8321   if (CAN_RUN()) {
8322     RUN();
8323 
8324     VIXL_CHECK(array[0] == (1 * low_base) + (2 * low_base << kWRegSize));
8325     VIXL_CHECK(array[1] == (3 * low_base) + (4 * low_base << kWRegSize));
8326     VIXL_CHECK(array[2] == (1 * low_base) + (2 * low_base << kWRegSize));
8327     VIXL_CHECK(array[3] == (3 * low_base) + (4 * low_base << kWRegSize));
8328     VIXL_CHECK(array[4] == 1 * base);
8329     VIXL_CHECK(array[5] == 2 * base);
8330     VIXL_CHECK(array[6] == 3 * base);
8331     VIXL_CHECK(array[7] == 4 * base);
8332     VIXL_CHECK(array[8] == 1 * base);
8333     VIXL_CHECK(array[9] == 2 * base);
8334     VIXL_CHECK(array[10] == 3 * base);
8335     VIXL_CHECK(array[11] == 4 * base);
8336     VIXL_CHECK(array[12] == ((1 * low_base) << kSRegSize));
8337     VIXL_CHECK(array[13] == (((2 * low_base) << kSRegSize) | (1 * high_base)));
8338     VIXL_CHECK(array[14] == (((3 * low_base) << kSRegSize) | (2 * high_base)));
8339     VIXL_CHECK(array[15] == (((4 * low_base) << kSRegSize) | (3 * high_base)));
8340     VIXL_CHECK(array[16] == (((1 * low_base) << kSRegSize) | (4 * high_base)));
8341     VIXL_CHECK(array[17] == (((2 * low_base) << kSRegSize) | (1 * high_base)));
8342     VIXL_CHECK(array[18] == (((3 * low_base) << kSRegSize) | (2 * high_base)));
8343     VIXL_CHECK(array[19] == (((4 * low_base) << kSRegSize) | (3 * high_base)));
8344     VIXL_CHECK(array[20] == (4 * high_base));
8345 
8346     ASSERT_EQUAL_64(1 * low_base, x11);
8347     ASSERT_EQUAL_64(2 * low_base, x12);
8348     ASSERT_EQUAL_64(3 * low_base, x13);
8349     ASSERT_EQUAL_64(4 * low_base, x14);
8350     ASSERT_EQUAL_FP64(RawbitsToDouble(1 * base), d11);
8351     ASSERT_EQUAL_FP64(RawbitsToDouble(2 * base), d12);
8352     ASSERT_EQUAL_FP64(RawbitsToDouble(3 * base), d13);
8353     ASSERT_EQUAL_FP64(RawbitsToDouble(4 * base), d14);
8354     ASSERT_EQUAL_FP64(RawbitsToDouble(1 * base), d15);
8355     ASSERT_EQUAL_FP64(RawbitsToDouble(2 * base), d16);
8356     ASSERT_EQUAL_FP64(RawbitsToDouble(3 * base), d17);
8357     ASSERT_EQUAL_FP64(RawbitsToDouble(4 * base), d18);
8358   }
8359 }
8360 
8361 
8362 // This enum is used only as an argument to the push-pop test helpers.
8363 enum PushPopMethod {
8364   // Push or Pop using the Push and Pop methods, with blocks of up to four
8365   // registers. (Smaller blocks will be used if necessary.)
8366   PushPopByFour,
8367 
8368   // Use Push<Size>RegList and Pop<Size>RegList to transfer the registers.
8369   PushPopRegList
8370 };
8371 
8372 
8373 // For the PushPop* tests, use the maximum number of registers that the test
8374 // supports (where a reg_count argument would otherwise be provided).
8375 static int const kPushPopUseMaxRegCount = -1;
8376 
8377 // Test a simple push-pop pattern:
8378 //  * Claim <claim> bytes to set the stack alignment.
8379 //  * Push <reg_count> registers with size <reg_size>.
8380 //  * Clobber the register contents.
8381 //  * Pop <reg_count> registers to restore the original contents.
8382 //  * Drop <claim> bytes to restore the original stack pointer.
8383 //
8384 // Different push and pop methods can be specified independently to test for
8385 // proper word-endian behaviour.
8386 static void PushPopSimpleHelper(int reg_count,
8387                                 int claim,
8388                                 int reg_size,
8389                                 PushPopMethod push_method,
8390                                 PushPopMethod pop_method) {
8391   SETUP();
8392 
8393   START();
8394 
8395   // Arbitrarily pick a register to use as a stack pointer.
8396   const Register& stack_pointer = x20;
8397   const RegList allowed = ~stack_pointer.GetBit();
8398   if (reg_count == kPushPopUseMaxRegCount) {
8399     reg_count = CountSetBits(allowed, kNumberOfRegisters);
8400   }
8401   // Work out which registers to use, based on reg_size.
8402   Register r[kNumberOfRegisters];
8403   Register x[kNumberOfRegisters];
8404   RegList list =
8405       PopulateRegisterArray(NULL, x, r, reg_size, reg_count, allowed);
8406 
8407   // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
8408   UseScratchRegisterScope temps(&masm);
8409   temps.ExcludeAll();
8410 
8411   // The literal base is chosen to have two useful properties:
8412   //  * When multiplied by small values (such as a register index), this value
8413   //    is clearly readable in the result.
8414   //  * The value is not formed from repeating fixed-size smaller values, so it
8415   //    can be used to detect endianness-related errors.
8416   uint64_t literal_base = 0x0100001000100101;
8417 
8418   {
8419     VIXL_ASSERT(__ StackPointer().Is(sp));
8420     __ Mov(stack_pointer, __ StackPointer());
8421     __ SetStackPointer(stack_pointer);
8422 
8423     int i;
8424 
8425     // Initialize the registers.
8426     for (i = 0; i < reg_count; i++) {
8427       // Always write into the X register, to ensure that the upper word is
8428       // properly ignored by Push when testing W registers.
8429       __ Mov(x[i], literal_base * i);
8430     }
8431 
8432     // Claim memory first, as requested.
8433     __ Claim(claim);
8434 
8435     switch (push_method) {
8436       case PushPopByFour:
8437         // Push high-numbered registers first (to the highest addresses).
8438         for (i = reg_count; i >= 4; i -= 4) {
8439           __ Push(r[i - 1], r[i - 2], r[i - 3], r[i - 4]);
8440         }
8441         // Finish off the leftovers.
8442         switch (i) {
8443           case 3:
8444             __ Push(r[2], r[1], r[0]);
8445             break;
8446           case 2:
8447             __ Push(r[1], r[0]);
8448             break;
8449           case 1:
8450             __ Push(r[0]);
8451             break;
8452           default:
8453             VIXL_ASSERT(i == 0);
8454             break;
8455         }
8456         break;
8457       case PushPopRegList:
8458         __ PushSizeRegList(list, reg_size);
8459         break;
8460     }
8461 
8462     // Clobber all the registers, to ensure that they get repopulated by Pop.
8463     Clobber(&masm, list);
8464 
8465     switch (pop_method) {
8466       case PushPopByFour:
8467         // Pop low-numbered registers first (from the lowest addresses).
8468         for (i = 0; i <= (reg_count - 4); i += 4) {
8469           __ Pop(r[i], r[i + 1], r[i + 2], r[i + 3]);
8470         }
8471         // Finish off the leftovers.
8472         switch (reg_count - i) {
8473           case 3:
8474             __ Pop(r[i], r[i + 1], r[i + 2]);
8475             break;
8476           case 2:
8477             __ Pop(r[i], r[i + 1]);
8478             break;
8479           case 1:
8480             __ Pop(r[i]);
8481             break;
8482           default:
8483             VIXL_ASSERT(i == reg_count);
8484             break;
8485         }
8486         break;
8487       case PushPopRegList:
8488         __ PopSizeRegList(list, reg_size);
8489         break;
8490     }
8491 
8492     // Drop memory to restore stack_pointer.
8493     __ Drop(claim);
8494 
8495     __ Mov(sp, __ StackPointer());
8496     __ SetStackPointer(sp);
8497   }
8498 
8499   END();
8500 
8501   if (CAN_RUN()) {
8502     RUN();
8503 
8504     // Check that the register contents were preserved.
8505     // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
8506     // that the upper word was properly cleared by Pop.
8507     literal_base &= (0xffffffffffffffff >> (64 - reg_size));
8508     for (int i = 0; i < reg_count; i++) {
8509       if (x[i].Is(xzr)) {
8510         ASSERT_EQUAL_64(0, x[i]);
8511       } else {
8512         ASSERT_EQUAL_64(literal_base * i, x[i]);
8513       }
8514     }
8515   }
8516 }
8517 
8518 
8519 TEST(push_pop_xreg_simple_32) {
8520   for (int claim = 0; claim <= 8; claim++) {
8521     for (int count = 0; count <= 8; count++) {
8522       PushPopSimpleHelper(count,
8523                           claim,
8524                           kWRegSize,
8525                           PushPopByFour,
8526                           PushPopByFour);
8527       PushPopSimpleHelper(count,
8528                           claim,
8529                           kWRegSize,
8530                           PushPopByFour,
8531                           PushPopRegList);
8532       PushPopSimpleHelper(count,
8533                           claim,
8534                           kWRegSize,
8535                           PushPopRegList,
8536                           PushPopByFour);
8537       PushPopSimpleHelper(count,
8538                           claim,
8539                           kWRegSize,
8540                           PushPopRegList,
8541                           PushPopRegList);
8542     }
8543     // Test with the maximum number of registers.
8544     PushPopSimpleHelper(kPushPopUseMaxRegCount,
8545                         claim,
8546                         kWRegSize,
8547                         PushPopByFour,
8548                         PushPopByFour);
8549     PushPopSimpleHelper(kPushPopUseMaxRegCount,
8550                         claim,
8551                         kWRegSize,
8552                         PushPopByFour,
8553                         PushPopRegList);
8554     PushPopSimpleHelper(kPushPopUseMaxRegCount,
8555                         claim,
8556                         kWRegSize,
8557                         PushPopRegList,
8558                         PushPopByFour);
8559     PushPopSimpleHelper(kPushPopUseMaxRegCount,
8560                         claim,
8561                         kWRegSize,
8562                         PushPopRegList,
8563                         PushPopRegList);
8564   }
8565 }
8566 
8567 
8568 TEST(push_pop_xreg_simple_64) {
8569   for (int claim = 0; claim <= 8; claim++) {
8570     for (int count = 0; count <= 8; count++) {
8571       PushPopSimpleHelper(count,
8572                           claim,
8573                           kXRegSize,
8574                           PushPopByFour,
8575                           PushPopByFour);
8576       PushPopSimpleHelper(count,
8577                           claim,
8578                           kXRegSize,
8579                           PushPopByFour,
8580                           PushPopRegList);
8581       PushPopSimpleHelper(count,
8582                           claim,
8583                           kXRegSize,
8584                           PushPopRegList,
8585                           PushPopByFour);
8586       PushPopSimpleHelper(count,
8587                           claim,
8588                           kXRegSize,
8589                           PushPopRegList,
8590                           PushPopRegList);
8591     }
8592     // Test with the maximum number of registers.
8593     PushPopSimpleHelper(kPushPopUseMaxRegCount,
8594                         claim,
8595                         kXRegSize,
8596                         PushPopByFour,
8597                         PushPopByFour);
8598     PushPopSimpleHelper(kPushPopUseMaxRegCount,
8599                         claim,
8600                         kXRegSize,
8601                         PushPopByFour,
8602                         PushPopRegList);
8603     PushPopSimpleHelper(kPushPopUseMaxRegCount,
8604                         claim,
8605                         kXRegSize,
8606                         PushPopRegList,
8607                         PushPopByFour);
8608     PushPopSimpleHelper(kPushPopUseMaxRegCount,
8609                         claim,
8610                         kXRegSize,
8611                         PushPopRegList,
8612                         PushPopRegList);
8613   }
8614 }
8615 
8616 // For the PushPopFP* tests, use the maximum number of registers that the test
8617 // supports (where a reg_count argument would otherwise be provided).
8618 static int const kPushPopFPUseMaxRegCount = -1;
8619 
8620 // Test a simple push-pop pattern:
8621 //  * Claim <claim> bytes to set the stack alignment.
8622 //  * Push <reg_count> FP registers with size <reg_size>.
8623 //  * Clobber the register contents.
8624 //  * Pop <reg_count> FP registers to restore the original contents.
8625 //  * Drop <claim> bytes to restore the original stack pointer.
8626 //
8627 // Different push and pop methods can be specified independently to test for
8628 // proper word-endian behaviour.
8629 static void PushPopFPSimpleHelper(int reg_count,
8630                                   int claim,
8631                                   int reg_size,
8632                                   PushPopMethod push_method,
8633                                   PushPopMethod pop_method) {
8634   SETUP_WITH_FEATURES((reg_count == 0) ? CPUFeatures::kNone : CPUFeatures::kFP);
8635 
8636   START();
8637 
8638   // We can use any floating-point register. None of them are reserved for
8639   // debug code, for example.
8640   static RegList const allowed = ~0;
8641   if (reg_count == kPushPopFPUseMaxRegCount) {
8642     reg_count = CountSetBits(allowed, kNumberOfVRegisters);
8643   }
8644   // Work out which registers to use, based on reg_size.
8645   VRegister v[kNumberOfRegisters];
8646   VRegister d[kNumberOfRegisters];
8647   RegList list =
8648       PopulateVRegisterArray(NULL, d, v, reg_size, reg_count, allowed);
8649 
8650   // Arbitrarily pick a register to use as a stack pointer.
8651   const Register& stack_pointer = x10;
8652 
8653   // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
8654   UseScratchRegisterScope temps(&masm);
8655   temps.ExcludeAll();
8656 
8657   // The literal base is chosen to have two useful properties:
8658   //  * When multiplied (using an integer) by small values (such as a register
8659   //    index), this value is clearly readable in the result.
8660   //  * The value is not formed from repeating fixed-size smaller values, so it
8661   //    can be used to detect endianness-related errors.
8662   //  * It is never a floating-point NaN, and will therefore always compare
8663   //    equal to itself.
8664   uint64_t literal_base = 0x0100001000100101;
8665 
8666   {
8667     VIXL_ASSERT(__ StackPointer().Is(sp));
8668     __ Mov(stack_pointer, __ StackPointer());
8669     __ SetStackPointer(stack_pointer);
8670 
8671     int i;
8672 
8673     // Initialize the registers, using X registers to load the literal.
8674     __ Mov(x0, 0);
8675     __ Mov(x1, literal_base);
8676     for (i = 0; i < reg_count; i++) {
8677       // Always write into the D register, to ensure that the upper word is
8678       // properly ignored by Push when testing S registers.
8679       __ Fmov(d[i], x0);
8680       // Calculate the next literal.
8681       __ Add(x0, x0, x1);
8682     }
8683 
8684     // Claim memory first, as requested.
8685     __ Claim(claim);
8686 
8687     switch (push_method) {
8688       case PushPopByFour:
8689         // Push high-numbered registers first (to the highest addresses).
8690         for (i = reg_count; i >= 4; i -= 4) {
8691           __ Push(v[i - 1], v[i - 2], v[i - 3], v[i - 4]);
8692         }
8693         // Finish off the leftovers.
8694         switch (i) {
8695           case 3:
8696             __ Push(v[2], v[1], v[0]);
8697             break;
8698           case 2:
8699             __ Push(v[1], v[0]);
8700             break;
8701           case 1:
8702             __ Push(v[0]);
8703             break;
8704           default:
8705             VIXL_ASSERT(i == 0);
8706             break;
8707         }
8708         break;
8709       case PushPopRegList:
8710         __ PushSizeRegList(list, reg_size, CPURegister::kVRegister);
8711         break;
8712     }
8713 
8714     // Clobber all the registers, to ensure that they get repopulated by Pop.
8715     ClobberFP(&masm, list);
8716 
8717     switch (pop_method) {
8718       case PushPopByFour:
8719         // Pop low-numbered registers first (from the lowest addresses).
8720         for (i = 0; i <= (reg_count - 4); i += 4) {
8721           __ Pop(v[i], v[i + 1], v[i + 2], v[i + 3]);
8722         }
8723         // Finish off the leftovers.
8724         switch (reg_count - i) {
8725           case 3:
8726             __ Pop(v[i], v[i + 1], v[i + 2]);
8727             break;
8728           case 2:
8729             __ Pop(v[i], v[i + 1]);
8730             break;
8731           case 1:
8732             __ Pop(v[i]);
8733             break;
8734           default:
8735             VIXL_ASSERT(i == reg_count);
8736             break;
8737         }
8738         break;
8739       case PushPopRegList:
8740         __ PopSizeRegList(list, reg_size, CPURegister::kVRegister);
8741         break;
8742     }
8743 
8744     // Drop memory to restore the stack pointer.
8745     __ Drop(claim);
8746 
8747     __ Mov(sp, __ StackPointer());
8748     __ SetStackPointer(sp);
8749   }
8750 
8751   END();
8752 
8753   if (CAN_RUN()) {
8754     RUN();
8755 
8756     // Check that the register contents were preserved.
8757     // Always use ASSERT_EQUAL_FP64, even when testing S registers, so we can
8758     // test that the upper word was properly cleared by Pop.
8759     literal_base &= (0xffffffffffffffff >> (64 - reg_size));
8760     for (int i = 0; i < reg_count; i++) {
8761       uint64_t literal = literal_base * i;
8762       double expected;
8763       memcpy(&expected, &literal, sizeof(expected));
8764       ASSERT_EQUAL_FP64(expected, d[i]);
8765     }
8766   }
8767 }
8768 
8769 
8770 TEST(push_pop_fp_xreg_simple_32) {
8771   for (int claim = 0; claim <= 8; claim++) {
8772     for (int count = 0; count <= 8; count++) {
8773       PushPopFPSimpleHelper(count,
8774                             claim,
8775                             kSRegSize,
8776                             PushPopByFour,
8777                             PushPopByFour);
8778       PushPopFPSimpleHelper(count,
8779                             claim,
8780                             kSRegSize,
8781                             PushPopByFour,
8782                             PushPopRegList);
8783       PushPopFPSimpleHelper(count,
8784                             claim,
8785                             kSRegSize,
8786                             PushPopRegList,
8787                             PushPopByFour);
8788       PushPopFPSimpleHelper(count,
8789                             claim,
8790                             kSRegSize,
8791                             PushPopRegList,
8792                             PushPopRegList);
8793     }
8794     // Test with the maximum number of registers.
8795     PushPopFPSimpleHelper(kPushPopFPUseMaxRegCount,
8796                           claim,
8797                           kSRegSize,
8798                           PushPopByFour,
8799                           PushPopByFour);
8800     PushPopFPSimpleHelper(kPushPopFPUseMaxRegCount,
8801                           claim,
8802                           kSRegSize,
8803                           PushPopByFour,
8804                           PushPopRegList);
8805     PushPopFPSimpleHelper(kPushPopFPUseMaxRegCount,
8806                           claim,
8807                           kSRegSize,
8808                           PushPopRegList,
8809                           PushPopByFour);
8810     PushPopFPSimpleHelper(kPushPopFPUseMaxRegCount,
8811                           claim,
8812                           kSRegSize,
8813                           PushPopRegList,
8814                           PushPopRegList);
8815   }
8816 }
8817 
8818 
8819 TEST(push_pop_fp_xreg_simple_64) {
8820   for (int claim = 0; claim <= 8; claim++) {
8821     for (int count = 0; count <= 8; count++) {
8822       PushPopFPSimpleHelper(count,
8823                             claim,
8824                             kDRegSize,
8825                             PushPopByFour,
8826                             PushPopByFour);
8827       PushPopFPSimpleHelper(count,
8828                             claim,
8829                             kDRegSize,
8830                             PushPopByFour,
8831                             PushPopRegList);
8832       PushPopFPSimpleHelper(count,
8833                             claim,
8834                             kDRegSize,
8835                             PushPopRegList,
8836                             PushPopByFour);
8837       PushPopFPSimpleHelper(count,
8838                             claim,
8839                             kDRegSize,
8840                             PushPopRegList,
8841                             PushPopRegList);
8842     }
8843     // Test with the maximum number of registers.
8844     PushPopFPSimpleHelper(kPushPopFPUseMaxRegCount,
8845                           claim,
8846                           kDRegSize,
8847                           PushPopByFour,
8848                           PushPopByFour);
8849     PushPopFPSimpleHelper(kPushPopFPUseMaxRegCount,
8850                           claim,
8851                           kDRegSize,
8852                           PushPopByFour,
8853                           PushPopRegList);
8854     PushPopFPSimpleHelper(kPushPopFPUseMaxRegCount,
8855                           claim,
8856                           kDRegSize,
8857                           PushPopRegList,
8858                           PushPopByFour);
8859     PushPopFPSimpleHelper(kPushPopFPUseMaxRegCount,
8860                           claim,
8861                           kDRegSize,
8862                           PushPopRegList,
8863                           PushPopRegList);
8864   }
8865 }
8866 
8867 
8868 // Push and pop data using an overlapping combination of Push/Pop and
8869 // RegList-based methods.
8870 static void PushPopMixedMethodsHelper(int claim, int reg_size) {
8871   SETUP();
8872 
8873   // Arbitrarily pick a register to use as a stack pointer.
8874   const Register& stack_pointer = x5;
8875   const RegList allowed = ~stack_pointer.GetBit();
8876   // Work out which registers to use, based on reg_size.
8877   Register r[10];
8878   Register x[10];
8879   PopulateRegisterArray(NULL, x, r, reg_size, 10, allowed);
8880 
8881   // Calculate some handy register lists.
8882   RegList r0_to_r3 = 0;
8883   for (int i = 0; i <= 3; i++) {
8884     r0_to_r3 |= x[i].GetBit();
8885   }
8886   RegList r4_to_r5 = 0;
8887   for (int i = 4; i <= 5; i++) {
8888     r4_to_r5 |= x[i].GetBit();
8889   }
8890   RegList r6_to_r9 = 0;
8891   for (int i = 6; i <= 9; i++) {
8892     r6_to_r9 |= x[i].GetBit();
8893   }
8894 
8895   // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
8896   UseScratchRegisterScope temps(&masm);
8897   temps.ExcludeAll();
8898 
8899   // The literal base is chosen to have two useful properties:
8900   //  * When multiplied by small values (such as a register index), this value
8901   //    is clearly readable in the result.
8902   //  * The value is not formed from repeating fixed-size smaller values, so it
8903   //    can be used to detect endianness-related errors.
8904   uint64_t literal_base = 0x0100001000100101;
8905 
8906   START();
8907   {
8908     VIXL_ASSERT(__ StackPointer().Is(sp));
8909     __ Mov(stack_pointer, __ StackPointer());
8910     __ SetStackPointer(stack_pointer);
8911 
8912     // Claim memory first, as requested.
8913     __ Claim(claim);
8914 
8915     __ Mov(x[3], literal_base * 3);
8916     __ Mov(x[2], literal_base * 2);
8917     __ Mov(x[1], literal_base * 1);
8918     __ Mov(x[0], literal_base * 0);
8919 
8920     __ PushSizeRegList(r0_to_r3, reg_size);
8921     __ Push(r[3], r[2]);
8922 
8923     Clobber(&masm, r0_to_r3);
8924     __ PopSizeRegList(r0_to_r3, reg_size);
8925 
8926     __ Push(r[2], r[1], r[3], r[0]);
8927 
8928     Clobber(&masm, r4_to_r5);
8929     __ Pop(r[4], r[5]);
8930     Clobber(&masm, r6_to_r9);
8931     __ Pop(r[6], r[7], r[8], r[9]);
8932 
8933     // Drop memory to restore stack_pointer.
8934     __ Drop(claim);
8935 
8936     __ Mov(sp, __ StackPointer());
8937     __ SetStackPointer(sp);
8938   }
8939 
8940   END();
8941 
8942   if (CAN_RUN()) {
8943     RUN();
8944 
8945     // Always use ASSERT_EQUAL_64, even when testing W registers, so we can test
8946     // that the upper word was properly cleared by Pop.
8947     literal_base &= (0xffffffffffffffff >> (64 - reg_size));
8948 
8949     ASSERT_EQUAL_64(literal_base * 3, x[9]);
8950     ASSERT_EQUAL_64(literal_base * 2, x[8]);
8951     ASSERT_EQUAL_64(literal_base * 0, x[7]);
8952     ASSERT_EQUAL_64(literal_base * 3, x[6]);
8953     ASSERT_EQUAL_64(literal_base * 1, x[5]);
8954     ASSERT_EQUAL_64(literal_base * 2, x[4]);
8955   }
8956 }
8957 
8958 
8959 TEST(push_pop_xreg_mixed_methods_64) {
8960   for (int claim = 0; claim <= 8; claim++) {
8961     PushPopMixedMethodsHelper(claim, kXRegSize);
8962   }
8963 }
8964 
8965 
8966 TEST(push_pop_xreg_mixed_methods_32) {
8967   for (int claim = 0; claim <= 8; claim++) {
8968     PushPopMixedMethodsHelper(claim, kWRegSize);
8969   }
8970 }
8971 
8972 
8973 // Push and pop data using overlapping X- and W-sized quantities.
8974 static void PushPopWXOverlapHelper(int reg_count, int claim) {
8975   SETUP();
8976 
8977   // Arbitrarily pick a register to use as a stack pointer.
8978   const Register& stack_pointer = x10;
8979   const RegList allowed = ~stack_pointer.GetBit();
8980   if (reg_count == kPushPopUseMaxRegCount) {
8981     reg_count = CountSetBits(allowed, kNumberOfRegisters);
8982   }
8983   // Work out which registers to use, based on reg_size.
8984   Register w[kNumberOfRegisters];
8985   Register x[kNumberOfRegisters];
8986   RegList list = PopulateRegisterArray(w, x, NULL, 0, reg_count, allowed);
8987 
8988   // The number of W-sized slots we expect to pop. When we pop, we alternate
8989   // between W and X registers, so we need reg_count*1.5 W-sized slots.
8990   int const requested_w_slots = reg_count + reg_count / 2;
8991 
8992   // Track what _should_ be on the stack, using W-sized slots.
8993   static int const kMaxWSlots = kNumberOfRegisters + kNumberOfRegisters / 2;
8994   uint32_t stack[kMaxWSlots];
8995   for (int i = 0; i < kMaxWSlots; i++) {
8996     stack[i] = 0xdeadbeef;
8997   }
8998 
8999   // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
9000   UseScratchRegisterScope temps(&masm);
9001   temps.ExcludeAll();
9002 
9003   // The literal base is chosen to have two useful properties:
9004   //  * When multiplied by small values (such as a register index), this value
9005   //    is clearly readable in the result.
9006   //  * The value is not formed from repeating fixed-size smaller values, so it
9007   //    can be used to detect endianness-related errors.
9008   static uint64_t const literal_base = 0x0100001000100101;
9009   static uint64_t const literal_base_hi = literal_base >> 32;
9010   static uint64_t const literal_base_lo = literal_base & 0xffffffff;
9011   static uint64_t const literal_base_w = literal_base & 0xffffffff;
9012 
9013   START();
9014   {
9015     VIXL_ASSERT(__ StackPointer().Is(sp));
9016     __ Mov(stack_pointer, __ StackPointer());
9017     __ SetStackPointer(stack_pointer);
9018 
9019     // Initialize the registers.
9020     for (int i = 0; i < reg_count; i++) {
9021       // Always write into the X register, to ensure that the upper word is
9022       // properly ignored by Push when testing W registers.
9023       __ Mov(x[i], literal_base * i);
9024     }
9025 
9026     // Claim memory first, as requested.
9027     __ Claim(claim);
9028 
9029     // The push-pop pattern is as follows:
9030     // Push:           Pop:
9031     //  x[0](hi)   ->   w[0]
9032     //  x[0](lo)   ->   x[1](hi)
9033     //  w[1]       ->   x[1](lo)
9034     //  w[1]       ->   w[2]
9035     //  x[2](hi)   ->   x[2](hi)
9036     //  x[2](lo)   ->   x[2](lo)
9037     //  x[2](hi)   ->   w[3]
9038     //  x[2](lo)   ->   x[4](hi)
9039     //  x[2](hi)   ->   x[4](lo)
9040     //  x[2](lo)   ->   w[5]
9041     //  w[3]       ->   x[5](hi)
9042     //  w[3]       ->   x[6](lo)
9043     //  w[3]       ->   w[7]
9044     //  w[3]       ->   x[8](hi)
9045     //  x[4](hi)   ->   x[8](lo)
9046     //  x[4](lo)   ->   w[9]
9047     // ... pattern continues ...
9048     //
9049     // That is, registers are pushed starting with the lower numbers,
9050     // alternating between x and w registers, and pushing i%4+1 copies of each,
9051     // where i is the register number.
9052     // Registers are popped starting with the higher numbers one-by-one,
9053     // alternating between x and w registers, but only popping one at a time.
9054     //
9055     // This pattern provides a wide variety of alignment effects and overlaps.
9056 
9057     // ---- Push ----
9058 
9059     int active_w_slots = 0;
9060     for (int i = 0; active_w_slots < requested_w_slots; i++) {
9061       VIXL_ASSERT(i < reg_count);
9062       // In order to test various arguments to PushMultipleTimes, and to try to
9063       // exercise different alignment and overlap effects, we push each
9064       // register a different number of times.
9065       int times = i % 4 + 1;
9066       if (i & 1) {
9067         // Push odd-numbered registers as W registers.
9068         __ PushMultipleTimes(times, w[i]);
9069         // Fill in the expected stack slots.
9070         for (int j = 0; j < times; j++) {
9071           if (w[i].Is(wzr)) {
9072             // The zero register always writes zeroes.
9073             stack[active_w_slots++] = 0;
9074           } else {
9075             stack[active_w_slots++] = literal_base_w * i;
9076           }
9077         }
9078       } else {
9079         // Push even-numbered registers as X registers.
9080         __ PushMultipleTimes(times, x[i]);
9081         // Fill in the expected stack slots.
9082         for (int j = 0; j < times; j++) {
9083           if (x[i].Is(xzr)) {
9084             // The zero register always writes zeroes.
9085             stack[active_w_slots++] = 0;
9086             stack[active_w_slots++] = 0;
9087           } else {
9088             stack[active_w_slots++] = literal_base_hi * i;
9089             stack[active_w_slots++] = literal_base_lo * i;
9090           }
9091         }
9092       }
9093     }
9094     // Because we were pushing several registers at a time, we probably pushed
9095     // more than we needed to.
9096     if (active_w_slots > requested_w_slots) {
9097       __ Drop((active_w_slots - requested_w_slots) * kWRegSizeInBytes);
9098       // Bump the number of active W-sized slots back to where it should be,
9099       // and fill the empty space with a placeholder value.
9100       do {
9101         stack[active_w_slots--] = 0xdeadbeef;
9102       } while (active_w_slots > requested_w_slots);
9103     }
9104 
9105     // ---- Pop ----
9106 
9107     Clobber(&masm, list);
9108 
9109     // If popping an even number of registers, the first one will be X-sized.
9110     // Otherwise, the first one will be W-sized.
9111     bool next_is_64 = !(reg_count & 1);
9112     for (int i = reg_count - 1; i >= 0; i--) {
9113       if (next_is_64) {
9114         __ Pop(x[i]);
9115         active_w_slots -= 2;
9116       } else {
9117         __ Pop(w[i]);
9118         active_w_slots -= 1;
9119       }
9120       next_is_64 = !next_is_64;
9121     }
9122     VIXL_ASSERT(active_w_slots == 0);
9123 
9124     // Drop memory to restore stack_pointer.
9125     __ Drop(claim);
9126 
9127     __ Mov(sp, __ StackPointer());
9128     __ SetStackPointer(sp);
9129   }
9130 
9131   END();
9132 
9133   if (CAN_RUN()) {
9134     RUN();
9135 
9136     int slot = 0;
9137     for (int i = 0; i < reg_count; i++) {
9138       // Even-numbered registers were written as W registers.
9139       // Odd-numbered registers were written as X registers.
9140       bool expect_64 = (i & 1);
9141       uint64_t expected;
9142 
9143       if (expect_64) {
9144         uint64_t hi = stack[slot++];
9145         uint64_t lo = stack[slot++];
9146         expected = (hi << 32) | lo;
9147       } else {
9148         expected = stack[slot++];
9149       }
9150 
9151       // Always use ASSERT_EQUAL_64, even when testing W registers, so we can
9152       // test that the upper word was properly cleared by Pop.
9153       if (x[i].Is(xzr)) {
9154         ASSERT_EQUAL_64(0, x[i]);
9155       } else {
9156         ASSERT_EQUAL_64(expected, x[i]);
9157       }
9158     }
9159     VIXL_ASSERT(slot == requested_w_slots);
9160   }
9161 }
9162 
9163 
9164 TEST(push_pop_xreg_wx_overlap) {
9165   for (int claim = 0; claim <= 8; claim++) {
9166     for (int count = 1; count <= 8; count++) {
9167       PushPopWXOverlapHelper(count, claim);
9168     }
9169     // Test with the maximum number of registers.
9170     PushPopWXOverlapHelper(kPushPopUseMaxRegCount, claim);
9171   }
9172 }
9173 
9174 
9175 TEST(push_pop_sp) {
9176   SETUP();
9177 
9178   START();
9179 
9180   VIXL_ASSERT(sp.Is(__ StackPointer()));
9181 
9182   // Acquire all temps from the MacroAssembler. They are used arbitrarily below.
9183   UseScratchRegisterScope temps(&masm);
9184   temps.ExcludeAll();
9185 
9186   __ Mov(x3, 0x3333333333333333);
9187   __ Mov(x2, 0x2222222222222222);
9188   __ Mov(x1, 0x1111111111111111);
9189   __ Mov(x0, 0x0000000000000000);
9190   __ Claim(2 * kXRegSizeInBytes);
9191   __ PushXRegList(x0.GetBit() | x1.GetBit() | x2.GetBit() | x3.GetBit());
9192   __ Push(x3, x2);
9193   __ PopXRegList(x0.GetBit() | x1.GetBit() | x2.GetBit() | x3.GetBit());
9194   __ Push(x2, x1, x3, x0);
9195   __ Pop(x4, x5);
9196   __ Pop(x6, x7, x8, x9);
9197 
9198   __ Claim(2 * kXRegSizeInBytes);
9199   __ PushWRegList(w0.GetBit() | w1.GetBit() | w2.GetBit() | w3.GetBit());
9200   __ Push(w3, w1, w2, w0);
9201   __ PopWRegList(w10.GetBit() | w11.GetBit() | w12.GetBit() | w13.GetBit());
9202   __ Pop(w14, w15, w16, w17);
9203 
9204   __ Claim(2 * kXRegSizeInBytes);
9205   __ Push(w2, w2, w1, w1);
9206   __ Push(x3, x3);
9207   __ Pop(w18, w19, w20, w21);
9208   __ Pop(x22, x23);
9209 
9210   __ Claim(2 * kXRegSizeInBytes);
9211   __ PushXRegList(x1.GetBit() | x22.GetBit());
9212   __ PopXRegList(x24.GetBit() | x26.GetBit());
9213 
9214   __ Claim(2 * kXRegSizeInBytes);
9215   __ PushWRegList(w1.GetBit() | w2.GetBit() | w4.GetBit() | w22.GetBit());
9216   __ PopWRegList(w25.GetBit() | w27.GetBit() | w28.GetBit() | w29.GetBit());
9217 
9218   __ Claim(2 * kXRegSizeInBytes);
9219   __ PushXRegList(0);
9220   __ PopXRegList(0);
9221   __ PushXRegList(0xffffffff);
9222   __ PopXRegList(0xffffffff);
9223   __ Drop(12 * kXRegSizeInBytes);
9224   END();
9225 
9226   if (CAN_RUN()) {
9227     RUN();
9228 
9229     ASSERT_EQUAL_64(0x1111111111111111, x3);
9230     ASSERT_EQUAL_64(0x0000000000000000, x2);
9231     ASSERT_EQUAL_64(0x3333333333333333, x1);
9232     ASSERT_EQUAL_64(0x2222222222222222, x0);
9233     ASSERT_EQUAL_64(0x3333333333333333, x9);
9234     ASSERT_EQUAL_64(0x2222222222222222, x8);
9235     ASSERT_EQUAL_64(0x0000000000000000, x7);
9236     ASSERT_EQUAL_64(0x3333333333333333, x6);
9237     ASSERT_EQUAL_64(0x1111111111111111, x5);
9238     ASSERT_EQUAL_64(0x2222222222222222, x4);
9239 
9240     ASSERT_EQUAL_32(0x11111111U, w13);
9241     ASSERT_EQUAL_32(0x33333333U, w12);
9242     ASSERT_EQUAL_32(0x00000000U, w11);
9243     ASSERT_EQUAL_32(0x22222222U, w10);
9244     ASSERT_EQUAL_32(0x11111111U, w17);
9245     ASSERT_EQUAL_32(0x00000000U, w16);
9246     ASSERT_EQUAL_32(0x33333333U, w15);
9247     ASSERT_EQUAL_32(0x22222222U, w14);
9248 
9249     ASSERT_EQUAL_32(0x11111111U, w18);
9250     ASSERT_EQUAL_32(0x11111111U, w19);
9251     ASSERT_EQUAL_32(0x11111111U, w20);
9252     ASSERT_EQUAL_32(0x11111111U, w21);
9253     ASSERT_EQUAL_64(0x3333333333333333, x22);
9254     ASSERT_EQUAL_64(0x0000000000000000, x23);
9255 
9256     ASSERT_EQUAL_64(0x3333333333333333, x24);
9257     ASSERT_EQUAL_64(0x3333333333333333, x26);
9258 
9259     ASSERT_EQUAL_32(0x33333333U, w25);
9260     ASSERT_EQUAL_32(0x00000000U, w27);
9261     ASSERT_EQUAL_32(0x22222222U, w28);
9262     ASSERT_EQUAL_32(0x33333333U, w29);
9263   }
9264 }
9265 
9266 
9267 TEST(printf) {
9268   // RegisterDump::Dump uses NEON.
9269   // Printf uses FP to cast FP arguments to doubles.
9270   SETUP_WITH_FEATURES(CPUFeatures::kNEON, CPUFeatures::kFP);
9271 
9272   START();
9273 
9274   char const* test_plain_string = "Printf with no arguments.\n";
9275   char const* test_substring = "'This is a substring.'";
9276   RegisterDump before;
9277 
9278   // Initialize x29 to the value of the stack pointer. We will use x29 as a
9279   // temporary stack pointer later, and initializing it in this way allows the
9280   // RegisterDump check to pass.
9281   __ Mov(x29, __ StackPointer());
9282 
9283   // Test simple integer arguments.
9284   __ Mov(x0, 1234);
9285   __ Mov(x1, 0x1234);
9286 
9287   // Test simple floating-point arguments.
9288   __ Fmov(d0, 1.234);
9289 
9290   // Test pointer (string) arguments.
9291   __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
9292 
9293   // Test the maximum number of arguments, and sign extension.
9294   __ Mov(w3, 0xffffffff);
9295   __ Mov(w4, 0xffffffff);
9296   __ Mov(x5, 0xffffffffffffffff);
9297   __ Mov(x6, 0xffffffffffffffff);
9298   __ Fmov(s1, 1.234);
9299   __ Fmov(s2, 2.345);
9300   __ Fmov(d3, 3.456);
9301   __ Fmov(d4, 4.567);
9302 
9303   // Test printing callee-saved registers.
9304   __ Mov(x28, 0x123456789abcdef);
9305   __ Fmov(d10, 42.0);
9306 
9307   // Test with three arguments.
9308   __ Mov(x10, 3);
9309   __ Mov(x11, 40);
9310   __ Mov(x12, 500);
9311 
9312   // A single character.
9313   __ Mov(w13, 'x');
9314 
9315   // Check that we don't clobber any registers.
9316   before.Dump(&masm);
9317 
9318   __ Printf(test_plain_string);  // NOLINT(runtime/printf)
9319   __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
9320   __ Printf("w5: %" PRId32 ", x5: %" PRId64 "\n", w5, x5);
9321   __ Printf("d0: %f\n", d0);
9322   __ Printf("Test %%s: %s\n", x2);
9323   __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32
9324             "\n"
9325             "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
9326             w3,
9327             w4,
9328             x5,
9329             x6);
9330   __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
9331   __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
9332   __ Printf("%g\n", d10);
9333   __ Printf("%%%%%s%%%c%%\n", x2, w13);
9334 
9335   // Print the stack pointer (sp).
9336   __ Printf("StackPointer(sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
9337             __ StackPointer(),
9338             __ StackPointer().W());
9339 
9340   // Test with a different stack pointer.
9341   const Register old_stack_pointer = __ StackPointer();
9342   __ Mov(x29, old_stack_pointer);
9343   __ SetStackPointer(x29);
9344   // Print the stack pointer (not sp).
9345   __ Printf("StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n",
9346             __ StackPointer(),
9347             __ StackPointer().W());
9348   __ Mov(old_stack_pointer, __ StackPointer());
9349   __ SetStackPointer(old_stack_pointer);
9350 
9351   // Test with three arguments.
9352   __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
9353 
9354   // Mixed argument types.
9355   __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
9356             w3,
9357             s1,
9358             x5,
9359             d3);
9360   __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n",
9361             s1,
9362             d3,
9363             w3,
9364             x5);
9365 
9366   END();
9367   if (CAN_RUN()) {
9368     RUN();
9369 
9370     // We cannot easily test the output of the Printf sequences, and because
9371     // Printf preserves all registers by default, we can't look at the number of
9372     // bytes that were printed. However, the printf_no_preserve test should
9373     // check
9374     // that, and here we just test that we didn't clobber any registers.
9375     ASSERT_EQUAL_REGISTERS(before);
9376   }
9377 }
9378 
9379 
9380 TEST(printf_no_preserve) {
9381   // PrintfNoPreserve uses FP to cast FP arguments to doubles.
9382   SETUP_WITH_FEATURES(CPUFeatures::kFP);
9383 
9384   START();
9385 
9386   char const* test_plain_string = "Printf with no arguments.\n";
9387   char const* test_substring = "'This is a substring.'";
9388 
9389   __ PrintfNoPreserve(test_plain_string);
9390   __ Mov(x19, x0);
9391 
9392   // Test simple integer arguments.
9393   __ Mov(x0, 1234);
9394   __ Mov(x1, 0x1234);
9395   __ PrintfNoPreserve("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
9396   __ Mov(x20, x0);
9397 
9398   // Test simple floating-point arguments.
9399   __ Fmov(d0, 1.234);
9400   __ PrintfNoPreserve("d0: %f\n", d0);
9401   __ Mov(x21, x0);
9402 
9403   // Test pointer (string) arguments.
9404   __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
9405   __ PrintfNoPreserve("Test %%s: %s\n", x2);
9406   __ Mov(x22, x0);
9407 
9408   // Test the maximum number of arguments, and sign extension.
9409   __ Mov(w3, 0xffffffff);
9410   __ Mov(w4, 0xffffffff);
9411   __ Mov(x5, 0xffffffffffffffff);
9412   __ Mov(x6, 0xffffffffffffffff);
9413   __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32
9414                       "\n"
9415                       "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
9416                       w3,
9417                       w4,
9418                       x5,
9419                       x6);
9420   __ Mov(x23, x0);
9421 
9422   __ Fmov(s1, 1.234);
9423   __ Fmov(s2, 2.345);
9424   __ Fmov(d3, 3.456);
9425   __ Fmov(d4, 4.567);
9426   __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
9427   __ Mov(x24, x0);
9428 
9429   // Test printing callee-saved registers.
9430   __ Mov(x28, 0x123456789abcdef);
9431   __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
9432   __ Mov(x25, x0);
9433 
9434   __ Fmov(d10, 42.0);
9435   __ PrintfNoPreserve("%g\n", d10);
9436   __ Mov(x26, x0);
9437 
9438   // Test with a different stack pointer.
9439   const Register old_stack_pointer = __ StackPointer();
9440   __ Mov(x29, old_stack_pointer);
9441   __ SetStackPointer(x29);
9442   // Print the stack pointer (not sp).
9443   __ PrintfNoPreserve("StackPointer(not sp): 0x%016" PRIx64 ", 0x%08" PRIx32
9444                       "\n",
9445                       __ StackPointer(),
9446                       __ StackPointer().W());
9447   __ Mov(x27, x0);
9448   __ Mov(old_stack_pointer, __ StackPointer());
9449   __ SetStackPointer(old_stack_pointer);
9450 
9451   // Test with three arguments.
9452   __ Mov(x3, 3);
9453   __ Mov(x4, 40);
9454   __ Mov(x5, 500);
9455   __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
9456   __ Mov(x28, x0);
9457 
9458   // Mixed argument types.
9459   __ Mov(w3, 0xffffffff);
9460   __ Fmov(s1, 1.234);
9461   __ Mov(x5, 0xffffffffffffffff);
9462   __ Fmov(d3, 3.456);
9463   __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n",
9464                       w3,
9465                       s1,
9466                       x5,
9467                       d3);
9468   __ Mov(x29, x0);
9469 
9470   END();
9471   if (CAN_RUN()) {
9472     RUN();
9473 
9474     // We cannot easily test the exact output of the Printf sequences, but we
9475     // can
9476     // use the return code to check that the string length was correct.
9477 
9478     // Printf with no arguments.
9479     ASSERT_EQUAL_64(strlen(test_plain_string), x19);
9480     // x0: 1234, x1: 0x00001234
9481     ASSERT_EQUAL_64(25, x20);
9482     // d0: 1.234000
9483     ASSERT_EQUAL_64(13, x21);
9484     // Test %s: 'This is a substring.'
9485     ASSERT_EQUAL_64(32, x22);
9486     // w3(uint32): 4294967295
9487     // w4(int32): -1
9488     // x5(uint64): 18446744073709551615
9489     // x6(int64): -1
9490     ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23);
9491     // %f: 1.234000
9492     // %g: 2.345
9493     // %e: 3.456000e+00
9494     // %E: 4.567000E+00
9495     ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24);
9496     // 0x89abcdef, 0x123456789abcdef
9497     ASSERT_EQUAL_64(30, x25);
9498     // 42
9499     ASSERT_EQUAL_64(3, x26);
9500     // StackPointer(not sp): 0x00007fb037ae2370, 0x37ae2370
9501     // Note: This is an example value, but the field width is fixed here so the
9502     // string length is still predictable.
9503     ASSERT_EQUAL_64(53, x27);
9504     // 3=3, 4=40, 5=500
9505     ASSERT_EQUAL_64(17, x28);
9506     // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
9507     ASSERT_EQUAL_64(69, x29);
9508   }
9509 }
9510 
9511 
9512 TEST(trace) {
9513   // The Trace helper should not generate any code unless the simulator is being
9514   // used.
9515   SETUP();
9516   START();
9517 
9518   Label start;
9519   __ Bind(&start);
9520   __ Trace(LOG_ALL, TRACE_ENABLE);
9521   __ Trace(LOG_ALL, TRACE_DISABLE);
9522   if (masm.GenerateSimulatorCode()) {
9523     VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&start) > 0);
9524   } else {
9525     VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&start) == 0);
9526   }
9527 
9528   END();
9529 }
9530 
9531 
9532 TEST(log) {
9533   // The Log helper should not generate any code unless the simulator is being
9534   // used.
9535   SETUP();
9536   START();
9537 
9538   Label start;
9539   __ Bind(&start);
9540   __ Log(LOG_ALL);
9541   if (masm.GenerateSimulatorCode()) {
9542     VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&start) > 0);
9543   } else {
9544     VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&start) == 0);
9545   }
9546 
9547   END();
9548 }
9549 
9550 
9551 TEST(blr_lr) {
9552   // A simple test to check that the simulator correctly handle "blr lr".
9553   SETUP();
9554 
9555   START();
9556   Label target;
9557   Label end;
9558 
9559   __ Mov(x0, 0x0);
9560   __ Adr(lr, &target);
9561 
9562   __ Blr(lr);
9563   __ Mov(x0, 0xdeadbeef);
9564   __ B(&end);
9565 
9566   __ Bind(&target);
9567   __ Mov(x0, 0xc001c0de);
9568 
9569   __ Bind(&end);
9570   END();
9571 
9572   if (CAN_RUN()) {
9573     RUN();
9574 
9575     ASSERT_EQUAL_64(0xc001c0de, x0);
9576   }
9577 }
9578 
9579 
9580 TEST(barriers) {
9581   // Generate all supported barriers, this is just a smoke test
9582   SETUP();
9583 
9584   START();
9585 
9586   // DMB
9587   __ Dmb(FullSystem, BarrierAll);
9588   __ Dmb(FullSystem, BarrierReads);
9589   __ Dmb(FullSystem, BarrierWrites);
9590   __ Dmb(FullSystem, BarrierOther);
9591 
9592   __ Dmb(InnerShareable, BarrierAll);
9593   __ Dmb(InnerShareable, BarrierReads);
9594   __ Dmb(InnerShareable, BarrierWrites);
9595   __ Dmb(InnerShareable, BarrierOther);
9596 
9597   __ Dmb(NonShareable, BarrierAll);
9598   __ Dmb(NonShareable, BarrierReads);
9599   __ Dmb(NonShareable, BarrierWrites);
9600   __ Dmb(NonShareable, BarrierOther);
9601 
9602   __ Dmb(OuterShareable, BarrierAll);
9603   __ Dmb(OuterShareable, BarrierReads);
9604   __ Dmb(OuterShareable, BarrierWrites);
9605   __ Dmb(OuterShareable, BarrierOther);
9606 
9607   // DSB
9608   __ Dsb(FullSystem, BarrierAll);
9609   __ Dsb(FullSystem, BarrierReads);
9610   __ Dsb(FullSystem, BarrierWrites);
9611   __ Dsb(FullSystem, BarrierOther);
9612 
9613   __ Dsb(InnerShareable, BarrierAll);
9614   __ Dsb(InnerShareable, BarrierReads);
9615   __ Dsb(InnerShareable, BarrierWrites);
9616   __ Dsb(InnerShareable, BarrierOther);
9617 
9618   __ Dsb(NonShareable, BarrierAll);
9619   __ Dsb(NonShareable, BarrierReads);
9620   __ Dsb(NonShareable, BarrierWrites);
9621   __ Dsb(NonShareable, BarrierOther);
9622 
9623   __ Dsb(OuterShareable, BarrierAll);
9624   __ Dsb(OuterShareable, BarrierReads);
9625   __ Dsb(OuterShareable, BarrierWrites);
9626   __ Dsb(OuterShareable, BarrierOther);
9627 
9628   // ISB
9629   __ Isb();
9630 
9631   END();
9632 
9633   if (CAN_RUN()) {
9634     RUN();
9635   }
9636 }
9637 
9638 
9639 TEST(ldar_stlr) {
9640   // The middle value is read, modified, and written. The padding exists only to
9641   // check for over-write.
9642   uint8_t b[] = {0, 0x12, 0};
9643   uint16_t h[] = {0, 0x1234, 0};
9644   uint32_t w[] = {0, 0x12345678, 0};
9645   uint64_t x[] = {0, 0x123456789abcdef0, 0};
9646 
9647   SETUP();
9648   START();
9649 
9650   __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
9651   __ Ldarb(w0, MemOperand(x10));
9652   __ Add(w0, w0, 1);
9653   __ Stlrb(w0, MemOperand(x10));
9654 
9655   __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
9656   __ Ldarh(w0, MemOperand(x10));
9657   __ Add(w0, w0, 1);
9658   __ Stlrh(w0, MemOperand(x10));
9659 
9660   __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
9661   __ Ldar(w0, MemOperand(x10));
9662   __ Add(w0, w0, 1);
9663   __ Stlr(w0, MemOperand(x10));
9664 
9665   __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
9666   __ Ldar(x0, MemOperand(x10));
9667   __ Add(x0, x0, 1);
9668   __ Stlr(x0, MemOperand(x10));
9669 
9670   END();
9671   if (CAN_RUN()) {
9672     RUN();
9673 
9674     ASSERT_EQUAL_32(0x13, b[1]);
9675     ASSERT_EQUAL_32(0x1235, h[1]);
9676     ASSERT_EQUAL_32(0x12345679, w[1]);
9677     ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
9678 
9679     // Check for over-write.
9680     ASSERT_EQUAL_32(0, b[0]);
9681     ASSERT_EQUAL_32(0, b[2]);
9682     ASSERT_EQUAL_32(0, h[0]);
9683     ASSERT_EQUAL_32(0, h[2]);
9684     ASSERT_EQUAL_32(0, w[0]);
9685     ASSERT_EQUAL_32(0, w[2]);
9686     ASSERT_EQUAL_64(0, x[0]);
9687     ASSERT_EQUAL_64(0, x[2]);
9688   }
9689 }
9690 
9691 
9692 TEST(ldlar_stllr) {
9693   // The middle value is read, modified, and written. The padding exists only to
9694   // check for over-write.
9695   uint8_t b[] = {0, 0x12, 0};
9696   uint16_t h[] = {0, 0x1234, 0};
9697   uint32_t w[] = {0, 0x12345678, 0};
9698   uint64_t x[] = {0, 0x123456789abcdef0, 0};
9699 
9700   SETUP_WITH_FEATURES(CPUFeatures::kLORegions);
9701 
9702   START();
9703 
9704   __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
9705   __ Ldlarb(w0, MemOperand(x10));
9706   __ Add(w0, w0, 1);
9707   __ Stllrb(w0, MemOperand(x10));
9708 
9709   __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
9710   __ Ldlarh(w0, MemOperand(x10));
9711   __ Add(w0, w0, 1);
9712   __ Stllrh(w0, MemOperand(x10));
9713 
9714   __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
9715   __ Ldlar(w0, MemOperand(x10));
9716   __ Add(w0, w0, 1);
9717   __ Stllr(w0, MemOperand(x10));
9718 
9719   __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
9720   __ Ldlar(x0, MemOperand(x10));
9721   __ Add(x0, x0, 1);
9722   __ Stllr(x0, MemOperand(x10));
9723 
9724   END();
9725 
9726   if (CAN_RUN()) {
9727     RUN();
9728 
9729     ASSERT_EQUAL_32(0x13, b[1]);
9730     ASSERT_EQUAL_32(0x1235, h[1]);
9731     ASSERT_EQUAL_32(0x12345679, w[1]);
9732     ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
9733 
9734     // Check for over-write.
9735     ASSERT_EQUAL_32(0, b[0]);
9736     ASSERT_EQUAL_32(0, b[2]);
9737     ASSERT_EQUAL_32(0, h[0]);
9738     ASSERT_EQUAL_32(0, h[2]);
9739     ASSERT_EQUAL_32(0, w[0]);
9740     ASSERT_EQUAL_32(0, w[2]);
9741     ASSERT_EQUAL_64(0, x[0]);
9742     ASSERT_EQUAL_64(0, x[2]);
9743   }
9744 }
9745 
9746 
9747 TEST(ldxr_stxr) {
9748   // The middle value is read, modified, and written. The padding exists only to
9749   // check for over-write.
9750   uint8_t b[] = {0, 0x12, 0};
9751   uint16_t h[] = {0, 0x1234, 0};
9752   uint32_t w[] = {0, 0x12345678, 0};
9753   uint64_t x[] = {0, 0x123456789abcdef0, 0};
9754 
9755   // As above, but get suitably-aligned values for ldxp and stxp.
9756   uint32_t wp_data[] = {0, 0, 0, 0, 0};
9757   uint32_t* wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
9758   wp[1] = 0x12345678;  // wp[1] is 64-bit-aligned.
9759   wp[2] = 0x87654321;
9760   uint64_t xp_data[] = {0, 0, 0, 0, 0};
9761   uint64_t* xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
9762   xp[1] = 0x123456789abcdef0;  // xp[1] is 128-bit-aligned.
9763   xp[2] = 0x0fedcba987654321;
9764 
9765   SETUP();
9766   START();
9767 
9768   __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
9769   Label try_b;
9770   __ Bind(&try_b);
9771   __ Ldxrb(w0, MemOperand(x10));
9772   __ Add(w0, w0, 1);
9773   __ Stxrb(w5, w0, MemOperand(x10));
9774   __ Cbnz(w5, &try_b);
9775 
9776   __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
9777   Label try_h;
9778   __ Bind(&try_h);
9779   __ Ldxrh(w0, MemOperand(x10));
9780   __ Add(w0, w0, 1);
9781   __ Stxrh(w5, w0, MemOperand(x10));
9782   __ Cbnz(w5, &try_h);
9783 
9784   __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
9785   Label try_w;
9786   __ Bind(&try_w);
9787   __ Ldxr(w0, MemOperand(x10));
9788   __ Add(w0, w0, 1);
9789   __ Stxr(w5, w0, MemOperand(x10));
9790   __ Cbnz(w5, &try_w);
9791 
9792   __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
9793   Label try_x;
9794   __ Bind(&try_x);
9795   __ Ldxr(x0, MemOperand(x10));
9796   __ Add(x0, x0, 1);
9797   __ Stxr(w5, x0, MemOperand(x10));
9798   __ Cbnz(w5, &try_x);
9799 
9800   __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
9801   Label try_wp;
9802   __ Bind(&try_wp);
9803   __ Ldxp(w0, w1, MemOperand(x10));
9804   __ Add(w0, w0, 1);
9805   __ Add(w1, w1, 1);
9806   __ Stxp(w5, w0, w1, MemOperand(x10));
9807   __ Cbnz(w5, &try_wp);
9808 
9809   __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
9810   Label try_xp;
9811   __ Bind(&try_xp);
9812   __ Ldxp(x0, x1, MemOperand(x10));
9813   __ Add(x0, x0, 1);
9814   __ Add(x1, x1, 1);
9815   __ Stxp(w5, x0, x1, MemOperand(x10));
9816   __ Cbnz(w5, &try_xp);
9817 
9818   END();
9819   if (CAN_RUN()) {
9820     RUN();
9821 
9822     ASSERT_EQUAL_32(0x13, b[1]);
9823     ASSERT_EQUAL_32(0x1235, h[1]);
9824     ASSERT_EQUAL_32(0x12345679, w[1]);
9825     ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
9826     ASSERT_EQUAL_32(0x12345679, wp[1]);
9827     ASSERT_EQUAL_32(0x87654322, wp[2]);
9828     ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
9829     ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
9830 
9831     // Check for over-write.
9832     ASSERT_EQUAL_32(0, b[0]);
9833     ASSERT_EQUAL_32(0, b[2]);
9834     ASSERT_EQUAL_32(0, h[0]);
9835     ASSERT_EQUAL_32(0, h[2]);
9836     ASSERT_EQUAL_32(0, w[0]);
9837     ASSERT_EQUAL_32(0, w[2]);
9838     ASSERT_EQUAL_64(0, x[0]);
9839     ASSERT_EQUAL_64(0, x[2]);
9840     ASSERT_EQUAL_32(0, wp[0]);
9841     ASSERT_EQUAL_32(0, wp[3]);
9842     ASSERT_EQUAL_64(0, xp[0]);
9843     ASSERT_EQUAL_64(0, xp[3]);
9844   }
9845 }
9846 
9847 
9848 TEST(ldaxr_stlxr) {
9849   // The middle value is read, modified, and written. The padding exists only to
9850   // check for over-write.
9851   uint8_t b[] = {0, 0x12, 0};
9852   uint16_t h[] = {0, 0x1234, 0};
9853   uint32_t w[] = {0, 0x12345678, 0};
9854   uint64_t x[] = {0, 0x123456789abcdef0, 0};
9855 
9856   // As above, but get suitably-aligned values for ldxp and stxp.
9857   uint32_t wp_data[] = {0, 0, 0, 0, 0};
9858   uint32_t* wp = AlignUp(wp_data + 1, kWRegSizeInBytes * 2) - 1;
9859   wp[1] = 0x12345678;  // wp[1] is 64-bit-aligned.
9860   wp[2] = 0x87654321;
9861   uint64_t xp_data[] = {0, 0, 0, 0, 0};
9862   uint64_t* xp = AlignUp(xp_data + 1, kXRegSizeInBytes * 2) - 1;
9863   xp[1] = 0x123456789abcdef0;  // xp[1] is 128-bit-aligned.
9864   xp[2] = 0x0fedcba987654321;
9865 
9866   SETUP();
9867   START();
9868 
9869   __ Mov(x10, reinterpret_cast<uintptr_t>(&b[1]));
9870   Label try_b;
9871   __ Bind(&try_b);
9872   __ Ldaxrb(w0, MemOperand(x10));
9873   __ Add(w0, w0, 1);
9874   __ Stlxrb(w5, w0, MemOperand(x10));
9875   __ Cbnz(w5, &try_b);
9876 
9877   __ Mov(x10, reinterpret_cast<uintptr_t>(&h[1]));
9878   Label try_h;
9879   __ Bind(&try_h);
9880   __ Ldaxrh(w0, MemOperand(x10));
9881   __ Add(w0, w0, 1);
9882   __ Stlxrh(w5, w0, MemOperand(x10));
9883   __ Cbnz(w5, &try_h);
9884 
9885   __ Mov(x10, reinterpret_cast<uintptr_t>(&w[1]));
9886   Label try_w;
9887   __ Bind(&try_w);
9888   __ Ldaxr(w0, MemOperand(x10));
9889   __ Add(w0, w0, 1);
9890   __ Stlxr(w5, w0, MemOperand(x10));
9891   __ Cbnz(w5, &try_w);
9892 
9893   __ Mov(x10, reinterpret_cast<uintptr_t>(&x[1]));
9894   Label try_x;
9895   __ Bind(&try_x);
9896   __ Ldaxr(x0, MemOperand(x10));
9897   __ Add(x0, x0, 1);
9898   __ Stlxr(w5, x0, MemOperand(x10));
9899   __ Cbnz(w5, &try_x);
9900 
9901   __ Mov(x10, reinterpret_cast<uintptr_t>(&wp[1]));
9902   Label try_wp;
9903   __ Bind(&try_wp);
9904   __ Ldaxp(w0, w1, MemOperand(x10));
9905   __ Add(w0, w0, 1);
9906   __ Add(w1, w1, 1);
9907   __ Stlxp(w5, w0, w1, MemOperand(x10));
9908   __ Cbnz(w5, &try_wp);
9909 
9910   __ Mov(x10, reinterpret_cast<uintptr_t>(&xp[1]));
9911   Label try_xp;
9912   __ Bind(&try_xp);
9913   __ Ldaxp(x0, x1, MemOperand(x10));
9914   __ Add(x0, x0, 1);
9915   __ Add(x1, x1, 1);
9916   __ Stlxp(w5, x0, x1, MemOperand(x10));
9917   __ Cbnz(w5, &try_xp);
9918 
9919   END();
9920   if (CAN_RUN()) {
9921     RUN();
9922 
9923     ASSERT_EQUAL_32(0x13, b[1]);
9924     ASSERT_EQUAL_32(0x1235, h[1]);
9925     ASSERT_EQUAL_32(0x12345679, w[1]);
9926     ASSERT_EQUAL_64(0x123456789abcdef1, x[1]);
9927     ASSERT_EQUAL_32(0x12345679, wp[1]);
9928     ASSERT_EQUAL_32(0x87654322, wp[2]);
9929     ASSERT_EQUAL_64(0x123456789abcdef1, xp[1]);
9930     ASSERT_EQUAL_64(0x0fedcba987654322, xp[2]);
9931 
9932     // Check for over-write.
9933     ASSERT_EQUAL_32(0, b[0]);
9934     ASSERT_EQUAL_32(0, b[2]);
9935     ASSERT_EQUAL_32(0, h[0]);
9936     ASSERT_EQUAL_32(0, h[2]);
9937     ASSERT_EQUAL_32(0, w[0]);
9938     ASSERT_EQUAL_32(0, w[2]);
9939     ASSERT_EQUAL_64(0, x[0]);
9940     ASSERT_EQUAL_64(0, x[2]);
9941     ASSERT_EQUAL_32(0, wp[0]);
9942     ASSERT_EQUAL_32(0, wp[3]);
9943     ASSERT_EQUAL_64(0, xp[0]);
9944     ASSERT_EQUAL_64(0, xp[3]);
9945   }
9946 }
9947 
9948 
9949 TEST(clrex) {
9950   // This data should never be written.
9951   uint64_t data[] = {0, 0, 0};
9952   uint64_t* data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
9953 
9954   SETUP();
9955   START();
9956 
9957   __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
9958   __ Mov(w6, 0);
9959 
9960   __ Ldxrb(w0, MemOperand(x10));
9961   __ Clrex();
9962   __ Add(w0, w0, 1);
9963   __ Stxrb(w5, w0, MemOperand(x10));
9964   __ Add(w6, w6, w5);
9965 
9966   __ Ldxrh(w0, MemOperand(x10));
9967   __ Clrex();
9968   __ Add(w0, w0, 1);
9969   __ Stxrh(w5, w0, MemOperand(x10));
9970   __ Add(w6, w6, w5);
9971 
9972   __ Ldxr(w0, MemOperand(x10));
9973   __ Clrex();
9974   __ Add(w0, w0, 1);
9975   __ Stxr(w5, w0, MemOperand(x10));
9976   __ Add(w6, w6, w5);
9977 
9978   __ Ldxr(x0, MemOperand(x10));
9979   __ Clrex();
9980   __ Add(x0, x0, 1);
9981   __ Stxr(w5, x0, MemOperand(x10));
9982   __ Add(w6, w6, w5);
9983 
9984   __ Ldxp(w0, w1, MemOperand(x10));
9985   __ Clrex();
9986   __ Add(w0, w0, 1);
9987   __ Add(w1, w1, 1);
9988   __ Stxp(w5, w0, w1, MemOperand(x10));
9989   __ Add(w6, w6, w5);
9990 
9991   __ Ldxp(x0, x1, MemOperand(x10));
9992   __ Clrex();
9993   __ Add(x0, x0, 1);
9994   __ Add(x1, x1, 1);
9995   __ Stxp(w5, x0, x1, MemOperand(x10));
9996   __ Add(w6, w6, w5);
9997 
9998   // Acquire-release variants.
9999 
10000   __ Ldaxrb(w0, MemOperand(x10));
10001   __ Clrex();
10002   __ Add(w0, w0, 1);
10003   __ Stlxrb(w5, w0, MemOperand(x10));
10004   __ Add(w6, w6, w5);
10005 
10006   __ Ldaxrh(w0, MemOperand(x10));
10007   __ Clrex();
10008   __ Add(w0, w0, 1);
10009   __ Stlxrh(w5, w0, MemOperand(x10));
10010   __ Add(w6, w6, w5);
10011 
10012   __ Ldaxr(w0, MemOperand(x10));
10013   __ Clrex();
10014   __ Add(w0, w0, 1);
10015   __ Stlxr(w5, w0, MemOperand(x10));
10016   __ Add(w6, w6, w5);
10017 
10018   __ Ldaxr(x0, MemOperand(x10));
10019   __ Clrex();
10020   __ Add(x0, x0, 1);
10021   __ Stlxr(w5, x0, MemOperand(x10));
10022   __ Add(w6, w6, w5);
10023 
10024   __ Ldaxp(w0, w1, MemOperand(x10));
10025   __ Clrex();
10026   __ Add(w0, w0, 1);
10027   __ Add(w1, w1, 1);
10028   __ Stlxp(w5, w0, w1, MemOperand(x10));
10029   __ Add(w6, w6, w5);
10030 
10031   __ Ldaxp(x0, x1, MemOperand(x10));
10032   __ Clrex();
10033   __ Add(x0, x0, 1);
10034   __ Add(x1, x1, 1);
10035   __ Stlxp(w5, x0, x1, MemOperand(x10));
10036   __ Add(w6, w6, w5);
10037 
10038   END();
10039   if (CAN_RUN()) {
10040     RUN();
10041 
10042     // None of the 12 store-exclusives should have succeeded.
10043     ASSERT_EQUAL_32(12, w6);
10044 
10045     ASSERT_EQUAL_64(0, data[0]);
10046     ASSERT_EQUAL_64(0, data[1]);
10047     ASSERT_EQUAL_64(0, data[2]);
10048   }
10049 }
10050 
10051 
10052 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
10053 // Check that the simulator occasionally makes store-exclusive fail.
10054 TEST(ldxr_stxr_fail) {
10055   uint64_t data[] = {0, 0, 0};
10056   uint64_t* data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
10057 
10058   // Impose a hard limit on the number of attempts, so the test cannot hang.
10059   static const uint64_t kWatchdog = 10000;
10060   Label done;
10061 
10062   SETUP();
10063   START();
10064 
10065   __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
10066   __ Mov(x11, kWatchdog);
10067 
10068   // This loop is the opposite of what we normally do with ldxr and stxr; we
10069   // keep trying until we fail (or the watchdog counter runs out).
10070   Label try_b;
10071   __ Bind(&try_b);
10072   __ Ldxrb(w0, MemOperand(x10));
10073   __ Stxrb(w5, w0, MemOperand(x10));
10074   // Check the watchdog counter.
10075   __ Sub(x11, x11, 1);
10076   __ Cbz(x11, &done);
10077   // Check the exclusive-store result.
10078   __ Cbz(w5, &try_b);
10079 
10080   Label try_h;
10081   __ Bind(&try_h);
10082   __ Ldxrh(w0, MemOperand(x10));
10083   __ Stxrh(w5, w0, MemOperand(x10));
10084   __ Sub(x11, x11, 1);
10085   __ Cbz(x11, &done);
10086   __ Cbz(w5, &try_h);
10087 
10088   Label try_w;
10089   __ Bind(&try_w);
10090   __ Ldxr(w0, MemOperand(x10));
10091   __ Stxr(w5, w0, MemOperand(x10));
10092   __ Sub(x11, x11, 1);
10093   __ Cbz(x11, &done);
10094   __ Cbz(w5, &try_w);
10095 
10096   Label try_x;
10097   __ Bind(&try_x);
10098   __ Ldxr(x0, MemOperand(x10));
10099   __ Stxr(w5, x0, MemOperand(x10));
10100   __ Sub(x11, x11, 1);
10101   __ Cbz(x11, &done);
10102   __ Cbz(w5, &try_x);
10103 
10104   Label try_wp;
10105   __ Bind(&try_wp);
10106   __ Ldxp(w0, w1, MemOperand(x10));
10107   __ Stxp(w5, w0, w1, MemOperand(x10));
10108   __ Sub(x11, x11, 1);
10109   __ Cbz(x11, &done);
10110   __ Cbz(w5, &try_wp);
10111 
10112   Label try_xp;
10113   __ Bind(&try_xp);
10114   __ Ldxp(x0, x1, MemOperand(x10));
10115   __ Stxp(w5, x0, x1, MemOperand(x10));
10116   __ Sub(x11, x11, 1);
10117   __ Cbz(x11, &done);
10118   __ Cbz(w5, &try_xp);
10119 
10120   __ Bind(&done);
10121   // Trigger an error if x11 (watchdog) is zero.
10122   __ Cmp(x11, 0);
10123   __ Cset(x12, eq);
10124 
10125   END();
10126   if (CAN_RUN()) {
10127     RUN();
10128 
10129     // Check that the watchdog counter didn't run out.
10130     ASSERT_EQUAL_64(0, x12);
10131   }
10132 }
10133 #endif
10134 
10135 
10136 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
10137 // Check that the simulator occasionally makes store-exclusive fail.
10138 TEST(ldaxr_stlxr_fail) {
10139   uint64_t data[] = {0, 0, 0};
10140   uint64_t* data_aligned = AlignUp(data, kXRegSizeInBytes * 2);
10141 
10142   // Impose a hard limit on the number of attempts, so the test cannot hang.
10143   static const uint64_t kWatchdog = 10000;
10144   Label done;
10145 
10146   SETUP();
10147   START();
10148 
10149   __ Mov(x10, reinterpret_cast<uintptr_t>(data_aligned));
10150   __ Mov(x11, kWatchdog);
10151 
10152   // This loop is the opposite of what we normally do with ldxr and stxr; we
10153   // keep trying until we fail (or the watchdog counter runs out).
10154   Label try_b;
10155   __ Bind(&try_b);
10156   __ Ldxrb(w0, MemOperand(x10));
10157   __ Stxrb(w5, w0, MemOperand(x10));
10158   // Check the watchdog counter.
10159   __ Sub(x11, x11, 1);
10160   __ Cbz(x11, &done);
10161   // Check the exclusive-store result.
10162   __ Cbz(w5, &try_b);
10163 
10164   Label try_h;
10165   __ Bind(&try_h);
10166   __ Ldaxrh(w0, MemOperand(x10));
10167   __ Stlxrh(w5, w0, MemOperand(x10));
10168   __ Sub(x11, x11, 1);
10169   __ Cbz(x11, &done);
10170   __ Cbz(w5, &try_h);
10171 
10172   Label try_w;
10173   __ Bind(&try_w);
10174   __ Ldaxr(w0, MemOperand(x10));
10175   __ Stlxr(w5, w0, MemOperand(x10));
10176   __ Sub(x11, x11, 1);
10177   __ Cbz(x11, &done);
10178   __ Cbz(w5, &try_w);
10179 
10180   Label try_x;
10181   __ Bind(&try_x);
10182   __ Ldaxr(x0, MemOperand(x10));
10183   __ Stlxr(w5, x0, MemOperand(x10));
10184   __ Sub(x11, x11, 1);
10185   __ Cbz(x11, &done);
10186   __ Cbz(w5, &try_x);
10187 
10188   Label try_wp;
10189   __ Bind(&try_wp);
10190   __ Ldaxp(w0, w1, MemOperand(x10));
10191   __ Stlxp(w5, w0, w1, MemOperand(x10));
10192   __ Sub(x11, x11, 1);
10193   __ Cbz(x11, &done);
10194   __ Cbz(w5, &try_wp);
10195 
10196   Label try_xp;
10197   __ Bind(&try_xp);
10198   __ Ldaxp(x0, x1, MemOperand(x10));
10199   __ Stlxp(w5, x0, x1, MemOperand(x10));
10200   __ Sub(x11, x11, 1);
10201   __ Cbz(x11, &done);
10202   __ Cbz(w5, &try_xp);
10203 
10204   __ Bind(&done);
10205   // Trigger an error if x11 (watchdog) is zero.
10206   __ Cmp(x11, 0);
10207   __ Cset(x12, eq);
10208 
10209   END();
10210   if (CAN_RUN()) {
10211     RUN();
10212 
10213     // Check that the watchdog counter didn't run out.
10214     ASSERT_EQUAL_64(0, x12);
10215   }
10216 }
10217 #endif
10218 
10219 TEST(cas_casa_casl_casal_w) {
10220   uint64_t data1 = 0x0123456789abcdef;
10221   uint64_t data2 = 0x0123456789abcdef;
10222   uint64_t data3 = 0x0123456789abcdef;
10223   uint64_t data4 = 0x0123456789abcdef;
10224   uint64_t data5 = 0x0123456789abcdef;
10225   uint64_t data6 = 0x0123456789abcdef;
10226   uint64_t data7 = 0x0123456789abcdef;
10227   uint64_t data8 = 0x0123456789abcdef;
10228 
10229   SETUP_WITH_FEATURES(CPUFeatures::kAtomics);
10230 
10231   START();
10232 
10233   __ Mov(x21, reinterpret_cast<uintptr_t>(&data1) + 0);
10234   __ Mov(x22, reinterpret_cast<uintptr_t>(&data2) + 0);
10235   __ Mov(x23, reinterpret_cast<uintptr_t>(&data3) + 4);
10236   __ Mov(x24, reinterpret_cast<uintptr_t>(&data4) + 4);
10237   __ Mov(x25, reinterpret_cast<uintptr_t>(&data5) + 0);
10238   __ Mov(x26, reinterpret_cast<uintptr_t>(&data6) + 0);
10239   __ Mov(x27, reinterpret_cast<uintptr_t>(&data7) + 4);
10240   __ Mov(x28, reinterpret_cast<uintptr_t>(&data8) + 4);
10241 
10242   __ Mov(x0, 0xffffffff);
10243 
10244   __ Mov(x1, 0xfedcba9876543210);
10245   __ Mov(x2, 0x0123456789abcdef);
10246   __ Mov(x3, 0xfedcba9876543210);
10247   __ Mov(x4, 0x89abcdef01234567);
10248   __ Mov(x5, 0xfedcba9876543210);
10249   __ Mov(x6, 0x0123456789abcdef);
10250   __ Mov(x7, 0xfedcba9876543210);
10251   __ Mov(x8, 0x89abcdef01234567);
10252 
10253   __ Cas(w1, w0, MemOperand(x21));
10254   __ Cas(w2, w0, MemOperand(x22));
10255   __ Casa(w3, w0, MemOperand(x23));
10256   __ Casa(w4, w0, MemOperand(x24));
10257   __ Casl(w5, w0, MemOperand(x25));
10258   __ Casl(w6, w0, MemOperand(x26));
10259   __ Casal(w7, w0, MemOperand(x27));
10260   __ Casal(w8, w0, MemOperand(x28));
10261 
10262   END();
10263 
10264   if (CAN_RUN()) {
10265     RUN();
10266 
10267     ASSERT_EQUAL_64(0x89abcdef, x1);
10268     ASSERT_EQUAL_64(0x89abcdef, x2);
10269     ASSERT_EQUAL_64(0x01234567, x3);
10270     ASSERT_EQUAL_64(0x01234567, x4);
10271     ASSERT_EQUAL_64(0x89abcdef, x5);
10272     ASSERT_EQUAL_64(0x89abcdef, x6);
10273     ASSERT_EQUAL_64(0x01234567, x7);
10274     ASSERT_EQUAL_64(0x01234567, x8);
10275 
10276     ASSERT_EQUAL_64(0x0123456789abcdef, data1);
10277     ASSERT_EQUAL_64(0x01234567ffffffff, data2);
10278     ASSERT_EQUAL_64(0x0123456789abcdef, data3);
10279     ASSERT_EQUAL_64(0xffffffff89abcdef, data4);
10280     ASSERT_EQUAL_64(0x0123456789abcdef, data5);
10281     ASSERT_EQUAL_64(0x01234567ffffffff, data6);
10282     ASSERT_EQUAL_64(0x0123456789abcdef, data7);
10283     ASSERT_EQUAL_64(0xffffffff89abcdef, data8);
10284   }
10285 }
10286 
10287 TEST(cas_casa_casl_casal_x) {
10288   uint64_t data1 = 0x0123456789abcdef;
10289   uint64_t data2 = 0x0123456789abcdef;
10290   uint64_t data3 = 0x0123456789abcdef;
10291   uint64_t data4 = 0x0123456789abcdef;
10292   uint64_t data5 = 0x0123456789abcdef;
10293   uint64_t data6 = 0x0123456789abcdef;
10294   uint64_t data7 = 0x0123456789abcdef;
10295   uint64_t data8 = 0x0123456789abcdef;
10296 
10297   SETUP_WITH_FEATURES(CPUFeatures::kAtomics);
10298 
10299   START();
10300 
10301   __ Mov(x21, reinterpret_cast<uintptr_t>(&data1));
10302   __ Mov(x22, reinterpret_cast<uintptr_t>(&data2));
10303   __ Mov(x23, reinterpret_cast<uintptr_t>(&data3));
10304   __ Mov(x24, reinterpret_cast<uintptr_t>(&data4));
10305   __ Mov(x25, reinterpret_cast<uintptr_t>(&data5));
10306   __ Mov(x26, reinterpret_cast<uintptr_t>(&data6));
10307   __ Mov(x27, reinterpret_cast<uintptr_t>(&data7));
10308   __ Mov(x28, reinterpret_cast<uintptr_t>(&data8));
10309 
10310   __ Mov(x0, 0xffffffffffffffff);
10311 
10312   __ Mov(x1, 0xfedcba9876543210);
10313   __ Mov(x2, 0x0123456789abcdef);
10314   __ Mov(x3, 0xfedcba9876543210);
10315   __ Mov(x4, 0x0123456789abcdef);
10316   __ Mov(x5, 0xfedcba9876543210);
10317   __ Mov(x6, 0x0123456789abcdef);
10318   __ Mov(x7, 0xfedcba9876543210);
10319   __ Mov(x8, 0x0123456789abcdef);
10320 
10321   __ Cas(x1, x0, MemOperand(x21));
10322   __ Cas(x2, x0, MemOperand(x22));
10323   __ Casa(x3, x0, MemOperand(x23));
10324   __ Casa(x4, x0, MemOperand(x24));
10325   __ Casl(x5, x0, MemOperand(x25));
10326   __ Casl(x6, x0, MemOperand(x26));
10327   __ Casal(x7, x0, MemOperand(x27));
10328   __ Casal(x8, x0, MemOperand(x28));
10329 
10330   END();
10331 
10332   if (CAN_RUN()) {
10333     RUN();
10334 
10335     ASSERT_EQUAL_64(0x0123456789abcdef, x1);
10336     ASSERT_EQUAL_64(0x0123456789abcdef, x2);
10337     ASSERT_EQUAL_64(0x0123456789abcdef, x3);
10338     ASSERT_EQUAL_64(0x0123456789abcdef, x4);
10339     ASSERT_EQUAL_64(0x0123456789abcdef, x5);
10340     ASSERT_EQUAL_64(0x0123456789abcdef, x6);
10341     ASSERT_EQUAL_64(0x0123456789abcdef, x7);
10342     ASSERT_EQUAL_64(0x0123456789abcdef, x8);
10343 
10344     ASSERT_EQUAL_64(0x0123456789abcdef, data1);
10345     ASSERT_EQUAL_64(0xffffffffffffffff, data2);
10346     ASSERT_EQUAL_64(0x0123456789abcdef, data3);
10347     ASSERT_EQUAL_64(0xffffffffffffffff, data4);
10348     ASSERT_EQUAL_64(0x0123456789abcdef, data5);
10349     ASSERT_EQUAL_64(0xffffffffffffffff, data6);
10350     ASSERT_EQUAL_64(0x0123456789abcdef, data7);
10351     ASSERT_EQUAL_64(0xffffffffffffffff, data8);
10352   }
10353 }
10354 
10355 TEST(casb_casab_caslb_casalb) {
10356   uint32_t data1 = 0x01234567;
10357   uint32_t data2 = 0x01234567;
10358   uint32_t data3 = 0x01234567;
10359   uint32_t data4 = 0x01234567;
10360   uint32_t data5 = 0x01234567;
10361   uint32_t data6 = 0x01234567;
10362   uint32_t data7 = 0x01234567;
10363   uint32_t data8 = 0x01234567;
10364 
10365   SETUP_WITH_FEATURES(CPUFeatures::kAtomics);
10366 
10367   START();
10368 
10369   __ Mov(x21, reinterpret_cast<uintptr_t>(&data1) + 0);
10370   __ Mov(x22, reinterpret_cast<uintptr_t>(&data2) + 0);
10371   __ Mov(x23, reinterpret_cast<uintptr_t>(&data3) + 1);
10372   __ Mov(x24, reinterpret_cast<uintptr_t>(&data4) + 1);
10373   __ Mov(x25, reinterpret_cast<uintptr_t>(&data5) + 2);
10374   __ Mov(x26, reinterpret_cast<uintptr_t>(&data6) + 2);
10375   __ Mov(x27, reinterpret_cast<uintptr_t>(&data7) + 3);
10376   __ Mov(x28, reinterpret_cast<uintptr_t>(&data8) + 3);
10377 
10378   __ Mov(x0, 0xff);
10379 
10380   __ Mov(x1, 0x76543210);
10381   __ Mov(x2, 0x01234567);
10382   __ Mov(x3, 0x76543210);
10383   __ Mov(x4, 0x67012345);
10384   __ Mov(x5, 0x76543210);
10385   __ Mov(x6, 0x45670123);
10386   __ Mov(x7, 0x76543210);
10387   __ Mov(x8, 0x23456701);
10388 
10389   __ Casb(w1, w0, MemOperand(x21));
10390   __ Casb(w2, w0, MemOperand(x22));
10391   __ Casab(w3, w0, MemOperand(x23));
10392   __ Casab(w4, w0, MemOperand(x24));
10393   __ Caslb(w5, w0, MemOperand(x25));
10394   __ Caslb(w6, w0, MemOperand(x26));
10395   __ Casalb(w7, w0, MemOperand(x27));
10396   __ Casalb(w8, w0, MemOperand(x28));
10397 
10398   END();
10399 
10400   if (CAN_RUN()) {
10401     RUN();
10402 
10403     ASSERT_EQUAL_64(0x00000067, x1);
10404     ASSERT_EQUAL_64(0x00000067, x2);
10405     ASSERT_EQUAL_64(0x00000045, x3);
10406     ASSERT_EQUAL_64(0x00000045, x4);
10407     ASSERT_EQUAL_64(0x00000023, x5);
10408     ASSERT_EQUAL_64(0x00000023, x6);
10409     ASSERT_EQUAL_64(0x00000001, x7);
10410     ASSERT_EQUAL_64(0x00000001, x8);
10411 
10412     ASSERT_EQUAL_64(0x01234567, data1);
10413     ASSERT_EQUAL_64(0x012345ff, data2);
10414     ASSERT_EQUAL_64(0x01234567, data3);
10415     ASSERT_EQUAL_64(0x0123ff67, data4);
10416     ASSERT_EQUAL_64(0x01234567, data5);
10417     ASSERT_EQUAL_64(0x01ff4567, data6);
10418     ASSERT_EQUAL_64(0x01234567, data7);
10419     ASSERT_EQUAL_64(0xff234567, data8);
10420   }
10421 }
10422 
10423 TEST(cash_casah_caslh_casalh) {
10424   uint64_t data1 = 0x0123456789abcdef;
10425   uint64_t data2 = 0x0123456789abcdef;
10426   uint64_t data3 = 0x0123456789abcdef;
10427   uint64_t data4 = 0x0123456789abcdef;
10428   uint64_t data5 = 0x0123456789abcdef;
10429   uint64_t data6 = 0x0123456789abcdef;
10430   uint64_t data7 = 0x0123456789abcdef;
10431   uint64_t data8 = 0x0123456789abcdef;
10432 
10433   SETUP_WITH_FEATURES(CPUFeatures::kAtomics);
10434 
10435   START();
10436 
10437   __ Mov(x21, reinterpret_cast<uintptr_t>(&data1) + 0);
10438   __ Mov(x22, reinterpret_cast<uintptr_t>(&data2) + 0);
10439   __ Mov(x23, reinterpret_cast<uintptr_t>(&data3) + 2);
10440   __ Mov(x24, reinterpret_cast<uintptr_t>(&data4) + 2);
10441   __ Mov(x25, reinterpret_cast<uintptr_t>(&data5) + 4);
10442   __ Mov(x26, reinterpret_cast<uintptr_t>(&data6) + 4);
10443   __ Mov(x27, reinterpret_cast<uintptr_t>(&data7) + 6);
10444   __ Mov(x28, reinterpret_cast<uintptr_t>(&data8) + 6);
10445 
10446   __ Mov(x0, 0xffff);
10447 
10448   __ Mov(x1, 0xfedcba9876543210);
10449   __ Mov(x2, 0x0123456789abcdef);
10450   __ Mov(x3, 0xfedcba9876543210);
10451   __ Mov(x4, 0xcdef0123456789ab);
10452   __ Mov(x5, 0xfedcba9876543210);
10453   __ Mov(x6, 0x89abcdef01234567);
10454   __ Mov(x7, 0xfedcba9876543210);
10455   __ Mov(x8, 0x456789abcdef0123);
10456 
10457   __ Cash(w1, w0, MemOperand(x21));
10458   __ Cash(w2, w0, MemOperand(x22));
10459   __ Casah(w3, w0, MemOperand(x23));
10460   __ Casah(w4, w0, MemOperand(x24));
10461   __ Caslh(w5, w0, MemOperand(x25));
10462   __ Caslh(w6, w0, MemOperand(x26));
10463   __ Casalh(w7, w0, MemOperand(x27));
10464   __ Casalh(w8, w0, MemOperand(x28));
10465 
10466   END();
10467 
10468   if (CAN_RUN()) {
10469     RUN();
10470 
10471     ASSERT_EQUAL_64(0x0000cdef, x1);
10472     ASSERT_EQUAL_64(0x0000cdef, x2);
10473     ASSERT_EQUAL_64(0x000089ab, x3);
10474     ASSERT_EQUAL_64(0x000089ab, x4);
10475     ASSERT_EQUAL_64(0x00004567, x5);
10476     ASSERT_EQUAL_64(0x00004567, x6);
10477     ASSERT_EQUAL_64(0x00000123, x7);
10478     ASSERT_EQUAL_64(0x00000123, x8);
10479 
10480     ASSERT_EQUAL_64(0x0123456789abcdef, data1);
10481     ASSERT_EQUAL_64(0x0123456789abffff, data2);
10482     ASSERT_EQUAL_64(0x0123456789abcdef, data3);
10483     ASSERT_EQUAL_64(0x01234567ffffcdef, data4);
10484     ASSERT_EQUAL_64(0x0123456789abcdef, data5);
10485     ASSERT_EQUAL_64(0x0123ffff89abcdef, data6);
10486     ASSERT_EQUAL_64(0x0123456789abcdef, data7);
10487     ASSERT_EQUAL_64(0xffff456789abcdef, data8);
10488   }
10489 }
10490 
10491 TEST(casp_caspa_caspl_caspal_w) {
10492   uint64_t data1[] = {0x7766554433221100, 0xffeeddccbbaa9988};
10493   uint64_t data2[] = {0x7766554433221100, 0xffeeddccbbaa9988};
10494   uint64_t data3[] = {0x7766554433221100, 0xffeeddccbbaa9988};
10495   uint64_t data4[] = {0x7766554433221100, 0xffeeddccbbaa9988};
10496   uint64_t data5[] = {0x7766554433221100, 0xffeeddccbbaa9988};
10497   uint64_t data6[] = {0x7766554433221100, 0xffeeddccbbaa9988};
10498   uint64_t data7[] = {0x7766554433221100, 0xffeeddccbbaa9988};
10499   uint64_t data8[] = {0x7766554433221100, 0xffeeddccbbaa9988};
10500 
10501   SETUP_WITH_FEATURES(CPUFeatures::kAtomics);
10502 
10503   START();
10504 
10505   __ Mov(x21, reinterpret_cast<uintptr_t>(data1) + 0);
10506   __ Mov(x22, reinterpret_cast<uintptr_t>(data2) + 0);
10507   __ Mov(x23, reinterpret_cast<uintptr_t>(data3) + 8);
10508   __ Mov(x24, reinterpret_cast<uintptr_t>(data4) + 8);
10509   __ Mov(x25, reinterpret_cast<uintptr_t>(data5) + 8);
10510   __ Mov(x26, reinterpret_cast<uintptr_t>(data6) + 8);
10511   __ Mov(x27, reinterpret_cast<uintptr_t>(data7) + 0);
10512   __ Mov(x28, reinterpret_cast<uintptr_t>(data8) + 0);
10513 
10514   __ Mov(x0, 0xfff00fff);
10515   __ Mov(x1, 0xfff11fff);
10516 
10517   __ Mov(x2, 0x77665544);
10518   __ Mov(x3, 0x33221100);
10519   __ Mov(x4, 0x33221100);
10520   __ Mov(x5, 0x77665544);
10521 
10522   __ Mov(x6, 0xffeeddcc);
10523   __ Mov(x7, 0xbbaa9988);
10524   __ Mov(x8, 0xbbaa9988);
10525   __ Mov(x9, 0xffeeddcc);
10526 
10527   __ Mov(x10, 0xffeeddcc);
10528   __ Mov(x11, 0xbbaa9988);
10529   __ Mov(x12, 0xbbaa9988);
10530   __ Mov(x13, 0xffeeddcc);
10531 
10532   __ Mov(x14, 0x77665544);
10533   __ Mov(x15, 0x33221100);
10534   __ Mov(x16, 0x33221100);
10535   __ Mov(x17, 0x77665544);
10536 
10537   __ Casp(w2, w3, w0, w1, MemOperand(x21));
10538   __ Casp(w4, w5, w0, w1, MemOperand(x22));
10539   __ Caspa(w6, w7, w0, w1, MemOperand(x23));
10540   __ Caspa(w8, w9, w0, w1, MemOperand(x24));
10541   __ Caspl(w10, w11, w0, w1, MemOperand(x25));
10542   __ Caspl(w12, w13, w0, w1, MemOperand(x26));
10543   __ Caspal(w14, w15, w0, w1, MemOperand(x27));
10544   __ Caspal(w16, w17, w0, w1, MemOperand(x28));
10545 
10546   END();
10547 
10548   if (CAN_RUN()) {
10549     RUN();
10550 
10551     ASSERT_EQUAL_64(0x33221100, x2);
10552     ASSERT_EQUAL_64(0x77665544, x3);
10553     ASSERT_EQUAL_64(0x33221100, x4);
10554     ASSERT_EQUAL_64(0x77665544, x5);
10555     ASSERT_EQUAL_64(0xbbaa9988, x6);
10556     ASSERT_EQUAL_64(0xffeeddcc, x7);
10557     ASSERT_EQUAL_64(0xbbaa9988, x8);
10558     ASSERT_EQUAL_64(0xffeeddcc, x9);
10559     ASSERT_EQUAL_64(0xbbaa9988, x10);
10560     ASSERT_EQUAL_64(0xffeeddcc, x11);
10561     ASSERT_EQUAL_64(0xbbaa9988, x12);
10562     ASSERT_EQUAL_64(0xffeeddcc, x13);
10563     ASSERT_EQUAL_64(0x33221100, x14);
10564     ASSERT_EQUAL_64(0x77665544, x15);
10565     ASSERT_EQUAL_64(0x33221100, x16);
10566     ASSERT_EQUAL_64(0x77665544, x17);
10567 
10568     ASSERT_EQUAL_64(0x7766554433221100, data1[0]);
10569     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data1[1]);
10570     ASSERT_EQUAL_64(0xfff11ffffff00fff, data2[0]);
10571     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data2[1]);
10572     ASSERT_EQUAL_64(0x7766554433221100, data3[0]);
10573     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data3[1]);
10574     ASSERT_EQUAL_64(0x7766554433221100, data4[0]);
10575     ASSERT_EQUAL_64(0xfff11ffffff00fff, data4[1]);
10576     ASSERT_EQUAL_64(0x7766554433221100, data5[0]);
10577     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data5[1]);
10578     ASSERT_EQUAL_64(0x7766554433221100, data6[0]);
10579     ASSERT_EQUAL_64(0xfff11ffffff00fff, data6[1]);
10580     ASSERT_EQUAL_64(0x7766554433221100, data7[0]);
10581     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data7[1]);
10582     ASSERT_EQUAL_64(0xfff11ffffff00fff, data8[0]);
10583     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data8[1]);
10584   }
10585 }
10586 
10587 TEST(casp_caspa_caspl_caspal_x) {
10588   alignas(kXRegSizeInBytes * 2) uint64_t data1[] = {0x7766554433221100,
10589                                                     0xffeeddccbbaa9988,
10590                                                     0xfedcba9876543210,
10591                                                     0x0123456789abcdef};
10592   alignas(kXRegSizeInBytes * 2) uint64_t data2[] = {0x7766554433221100,
10593                                                     0xffeeddccbbaa9988,
10594                                                     0xfedcba9876543210,
10595                                                     0x0123456789abcdef};
10596   alignas(kXRegSizeInBytes * 2) uint64_t data3[] = {0x7766554433221100,
10597                                                     0xffeeddccbbaa9988,
10598                                                     0xfedcba9876543210,
10599                                                     0x0123456789abcdef};
10600   alignas(kXRegSizeInBytes * 2) uint64_t data4[] = {0x7766554433221100,
10601                                                     0xffeeddccbbaa9988,
10602                                                     0xfedcba9876543210,
10603                                                     0x0123456789abcdef};
10604   alignas(kXRegSizeInBytes * 2) uint64_t data5[] = {0x7766554433221100,
10605                                                     0xffeeddccbbaa9988,
10606                                                     0xfedcba9876543210,
10607                                                     0x0123456789abcdef};
10608   alignas(kXRegSizeInBytes * 2) uint64_t data6[] = {0x7766554433221100,
10609                                                     0xffeeddccbbaa9988,
10610                                                     0xfedcba9876543210,
10611                                                     0x0123456789abcdef};
10612   alignas(kXRegSizeInBytes * 2) uint64_t data7[] = {0x7766554433221100,
10613                                                     0xffeeddccbbaa9988,
10614                                                     0xfedcba9876543210,
10615                                                     0x0123456789abcdef};
10616   alignas(kXRegSizeInBytes * 2) uint64_t data8[] = {0x7766554433221100,
10617                                                     0xffeeddccbbaa9988,
10618                                                     0xfedcba9876543210,
10619                                                     0x0123456789abcdef};
10620 
10621   SETUP_WITH_FEATURES(CPUFeatures::kAtomics);
10622 
10623   START();
10624 
10625   __ Mov(x21, reinterpret_cast<uintptr_t>(data1) + 0);
10626   __ Mov(x22, reinterpret_cast<uintptr_t>(data2) + 0);
10627   __ Mov(x23, reinterpret_cast<uintptr_t>(data3) + 16);
10628   __ Mov(x24, reinterpret_cast<uintptr_t>(data4) + 16);
10629   __ Mov(x25, reinterpret_cast<uintptr_t>(data5) + 16);
10630   __ Mov(x26, reinterpret_cast<uintptr_t>(data6) + 16);
10631   __ Mov(x27, reinterpret_cast<uintptr_t>(data7) + 0);
10632   __ Mov(x28, reinterpret_cast<uintptr_t>(data8) + 0);
10633 
10634   __ Mov(x0, 0xfffffff00fffffff);
10635   __ Mov(x1, 0xfffffff11fffffff);
10636 
10637   __ Mov(x2, 0xffeeddccbbaa9988);
10638   __ Mov(x3, 0x7766554433221100);
10639   __ Mov(x4, 0x7766554433221100);
10640   __ Mov(x5, 0xffeeddccbbaa9988);
10641 
10642   __ Mov(x6, 0x0123456789abcdef);
10643   __ Mov(x7, 0xfedcba9876543210);
10644   __ Mov(x8, 0xfedcba9876543210);
10645   __ Mov(x9, 0x0123456789abcdef);
10646 
10647   __ Mov(x10, 0x0123456789abcdef);
10648   __ Mov(x11, 0xfedcba9876543210);
10649   __ Mov(x12, 0xfedcba9876543210);
10650   __ Mov(x13, 0x0123456789abcdef);
10651 
10652   __ Mov(x14, 0xffeeddccbbaa9988);
10653   __ Mov(x15, 0x7766554433221100);
10654   __ Mov(x16, 0x7766554433221100);
10655   __ Mov(x17, 0xffeeddccbbaa9988);
10656 
10657   __ Casp(x2, x3, x0, x1, MemOperand(x21));
10658   __ Casp(x4, x5, x0, x1, MemOperand(x22));
10659   __ Caspa(x6, x7, x0, x1, MemOperand(x23));
10660   __ Caspa(x8, x9, x0, x1, MemOperand(x24));
10661   __ Caspl(x10, x11, x0, x1, MemOperand(x25));
10662   __ Caspl(x12, x13, x0, x1, MemOperand(x26));
10663   __ Caspal(x14, x15, x0, x1, MemOperand(x27));
10664   __ Caspal(x16, x17, x0, x1, MemOperand(x28));
10665 
10666   END();
10667 
10668   if (CAN_RUN()) {
10669     RUN();
10670 
10671     ASSERT_EQUAL_64(0x7766554433221100, x2);
10672     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x3);
10673     ASSERT_EQUAL_64(0x7766554433221100, x4);
10674     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x5);
10675 
10676     ASSERT_EQUAL_64(0xfedcba9876543210, x6);
10677     ASSERT_EQUAL_64(0x0123456789abcdef, x7);
10678     ASSERT_EQUAL_64(0xfedcba9876543210, x8);
10679     ASSERT_EQUAL_64(0x0123456789abcdef, x9);
10680 
10681     ASSERT_EQUAL_64(0xfedcba9876543210, x10);
10682     ASSERT_EQUAL_64(0x0123456789abcdef, x11);
10683     ASSERT_EQUAL_64(0xfedcba9876543210, x12);
10684     ASSERT_EQUAL_64(0x0123456789abcdef, x13);
10685 
10686     ASSERT_EQUAL_64(0x7766554433221100, x14);
10687     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x15);
10688     ASSERT_EQUAL_64(0x7766554433221100, x16);
10689     ASSERT_EQUAL_64(0xffeeddccbbaa9988, x17);
10690 
10691     ASSERT_EQUAL_64(0x7766554433221100, data1[0]);
10692     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data1[1]);
10693     ASSERT_EQUAL_64(0xfedcba9876543210, data1[2]);
10694     ASSERT_EQUAL_64(0x0123456789abcdef, data1[3]);
10695 
10696     ASSERT_EQUAL_64(0xfffffff00fffffff, data2[0]);
10697     ASSERT_EQUAL_64(0xfffffff11fffffff, data2[1]);
10698     ASSERT_EQUAL_64(0xfedcba9876543210, data2[2]);
10699     ASSERT_EQUAL_64(0x0123456789abcdef, data2[3]);
10700 
10701     ASSERT_EQUAL_64(0x7766554433221100, data3[0]);
10702     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data3[1]);
10703     ASSERT_EQUAL_64(0xfedcba9876543210, data3[2]);
10704     ASSERT_EQUAL_64(0x0123456789abcdef, data3[3]);
10705 
10706     ASSERT_EQUAL_64(0x7766554433221100, data4[0]);
10707     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data4[1]);
10708     ASSERT_EQUAL_64(0xfffffff00fffffff, data4[2]);
10709     ASSERT_EQUAL_64(0xfffffff11fffffff, data4[3]);
10710 
10711     ASSERT_EQUAL_64(0x7766554433221100, data5[0]);
10712     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data5[1]);
10713     ASSERT_EQUAL_64(0xfedcba9876543210, data5[2]);
10714     ASSERT_EQUAL_64(0x0123456789abcdef, data5[3]);
10715 
10716     ASSERT_EQUAL_64(0x7766554433221100, data6[0]);
10717     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data6[1]);
10718     ASSERT_EQUAL_64(0xfffffff00fffffff, data6[2]);
10719     ASSERT_EQUAL_64(0xfffffff11fffffff, data6[3]);
10720 
10721     ASSERT_EQUAL_64(0x7766554433221100, data7[0]);
10722     ASSERT_EQUAL_64(0xffeeddccbbaa9988, data7[1]);
10723     ASSERT_EQUAL_64(0xfedcba9876543210, data7[2]);
10724     ASSERT_EQUAL_64(0x0123456789abcdef, data7[3]);
10725 
10726     ASSERT_EQUAL_64(0xfffffff00fffffff, data8[0]);
10727     ASSERT_EQUAL_64(0xfffffff11fffffff, data8[1]);
10728     ASSERT_EQUAL_64(0xfedcba9876543210, data8[2]);
10729     ASSERT_EQUAL_64(0x0123456789abcdef, data8[3]);
10730   }
10731 }
10732 
10733 
10734 typedef void (MacroAssembler::*AtomicMemoryLoadSignature)(
10735     const Register& rs, const Register& rt, const MemOperand& src);
10736 typedef void (MacroAssembler::*AtomicMemoryStoreSignature)(
10737     const Register& rs, const MemOperand& src);
10738 
10739 void AtomicMemoryWHelper(AtomicMemoryLoadSignature* load_funcs,
10740                          AtomicMemoryStoreSignature* store_funcs,
10741                          uint64_t arg1,
10742                          uint64_t arg2,
10743                          uint64_t expected,
10744                          uint64_t result_mask) {
10745   uint64_t data0[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10746   uint64_t data1[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10747   uint64_t data2[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10748   uint64_t data3[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10749   uint64_t data4[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10750   uint64_t data5[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10751 
10752   SETUP_WITH_FEATURES(CPUFeatures::kAtomics);
10753   START();
10754 
10755   __ Mov(x20, reinterpret_cast<uintptr_t>(data0));
10756   __ Mov(x21, reinterpret_cast<uintptr_t>(data1));
10757   __ Mov(x22, reinterpret_cast<uintptr_t>(data2));
10758   __ Mov(x23, reinterpret_cast<uintptr_t>(data3));
10759 
10760   __ Mov(x0, arg1);
10761   __ Mov(x1, arg1);
10762   __ Mov(x2, arg1);
10763   __ Mov(x3, arg1);
10764 
10765   (masm.*(load_funcs[0]))(w0, w10, MemOperand(x20));
10766   (masm.*(load_funcs[1]))(w1, w11, MemOperand(x21));
10767   (masm.*(load_funcs[2]))(w2, w12, MemOperand(x22));
10768   (masm.*(load_funcs[3]))(w3, w13, MemOperand(x23));
10769 
10770   if (store_funcs != NULL) {
10771     __ Mov(x24, reinterpret_cast<uintptr_t>(data4));
10772     __ Mov(x25, reinterpret_cast<uintptr_t>(data5));
10773     __ Mov(x4, arg1);
10774     __ Mov(x5, arg1);
10775 
10776     (masm.*(store_funcs[0]))(w4, MemOperand(x24));
10777     (masm.*(store_funcs[1]))(w5, MemOperand(x25));
10778   }
10779 
10780   END();
10781 
10782   if (CAN_RUN()) {
10783     RUN();
10784 
10785     uint64_t stored_value = arg2 & result_mask;
10786     ASSERT_EQUAL_64(stored_value, x10);
10787     ASSERT_EQUAL_64(stored_value, x11);
10788     ASSERT_EQUAL_64(stored_value, x12);
10789     ASSERT_EQUAL_64(stored_value, x13);
10790 
10791     // The data fields contain arg2 already then only the bits masked by
10792     // result_mask are overwritten.
10793     uint64_t final_expected = (arg2 & ~result_mask) | (expected & result_mask);
10794     ASSERT_EQUAL_64(final_expected, data0[0]);
10795     ASSERT_EQUAL_64(final_expected, data1[0]);
10796     ASSERT_EQUAL_64(final_expected, data2[0]);
10797     ASSERT_EQUAL_64(final_expected, data3[0]);
10798 
10799     if (store_funcs != NULL) {
10800       ASSERT_EQUAL_64(final_expected, data4[0]);
10801       ASSERT_EQUAL_64(final_expected, data5[0]);
10802     }
10803   }
10804 }
10805 
10806 void AtomicMemoryXHelper(AtomicMemoryLoadSignature* load_funcs,
10807                          AtomicMemoryStoreSignature* store_funcs,
10808                          uint64_t arg1,
10809                          uint64_t arg2,
10810                          uint64_t expected) {
10811   uint64_t data0[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10812   uint64_t data1[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10813   uint64_t data2[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10814   uint64_t data3[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10815   uint64_t data4[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10816   uint64_t data5[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {arg2, 0};
10817 
10818   SETUP_WITH_FEATURES(CPUFeatures::kAtomics);
10819   START();
10820 
10821   __ Mov(x20, reinterpret_cast<uintptr_t>(data0));
10822   __ Mov(x21, reinterpret_cast<uintptr_t>(data1));
10823   __ Mov(x22, reinterpret_cast<uintptr_t>(data2));
10824   __ Mov(x23, reinterpret_cast<uintptr_t>(data3));
10825 
10826   __ Mov(x0, arg1);
10827   __ Mov(x1, arg1);
10828   __ Mov(x2, arg1);
10829   __ Mov(x3, arg1);
10830 
10831   (masm.*(load_funcs[0]))(x0, x10, MemOperand(x20));
10832   (masm.*(load_funcs[1]))(x1, x11, MemOperand(x21));
10833   (masm.*(load_funcs[2]))(x2, x12, MemOperand(x22));
10834   (masm.*(load_funcs[3]))(x3, x13, MemOperand(x23));
10835 
10836   if (store_funcs != NULL) {
10837     __ Mov(x24, reinterpret_cast<uintptr_t>(data4));
10838     __ Mov(x25, reinterpret_cast<uintptr_t>(data5));
10839     __ Mov(x4, arg1);
10840     __ Mov(x5, arg1);
10841 
10842     (masm.*(store_funcs[0]))(x4, MemOperand(x24));
10843     (masm.*(store_funcs[1]))(x5, MemOperand(x25));
10844   }
10845 
10846   END();
10847 
10848   if (CAN_RUN()) {
10849     RUN();
10850 
10851     ASSERT_EQUAL_64(arg2, x10);
10852     ASSERT_EQUAL_64(arg2, x11);
10853     ASSERT_EQUAL_64(arg2, x12);
10854     ASSERT_EQUAL_64(arg2, x13);
10855 
10856     ASSERT_EQUAL_64(expected, data0[0]);
10857     ASSERT_EQUAL_64(expected, data1[0]);
10858     ASSERT_EQUAL_64(expected, data2[0]);
10859     ASSERT_EQUAL_64(expected, data3[0]);
10860 
10861     if (store_funcs != NULL) {
10862       ASSERT_EQUAL_64(expected, data4[0]);
10863       ASSERT_EQUAL_64(expected, data5[0]);
10864     }
10865   }
10866 }
10867 
10868 // clang-format off
10869 #define MAKE_LOADS(NAME)           \
10870     {&MacroAssembler::Ld##NAME,    \
10871      &MacroAssembler::Ld##NAME##a, \
10872      &MacroAssembler::Ld##NAME##l, \
10873      &MacroAssembler::Ld##NAME##al}
10874 #define MAKE_STORES(NAME) \
10875     {&MacroAssembler::St##NAME, &MacroAssembler::St##NAME##l}
10876 
10877 #define MAKE_B_LOADS(NAME)          \
10878     {&MacroAssembler::Ld##NAME##b,  \
10879      &MacroAssembler::Ld##NAME##ab, \
10880      &MacroAssembler::Ld##NAME##lb, \
10881      &MacroAssembler::Ld##NAME##alb}
10882 #define MAKE_B_STORES(NAME) \
10883     {&MacroAssembler::St##NAME##b, &MacroAssembler::St##NAME##lb}
10884 
10885 #define MAKE_H_LOADS(NAME)          \
10886     {&MacroAssembler::Ld##NAME##h,  \
10887      &MacroAssembler::Ld##NAME##ah, \
10888      &MacroAssembler::Ld##NAME##lh, \
10889      &MacroAssembler::Ld##NAME##alh}
10890 #define MAKE_H_STORES(NAME) \
10891     {&MacroAssembler::St##NAME##h, &MacroAssembler::St##NAME##lh}
10892 // clang-format on
10893 
10894 TEST(atomic_memory_add) {
10895   AtomicMemoryLoadSignature loads[] = MAKE_LOADS(add);
10896   AtomicMemoryStoreSignature stores[] = MAKE_STORES(add);
10897   AtomicMemoryLoadSignature b_loads[] = MAKE_B_LOADS(add);
10898   AtomicMemoryStoreSignature b_stores[] = MAKE_B_STORES(add);
10899   AtomicMemoryLoadSignature h_loads[] = MAKE_H_LOADS(add);
10900   AtomicMemoryStoreSignature h_stores[] = MAKE_H_STORES(add);
10901 
10902   // The arguments are chosen to have two useful properties:
10903   //  * When multiplied by small values (such as a register index), this value
10904   //    is clearly readable in the result.
10905   //  * The value is not formed from repeating fixed-size smaller values, so it
10906   //    can be used to detect endianness-related errors.
10907   uint64_t arg1 = 0x0100001000100101;
10908   uint64_t arg2 = 0x0200002000200202;
10909   uint64_t expected = arg1 + arg2;
10910 
10911   AtomicMemoryWHelper(b_loads, b_stores, arg1, arg2, expected, kByteMask);
10912   AtomicMemoryWHelper(h_loads, h_stores, arg1, arg2, expected, kHalfWordMask);
10913   AtomicMemoryWHelper(loads, stores, arg1, arg2, expected, kWordMask);
10914   AtomicMemoryXHelper(loads, stores, arg1, arg2, expected);
10915 }
10916 
10917 TEST(atomic_memory_clr) {
10918   AtomicMemoryLoadSignature loads[] = MAKE_LOADS(clr);
10919   AtomicMemoryStoreSignature stores[] = MAKE_STORES(clr);
10920   AtomicMemoryLoadSignature b_loads[] = MAKE_B_LOADS(clr);
10921   AtomicMemoryStoreSignature b_stores[] = MAKE_B_STORES(clr);
10922   AtomicMemoryLoadSignature h_loads[] = MAKE_H_LOADS(clr);
10923   AtomicMemoryStoreSignature h_stores[] = MAKE_H_STORES(clr);
10924 
10925   uint64_t arg1 = 0x0300003000300303;
10926   uint64_t arg2 = 0x0500005000500505;
10927   uint64_t expected = arg2 & ~arg1;
10928 
10929   AtomicMemoryWHelper(b_loads, b_stores, arg1, arg2, expected, kByteMask);
10930   AtomicMemoryWHelper(h_loads, h_stores, arg1, arg2, expected, kHalfWordMask);
10931   AtomicMemoryWHelper(loads, stores, arg1, arg2, expected, kWordMask);
10932   AtomicMemoryXHelper(loads, stores, arg1, arg2, expected);
10933 }
10934 
10935 TEST(atomic_memory_eor) {
10936   AtomicMemoryLoadSignature loads[] = MAKE_LOADS(eor);
10937   AtomicMemoryStoreSignature stores[] = MAKE_STORES(eor);
10938   AtomicMemoryLoadSignature b_loads[] = MAKE_B_LOADS(eor);
10939   AtomicMemoryStoreSignature b_stores[] = MAKE_B_STORES(eor);
10940   AtomicMemoryLoadSignature h_loads[] = MAKE_H_LOADS(eor);
10941   AtomicMemoryStoreSignature h_stores[] = MAKE_H_STORES(eor);
10942 
10943   uint64_t arg1 = 0x0300003000300303;
10944   uint64_t arg2 = 0x0500005000500505;
10945   uint64_t expected = arg1 ^ arg2;
10946 
10947   AtomicMemoryWHelper(b_loads, b_stores, arg1, arg2, expected, kByteMask);
10948   AtomicMemoryWHelper(h_loads, h_stores, arg1, arg2, expected, kHalfWordMask);
10949   AtomicMemoryWHelper(loads, stores, arg1, arg2, expected, kWordMask);
10950   AtomicMemoryXHelper(loads, stores, arg1, arg2, expected);
10951 }
10952 
10953 TEST(atomic_memory_set) {
10954   AtomicMemoryLoadSignature loads[] = MAKE_LOADS(set);
10955   AtomicMemoryStoreSignature stores[] = MAKE_STORES(set);
10956   AtomicMemoryLoadSignature b_loads[] = MAKE_B_LOADS(set);
10957   AtomicMemoryStoreSignature b_stores[] = MAKE_B_STORES(set);
10958   AtomicMemoryLoadSignature h_loads[] = MAKE_H_LOADS(set);
10959   AtomicMemoryStoreSignature h_stores[] = MAKE_H_STORES(set);
10960 
10961   uint64_t arg1 = 0x0300003000300303;
10962   uint64_t arg2 = 0x0500005000500505;
10963   uint64_t expected = arg1 | arg2;
10964 
10965   AtomicMemoryWHelper(b_loads, b_stores, arg1, arg2, expected, kByteMask);
10966   AtomicMemoryWHelper(h_loads, h_stores, arg1, arg2, expected, kHalfWordMask);
10967   AtomicMemoryWHelper(loads, stores, arg1, arg2, expected, kWordMask);
10968   AtomicMemoryXHelper(loads, stores, arg1, arg2, expected);
10969 }
10970 
10971 TEST(atomic_memory_smax) {
10972   AtomicMemoryLoadSignature loads[] = MAKE_LOADS(smax);
10973   AtomicMemoryStoreSignature stores[] = MAKE_STORES(smax);
10974   AtomicMemoryLoadSignature b_loads[] = MAKE_B_LOADS(smax);
10975   AtomicMemoryStoreSignature b_stores[] = MAKE_B_STORES(smax);
10976   AtomicMemoryLoadSignature h_loads[] = MAKE_H_LOADS(smax);
10977   AtomicMemoryStoreSignature h_stores[] = MAKE_H_STORES(smax);
10978 
10979   uint64_t arg1 = 0x8100000080108181;
10980   uint64_t arg2 = 0x0100001000100101;
10981   uint64_t expected = 0x0100001000100101;
10982 
10983   AtomicMemoryWHelper(b_loads, b_stores, arg1, arg2, expected, kByteMask);
10984   AtomicMemoryWHelper(h_loads, h_stores, arg1, arg2, expected, kHalfWordMask);
10985   AtomicMemoryWHelper(loads, stores, arg1, arg2, expected, kWordMask);
10986   AtomicMemoryXHelper(loads, stores, arg1, arg2, expected);
10987 }
10988 
10989 TEST(atomic_memory_smin) {
10990   AtomicMemoryLoadSignature loads[] = MAKE_LOADS(smin);
10991   AtomicMemoryStoreSignature stores[] = MAKE_STORES(smin);
10992   AtomicMemoryLoadSignature b_loads[] = MAKE_B_LOADS(smin);
10993   AtomicMemoryStoreSignature b_stores[] = MAKE_B_STORES(smin);
10994   AtomicMemoryLoadSignature h_loads[] = MAKE_H_LOADS(smin);
10995   AtomicMemoryStoreSignature h_stores[] = MAKE_H_STORES(smin);
10996 
10997   uint64_t arg1 = 0x8100000080108181;
10998   uint64_t arg2 = 0x0100001000100101;
10999   uint64_t expected = 0x8100000080108181;
11000 
11001   AtomicMemoryWHelper(b_loads, b_stores, arg1, arg2, expected, kByteMask);
11002   AtomicMemoryWHelper(h_loads, h_stores, arg1, arg2, expected, kHalfWordMask);
11003   AtomicMemoryWHelper(loads, stores, arg1, arg2, expected, kWordMask);
11004   AtomicMemoryXHelper(loads, stores, arg1, arg2, expected);
11005 }
11006 
11007 TEST(atomic_memory_umax) {
11008   AtomicMemoryLoadSignature loads[] = MAKE_LOADS(umax);
11009   AtomicMemoryStoreSignature stores[] = MAKE_STORES(umax);
11010   AtomicMemoryLoadSignature b_loads[] = MAKE_B_LOADS(umax);
11011   AtomicMemoryStoreSignature b_stores[] = MAKE_B_STORES(umax);
11012   AtomicMemoryLoadSignature h_loads[] = MAKE_H_LOADS(umax);
11013   AtomicMemoryStoreSignature h_stores[] = MAKE_H_STORES(umax);
11014 
11015   uint64_t arg1 = 0x8100000080108181;
11016   uint64_t arg2 = 0x0100001000100101;
11017   uint64_t expected = 0x8100000080108181;
11018 
11019   AtomicMemoryWHelper(b_loads, b_stores, arg1, arg2, expected, kByteMask);
11020   AtomicMemoryWHelper(h_loads, h_stores, arg1, arg2, expected, kHalfWordMask);
11021   AtomicMemoryWHelper(loads, stores, arg1, arg2, expected, kWordMask);
11022   AtomicMemoryXHelper(loads, stores, arg1, arg2, expected);
11023 }
11024 
11025 TEST(atomic_memory_umin) {
11026   AtomicMemoryLoadSignature loads[] = MAKE_LOADS(umin);
11027   AtomicMemoryStoreSignature stores[] = MAKE_STORES(umin);
11028   AtomicMemoryLoadSignature b_loads[] = MAKE_B_LOADS(umin);
11029   AtomicMemoryStoreSignature b_stores[] = MAKE_B_STORES(umin);
11030   AtomicMemoryLoadSignature h_loads[] = MAKE_H_LOADS(umin);
11031   AtomicMemoryStoreSignature h_stores[] = MAKE_H_STORES(umin);
11032 
11033   uint64_t arg1 = 0x8100000080108181;
11034   uint64_t arg2 = 0x0100001000100101;
11035   uint64_t expected = 0x0100001000100101;
11036 
11037   AtomicMemoryWHelper(b_loads, b_stores, arg1, arg2, expected, kByteMask);
11038   AtomicMemoryWHelper(h_loads, h_stores, arg1, arg2, expected, kHalfWordMask);
11039   AtomicMemoryWHelper(loads, stores, arg1, arg2, expected, kWordMask);
11040   AtomicMemoryXHelper(loads, stores, arg1, arg2, expected);
11041 }
11042 
11043 TEST(atomic_memory_swp) {
11044   AtomicMemoryLoadSignature loads[] = {&MacroAssembler::Swp,
11045                                        &MacroAssembler::Swpa,
11046                                        &MacroAssembler::Swpl,
11047                                        &MacroAssembler::Swpal};
11048   AtomicMemoryLoadSignature b_loads[] = {&MacroAssembler::Swpb,
11049                                          &MacroAssembler::Swpab,
11050                                          &MacroAssembler::Swplb,
11051                                          &MacroAssembler::Swpalb};
11052   AtomicMemoryLoadSignature h_loads[] = {&MacroAssembler::Swph,
11053                                          &MacroAssembler::Swpah,
11054                                          &MacroAssembler::Swplh,
11055                                          &MacroAssembler::Swpalh};
11056 
11057   uint64_t arg1 = 0x0100001000100101;
11058   uint64_t arg2 = 0x0200002000200202;
11059   uint64_t expected = 0x0100001000100101;
11060 
11061   // SWP functions have equivalent signatures to the Atomic Memory LD functions
11062   // so we can use the same helper but without the ST aliases.
11063   AtomicMemoryWHelper(b_loads, NULL, arg1, arg2, expected, kByteMask);
11064   AtomicMemoryWHelper(h_loads, NULL, arg1, arg2, expected, kHalfWordMask);
11065   AtomicMemoryWHelper(loads, NULL, arg1, arg2, expected, kWordMask);
11066   AtomicMemoryXHelper(loads, NULL, arg1, arg2, expected);
11067 }
11068 
11069 
11070 TEST(ldaprb_ldaprh_ldapr) {
11071   uint64_t data0[] = {0x1010101010101010, 0x1010101010101010};
11072   uint64_t data1[] = {0x1010101010101010, 0x1010101010101010};
11073   uint64_t data2[] = {0x1010101010101010, 0x1010101010101010};
11074   uint64_t data3[] = {0x1010101010101010, 0x1010101010101010};
11075 
11076   uint64_t* data0_aligned = AlignUp(data0, kXRegSizeInBytes * 2);
11077   uint64_t* data1_aligned = AlignUp(data1, kXRegSizeInBytes * 2);
11078   uint64_t* data2_aligned = AlignUp(data2, kXRegSizeInBytes * 2);
11079   uint64_t* data3_aligned = AlignUp(data3, kXRegSizeInBytes * 2);
11080 
11081   SETUP_WITH_FEATURES(CPUFeatures::kRCpc);
11082   START();
11083 
11084   __ Mov(x20, reinterpret_cast<uintptr_t>(data0_aligned));
11085   __ Mov(x21, reinterpret_cast<uintptr_t>(data1_aligned));
11086   __ Mov(x22, reinterpret_cast<uintptr_t>(data2_aligned));
11087   __ Mov(x23, reinterpret_cast<uintptr_t>(data3_aligned));
11088 
11089   __ Ldaprb(w0, MemOperand(x20));
11090   __ Ldaprh(w1, MemOperand(x21));
11091   __ Ldapr(w2, MemOperand(x22));
11092   __ Ldapr(x3, MemOperand(x23));
11093 
11094   END();
11095 
11096   if (CAN_RUN()) {
11097     RUN();
11098     ASSERT_EQUAL_64(0x10, x0);
11099     ASSERT_EQUAL_64(0x1010, x1);
11100     ASSERT_EQUAL_64(0x10101010, x2);
11101     ASSERT_EQUAL_64(0x1010101010101010, x3);
11102   }
11103 }
11104 
11105 
11106 TEST(ldapurb_ldapurh_ldapur) {
11107   uint64_t data[]
11108       __attribute__((aligned(kXRegSizeInBytes * 2))) = {0x0123456789abcdef,
11109                                                         0xfedcba9876543210};
11110 
11111   uintptr_t data_base = reinterpret_cast<uintptr_t>(data);
11112 
11113   SETUP_WITH_FEATURES(CPUFeatures::kRCpc, CPUFeatures::kRCpcImm);
11114   START();
11115 
11116   __ Mov(x20, data_base);
11117   __ Mov(x21, data_base + 2 * sizeof(data[0]));
11118 
11119   __ Ldaprb(w0, MemOperand(x20));
11120   __ Ldaprh(w1, MemOperand(x20));
11121   __ Ldapr(w2, MemOperand(x20));
11122   __ Ldapr(x3, MemOperand(x20));
11123   __ Ldaprb(w4, MemOperand(x20, 12));
11124   __ Ldaprh(w5, MemOperand(x20, 8));
11125   __ Ldapr(w6, MemOperand(x20, 10));
11126   __ Ldapr(x7, MemOperand(x20, 7));
11127   __ Ldaprb(w8, MemOperand(x21, -1));
11128   __ Ldaprh(w9, MemOperand(x21, -3));
11129   __ Ldapr(w10, MemOperand(x21, -9));
11130   __ Ldapr(x11, MemOperand(x21, -12));
11131 
11132   END();
11133 
11134   if (CAN_RUN()) {
11135     RUN();
11136     ASSERT_EQUAL_64(0xef, x0);
11137     ASSERT_EQUAL_64(0xcdef, x1);
11138     ASSERT_EQUAL_64(0x89abcdef, x2);
11139     ASSERT_EQUAL_64(0x0123456789abcdef, x3);
11140     ASSERT_EQUAL_64(0x98, x4);
11141     ASSERT_EQUAL_64(0x3210, x5);
11142     ASSERT_EQUAL_64(0xba987654, x6);
11143     ASSERT_EQUAL_64(0xdcba987654321001, x7);
11144     ASSERT_EQUAL_64(0xfe, x8);
11145     ASSERT_EQUAL_64(0xdcba, x9);
11146     ASSERT_EQUAL_64(0x54321001, x10);
11147     ASSERT_EQUAL_64(0x7654321001234567, x11);
11148   }
11149 }
11150 
11151 
11152 TEST(ldapursb_ldapursh_ldapursw) {
11153   uint64_t data[]
11154       __attribute__((aligned(kXRegSizeInBytes * 2))) = {0x0123456789abcdef,
11155                                                         0xfedcba9876543210};
11156 
11157   uintptr_t data_base = reinterpret_cast<uintptr_t>(data);
11158 
11159   SETUP_WITH_FEATURES(CPUFeatures::kRCpc, CPUFeatures::kRCpcImm);
11160   START();
11161 
11162   __ Mov(x20, data_base);
11163   __ Mov(x21, data_base + 2 * sizeof(data[0]));
11164 
11165   __ Ldapursb(w0, MemOperand(x20));
11166   __ Ldapursb(x1, MemOperand(x20));
11167   __ Ldapursh(w2, MemOperand(x20));
11168   __ Ldapursh(x3, MemOperand(x20));
11169   __ Ldapursw(x4, MemOperand(x20));
11170   __ Ldapursb(w5, MemOperand(x20, 12));
11171   __ Ldapursb(x6, MemOperand(x20, 12));
11172   __ Ldapursh(w7, MemOperand(x20, 13));
11173   __ Ldapursh(x8, MemOperand(x20, 13));
11174   __ Ldapursw(x9, MemOperand(x20, 10));
11175   __ Ldapursb(w10, MemOperand(x21, -1));
11176   __ Ldapursb(x11, MemOperand(x21, -1));
11177   __ Ldapursh(w12, MemOperand(x21, -4));
11178   __ Ldapursh(x13, MemOperand(x21, -4));
11179   __ Ldapursw(x14, MemOperand(x21, -5));
11180 
11181   __ Ldapursb(x15, MemOperand(x20, 8));
11182   __ Ldapursh(x16, MemOperand(x20, 8));
11183   __ Ldapursw(x17, MemOperand(x20, 8));
11184 
11185   END();
11186 
11187   if (CAN_RUN()) {
11188     RUN();
11189     ASSERT_EQUAL_64(0xffffffef, x0);
11190     ASSERT_EQUAL_64(0xffffffffffffffef, x1);
11191     ASSERT_EQUAL_64(0xffffcdef, x2);
11192     ASSERT_EQUAL_64(0xffffffffffffcdef, x3);
11193     ASSERT_EQUAL_64(0xffffffff89abcdef, x4);
11194     ASSERT_EQUAL_64(0xffffff98, x5);
11195     ASSERT_EQUAL_64(0xffffffffffffff98, x6);
11196     ASSERT_EQUAL_64(0xffffdcba, x7);
11197     ASSERT_EQUAL_64(0xffffffffffffdcba, x8);
11198     ASSERT_EQUAL_64(0xffffffffba987654, x9);
11199     ASSERT_EQUAL_64(0xfffffffe, x10);
11200     ASSERT_EQUAL_64(0xfffffffffffffffe, x11);
11201     ASSERT_EQUAL_64(0xffffba98, x12);
11202     ASSERT_EQUAL_64(0xffffffffffffba98, x13);
11203     ASSERT_EQUAL_64(0xffffffffdcba9876, x14);
11204 
11205     ASSERT_EQUAL_64(0x0000000000000010, x15);
11206     ASSERT_EQUAL_64(0x0000000000003210, x16);
11207     ASSERT_EQUAL_64(0x0000000076543210, x17);
11208   }
11209 }
11210 
11211 
11212 TEST(stlurb_stlurh_strlur) {
11213   uint64_t data[] __attribute__((aligned(kXRegSizeInBytes * 2))) = {0x0, 0x0};
11214 
11215   uintptr_t data_base = reinterpret_cast<uintptr_t>(data);
11216 
11217   SETUP_WITH_FEATURES(CPUFeatures::kRCpc, CPUFeatures::kRCpcImm);
11218   START();
11219 
11220   __ Mov(x0, 0x0011223344556677);
11221   __ Mov(x20, data_base);
11222   __ Mov(x21, data_base + 2 * sizeof(data[0]));
11223 
11224   __ Stlrb(w0, MemOperand(x20));
11225   __ Stlrh(w0, MemOperand(x20, 1));
11226   __ Stlr(w0, MemOperand(x20, 3));
11227   __ Stlr(x0, MemOperand(x21, -8));
11228 
11229   END();
11230 
11231   if (CAN_RUN()) {
11232     RUN();
11233     ASSERT_EQUAL_64(0x0044556677667777, data[0]);
11234     ASSERT_EQUAL_64(0x0011223344556677, data[1]);
11235   }
11236 }
11237 
11238 
11239 #define SIMPLE_ATOMIC_OPS(V, DEF) \
11240   V(DEF, add)                     \
11241   V(DEF, clr)                     \
11242   V(DEF, eor)                     \
11243   V(DEF, set)                     \
11244   V(DEF, smax)                    \
11245   V(DEF, smin)                    \
11246   V(DEF, umax)                    \
11247   V(DEF, umin)
11248 
11249 #define SIMPLE_ATOMIC_STORE_MODES(V, NAME) \
11250   V(NAME)                                  \
11251   V(NAME##l)
11252 
11253 #define SIMPLE_ATOMIC_LOAD_MODES(V, NAME) \
11254   SIMPLE_ATOMIC_STORE_MODES(V, NAME)      \
11255   V(NAME##a)                              \
11256   V(NAME##al)
11257 
11258 
11259 TEST(unaligned_single_copy_atomicity) {
11260   uint64_t data0[] = {0x1010101010101010, 0x1010101010101010};
11261   uint64_t dst[] = {0x0000000000000000, 0x0000000000000000};
11262 
11263   uint64_t* data0_aligned = AlignUp(data0, kAtomicAccessGranule);
11264   uint64_t* dst_aligned = AlignUp(dst, kAtomicAccessGranule);
11265 
11266   CPUFeatures features(CPUFeatures::kAtomics,
11267                        CPUFeatures::kLORegions,
11268                        CPUFeatures::kRCpc,
11269                        CPUFeatures::kRCpcImm);
11270   features.Combine(CPUFeatures::kUSCAT);
11271   SETUP_WITH_FEATURES(features);
11272   START();
11273 
11274   __ Mov(x0, 0x0123456789abcdef);
11275   __ Mov(x1, 0x456789abcdef0123);
11276   __ Mov(x2, 0x89abcdef01234567);
11277   __ Mov(x3, 0xcdef0123456789ab);
11278   __ Mov(x18, reinterpret_cast<uintptr_t>(data0_aligned));
11279   __ Mov(x19, reinterpret_cast<uintptr_t>(dst_aligned));
11280   __ Mov(x20, x18);
11281   __ Mov(x21, x19);
11282 
11283   for (unsigned i = 0; i < kAtomicAccessGranule; i++) {
11284     __ Stxrb(w0, w1, MemOperand(x20));
11285     __ Stlxrb(w0, w1, MemOperand(x20));
11286     __ Ldxrb(w0, MemOperand(x20));
11287     __ Ldaxrb(w0, MemOperand(x20));
11288     __ Stllrb(w0, MemOperand(x20));
11289     __ Stlrb(w0, MemOperand(x20));
11290     __ Casb(w0, w1, MemOperand(x20));
11291     __ Caslb(w0, w1, MemOperand(x20));
11292     __ Ldlarb(w0, MemOperand(x20));
11293     __ Ldarb(w0, MemOperand(x20));
11294     __ Casab(w0, w1, MemOperand(x20));
11295     __ Casalb(w0, w1, MemOperand(x20));
11296 
11297     __ Swpb(w0, w1, MemOperand(x20));
11298     __ Swplb(w0, w1, MemOperand(x20));
11299     __ Swpab(w0, w1, MemOperand(x20));
11300     __ Swpalb(w0, w1, MemOperand(x20));
11301     __ Ldaprb(w0, MemOperand(x20));
11302     // Use offset instead of Add to test Stlurb and Ldapurb.
11303     __ Stlrb(w0, MemOperand(x19, i));
11304     __ Ldaprb(w0, MemOperand(x19, i));
11305     __ Ldapursb(w0, MemOperand(x20));
11306     __ Ldapursb(x0, MemOperand(x20));
11307 
11308 #define ATOMIC_LOAD_B(NAME) __ Ld##NAME##b(w0, w1, MemOperand(x20));
11309 #define ATOMIC_STORE_B(NAME) __ St##NAME##b(w0, MemOperand(x20));
11310     SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_LOAD_MODES, ATOMIC_LOAD_B)
11311     SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_STORE_MODES, ATOMIC_STORE_B)
11312 #undef ATOMIC_LOAD_B
11313 #undef ATOMIC_STORE_B
11314 
11315     if (i <= (kAtomicAccessGranule - kHRegSizeInBytes)) {
11316       __ Stxrh(w0, w1, MemOperand(x20));
11317       __ Stlxrh(w0, w1, MemOperand(x20));
11318       __ Ldxrh(w0, MemOperand(x20));
11319       __ Ldaxrh(w0, MemOperand(x20));
11320       __ Stllrh(w0, MemOperand(x20));
11321       __ Stlrh(w0, MemOperand(x20));
11322       __ Cash(w0, w1, MemOperand(x20));
11323       __ Caslh(w0, w1, MemOperand(x20));
11324       __ Ldlarh(w0, MemOperand(x20));
11325       __ Ldarh(w0, MemOperand(x20));
11326       __ Casah(w0, w1, MemOperand(x20));
11327       __ Casalh(w0, w1, MemOperand(x20));
11328 
11329       __ Swph(w0, w1, MemOperand(x20));
11330       __ Swplh(w0, w1, MemOperand(x20));
11331       __ Swpah(w0, w1, MemOperand(x20));
11332       __ Swpalh(w0, w1, MemOperand(x20));
11333       __ Ldaprh(w0, MemOperand(x20));
11334       // Use offset instead of Add to test Stlurh and Ldapurh.
11335       __ Stlrh(w0, MemOperand(x19, i));
11336       __ Ldaprh(w0, MemOperand(x19, i));
11337       __ Ldapursh(w0, MemOperand(x20));
11338       __ Ldapursh(x0, MemOperand(x20));
11339 
11340 #define ATOMIC_LOAD_H(NAME) __ Ld##NAME##h(w0, w1, MemOperand(x20));
11341 #define ATOMIC_STORE_H(NAME) __ St##NAME##h(w0, MemOperand(x20));
11342       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_LOAD_MODES, ATOMIC_LOAD_H)
11343       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_STORE_MODES, ATOMIC_STORE_H)
11344 #undef ATOMIC_LOAD_H
11345 #undef ATOMIC_STORE_H
11346     }
11347 
11348     if (i <= (kAtomicAccessGranule - kWRegSizeInBytes)) {
11349       __ Stxr(w0, w1, MemOperand(x20));
11350       __ Stlxr(w0, w1, MemOperand(x20));
11351       __ Ldxr(w0, MemOperand(x20));
11352       __ Ldaxr(w0, MemOperand(x20));
11353       __ Stllr(w0, MemOperand(x20));
11354       __ Stlr(w0, MemOperand(x20));
11355       __ Cas(w0, w1, MemOperand(x20));
11356       __ Casl(w0, w1, MemOperand(x20));
11357       __ Ldlar(w0, MemOperand(x20));
11358       __ Ldar(w0, MemOperand(x20));
11359       __ Casa(w0, w1, MemOperand(x20));
11360       __ Casal(w0, w1, MemOperand(x20));
11361 
11362       __ Swp(w0, w1, MemOperand(x20));
11363       __ Swpl(w0, w1, MemOperand(x20));
11364       __ Swpa(w0, w1, MemOperand(x20));
11365       __ Swpal(w0, w1, MemOperand(x20));
11366       __ Ldapr(w0, MemOperand(x20));
11367       // Use offset instead of Add to test Stlur and Ldapur.
11368       __ Stlr(w0, MemOperand(x19, i));
11369       __ Ldapr(w0, MemOperand(x19, i));
11370       __ Ldapursw(x0, MemOperand(x20));
11371 
11372 #define ATOMIC_LOAD_W(NAME) __ Ld##NAME(w0, w1, MemOperand(x20));
11373 #define ATOMIC_STORE_W(NAME) __ St##NAME(w0, MemOperand(x20));
11374       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_LOAD_MODES, ATOMIC_LOAD_W)
11375       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_STORE_MODES, ATOMIC_STORE_W)
11376 #undef ATOMIC_LOAD_W
11377 #undef ATOMIC_STORE_W
11378     }
11379 
11380     if (i <= (kAtomicAccessGranule - (kWRegSizeInBytes * 2))) {
11381       __ Casp(w0, w1, w2, w3, MemOperand(x20));
11382       __ Caspl(w0, w1, w2, w3, MemOperand(x20));
11383       __ Caspa(w0, w1, w2, w3, MemOperand(x20));
11384       __ Caspal(w0, w1, w2, w3, MemOperand(x20));
11385       __ Stxp(w0, w1, w2, MemOperand(x20));
11386       __ Stlxp(w0, w1, w2, MemOperand(x20));
11387       __ Ldxp(w0, w1, MemOperand(x20));
11388       __ Ldaxp(w0, w1, MemOperand(x20));
11389     }
11390 
11391     if (i <= (kAtomicAccessGranule - kXRegSizeInBytes)) {
11392       __ Stxr(x0, x1, MemOperand(x20));
11393       __ Stlxr(x0, x1, MemOperand(x20));
11394       __ Ldxr(x0, MemOperand(x20));
11395       __ Ldaxr(x0, MemOperand(x20));
11396       __ Stllr(x0, MemOperand(x20));
11397       __ Stlr(x0, MemOperand(x20));
11398       __ Cas(x0, x1, MemOperand(x20));
11399       __ Casl(x0, x1, MemOperand(x20));
11400       __ Ldlar(x0, MemOperand(x20));
11401       __ Ldar(x0, MemOperand(x20));
11402       __ Casa(x0, x1, MemOperand(x20));
11403       __ Casal(x0, x1, MemOperand(x20));
11404 
11405       __ Swp(x0, x1, MemOperand(x20));
11406       __ Swpl(x0, x1, MemOperand(x20));
11407       __ Swpa(x0, x1, MemOperand(x20));
11408       __ Swpal(x0, x1, MemOperand(x20));
11409       __ Ldapr(x0, MemOperand(x20));
11410       // Use offset instead of Add to test Stlur and Ldapur.
11411       __ Stlr(x0, MemOperand(x19, i));
11412       __ Ldapr(x0, MemOperand(x19, i));
11413 
11414 #define ATOMIC_LOAD_X(NAME) __ Ld##NAME(x0, x1, MemOperand(x20));
11415 #define ATOMIC_STORE_X(NAME) __ St##NAME(x0, MemOperand(x20));
11416       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_LOAD_MODES, ATOMIC_LOAD_X)
11417       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_STORE_MODES, ATOMIC_STORE_X)
11418 #undef ATOMIC_LOAD_X
11419 #undef ATOMIC_STORE_X
11420     }
11421 
11422     if (i <= (kAtomicAccessGranule - (kXRegSizeInBytes * 2))) {
11423       __ Casp(x0, x1, x2, x3, MemOperand(x20));
11424       __ Caspl(x0, x1, x2, x3, MemOperand(x20));
11425       __ Caspa(x0, x1, x2, x3, MemOperand(x20));
11426       __ Caspal(x0, x1, x2, x3, MemOperand(x20));
11427       __ Stxp(x0, x1, x2, MemOperand(x20));
11428       __ Stlxp(x0, x1, x2, MemOperand(x20));
11429       __ Ldxp(x0, x1, MemOperand(x20));
11430       __ Ldaxp(x0, x1, MemOperand(x20));
11431     }
11432 
11433     __ Add(x20, x20, 1);
11434     __ Add(x21, x21, 1);
11435   }
11436   END();
11437 
11438   if (CAN_RUN()) {
11439     // We can't detect kUSCAT with the CPUFeaturesAuditor so it fails the seen
11440     // check.
11441     RUN_WITHOUT_SEEN_FEATURE_CHECK();
11442   }
11443 }
11444 
11445 
11446 #if defined(VIXL_NEGATIVE_TESTING) && defined(VIXL_INCLUDE_SIMULATOR_AARCH64)
11447 
11448 #define CHECK_ALIGN_FAIL(i, expr)                                              \
11449   {                                                                            \
11450     CPUFeatures features(CPUFeatures::kAtomics,                                \
11451                          CPUFeatures::kLORegions,                              \
11452                          CPUFeatures::kRCpc,                                   \
11453                          CPUFeatures::kRCpcImm);                               \
11454     features.Combine(CPUFeatures::kUSCAT);                                     \
11455     SETUP_WITH_FEATURES(features);                                             \
11456     START();                                                                   \
11457     __ Mov(x0, 0x0123456789abcdef);                                            \
11458     __ Mov(x1, 0x456789abcdef0123);                                            \
11459     __ Mov(x2, 0x89abcdef01234567);                                            \
11460     __ Mov(x3, 0xcdef0123456789ab);                                            \
11461     __ Mov(x20, reinterpret_cast<uintptr_t>(data0_aligned));                   \
11462     __ Mov(x21, reinterpret_cast<uintptr_t>(dst_aligned));                     \
11463     __ Add(x20, x20, i);                                                       \
11464     __ Add(x21, x21, i);                                                       \
11465     expr;                                                                      \
11466     END();                                                                     \
11467     if (CAN_RUN()) {                                                           \
11468       /* We can't detect kUSCAT with the CPUFeaturesAuditor so it fails the */ \
11469       /* seen check. */                                                        \
11470       MUST_FAIL_WITH_MESSAGE(RUN_WITHOUT_SEEN_FEATURE_CHECK(),                 \
11471                              "ALIGNMENT EXCEPTION");                           \
11472     }                                                                          \
11473   }
11474 
11475 TEST(unaligned_single_copy_atomicity_negative_test) {
11476   uint64_t data0[] = {0x1010101010101010, 0x1010101010101010};
11477   uint64_t dst[] = {0x0000000000000000, 0x0000000000000000};
11478 
11479   uint64_t* data0_aligned = AlignUp(data0, kAtomicAccessGranule);
11480   uint64_t* dst_aligned = AlignUp(dst, kAtomicAccessGranule);
11481 
11482   for (unsigned i = 0; i < kAtomicAccessGranule; i++) {
11483     if (i > (kAtomicAccessGranule - kHRegSizeInBytes)) {
11484       CHECK_ALIGN_FAIL(i, __ Stxrh(w0, w1, MemOperand(x20)));
11485       CHECK_ALIGN_FAIL(i, __ Stlxrh(w0, w1, MemOperand(x20)));
11486       CHECK_ALIGN_FAIL(i, __ Ldxrh(w0, MemOperand(x20)));
11487       CHECK_ALIGN_FAIL(i, __ Ldaxrh(w0, MemOperand(x20)));
11488       CHECK_ALIGN_FAIL(i, __ Stllrh(w0, MemOperand(x20)));
11489       CHECK_ALIGN_FAIL(i, __ Stlrh(w0, MemOperand(x20)));
11490       CHECK_ALIGN_FAIL(i, __ Cash(w0, w1, MemOperand(x20)));
11491       CHECK_ALIGN_FAIL(i, __ Caslh(w0, w1, MemOperand(x20)));
11492       CHECK_ALIGN_FAIL(i, __ Ldlarh(w0, MemOperand(x20)));
11493       CHECK_ALIGN_FAIL(i, __ Ldarh(w0, MemOperand(x20)));
11494       CHECK_ALIGN_FAIL(i, __ Casah(w0, w1, MemOperand(x20)));
11495       CHECK_ALIGN_FAIL(i, __ Casalh(w0, w1, MemOperand(x20)));
11496 
11497       CHECK_ALIGN_FAIL(i, __ Swph(w0, w1, MemOperand(x20)));
11498       CHECK_ALIGN_FAIL(i, __ Swplh(w0, w1, MemOperand(x20)));
11499       CHECK_ALIGN_FAIL(i, __ Swpah(w0, w1, MemOperand(x20)));
11500       CHECK_ALIGN_FAIL(i, __ Swpalh(w0, w1, MemOperand(x20)));
11501       CHECK_ALIGN_FAIL(i, __ Ldaprh(w0, MemOperand(x20)));
11502       // Use offset instead of Add to test Stlurh and Ldapurh.
11503       CHECK_ALIGN_FAIL(0, __ Stlrh(w0, MemOperand(x20, i)));
11504       CHECK_ALIGN_FAIL(0, __ Ldaprh(w0, MemOperand(x20, i)));
11505       CHECK_ALIGN_FAIL(i, __ Ldapursh(w0, MemOperand(x20)));
11506       CHECK_ALIGN_FAIL(i, __ Ldapursh(x0, MemOperand(x20)));
11507 
11508 #define ATOMIC_LOAD_H(NAME) \
11509   CHECK_ALIGN_FAIL(i, __ Ld##NAME##h(w0, w1, MemOperand(x20)));
11510 #define ATOMIC_STORE_H(NAME) \
11511   CHECK_ALIGN_FAIL(i, __ St##NAME##h(w0, MemOperand(x20)));
11512       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_LOAD_MODES, ATOMIC_LOAD_H)
11513       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_STORE_MODES, ATOMIC_STORE_H)
11514 #undef ATOMIC_LOAD_H
11515 #undef ATOMIC_STORE_H
11516     }
11517 
11518     if (i > (kAtomicAccessGranule - kWRegSizeInBytes)) {
11519       CHECK_ALIGN_FAIL(i, __ Stxr(w0, w1, MemOperand(x20)));
11520       CHECK_ALIGN_FAIL(i, __ Stlxr(w0, w1, MemOperand(x20)));
11521       CHECK_ALIGN_FAIL(i, __ Ldxr(w0, MemOperand(x20)));
11522       CHECK_ALIGN_FAIL(i, __ Ldaxr(w0, MemOperand(x20)));
11523       CHECK_ALIGN_FAIL(i, __ Stllr(w0, MemOperand(x20)));
11524       CHECK_ALIGN_FAIL(i, __ Stlr(w0, MemOperand(x20)));
11525       CHECK_ALIGN_FAIL(i, __ Cas(w0, w1, MemOperand(x20)));
11526       CHECK_ALIGN_FAIL(i, __ Casl(w0, w1, MemOperand(x20)));
11527       CHECK_ALIGN_FAIL(i, __ Ldlar(w0, MemOperand(x20)));
11528       CHECK_ALIGN_FAIL(i, __ Ldar(w0, MemOperand(x20)));
11529       CHECK_ALIGN_FAIL(i, __ Casa(w0, w1, MemOperand(x20)));
11530       CHECK_ALIGN_FAIL(i, __ Casal(w0, w1, MemOperand(x20)));
11531 
11532       CHECK_ALIGN_FAIL(i, __ Swp(w0, w1, MemOperand(x20)));
11533       CHECK_ALIGN_FAIL(i, __ Swpl(w0, w1, MemOperand(x20)));
11534       CHECK_ALIGN_FAIL(i, __ Swpa(w0, w1, MemOperand(x20)));
11535       CHECK_ALIGN_FAIL(i, __ Swpal(w0, w1, MemOperand(x20)));
11536       CHECK_ALIGN_FAIL(i, __ Ldapr(w0, MemOperand(x20)));
11537       // Use offset instead of add to test Stlur and Ldapur.
11538       CHECK_ALIGN_FAIL(0, __ Stlr(w0, MemOperand(x20, i)));
11539       CHECK_ALIGN_FAIL(0, __ Ldapr(w0, MemOperand(x20, i)));
11540       CHECK_ALIGN_FAIL(i, __ Ldapursw(x0, MemOperand(x20)));
11541 
11542 #define ATOMIC_LOAD_W(NAME) \
11543   CHECK_ALIGN_FAIL(i, __ Ld##NAME(w0, w1, MemOperand(x20)));
11544 #define ATOMIC_STORE_W(NAME) \
11545   CHECK_ALIGN_FAIL(i, __ St##NAME(w0, MemOperand(x20)));
11546       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_LOAD_MODES, ATOMIC_LOAD_W)
11547       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_STORE_MODES, ATOMIC_STORE_W)
11548 #undef ATOMIC_LOAD_W
11549 #undef ATOMIC_STORE_W
11550     }
11551 
11552     if (i > (kAtomicAccessGranule - (kWRegSizeInBytes * 2))) {
11553       CHECK_ALIGN_FAIL(i, __ Casp(w0, w1, w2, w3, MemOperand(x20)));
11554       CHECK_ALIGN_FAIL(i, __ Caspl(w0, w1, w2, w3, MemOperand(x20)));
11555       CHECK_ALIGN_FAIL(i, __ Caspa(w0, w1, w2, w3, MemOperand(x20)));
11556       CHECK_ALIGN_FAIL(i, __ Caspal(w0, w1, w2, w3, MemOperand(x20)));
11557       CHECK_ALIGN_FAIL(i, __ Stxp(w0, w1, w2, MemOperand(x20)));
11558       CHECK_ALIGN_FAIL(i, __ Stlxp(w0, w1, w2, MemOperand(x20)));
11559       CHECK_ALIGN_FAIL(i, __ Ldxp(w0, w1, MemOperand(x20)));
11560       CHECK_ALIGN_FAIL(i, __ Ldaxp(w0, w1, MemOperand(x20)));
11561     }
11562 
11563     if (i > (kAtomicAccessGranule - kXRegSizeInBytes)) {
11564       CHECK_ALIGN_FAIL(i, __ Stxr(x0, x1, MemOperand(x20)));
11565       CHECK_ALIGN_FAIL(i, __ Stlxr(x0, x1, MemOperand(x20)));
11566       CHECK_ALIGN_FAIL(i, __ Ldxr(x0, MemOperand(x20)));
11567       CHECK_ALIGN_FAIL(i, __ Ldaxr(x0, MemOperand(x20)));
11568       CHECK_ALIGN_FAIL(i, __ Stllr(x0, MemOperand(x20)));
11569       CHECK_ALIGN_FAIL(i, __ Stlr(x0, MemOperand(x20)));
11570       CHECK_ALIGN_FAIL(i, __ Cas(x0, x1, MemOperand(x20)));
11571       CHECK_ALIGN_FAIL(i, __ Casl(x0, x1, MemOperand(x20)));
11572       CHECK_ALIGN_FAIL(i, __ Ldlar(x0, MemOperand(x20)));
11573       CHECK_ALIGN_FAIL(i, __ Ldar(x0, MemOperand(x20)));
11574       CHECK_ALIGN_FAIL(i, __ Casa(x0, x1, MemOperand(x20)));
11575       CHECK_ALIGN_FAIL(i, __ Casal(x0, x1, MemOperand(x20)));
11576 
11577       CHECK_ALIGN_FAIL(i, __ Swp(x0, x1, MemOperand(x20)));
11578       CHECK_ALIGN_FAIL(i, __ Swpl(x0, x1, MemOperand(x20)));
11579       CHECK_ALIGN_FAIL(i, __ Swpa(x0, x1, MemOperand(x20)));
11580       CHECK_ALIGN_FAIL(i, __ Swpal(x0, x1, MemOperand(x20)));
11581       CHECK_ALIGN_FAIL(i, __ Ldapr(x0, MemOperand(x20)));
11582       // Use offset instead of add to test Stlur and Ldapur.
11583       CHECK_ALIGN_FAIL(0, __ Stlr(x0, MemOperand(x20, i)));
11584       CHECK_ALIGN_FAIL(0, __ Ldapr(x0, MemOperand(x20, i)));
11585 
11586 #define ATOMIC_LOAD_X(NAME) \
11587   CHECK_ALIGN_FAIL(i, __ Ld##NAME(x0, x1, MemOperand(x20)));
11588 #define ATOMIC_STORE_X(NAME) \
11589   CHECK_ALIGN_FAIL(i, __ St##NAME(x0, MemOperand(x20)));
11590       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_LOAD_MODES, ATOMIC_LOAD_X)
11591       SIMPLE_ATOMIC_OPS(SIMPLE_ATOMIC_STORE_MODES, ATOMIC_STORE_X)
11592 #undef ATOMIC_LOAD_X
11593 #undef ATOMIC_STORE_X
11594     }
11595 
11596     if (i > (kAtomicAccessGranule - (kXRegSizeInBytes * 2))) {
11597       CHECK_ALIGN_FAIL(i, __ Casp(x0, x1, x2, x3, MemOperand(x20)));
11598       CHECK_ALIGN_FAIL(i, __ Caspl(x0, x1, x2, x3, MemOperand(x20)));
11599       CHECK_ALIGN_FAIL(i, __ Caspa(x0, x1, x2, x3, MemOperand(x20)));
11600       CHECK_ALIGN_FAIL(i, __ Caspal(x0, x1, x2, x3, MemOperand(x20)));
11601       CHECK_ALIGN_FAIL(i, __ Stxp(x0, x1, x2, MemOperand(x20)));
11602       CHECK_ALIGN_FAIL(i, __ Stlxp(x0, x1, x2, MemOperand(x20)));
11603       CHECK_ALIGN_FAIL(i, __ Ldxp(x0, x1, MemOperand(x20)));
11604       CHECK_ALIGN_FAIL(i, __ Ldaxp(x0, x1, MemOperand(x20)));
11605     }
11606   }
11607 }
11608 
11609 TEST(unaligned_single_copy_atomicity_negative_test_2) {
11610   uint64_t data[] = {0x1010101010101010, 0x1010101010101010};
11611 
11612   uint64_t* data_aligned = AlignUp(data, kAtomicAccessGranule);
11613 
11614   // Check that the same code doesn't fail with USCAT enabled but does
11615   // fail when not enabled.
11616   {
11617     SETUP_WITH_FEATURES(CPUFeatures::kUSCAT);
11618     START();
11619     __ Mov(x0, reinterpret_cast<uintptr_t>(data_aligned));
11620     __ Add(x0, x0, 1);
11621     __ Ldxrh(w1, MemOperand(x0));
11622     END();
11623     if (CAN_RUN()) {
11624       RUN_WITHOUT_SEEN_FEATURE_CHECK();
11625     }
11626   }
11627   {
11628     SETUP();
11629     START();
11630     __ Mov(x0, reinterpret_cast<uintptr_t>(data_aligned));
11631     __ Add(x0, x0, 1);
11632     __ Ldxrh(w1, MemOperand(x0));
11633     END();
11634     if (CAN_RUN()) {
11635       MUST_FAIL_WITH_MESSAGE(RUN(), "ALIGNMENT EXCEPTION");
11636     }
11637   }
11638 }
11639 #endif  // VIXL_NEGATIVE_TESTING && VIXL_INCLUDE_SIMULATOR_AARCH64
11640 
11641 
11642 TEST(load_store_tagged_immediate_offset) {
11643   uint64_t tags[] = {0x00, 0x1, 0x55, 0xff};
11644   int tag_count = sizeof(tags) / sizeof(tags[0]);
11645 
11646   const int kMaxDataLength = 160;
11647 
11648   for (int i = 0; i < tag_count; i++) {
11649     unsigned char src[kMaxDataLength];
11650     uint64_t src_raw = reinterpret_cast<uint64_t>(src);
11651     uint64_t src_tag = tags[i];
11652     uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
11653 
11654     for (int k = 0; k < kMaxDataLength; k++) {
11655       src[k] = k + 1;
11656     }
11657 
11658     for (int j = 0; j < tag_count; j++) {
11659       unsigned char dst[kMaxDataLength];
11660       uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
11661       uint64_t dst_tag = tags[j];
11662       uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
11663 
11664       memset(dst, 0, kMaxDataLength);
11665 
11666       SETUP_WITH_FEATURES(CPUFeatures::kNEON);
11667       START();
11668 
11669       __ Mov(x0, src_tagged);
11670       __ Mov(x1, dst_tagged);
11671 
11672       int offset = 0;
11673 
11674       // Scaled-immediate offsets.
11675       {
11676         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11677         __ ldp(q0, q1, MemOperand(x0, offset));
11678         __ stp(q0, q1, MemOperand(x1, offset));
11679       }
11680       offset += 2 * kQRegSizeInBytes;
11681 
11682       {
11683         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11684         __ ldp(x2, x3, MemOperand(x0, offset));
11685         __ stp(x2, x3, MemOperand(x1, offset));
11686       }
11687       offset += 2 * kXRegSizeInBytes;
11688 
11689       {
11690         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11691         __ ldpsw(x2, x3, MemOperand(x0, offset));
11692         __ stp(w2, w3, MemOperand(x1, offset));
11693       }
11694       offset += 2 * kWRegSizeInBytes;
11695 
11696       {
11697         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11698         __ ldp(d0, d1, MemOperand(x0, offset));
11699         __ stp(d0, d1, MemOperand(x1, offset));
11700       }
11701       offset += 2 * kDRegSizeInBytes;
11702 
11703       {
11704         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11705         __ ldp(w2, w3, MemOperand(x0, offset));
11706         __ stp(w2, w3, MemOperand(x1, offset));
11707       }
11708       offset += 2 * kWRegSizeInBytes;
11709 
11710       {
11711         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11712         __ ldp(s0, s1, MemOperand(x0, offset));
11713         __ stp(s0, s1, MemOperand(x1, offset));
11714       }
11715       offset += 2 * kSRegSizeInBytes;
11716 
11717       {
11718         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11719         __ ldr(x2, MemOperand(x0, offset), RequireScaledOffset);
11720         __ str(x2, MemOperand(x1, offset), RequireScaledOffset);
11721       }
11722       offset += kXRegSizeInBytes;
11723 
11724       {
11725         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11726         __ ldr(d0, MemOperand(x0, offset), RequireScaledOffset);
11727         __ str(d0, MemOperand(x1, offset), RequireScaledOffset);
11728       }
11729       offset += kDRegSizeInBytes;
11730 
11731       {
11732         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11733         __ ldr(w2, MemOperand(x0, offset), RequireScaledOffset);
11734         __ str(w2, MemOperand(x1, offset), RequireScaledOffset);
11735       }
11736       offset += kWRegSizeInBytes;
11737 
11738       {
11739         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11740         __ ldr(s0, MemOperand(x0, offset), RequireScaledOffset);
11741         __ str(s0, MemOperand(x1, offset), RequireScaledOffset);
11742       }
11743       offset += kSRegSizeInBytes;
11744 
11745       {
11746         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11747         __ ldrh(w2, MemOperand(x0, offset), RequireScaledOffset);
11748         __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
11749       }
11750       offset += 2;
11751 
11752       {
11753         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11754         __ ldrsh(w2, MemOperand(x0, offset), RequireScaledOffset);
11755         __ strh(w2, MemOperand(x1, offset), RequireScaledOffset);
11756       }
11757       offset += 2;
11758 
11759       {
11760         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11761         __ ldrb(w2, MemOperand(x0, offset), RequireScaledOffset);
11762         __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
11763       }
11764       offset += 1;
11765 
11766       {
11767         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11768         __ ldrsb(w2, MemOperand(x0, offset), RequireScaledOffset);
11769         __ strb(w2, MemOperand(x1, offset), RequireScaledOffset);
11770       }
11771       offset += 1;
11772 
11773       // Unscaled-immediate offsets.
11774 
11775       {
11776         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11777         __ ldur(x2, MemOperand(x0, offset), RequireUnscaledOffset);
11778         __ stur(x2, MemOperand(x1, offset), RequireUnscaledOffset);
11779       }
11780       offset += kXRegSizeInBytes;
11781 
11782       {
11783         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11784         __ ldur(d0, MemOperand(x0, offset), RequireUnscaledOffset);
11785         __ stur(d0, MemOperand(x1, offset), RequireUnscaledOffset);
11786       }
11787       offset += kDRegSizeInBytes;
11788 
11789       {
11790         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11791         __ ldur(w2, MemOperand(x0, offset), RequireUnscaledOffset);
11792         __ stur(w2, MemOperand(x1, offset), RequireUnscaledOffset);
11793       }
11794       offset += kWRegSizeInBytes;
11795 
11796       {
11797         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11798         __ ldur(s0, MemOperand(x0, offset), RequireUnscaledOffset);
11799         __ stur(s0, MemOperand(x1, offset), RequireUnscaledOffset);
11800       }
11801       offset += kSRegSizeInBytes;
11802 
11803       {
11804         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11805         __ ldurh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
11806         __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
11807       }
11808       offset += 2;
11809 
11810       {
11811         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11812         __ ldursh(w2, MemOperand(x0, offset), RequireUnscaledOffset);
11813         __ sturh(w2, MemOperand(x1, offset), RequireUnscaledOffset);
11814       }
11815       offset += 2;
11816 
11817       {
11818         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11819         __ ldurb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
11820         __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
11821       }
11822       offset += 1;
11823 
11824       {
11825         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11826         __ ldursb(w2, MemOperand(x0, offset), RequireUnscaledOffset);
11827         __ sturb(w2, MemOperand(x1, offset), RequireUnscaledOffset);
11828       }
11829       offset += 1;
11830 
11831       // Extract the tag (so we can test that it was preserved correctly).
11832       __ Ubfx(x0, x0, kAddressTagOffset, kAddressTagWidth);
11833       __ Ubfx(x1, x1, kAddressTagOffset, kAddressTagWidth);
11834 
11835       VIXL_ASSERT(kMaxDataLength >= offset);
11836 
11837       END();
11838       if (CAN_RUN()) {
11839         RUN();
11840 
11841         ASSERT_EQUAL_64(src_tag, x0);
11842         ASSERT_EQUAL_64(dst_tag, x1);
11843 
11844         for (int k = 0; k < offset; k++) {
11845           VIXL_CHECK(src[k] == dst[k]);
11846         }
11847       }
11848     }
11849   }
11850 }
11851 
11852 
11853 TEST(load_store_tagged_immediate_preindex) {
11854   uint64_t tags[] = {0x00, 0x1, 0x55, 0xff};
11855   int tag_count = sizeof(tags) / sizeof(tags[0]);
11856 
11857   const int kMaxDataLength = 128;
11858 
11859   for (int i = 0; i < tag_count; i++) {
11860     unsigned char src[kMaxDataLength];
11861     uint64_t src_raw = reinterpret_cast<uint64_t>(src);
11862     uint64_t src_tag = tags[i];
11863     uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
11864 
11865     for (int k = 0; k < kMaxDataLength; k++) {
11866       src[k] = k + 1;
11867     }
11868 
11869     for (int j = 0; j < tag_count; j++) {
11870       unsigned char dst[kMaxDataLength];
11871       uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
11872       uint64_t dst_tag = tags[j];
11873       uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
11874 
11875       for (int k = 0; k < kMaxDataLength; k++) {
11876         dst[k] = 0;
11877       }
11878 
11879       SETUP_WITH_FEATURES(CPUFeatures::kNEON);
11880       START();
11881 
11882       // Each MemOperand must apply a pre-index equal to the size of the
11883       // previous access.
11884 
11885       // Start with a non-zero preindex.
11886       int preindex = 62 * kXRegSizeInBytes;
11887       int data_length = 0;
11888 
11889       __ Mov(x0, src_tagged - preindex);
11890       __ Mov(x1, dst_tagged - preindex);
11891 
11892       {
11893         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11894         __ ldp(q0, q1, MemOperand(x0, preindex, PreIndex));
11895         __ stp(q0, q1, MemOperand(x1, preindex, PreIndex));
11896       }
11897       preindex = 2 * kQRegSizeInBytes;
11898       data_length = preindex;
11899 
11900       {
11901         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11902         __ ldp(x2, x3, MemOperand(x0, preindex, PreIndex));
11903         __ stp(x2, x3, MemOperand(x1, preindex, PreIndex));
11904       }
11905       preindex = 2 * kXRegSizeInBytes;
11906       data_length += preindex;
11907 
11908       {
11909         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11910         __ ldpsw(x2, x3, MemOperand(x0, preindex, PreIndex));
11911         __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
11912       }
11913       preindex = 2 * kWRegSizeInBytes;
11914       data_length += preindex;
11915 
11916       {
11917         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11918         __ ldp(d0, d1, MemOperand(x0, preindex, PreIndex));
11919         __ stp(d0, d1, MemOperand(x1, preindex, PreIndex));
11920       }
11921       preindex = 2 * kDRegSizeInBytes;
11922       data_length += preindex;
11923 
11924       {
11925         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11926         __ ldp(w2, w3, MemOperand(x0, preindex, PreIndex));
11927         __ stp(w2, w3, MemOperand(x1, preindex, PreIndex));
11928       }
11929       preindex = 2 * kWRegSizeInBytes;
11930       data_length += preindex;
11931 
11932       {
11933         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11934         __ ldp(s0, s1, MemOperand(x0, preindex, PreIndex));
11935         __ stp(s0, s1, MemOperand(x1, preindex, PreIndex));
11936       }
11937       preindex = 2 * kSRegSizeInBytes;
11938       data_length += preindex;
11939 
11940       {
11941         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11942         __ ldr(x2, MemOperand(x0, preindex, PreIndex));
11943         __ str(x2, MemOperand(x1, preindex, PreIndex));
11944       }
11945       preindex = kXRegSizeInBytes;
11946       data_length += preindex;
11947 
11948       {
11949         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11950         __ ldr(d0, MemOperand(x0, preindex, PreIndex));
11951         __ str(d0, MemOperand(x1, preindex, PreIndex));
11952       }
11953       preindex = kDRegSizeInBytes;
11954       data_length += preindex;
11955 
11956       {
11957         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11958         __ ldr(w2, MemOperand(x0, preindex, PreIndex));
11959         __ str(w2, MemOperand(x1, preindex, PreIndex));
11960       }
11961       preindex = kWRegSizeInBytes;
11962       data_length += preindex;
11963 
11964       {
11965         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11966         __ ldr(s0, MemOperand(x0, preindex, PreIndex));
11967         __ str(s0, MemOperand(x1, preindex, PreIndex));
11968       }
11969       preindex = kSRegSizeInBytes;
11970       data_length += preindex;
11971 
11972       {
11973         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11974         __ ldrh(w2, MemOperand(x0, preindex, PreIndex));
11975         __ strh(w2, MemOperand(x1, preindex, PreIndex));
11976       }
11977       preindex = 2;
11978       data_length += preindex;
11979 
11980       {
11981         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11982         __ ldrsh(w2, MemOperand(x0, preindex, PreIndex));
11983         __ strh(w2, MemOperand(x1, preindex, PreIndex));
11984       }
11985       preindex = 2;
11986       data_length += preindex;
11987 
11988       {
11989         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11990         __ ldrb(w2, MemOperand(x0, preindex, PreIndex));
11991         __ strb(w2, MemOperand(x1, preindex, PreIndex));
11992       }
11993       preindex = 1;
11994       data_length += preindex;
11995 
11996       {
11997         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
11998         __ ldrsb(w2, MemOperand(x0, preindex, PreIndex));
11999         __ strb(w2, MemOperand(x1, preindex, PreIndex));
12000       }
12001       preindex = 1;
12002       data_length += preindex;
12003 
12004       VIXL_ASSERT(kMaxDataLength >= data_length);
12005 
12006       END();
12007       if (CAN_RUN()) {
12008         RUN();
12009 
12010         // Check that the preindex was correctly applied in each operation, and
12011         // that the tag was preserved.
12012         ASSERT_EQUAL_64(src_tagged + data_length - preindex, x0);
12013         ASSERT_EQUAL_64(dst_tagged + data_length - preindex, x1);
12014 
12015         for (int k = 0; k < data_length; k++) {
12016           VIXL_CHECK(src[k] == dst[k]);
12017         }
12018       }
12019     }
12020   }
12021 }
12022 
12023 
12024 TEST(load_store_tagged_immediate_postindex) {
12025   uint64_t tags[] = {0x00, 0x1, 0x55, 0xff};
12026   int tag_count = sizeof(tags) / sizeof(tags[0]);
12027 
12028   const int kMaxDataLength = 128;
12029 
12030   for (int i = 0; i < tag_count; i++) {
12031     unsigned char src[kMaxDataLength];
12032     uint64_t src_raw = reinterpret_cast<uint64_t>(src);
12033     uint64_t src_tag = tags[i];
12034     uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
12035 
12036     for (int k = 0; k < kMaxDataLength; k++) {
12037       src[k] = k + 1;
12038     }
12039 
12040     for (int j = 0; j < tag_count; j++) {
12041       unsigned char dst[kMaxDataLength];
12042       uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
12043       uint64_t dst_tag = tags[j];
12044       uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
12045 
12046       for (int k = 0; k < kMaxDataLength; k++) {
12047         dst[k] = 0;
12048       }
12049 
12050       SETUP_WITH_FEATURES(CPUFeatures::kNEON);
12051       START();
12052 
12053       int postindex = 2 * kXRegSizeInBytes;
12054       int data_length = 0;
12055 
12056       __ Mov(x0, src_tagged);
12057       __ Mov(x1, dst_tagged);
12058 
12059       {
12060         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12061         __ ldp(x2, x3, MemOperand(x0, postindex, PostIndex));
12062         __ stp(x2, x3, MemOperand(x1, postindex, PostIndex));
12063       }
12064       data_length = postindex;
12065 
12066       postindex = 2 * kQRegSizeInBytes;
12067       {
12068         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12069         __ ldp(q0, q1, MemOperand(x0, postindex, PostIndex));
12070         __ stp(q0, q1, MemOperand(x1, postindex, PostIndex));
12071       }
12072       data_length += postindex;
12073 
12074       postindex = 2 * kWRegSizeInBytes;
12075       {
12076         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12077         __ ldpsw(x2, x3, MemOperand(x0, postindex, PostIndex));
12078         __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
12079       }
12080       data_length += postindex;
12081 
12082       postindex = 2 * kDRegSizeInBytes;
12083       {
12084         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12085         __ ldp(d0, d1, MemOperand(x0, postindex, PostIndex));
12086         __ stp(d0, d1, MemOperand(x1, postindex, PostIndex));
12087       }
12088       data_length += postindex;
12089 
12090       postindex = 2 * kWRegSizeInBytes;
12091       {
12092         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12093         __ ldp(w2, w3, MemOperand(x0, postindex, PostIndex));
12094         __ stp(w2, w3, MemOperand(x1, postindex, PostIndex));
12095       }
12096       data_length += postindex;
12097 
12098       postindex = 2 * kSRegSizeInBytes;
12099       {
12100         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12101         __ ldp(s0, s1, MemOperand(x0, postindex, PostIndex));
12102         __ stp(s0, s1, MemOperand(x1, postindex, PostIndex));
12103       }
12104       data_length += postindex;
12105 
12106       postindex = kXRegSizeInBytes;
12107       {
12108         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12109         __ ldr(x2, MemOperand(x0, postindex, PostIndex));
12110         __ str(x2, MemOperand(x1, postindex, PostIndex));
12111       }
12112       data_length += postindex;
12113 
12114       postindex = kDRegSizeInBytes;
12115       {
12116         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12117         __ ldr(d0, MemOperand(x0, postindex, PostIndex));
12118         __ str(d0, MemOperand(x1, postindex, PostIndex));
12119       }
12120       data_length += postindex;
12121 
12122       postindex = kWRegSizeInBytes;
12123       {
12124         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12125         __ ldr(w2, MemOperand(x0, postindex, PostIndex));
12126         __ str(w2, MemOperand(x1, postindex, PostIndex));
12127       }
12128       data_length += postindex;
12129 
12130       postindex = kSRegSizeInBytes;
12131       {
12132         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12133         __ ldr(s0, MemOperand(x0, postindex, PostIndex));
12134         __ str(s0, MemOperand(x1, postindex, PostIndex));
12135       }
12136       data_length += postindex;
12137 
12138       postindex = 2;
12139       {
12140         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12141         __ ldrh(w2, MemOperand(x0, postindex, PostIndex));
12142         __ strh(w2, MemOperand(x1, postindex, PostIndex));
12143       }
12144       data_length += postindex;
12145 
12146       postindex = 2;
12147       {
12148         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12149         __ ldrsh(w2, MemOperand(x0, postindex, PostIndex));
12150         __ strh(w2, MemOperand(x1, postindex, PostIndex));
12151       }
12152       data_length += postindex;
12153 
12154       postindex = 1;
12155       {
12156         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12157         __ ldrb(w2, MemOperand(x0, postindex, PostIndex));
12158         __ strb(w2, MemOperand(x1, postindex, PostIndex));
12159       }
12160       data_length += postindex;
12161 
12162       postindex = 1;
12163       {
12164         ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12165         __ ldrsb(w2, MemOperand(x0, postindex, PostIndex));
12166         __ strb(w2, MemOperand(x1, postindex, PostIndex));
12167       }
12168       data_length += postindex;
12169 
12170       VIXL_ASSERT(kMaxDataLength >= data_length);
12171 
12172       END();
12173       if (CAN_RUN()) {
12174         RUN();
12175 
12176         // Check that the postindex was correctly applied in each operation, and
12177         // that the tag was preserved.
12178         ASSERT_EQUAL_64(src_tagged + data_length, x0);
12179         ASSERT_EQUAL_64(dst_tagged + data_length, x1);
12180 
12181         for (int k = 0; k < data_length; k++) {
12182           VIXL_CHECK(src[k] == dst[k]);
12183         }
12184       }
12185     }
12186   }
12187 }
12188 
12189 
12190 TEST(load_store_tagged_register_offset) {
12191   uint64_t tags[] = {0x00, 0x1, 0x55, 0xff};
12192   int tag_count = sizeof(tags) / sizeof(tags[0]);
12193 
12194   const int kMaxDataLength = 128;
12195 
12196   for (int i = 0; i < tag_count; i++) {
12197     unsigned char src[kMaxDataLength];
12198     uint64_t src_raw = reinterpret_cast<uint64_t>(src);
12199     uint64_t src_tag = tags[i];
12200     uint64_t src_tagged = CPU::SetPointerTag(src_raw, src_tag);
12201 
12202     for (int k = 0; k < kMaxDataLength; k++) {
12203       src[k] = k + 1;
12204     }
12205 
12206     for (int j = 0; j < tag_count; j++) {
12207       unsigned char dst[kMaxDataLength];
12208       uint64_t dst_raw = reinterpret_cast<uint64_t>(dst);
12209       uint64_t dst_tag = tags[j];
12210       uint64_t dst_tagged = CPU::SetPointerTag(dst_raw, dst_tag);
12211 
12212       // Also tag the offset register; the operation should still succeed.
12213       for (int o = 0; o < tag_count; o++) {
12214         uint64_t offset_base = CPU::SetPointerTag(UINT64_C(0), tags[o]);
12215         int data_length = 0;
12216 
12217         for (int k = 0; k < kMaxDataLength; k++) {
12218           dst[k] = 0;
12219         }
12220 
12221         SETUP_WITH_FEATURES(CPUFeatures::kNEON);
12222         START();
12223 
12224         __ Mov(x0, src_tagged);
12225         __ Mov(x1, dst_tagged);
12226 
12227         __ Mov(x10, offset_base + data_length);
12228         {
12229           ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12230           __ ldr(x2, MemOperand(x0, x10));
12231           __ str(x2, MemOperand(x1, x10));
12232         }
12233         data_length += kXRegSizeInBytes;
12234 
12235         __ Mov(x10, offset_base + data_length);
12236         {
12237           ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12238           __ ldr(d0, MemOperand(x0, x10));
12239           __ str(d0, MemOperand(x1, x10));
12240         }
12241         data_length += kDRegSizeInBytes;
12242 
12243         __ Mov(x10, offset_base + data_length);
12244         {
12245           ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12246           __ ldr(w2, MemOperand(x0, x10));
12247           __ str(w2, MemOperand(x1, x10));
12248         }
12249         data_length += kWRegSizeInBytes;
12250 
12251         __ Mov(x10, offset_base + data_length);
12252         {
12253           ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12254           __ ldr(s0, MemOperand(x0, x10));
12255           __ str(s0, MemOperand(x1, x10));
12256         }
12257         data_length += kSRegSizeInBytes;
12258 
12259         __ Mov(x10, offset_base + data_length);
12260         {
12261           ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12262           __ ldrh(w2, MemOperand(x0, x10));
12263           __ strh(w2, MemOperand(x1, x10));
12264         }
12265         data_length += 2;
12266 
12267         __ Mov(x10, offset_base + data_length);
12268         {
12269           ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12270           __ ldrsh(w2, MemOperand(x0, x10));
12271           __ strh(w2, MemOperand(x1, x10));
12272         }
12273         data_length += 2;
12274 
12275         __ Mov(x10, offset_base + data_length);
12276         {
12277           ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12278           __ ldrb(w2, MemOperand(x0, x10));
12279           __ strb(w2, MemOperand(x1, x10));
12280         }
12281         data_length += 1;
12282 
12283         __ Mov(x10, offset_base + data_length);
12284         {
12285           ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
12286           __ ldrsb(w2, MemOperand(x0, x10));
12287           __ strb(w2, MemOperand(x1, x10));
12288         }
12289         data_length += 1;
12290 
12291         VIXL_ASSERT(kMaxDataLength >= data_length);
12292 
12293         END();
12294         if (CAN_RUN()) {
12295           RUN();
12296 
12297           // Check that the postindex was correctly applied in each operation,
12298           // and that the tag was preserved.
12299           ASSERT_EQUAL_64(src_tagged, x0);
12300           ASSERT_EQUAL_64(dst_tagged, x1);
12301           ASSERT_EQUAL_64(offset_base + data_length - 1, x10);
12302 
12303           for (int k = 0; k < data_length; k++) {
12304             VIXL_CHECK(src[k] == dst[k]);
12305           }
12306         }
12307       }
12308     }
12309   }
12310 }
12311 
12312 
12313 TEST(load_store_tagged_register_postindex) {
12314   uint64_t src[] = {0x0706050403020100, 0x0f0e0d0c0b0a0908};
12315   uint64_t tags[] = {0x00, 0x1, 0x55, 0xff};
12316   int tag_count = sizeof(tags) / sizeof(tags[0]);
12317 
12318   for (int j = 0; j < tag_count; j++) {
12319     for (int i = 0; i < tag_count; i++) {
12320       SETUP_WITH_FEATURES(CPUFeatures::kNEON);
12321 
12322       uint64_t src_base = reinterpret_cast<uint64_t>(src);
12323       uint64_t src_tagged = CPU::SetPointerTag(src_base, tags[i]);
12324       uint64_t offset_tagged = CPU::SetPointerTag(UINT64_C(0), tags[j]);
12325 
12326       START();
12327       __ Mov(x10, src_tagged);
12328       __ Mov(x11, offset_tagged);
12329       __ Ld1(v0.V16B(), MemOperand(x10, x11, PostIndex));
12330       // TODO: add other instructions (ld2-4, st1-4) as they become available.
12331       END();
12332 
12333       if (CAN_RUN()) {
12334         RUN();
12335 
12336         ASSERT_EQUAL_128(0x0f0e0d0c0b0a0908, 0x0706050403020100, q0);
12337         ASSERT_EQUAL_64(src_tagged + offset_tagged, x10);
12338       }
12339     }
12340   }
12341 }
12342 
12343 
12344 TEST(branch_tagged) {
12345   SETUP();
12346   START();
12347 
12348   Label loop, loop_entry, done;
12349   __ Adr(x0, &loop);
12350   __ Mov(x1, 0);
12351   __ B(&loop_entry);
12352 
12353   __ Bind(&loop);
12354   __ Add(x1, x1, 1);  // Count successful jumps.
12355 
12356   // Advance to the next tag, then bail out if we've come back around to tag 0.
12357   __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
12358   __ Tst(x0, kAddressTagMask);
12359   __ B(eq, &done);
12360 
12361   __ Bind(&loop_entry);
12362   __ Br(x0);
12363 
12364   __ Bind(&done);
12365 
12366   END();
12367   if (CAN_RUN()) {
12368     RUN();
12369 
12370     ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
12371   }
12372 }
12373 
12374 
12375 TEST(branch_and_link_tagged) {
12376   SETUP();
12377   START();
12378 
12379   Label loop, loop_entry, done;
12380   __ Adr(x0, &loop);
12381   __ Mov(x1, 0);
12382   __ B(&loop_entry);
12383 
12384   __ Bind(&loop);
12385 
12386   // Bail out (before counting a successful jump) if lr appears to be tagged.
12387   __ Tst(lr, kAddressTagMask);
12388   __ B(ne, &done);
12389 
12390   __ Add(x1, x1, 1);  // Count successful jumps.
12391 
12392   // Advance to the next tag, then bail out if we've come back around to tag 0.
12393   __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
12394   __ Tst(x0, kAddressTagMask);
12395   __ B(eq, &done);
12396 
12397   __ Bind(&loop_entry);
12398   __ Blr(x0);
12399 
12400   __ Bind(&done);
12401 
12402   END();
12403   if (CAN_RUN()) {
12404     RUN();
12405 
12406     ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
12407   }
12408 }
12409 
12410 
12411 TEST(branch_tagged_and_adr_adrp) {
12412   SETUP_CUSTOM(kPageSize, PageOffsetDependentCode);
12413   START();
12414 
12415   Label loop, loop_entry, done;
12416   __ Adr(x0, &loop);
12417   __ Mov(x1, 0);
12418   __ B(&loop_entry);
12419 
12420   __ Bind(&loop);
12421 
12422   // Bail out (before counting a successful jump) if `adr x10, ...` is tagged.
12423   __ Adr(x10, &done);
12424   __ Tst(x10, kAddressTagMask);
12425   __ B(ne, &done);
12426 
12427   // Bail out (before counting a successful jump) if `adrp x11, ...` is tagged.
12428   __ Adrp(x11, &done);
12429   __ Tst(x11, kAddressTagMask);
12430   __ B(ne, &done);
12431 
12432   __ Add(x1, x1, 1);  // Count successful iterations.
12433 
12434   // Advance to the next tag, then bail out if we've come back around to tag 0.
12435   __ Add(x0, x0, UINT64_C(1) << kAddressTagOffset);
12436   __ Tst(x0, kAddressTagMask);
12437   __ B(eq, &done);
12438 
12439   __ Bind(&loop_entry);
12440   __ Br(x0);
12441 
12442   __ Bind(&done);
12443 
12444   END();
12445   if (CAN_RUN()) {
12446     RUN();
12447 
12448     ASSERT_EQUAL_64(1 << kAddressTagWidth, x1);
12449   }
12450 }
12451 
12452 TEST(system_sys) {
12453   SETUP();
12454   const char* msg = "SYS test!";
12455   uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
12456 
12457   START();
12458   __ Mov(x4, msg_addr);
12459   __ Sys(3, 0x7, 0x5, 1, x4);
12460   __ Mov(x3, x4);
12461   __ Sys(3, 0x7, 0xa, 1, x3);
12462   __ Mov(x2, x3);
12463   __ Sys(3, 0x7, 0xb, 1, x2);
12464   __ Mov(x1, x2);
12465   __ Sys(3, 0x7, 0xe, 1, x1);
12466   // TODO: Add tests to check ZVA equivalent.
12467   END();
12468 
12469   if (CAN_RUN()) {
12470     RUN();
12471   }
12472 }
12473 
12474 
12475 TEST(system_ic) {
12476   SETUP();
12477   const char* msg = "IC test!";
12478   uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
12479 
12480   START();
12481   __ Mov(x11, msg_addr);
12482   __ Ic(IVAU, x11);
12483   END();
12484 
12485   if (CAN_RUN()) {
12486     RUN();
12487   }
12488 }
12489 
12490 
12491 TEST(system_dc) {
12492   SETUP();
12493   const char* msg = "DC test!";
12494   uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
12495 
12496   START();
12497   __ Mov(x20, msg_addr);
12498   __ Dc(CVAC, x20);
12499   __ Mov(x21, msg_addr);
12500   __ Dc(CVAU, x21);
12501   __ Mov(x22, msg_addr);
12502   __ Dc(CIVAC, x22);
12503   // TODO: Add tests to check ZVA.
12504   END();
12505 
12506   if (CAN_RUN()) {
12507     RUN();
12508     ASSERT_EQUAL_64(msg_addr, x20);
12509     ASSERT_EQUAL_64(msg_addr, x21);
12510     ASSERT_EQUAL_64(msg_addr, x22);
12511   }
12512 }
12513 
12514 
12515 TEST(system_dcpop) {
12516   SETUP_WITH_FEATURES(CPUFeatures::kDCPoP);
12517   const char* msg = "DCPoP test!";
12518   uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
12519 
12520   START();
12521   __ Mov(x20, msg_addr);
12522   __ Dc(CVAP, x20);
12523   END();
12524 
12525   if (CAN_RUN()) {
12526     RUN();
12527     ASSERT_EQUAL_64(msg_addr, x20);
12528   }
12529 }
12530 
12531 TEST(system_dccvadp) {
12532   SETUP_WITH_FEATURES(CPUFeatures::kDCCVADP);
12533   const char* msg = "DCCVADP test!";
12534   uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
12535 
12536   START();
12537   __ Mov(x20, msg_addr);
12538   __ Dc(CVADP, x20);
12539   END();
12540 
12541   if (CAN_RUN()) {
12542     RUN();
12543     ASSERT_EQUAL_64(msg_addr, x20);
12544   }
12545 }
12546 
12547 TEST(system_dc_mte) {
12548   SETUP_WITH_FEATURES(CPUFeatures::kMTE);
12549   const char* msg = "DC MTE test!";
12550   uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
12551 
12552   START();
12553   __ Mov(x20, msg_addr);
12554   __ Dc(CGVAC, x20);
12555   __ Dc(CGDVAC, x20);
12556   __ Dc(CGVAP, x20);
12557   __ Dc(CGDVAP, x20);
12558   __ Dc(CIGVAC, x20);
12559   __ Dc(CIGDVAC, x20);
12560   END();
12561 
12562   if (CAN_RUN()) {
12563     RUN();
12564     ASSERT_EQUAL_64(msg_addr, x20);
12565   }
12566 }
12567 
12568 // We currently disable tests for CRC32 instructions when running natively.
12569 // Support for this family of instruction is optional, and so native platforms
12570 // may simply fail to execute the test.
12571 TEST(crc32b) {
12572   SETUP_WITH_FEATURES(CPUFeatures::kCRC32);
12573 
12574   START();
12575 
12576   __ Mov(w0, 0);
12577   __ Mov(w1, 0);
12578   __ Crc32b(w10, w0, w1);
12579 
12580   __ Mov(w0, 0x1);
12581   __ Mov(w1, 0x138);
12582   __ Crc32b(w11, w0, w1);
12583 
12584   __ Mov(w0, 0x1);
12585   __ Mov(w1, 0x38);
12586   __ Crc32b(w12, w0, w1);
12587 
12588   __ Mov(w0, 0);
12589   __ Mov(w1, 128);
12590   __ Crc32b(w13, w0, w1);
12591 
12592   __ Mov(w0, UINT32_MAX);
12593   __ Mov(w1, 255);
12594   __ Crc32b(w14, w0, w1);
12595 
12596   __ Mov(w0, 0x00010001);
12597   __ Mov(w1, 0x10001000);
12598   __ Crc32b(w15, w0, w1);
12599 
12600   END();
12601 
12602   if (CAN_RUN()) {
12603     RUN();
12604 
12605     ASSERT_EQUAL_64(0x0, x10);
12606     ASSERT_EQUAL_64(0x5f058808, x11);
12607     ASSERT_EQUAL_64(0x5f058808, x12);
12608     ASSERT_EQUAL_64(0xedb88320, x13);
12609     ASSERT_EQUAL_64(0x00ffffff, x14);
12610     ASSERT_EQUAL_64(0x77073196, x15);
12611   }
12612 }
12613 
12614 
12615 TEST(crc32h) {
12616   SETUP_WITH_FEATURES(CPUFeatures::kCRC32);
12617 
12618   START();
12619 
12620   __ Mov(w0, 0);
12621   __ Mov(w1, 0);
12622   __ Crc32h(w10, w0, w1);
12623 
12624   __ Mov(w0, 0x1);
12625   __ Mov(w1, 0x10038);
12626   __ Crc32h(w11, w0, w1);
12627 
12628   __ Mov(w0, 0x1);
12629   __ Mov(w1, 0x38);
12630   __ Crc32h(w12, w0, w1);
12631 
12632   __ Mov(w0, 0);
12633   __ Mov(w1, 128);
12634   __ Crc32h(w13, w0, w1);
12635 
12636   __ Mov(w0, UINT32_MAX);
12637   __ Mov(w1, 255);
12638   __ Crc32h(w14, w0, w1);
12639 
12640   __ Mov(w0, 0x00010001);
12641   __ Mov(w1, 0x10001000);
12642   __ Crc32h(w15, w0, w1);
12643 
12644   END();
12645 
12646   if (CAN_RUN()) {
12647     RUN();
12648 
12649     ASSERT_EQUAL_64(0x0, x10);
12650     ASSERT_EQUAL_64(0x0e848dba, x11);
12651     ASSERT_EQUAL_64(0x0e848dba, x12);
12652     ASSERT_EQUAL_64(0x3b83984b, x13);
12653     ASSERT_EQUAL_64(0x2d021072, x14);
12654     ASSERT_EQUAL_64(0x04ac2124, x15);
12655   }
12656 }
12657 
12658 
12659 TEST(crc32w) {
12660   SETUP_WITH_FEATURES(CPUFeatures::kCRC32);
12661 
12662   START();
12663 
12664   __ Mov(w0, 0);
12665   __ Mov(w1, 0);
12666   __ Crc32w(w10, w0, w1);
12667 
12668   __ Mov(w0, 0x1);
12669   __ Mov(w1, 0x80000031);
12670   __ Crc32w(w11, w0, w1);
12671 
12672   __ Mov(w0, 0);
12673   __ Mov(w1, 128);
12674   __ Crc32w(w13, w0, w1);
12675 
12676   __ Mov(w0, UINT32_MAX);
12677   __ Mov(w1, 255);
12678   __ Crc32w(w14, w0, w1);
12679 
12680   __ Mov(w0, 0x00010001);
12681   __ Mov(w1, 0x10001000);
12682   __ Crc32w(w15, w0, w1);
12683 
12684   END();
12685 
12686   if (CAN_RUN()) {
12687     RUN();
12688 
12689     ASSERT_EQUAL_64(0x0, x10);
12690     ASSERT_EQUAL_64(0x1d937b81, x11);
12691     ASSERT_EQUAL_64(0xed59b63b, x13);
12692     ASSERT_EQUAL_64(0x00be2612, x14);
12693     ASSERT_EQUAL_64(0xa036e530, x15);
12694   }
12695 }
12696 
12697 
12698 TEST(crc32x) {
12699   SETUP_WITH_FEATURES(CPUFeatures::kCRC32);
12700 
12701   START();
12702 
12703   __ Mov(w0, 0);
12704   __ Mov(x1, 0);
12705   __ Crc32x(w10, w0, x1);
12706 
12707   __ Mov(w0, 0x1);
12708   __ Mov(x1, UINT64_C(0x0000000800000031));
12709   __ Crc32x(w11, w0, x1);
12710 
12711   __ Mov(w0, 0);
12712   __ Mov(x1, 128);
12713   __ Crc32x(w13, w0, x1);
12714 
12715   __ Mov(w0, UINT32_MAX);
12716   __ Mov(x1, 255);
12717   __ Crc32x(w14, w0, x1);
12718 
12719   __ Mov(w0, 0x00010001);
12720   __ Mov(x1, UINT64_C(0x1000100000000000));
12721   __ Crc32x(w15, w0, x1);
12722 
12723   END();
12724 
12725   if (CAN_RUN()) {
12726     RUN();
12727 
12728     ASSERT_EQUAL_64(0x0, x10);
12729     ASSERT_EQUAL_64(0x40797b92, x11);
12730     ASSERT_EQUAL_64(0x533b85da, x13);
12731     ASSERT_EQUAL_64(0xbc962670, x14);
12732     ASSERT_EQUAL_64(0x0667602f, x15);
12733   }
12734 }
12735 
12736 
12737 TEST(crc32cb) {
12738   SETUP_WITH_FEATURES(CPUFeatures::kCRC32);
12739 
12740   START();
12741 
12742   __ Mov(w0, 0);
12743   __ Mov(w1, 0);
12744   __ Crc32cb(w10, w0, w1);
12745 
12746   __ Mov(w0, 0x1);
12747   __ Mov(w1, 0x138);
12748   __ Crc32cb(w11, w0, w1);
12749 
12750   __ Mov(w0, 0x1);
12751   __ Mov(w1, 0x38);
12752   __ Crc32cb(w12, w0, w1);
12753 
12754   __ Mov(w0, 0);
12755   __ Mov(w1, 128);
12756   __ Crc32cb(w13, w0, w1);
12757 
12758   __ Mov(w0, UINT32_MAX);
12759   __ Mov(w1, 255);
12760   __ Crc32cb(w14, w0, w1);
12761 
12762   __ Mov(w0, 0x00010001);
12763   __ Mov(w1, 0x10001000);
12764   __ Crc32cb(w15, w0, w1);
12765 
12766   END();
12767 
12768   if (CAN_RUN()) {
12769     RUN();
12770 
12771     ASSERT_EQUAL_64(0x0, x10);
12772     ASSERT_EQUAL_64(0x4851927d, x11);
12773     ASSERT_EQUAL_64(0x4851927d, x12);
12774     ASSERT_EQUAL_64(0x82f63b78, x13);
12775     ASSERT_EQUAL_64(0x00ffffff, x14);
12776     ASSERT_EQUAL_64(0xf26b8203, x15);
12777   }
12778 }
12779 
12780 
12781 TEST(crc32ch) {
12782   SETUP_WITH_FEATURES(CPUFeatures::kCRC32);
12783 
12784   START();
12785 
12786   __ Mov(w0, 0);
12787   __ Mov(w1, 0);
12788   __ Crc32ch(w10, w0, w1);
12789 
12790   __ Mov(w0, 0x1);
12791   __ Mov(w1, 0x10038);
12792   __ Crc32ch(w11, w0, w1);
12793 
12794   __ Mov(w0, 0x1);
12795   __ Mov(w1, 0x38);
12796   __ Crc32ch(w12, w0, w1);
12797 
12798   __ Mov(w0, 0);
12799   __ Mov(w1, 128);
12800   __ Crc32ch(w13, w0, w1);
12801 
12802   __ Mov(w0, UINT32_MAX);
12803   __ Mov(w1, 255);
12804   __ Crc32ch(w14, w0, w1);
12805 
12806   __ Mov(w0, 0x00010001);
12807   __ Mov(w1, 0x10001000);
12808   __ Crc32ch(w15, w0, w1);
12809 
12810   END();
12811 
12812   if (CAN_RUN()) {
12813     RUN();
12814 
12815     ASSERT_EQUAL_64(0x0, x10);
12816     ASSERT_EQUAL_64(0xcef8494c, x11);
12817     ASSERT_EQUAL_64(0xcef8494c, x12);
12818     ASSERT_EQUAL_64(0xfbc3faf9, x13);
12819     ASSERT_EQUAL_64(0xad7dacae, x14);
12820     ASSERT_EQUAL_64(0x03fc5f19, x15);
12821   }
12822 }
12823 
12824 
12825 TEST(crc32cw) {
12826   SETUP_WITH_FEATURES(CPUFeatures::kCRC32);
12827 
12828   START();
12829 
12830   __ Mov(w0, 0);
12831   __ Mov(w1, 0);
12832   __ Crc32cw(w10, w0, w1);
12833 
12834   __ Mov(w0, 0x1);
12835   __ Mov(w1, 0x80000031);
12836   __ Crc32cw(w11, w0, w1);
12837 
12838   __ Mov(w0, 0);
12839   __ Mov(w1, 128);
12840   __ Crc32cw(w13, w0, w1);
12841 
12842   __ Mov(w0, UINT32_MAX);
12843   __ Mov(w1, 255);
12844   __ Crc32cw(w14, w0, w1);
12845 
12846   __ Mov(w0, 0x00010001);
12847   __ Mov(w1, 0x10001000);
12848   __ Crc32cw(w15, w0, w1);
12849 
12850   END();
12851 
12852   if (CAN_RUN()) {
12853     RUN();
12854 
12855     ASSERT_EQUAL_64(0x0, x10);
12856     ASSERT_EQUAL_64(0xbcb79ece, x11);
12857     ASSERT_EQUAL_64(0x52a0c93f, x13);
12858     ASSERT_EQUAL_64(0x9f9b5c7a, x14);
12859     ASSERT_EQUAL_64(0xae1b882a, x15);
12860   }
12861 }
12862 
12863 
12864 TEST(crc32cx) {
12865   SETUP_WITH_FEATURES(CPUFeatures::kCRC32);
12866 
12867   START();
12868 
12869   __ Mov(w0, 0);
12870   __ Mov(x1, 0);
12871   __ Crc32cx(w10, w0, x1);
12872 
12873   __ Mov(w0, 0x1);
12874   __ Mov(x1, UINT64_C(0x0000000800000031));
12875   __ Crc32cx(w11, w0, x1);
12876 
12877   __ Mov(w0, 0);
12878   __ Mov(x1, 128);
12879   __ Crc32cx(w13, w0, x1);
12880 
12881   __ Mov(w0, UINT32_MAX);
12882   __ Mov(x1, 255);
12883   __ Crc32cx(w14, w0, x1);
12884 
12885   __ Mov(w0, 0x00010001);
12886   __ Mov(x1, UINT64_C(0x1000100000000000));
12887   __ Crc32cx(w15, w0, x1);
12888 
12889   END();
12890 
12891   if (CAN_RUN()) {
12892     RUN();
12893 
12894     ASSERT_EQUAL_64(0x0, x10);
12895     ASSERT_EQUAL_64(0x7f320fcb, x11);
12896     ASSERT_EQUAL_64(0x34019664, x13);
12897     ASSERT_EQUAL_64(0x6cc27dd0, x14);
12898     ASSERT_EQUAL_64(0xc6f0acdb, x15);
12899   }
12900 }
12901 
12902 TEST(regress_cmp_shift_imm) {
12903   SETUP();
12904 
12905   START();
12906 
12907   __ Mov(x0, 0x3d720c8d);
12908   __ Cmp(x0, Operand(0x3d720c8d));
12909 
12910   END();
12911   if (CAN_RUN()) {
12912     RUN();
12913 
12914     ASSERT_EQUAL_NZCV(ZCFlag);
12915   }
12916 }
12917 
12918 
12919 TEST(compute_address) {
12920   SETUP();
12921 
12922   START();
12923   int64_t base_address = INT64_C(0x123000000abc);
12924   int64_t reg_offset = INT64_C(0x1087654321);
12925   Register base = x0;
12926   Register offset = x1;
12927 
12928   __ Mov(base, base_address);
12929   __ Mov(offset, reg_offset);
12930 
12931 
12932   __ ComputeAddress(x2, MemOperand(base, 0));
12933   __ ComputeAddress(x3, MemOperand(base, 8));
12934   __ ComputeAddress(x4, MemOperand(base, -100));
12935 
12936   __ ComputeAddress(x5, MemOperand(base, offset));
12937   __ ComputeAddress(x6, MemOperand(base, offset, LSL, 2));
12938   __ ComputeAddress(x7, MemOperand(base, offset, LSL, 4));
12939   __ ComputeAddress(x8, MemOperand(base, offset, LSL, 8));
12940 
12941   __ ComputeAddress(x9, MemOperand(base, offset, SXTW));
12942   __ ComputeAddress(x10, MemOperand(base, offset, UXTW, 1));
12943   __ ComputeAddress(x11, MemOperand(base, offset, SXTW, 2));
12944   __ ComputeAddress(x12, MemOperand(base, offset, UXTW, 3));
12945 
12946   END();
12947 
12948   if (CAN_RUN()) {
12949     RUN();
12950 
12951     ASSERT_EQUAL_64(base_address, base);
12952 
12953     ASSERT_EQUAL_64(INT64_C(0x123000000abc), x2);
12954     ASSERT_EQUAL_64(INT64_C(0x123000000ac4), x3);
12955     ASSERT_EQUAL_64(INT64_C(0x123000000a58), x4);
12956 
12957     ASSERT_EQUAL_64(INT64_C(0x124087654ddd), x5);
12958     ASSERT_EQUAL_64(INT64_C(0x12721d951740), x6);
12959     ASSERT_EQUAL_64(INT64_C(0x133876543ccc), x7);
12960     ASSERT_EQUAL_64(INT64_C(0x22b765432bbc), x8);
12961 
12962     ASSERT_EQUAL_64(INT64_C(0x122f87654ddd), x9);
12963     ASSERT_EQUAL_64(INT64_C(0x12310eca90fe), x10);
12964     ASSERT_EQUAL_64(INT64_C(0x122e1d951740), x11);
12965     ASSERT_EQUAL_64(INT64_C(0x12343b2a23c4), x12);
12966   }
12967 }
12968 
12969 
12970 TEST(far_branch_backward) {
12971   // Test that the MacroAssembler correctly resolves backward branches to labels
12972   // that are outside the immediate range of branch instructions.
12973   // Take into account that backward branches can reach one instruction further
12974   // than forward branches.
12975   const int overflow_size =
12976       kInstructionSize +
12977       std::max(Instruction::GetImmBranchForwardRange(TestBranchType),
12978                std::max(Instruction::GetImmBranchForwardRange(
12979                             CompareBranchType),
12980                         Instruction::GetImmBranchForwardRange(CondBranchType)));
12981 
12982   SETUP();
12983   START();
12984 
12985   Label done, fail;
12986   Label test_tbz, test_cbz, test_bcond;
12987   Label success_tbz, success_cbz, success_bcond;
12988 
12989   __ Mov(x0, 0);
12990   __ Mov(x1, 1);
12991   __ Mov(x10, 0);
12992 
12993   __ B(&test_tbz);
12994   __ Bind(&success_tbz);
12995   __ Orr(x0, x0, 1 << 0);
12996   __ B(&test_cbz);
12997   __ Bind(&success_cbz);
12998   __ Orr(x0, x0, 1 << 1);
12999   __ B(&test_bcond);
13000   __ Bind(&success_bcond);
13001   __ Orr(x0, x0, 1 << 2);
13002 
13003   __ B(&done);
13004 
13005   // Generate enough code to overflow the immediate range of the three types of
13006   // branches below.
13007   for (unsigned i = 0; i < overflow_size / kInstructionSize; ++i) {
13008     if (i % 100 == 0) {
13009       // If we do land in this code, we do not want to execute so many nops
13010       // before reaching the end of test (especially if tracing is activated).
13011       __ B(&fail);
13012     } else {
13013       __ Nop();
13014     }
13015   }
13016   __ B(&fail);
13017 
13018   __ Bind(&test_tbz);
13019   __ Tbz(x10, 7, &success_tbz);
13020   __ Bind(&test_cbz);
13021   __ Cbz(x10, &success_cbz);
13022   __ Bind(&test_bcond);
13023   __ Cmp(x10, 0);
13024   __ B(eq, &success_bcond);
13025 
13026   // For each out-of-range branch instructions, at least two instructions should
13027   // have been generated.
13028   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&test_tbz) >=
13029              7 * kInstructionSize);
13030 
13031   __ Bind(&fail);
13032   __ Mov(x1, 0);
13033   __ Bind(&done);
13034 
13035   END();
13036   if (CAN_RUN()) {
13037     RUN();
13038 
13039     ASSERT_EQUAL_64(0x7, x0);
13040     ASSERT_EQUAL_64(0x1, x1);
13041   }
13042 }
13043 
13044 
13045 TEST(single_veneer) {
13046   SETUP();
13047   START();
13048 
13049   const int max_range = Instruction::GetImmBranchForwardRange(TestBranchType);
13050 
13051   Label success, fail, done;
13052 
13053   __ Mov(x0, 0);
13054   __ Mov(x1, 1);
13055   __ Mov(x10, 0);
13056 
13057   __ Tbz(x10, 7, &success);
13058 
13059   // Generate enough code to overflow the immediate range of the `tbz`.
13060   for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
13061     if (i % 100 == 0) {
13062       // If we do land in this code, we do not want to execute so many nops
13063       // before reaching the end of test (especially if tracing is activated).
13064       __ B(&fail);
13065     } else {
13066       __ Nop();
13067     }
13068   }
13069   __ B(&fail);
13070 
13071   __ Bind(&success);
13072   __ Mov(x0, 1);
13073 
13074   __ B(&done);
13075   __ Bind(&fail);
13076   __ Mov(x1, 0);
13077   __ Bind(&done);
13078 
13079   END();
13080   if (CAN_RUN()) {
13081     RUN();
13082 
13083     ASSERT_EQUAL_64(1, x0);
13084     ASSERT_EQUAL_64(1, x1);
13085   }
13086 }
13087 
13088 
13089 TEST(simple_veneers) {
13090   // Test that the MacroAssembler correctly emits veneers for forward branches
13091   // to labels that are outside the immediate range of branch instructions.
13092   const int max_range =
13093       std::max(Instruction::GetImmBranchForwardRange(TestBranchType),
13094                std::max(Instruction::GetImmBranchForwardRange(
13095                             CompareBranchType),
13096                         Instruction::GetImmBranchForwardRange(CondBranchType)));
13097 
13098   SETUP();
13099   START();
13100 
13101   Label done, fail;
13102   Label test_tbz, test_cbz, test_bcond;
13103   Label success_tbz, success_cbz, success_bcond;
13104 
13105   __ Mov(x0, 0);
13106   __ Mov(x1, 1);
13107   __ Mov(x10, 0);
13108 
13109   __ Bind(&test_tbz);
13110   __ Tbz(x10, 7, &success_tbz);
13111   __ Bind(&test_cbz);
13112   __ Cbz(x10, &success_cbz);
13113   __ Bind(&test_bcond);
13114   __ Cmp(x10, 0);
13115   __ B(eq, &success_bcond);
13116 
13117   // Generate enough code to overflow the immediate range of the three types of
13118   // branches below.
13119   for (unsigned i = 0; i < max_range / kInstructionSize + 1; ++i) {
13120     if (i % 100 == 0) {
13121       // If we do land in this code, we do not want to execute so many nops
13122       // before reaching the end of test (especially if tracing is activated).
13123       __ B(&fail);
13124     } else {
13125       __ Nop();
13126     }
13127   }
13128   __ B(&fail);
13129 
13130   __ Bind(&success_tbz);
13131   __ Orr(x0, x0, 1 << 0);
13132   __ B(&test_cbz);
13133   __ Bind(&success_cbz);
13134   __ Orr(x0, x0, 1 << 1);
13135   __ B(&test_bcond);
13136   __ Bind(&success_bcond);
13137   __ Orr(x0, x0, 1 << 2);
13138 
13139   __ B(&done);
13140   __ Bind(&fail);
13141   __ Mov(x1, 0);
13142   __ Bind(&done);
13143 
13144   END();
13145   if (CAN_RUN()) {
13146     RUN();
13147 
13148     ASSERT_EQUAL_64(0x7, x0);
13149     ASSERT_EQUAL_64(0x1, x1);
13150   }
13151 }
13152 
13153 
13154 TEST(veneers_stress) {
13155   SETUP();
13156   START();
13157 
13158   // This is a code generation test stressing the emission of veneers. The code
13159   // generated is not executed.
13160 
13161   Label target;
13162   const unsigned max_range =
13163       Instruction::GetImmBranchForwardRange(CondBranchType);
13164   const unsigned iterations =
13165       (max_range + max_range / 4) / (4 * kInstructionSize);
13166   for (unsigned i = 0; i < iterations; i++) {
13167     __ B(&target);
13168     __ B(eq, &target);
13169     __ Cbz(x0, &target);
13170     __ Tbz(x0, 0, &target);
13171   }
13172   __ Bind(&target);
13173 
13174   END();
13175 }
13176 
13177 
13178 TEST(veneers_two_out_of_range) {
13179   SETUP();
13180   START();
13181 
13182   // This is a code generation test. The code generated is not executed.
13183   // Ensure that the MacroAssembler considers unresolved branches to chose when
13184   // a veneer pool should be emitted. We generate two branches that go out of
13185   // range at the same offset. When the MacroAssembler decides to emit the
13186   // veneer pool, the emission of a first veneer should not cause the other
13187   // branch to go out of range.
13188 
13189   int range_cbz = Instruction::GetImmBranchForwardRange(CompareBranchType);
13190   int range_tbz = Instruction::GetImmBranchForwardRange(TestBranchType);
13191   int max_target = static_cast<int>(masm.GetCursorOffset()) + range_cbz;
13192 
13193   Label done;
13194 
13195   // We use different labels to prevent the MacroAssembler from sharing veneers.
13196   Label target_cbz, target_tbz;
13197 
13198   __ Cbz(x0, &target_cbz);
13199   while (masm.GetCursorOffset() < max_target - range_tbz) {
13200     __ Nop();
13201   }
13202   __ Tbz(x0, 0, &target_tbz);
13203   while (masm.GetCursorOffset() < max_target) {
13204     __ Nop();
13205   }
13206 
13207   // This additional nop makes the branches go out of range.
13208   __ Nop();
13209 
13210   __ Bind(&target_cbz);
13211   __ Bind(&target_tbz);
13212 
13213   END();
13214 }
13215 
13216 
13217 TEST(veneers_hanging) {
13218   SETUP();
13219   START();
13220 
13221   // This is a code generation test. The code generated is not executed.
13222   // Ensure that the MacroAssembler considers unresolved branches to chose when
13223   // a veneer pool should be emitted. This is similar to the
13224   // 'veneers_two_out_of_range' test. We try to trigger the following situation:
13225   //   b.eq label
13226   //   b.eq label
13227   //   ...
13228   //   nop
13229   //   ...
13230   //   cbz x0, label
13231   //   cbz x0, label
13232   //   ...
13233   //   tbz x0, 0 label
13234   //   nop
13235   //   ...
13236   //   nop    <- From here the `b.eq` and `cbz` instructions run out of range,
13237   //             so a literal pool is required.
13238   //   veneer
13239   //   veneer
13240   //   veneer <- The `tbz` runs out of range somewhere in the middle of the
13241   //   veneer    veneer pool.
13242   //   veneer
13243 
13244   const int range_bcond = Instruction::GetImmBranchForwardRange(CondBranchType);
13245   const int range_cbz =
13246       Instruction::GetImmBranchForwardRange(CompareBranchType);
13247   const int range_tbz = Instruction::GetImmBranchForwardRange(TestBranchType);
13248   const int max_target = static_cast<int>(masm.GetCursorOffset()) + range_bcond;
13249 
13250   Label done;
13251   const int n_bcond = 100;
13252   const int n_cbz = 100;
13253   const int n_tbz = 1;
13254   const int kNTotalBranches = n_bcond + n_cbz + n_tbz;
13255 
13256   // We use different labels to prevent the MacroAssembler from sharing veneers.
13257   Label labels[kNTotalBranches];
13258   for (int i = 0; i < kNTotalBranches; i++) {
13259     new (&labels[i]) Label();
13260   }
13261 
13262   for (int i = 0; i < n_bcond; i++) {
13263     __ B(eq, &labels[i]);
13264   }
13265 
13266   while (masm.GetCursorOffset() < max_target - range_cbz) {
13267     __ Nop();
13268   }
13269 
13270   for (int i = 0; i < n_cbz; i++) {
13271     __ Cbz(x0, &labels[n_bcond + i]);
13272   }
13273 
13274   // Ensure the 'tbz' will go out of range after some of the previously
13275   // generated branches.
13276   int margin = (n_bcond / 2) * kInstructionSize;
13277   while (masm.GetCursorOffset() < max_target - range_tbz + margin) {
13278     __ Nop();
13279   }
13280 
13281   __ Tbz(x0, 0, &labels[n_bcond + n_cbz]);
13282 
13283   while (masm.GetCursorOffset() < max_target) {
13284     __ Nop();
13285   }
13286 
13287   // This additional nop makes the 'b.eq' and 'cbz' instructions go out of range
13288   // and forces the emission of a veneer pool. The 'tbz' is not yet out of
13289   // range, but will go out of range while veneers are emitted for the other
13290   // branches.
13291   // The MacroAssembler should ensure that veneers are correctly emitted for all
13292   // the branches, including the 'tbz'. Checks will fail if the target of a
13293   // branch is out of range.
13294   __ Nop();
13295 
13296   for (int i = 0; i < kNTotalBranches; i++) {
13297     __ Bind(&labels[i]);
13298   }
13299 
13300   END();
13301 }
13302 
13303 
13304 TEST(collision_literal_veneer_pools) {
13305   SETUP_WITH_FEATURES(CPUFeatures::kFP);
13306   START();
13307 
13308   // This is a code generation test. The code generated is not executed.
13309 
13310   // Make sure the literal pool is empty;
13311   masm.EmitLiteralPool(LiteralPool::kBranchRequired);
13312   ASSERT_LITERAL_POOL_SIZE(0);
13313 
13314   // We chose the offsets below to (try to) trigger the following situation:
13315   // buffer offset
13316   //              0:   tbz x0, 0, target_tbz ----------------------------------.
13317   //              4:   nop                                                     |
13318   //                   ...                                                     |
13319   //                   nop                                                     |
13320   //    literal gen:   ldr s0, [pc + ...]   ; load from `pool start + 0`       |
13321   //                   ldr s0, [pc + ...]   ; load from `pool start + 4`       |
13322   //                   ...                                                     |
13323   //                   ldr s0, [pc + ...]                                      |
13324   //     pool start:   floating-point literal (0.1)                            |
13325   //                   floating-point literal (1.1)                            |
13326   //                   ...                                                     |
13327   //                   floating-point literal (<n>.1)     <-----tbz-max-range--'
13328   //                   floating-point literal (<n+1>.1)
13329   //                   ...
13330 
13331   const int range_tbz = Instruction::GetImmBranchForwardRange(TestBranchType);
13332   const int max_target = static_cast<int>(masm.GetCursorOffset()) + range_tbz;
13333 
13334   const size_t target_literal_pool_size = 100 * kInstructionSize;
13335   const int offset_start_literal_gen =
13336       target_literal_pool_size + target_literal_pool_size / 2;
13337 
13338 
13339   Label target_tbz;
13340 
13341   __ Tbz(x0, 0, &target_tbz);
13342   VIXL_CHECK(masm.GetNumberOfPotentialVeneers() == 1);
13343   while (masm.GetCursorOffset() < max_target - offset_start_literal_gen) {
13344     __ Nop();
13345   }
13346   VIXL_CHECK(masm.GetNumberOfPotentialVeneers() == 1);
13347 
13348   for (int i = 0; i < 100; i++) {
13349     // Use a different value to force one literal pool entry per iteration.
13350     __ Ldr(s0, i + 0.1);
13351   }
13352   VIXL_CHECK(masm.GetLiteralPoolSize() >= target_literal_pool_size);
13353 
13354   // Force emission of a literal pool.
13355   masm.EmitLiteralPool(LiteralPool::kBranchRequired);
13356   ASSERT_LITERAL_POOL_SIZE(0);
13357 
13358   // The branch should not have gone out of range during the emission of the
13359   // literal pool.
13360   __ Bind(&target_tbz);
13361 
13362   VIXL_CHECK(masm.GetNumberOfPotentialVeneers() == 0);
13363 
13364   END();
13365 }
13366 
13367 
13368 TEST(ldr_literal_explicit) {
13369   SETUP();
13370 
13371   START();
13372   Literal<int64_t> automatically_placed_literal(1, masm.GetLiteralPool());
13373   Literal<int64_t> manually_placed_literal(2);
13374   {
13375     ExactAssemblyScope scope(&masm, kInstructionSize + sizeof(int64_t));
13376     Label over_literal;
13377     __ b(&over_literal);
13378     __ place(&manually_placed_literal);
13379     __ bind(&over_literal);
13380   }
13381   __ Ldr(x1, &manually_placed_literal);
13382   __ Ldr(x2, &automatically_placed_literal);
13383   __ Add(x0, x1, x2);
13384   END();
13385 
13386   if (CAN_RUN()) {
13387     RUN();
13388 
13389     ASSERT_EQUAL_64(3, x0);
13390   }
13391 }
13392 
13393 
13394 TEST(ldr_literal_automatically_placed) {
13395   SETUP_WITH_FEATURES(CPUFeatures::kFP);
13396 
13397   START();
13398 
13399   // We start with an empty literal pool.
13400   ASSERT_LITERAL_POOL_SIZE(0);
13401 
13402   // Create a literal that should be placed by the literal pool.
13403   Literal<int64_t> explicit_literal(2, masm.GetLiteralPool());
13404   // It should not appear in the literal pool until its first use.
13405   ASSERT_LITERAL_POOL_SIZE(0);
13406 
13407   // Check that using standard literals does not break the use of explicitly
13408   // created literals.
13409   __ Ldr(d1, 1.1);
13410   ASSERT_LITERAL_POOL_SIZE(8);
13411   masm.EmitLiteralPool(LiteralPool::kBranchRequired);
13412   ASSERT_LITERAL_POOL_SIZE(0);
13413 
13414   __ Ldr(x2, &explicit_literal);
13415   ASSERT_LITERAL_POOL_SIZE(8);
13416   masm.EmitLiteralPool(LiteralPool::kBranchRequired);
13417   ASSERT_LITERAL_POOL_SIZE(0);
13418 
13419   __ Ldr(d3, 3.3);
13420   ASSERT_LITERAL_POOL_SIZE(8);
13421   masm.EmitLiteralPool(LiteralPool::kBranchRequired);
13422   ASSERT_LITERAL_POOL_SIZE(0);
13423 
13424   // Re-use our explicitly created literal. It has already been placed, so it
13425   // should not impact the literal pool.
13426   __ Ldr(x4, &explicit_literal);
13427   ASSERT_LITERAL_POOL_SIZE(0);
13428 
13429   END();
13430 
13431   if (CAN_RUN()) {
13432     RUN();
13433 
13434     ASSERT_EQUAL_FP64(1.1, d1);
13435     ASSERT_EQUAL_64(2, x2);
13436     ASSERT_EQUAL_FP64(3.3, d3);
13437     ASSERT_EQUAL_64(2, x4);
13438   }
13439 }
13440 
13441 
13442 TEST(literal_update_overwrite) {
13443   SETUP();
13444 
13445   START();
13446 
13447   ASSERT_LITERAL_POOL_SIZE(0);
13448   LiteralPool* literal_pool = masm.GetLiteralPool();
13449 
13450   Literal<int32_t> lit_32_update_before_pool(0xbad, literal_pool);
13451   Literal<int32_t> lit_32_update_after_pool(0xbad, literal_pool);
13452   Literal<int64_t> lit_64_update_before_pool(0xbad, literal_pool);
13453   Literal<int64_t> lit_64_update_after_pool(0xbad, literal_pool);
13454 
13455   ASSERT_LITERAL_POOL_SIZE(0);
13456 
13457   lit_32_update_before_pool.UpdateValue(32);
13458   lit_64_update_before_pool.UpdateValue(64);
13459 
13460   __ Ldr(w1, &lit_32_update_before_pool);
13461   __ Ldr(x2, &lit_64_update_before_pool);
13462   __ Ldr(w3, &lit_32_update_after_pool);
13463   __ Ldr(x4, &lit_64_update_after_pool);
13464 
13465   masm.EmitLiteralPool(LiteralPool::kBranchRequired);
13466 
13467   VIXL_ASSERT(lit_32_update_after_pool.IsPlaced());
13468   VIXL_ASSERT(lit_64_update_after_pool.IsPlaced());
13469   lit_32_update_after_pool.UpdateValue(128, &masm);
13470   lit_64_update_after_pool.UpdateValue(256, &masm);
13471 
13472   END();
13473 
13474   if (CAN_RUN()) {
13475     RUN();
13476 
13477     ASSERT_EQUAL_64(32, x1);
13478     ASSERT_EQUAL_64(64, x2);
13479     ASSERT_EQUAL_64(128, x3);
13480     ASSERT_EQUAL_64(256, x4);
13481   }
13482 }
13483 
13484 
13485 TEST(literal_deletion_policies) {
13486   SETUP();
13487 
13488   START();
13489 
13490   // We cannot check exactly when the deletion of the literals occur, but we
13491   // check that usage of the deletion policies is not broken.
13492 
13493   ASSERT_LITERAL_POOL_SIZE(0);
13494   LiteralPool* literal_pool = masm.GetLiteralPool();
13495 
13496   Literal<int32_t> lit_manual(0xbad, literal_pool);
13497   Literal<int32_t>* lit_deleted_on_placement =
13498       new Literal<int32_t>(0xbad,
13499                            literal_pool,
13500                            RawLiteral::kDeletedOnPlacementByPool);
13501   Literal<int32_t>* lit_deleted_on_pool_destruction =
13502       new Literal<int32_t>(0xbad,
13503                            literal_pool,
13504                            RawLiteral::kDeletedOnPoolDestruction);
13505 
13506   ASSERT_LITERAL_POOL_SIZE(0);
13507 
13508   lit_manual.UpdateValue(32);
13509   lit_deleted_on_placement->UpdateValue(64);
13510 
13511   __ Ldr(w1, &lit_manual);
13512   __ Ldr(w2, lit_deleted_on_placement);
13513   __ Ldr(w3, lit_deleted_on_pool_destruction);
13514 
13515   masm.EmitLiteralPool(LiteralPool::kBranchRequired);
13516 
13517   VIXL_ASSERT(lit_manual.IsPlaced());
13518   VIXL_ASSERT(lit_deleted_on_pool_destruction->IsPlaced());
13519   lit_deleted_on_pool_destruction->UpdateValue(128, &masm);
13520 
13521   END();
13522 
13523   if (CAN_RUN()) {
13524     RUN();
13525 
13526     ASSERT_EQUAL_64(32, x1);
13527     ASSERT_EQUAL_64(64, x2);
13528     ASSERT_EQUAL_64(128, x3);
13529   }
13530 }
13531 
13532 
13533 TEST(generic_operand) {
13534   SETUP_WITH_FEATURES(CPUFeatures::kFP);
13535 
13536   int32_t data_32_array[5] = {0xbadbeef,
13537                               0x11111111,
13538                               0xbadbeef,
13539                               0x33333333,
13540                               0xbadbeef};
13541   int64_t data_64_array[5] = {INT64_C(0xbadbadbadbeef),
13542                               INT64_C(0x1111111111111111),
13543                               INT64_C(0xbadbadbadbeef),
13544                               INT64_C(0x3333333333333333),
13545                               INT64_C(0xbadbadbadbeef)};
13546   size_t size_32 = sizeof(data_32_array[0]);
13547   size_t size_64 = sizeof(data_64_array[0]);
13548 
13549   START();
13550 
13551   intptr_t data_32_address = reinterpret_cast<intptr_t>(&data_32_array[0]);
13552   intptr_t data_64_address = reinterpret_cast<intptr_t>(&data_64_array[0]);
13553   Register data_32 = x27;
13554   Register data_64 = x28;
13555   __ Mov(data_32, data_32_address);
13556   __ Mov(data_64, data_64_address);
13557 
13558   __ Move(GenericOperand(w0),
13559           GenericOperand(MemOperand(data_32, 1 * size_32), size_32));
13560   __ Move(GenericOperand(s0),
13561           GenericOperand(MemOperand(data_32, 3 * size_32), size_32));
13562   __ Move(GenericOperand(x10),
13563           GenericOperand(MemOperand(data_64, 1 * size_64), size_64));
13564   __ Move(GenericOperand(d10),
13565           GenericOperand(MemOperand(data_64, 3 * size_64), size_64));
13566 
13567   __ Move(GenericOperand(w1), GenericOperand(w0));
13568   __ Move(GenericOperand(s1), GenericOperand(s0));
13569   __ Move(GenericOperand(x11), GenericOperand(x10));
13570   __ Move(GenericOperand(d11), GenericOperand(d10));
13571 
13572   __ Move(GenericOperand(MemOperand(data_32, 0 * size_32), size_32),
13573           GenericOperand(w1));
13574   __ Move(GenericOperand(MemOperand(data_32, 2 * size_32), size_32),
13575           GenericOperand(s1));
13576   __ Move(GenericOperand(MemOperand(data_64, 0 * size_64), size_64),
13577           GenericOperand(x11));
13578   __ Move(GenericOperand(MemOperand(data_64, 2 * size_64), size_64),
13579           GenericOperand(d11));
13580 
13581   __ Move(GenericOperand(MemOperand(data_32, 4 * size_32), size_32),
13582           GenericOperand(MemOperand(data_32, 0 * size_32), size_32));
13583   __ Move(GenericOperand(MemOperand(data_64, 4 * size_64), size_64),
13584           GenericOperand(MemOperand(data_64, 0 * size_64), size_64));
13585   END();
13586 
13587   if (CAN_RUN()) {
13588     RUN();
13589 
13590     ASSERT_EQUAL_64(data_32_address, data_32);
13591     ASSERT_EQUAL_64(data_64_address, data_64);
13592 
13593     ASSERT_EQUAL_32(0x11111111, w0);
13594     ASSERT_EQUAL_32(0x33333333, core.sreg_bits(0));
13595     ASSERT_EQUAL_64(INT64_C(0x1111111111111111), x10);
13596     ASSERT_EQUAL_64(INT64_C(0x3333333333333333), core.dreg_bits(10));
13597 
13598     ASSERT_EQUAL_32(0x11111111, w1);
13599     ASSERT_EQUAL_32(0x33333333, core.sreg_bits(1));
13600     ASSERT_EQUAL_64(INT64_C(0x1111111111111111), x11);
13601     ASSERT_EQUAL_64(INT64_C(0x3333333333333333), core.dreg_bits(11));
13602 
13603     VIXL_CHECK(data_32_array[0] == 0x11111111);
13604     VIXL_CHECK(data_32_array[1] == 0x11111111);
13605     VIXL_CHECK(data_32_array[2] == 0x33333333);
13606     VIXL_CHECK(data_32_array[3] == 0x33333333);
13607     VIXL_CHECK(data_32_array[4] == 0x11111111);
13608 
13609     VIXL_CHECK(data_64_array[0] == INT64_C(0x1111111111111111));
13610     VIXL_CHECK(data_64_array[1] == INT64_C(0x1111111111111111));
13611     VIXL_CHECK(data_64_array[2] == INT64_C(0x3333333333333333));
13612     VIXL_CHECK(data_64_array[3] == INT64_C(0x3333333333333333));
13613     VIXL_CHECK(data_64_array[4] == INT64_C(0x1111111111111111));
13614   }
13615 }
13616 
13617 
13618 // Test feature detection of calls to runtime functions.
13619 
13620 // C++11 should be sufficient to provide simulated runtime calls, except for a
13621 // GCC bug before 4.9.1.
13622 #if defined(VIXL_INCLUDE_SIMULATOR_AARCH64) && (__cplusplus >= 201103L) && \
13623     (defined(__clang__) || GCC_VERSION_OR_NEWER(4, 9, 1)) &&               \
13624     !defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT)
13625 #error \
13626     "C++11 should be sufficient to provide support for simulated runtime calls."
13627 #endif  // #if defined(VIXL_INCLUDE_SIMULATOR_AARCH64) && ...
13628 
13629 #if (__cplusplus >= 201103L) && \
13630     !defined(VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT)
13631 #error \
13632     "C++11 should be sufficient to provide support for `MacroAssembler::CallRuntime()`."
13633 #endif  // #if (__cplusplus >= 201103L) && ...
13634 
13635 #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
13636 int32_t runtime_call_add_one(int32_t a) { return a + 1; }
13637 
13638 double runtime_call_add_doubles(double a, double b, double c) {
13639   return a + b + c;
13640 }
13641 
13642 int64_t runtime_call_one_argument_on_stack(int64_t arg1 __attribute__((unused)),
13643                                            int64_t arg2 __attribute__((unused)),
13644                                            int64_t arg3 __attribute__((unused)),
13645                                            int64_t arg4 __attribute__((unused)),
13646                                            int64_t arg5 __attribute__((unused)),
13647                                            int64_t arg6 __attribute__((unused)),
13648                                            int64_t arg7 __attribute__((unused)),
13649                                            int64_t arg8 __attribute__((unused)),
13650                                            int64_t arg9) {
13651   return arg9;
13652 }
13653 
13654 double runtime_call_two_arguments_on_stack(int64_t arg1 __attribute__((unused)),
13655                                            int64_t arg2 __attribute__((unused)),
13656                                            int64_t arg3 __attribute__((unused)),
13657                                            int64_t arg4 __attribute__((unused)),
13658                                            int64_t arg5 __attribute__((unused)),
13659                                            int64_t arg6 __attribute__((unused)),
13660                                            int64_t arg7 __attribute__((unused)),
13661                                            int64_t arg8 __attribute__((unused)),
13662                                            double arg9,
13663                                            double arg10) {
13664   return arg9 - arg10;
13665 }
13666 
13667 void runtime_call_store_at_address(int64_t* address) { *address = 0xf00d; }
13668 
13669 int32_t runtime_call_no_args() { return 1; }
13670 
13671 enum RuntimeCallTestEnum { Enum0 };
13672 
13673 RuntimeCallTestEnum runtime_call_enum(RuntimeCallTestEnum e) { return e; }
13674 
13675 enum class RuntimeCallTestEnumClass { Enum0 };
13676 
13677 RuntimeCallTestEnumClass runtime_call_enum_class(RuntimeCallTestEnumClass e) {
13678   return e;
13679 }
13680 
13681 int8_t test_int8_t(int8_t x) { return x; }
13682 uint8_t test_uint8_t(uint8_t x) { return x; }
13683 int16_t test_int16_t(int16_t x) { return x; }
13684 uint16_t test_uint16_t(uint16_t x) { return x; }
13685 
13686 TEST(runtime_calls) {
13687   SETUP_WITH_FEATURES(CPUFeatures::kFP);
13688 
13689 #ifndef VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT
13690   if (masm.GenerateSimulatorCode()) {
13691     // This configuration is unsupported and a `VIXL_UNREACHABLE()` would fire
13692     // while trying to generate `CallRuntime`. This configuration should only be
13693     // reachable with C++11 and a (buggy) version of GCC pre-4.9.1.
13694     return;
13695   }
13696 #endif
13697 
13698   START();
13699 
13700   // Test `CallRuntime`.
13701 
13702   __ Mov(w0, 0);
13703   __ CallRuntime(runtime_call_add_one);
13704   __ Mov(w20, w0);
13705 
13706   __ Fmov(d0, 0.0);
13707   __ Fmov(d1, 1.5);
13708   __ Fmov(d2, 2.5);
13709   __ CallRuntime(runtime_call_add_doubles);
13710   __ Fmov(d20, d0);
13711 
13712   __ Mov(x0, 0x123);
13713   __ Push(x0, x0);
13714   __ CallRuntime(runtime_call_one_argument_on_stack);
13715   __ Mov(x21, x0);
13716   __ Pop(x0, x1);
13717 
13718   __ Fmov(d0, 314.0);
13719   __ Fmov(d1, 4.0);
13720   __ Push(d1, d0);
13721   __ CallRuntime(runtime_call_two_arguments_on_stack);
13722   __ Fmov(d21, d0);
13723   __ Pop(d1, d0);
13724 
13725   // Test that the template mechanisms don't break with enums.
13726   __ Mov(w0, 0);
13727   __ CallRuntime(runtime_call_enum);
13728   __ Mov(w0, 0);
13729   __ CallRuntime(runtime_call_enum_class);
13730 
13731   // Test `TailCallRuntime`.
13732 
13733   Label function, after_function;
13734   __ B(&after_function);
13735   __ Bind(&function);
13736   __ Mov(x22, 0);
13737   __ Mov(w0, 123);
13738   __ TailCallRuntime(runtime_call_add_one);
13739   // Control should not fall through.
13740   __ Mov(x22, 0xbad);
13741   __ Ret();
13742   __ Bind(&after_function);
13743 
13744   // Call our placeholder function, taking care to preserve the link register.
13745   __ Push(ip0, lr);
13746   __ Bl(&function);
13747   __ Pop(lr, ip0);
13748   // Save the result.
13749   __ Mov(w23, w0);
13750 
13751   __ Mov(x24, 0);
13752   int test_values[] = {static_cast<int8_t>(-1),
13753                        static_cast<uint8_t>(-1),
13754                        static_cast<int16_t>(-1),
13755                        static_cast<uint16_t>(-1),
13756                        -256,
13757                        -1,
13758                        0,
13759                        1,
13760                        256};
13761   for (size_t i = 0; i < sizeof(test_values) / sizeof(test_values[0]); ++i) {
13762     Label pass_int8, pass_uint8, pass_int16, pass_uint16;
13763     int x = test_values[i];
13764     __ Mov(w0, x);
13765     __ CallRuntime(test_int8_t);
13766     __ Sxtb(w0, w0);
13767     __ Cmp(w0, ExtractSignedBitfield32(7, 0, x));
13768     __ Cinc(x24, x24, ne);
13769     __ Mov(w0, x);
13770     __ CallRuntime(test_uint8_t);
13771     __ Uxtb(w0, w0);
13772     __ Cmp(w0, ExtractUnsignedBitfield32(7, 0, x));
13773     __ Cinc(x24, x24, ne);
13774     __ Mov(w0, x);
13775     __ CallRuntime(test_int16_t);
13776     __ Sxth(w0, w0);
13777     __ Cmp(w0, ExtractSignedBitfield32(15, 0, x));
13778     __ Cinc(x24, x24, ne);
13779     __ Mov(w0, x);
13780     __ CallRuntime(test_uint16_t);
13781     __ Uxth(w0, w0);
13782     __ Cmp(w0, ExtractUnsignedBitfield32(15, 0, x));
13783     __ Cinc(x24, x24, ne);
13784   }
13785 
13786 
13787   int64_t value = 0xbadbeef;
13788   __ Mov(x0, reinterpret_cast<uint64_t>(&value));
13789   __ CallRuntime(runtime_call_store_at_address);
13790 
13791   __ Mov(w0, 0);
13792   __ CallRuntime(runtime_call_no_args);
13793   __ Mov(w25, w0);
13794 
13795   END();
13796 
13797 #if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) || \
13798     !defined(VIXL_INCLUDE_SIMULATOR_AARCH64)
13799   if (CAN_RUN()) {
13800     RUN();
13801 
13802     ASSERT_EQUAL_32(1, w20);
13803     ASSERT_EQUAL_FP64(4.0, d20);
13804     ASSERT_EQUAL_64(0x123, x21);
13805     ASSERT_EQUAL_FP64(310.0, d21);
13806     VIXL_CHECK(value == 0xf00d);
13807     ASSERT_EQUAL_64(0, x22);
13808     ASSERT_EQUAL_32(124, w23);
13809     ASSERT_EQUAL_64(0, x24);
13810     ASSERT_EQUAL_32(1, w25);
13811   }
13812 #endif  // #if defined(VIXL_HAS_SIMULATED_RUNTIME_CALL_SUPPORT) || ...
13813 }
13814 
13815 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
13816 void void_func() {}
13817 uint32_t uint32_func() { return 2; }
13818 void void_param_func(uint32_t x) { USE(x); }
13819 uint32_t uint32_param_func(uint32_t x) { return ++x; }
13820 
13821 void void_placeholder() {}
13822 uint32_t uint32_placeholder() { return 4; }
13823 void void_param_placeholder(uint32_t x) { USE(x); }
13824 uint32_t uint32_param_placeholder(uint32_t x) { return ++x; }
13825 
13826 #define DO_TEST_BRANCH_INTERCEPTION(func)        \
13827   __ Mov(x16, reinterpret_cast<uint64_t>(func)); \
13828   __ Blr(x16);
13829 
13830 TEST(branch_interception) {
13831   SETUP();
13832   START();
13833 
13834   // Test default branch interception, i.e: do a runtime call to the function.
13835   DO_TEST_BRANCH_INTERCEPTION(void_func);
13836   DO_TEST_BRANCH_INTERCEPTION(uint32_func);
13837   __ Mov(w20, w0);
13838   DO_TEST_BRANCH_INTERCEPTION(void_param_func);
13839   __ Mov(w0, 2);
13840   DO_TEST_BRANCH_INTERCEPTION(uint32_param_func);
13841   __ Mov(w21, w0);
13842 
13843   // Test interceptions with callbacks.
13844   DO_TEST_BRANCH_INTERCEPTION(void_placeholder);
13845   __ Mov(w22, w0);
13846   DO_TEST_BRANCH_INTERCEPTION(uint32_placeholder);
13847   __ Mov(w23, w0);
13848   __ Mov(w0, 4);
13849   DO_TEST_BRANCH_INTERCEPTION(uint32_placeholder);
13850   __ Mov(w24, w0);
13851   DO_TEST_BRANCH_INTERCEPTION(uint32_placeholder);
13852   __ Mov(w25, w0);
13853 
13854   END();
13855 
13856   simulator.RegisterBranchInterception(void_func);
13857   simulator.RegisterBranchInterception(uint32_func);
13858   simulator.RegisterBranchInterception(void_param_func);
13859   simulator.RegisterBranchInterception(uint32_param_func);
13860 
13861   auto callback = [&simulator](uint64_t original_target) {
13862     USE(original_target);
13863     simulator.WriteWRegister(0, 1);
13864   };
13865 
13866   simulator.RegisterBranchInterception(void_placeholder, callback);
13867   simulator.RegisterBranchInterception(uint32_placeholder, callback);
13868   simulator.RegisterBranchInterception(void_param_placeholder, callback);
13869   simulator.RegisterBranchInterception(uint32_param_placeholder, callback);
13870 
13871   if (CAN_RUN()) {
13872     RUN();
13873 
13874     ASSERT_EQUAL_32(2, w20);
13875     ASSERT_EQUAL_32(3, w21);
13876     ASSERT_EQUAL_32(1, w22);
13877     ASSERT_EQUAL_32(1, w23);
13878     ASSERT_EQUAL_32(1, w24);
13879     ASSERT_EQUAL_32(1, w25);
13880   }
13881 }
13882 #endif  // #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
13883 #endif  // #ifdef VIXL_HAS_MACROASSEMBLER_RUNTIME_CALL_SUPPORT
13884 
13885 
13886 TEST(optimised_mov_register) {
13887   SETUP();
13888 
13889   START();
13890   Label start;
13891   __ Bind(&start);
13892   __ Mov(x0, x0);
13893   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) == 0);
13894   __ Mov(w0, w0, kDiscardForSameWReg);
13895   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) == 0);
13896   __ Mov(w0, w0);
13897   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) == kInstructionSize);
13898 
13899   END();
13900 
13901   if (CAN_RUN()) {
13902     RUN();
13903   }
13904 }
13905 
13906 
13907 TEST(nop) {
13908   MacroAssembler masm;
13909 
13910   Label start;
13911   __ Bind(&start);
13912   __ Nop();
13913   // `MacroAssembler::Nop` must generate at least one nop.
13914   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) >= kInstructionSize);
13915 
13916   masm.FinalizeCode();
13917 }
13918 
13919 
13920 TEST(mte_addg_subg) {
13921   SETUP_WITH_FEATURES(CPUFeatures::kMTE);
13922 
13923   START();
13924   __ Mov(x0, 0x5555000055555555);
13925 
13926   // Add/subtract an address offset, changing tag each time.
13927   __ Addg(x1, x0, 16, 2);
13928   __ Subg(x2, x1, 16, 1);
13929 
13930   // Add/subtract address offsets, keep tag.
13931   __ Addg(x3, x0, 1008, 0);
13932   __ Subg(x4, x3, 1008, 0);
13933 
13934   // Change tag only. Check wraparound.
13935   __ Addg(x5, x0, 0, 15);
13936   __ Subg(x6, x0, 0, 14);
13937 
13938   // Do nothing.
13939   __ Addg(x7, x0, 0, 0);
13940   __ Subg(x8, x0, 0, 0);
13941 
13942   // Use stack pointer as source/destination.
13943   __ Mov(x20, sp);  // Store original sp.
13944 
13945   __ Subg(sp, sp, 32, 0);  // Claim 32 bytes.
13946   __ Sub(x9, sp, x20);     // Subtract original sp and store difference.
13947 
13948   __ Mov(sp, x20);  // Restore original sp.
13949   __ Claim(32);
13950   __ Addg(sp, sp, 32, 0);  // Drop 32 bytes.
13951   __ Sub(x10, sp, x20);    // Subtract original sp and store difference.
13952 
13953   __ Mov(sp, x20);        // Restore sp (should be no-op)
13954   __ Addg(sp, sp, 0, 1);  // Tag the sp.
13955   __ Sub(x11, sp, x20);  // Subtract original sp and store for later comparison.
13956   __ Mov(sp, x20);       // Restore sp.
13957 
13958   END();
13959 
13960   if (CAN_RUN()) {
13961     RUN();
13962 
13963     ASSERT_EQUAL_64(0x5755000055555565, x1);
13964     ASSERT_EQUAL_64(0x5855000055555555, x2);
13965     ASSERT_EQUAL_64(0x5555000055555945, x3);
13966     ASSERT_EQUAL_64(0x5555000055555555, x4);
13967     ASSERT_EQUAL_64(0x5455000055555555, x5);
13968     ASSERT_EQUAL_64(0x5355000055555555, x6);
13969     ASSERT_EQUAL_64(0x5555000055555555, x7);
13970     ASSERT_EQUAL_64(0x5555000055555555, x8);
13971     ASSERT_EQUAL_64(-32, x9);
13972     ASSERT_EQUAL_64(0, x10);
13973     ASSERT_EQUAL_64(UINT64_C(1) << 56, x11);
13974   }
13975 }
13976 
13977 TEST(mte_subp) {
13978   SETUP_WITH_FEATURES(CPUFeatures::kMTE);
13979 
13980   START();
13981   __ Mov(x0, 0x5555555555555555);
13982   __ Mov(x1, -42);
13983 
13984   // Test subp with equivalent sbfx/sub(s) operations.
13985   __ Sbfx(x10, x0, 0, 56);
13986   __ Sbfx(x11, x1, 0, 56);
13987 
13988   __ Subp(x4, x0, x1);
13989   __ Sub(x5, x10, x11);
13990 
13991   __ Subp(x6, x1, x0);
13992   __ Sub(x7, x11, x10);
13993 
13994   __ Subps(x8, x0, x1);
13995   __ Mrs(x18, NZCV);
13996   __ Subs(x9, x10, x11);
13997   __ Mrs(x19, NZCV);
13998 
13999   __ Cmpp(x1, x0);
14000   __ Mrs(x20, NZCV);
14001   __ Cmp(x11, x10);
14002   __ Mrs(x21, NZCV);
14003 
14004   // Test equal pointers with mismatched tags compare equal and produce a zero
14005   // difference with subps.
14006   __ Mov(x2, 0x20);  // Exclude tag 5.
14007   __ Irg(x3, x0, x2);
14008   __ Subps(x22, x0, x3);
14009 
14010   END();
14011 
14012   if (CAN_RUN()) {
14013     RUN();
14014 
14015     ASSERT_EQUAL_64(x5, x4);
14016     ASSERT_EQUAL_64(x7, x6);
14017     ASSERT_EQUAL_64(x9, x8);
14018     ASSERT_EQUAL_64(x19, x18);
14019     ASSERT_EQUAL_64(x20, x21);
14020     ASSERT_EQUAL_64(0, x22);
14021     ASSERT_EQUAL_NZCV(ZCFlag);
14022   }
14023 }
14024 
14025 TEST(mte_gmi) {
14026   SETUP_WITH_FEATURES(CPUFeatures::kMTE);
14027 
14028   START();
14029   __ Mov(x0, 0xaaaa);
14030   __ Mov(x20, 0x12345678);
14031 
14032   __ Gmi(x0, x20, x0);  // Add mask bit 0.
14033   __ Addg(x20, x20, 0, 1);
14034   __ Gmi(x1, x20, x0);  // No effect.
14035   __ Addg(x20, x20, 0, 1);
14036   __ Gmi(x2, x20, x1);  // Add mask bit 2.
14037   __ Addg(x20, x20, 0, 1);
14038   __ Gmi(x3, x20, x2);  // No effect.
14039   __ Addg(x20, x20, 0, 1);
14040   __ Gmi(x4, x20, x3);  // Add mask bit 4.
14041   __ Addg(x20, x20, 0, 1);
14042   __ Gmi(x5, x20, x4);  // No effect.
14043   __ Addg(x20, x20, 0, 9);
14044   __ Gmi(x6, x20, x5);   // Add mask bit 14.
14045   __ Gmi(x7, x20, xzr);  // Only mask bit 14.
14046   END();
14047 
14048   if (CAN_RUN()) {
14049     RUN();
14050 
14051     ASSERT_EQUAL_64(0xaaab, x0);
14052     ASSERT_EQUAL_64(0xaaab, x1);
14053     ASSERT_EQUAL_64(0xaaaf, x2);
14054     ASSERT_EQUAL_64(0xaaaf, x3);
14055     ASSERT_EQUAL_64(0xaabf, x4);
14056     ASSERT_EQUAL_64(0xaabf, x5);
14057     ASSERT_EQUAL_64(0xeabf, x6);
14058     ASSERT_EQUAL_64(0x4000, x7);
14059   }
14060 }
14061 
14062 TEST(mte_irg) {
14063   SETUP_WITH_FEATURES(CPUFeatures::kMTE);
14064 
14065   START();
14066   __ Mov(x10, 8);
14067   __ Mov(x0, 0x5555555555555555);
14068   // Insert a random tag repeatedly. If the loop doesn't exit in the expected
14069   // way, it's statistically likely that a random tag was never inserted.
14070   Label loop, failed, done;
14071   __ Bind(&loop);
14072   __ Irg(x1, x0);
14073   __ Sub(x10, x10, 1);
14074   __ Cbz(x10, &failed);  // Exit if loop count exceeded.
14075   __ Cmp(x1, 0x5555555555555555);
14076   __ B(eq, &loop);  // Loop if the tag hasn't changed.
14077 
14078   // Check non-tag bits have not changed.
14079   __ Bic(x1, x1, 0x0f00000000000000);
14080   __ Subs(x1, x1, 0x5055555555555555);
14081   __ B(&done);
14082 
14083   __ Bind(&failed);
14084   __ Mov(x1, 1);
14085 
14086   __ Bind(&done);
14087 
14088   // Insert random tags, excluding oddly-numbered tags, then orr them together.
14089   // After 128 rounds, it's statistically likely that all but the least
14090   // significant bit will be set.
14091   __ Mov(x3, 0);
14092   __ Mov(x10, 128);
14093   __ Mov(x11, 0xaaaa);
14094 
14095   Label loop2;
14096   __ Bind(&loop2);
14097   __ Irg(x2, x1, x11);
14098   __ Orr(x3, x3, x2);
14099   __ Subs(x10, x10, 1);
14100   __ B(ne, &loop2);
14101   __ Lsr(x2, x3, 56);
14102 
14103   // Check that excluding all tags results in zero tag insertion.
14104   __ Mov(x3, 0xffffffffffffffff);
14105   __ Irg(x3, x3, x3);
14106   END();
14107 
14108   if (CAN_RUN()) {
14109     RUN();
14110 
14111     ASSERT_EQUAL_64(0, x1);
14112     ASSERT_EQUAL_64(0xe, x2);
14113     ASSERT_EQUAL_64(0xf0ffffffffffffff, x3);
14114   }
14115 }
14116 
14117 TEST(mops_set) {
14118   SETUP_WITH_FEATURES(CPUFeatures::kMOPS);
14119 
14120   uint8_t dst[16];
14121   memset(dst, 0x55, ArrayLength(dst));
14122   uintptr_t dst_addr = reinterpret_cast<uintptr_t>(dst);
14123 
14124   START();
14125   __ Mov(x0, dst_addr);
14126   __ Add(x1, x0, 1);
14127   __ Mov(x2, 13);
14128   __ Mov(x3, 0x1234aa);
14129 
14130   // Set 13 bytes dst[1] onwards to 0xaa.
14131   __ Setp(x1, x2, x3);
14132   __ Setm(x1, x2, x3);
14133   __ Sete(x1, x2, x3);
14134 
14135   // x2 is now zero, so this should do nothing.
14136   __ Setp(x1, x2, x3);
14137   __ Setm(x1, x2, x3);
14138   __ Sete(x1, x2, x3);
14139 
14140   // Set dst[15] to zero using the masm helper.
14141   __ Add(x1, x0, 15);
14142   __ Mov(x2, 1);
14143   __ Set(x1, x2, xzr);
14144 
14145   // Load dst for comparison.
14146   __ Ldp(x10, x11, MemOperand(x0));
14147   END();
14148 
14149   if (CAN_RUN()) {
14150     RUN();
14151     ASSERT_EQUAL_64(dst_addr + 16, x1);
14152     ASSERT_EQUAL_64(0, x2);
14153     ASSERT_EQUAL_64(0x1234aa, x3);
14154     ASSERT_EQUAL_64(0xaaaa'aaaa'aaaa'aa55, x10);
14155     ASSERT_EQUAL_64(0x0055'aaaa'aaaa'aaaa, x11);
14156   }
14157 }
14158 
14159 TEST(mops_setn) {
14160   SETUP_WITH_FEATURES(CPUFeatures::kMOPS);
14161 
14162   // In simulation, non-temporal set is handled by the same code as normal set,
14163   // so only a basic test is required beyond that already provided above.
14164 
14165   uint8_t dst[16] = {0x55};
14166   uintptr_t dst_addr = reinterpret_cast<uintptr_t>(dst);
14167 
14168   START();
14169   __ Mov(x0, dst_addr);
14170   __ Mov(x1, x0);
14171   __ Mov(x2, 16);
14172   __ Mov(x3, 0x42);
14173   __ Setn(x1, x2, x3);
14174   __ Ldp(x10, x11, MemOperand(x0));
14175   END();
14176 
14177   if (CAN_RUN()) {
14178     RUN();
14179     ASSERT_EQUAL_64(dst_addr + 16, x1);
14180     ASSERT_EQUAL_64(0, x2);
14181     ASSERT_EQUAL_64(0x42, x3);
14182     ASSERT_EQUAL_64(0x4242'4242'4242'4242, x10);
14183     ASSERT_EQUAL_64(0x4242'4242'4242'4242, x11);
14184   }
14185 }
14186 
14187 TEST(mops_setg) {
14188   SETUP_WITH_FEATURES(CPUFeatures::kMOPS, CPUFeatures::kMTE);
14189 
14190   uint8_t* dst_addr = nullptr;
14191 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
14192   const int dst_size = 32;
14193   dst_addr = reinterpret_cast<uint8_t*>(
14194       simulator.Mmap(NULL,
14195                      dst_size * sizeof(uint8_t),
14196                      PROT_READ | PROT_WRITE | PROT_MTE,
14197                      MAP_PRIVATE | MAP_ANONYMOUS,
14198                      -1,
14199                      0));
14200 
14201   VIXL_ASSERT(dst_addr != nullptr);
14202   uint8_t* untagged_ptr = AddressUntag(dst_addr);
14203   memset(untagged_ptr, 0xc9, dst_size);
14204 #else
14205 // TODO: Port the memory allocation to work on MTE supported platform natively.
14206 // Note that `CAN_RUN` prevents running in MTE-unsupported environments.
14207 #endif
14208 
14209   START();
14210   __ Mov(x0, reinterpret_cast<uint64_t>(dst_addr));
14211   __ Gmi(x2, x0, xzr);
14212   __ Irg(x1, x0, x2);  // Choose new tag for setg destination.
14213   __ Mov(x2, 16);
14214   __ Mov(x3, 0x42);
14215   __ Setg(x1, x2, x3);
14216 
14217   __ Ubfx(x4, x1, 56, 4);  // Extract new tag.
14218   __ Bfi(x0, x4, 56, 4);   // Tag dst_addr so set region can be loaded.
14219   __ Ldp(x10, x11, MemOperand(x0));
14220 
14221   __ Mov(x0, reinterpret_cast<uint64_t>(dst_addr));
14222   __ Ldp(x12, x13, MemOperand(x0, 16));  // Unset region has original tag.
14223   END();
14224 
14225   if (CAN_RUN()) {
14226     RUN();
14227     ASSERT_EQUAL_64(0, x2);
14228     ASSERT_EQUAL_64(0x42, x3);
14229     ASSERT_EQUAL_64(0x4242'4242'4242'4242, x10);
14230     ASSERT_EQUAL_64(0x4242'4242'4242'4242, x11);
14231     ASSERT_EQUAL_64(0xc9c9'c9c9'c9c9'c9c9, x12);
14232     ASSERT_EQUAL_64(0xc9c9'c9c9'c9c9'c9c9, x13);
14233   }
14234 
14235 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
14236   simulator.Munmap(dst_addr, dst_size, PROT_MTE);
14237 #endif
14238 }
14239 
14240 TEST(mops_cpy) {
14241   SETUP_WITH_FEATURES(CPUFeatures::kMOPS);
14242 
14243   uint8_t buf[16];
14244   uintptr_t buf_addr = reinterpret_cast<uintptr_t>(buf);
14245 
14246   for (unsigned i = 0; i < ArrayLength(buf); i++) {
14247     buf[i] = i;
14248   }
14249 
14250   START();
14251   __ Mov(x0, buf_addr);
14252 
14253   // Copy first eight bytes into second eight.
14254   __ Mov(x2, x0);     // src = &buf[0]
14255   __ Add(x3, x0, 8);  // dst = &buf[8]
14256   __ Mov(x4, 8);      // count = 8
14257   __ Cpyp(x3, x2, x4);
14258   __ Cpym(x3, x2, x4);
14259   __ Cpye(x3, x2, x4);
14260   __ Ldp(x10, x11, MemOperand(x0));
14261   __ Mrs(x20, NZCV);
14262 
14263   // Copy first eight bytes to overlapping offset, causing reverse copy.
14264   __ Mov(x5, x0);     // src = &buf[0]
14265   __ Add(x6, x0, 4);  // dst = &buf[4]
14266   __ Mov(x7, 8);      // count = 8
14267   __ Cpy(x6, x5, x7);
14268   __ Ldp(x12, x13, MemOperand(x0));
14269   END();
14270 
14271   if (CAN_RUN()) {
14272     RUN();
14273     ASSERT_EQUAL_64(buf_addr + 8, x2);
14274     ASSERT_EQUAL_64(buf_addr + 16, x3);
14275     ASSERT_EQUAL_64(0, x4);
14276     ASSERT_EQUAL_64(0x0706'0504'0302'0100, x10);
14277     ASSERT_EQUAL_64(0x0706'0504'0302'0100, x11);
14278     ASSERT_EQUAL_64(CFlag, x20);
14279 
14280     ASSERT_EQUAL_64(buf_addr, x5);
14281     ASSERT_EQUAL_64(buf_addr + 4, x6);
14282     ASSERT_EQUAL_64(0, x7);
14283     ASSERT_EQUAL_64(0x0302'0100'0302'0100, x12);
14284     ASSERT_EQUAL_64(0x0706'0504'0706'0504, x13);
14285     ASSERT_EQUAL_NZCV(NCFlag);
14286   }
14287 }
14288 
14289 TEST(mops_cpyn) {
14290   SETUP_WITH_FEATURES(CPUFeatures::kMOPS);
14291 
14292   // In simulation, non-temporal cpy is handled by the same code as normal cpy,
14293   // so only a basic test is required beyond that already provided above.
14294 
14295   uint8_t buf[16];
14296   uintptr_t buf_addr = reinterpret_cast<uintptr_t>(buf);
14297 
14298   for (unsigned i = 0; i < ArrayLength(buf); i++) {
14299     buf[i] = i;
14300   }
14301 
14302   START();
14303   __ Mov(x0, buf_addr);
14304 
14305   __ Add(x2, x0, 1);  // src = &buf[1]
14306   __ Mov(x3, x0);     // dst = &buf[0]
14307   __ Mov(x4, 15);     // count = 15
14308   __ Cpyn(x3, x2, x4);
14309   __ Ldp(x10, x11, MemOperand(x0));
14310 
14311   __ Add(x5, x0, 1);  // src = &buf[1]
14312   __ Mov(x6, x0);     // dst = &buf[0]
14313   __ Mov(x4, 15);     // count = 15
14314   __ Cpyrn(x6, x5, x4);
14315   __ Ldp(x12, x13, MemOperand(x0));
14316 
14317   __ Add(x7, x0, 1);  // src = &buf[1]
14318   __ Mov(x8, x0);     // dst = &buf[0]
14319   __ Mov(x4, 15);     // count = 15
14320   __ Cpywn(x8, x7, x4);
14321   __ Ldp(x14, x15, MemOperand(x0));
14322   END();
14323 
14324   if (CAN_RUN()) {
14325     RUN();
14326     ASSERT_EQUAL_64(buf_addr + 16, x2);
14327     ASSERT_EQUAL_64(buf_addr + 15, x3);
14328     ASSERT_EQUAL_64(0x0807'0605'0403'0201, x10);
14329     ASSERT_EQUAL_64(0x0f0f'0e0d'0c0b'0a09, x11);
14330 
14331     ASSERT_EQUAL_64(buf_addr + 16, x5);
14332     ASSERT_EQUAL_64(buf_addr + 15, x6);
14333     ASSERT_EQUAL_64(0x0908'0706'0504'0302, x12);
14334     ASSERT_EQUAL_64(0x0f0f'0f0e'0d0c'0b0a, x13);
14335 
14336     ASSERT_EQUAL_64(buf_addr + 16, x7);
14337     ASSERT_EQUAL_64(buf_addr + 15, x8);
14338     ASSERT_EQUAL_64(0x0a09'0807'0605'0403, x14);
14339     ASSERT_EQUAL_64(0x0f0f'0f0f'0e0d'0c0b, x15);
14340 
14341     ASSERT_EQUAL_64(0, x4);
14342     ASSERT_EQUAL_NZCV(CFlag);
14343   }
14344 }
14345 
14346 TEST(mops_cpyf) {
14347   SETUP_WITH_FEATURES(CPUFeatures::kMOPS);
14348 
14349   uint8_t buf[16];
14350   uintptr_t buf_addr = reinterpret_cast<uintptr_t>(buf);
14351 
14352   for (unsigned i = 0; i < ArrayLength(buf); i++) {
14353     buf[i] = i;
14354   }
14355 
14356   // This test matches the cpy variant above, but using cpyf will result in a
14357   // different answer for the overlapping copy.
14358   START();
14359   __ Mov(x0, buf_addr);
14360 
14361   // Copy first eight bytes into second eight.
14362   __ Mov(x2, x0);     // src = &buf[0]
14363   __ Add(x3, x0, 8);  // dst = &buf[8]
14364   __ Mov(x4, 8);      // count = 8
14365   __ Cpyf(x3, x2, x4);
14366   __ Ldp(x10, x11, MemOperand(x0));
14367   __ Mrs(x20, NZCV);
14368 
14369   // Copy first eight bytes to overlapping offset.
14370   __ Mov(x5, x0);     // src = &buf[0]
14371   __ Add(x6, x0, 4);  // dst = &buf[4]
14372   __ Mov(x7, 8);      // count = 8
14373   __ Cpyf(x6, x5, x7);
14374   __ Ldp(x12, x13, MemOperand(x0));
14375   END();
14376 
14377   if (CAN_RUN()) {
14378     RUN();
14379     ASSERT_EQUAL_64(buf_addr + 8, x2);
14380     ASSERT_EQUAL_64(buf_addr + 16, x3);
14381     ASSERT_EQUAL_64(0, x4);
14382     ASSERT_EQUAL_64(0x0706'0504'0302'0100, x10);
14383     ASSERT_EQUAL_64(0x0706'0504'0302'0100, x11);
14384     ASSERT_EQUAL_64(CFlag, x20);
14385 
14386     ASSERT_EQUAL_64(buf_addr + 8, x5);
14387     ASSERT_EQUAL_64(buf_addr + 12, x6);
14388     ASSERT_EQUAL_64(0, x7);
14389     ASSERT_EQUAL_NZCV(CFlag);
14390 
14391     // These results are not architecturally defined. They may change if the
14392     // simulator is implemented in a different, but still architecturally
14393     // correct, way.
14394     ASSERT_EQUAL_64(0x0302'0100'0302'0100, x12);
14395     ASSERT_EQUAL_64(0x0706'0504'0302'0100, x13);
14396   }
14397 }
14398 
14399 TEST(mops_cpyfn) {
14400   SETUP_WITH_FEATURES(CPUFeatures::kMOPS);
14401 
14402   // In simulation, non-temporal cpy is handled by the same code as normal cpy,
14403   // so only a basic test is required beyond that already provided above.
14404 
14405   uint8_t buf[16];
14406   uintptr_t buf_addr = reinterpret_cast<uintptr_t>(buf);
14407 
14408   for (unsigned i = 0; i < ArrayLength(buf); i++) {
14409     buf[i] = i;
14410   }
14411 
14412   START();
14413   __ Mov(x0, buf_addr);
14414 
14415   __ Add(x2, x0, 1);  // src = &buf[1]
14416   __ Mov(x3, x0);     // dst = &buf[0]
14417   __ Mov(x4, 15);     // count = 15
14418   __ Cpyfn(x3, x2, x4);
14419   __ Ldp(x10, x11, MemOperand(x0));
14420 
14421   __ Add(x5, x0, 1);  // src = &buf[1]
14422   __ Mov(x6, x0);     // dst = &buf[0]
14423   __ Mov(x4, 15);     // count = 15
14424   __ Cpyfrn(x6, x5, x4);
14425   __ Ldp(x12, x13, MemOperand(x0));
14426 
14427   __ Add(x7, x0, 1);  // src = &buf[1]
14428   __ Mov(x8, x0);     // dst = &buf[0]
14429   __ Mov(x4, 15);     // count = 15
14430   __ Cpyfwn(x8, x7, x4);
14431   __ Ldp(x14, x15, MemOperand(x0));
14432   END();
14433 
14434   if (CAN_RUN()) {
14435     RUN();
14436     ASSERT_EQUAL_64(buf_addr + 16, x2);
14437     ASSERT_EQUAL_64(buf_addr + 15, x3);
14438     ASSERT_EQUAL_64(0x0807'0605'0403'0201, x10);
14439     ASSERT_EQUAL_64(0x0f0f'0e0d'0c0b'0a09, x11);
14440 
14441     ASSERT_EQUAL_64(buf_addr + 16, x5);
14442     ASSERT_EQUAL_64(buf_addr + 15, x6);
14443     ASSERT_EQUAL_64(0x0908'0706'0504'0302, x12);
14444     ASSERT_EQUAL_64(0x0f0f'0f0e'0d0c'0b0a, x13);
14445 
14446     ASSERT_EQUAL_64(buf_addr + 16, x7);
14447     ASSERT_EQUAL_64(buf_addr + 15, x8);
14448     ASSERT_EQUAL_64(0x0a09'0807'0605'0403, x14);
14449     ASSERT_EQUAL_64(0x0f0f'0f0f'0e0d'0c0b, x15);
14450 
14451     ASSERT_EQUAL_64(0, x4);
14452     ASSERT_EQUAL_NZCV(CFlag);
14453   }
14454 }
14455 
14456 TEST(cssc_abs) {
14457   SETUP_WITH_FEATURES(CPUFeatures::kCSSC);
14458 
14459   START();
14460   __ Mov(x0, -1);
14461   __ Mov(x1, 1);
14462   __ Mov(x2, 0);
14463   __ Mov(x3, 0x7fff'ffff);
14464   __ Mov(x4, 0x8000'0000);
14465   __ Mov(x5, 0x8000'0001);
14466   __ Mov(x6, 0x7fff'ffff'ffff'ffff);
14467   __ Mov(x7, 0x8000'0000'0000'0000);
14468   __ Mov(x8, 0x8000'0000'0000'0001);
14469 
14470   __ Abs(w10, w0);
14471   __ Abs(x11, x0);
14472   __ Abs(w12, w1);
14473   __ Abs(x13, x1);
14474   __ Abs(w14, w2);
14475   __ Abs(x15, x2);
14476 
14477   __ Abs(w19, w3);
14478   __ Abs(x20, x3);
14479   __ Abs(w21, w4);
14480   __ Abs(x22, x4);
14481   __ Abs(w23, w5);
14482   __ Abs(x24, x5);
14483   __ Abs(w25, w6);
14484   __ Abs(x26, x6);
14485   __ Abs(w27, w7);
14486   __ Abs(x28, x7);
14487   __ Abs(w29, w8);
14488   __ Abs(x30, x8);
14489   END();
14490 
14491   if (CAN_RUN()) {
14492     RUN();
14493 
14494     ASSERT_EQUAL_64(1, x10);
14495     ASSERT_EQUAL_64(1, x11);
14496     ASSERT_EQUAL_64(1, x12);
14497     ASSERT_EQUAL_64(1, x13);
14498     ASSERT_EQUAL_64(0, x14);
14499     ASSERT_EQUAL_64(0, x15);
14500     ASSERT_EQUAL_64(0x7fff'ffff, x19);
14501     ASSERT_EQUAL_64(0x7fff'ffff, x20);
14502     ASSERT_EQUAL_64(0x8000'0000, x21);
14503     ASSERT_EQUAL_64(0x8000'0000, x22);
14504     ASSERT_EQUAL_64(0x7fff'ffff, x23);
14505     ASSERT_EQUAL_64(0x8000'0001, x24);
14506     ASSERT_EQUAL_64(1, x25);
14507     ASSERT_EQUAL_64(0x7fff'ffff'ffff'ffff, x26);
14508     ASSERT_EQUAL_64(0, x27);
14509     ASSERT_EQUAL_64(0x8000'0000'0000'0000, x28);
14510     ASSERT_EQUAL_64(1, x29);
14511     ASSERT_EQUAL_64(0x7fff'ffff'ffff'ffff, x30);
14512   }
14513 }
14514 
14515 TEST(cssc_cnt) {
14516   SETUP_WITH_FEATURES(CPUFeatures::kCSSC);
14517 
14518   START();
14519   __ Mov(x0, -1);
14520   __ Mov(x1, 1);
14521   __ Mov(x2, 0);
14522   __ Mov(x3, 0x7fff'ffff);
14523   __ Mov(x4, 0x8000'0000);
14524   __ Mov(x5, 0x8000'0001);
14525   __ Mov(x6, 0x7fff'ffff'ffff'ffff);
14526   __ Mov(x7, 0x4242'4242'aaaa'aaaa);
14527 
14528   __ Cnt(w10, w0);
14529   __ Cnt(x11, x0);
14530   __ Cnt(w12, w1);
14531   __ Cnt(x13, x1);
14532   __ Cnt(w14, w2);
14533   __ Cnt(x15, x2);
14534   __ Cnt(w19, w3);
14535   __ Cnt(x20, x3);
14536   __ Cnt(w21, w4);
14537   __ Cnt(x22, x4);
14538   __ Cnt(w23, w5);
14539   __ Cnt(x24, x5);
14540   __ Cnt(w25, w6);
14541   __ Cnt(x26, x6);
14542   __ Cnt(w27, w7);
14543   __ Cnt(x28, x7);
14544   END();
14545 
14546   if (CAN_RUN()) {
14547     RUN();
14548 
14549     ASSERT_EQUAL_64(32, x10);
14550     ASSERT_EQUAL_64(64, x11);
14551     ASSERT_EQUAL_64(1, x12);
14552     ASSERT_EQUAL_64(1, x13);
14553     ASSERT_EQUAL_64(0, x14);
14554     ASSERT_EQUAL_64(0, x15);
14555     ASSERT_EQUAL_64(31, x19);
14556     ASSERT_EQUAL_64(31, x20);
14557     ASSERT_EQUAL_64(1, x21);
14558     ASSERT_EQUAL_64(1, x22);
14559     ASSERT_EQUAL_64(2, x23);
14560     ASSERT_EQUAL_64(2, x24);
14561     ASSERT_EQUAL_64(32, x25);
14562     ASSERT_EQUAL_64(63, x26);
14563     ASSERT_EQUAL_64(16, x27);
14564     ASSERT_EQUAL_64(24, x28);
14565   }
14566 }
14567 
14568 TEST(cssc_ctz) {
14569   SETUP_WITH_FEATURES(CPUFeatures::kCSSC);
14570 
14571   START();
14572   __ Mov(x0, -1);
14573   __ Mov(x1, 1);
14574   __ Mov(x2, 2);
14575   __ Mov(x3, 0x7fff'ff00);
14576   __ Mov(x4, 0x8000'4000);
14577   __ Mov(x5, 0x4000'0001);
14578   __ Mov(x6, 0x0000'0001'0000'0000);
14579   __ Mov(x7, 0x4200'0000'0000'0000);
14580 
14581   __ Ctz(w10, w0);
14582   __ Ctz(x11, x0);
14583   __ Ctz(w12, w1);
14584   __ Ctz(x13, x1);
14585   __ Ctz(w14, w2);
14586   __ Ctz(x15, x2);
14587   __ Ctz(w19, w3);
14588   __ Ctz(x20, x3);
14589   __ Ctz(w21, w4);
14590   __ Ctz(x22, x4);
14591   __ Ctz(w23, w5);
14592   __ Ctz(x24, x5);
14593   __ Ctz(w25, w6);
14594   __ Ctz(x26, x6);
14595   __ Ctz(w27, w7);
14596   __ Ctz(x28, x7);
14597   END();
14598 
14599   if (CAN_RUN()) {
14600     RUN();
14601 
14602     ASSERT_EQUAL_64(0, x10);
14603     ASSERT_EQUAL_64(0, x11);
14604     ASSERT_EQUAL_64(0, x12);
14605     ASSERT_EQUAL_64(0, x13);
14606     ASSERT_EQUAL_64(1, x14);
14607     ASSERT_EQUAL_64(1, x15);
14608     ASSERT_EQUAL_64(8, x19);
14609     ASSERT_EQUAL_64(8, x20);
14610     ASSERT_EQUAL_64(14, x21);
14611     ASSERT_EQUAL_64(14, x22);
14612     ASSERT_EQUAL_64(0, x23);
14613     ASSERT_EQUAL_64(0, x24);
14614     ASSERT_EQUAL_64(32, x25);
14615     ASSERT_EQUAL_64(32, x26);
14616     ASSERT_EQUAL_64(32, x27);
14617     ASSERT_EQUAL_64(57, x28);
14618   }
14619 }
14620 
14621 using MinMaxOp = void (MacroAssembler::*)(const Register&,
14622                                           const Register&,
14623                                           const Operand&);
14624 
14625 static void MinMaxHelper(MinMaxOp op,
14626                          bool is_signed,
14627                          uint64_t a,
14628                          uint64_t b,
14629                          uint32_t wexp,
14630                          uint64_t xexp) {
14631   SETUP_WITH_FEATURES(CPUFeatures::kCSSC);
14632 
14633   START();
14634   __ Mov(x0, a);
14635   __ Mov(x1, b);
14636   if ((is_signed && IsInt8(b)) || (!is_signed && IsUint8(b))) {
14637     (masm.*op)(w10, w0, b);
14638     (masm.*op)(x11, x0, b);
14639   } else {
14640     (masm.*op)(w10, w0, w1);
14641     (masm.*op)(x11, x0, x1);
14642   }
14643   END();
14644 
14645   if (CAN_RUN()) {
14646     RUN();
14647     ASSERT_EQUAL_64(wexp, x10);
14648     ASSERT_EQUAL_64(xexp, x11);
14649   }
14650 }
14651 
14652 TEST(cssc_umin) {
14653   MinMaxOp op = &MacroAssembler::Umin;
14654   uint32_t s32min = 0x8000'0000;
14655   uint32_t s32max = 0x7fff'ffff;
14656   uint64_t s64min = 0x8000'0000'0000'0000;
14657   uint64_t s64max = 0x7fff'ffff'ffff'ffff;
14658 
14659   MinMaxHelper(op, false, 0, 0, 0, 0);
14660   MinMaxHelper(op, false, 128, 255, 128, 128);
14661   MinMaxHelper(op, false, 0, 0xffff'ffff'ffff'ffff, 0, 0);
14662   MinMaxHelper(op, false, s32max, s32min, s32max, s32max);
14663   MinMaxHelper(op, false, s32min, s32max, s32max, s32max);
14664   MinMaxHelper(op, false, s64max, s32min, s32min, s32min);
14665   MinMaxHelper(op, false, s64min, s64max, 0, s64max);
14666 }
14667 
14668 TEST(cssc_umax) {
14669   MinMaxOp op = &MacroAssembler::Umax;
14670   uint32_t s32min = 0x8000'0000;
14671   uint32_t s32max = 0x7fff'ffff;
14672   uint64_t s64min = 0x8000'0000'0000'0000;
14673   uint64_t s64max = 0x7fff'ffff'ffff'ffff;
14674 
14675   MinMaxHelper(op, false, 0, 0, 0, 0);
14676   MinMaxHelper(op, false, 128, 255, 255, 255);
14677   MinMaxHelper(op,
14678                false,
14679                0,
14680                0xffff'ffff'ffff'ffff,
14681                0xffff'ffff,
14682                0xffff'ffff'ffff'ffff);
14683   MinMaxHelper(op, false, s32max, s32min, s32min, s32min);
14684   MinMaxHelper(op, false, s32min, s32max, s32min, s32min);
14685   MinMaxHelper(op, false, s64max, s32min, 0xffff'ffff, s64max);
14686   MinMaxHelper(op, false, s64min, s64max, 0xffff'ffff, s64min);
14687 }
14688 
14689 TEST(cssc_smin) {
14690   MinMaxOp op = &MacroAssembler::Smin;
14691   uint32_t s32min = 0x8000'0000;
14692   uint32_t s32max = 0x7fff'ffff;
14693   uint64_t s64min = 0x8000'0000'0000'0000;
14694   uint64_t s64max = 0x7fff'ffff'ffff'ffff;
14695 
14696   MinMaxHelper(op, true, 0, 0, 0, 0);
14697   MinMaxHelper(op, true, 128, 255, 128, 128);
14698   MinMaxHelper(op,
14699                true,
14700                0,
14701                0xffff'ffff'ffff'ffff,
14702                0xffff'ffff,
14703                0xffff'ffff'ffff'ffff);
14704   MinMaxHelper(op, true, s32max, s32min, s32min, s32max);
14705   MinMaxHelper(op, true, s32min, s32max, s32min, s32max);
14706   MinMaxHelper(op, true, s64max, s32min, s32min, s32min);
14707   MinMaxHelper(op, true, s64min, s64max, 0xffff'ffff, s64min);
14708 }
14709 
14710 TEST(cssc_smax) {
14711   MinMaxOp op = &MacroAssembler::Smax;
14712   uint32_t s32min = 0x8000'0000;
14713   uint32_t s32max = 0x7fff'ffff;
14714   uint64_t s64min = 0x8000'0000'0000'0000;
14715   uint64_t s64max = 0x7fff'ffff'ffff'ffff;
14716 
14717   MinMaxHelper(op, true, 0, 0, 0, 0);
14718   MinMaxHelper(op, true, 128, 255, 255, 255);
14719   MinMaxHelper(op, true, 0, 0xffff'ffff'ffff'ffff, 0, 0);
14720   MinMaxHelper(op, true, s32max, s32min, s32max, s32min);
14721   MinMaxHelper(op, true, s32min, s32max, s32max, s32min);
14722   MinMaxHelper(op, true, s64max, s32min, 0xffff'ffff, s64max);
14723   MinMaxHelper(op, true, s64min, s64max, 0, s64max);
14724 }
14725 
14726 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
14727 // Test the pseudo-instructions that control CPUFeatures dynamically in the
14728 // Simulator. These are used by the test infrastructure itself, but in a fairly
14729 // limited way.
14730 
14731 static void RunHelperWithFeatureCombinations(
14732     void (*helper)(const CPUFeatures& base, const CPUFeatures& f)) {
14733   // Iterate, testing the first n features in this list.
14734   CPUFeatures::Feature features[] = {
14735       // Put kNone first, so that the first iteration uses an empty feature set.
14736       CPUFeatures::kNone,
14737       // The remaining features used are arbitrary.
14738       CPUFeatures::kIDRegisterEmulation,
14739       CPUFeatures::kDCPoP,
14740       CPUFeatures::kPAuth,
14741       CPUFeatures::kFcma,
14742       CPUFeatures::kAES,
14743       CPUFeatures::kNEON,
14744       CPUFeatures::kCRC32,
14745       CPUFeatures::kFP,
14746       CPUFeatures::kPmull1Q,
14747       CPUFeatures::kSM4,
14748       CPUFeatures::kSM3,
14749       CPUFeatures::kDotProduct,
14750   };
14751   VIXL_ASSERT(CPUFeatures(CPUFeatures::kNone) == CPUFeatures::None());
14752   // The features are not necessarily encoded in kInstructionSize-sized slots,
14753   // so the MacroAssembler must pad the list to align the following instruction.
14754   // Ensure that we have enough features in the list to cover all interesting
14755   // alignment cases, even if the highest common factor of kInstructionSize and
14756   // an encoded feature is one.
14757   VIXL_STATIC_ASSERT(ARRAY_SIZE(features) > kInstructionSize);
14758 
14759   CPUFeatures base = CPUFeatures::None();
14760   for (size_t i = 0; i < ARRAY_SIZE(features); i++) {
14761     base.Combine(features[i]);
14762     CPUFeatures f = CPUFeatures::None();
14763     for (size_t j = 0; j < ARRAY_SIZE(features); j++) {
14764       f.Combine(features[j]);
14765       helper(base, f);
14766     }
14767   }
14768 }
14769 
14770 static void SetSimulatorCPUFeaturesHelper(const CPUFeatures& base,
14771                                           const CPUFeatures& f) {
14772   SETUP_WITH_FEATURES(base);
14773   START();
14774 
14775   __ SetSimulatorCPUFeatures(f);
14776 
14777   END();
14778   if (CAN_RUN()) {
14779     RUN_WITHOUT_SEEN_FEATURE_CHECK();
14780     VIXL_CHECK(*(simulator.GetCPUFeatures()) == f);
14781   }
14782 }
14783 
14784 TEST(configure_cpu_features_set) {
14785   RunHelperWithFeatureCombinations(SetSimulatorCPUFeaturesHelper);
14786 }
14787 
14788 static void EnableSimulatorCPUFeaturesHelper(const CPUFeatures& base,
14789                                              const CPUFeatures& f) {
14790   SETUP_WITH_FEATURES(base);
14791   START();
14792 
14793   __ EnableSimulatorCPUFeatures(f);
14794 
14795   END();
14796   if (CAN_RUN()) {
14797     RUN_WITHOUT_SEEN_FEATURE_CHECK();
14798     VIXL_CHECK(*(simulator.GetCPUFeatures()) == base.With(f));
14799   }
14800 }
14801 
14802 TEST(configure_cpu_features_enable) {
14803   RunHelperWithFeatureCombinations(EnableSimulatorCPUFeaturesHelper);
14804 }
14805 
14806 static void DisableSimulatorCPUFeaturesHelper(const CPUFeatures& base,
14807                                               const CPUFeatures& f) {
14808   SETUP_WITH_FEATURES(base);
14809   START();
14810 
14811   __ DisableSimulatorCPUFeatures(f);
14812 
14813   END();
14814   if (CAN_RUN()) {
14815     RUN_WITHOUT_SEEN_FEATURE_CHECK();
14816     VIXL_CHECK(*(simulator.GetCPUFeatures()) == base.Without(f));
14817   }
14818 }
14819 
14820 TEST(configure_cpu_features_disable) {
14821   RunHelperWithFeatureCombinations(DisableSimulatorCPUFeaturesHelper);
14822 }
14823 
14824 static void SaveRestoreSimulatorCPUFeaturesHelper(const CPUFeatures& base,
14825                                                   const CPUFeatures& f) {
14826   SETUP_WITH_FEATURES(base);
14827   START();
14828 
14829   {
14830     __ SaveSimulatorCPUFeatures();
14831     __ SetSimulatorCPUFeatures(f);
14832     {
14833       __ SaveSimulatorCPUFeatures();
14834       __ SetSimulatorCPUFeatures(CPUFeatures::All());
14835       __ RestoreSimulatorCPUFeatures();
14836     }
14837     __ RestoreSimulatorCPUFeatures();
14838   }
14839 
14840   END();
14841   if (CAN_RUN()) {
14842     RUN_WITHOUT_SEEN_FEATURE_CHECK();
14843     VIXL_CHECK(*(simulator.GetCPUFeatures()) == base);
14844   }
14845 }
14846 
14847 TEST(configure_cpu_features_save_restore) {
14848   RunHelperWithFeatureCombinations(SaveRestoreSimulatorCPUFeaturesHelper);
14849 }
14850 
14851 static void SimulationCPUFeaturesScopeHelper(const CPUFeatures& base,
14852                                              const CPUFeatures& f) {
14853   SETUP_WITH_FEATURES(base);
14854   START();
14855 
14856   {
14857     SimulationCPUFeaturesScope scope_a(&masm, f);
14858     {
14859       SimulationCPUFeaturesScope scope_b(&masm, CPUFeatures::All());
14860       {
14861         SimulationCPUFeaturesScope scope_c(&masm, CPUFeatures::None());
14862         // The scope arguments should combine with 'Enable', so we should be
14863         // able to use any CPUFeatures here.
14864         __ Fadd(v0.V4S(), v1.V4S(), v2.V4S());  // Requires {FP, NEON}.
14865       }
14866     }
14867   }
14868 
14869   END();
14870   if (CAN_RUN()) {
14871     RUN_WITHOUT_SEEN_FEATURE_CHECK();
14872     VIXL_CHECK(*(simulator.GetCPUFeatures()) == base);
14873   }
14874 }
14875 
14876 TEST(configure_cpu_features_scope) {
14877   RunHelperWithFeatureCombinations(SimulationCPUFeaturesScopeHelper);
14878 }
14879 #endif
14880 
14881 
14882 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
14883 TEST(large_sim_stack) {
14884   SimStack builder;
14885   builder.SetUsableSize(16 * 1024);  // The default is 8kB.
14886   SimStack::Allocated stack = builder.Allocate();
14887   uintptr_t base = reinterpret_cast<uintptr_t>(stack.GetBase());
14888   uintptr_t limit = reinterpret_cast<uintptr_t>(stack.GetLimit());
14889   SETUP_CUSTOM_SIM(std::move(stack));
14890   START();
14891 
14892   // Check that we can access the extremes of the stack.
14893   __ Mov(x0, base);
14894   __ Mov(x1, limit);
14895   __ Mov(x2, sp);
14896   __ Add(sp, x1, 1);  // Avoid accessing memory below `sp`.
14897 
14898   __ Mov(x10, 42);
14899   __ Poke(x10, 0);
14900   __ Peek(x10, base - limit - kXRegSizeInBytes - 1);
14901 
14902   __ Mov(sp, x2);
14903 
14904   END();
14905   if (CAN_RUN()) {
14906     RUN();
14907   }
14908 }
14909 
14910 #ifdef VIXL_NEGATIVE_TESTING
14911 TEST(sim_stack_limit_guard_read) {
14912   SimStack builder;
14913   SimStack::Allocated stack = builder.Allocate();
14914   uintptr_t limit = reinterpret_cast<uintptr_t>(stack.GetLimit());
14915   SETUP_CUSTOM_SIM(std::move(stack));
14916   START();
14917 
14918   __ Mov(x1, limit);
14919   __ Mov(x2, sp);
14920   __ Add(sp, x1, 1);  // Avoid accessing memory below `sp`.
14921 
14922   // `sp` points to the lowest usable byte of the stack.
14923   __ Mov(w10, 42);
14924   __ Ldrb(w10, MemOperand(sp, -1));
14925 
14926   __ Mov(sp, x2);
14927 
14928   END();
14929   if (CAN_RUN()) {
14930     MUST_FAIL_WITH_MESSAGE(RUN(), "Attempt to read from stack guard region");
14931   }
14932 }
14933 
14934 TEST(sim_stack_limit_guard_write) {
14935   SimStack builder;
14936   SimStack::Allocated stack = builder.Allocate();
14937   uintptr_t limit = reinterpret_cast<uintptr_t>(stack.GetLimit());
14938   SETUP_CUSTOM_SIM(std::move(stack));
14939   START();
14940 
14941   __ Mov(x1, limit);
14942   __ Mov(x2, sp);
14943   __ Add(sp, x1, 1);  // Avoid accessing memory below `sp`.
14944 
14945   // `sp` points to the lowest usable byte of the stack.
14946   __ Mov(w10, 42);
14947   __ Strb(w10, MemOperand(sp, -1));
14948 
14949   __ Mov(sp, x2);
14950 
14951   END();
14952   if (CAN_RUN()) {
14953     MUST_FAIL_WITH_MESSAGE(RUN(), "Attempt to write to stack guard region");
14954   }
14955 }
14956 
14957 TEST(sim_stack_base_guard_read) {
14958   SimStack builder;
14959   SimStack::Allocated stack = builder.Allocate();
14960   uintptr_t base = reinterpret_cast<uintptr_t>(stack.GetBase());
14961   SETUP_CUSTOM_SIM(std::move(stack));
14962   START();
14963 
14964   __ Mov(x0, base);
14965   // `base` (x0) is the byte after the highest usable byte of the stack.
14966   // The last byte of this access will hit the guard region.
14967   __ Mov(x10, 42);
14968   __ Ldr(x10, MemOperand(x0, -static_cast<int64_t>(kXRegSizeInBytes) + 1));
14969 
14970   END();
14971   if (CAN_RUN()) {
14972     MUST_FAIL_WITH_MESSAGE(RUN(), "Attempt to read from stack guard region");
14973   }
14974 }
14975 
14976 TEST(sim_stack_base_guard_write) {
14977   SimStack builder;
14978   SimStack::Allocated stack = builder.Allocate();
14979   uintptr_t base = reinterpret_cast<uintptr_t>(stack.GetBase());
14980   SETUP_CUSTOM_SIM(std::move(stack));
14981   START();
14982 
14983   __ Mov(x0, base);
14984   // `base` (x0) is the byte after the highest usable byte of the stack.
14985   // The last byte of this access will hit the guard region.
14986   __ Mov(x10, 42);
14987   __ Str(x10, MemOperand(x0, -static_cast<int64_t>(kXRegSizeInBytes) + 1));
14988 
14989   END();
14990   if (CAN_RUN()) {
14991     MUST_FAIL_WITH_MESSAGE(RUN(), "Attempt to write to stack guard region");
14992   }
14993 }
14994 #endif
14995 #endif
14996 
14997 TEST(scalar_movi) {
14998   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kNEON);
14999   START();
15000 
15001   // Make sure that V0 is initialized to a non-zero value.
15002   __ Movi(v0.V16B(), 0xFF);
15003   // This constant value can't be encoded in a MOVI instruction,
15004   // so the program would use a fallback path that must set the
15005   // upper 64 bits of the destination vector to 0.
15006   __ Movi(v0.V1D(), 0xDECAFC0FFEE);
15007   __ Mov(x0, v0.V2D(), 1);
15008 
15009   END();
15010 
15011   if (CAN_RUN()) {
15012     RUN();
15013 
15014     ASSERT_EQUAL_64(0, x0);
15015   }
15016 }
15017 
15018 }  // namespace aarch64
15019 }  // namespace vixl
15020