1 // Copyright 2017, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include <cstdio>
28 #include <iostream>
29 #include <string>
30 
31 #include "test-runner.h"
32 #include "test-utils.h"
33 #include "aarch32/test-utils-aarch32.h"
34 
35 #include "aarch32/disasm-aarch32.h"
36 #include "aarch32/macro-assembler-aarch32.h"
37 
38 namespace vixl {
39 namespace aarch32 {
40 
41 #define STRINGIFY(x) #x
42 
43 #ifdef VIXL_INCLUDE_TARGET_A32_ONLY
44 #define TEST_T32(Name) \
45   void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
46 #else
47 // Tests declared with this macro will only target T32.
48 #define TEST_T32(Name)                                          \
49   void Test##Name##Impl(InstructionSet isa);                    \
50   void Test##Name() { Test##Name##Impl(T32); }                  \
51   Test test_##Name(STRINGIFY(AARCH32_T32_##Name), &Test##Name); \
52   void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
53 #endif
54 
55 #ifdef VIXL_INCLUDE_TARGET_T32_ONLY
56 #define TEST_A32(Name) \
57   void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
58 #else
59 // Test declared with this macro will only target A32.
60 #define TEST_A32(Name)                                          \
61   void Test##Name##Impl(InstructionSet isa);                    \
62   void Test##Name() { Test##Name##Impl(A32); }                  \
63   Test test_##Name(STRINGIFY(AARCH32_A32_##Name), &Test##Name); \
64   void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
65 #endif
66 
67 // Tests declared with this macro will be run twice: once targeting A32 and
68 // once targeting T32.
69 #if defined(VIXL_INCLUDE_TARGET_A32_ONLY)
70 #define TEST(Name) TEST_A32(Name)
71 #elif defined(VIXL_INCLUDE_TARGET_T32_ONLY)
72 #define TEST(Name) TEST_T32(Name)
73 #else
74 #define TEST(Name)                                              \
75   void Test##Name##Impl(InstructionSet isa);                    \
76   void Test##Name() {                                           \
77     Test##Name##Impl(A32);                                      \
78     printf(" > A32 done\n");                                    \
79     Test##Name##Impl(T32);                                      \
80     printf(" > T32 done\n");                                    \
81   }                                                             \
82   Test test_##Name(STRINGIFY(AARCH32_ASM_##Name), &Test##Name); \
83   void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
84 #endif
85 
86 // Tests declared with this macro are not expected to use any provided test
87 // helpers such as SETUP, RUN, etc.
88 #define TEST_NOASM(Name)                                    \
89   void Test##Name();                                        \
90   Test test_##Name(STRINGIFY(AARCH32_##Name), &Test##Name); \
91   void Test##Name()
92 
93 #define __ masm.
94 #define __TESTOBJ test.
95 #define BUF_SIZE (4096)
96 
97 #define CHECK_POOL_SIZE(size)                    \
98   do {                                           \
99     VIXL_CHECK(__TESTOBJ GetPoolSize() == size); \
100   } while (false)
101 
102 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
103 // No simulator yet.
104 
105 #define SETUP()                       \
106   MacroAssembler masm(BUF_SIZE, isa); \
107   TestMacroAssembler test(&masm);
108 
109 #define START() masm.GetBuffer()->Reset();
110 
111 #define END() \
112   __ Hlt(0);  \
113   __ FinalizeCode();
114 
115 #define RUN() DISASSEMBLE();
116 
117 #else  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32.
118 
119 #define SETUP()                       \
120   RegisterDump core;                  \
121   MacroAssembler masm(BUF_SIZE, isa); \
122   TestMacroAssembler test(&masm);     \
123   UseScratchRegisterScope harness_scratch;
124 
125 #define START()                 \
126   harness_scratch.Open(&masm);  \
127   harness_scratch.ExcludeAll(); \
128   masm.GetBuffer()->Reset();    \
129   __ Push(r4);                  \
130   __ Push(r5);                  \
131   __ Push(r6);                  \
132   __ Push(r7);                  \
133   __ Push(r8);                  \
134   __ Push(r9);                  \
135   __ Push(r10);                 \
136   __ Push(r11);                 \
137   __ Push(ip);                  \
138   __ Push(lr);                  \
139   __ Mov(r0, 0);                \
140   __ Msr(APSR_nzcvq, r0);       \
141   __ Vmsr(FPSCR, r0);           \
142   harness_scratch.Include(ip);
143 
144 #define END()                  \
145   harness_scratch.Exclude(ip); \
146   core.Dump(&masm);            \
147   __ Pop(lr);                  \
148   __ Pop(ip);                  \
149   __ Pop(r11);                 \
150   __ Pop(r10);                 \
151   __ Pop(r9);                  \
152   __ Pop(r8);                  \
153   __ Pop(r7);                  \
154   __ Pop(r6);                  \
155   __ Pop(r5);                  \
156   __ Pop(r4);                  \
157   __ Bx(lr);                   \
158   __ FinalizeCode();           \
159   harness_scratch.Close();
160 
161 // Execute the generated code from the MacroAssembler's automatic code buffer.
162 // Note the offset for ExecuteMemory since the PCS requires that
163 // the address be odd in the case of branching to T32 code.
164 #define RUN()                                                 \
165   DISASSEMBLE();                                              \
166   {                                                           \
167     int pcs_offset = masm.IsUsingT32() ? 1 : 0;               \
168     masm.GetBuffer()->SetExecutable();                        \
169     ExecuteMemory(masm.GetBuffer()->GetStartAddress<byte*>(), \
170                   masm.GetSizeOfCodeGenerated(),              \
171                   pcs_offset);                                \
172     masm.GetBuffer()->SetWritable();                          \
173   }
174 
175 #endif  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
176 
177 #ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
178 // No simulator yet. We can't test the results.
179 
180 #define ASSERT_EQUAL_32(expected, result)
181 
182 #define ASSERT_EQUAL_64(expected, result)
183 
184 #define ASSERT_EQUAL_128(expected_h, expected_l, result)
185 
186 #define ASSERT_EQUAL_FP32(expected, result)
187 
188 #define ASSERT_EQUAL_FP64(expected, result)
189 
190 #define ASSERT_EQUAL_NZCV(expected)
191 
192 #else
193 
194 #define ASSERT_EQUAL_32(expected, result) \
195   VIXL_CHECK(Equal32(expected, &core, result))
196 
197 #define ASSERT_EQUAL_64(expected, result) \
198   VIXL_CHECK(Equal64(expected, &core, result))
199 
200 #define ASSERT_EQUAL_128(expected_h, expected_l, result) \
201   VIXL_CHECK(Equal128(expected_h, expected_l, &core, result))
202 
203 #define ASSERT_EQUAL_FP32(expected, result) \
204   VIXL_CHECK(EqualFP32(expected, &core, result))
205 
206 #define ASSERT_EQUAL_FP64(expected, result) \
207   VIXL_CHECK(EqualFP64(expected, &core, result))
208 
209 #define ASSERT_EQUAL_NZCV(expected) \
210   VIXL_CHECK(EqualNzcv(expected, core.flags_nzcv()))
211 
212 #endif
213 
214 #define DISASSEMBLE()                                                          \
215   if (Test::disassemble()) {                                                   \
216     PrintDisassembler dis(std::cout, 0);                                       \
217     if (masm.IsUsingT32()) {                                                   \
218       dis.DisassembleT32Buffer(masm.GetBuffer()->GetStartAddress<uint16_t*>(), \
219                                masm.GetCursorOffset());                        \
220     } else {                                                                   \
221       dis.DisassembleA32Buffer(masm.GetBuffer()->GetStartAddress<uint32_t*>(), \
222                                masm.GetCursorOffset());                        \
223     }                                                                          \
224   }
225 
226 
227 // TODO: Add SBC to the ADC tests.
228 
229 
TEST(adc_shift)230 TEST(adc_shift) {
231   SETUP();
232 
233   START();
234   // Initialize registers.
235   __ Mov(r0, 0);
236   __ Mov(r1, 1);
237   __ Mov(r2, 0x01234567);
238   __ Mov(r3, 0xfedcba98);
239 
240   // Clear the C flag.
241   __ Adds(r0, r0, 0);
242 
243   __ Adc(r4, r2, r3);
244   __ Adc(r5, r0, Operand(r1, LSL, 30));
245   __ Adc(r6, r0, Operand(r2, LSR, 16));
246   __ Adc(r7, r2, Operand(r3, ASR, 4));
247   __ Adc(r8, r2, Operand(r3, ROR, 8));
248   __ Adc(r9, r2, Operand(r3, RRX));
249   END();
250 
251   RUN();
252 
253   ASSERT_EQUAL_32(0xffffffff, r4);
254   ASSERT_EQUAL_32(INT32_C(1) << 30, r5);
255   ASSERT_EQUAL_32(0x00000123, r6);
256   ASSERT_EQUAL_32(0x01111110, r7);
257   ASSERT_EQUAL_32(0x9a222221, r8);
258   ASSERT_EQUAL_32(0x8091a2b3, r9);
259 
260   START();
261   // Initialize registers.
262   __ Mov(r0, 0);
263   __ Mov(r1, 1);
264   __ Mov(r2, 0x01234567);
265   __ Mov(r3, 0xfedcba98);
266   __ Mov(r4, 0xffffffff);
267 
268   // Set the C flag.
269   __ Adds(r0, r4, r1);
270 
271   __ Adc(r5, r2, r3);
272   __ Adc(r6, r0, Operand(r1, LSL, 30));
273   __ Adc(r7, r0, Operand(r2, LSR, 16));
274   __ Adc(r8, r2, Operand(r3, ASR, 4));
275   __ Adc(r9, r2, Operand(r3, ROR, 8));
276   __ Adc(r10, r2, Operand(r3, RRX));
277   END();
278 
279   RUN();
280 
281   ASSERT_EQUAL_32(0xffffffff + 1, r5);
282   ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, r6);
283   ASSERT_EQUAL_32(0x00000123 + 1, r7);
284   ASSERT_EQUAL_32(0x01111110 + 1, r8);
285   ASSERT_EQUAL_32(0x9a222221 + 1, r9);
286   ASSERT_EQUAL_32(0x0091a2b3 + 1, r10);
287 
288   // Check that adc correctly sets the condition flags.
289   START();
290   __ Mov(r0, 0);
291   __ Mov(r1, 0xffffffff);
292   __ Mov(r2, 1);
293 
294   // Clear the C flag.
295   __ Adds(r0, r0, 0);
296   __ Adcs(r3, r2, r1);
297   END();
298 
299   RUN();
300 
301   ASSERT_EQUAL_NZCV(ZCFlag);
302   ASSERT_EQUAL_32(0, r3);
303 
304   START();
305   __ Mov(r0, 0);
306   __ Mov(r1, 0x80000000);
307   __ Mov(r2, 1);
308 
309   // Clear the C flag.
310   __ Adds(r0, r0, 0);
311   __ Adcs(r3, r2, Operand(r1, ASR, 31));
312   END();
313 
314   RUN();
315 
316   ASSERT_EQUAL_NZCV(ZCFlag);
317   ASSERT_EQUAL_32(0, r3);
318 
319   START();
320   __ Mov(r0, 0);
321   __ Mov(r1, 0x80000000);
322   __ Mov(r2, 0xffffffff);
323 
324   // Clear the C flag.
325   __ Adds(r0, r0, 0);
326   __ Adcs(r3, r2, Operand(r1, LSR, 31));
327   END();
328 
329   RUN();
330 
331   ASSERT_EQUAL_NZCV(ZCFlag);
332   ASSERT_EQUAL_32(0, r3);
333 
334   START();
335   __ Mov(r0, 0);
336   __ Mov(r1, 0x07ffffff);
337   __ Mov(r2, 0x10);
338 
339   // Clear the C flag.
340   __ Adds(r0, r0, 0);
341   __ Adcs(r3, r2, Operand(r1, LSL, 4));
342   END();
343 
344   RUN();
345 
346   ASSERT_EQUAL_NZCV(NVFlag);
347   ASSERT_EQUAL_32(0x080000000, r3);
348 
349   START();
350   __ Mov(r0, 0);
351   __ Mov(r1, 0xffffff00);
352   __ Mov(r2, 0xff000001);
353 
354   // Clear the C flag.
355   __ Adds(r0, r0, 0);
356   __ Adcs(r3, r2, Operand(r1, ROR, 8));
357   END();
358 
359   RUN();
360 
361   ASSERT_EQUAL_NZCV(ZCFlag);
362   ASSERT_EQUAL_32(0, r3);
363 
364   START();
365   __ Mov(r0, 0);
366   __ Mov(r1, 0xffffffff);
367   __ Mov(r2, 0x1);
368 
369   // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
370   __ Adds(r0, r0, 0);
371   __ Adcs(r3, r2, Operand(r1, RRX));
372   END();
373 
374   RUN();
375 
376   ASSERT_EQUAL_NZCV(NVFlag);
377   ASSERT_EQUAL_32(0x80000000, r3);
378 
379   START();
380   __ Mov(r0, 0);
381   __ Mov(r1, 0xffffffff);
382   __ Mov(r2, 0x1);
383 
384   // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
385   __ Adds(r0, r1, r2);
386   __ Adcs(r3, r2, Operand(r1, RRX));
387   END();
388 
389   RUN();
390 
391   ASSERT_EQUAL_NZCV(CFlag);
392   ASSERT_EQUAL_32(1, r3);
393 }
394 
395 
TEST(adc_wide_imm)396 TEST(adc_wide_imm) {
397   SETUP();
398 
399   START();
400   __ Mov(r0, 0);
401 
402   // Clear the C flag.
403   __ Adds(r0, r0, 0);
404 
405   __ Adc(r1, r0, 0x12345678);
406   __ Adc(r2, r0, 0xffffffff);
407 
408   // Set the C flag.
409   __ Cmp(r0, r0);
410 
411   __ Adc(r3, r0, 0x12345678);
412   __ Adc(r4, r0, 0xffffffff);
413   END();
414 
415   RUN();
416 
417   ASSERT_EQUAL_32(0x12345678, r1);
418   ASSERT_EQUAL_32(0xffffffff, r2);
419   ASSERT_EQUAL_32(0x12345678 + 1, r3);
420   ASSERT_EQUAL_32(0, r4);
421 }
422 
423 
424 // TODO: Add SUB tests to the ADD tests.
425 
426 
TEST(add_imm)427 TEST(add_imm) {
428   SETUP();
429 
430   START();
431   __ Mov(r0, 0);
432   __ Mov(r1, 0x1111);
433   __ Mov(r2, 0xffffffff);
434   __ Mov(r3, 0x80000000);
435 
436   __ Add(r4, r0, 0x12);
437   __ Add(r5, r1, 0x120000);
438   __ Add(r6, r0, 0xab << 12);
439   __ Add(r7, r2, 1);
440 
441   END();
442 
443   RUN();
444 
445   ASSERT_EQUAL_32(0x12, r4);
446   ASSERT_EQUAL_32(0x121111, r5);
447   ASSERT_EQUAL_32(0xab000, r6);
448   ASSERT_EQUAL_32(0x0, r7);
449 }
450 
451 
TEST(add_wide_imm)452 TEST(add_wide_imm) {
453   SETUP();
454 
455   START();
456   __ Mov(r0, 0);
457   __ Mov(r1, 1);
458 
459   __ Add(r2, r0, 0x12345678);
460   __ Add(r3, r1, 0xffff);
461   END();
462 
463   RUN();
464 
465   ASSERT_EQUAL_32(0x12345678, r2);
466   ASSERT_EQUAL_32(0x00010000, r3);
467 }
468 
469 
TEST(add_shifted)470 TEST(add_shifted) {
471   SETUP();
472 
473   START();
474   __ Mov(r0, 0);
475   __ Mov(r1, 0x01234567);
476   __ Mov(r2, 0x76543210);
477   __ Mov(r3, 0xffffffff);
478 
479   __ Add(r4, r1, r2);
480   __ Add(r5, r0, Operand(r1, LSL, 8));
481   __ Add(r6, r0, Operand(r1, LSR, 8));
482   __ Add(r7, r0, Operand(r1, ASR, 8));
483   __ Add(r8, r3, Operand(r1, ROR, 8));
484 
485   // Set the C flag.
486   __ Adds(r0, r3, 1);
487   __ Add(r9, r3, Operand(r1, RRX));
488 
489   // Clear the C flag.
490   __ Adds(r0, r0, 0);
491   __ Add(r10, r3, Operand(r1, RRX));
492 
493   END();
494 
495   RUN();
496 
497   ASSERT_EQUAL_32(0x77777777, r4);
498   ASSERT_EQUAL_32(0x23456700, r5);
499   ASSERT_EQUAL_32(0x00012345, r6);
500   ASSERT_EQUAL_32(0x00012345, r7);
501   ASSERT_EQUAL_32(0x67012344, r8);
502   ASSERT_EQUAL_32(0x8091a2b2, r9);
503   ASSERT_EQUAL_32(0x0091a2b2, r10);
504 }
505 
506 
TEST(and_)507 TEST(and_) {
508   SETUP();
509 
510   START();
511   __ Mov(r0, 0x0000fff0);
512   __ Mov(r1, 0xf00000ff);
513   __ Mov(r2, 0xffffffff);
514 
515   __ And(r3, r0, r1);
516   __ And(r4, r0, Operand(r1, LSL, 4));
517   __ And(r5, r0, Operand(r1, LSR, 1));
518   __ And(r6, r0, Operand(r1, ASR, 20));
519   __ And(r7, r0, Operand(r1, ROR, 28));
520   __ And(r8, r0, 0xff);
521 
522   // Set the C flag.
523   __ Adds(r9, r2, 1);
524   __ And(r9, r1, Operand(r1, RRX));
525 
526   // Clear the C flag.
527   __ Adds(r10, r0, 0);
528   __ And(r10, r1, Operand(r1, RRX));
529   END();
530 
531   RUN();
532 
533   ASSERT_EQUAL_32(0x000000f0, r3);
534   ASSERT_EQUAL_32(0x00000ff0, r4);
535   ASSERT_EQUAL_32(0x00000070, r5);
536   ASSERT_EQUAL_32(0x0000ff00, r6);
537   ASSERT_EQUAL_32(0x00000ff0, r7);
538   ASSERT_EQUAL_32(0x000000f0, r8);
539   ASSERT_EQUAL_32(0xf000007f, r9);
540   ASSERT_EQUAL_32(0x7000007f, r10);
541 }
542 
543 
TEST(ands)544 TEST(ands) {
545   SETUP();
546 
547   START();
548   __ Mov(r0, 0);
549   __ Mov(r1, 0xf00000ff);
550 
551   __ Ands(r0, r1, r1);
552   END();
553 
554   RUN();
555 
556   ASSERT_EQUAL_NZCV(NFlag);
557   ASSERT_EQUAL_32(0xf00000ff, r0);
558 
559   START();
560   __ Mov(r0, 0x00fff000);
561   __ Mov(r1, 0xf00000ff);
562 
563   __ Ands(r0, r0, Operand(r1, LSL, 4));
564   END();
565 
566   RUN();
567 
568   ASSERT_EQUAL_NZCV(ZCFlag);
569   ASSERT_EQUAL_32(0x00000000, r0);
570 
571   START();
572   __ Mov(r0, 0x0000fff0);
573   __ Mov(r1, 0xf00000ff);
574 
575   __ Ands(r0, r0, Operand(r1, LSR, 4));
576   END();
577 
578   RUN();
579 
580   ASSERT_EQUAL_NZCV(ZCFlag);
581   ASSERT_EQUAL_32(0x00000000, r0);
582 
583   START();
584   __ Mov(r0, 0xf000fff0);
585   __ Mov(r1, 0xf00000ff);
586 
587   __ Ands(r0, r0, Operand(r1, ASR, 4));
588   END();
589 
590   RUN();
591 
592   ASSERT_EQUAL_NZCV(NCFlag);
593   ASSERT_EQUAL_32(0xf0000000, r0);
594 
595   START();
596   __ Mov(r0, 0x80000000);
597   __ Mov(r1, 0x00000001);
598 
599   __ Ands(r0, r0, Operand(r1, ROR, 1));
600   END();
601 
602   RUN();
603 
604   ASSERT_EQUAL_NZCV(NCFlag);
605   ASSERT_EQUAL_32(0x80000000, r0);
606 
607   START();
608   __ Mov(r0, 0x80000000);
609   __ Mov(r1, 0x80000001);
610 
611   // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
612   __ Adds(r2, r0, 0);
613   __ Ands(r2, r0, Operand(r1, RRX));
614   END();
615 
616   RUN();
617 
618   ASSERT_EQUAL_NZCV(ZCFlag);
619   ASSERT_EQUAL_32(0, r2);
620 
621   START();
622   __ Mov(r0, 0x80000000);
623   __ Mov(r1, 0x80000001);
624   __ Mov(r2, 0xffffffff);
625 
626   // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
627   __ Adds(r2, r2, 1);
628   __ Ands(r2, r0, Operand(r1, RRX));
629   END();
630 
631   RUN();
632 
633   ASSERT_EQUAL_NZCV(NCFlag);
634   ASSERT_EQUAL_32(0x80000000, r2);
635 
636   START();
637   __ Mov(r0, 0xfff0);
638 
639   __ Ands(r0, r0, 0xf);
640   END();
641 
642   RUN();
643 
644   ASSERT_EQUAL_NZCV(ZFlag);
645   ASSERT_EQUAL_32(0x00000000, r0);
646 
647   START();
648   __ Mov(r0, 0xff000000);
649 
650   __ Ands(r0, r0, 0x80000000);
651   END();
652 
653   RUN();
654 
655   ASSERT_EQUAL_NZCV(NCFlag);
656   ASSERT_EQUAL_32(0x80000000, r0);
657 }
658 
659 
TEST(adr_in_range)660 TEST(adr_in_range) {
661   SETUP();
662 
663   Label label_1, label_2, label_3, label_4;
664 
665   START();
666   {
667     size_t size_of_generated_code;
668     if (masm.IsUsingA32()) {
669       size_of_generated_code = 18 * kA32InstructionSizeInBytes;
670     } else {
671       size_of_generated_code = 18 * k32BitT32InstructionSizeInBytes +
672                                3 * k16BitT32InstructionSizeInBytes;
673     }
674     ExactAssemblyScope scope(&masm,
675                              size_of_generated_code,
676                              ExactAssemblyScope::kExactSize);
677 
678     __ mov(r0, 0x0);  // Set to zero to indicate success.
679     __ adr(r1, &label_3);
680 
681     __ adr(r2, &label_1);  // Multiple forward references to the same label.
682     __ adr(r3, &label_1);
683     __ adr(r4, &label_1);
684 
685     __ bind(&label_2);
686     __ eor(r5, r2, r3);  // Ensure that r2, r3 and r4 are identical.
687     __ eor(r6, r2, r4);
688     __ orr(r0, r5, r6);
689     if (masm.IsUsingT32()) {
690       // The jump target needs to have its least significant bit set to indicate
691       // that we are jumping into thumb mode.
692       __ orr(r2, r2, 1);
693     }
694     __ bx(r2);  // label_1, label_3
695 
696     __ bind(&label_3);
697     __ adr(r2, &label_3);  // Self-reference (offset 0).
698     __ eor(r1, r1, r2);
699     __ adr(r2, &label_4);  // Simple forward reference.
700     if (masm.IsUsingT32()) {
701       // The jump target needs to have its least significant bit set to indicate
702       // that we are jumping into thumb mode.
703       __ orr(r2, r2, 1);
704     }
705     __ bx(r2);  // label_4
706 
707     __ bind(&label_1);
708     __ adr(r2, &label_3);  // Multiple reverse references to the same label.
709     __ adr(r3, &label_3);
710     __ adr(r4, &label_3);
711     __ adr(r5, &label_2);  // Simple reverse reference.
712     if (masm.IsUsingT32()) {
713       // The jump target needs to have its least significant bit set to indicate
714       // that we are jumping into thumb mode.
715       __ orr(r5, r5, 1);
716     }
717     __ bx(r5);  // label_2
718 
719     __ bind(&label_4);
720   }
721   END();
722 
723   RUN();
724 
725   ASSERT_EQUAL_32(0x0, r0);
726   ASSERT_EQUAL_32(0x0, r1);
727 }
728 
729 
730 // Check that we can use adr with any alignement.
TEST(adr_unaligned)731 TEST(adr_unaligned) {
732   SETUP();
733 
734   Label label_end;
735 
736   START();
737   {
738     Location label_0, label_1, label_2, label_3;
739     // 5 instructions.
740     ExactAssemblyScope scope(&masm,
741                              5 * kA32InstructionSizeInBytes + 4,
742                              ExactAssemblyScope::kExactSize);
743     __ adr(Wide, r0, &label_0);
744     __ adr(Wide, r1, &label_1);
745     __ adr(Wide, r2, &label_2);
746     __ adr(Wide, r3, &label_3);
747     __ b(Wide, &label_end);
748     __ bind(&label_0);
749     __ GetBuffer()->EmitData("a", 1);
750     __ bind(&label_1);
751     __ GetBuffer()->EmitData("b", 1);
752     __ bind(&label_2);
753     __ GetBuffer()->EmitData("c", 1);
754     __ bind(&label_3);
755     __ GetBuffer()->EmitData("d", 1);
756   }
757   {
758     __ Bind(&label_end);
759     __ Ldrb(r0, MemOperand(r0));
760     __ Ldrb(r1, MemOperand(r1));
761     __ Ldrb(r2, MemOperand(r2));
762     __ Ldrb(r3, MemOperand(r3));
763   }
764   END();
765 
766   RUN();
767 
768   ASSERT_EQUAL_32('a', r0);
769   ASSERT_EQUAL_32('b', r1);
770   ASSERT_EQUAL_32('c', r2);
771   ASSERT_EQUAL_32('d', r3);
772 }
773 
774 
TEST(shift_imm)775 TEST(shift_imm) {
776   SETUP();
777 
778   START();
779   __ Mov(r0, 0);
780   __ Mov(r1, 0xfedcba98);
781   __ Mov(r2, 0xffffffff);
782 
783   __ Lsl(r3, r1, 4);
784   __ Lsr(r4, r1, 8);
785   __ Asr(r5, r1, 16);
786   __ Ror(r6, r1, 20);
787   END();
788 
789   RUN();
790 
791   ASSERT_EQUAL_32(0xedcba980, r3);
792   ASSERT_EQUAL_32(0x00fedcba, r4);
793   ASSERT_EQUAL_32(0xfffffedc, r5);
794   ASSERT_EQUAL_32(0xcba98fed, r6);
795 }
796 
797 
TEST(shift_reg)798 TEST(shift_reg) {
799   SETUP();
800 
801   START();
802   __ Mov(r0, 0);
803   __ Mov(r1, 0xfedcba98);
804   __ Mov(r2, 0xffffffff);
805 
806   __ Add(r9, r0, 4);
807   __ Lsl(r3, r1, r9);
808 
809   __ Add(r9, r0, 8);
810   __ Lsr(r4, r1, r9);
811 
812   __ Add(r9, r0, 16);
813   __ Asr(r5, r1, r9);
814 
815   __ Add(r9, r0, 20);
816   __ Ror(r6, r1, r9);
817 
818   // Set the C flag.
819   __ Adds(r7, r2, 1);
820   __ Rrx(r7, r1);
821 
822   // Clear the C flag.
823   __ Adds(r8, r0, 0);
824   __ Rrx(r8, r1);
825   END();
826 
827   RUN();
828 
829   ASSERT_EQUAL_32(0xedcba980, r3);
830   ASSERT_EQUAL_32(0x00fedcba, r4);
831   ASSERT_EQUAL_32(0xfffffedc, r5);
832   ASSERT_EQUAL_32(0xcba98fed, r6);
833   ASSERT_EQUAL_32(0xff6e5d4c, r7);
834   ASSERT_EQUAL_32(0x7f6e5d4c, r8);
835 }
836 
837 
TEST(branch_cond)838 TEST(branch_cond) {
839   SETUP();
840 
841   Label done, wrong;
842 
843   START();
844   __ Mov(r0, 0x0);
845   __ Mov(r1, 0x1);
846   __ Mov(r2, 0x80000000);
847   // TODO: Use r0 instead of r3 when r0 becomes available.
848   __ Mov(r3, 0x1);
849 
850   // For each 'cmp' instruction below, condition codes other than the ones
851   // following it would branch.
852 
853   __ Cmp(r1, 0);
854   __ B(eq, &wrong);
855   __ B(lo, &wrong);
856   __ B(mi, &wrong);
857   __ B(vs, &wrong);
858   __ B(ls, &wrong);
859   __ B(lt, &wrong);
860   __ B(le, &wrong);
861   Label ok_1;
862   __ B(ne, &ok_1);
863   // TODO: Use __ Mov(r0, 0x0) instead.
864   __ Add(r3, r0, 0x0);
865   __ Bind(&ok_1);
866 
867   __ Cmp(r1, 1);
868   __ B(ne, &wrong);
869   __ B(lo, &wrong);
870   __ B(mi, &wrong);
871   __ B(vs, &wrong);
872   __ B(hi, &wrong);
873   __ B(lt, &wrong);
874   __ B(gt, &wrong);
875   Label ok_2;
876   __ B(pl, &ok_2);
877   // TODO: Use __ Mov(r0, 0x0) instead.
878   __ Add(r3, r0, 0x0);
879   __ Bind(&ok_2);
880 
881   __ Cmp(r1, 2);
882   __ B(eq, &wrong);
883   __ B(hs, &wrong);
884   __ B(pl, &wrong);
885   __ B(vs, &wrong);
886   __ B(hi, &wrong);
887   __ B(ge, &wrong);
888   __ B(gt, &wrong);
889   Label ok_3;
890   __ B(vc, &ok_3);
891   // TODO: Use __ Mov(r0, 0x0) instead.
892   __ Add(r3, r0, 0x0);
893   __ Bind(&ok_3);
894 
895   __ Cmp(r2, 1);
896   __ B(eq, &wrong);
897   __ B(lo, &wrong);
898   __ B(mi, &wrong);
899   __ B(vc, &wrong);
900   __ B(ls, &wrong);
901   __ B(ge, &wrong);
902   __ B(gt, &wrong);
903   Label ok_4;
904   __ B(le, &ok_4);
905   // TODO: Use __ Mov(r0, 0x0) instead.
906   __ Add(r3, r0, 0x0);
907   __ Bind(&ok_4);
908 
909   Label ok_5;
910   __ B(&ok_5);
911   // TODO: Use __ Mov(r0, 0x0) instead.
912   __ Add(r3, r0, 0x0);
913   __ Bind(&ok_5);
914 
915   __ B(&done);
916 
917   __ Bind(&wrong);
918   // TODO: Use __ Mov(r0, 0x0) instead.
919   __ Add(r3, r0, 0x0);
920 
921   __ Bind(&done);
922   END();
923 
924   RUN();
925 
926   // TODO: Use r0.
927   ASSERT_EQUAL_32(0x1, r3);
928 }
929 
930 
TEST(bfc_bfi)931 TEST(bfc_bfi) {
932   SETUP();
933 
934   START();
935   __ Mov(r0, 0xffffffff);
936   __ Mov(r1, 0x01234567);
937   __ Mov(r2, 0x0);
938 
939   __ Bfc(r0, 0, 3);
940   __ Bfc(r0, 16, 5);
941 
942   __ Bfi(r2, r1, 0, 8);
943   __ Bfi(r2, r1, 16, 16);
944   END();
945 
946   RUN();
947 
948   ASSERT_EQUAL_32(0xffe0fff8, r0);
949   ASSERT_EQUAL_32(0x45670067, r2);
950 }
951 
952 
TEST(bic)953 TEST(bic) {
954   SETUP();
955 
956   START();
957   __ Mov(r0, 0xfff0);
958   __ Mov(r1, 0xf00000ff);
959   __ Mov(r2, 0xffffffff);
960 
961   __ Bic(r3, r0, r1);
962   __ Bic(r4, r0, Operand(r1, LSL, 4));
963   __ Bic(r5, r0, Operand(r1, LSR, 1));
964   __ Bic(r6, r0, Operand(r1, ASR, 20));
965   __ Bic(r7, r0, Operand(r1, ROR, 28));
966   __ Bic(r8, r0, 0x1f);
967 
968   // Set the C flag.
969   __ Adds(r9, r2, 1);
970   __ Bic(r9, r1, Operand(r1, RRX));
971 
972   // Clear the C flag.
973   __ Adds(r10, r0, 0);
974   __ Bic(r10, r1, Operand(r1, RRX));
975   END();
976 
977   RUN();
978 
979   ASSERT_EQUAL_32(0x0000ff00, r3);
980   ASSERT_EQUAL_32(0x0000f000, r4);
981   ASSERT_EQUAL_32(0x0000ff80, r5);
982   ASSERT_EQUAL_32(0x000000f0, r6);
983   ASSERT_EQUAL_32(0x0000f000, r7);
984   ASSERT_EQUAL_32(0x0000ffe0, r8);
985   ASSERT_EQUAL_32(0x00000080, r9);
986   ASSERT_EQUAL_32(0x80000080, r10);
987 }
988 
989 
TEST(bics)990 TEST(bics) {
991   SETUP();
992 
993   START();
994   __ Mov(r0, 0);
995   __ Mov(r1, 0xf00000ff);
996 
997   __ Bics(r0, r1, r1);
998   END();
999 
1000   RUN();
1001 
1002   ASSERT_EQUAL_NZCV(ZFlag);
1003   ASSERT_EQUAL_32(0, r0);
1004 
1005   START();
1006   __ Mov(r0, 0x00fff000);
1007   __ Mov(r1, 0x0fffff00);
1008 
1009   __ Bics(r0, r0, Operand(r1, LSL, 4));
1010   END();
1011 
1012   RUN();
1013 
1014   ASSERT_EQUAL_NZCV(ZFlag);
1015   ASSERT_EQUAL_32(0x00000000, r0);
1016 
1017   START();
1018   __ Mov(r0, 0x0000fff0);
1019   __ Mov(r1, 0x0fffff00);
1020 
1021   __ Bics(r0, r0, Operand(r1, LSR, 4));
1022   END();
1023 
1024   RUN();
1025 
1026   ASSERT_EQUAL_NZCV(ZFlag);
1027   ASSERT_EQUAL_32(0x00000000, r0);
1028 
1029   START();
1030   __ Mov(r0, 0xf000fff0);
1031   __ Mov(r1, 0x0fffff00);
1032 
1033   __ Bics(r0, r0, Operand(r1, ASR, 4));
1034   END();
1035 
1036   RUN();
1037 
1038   ASSERT_EQUAL_NZCV(NFlag);
1039   ASSERT_EQUAL_32(0xf0000000, r0);
1040 
1041   START();
1042   __ Mov(r0, 0x80000000);
1043   __ Mov(r1, 0xfffffffe);
1044 
1045   __ Bics(r0, r0, Operand(r1, ROR, 1));
1046   END();
1047 
1048   RUN();
1049 
1050   ASSERT_EQUAL_NZCV(NFlag);
1051   ASSERT_EQUAL_32(0x80000000, r0);
1052 
1053   START();
1054   __ Mov(r0, 0x80000000);
1055   __ Mov(r1, 0x80000001);
1056 
1057   // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
1058   __ Adds(r2, r0, 0);
1059   __ Bics(r2, r0, Operand(r1, RRX));
1060   END();
1061 
1062   RUN();
1063 
1064   ASSERT_EQUAL_NZCV(NCFlag);
1065   ASSERT_EQUAL_32(0x80000000, r2);
1066 
1067   START();
1068   __ Mov(r0, 0x80000000);
1069   __ Mov(r1, 0x80000001);
1070   __ Mov(r2, 0xffffffff);
1071 
1072   // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
1073   __ Adds(r2, r2, 1);
1074   __ Bics(r2, r0, Operand(r1, RRX));
1075   END();
1076 
1077   RUN();
1078 
1079   ASSERT_EQUAL_NZCV(ZCFlag);
1080   ASSERT_EQUAL_32(0, r2);
1081 
1082   START();
1083   __ Mov(r0, 0xf000);
1084 
1085   __ Bics(r0, r0, 0xf000);
1086   END();
1087 
1088   RUN();
1089 
1090   ASSERT_EQUAL_NZCV(ZFlag);
1091   ASSERT_EQUAL_32(0x00000000, r0);
1092 
1093   START();
1094   __ Mov(r0, 0xff000000);
1095 
1096   __ Bics(r0, r0, 0x7fffffff);
1097   END();
1098 
1099   RUN();
1100 
1101   ASSERT_EQUAL_NZCV(NFlag);
1102   ASSERT_EQUAL_32(0x80000000, r0);
1103 }
1104 
1105 // Make sure calling a macro-assembler instruction will generate literal pools
1106 // if needed.
TEST_T32(veneer_pool_generated_by_macro_instruction)1107 TEST_T32(veneer_pool_generated_by_macro_instruction) {
1108   SETUP();
1109 
1110   START();
1111 
1112   Label start, end;
1113 
1114   VIXL_CHECK(test.PoolIsEmpty());
1115 
1116   __ Mov(r0, 1);
1117 
1118   __ Bind(&start);
1119   __ Cbz(r0, &end);
1120 
1121   VIXL_CHECK(!test.PoolIsEmpty());
1122 
1123   // Generate enough code so that, after the loop, no instruction can be
1124   // generated before we need to generate the veneer pool.
1125   // Use `ExactAssemblyScope` and the assembler to generate the code.
1126   int32_t space = test.GetPoolCheckpoint() - masm.GetCursorOffset();
1127   {
1128     ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1129     while (space > 0) {
1130       __ nop();
1131       space -= k16BitT32InstructionSizeInBytes;
1132     }
1133   }
1134 
1135   // We should not have emitted the pool at this point.
1136   VIXL_CHECK(!test.PoolIsEmpty());
1137   VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
1138 
1139   // Now the pool will need to be generated before we can emit anything.
1140   Label check;
1141   __ Bind(&check);
1142   __ Mov(r0, 0);
1143   // We should have generated 3 wide instructions:
1144   //     b.w past_veneer_pool
1145   //     b.w end ;; veneer from CBZ to "end".
1146   //   past_veneer_pool:
1147   //     mov r0, #0
1148   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) ==
1149              (3 * k32BitT32InstructionSizeInBytes));
1150 
1151   // Branch back to make sure the veneers work.
1152   __ B(&start);
1153   __ Bind(&end);
1154 
1155   VIXL_CHECK(test.PoolIsEmpty());
1156 
1157   END();
1158 
1159   RUN();
1160 
1161   ASSERT_EQUAL_32(0, r0);
1162 }
1163 
1164 // NOTE: This test has needed modifications for the new pool manager, as it
1165 // was testing a corner case of the previous pool managers. We keep it as
1166 // another testcase.
TEST(emit_reused_load_literal)1167 TEST(emit_reused_load_literal) {
1168   SETUP();
1169 
1170   START();
1171 
1172   // Make sure the pool is empty.
1173   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1174   VIXL_CHECK(test.PoolIsEmpty());
1175 
1176   const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1177   const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1178   std::string test_string(string_size, 'x');
1179   StringLiteral big_literal(test_string.c_str());
1180   __ Adr(r4, &big_literal);
1181 
1182   // This load has a wider range than the Ldrd used below for the same
1183   // literal.
1184   Literal<uint64_t> l1(0xcafebeefdeadbaba);
1185   __ Ldr(r0, &l1);
1186 
1187   // With the old pool manager, this Ldrd used to force pool emission before
1188   // being generated. Now, 'l1' and 'big_literal' can be reordered in the pool,
1189   // and pool emission is not triggered anymore.
1190   __ Ldrd(r2, r3, &l1);
1191 
1192   __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
1193   END();
1194 
1195   RUN();
1196 
1197   // Check that the literals loaded correctly.
1198   ASSERT_EQUAL_32(0xdeadbaba, r0);
1199   ASSERT_EQUAL_32(0xdeadbaba, r2);
1200   ASSERT_EQUAL_32(0xcafebeef, r3);
1201   ASSERT_EQUAL_32(0x78787878, r4);
1202 }
1203 
1204 // NOTE: This test has needed modifications for the new pool manager, as it
1205 // was testing a corner case of the previous pool managers. We keep it as
1206 // another testcase.
TEST(emit_reused_load_literal_should_not_rewind)1207 TEST(emit_reused_load_literal_should_not_rewind) {
1208   // This test checks that we are not conservative when rewinding a load of a
1209   // literal that is already in the literal pool.
1210   SETUP();
1211 
1212   START();
1213 
1214   // Make sure the pool is empty.
1215   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1216   VIXL_CHECK(test.PoolIsEmpty());
1217 
1218   // This load has a wider range than the Ldrd used below for the same
1219   // literal.
1220   Literal<uint64_t> l1(0xcafebeefdeadbaba);
1221   __ Ldr(r0, &l1);
1222 
1223   // Add a large string to the literal pool, but only *after* l1, so the
1224   // Ldrd below should not need to rewind.
1225   const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1226   const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1227   std::string test_string(string_size, 'x');
1228   StringLiteral big_literal(test_string.c_str());
1229   __ Adr(r4, &big_literal);
1230   __ Ldrd(r2, r3, &l1);
1231 
1232   // Here we used to check the pool size, which can now be zero as we emit the
1233   // literals in a different order.
1234 
1235   // Make sure the pool is emitted.
1236   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1237   VIXL_CHECK(test.PoolIsEmpty());
1238 
1239   __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
1240   END();
1241 
1242   RUN();
1243 
1244   // Check that the literals loaded correctly.
1245   ASSERT_EQUAL_32(0xdeadbaba, r0);
1246   ASSERT_EQUAL_32(0xdeadbaba, r2);
1247   ASSERT_EQUAL_32(0xcafebeef, r3);
1248   ASSERT_EQUAL_32(0x78787878, r4);
1249 }
1250 
1251 
EmitReusedLoadLiteralStressTest(InstructionSet isa,bool conditional)1252 void EmitReusedLoadLiteralStressTest(InstructionSet isa, bool conditional) {
1253   // This test stresses loading a literal that is already in the literal pool,
1254   // for various positionings on the existing load from that literal. We try to
1255   // exercise cases where the two loads result in similar checkpoints for the
1256   // literal pool.
1257   SETUP();
1258 
1259   const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1260   const int ldr_range = 4095;
1261   const int nop_size = masm.IsUsingA32() ? 4 : 2;
1262   const int nops = (ldr_range - ldrd_range) / nop_size;
1263 
1264   for (int n = nops - 10; n < nops + 10; ++n) {
1265     START();
1266 
1267     // Make sure the pool is empty.
1268     masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1269     VIXL_CHECK(test.PoolIsEmpty());
1270 
1271     if (conditional) {
1272       __ Mov(r1, 0);
1273       __ Cmp(r1, 0);
1274     }
1275 
1276     // Add a large string to the pool, which will stress corner cases with the
1277     // Ldrd below (if the pool is not already emitted due to the Ldr).
1278     const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1279     std::string test_string(string_size, 'x');
1280     StringLiteral big_literal(test_string.c_str());
1281     __ Ldr(r4, &big_literal);
1282 
1283     // This load has a wider range than the Ldrd used below for the same
1284     // literal.
1285     Literal<uint64_t> l1(0xcafebeefdeadbaba);
1286     __ Ldr(r0, &l1);
1287 
1288     // Generate nops, in order to bring the checkpoints of the Ldr and Ldrd
1289     // closer.
1290     {
1291       ExactAssemblyScope scope(&masm,
1292                                n * nop_size,
1293                                ExactAssemblyScope::kExactSize);
1294       for (int i = 0; i < n; ++i) {
1295         __ nop();
1296       }
1297     }
1298 
1299     if (conditional) {
1300       __ Ldrd(eq, r2, r3, &l1);
1301     } else {
1302       __ Ldrd(r2, r3, &l1);
1303     }
1304 
1305     // Here we used to check that the pool is empty. Since the new pool manager
1306     // allows reordering of literals in the pool, this will not always be the
1307     // case. 'l1' can now be emitted before 'big_literal', allowing the pool to
1308     // be emitted after the ldrd when the number of nops is small enough.
1309 
1310     END();
1311 
1312     RUN();
1313 
1314     // Check that the literals loaded correctly.
1315     ASSERT_EQUAL_32(0xdeadbaba, r0);
1316     ASSERT_EQUAL_32(0xdeadbaba, r2);
1317     ASSERT_EQUAL_32(0xcafebeef, r3);
1318     ASSERT_EQUAL_32(0x78787878, r4);
1319   }
1320 }
1321 
1322 
TEST(emit_reused_load_literal_stress)1323 TEST(emit_reused_load_literal_stress) {
1324   EmitReusedLoadLiteralStressTest(isa, false /*conditional*/);
1325 }
1326 
1327 
TEST(emit_reused_conditional_load_literal_stress)1328 TEST(emit_reused_conditional_load_literal_stress) {
1329   EmitReusedLoadLiteralStressTest(isa, true /*conditional*/);
1330 }
1331 
1332 
TEST(test_many_loads_from_same_literal)1333 TEST(test_many_loads_from_same_literal) {
1334   // This test generates multiple loads from the same literal in order to
1335   // test that the delegate recursion limit is appropriate for Ldrd with
1336   // large negative offsets.
1337   SETUP();
1338 
1339   START();
1340 
1341   // Make sure the pool is empty.
1342   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1343   VIXL_CHECK(test.PoolIsEmpty());
1344 
1345   Literal<uint64_t> l0(0xcafebeefdeadbaba);
1346   __ Ldrd(r0, r1, &l0);
1347   for (int i = 0; i < 10000; ++i) {
1348     __ Add(r2, r2, i);
1349     __ Ldrd(r4, r5, &l0);
1350   }
1351 
1352   __ Ldrd(r2, r3, &l0);
1353 
1354   END();
1355 
1356   RUN();
1357 
1358   // Check that the literals loaded correctly.
1359   ASSERT_EQUAL_32(0xdeadbaba, r0);
1360   ASSERT_EQUAL_32(0xcafebeef, r1);
1361   ASSERT_EQUAL_32(0xdeadbaba, r2);
1362   ASSERT_EQUAL_32(0xcafebeef, r3);
1363   ASSERT_EQUAL_32(0xdeadbaba, r4);
1364   ASSERT_EQUAL_32(0xcafebeef, r5);
1365 }
1366 
1367 
1368 // Make sure calling a macro-assembler instruction will generate literal pools
1369 // if needed.
TEST_T32(literal_pool_generated_by_macro_instruction)1370 TEST_T32(literal_pool_generated_by_macro_instruction) {
1371   SETUP();
1372 
1373   START();
1374 
1375   VIXL_CHECK(test.PoolIsEmpty());
1376 
1377   __ Ldrd(r0, r1, 0x1234567890abcdef);
1378 
1379   VIXL_CHECK(!test.PoolIsEmpty());
1380 
1381   // Generate enough code so that, after the loop, no instruction can be
1382   // generated before we need to generate the literal pool.
1383   // Use `ExactAssemblyScope` and the assembler to generate the code.
1384   int32_t space = test.GetPoolCheckpoint() - masm.GetCursorOffset();
1385   {
1386     ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1387     while (space > 0) {
1388       __ nop();
1389       space -= k16BitT32InstructionSizeInBytes;
1390     }
1391   }
1392 
1393   // We should not have emitted the literal pool at this point.
1394   VIXL_CHECK(!test.PoolIsEmpty());
1395   VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
1396 
1397   // Now the pool will need to be generated before we emit anything.
1398   Label check;
1399   __ Bind(&check);
1400   __ Mov(r2, 0x12345678);
1401   // We should have generated 3 wide instructions and 8 bytes of data:
1402   //     b.w past_literal_pool
1403   //     .bytes 0x1234567890abcdef
1404   //   past_literal_pool:
1405   //     mov r2, #22136
1406   //     movt r2, #4660
1407   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) ==
1408              (3 * k32BitT32InstructionSizeInBytes + 8));
1409 
1410   VIXL_CHECK(test.PoolIsEmpty());
1411 
1412   END();
1413 
1414   RUN();
1415 
1416   ASSERT_EQUAL_32(0x90abcdef, r0);
1417   ASSERT_EQUAL_32(0x12345678, r1);
1418   ASSERT_EQUAL_32(0x12345678, r2);
1419 }
1420 
TEST(emit_single_literal)1421 TEST(emit_single_literal) {
1422   SETUP();
1423 
1424   START();
1425   // Make sure the pool is empty.
1426   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1427   VIXL_CHECK(test.PoolIsEmpty());
1428 
1429   // Create one literal pool entry.
1430   __ Ldrd(r0, r1, 0x1234567890abcdef);
1431   CHECK_POOL_SIZE(8);
1432   __ Vldr(s0, 1.0);
1433   __ Vldr(d1, 2.0);
1434   __ Vmov(d2, 4.1);
1435   __ Vmov(s8, 8.2);
1436   CHECK_POOL_SIZE(20);
1437   END();
1438 
1439   RUN();
1440 
1441   // Check that the literals loaded correctly.
1442   ASSERT_EQUAL_32(0x90abcdef, r0);
1443   ASSERT_EQUAL_32(0x12345678, r1);
1444   ASSERT_EQUAL_FP32(1.0f, s0);
1445   ASSERT_EQUAL_FP64(2.0, d1);
1446   ASSERT_EQUAL_FP64(4.1, d2);
1447   ASSERT_EQUAL_FP32(8.2f, s8);
1448 }
1449 
1450 
1451 #undef __
1452 #undef __TESTOBJ
1453 #define __ masm->
1454 #define __TESTOBJ test->
1455 
1456 
EmitLdrdLiteralTest(MacroAssembler * masm,TestMacroAssembler * test)1457 void EmitLdrdLiteralTest(MacroAssembler* masm, TestMacroAssembler* test) {
1458   const int ldrd_range = masm->IsUsingA32() ? 255 : 1020;
1459   // We want to emit code up to the maximum literal load range and ensure the
1460   // pool has not been emitted. Compute the limit (end).
1461   ptrdiff_t end = AlignDown(
1462       // Align down the PC to 4 bytes as the instruction does when it's
1463       // executed.
1464       // The PC will be the cursor offset plus the architecture state PC
1465       // offset.
1466       AlignDown(masm->GetBuffer()->GetCursorOffset() +
1467                     masm->GetArchitectureStatePCOffset(),
1468                 4) +
1469           // Maximum range allowed to access the constant.
1470           ldrd_range -
1471           // Take into account the branch over the pool.
1472           kMaxInstructionSizeInBytes,
1473       // AlignDown to 4 byte as the literals will be 4 byte aligned.
1474       4);
1475 
1476   // Create one literal pool entry.
1477   __ Ldrd(r0, r1, 0x1234567890abcdef);
1478   CHECK_POOL_SIZE(8);
1479 
1480   int32_t margin = test->GetPoolCheckpoint() - masm->GetCursorOffset();
1481   VIXL_ASSERT(end == test->GetPoolCheckpoint());
1482   {
1483     ExactAssemblyScope scope(masm, margin, ExactAssemblyScope::kExactSize);
1484     // Opening the scope should not have triggered the emission of the literal
1485     // pool.
1486     VIXL_CHECK(!test->PoolIsEmpty());
1487     while (masm->GetCursorOffset() < end) {
1488       __ nop();
1489     }
1490     VIXL_CHECK(masm->GetCursorOffset() == end);
1491   }
1492 
1493   // Check that the pool has not been emited along the way.
1494   CHECK_POOL_SIZE(8);
1495   // This extra instruction should trigger an emit of the pool.
1496   __ Nop();
1497   // The pool should have been emitted.
1498   VIXL_CHECK(test->PoolIsEmpty());
1499 }
1500 
1501 #undef __
1502 #undef __TESTOBJ
1503 #define __ masm.
1504 #define __TESTOBJ test.
1505 
1506 // NOTE: This test has needed modifications for the new pool manager, as it
1507 // was testing a corner case of the previous pool managers. We keep it as
1508 // another testcase.
TEST(emit_literal_rewind)1509 TEST(emit_literal_rewind) {
1510   SETUP();
1511 
1512   START();
1513 
1514   // Make sure the pool is empty.
1515   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1516   VIXL_CHECK(test.PoolIsEmpty());
1517 
1518   EmitLdrdLiteralTest(&masm, &test);
1519 
1520   const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1521   const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1522   std::string test_string(string_size, 'x');
1523   StringLiteral big_literal(test_string.c_str());
1524   __ Adr(r4, &big_literal);
1525   __ Ldrd(r2, r3, 0xcafebeefdeadbaba);
1526   // With the old pool manager, the adr above would overflow the literal pool
1527   // and force a rewind and pool emission.
1528   // Here we used to check the pool size to confirm that 'big_literal' had
1529   // already been emitted. This does not have to be the case now, as we can
1530   // emit the literals in a different order.
1531 
1532   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1533   VIXL_CHECK(test.PoolIsEmpty());
1534   __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
1535   END();
1536 
1537   RUN();
1538 
1539   // Check that the literals loaded correctly.
1540   ASSERT_EQUAL_32(0x90abcdef, r0);
1541   ASSERT_EQUAL_32(0x12345678, r1);
1542   ASSERT_EQUAL_32(0xdeadbaba, r2);
1543   ASSERT_EQUAL_32(0xcafebeef, r3);
1544   ASSERT_EQUAL_32(0x78787878, r4);
1545 }
1546 
1547 
1548 // NOTE: This test has needed modifications for the new pool manager, as it
1549 // was testing a corner case of the previous pool managers. We keep it as
1550 // another testcase.
TEST(emit_literal_conditional_rewind)1551 TEST(emit_literal_conditional_rewind) {
1552   SETUP();
1553 
1554   START();
1555 
1556   // This test is almost identical to the test above, but the Ldrd instruction
1557   // is conditional and there is a second conditional Ldrd instruction that will
1558   // not be executed.
1559 
1560   // Make sure the pool is empty.
1561   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1562   VIXL_CHECK(test.PoolIsEmpty());
1563 
1564   const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1565   const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1566   std::string test_string(string_size, 'x');
1567   StringLiteral big_literal(test_string.c_str());
1568   __ Adr(r2, &big_literal);
1569   __ Mov(r0, 0);
1570   __ Mov(r1, 0);
1571   __ Mov(r3, 1);
1572   __ Cmp(r3, 1);
1573   __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
1574   __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
1575   // With the old pool manager, the adr above would overflow the literal pool
1576   // and force a rewind and pool emission.
1577   // Here we used to check the pool size to confirm that 'big_literal' had
1578   // already been emitted. This does not have to be the case now, as we can
1579   // emit the literals in a different order.
1580 
1581   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1582   VIXL_CHECK(test.PoolIsEmpty());
1583   __ Ldr(r2, MemOperand(r2));  // Load the first 4 characters in r2.
1584   END();
1585 
1586   RUN();
1587 
1588   // Check that the literals loaded correctly.
1589   ASSERT_EQUAL_32(0xdeadbaba, r0);
1590   ASSERT_EQUAL_32(0xcafebeef, r1);
1591   ASSERT_EQUAL_32(0x78787878, r2);
1592 }
1593 
1594 enum LiteralStressTestMode {
1595   kUnconditional,
1596   kConditionalTrue,
1597   kConditionalFalse,
1598   kConditionalBoth
1599 };
1600 
1601 // Test loading a literal when the size of the literal pool is close to the
1602 // maximum range of the load, with varying PC values (and alignment, for T32).
1603 // This test is similar to the tests above, with the difference that we allow
1604 // an extra offset to the string size in order to make sure that various pool
1605 // sizes close to the maximum supported offset will produce code that executes
1606 // correctly. As the Ldrd might or might not be emitted before the pool, we do
1607 // not assert on the size of the literal pool in this test.
EmitLdrdLiteralStressTest(InstructionSet isa,bool unaligned,LiteralStressTestMode test_mode)1608 void EmitLdrdLiteralStressTest(InstructionSet isa,
1609                                bool unaligned,
1610                                LiteralStressTestMode test_mode) {
1611   SETUP();
1612 
1613   for (int offset = -10; offset <= 10; ++offset) {
1614     START();
1615 
1616     if (unaligned) {
1617       __ Nop();
1618       VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
1619     }
1620 
1621     // Make sure the pool is empty.
1622     masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1623     VIXL_CHECK(test.PoolIsEmpty());
1624 
1625     const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1626     const int string_size = ldrd_range + offset;
1627     std::string test_string(string_size - 1, 'x');
1628     StringLiteral big_literal(test_string.c_str());
1629     __ Adr(r2, &big_literal);
1630     __ Mov(r0, 0);
1631     __ Mov(r1, 0);
1632     switch (test_mode) {
1633       case kUnconditional:
1634         __ Ldrd(r0, r1, 0xcafebeefdeadbaba);
1635         break;
1636       case kConditionalTrue:
1637         __ Mov(r0, 0xffffffff);
1638         __ Mov(r1, r0);
1639         __ Mov(r3, 1);
1640         __ Cmp(r3, 1);
1641         __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
1642         break;
1643       case kConditionalFalse:
1644         __ Mov(r0, 0xdeadbaba);
1645         __ Mov(r1, 0xcafebeef);
1646         __ Mov(r3, 1);
1647         __ Cmp(r3, 1);
1648         __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
1649         break;
1650       case kConditionalBoth:
1651         __ Mov(r3, 1);
1652         __ Cmp(r3, 1);
1653         __ Ldrd(eq, r0, r1, 0xcafebeefdeadbaba);
1654         __ Ldrd(ne, r0, r1, 0xdeadcafebeefbaba);
1655         break;
1656     }
1657 
1658     masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1659     VIXL_CHECK(test.PoolIsEmpty());
1660     __ Ldr(r2, MemOperand(r2));  // Load the first 4 characters in r2.
1661     END();
1662 
1663     RUN();
1664 
1665     // Check that the literals loaded correctly.
1666     ASSERT_EQUAL_32(0xdeadbaba, r0);
1667     ASSERT_EQUAL_32(0xcafebeef, r1);
1668     ASSERT_EQUAL_32(0x78787878, r2);
1669   }
1670 }
1671 
1672 
TEST(emit_literal_stress)1673 TEST(emit_literal_stress) {
1674   EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kUnconditional);
1675 }
1676 
1677 
TEST_T32(emit_literal_stress_unaligned)1678 TEST_T32(emit_literal_stress_unaligned) {
1679   EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kUnconditional);
1680 }
1681 
1682 
TEST(emit_literal_conditional_stress)1683 TEST(emit_literal_conditional_stress) {
1684   EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalTrue);
1685   EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalFalse);
1686   EmitLdrdLiteralStressTest(isa, false /*unaligned*/, kConditionalBoth);
1687 }
1688 
1689 
TEST_T32(emit_literal_conditional_stress_unaligned)1690 TEST_T32(emit_literal_conditional_stress_unaligned) {
1691   EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalTrue);
1692   EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalFalse);
1693   EmitLdrdLiteralStressTest(isa, true /*unaligned*/, kConditionalBoth);
1694 }
1695 
TEST_T32(emit_literal_unaligned)1696 TEST_T32(emit_literal_unaligned) {
1697   SETUP();
1698 
1699   START();
1700 
1701   // Make sure the pool is empty.
1702   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1703   VIXL_CHECK(test.PoolIsEmpty());
1704 
1705   // Generate a nop to break the 4 bytes alignment.
1706   __ Nop();
1707 
1708   EmitLdrdLiteralTest(&masm, &test);
1709 
1710   END();
1711 
1712   RUN();
1713 
1714   // Check that the literals loaded correctly.
1715   ASSERT_EQUAL_32(0x90abcdef, r0);
1716   ASSERT_EQUAL_32(0x12345678, r1);
1717 }
1718 
TEST(literal_multiple_uses)1719 TEST(literal_multiple_uses) {
1720   SETUP();
1721 
1722   START();
1723   Literal<int32_t> lit(42);
1724   __ Ldr(r0, &lit);
1725   CHECK_POOL_SIZE(4);
1726 
1727   // Multiple uses of the same literal object should not make the
1728   // pool grow.
1729   __ Ldrb(r1, &lit);
1730   __ Ldrsb(r2, &lit);
1731   __ Ldrh(r3, &lit);
1732   __ Ldrsh(r4, &lit);
1733   CHECK_POOL_SIZE(4);
1734 
1735   END();
1736 
1737   RUN();
1738 
1739   ASSERT_EQUAL_32(42, r0);
1740   ASSERT_EQUAL_32(42, r1);
1741   ASSERT_EQUAL_32(42, r2);
1742   ASSERT_EQUAL_32(42, r3);
1743   ASSERT_EQUAL_32(42, r4);
1744 }
1745 
1746 
1747 // A test with two loads literal which go out of range at the same time.
TEST_A32(ldr_literal_range_same_time)1748 TEST_A32(ldr_literal_range_same_time) {
1749   SETUP();
1750 
1751   START();
1752   const int ldrd_range = 255;
1753   // We need to take into account the jump over the pool.
1754   const int ldrd_padding = ldrd_range - 2 * kA32InstructionSizeInBytes;
1755   const int ldr_range = 4095;
1756   // We need to take into account the ldrd padding and the ldrd instruction.
1757   const int ldr_padding =
1758       ldr_range - ldrd_padding - 2 * kA32InstructionSizeInBytes;
1759 
1760   __ Ldr(r1, 0x12121212);
1761   CHECK_POOL_SIZE(4);
1762 
1763   {
1764     int space = AlignDown(ldr_padding, kA32InstructionSizeInBytes);
1765     ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1766     int32_t end = masm.GetCursorOffset() + space;
1767     while (masm.GetCursorOffset() < end) {
1768       __ nop();
1769     }
1770   }
1771 
1772   __ Ldrd(r2, r3, 0x1234567890abcdef);
1773   CHECK_POOL_SIZE(12);
1774 
1775   {
1776     int space = AlignDown(ldrd_padding, kA32InstructionSizeInBytes);
1777     ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1778     for (int32_t end = masm.GetCursorOffset() + space;
1779          masm.GetCursorOffset() < end;) {
1780       __ nop();
1781     }
1782   }
1783   CHECK_POOL_SIZE(12);
1784 
1785   // This mov will put the two loads literal out of range and will force
1786   // the literal pool emission.
1787   __ Mov(r0, 0);
1788   VIXL_CHECK(test.PoolIsEmpty());
1789   END();
1790 
1791   RUN();
1792 
1793   ASSERT_EQUAL_32(0x12121212, r1);
1794   ASSERT_EQUAL_32(0x90abcdef, r2);
1795   ASSERT_EQUAL_32(0x12345678, r3);
1796 }
1797 
1798 
TEST(ldr_literal_mix_types)1799 TEST(ldr_literal_mix_types) {
1800   SETUP();
1801 
1802   START();
1803   Literal<uint64_t> l0(0x1234567890abcdef);
1804   Literal<int32_t> l1(0x12345678);
1805   Literal<uint16_t> l2(1234);
1806   Literal<int16_t> l3(-678);
1807   Literal<uint8_t> l4(42);
1808   Literal<int8_t> l5(-12);
1809 
1810   __ Ldrd(r0, r1, &l0);
1811   __ Ldr(r2, &l1);
1812   __ Ldrh(r3, &l2);
1813   __ Ldrsh(r4, &l3);
1814   __ Ldrb(r5, &l4);
1815   __ Ldrsb(r6, &l5);
1816   // The pool size does not include padding.
1817   CHECK_POOL_SIZE(18);
1818 
1819   END();
1820 
1821   RUN();
1822 
1823   ASSERT_EQUAL_32(0x90abcdef, r0);
1824   ASSERT_EQUAL_32(0x12345678, r1);
1825   ASSERT_EQUAL_32(0x12345678, r2);
1826   ASSERT_EQUAL_32(1234, r3);
1827   ASSERT_EQUAL_32(-678, r4);
1828   ASSERT_EQUAL_32(42, r5);
1829   ASSERT_EQUAL_32(-12, r6);
1830 }
1831 
1832 
TEST(ldr_literal_conditional)1833 TEST(ldr_literal_conditional) {
1834   SETUP();
1835 
1836   START();
1837   Literal<uint64_t> l0(0x1234567890abcdef);
1838   Literal<uint64_t> l0_not_taken(0x90abcdef12345678);
1839   Literal<int32_t> l1(0x12345678);
1840   Literal<int32_t> l1_not_taken(0x56781234);
1841   Literal<uint16_t> l2(1234);
1842   Literal<uint16_t> l2_not_taken(3412);
1843   Literal<int16_t> l3(-678);
1844   Literal<int16_t> l3_not_taken(678);
1845   Literal<uint8_t> l4(42);
1846   Literal<uint8_t> l4_not_taken(-42);
1847   Literal<int8_t> l5(-12);
1848   Literal<int8_t> l5_not_taken(12);
1849   Literal<float> l6(1.2345f);
1850   Literal<float> l6_not_taken(0.0f);
1851   Literal<double> l7(1.3333);
1852   Literal<double> l7_not_taken(0.0);
1853 
1854   // Check that conditionally loading literals of different types works
1855   // correctly for both A32 and T32.
1856   __ Mov(r7, 1);
1857   __ Cmp(r7, 1);
1858   __ Ldrd(eq, r0, r1, &l0);
1859   __ Ldrd(ne, r0, r1, &l0_not_taken);
1860   __ Cmp(r7, 0);
1861   __ Ldr(gt, r2, &l1);
1862   __ Ldr(le, r2, &l1_not_taken);
1863   __ Cmp(r7, 2);
1864   __ Ldrh(lt, r3, &l2);
1865   __ Ldrh(ge, r3, &l2_not_taken);
1866   __ Ldrsh(le, r4, &l3);
1867   __ Ldrsh(gt, r4, &l3_not_taken);
1868   __ Cmp(r7, 1);
1869   __ Ldrb(ge, r5, &l4);
1870   __ Ldrb(lt, r5, &l4_not_taken);
1871   __ Ldrsb(eq, r6, &l5);
1872   __ Ldrsb(ne, r6, &l5_not_taken);
1873   __ Vldr(Condition(eq), s0, &l6);
1874   __ Vldr(Condition(ne), s0, &l6_not_taken);
1875   __ Vldr(Condition(eq), d1, &l7);
1876   __ Vldr(Condition(ne), d1, &l7_not_taken);
1877 
1878   END();
1879 
1880   RUN();
1881 
1882   ASSERT_EQUAL_32(0x90abcdef, r0);
1883   ASSERT_EQUAL_32(0x12345678, r1);
1884   ASSERT_EQUAL_32(0x12345678, r2);
1885   ASSERT_EQUAL_32(1234, r3);
1886   ASSERT_EQUAL_32(-678, r4);
1887   ASSERT_EQUAL_32(42, r5);
1888   ASSERT_EQUAL_32(-12, r6);
1889   ASSERT_EQUAL_FP32(1.2345f, s0);
1890   ASSERT_EQUAL_FP64(1.3333, d1);
1891 }
1892 
1893 
1894 struct LdrLiteralRangeTest {
1895   void (MacroAssembler::*instruction)(Register, RawLiteral*);
1896   Register result_reg;
1897   int a32_range;
1898   int t32_range;
1899   uint32_t literal_value;
1900   uint32_t test_value;
1901 };
1902 
1903 
1904 const LdrLiteralRangeTest kLdrLiteralRangeTestData[] =
1905     {{&MacroAssembler::Ldr, r1, 4095, 4095, 0x12345678, 0x12345678},
1906      {&MacroAssembler::Ldrh, r2, 255, 4095, 0xabcdefff, 0x0000efff},
1907      {&MacroAssembler::Ldrsh, r3, 255, 4095, 0x00008765, 0xffff8765},
1908      {&MacroAssembler::Ldrb, r4, 4095, 4095, 0x12345678, 0x00000078},
1909      {&MacroAssembler::Ldrsb, r5, 255, 4095, 0x00000087, 0xffffff87}};
1910 
1911 
GenerateLdrLiteralTriggerPoolEmission(InstructionSet isa,bool unaligned_ldr)1912 void GenerateLdrLiteralTriggerPoolEmission(InstructionSet isa,
1913                                            bool unaligned_ldr) {
1914   SETUP();
1915 
1916   for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
1917     const LdrLiteralRangeTest& test_case = kLdrLiteralRangeTestData[i];
1918 
1919     START();
1920 
1921     if (unaligned_ldr) {
1922       // Generate a nop to break the 4-byte alignment.
1923       __ Nop();
1924       VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
1925     }
1926 
1927     __ Ldr(r6, 0x12345678);
1928     CHECK_POOL_SIZE(4);
1929 
1930     // TODO: The MacroAssembler currently checks for more space than required
1931     // when emitting macro instructions, triggering emission of the pool before
1932     // absolutely required. For now we keep a buffer. Fix this test when the
1933     // MacroAssembler becomes precise again.
1934     int masm_check_margin = 10 * kMaxInstructionSizeInBytes;
1935     int expected_pool_size = 4;
1936     while ((test.GetPoolCheckpoint() - masm.GetCursorOffset() -
1937             masm_check_margin) >=
1938            static_cast<int32_t>(kMaxInstructionSizeInBytes)) {
1939       __ Ldr(r7, 0x90abcdef);
1940       // Each ldr instruction will force a new literal value to be added
1941       // to the pool. Check that the literal pool grows accordingly.
1942       expected_pool_size += 4;
1943       CHECK_POOL_SIZE(expected_pool_size);
1944     }
1945 
1946     int space = test.GetPoolCheckpoint() - masm.GetCursorOffset();
1947     int end = masm.GetCursorOffset() + space;
1948     {
1949       // Generate nops precisely to fill the buffer.
1950       ExactAssemblyScope accurate_scope(&masm, space);  // This should not
1951                                                         // trigger emission of
1952                                                         // the pool.
1953       VIXL_CHECK(!test.PoolIsEmpty());
1954       while (masm.GetCursorOffset() < end) {
1955         __ nop();
1956       }
1957     }
1958 
1959     // This ldr will force the literal pool to be emitted before emitting
1960     // the load and will create a new pool for the new literal used by this ldr.
1961     VIXL_CHECK(!test.PoolIsEmpty());
1962     Literal<uint32_t> literal(test_case.literal_value);
1963     (masm.*test_case.instruction)(test_case.result_reg, &literal);
1964     CHECK_POOL_SIZE(4);
1965 
1966     END();
1967 
1968     RUN();
1969 
1970     ASSERT_EQUAL_32(0x12345678, r6);
1971     ASSERT_EQUAL_32(0x90abcdef, r7);
1972     ASSERT_EQUAL_32(test_case.test_value, test_case.result_reg);
1973   }
1974 }
1975 
1976 
TEST(ldr_literal_trigger_pool_emission)1977 TEST(ldr_literal_trigger_pool_emission) {
1978   GenerateLdrLiteralTriggerPoolEmission(isa, false);
1979 }
1980 
1981 
TEST_T32(ldr_literal_trigger_pool_emission_unaligned)1982 TEST_T32(ldr_literal_trigger_pool_emission_unaligned) {
1983   GenerateLdrLiteralTriggerPoolEmission(isa, true);
1984 }
1985 
GenerateLdrLiteralRangeTest(InstructionSet isa,bool unaligned_ldr)1986 void GenerateLdrLiteralRangeTest(InstructionSet isa, bool unaligned_ldr) {
1987   SETUP();
1988 
1989   for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
1990     const LdrLiteralRangeTest& test_case = kLdrLiteralRangeTestData[i];
1991 
1992     START();
1993 
1994     // Make sure the pool is empty.
1995     masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
1996     VIXL_CHECK(test.PoolIsEmpty());
1997 
1998     if (unaligned_ldr) {
1999       // Generate a nop to break the 4-byte alignment.
2000       __ Nop();
2001       VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
2002     }
2003 
2004     Literal<uint32_t> literal(test_case.literal_value);
2005     (masm.*test_case.instruction)(test_case.result_reg, &literal);
2006     CHECK_POOL_SIZE(4);
2007 
2008     // Generate enough instruction so that we go out of range for the load
2009     // literal we just emitted.
2010     ptrdiff_t end =
2011         masm.GetBuffer()->GetCursorOffset() +
2012         ((masm.IsUsingA32()) ? test_case.a32_range : test_case.t32_range);
2013     while (masm.GetBuffer()->GetCursorOffset() < end) {
2014       __ Mov(r0, 0);
2015     }
2016 
2017     // The literal pool should have been emitted now.
2018     VIXL_CHECK(literal.IsBound());
2019     VIXL_CHECK(test.PoolIsEmpty());
2020 
2021     END();
2022 
2023     RUN();
2024 
2025     ASSERT_EQUAL_32(test_case.test_value, test_case.result_reg);
2026   }
2027 }
2028 
2029 
TEST(ldr_literal_range)2030 TEST(ldr_literal_range) { GenerateLdrLiteralRangeTest(isa, false); }
2031 
2032 
TEST_T32(ldr_literal_range_unaligned)2033 TEST_T32(ldr_literal_range_unaligned) {
2034   GenerateLdrLiteralRangeTest(isa, true);
2035 }
2036 
2037 
TEST(string_literal)2038 TEST(string_literal) {
2039   SETUP();
2040 
2041   START();
2042   // Make sure the pool is empty.
2043   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
2044   VIXL_CHECK(test.PoolIsEmpty());
2045 
2046   StringLiteral hello_string("hello");
2047 
2048   __ Ldrb(r1, &hello_string);
2049 
2050   __ Adr(r0, &hello_string);
2051   __ Ldrb(r2, MemOperand(r0));
2052   END();
2053 
2054   RUN();
2055 
2056   ASSERT_EQUAL_32('h', r1);
2057   ASSERT_EQUAL_32('h', r2);
2058 }
2059 
2060 
TEST(custom_literal_in_pool)2061 TEST(custom_literal_in_pool) {
2062   SETUP();
2063 
2064   START();
2065   // Make sure the pool is empty.
2066   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
2067   VIXL_CHECK(test.PoolIsEmpty());
2068 
2069   Literal<uint32_t> l0(static_cast<uint32_t>(0x12345678));
2070   __ Ldr(r0, &l0);
2071   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
2072   __ Ldr(r1, &l0);
2073   VIXL_CHECK(test.PoolIsEmpty());
2074 
2075   Literal<uint64_t> cafebeefdeadbaba(0xcafebeefdeadbaba);
2076   __ Ldrd(r8, r9, &cafebeefdeadbaba);
2077   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
2078   __ Ldrd(r2, r3, &cafebeefdeadbaba);
2079   VIXL_CHECK(test.PoolIsEmpty());
2080 
2081   Literal<uint32_t> l1(0x09abcdef);
2082   __ Adr(r4, &l1);
2083   __ Ldr(r4, MemOperand(r4));
2084   masm.EmitLiteralPool();
2085   __ Adr(r5, &l1);
2086   __ Ldr(r5, MemOperand(r5));
2087   VIXL_CHECK(test.PoolIsEmpty());
2088 
2089   END();
2090 
2091   RUN();
2092 
2093   // Check that the literals loaded correctly.
2094   ASSERT_EQUAL_32(0x12345678, r0);
2095   ASSERT_EQUAL_32(0x12345678, r1);
2096   ASSERT_EQUAL_32(0xdeadbaba, r2);
2097   ASSERT_EQUAL_32(0xcafebeef, r3);
2098   ASSERT_EQUAL_32(0xdeadbaba, r8);
2099   ASSERT_EQUAL_32(0xcafebeef, r9);
2100   ASSERT_EQUAL_32(0x09abcdef, r4);
2101   ASSERT_EQUAL_32(0x09abcdef, r5);
2102 }
2103 
2104 
TEST(custom_literal_place)2105 TEST(custom_literal_place) {
2106   SETUP();
2107 
2108   START();
2109   // Make sure the pool is empty.
2110   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
2111   VIXL_CHECK(test.PoolIsEmpty());
2112 
2113   Literal<uint64_t> l0(0xcafebeefdeadbaba, RawLiteral::kManuallyPlaced);
2114   Literal<int32_t> l1(0x12345678, RawLiteral::kManuallyPlaced);
2115   Literal<uint16_t> l2(4567, RawLiteral::kManuallyPlaced);
2116   Literal<int16_t> l3(-4567, RawLiteral::kManuallyPlaced);
2117   Literal<uint8_t> l4(123, RawLiteral::kManuallyPlaced);
2118   Literal<int8_t> l5(-123, RawLiteral::kManuallyPlaced);
2119 
2120   __ Ldrd(r0, r1, &l0);
2121   __ Ldr(r2, &l1);
2122   __ Ldrh(r3, &l2);
2123   __ Ldrsh(r4, &l3);
2124   __ Ldrb(r5, &l4);
2125   __ Ldrsb(r6, &l5);
2126 
2127   VIXL_CHECK(test.PoolIsEmpty());
2128 
2129   // Manually generate a literal pool.
2130   Label after_pool;
2131   __ B(&after_pool);
2132   __ Place(&l0);
2133   __ Place(&l1);
2134   __ Place(&l2);
2135   __ Place(&l3);
2136   __ Place(&l4);
2137   __ Place(&l5);
2138   __ Bind(&after_pool);
2139 
2140   {
2141     UseScratchRegisterScope temps(&masm);
2142     Register temp = temps.Acquire();
2143     VIXL_CHECK(temp.Is(r12));
2144 
2145     __ Ldrd(r8, r9, &l0);
2146     __ Ldr(r7, &l1);
2147     __ Ldrh(r10, &l2);
2148     __ Ldrsh(r11, &l3);
2149     __ Ldrb(temp, &l4);
2150     // We don't use any function call so we can use lr as an extra register.
2151     __ Ldrsb(lr, &l5);
2152   }
2153 
2154   VIXL_CHECK(test.PoolIsEmpty());
2155 
2156   END();
2157 
2158   RUN();
2159 
2160   // Check that the literals loaded correctly.
2161   ASSERT_EQUAL_32(0xdeadbaba, r0);
2162   ASSERT_EQUAL_32(0xcafebeef, r1);
2163   ASSERT_EQUAL_32(0x12345678, r2);
2164   ASSERT_EQUAL_32(4567, r3);
2165   ASSERT_EQUAL_32(-4567, r4);
2166   ASSERT_EQUAL_32(123, r5);
2167   ASSERT_EQUAL_32(-123, r6);
2168 
2169   ASSERT_EQUAL_32(0xdeadbaba, r8);
2170   ASSERT_EQUAL_32(0xcafebeef, r9);
2171   ASSERT_EQUAL_32(0x12345678, r7);
2172   ASSERT_EQUAL_32(4567, r10);
2173   ASSERT_EQUAL_32(-4567, r11);
2174   ASSERT_EQUAL_32(123, r12);
2175   ASSERT_EQUAL_32(-123, lr);
2176 }
2177 
2178 
TEST(custom_literal_place_shared)2179 TEST(custom_literal_place_shared) {
2180   SETUP();
2181 
2182   for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
2183     const LdrLiteralRangeTest& test_case = kLdrLiteralRangeTestData[i];
2184 
2185     START();
2186 
2187     // Make sure the pool is empty.
2188     masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
2189     VIXL_CHECK(test.PoolIsEmpty());
2190 
2191     Literal<uint32_t> before(test_case.literal_value,
2192                              RawLiteral::kManuallyPlaced);
2193     Literal<uint32_t> after(test_case.literal_value,
2194                             RawLiteral::kManuallyPlaced);
2195 
2196     VIXL_CHECK(!before.IsBound());
2197     VIXL_CHECK(!after.IsBound());
2198 
2199     // Manually generate a pool.
2200     Label end_of_pool_before;
2201     __ B(&end_of_pool_before);
2202     __ Place(&before);
2203     __ Bind(&end_of_pool_before);
2204 
2205     VIXL_CHECK(test.PoolIsEmpty());
2206     VIXL_CHECK(before.IsBound());
2207     VIXL_CHECK(!after.IsBound());
2208 
2209     // Load the entries several times to test that literals can be shared.
2210     for (int i = 0; i < 20; i++) {
2211       (masm.*test_case.instruction)(r0, &before);
2212       (masm.*test_case.instruction)(r1, &after);
2213     }
2214 
2215     VIXL_CHECK(test.PoolIsEmpty());
2216     VIXL_CHECK(before.IsBound());
2217     VIXL_CHECK(!after.IsBound());
2218 
2219     // Manually generate a pool.
2220     Label end_of_pool_after;
2221     __ B(&end_of_pool_after);
2222     __ Place(&after);
2223     __ Bind(&end_of_pool_after);
2224 
2225     VIXL_CHECK(test.PoolIsEmpty());
2226     VIXL_CHECK(before.IsBound());
2227     VIXL_CHECK(after.IsBound());
2228 
2229     END();
2230 
2231     RUN();
2232 
2233     ASSERT_EQUAL_32(test_case.test_value, r0);
2234     ASSERT_EQUAL_32(test_case.test_value, r1);
2235   }
2236 }
2237 
2238 
TEST(custom_literal_place_range)2239 TEST(custom_literal_place_range) {
2240   SETUP();
2241 
2242   for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
2243     const LdrLiteralRangeTest& test_case = kLdrLiteralRangeTestData[i];
2244     const int nop_size = masm.IsUsingA32() ? kA32InstructionSizeInBytes
2245                                            : k16BitT32InstructionSizeInBytes;
2246     const int range =
2247         masm.IsUsingA32() ? test_case.a32_range : test_case.t32_range;
2248     // On T32 the PC will be 4-byte aligned to compute the range. The
2249     // MacroAssembler might also need to align the code buffer before emitting
2250     // the literal when placing it. We keep a margin to account for this.
2251     const int margin = masm.IsUsingT32() ? 4 : 0;
2252 
2253     // Take PC offset into account and make sure the literal is in the range.
2254     const int padding_before =
2255         range - masm.GetArchitectureStatePCOffset() - sizeof(uint32_t) - margin;
2256 
2257     // The margin computation below is correct because the ranges are not
2258     // 4-byte aligned. Otherwise this test would insert the exact number of
2259     // instructions to cover the range and the literal would end up being
2260     // placed outside the range.
2261     VIXL_ASSERT((range % 4) != 0);
2262 
2263     // The range is extended by the PC offset but we need to consider the ldr
2264     // instruction itself and the branch over the pool.
2265     const int padding_after = range + masm.GetArchitectureStatePCOffset() -
2266                               (2 * kMaxInstructionSizeInBytes) - margin;
2267     START();
2268 
2269     Literal<uint32_t> before(test_case.literal_value,
2270                              RawLiteral::kManuallyPlaced);
2271     Literal<uint32_t> after(test_case.literal_value,
2272                             RawLiteral::kManuallyPlaced);
2273 
2274     Label test_start;
2275     __ B(&test_start);
2276     __ Place(&before);
2277 
2278     {
2279       int space = AlignDown(padding_before, nop_size);
2280       ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
2281       for (int32_t end = masm.GetCursorOffset() + space;
2282            masm.GetCursorOffset() < end;) {
2283         __ nop();
2284       }
2285     }
2286 
2287     __ Bind(&test_start);
2288     (masm.*test_case.instruction)(r0, &before);
2289     (masm.*test_case.instruction)(r1, &after);
2290 
2291     {
2292       int space = AlignDown(padding_after, nop_size);
2293       ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
2294       for (int32_t end = masm.GetCursorOffset() + space;
2295            masm.GetCursorOffset() < end;) {
2296         __ nop();
2297       }
2298     }
2299 
2300     Label after_pool;
2301     __ B(&after_pool);
2302     __ Place(&after);
2303     __ Bind(&after_pool);
2304 
2305     END();
2306 
2307     RUN();
2308 
2309     ASSERT_EQUAL_32(test_case.test_value, r0);
2310     ASSERT_EQUAL_32(test_case.test_value, r1);
2311   }
2312 }
2313 
2314 
TEST(emit_big_pool)2315 TEST(emit_big_pool) {
2316   SETUP();
2317 
2318   START();
2319   // Make sure the pool is empty.
2320   VIXL_CHECK(test.PoolIsEmpty());
2321 
2322   Label start;
2323   __ Bind(&start);
2324   for (int i = 1000; i > 0; --i) {
2325     __ Ldr(r0, i);
2326   }
2327 
2328   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&start) == 4000);
2329 
2330   CHECK_POOL_SIZE(4000);
2331   END();
2332 
2333   RUN();
2334 
2335   // Check that the literals loaded correctly.
2336   ASSERT_EQUAL_32(1, r0);
2337 }
2338 
2339 
TEST_T32(too_far_cbz)2340 TEST_T32(too_far_cbz) {
2341   SETUP();
2342 
2343   START();
2344   Label start;
2345   Label end;
2346   Label exit;
2347   __ Mov(r0, 0);
2348   __ B(&start);
2349   __ Bind(&end);
2350   __ Mov(r0, 1);
2351   __ B(&exit);
2352   __ Bind(&start);
2353   // Cbz is only defined for forward jump. Check that it will work (substituted
2354   // by Cbnz/B).
2355   __ Cbz(r0, &end);
2356   __ Bind(&exit);
2357   END();
2358 
2359   RUN();
2360 
2361   ASSERT_EQUAL_32(1, r0);
2362 }
2363 
2364 
TEST_T32(close_cbz)2365 TEST_T32(close_cbz) {
2366   SETUP();
2367 
2368   START();
2369   Label first;
2370   Label second;
2371   __ Mov(r0, 0);
2372   __ Mov(r1, 0);
2373   __ Mov(r2, 0);
2374   __ Cbz(r0, &first);
2375   __ Bind(&first);
2376   __ Mov(r1, 1);
2377   __ Cbnz(r0, &second);
2378   __ Bind(&second);
2379   __ Mov(r2, 2);
2380   END();
2381 
2382   RUN();
2383 
2384   ASSERT_EQUAL_32(0, r0);
2385   ASSERT_EQUAL_32(1, r1);
2386   ASSERT_EQUAL_32(2, r2);
2387 }
2388 
2389 
TEST_T32(close_cbz2)2390 TEST_T32(close_cbz2) {
2391   SETUP();
2392 
2393   START();
2394   Label first;
2395   Label second;
2396   __ Mov(r0, 0);
2397   __ Mov(r1, 0);
2398   __ Mov(r2, 0);
2399   __ Cmp(r0, 0);
2400   __ B(ne, &first);
2401   __ B(gt, &second);
2402   __ Cbz(r0, &first);
2403   __ Bind(&first);
2404   __ Mov(r1, 1);
2405   __ Cbnz(r0, &second);
2406   __ Bind(&second);
2407   __ Mov(r2, 2);
2408   END();
2409 
2410   RUN();
2411 
2412   ASSERT_EQUAL_32(0, r0);
2413   ASSERT_EQUAL_32(1, r1);
2414   ASSERT_EQUAL_32(2, r2);
2415 }
2416 
2417 
TEST_T32(not_close_cbz)2418 TEST_T32(not_close_cbz) {
2419   SETUP();
2420 
2421   START();
2422   Label first;
2423   Label second;
2424   __ Cbz(r0, &first);
2425   __ B(ne, &first);
2426   __ Bind(&first);
2427   __ Cbnz(r0, &second);
2428   __ B(gt, &second);
2429   __ Bind(&second);
2430   END();
2431 
2432   RUN();
2433 }
2434 
2435 
TEST_T32(veneers)2436 TEST_T32(veneers) {
2437   SETUP();
2438 
2439   START();
2440   Label zero;
2441   Label exit;
2442   __ Mov(r0, 0);
2443   // Create one literal pool entry.
2444   __ Ldr(r1, 0x12345678);
2445   CHECK_POOL_SIZE(4);
2446   __ Cbz(r0, &zero);
2447   __ Mov(r0, 1);
2448   __ B(&exit);
2449   for (int i = 32; i > 0; i--) {
2450     __ Mov(r1, 0);
2451   }
2452   // Assert that the pool contains only the two veneers.
2453   const int kVeneerSize = 4;
2454   CHECK_POOL_SIZE(2 * kVeneerSize);
2455   __ Bind(&zero);
2456   __ Mov(r0, 2);
2457   __ Bind(&exit);
2458   END();
2459 
2460   RUN();
2461 
2462   ASSERT_EQUAL_32(2, r0);
2463   ASSERT_EQUAL_32(0x12345678, r1);
2464 }
2465 
2466 
2467 // This test checks that veneers are sorted. If not, the test failed as the
2468 // veneer for "exit" is emitted before the veneer for "zero" and the "zero"
2469 // veneer is out of range for Cbz.
TEST_T32(veneers_labels_sort)2470 TEST_T32(veneers_labels_sort) {
2471   SETUP();
2472 
2473   START();
2474   Label start;
2475   Label zero;
2476   Label exit;
2477   __ Movs(r0, 0);
2478   __ B(ne, &exit);
2479   __ B(&start);
2480   for (int i = 1048400; i > 0; i -= 4) {
2481     __ Mov(r1, 0);
2482   }
2483   __ Bind(&start);
2484   __ Cbz(r0, &zero);
2485   __ Mov(r0, 1);
2486   __ B(&exit);
2487   for (int i = 32; i > 0; i--) {
2488     __ Mov(r1, 0);
2489   }
2490   __ Bind(&zero);
2491   __ Mov(r0, 2);
2492   __ Bind(&exit);
2493   END();
2494 
2495   RUN();
2496 
2497   ASSERT_EQUAL_32(2, r0);
2498 }
2499 
2500 // Check that a label bound within the assembler is effectively removed from
2501 // the veneer pool.
TEST_T32(veneer_bind)2502 TEST_T32(veneer_bind) {
2503   SETUP();
2504   START();
2505 
2506   Label target;
2507   __ Cbz(r0, &target);
2508   __ Nop();
2509 
2510   {
2511     // Bind the target label using the `Assembler`.
2512     ExactAssemblyScope scope(&masm,
2513                              kMaxInstructionSizeInBytes,
2514                              ExactAssemblyScope::kMaximumSize);
2515     __ bind(&target);
2516     __ nop();
2517   }
2518 
2519   VIXL_CHECK(target.IsBound());
2520   VIXL_CHECK(test.PoolIsEmpty());
2521 
2522   END();
2523 }
2524 
2525 
2526 // Check that the veneer pool is correctly emitted even if we do enough narrow
2527 // branches before a cbz so that the cbz needs its veneer emitted first in the
2528 // pool in order to work.
TEST_T32(b_narrow_and_cbz_sort)2529 TEST_T32(b_narrow_and_cbz_sort) {
2530   SETUP();
2531   START();
2532 
2533   const int kLabelsCount = 40;
2534   const int kNops = 30;
2535   Label b_labels[kLabelsCount];
2536   Label cbz_label;
2537 
2538   __ Nop();
2539 
2540   __ Mov(r0, 0);
2541   __ Cmp(r0, 0);
2542 
2543   for (int i = 0; i < kLabelsCount; ++i) {
2544     __ B(ne, &b_labels[i], kNear);
2545   }
2546 
2547   {
2548     ExactAssemblyScope scope(&masm,
2549                              k16BitT32InstructionSizeInBytes * kNops,
2550                              ExactAssemblyScope::kExactSize);
2551     for (int i = 0; i < kNops; i++) {
2552       __ nop();
2553     }
2554   }
2555 
2556   // The pool should not be emitted here.
2557   __ Cbz(r0, &cbz_label);
2558 
2559   // Force pool emission. If the labels are not sorted, the cbz will be out
2560   // of range.
2561   int32_t end = test.GetPoolCheckpoint();
2562   int32_t margin = end - masm.GetCursorOffset();
2563 
2564   {
2565     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
2566     while (masm.GetCursorOffset() < end) {
2567       __ nop();
2568     }
2569   }
2570 
2571   __ Mov(r0, 1);
2572 
2573   for (int i = 0; i < kLabelsCount; ++i) {
2574     __ Bind(&b_labels[i]);
2575   }
2576 
2577   __ Bind(&cbz_label);
2578 
2579   END();
2580 
2581   RUN();
2582 
2583   ASSERT_EQUAL_32(0, r0);
2584 }
2585 
2586 
TEST_T32(b_narrow_and_cbz_sort_2)2587 TEST_T32(b_narrow_and_cbz_sort_2) {
2588   SETUP();
2589   START();
2590 
2591   const int kLabelsCount = 40;
2592   const int kNops = 30;
2593   Label b_labels[kLabelsCount];
2594   Label cbz_label;
2595 
2596   __ Mov(r0, 0);
2597   __ Cmp(r0, 0);
2598 
2599   for (int i = 0; i < kLabelsCount; ++i) {
2600     __ B(ne, &b_labels[i], kNear);
2601   }
2602 
2603   {
2604     ExactAssemblyScope scope(&masm,
2605                              k16BitT32InstructionSizeInBytes * kNops,
2606                              ExactAssemblyScope::kExactSize);
2607     for (int i = 0; i < kNops; i++) {
2608       __ nop();
2609     }
2610   }
2611 
2612   // The pool should not be emitted here.
2613   __ Cbz(r0, &cbz_label);
2614 
2615   // Force pool emission. If the labels are not sorted, the cbz will be out
2616   // of range.
2617   int32_t end = test.GetPoolCheckpoint();
2618 
2619   while (masm.GetCursorOffset() < end) __ Nop();
2620 
2621   __ Mov(r0, 1);
2622 
2623   for (int i = 0; i < kLabelsCount; ++i) {
2624     __ Bind(&b_labels[i]);
2625   }
2626 
2627   __ Bind(&cbz_label);
2628 
2629   END();
2630 
2631   RUN();
2632 
2633   ASSERT_EQUAL_32(0, r0);
2634 }
2635 
2636 
TEST_T32(long_branch)2637 TEST_T32(long_branch) {
2638   SETUP();
2639   START();
2640 
2641   for (int label_count = 128; label_count < 2048; label_count *= 2) {
2642     Label* l = new Label[label_count];
2643 
2644     for (int i = 0; i < label_count; i++) {
2645       __ B(&l[i]);
2646     }
2647 
2648     for (int i = 0; i < label_count; i++) {
2649       __ B(ne, &l[i]);
2650     }
2651 
2652     for (int i = 0; i < 261625; i++) {
2653       __ Clz(r0, r0);
2654     }
2655 
2656     for (int i = label_count - 1; i >= 0; i--) {
2657       __ Bind(&l[i]);
2658       __ Nop();
2659     }
2660 
2661     delete[] l;
2662   }
2663 
2664   masm.FinalizeCode();
2665 
2666   END();
2667   RUN();
2668 }
2669 
2670 
TEST_T32(unaligned_branch_after_literal)2671 TEST_T32(unaligned_branch_after_literal) {
2672   SETUP();
2673 
2674   START();
2675 
2676   // This test manually places a 32-bit literal after a 16-bit branch
2677   // which branches over the literal to an unaligned PC.
2678   Literal<int32_t> l0(0x01234567, RawLiteral::kManuallyPlaced);
2679 
2680   __ Ldr(r0, &l0);
2681   VIXL_CHECK(test.PoolIsEmpty());
2682 
2683   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
2684   VIXL_CHECK(test.PoolIsEmpty());
2685 
2686   // Manually generate a literal pool.
2687   {
2688     Label after_pool;
2689     ExactAssemblyScope scope(&masm,
2690                              k16BitT32InstructionSizeInBytes + sizeof(int32_t),
2691                              CodeBufferCheckScope::kMaximumSize);
2692     __ b(Narrow, &after_pool);
2693     __ place(&l0);
2694     VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
2695     __ bind(&after_pool);
2696   }
2697 
2698   VIXL_CHECK(test.PoolIsEmpty());
2699 
2700   END();
2701 
2702   RUN();
2703 
2704   // Check that the literal was loaded correctly.
2705   ASSERT_EQUAL_32(0x01234567, r0);
2706 }
2707 
2708 
2709 // This test check that we can update a Literal after usage.
TEST(literal_update)2710 TEST(literal_update) {
2711   SETUP();
2712 
2713   START();
2714   Label exit;
2715   Literal<uint32_t>* a32 =
2716       new Literal<uint32_t>(0xabcdef01, RawLiteral::kDeletedOnPoolDestruction);
2717   Literal<uint64_t>* a64 =
2718       new Literal<uint64_t>(UINT64_C(0xabcdef01abcdef01),
2719                             RawLiteral::kDeletedOnPoolDestruction);
2720   __ Ldr(r0, a32);
2721   __ Ldrd(r2, r3, a64);
2722   __ EmitLiteralPool();
2723   Literal<uint32_t>* b32 =
2724       new Literal<uint32_t>(0x10fedcba, RawLiteral::kDeletedOnPoolDestruction);
2725   Literal<uint64_t>* b64 =
2726       new Literal<uint64_t>(UINT64_C(0x10fedcba10fedcba),
2727                             RawLiteral::kDeletedOnPoolDestruction);
2728   __ Ldr(r1, b32);
2729   __ Ldrd(r4, r5, b64);
2730   // Update literals' values. "a32" and "a64" are already emitted. "b32" and
2731   // "b64" will only be emitted when "END()" will be called.
2732   a32->UpdateValue(0x12345678, masm.GetBuffer());
2733   a64->UpdateValue(UINT64_C(0x13579bdf02468ace), masm.GetBuffer());
2734   b32->UpdateValue(0x87654321, masm.GetBuffer());
2735   b64->UpdateValue(UINT64_C(0x1032547698badcfe), masm.GetBuffer());
2736   END();
2737 
2738   RUN();
2739 
2740   ASSERT_EQUAL_32(0x12345678, r0);
2741   ASSERT_EQUAL_32(0x87654321, r1);
2742   ASSERT_EQUAL_32(0x02468ace, r2);
2743   ASSERT_EQUAL_32(0x13579bdf, r3);
2744   ASSERT_EQUAL_32(0x98badcfe, r4);
2745   ASSERT_EQUAL_32(0x10325476, r5);
2746 }
2747 
2748 
TEST(claim_peek_poke)2749 TEST(claim_peek_poke) {
2750   SETUP();
2751 
2752   START();
2753 
2754   Label start;
2755   __ Bind(&start);
2756   __ Claim(0);
2757   __ Drop(0);
2758   VIXL_CHECK((masm.GetCursorOffset() - start.GetLocation()) == 0);
2759 
2760   __ Claim(32);
2761   __ Ldr(r0, 0xcafe0000);
2762   __ Ldr(r1, 0xcafe0001);
2763   __ Ldr(r2, 0xcafe0002);
2764   __ Poke(r0, 0);
2765   __ Poke(r1, 4);
2766   __ Poke(r2, 8);
2767   __ Peek(r2, 0);
2768   __ Peek(r0, 4);
2769   __ Peek(r1, 8);
2770   __ Drop(32);
2771 
2772   END();
2773 
2774   RUN();
2775 
2776   ASSERT_EQUAL_32(0xcafe0001, r0);
2777   ASSERT_EQUAL_32(0xcafe0002, r1);
2778   ASSERT_EQUAL_32(0xcafe0000, r2);
2779 }
2780 
2781 
TEST(msr_i)2782 TEST(msr_i) {
2783   SETUP();
2784 
2785   START();
2786   __ Mov(r0, 0xdead);
2787   __ Mov(r1, 0xdead);
2788   __ Mov(r2, 0xdead);
2789   __ Mov(r3, 0xb);
2790   __ Msr(APSR_nzcvqg, 0);
2791   __ Mrs(r0, APSR);
2792   __ Msr(APSR_nzcvqg, 0xffffffff);
2793   __ Mrs(r1, APSR);
2794   // Only modify nzcvq => keep previous g.
2795   __ Lsl(r4, r3, 28);
2796   __ Msr(APSR_nzcvq, r4);
2797   __ Mrs(r2, APSR);
2798   END();
2799 
2800   RUN();
2801 
2802   ASSERT_EQUAL_32(0x10, r0);
2803   ASSERT_EQUAL_32(0xf80f0010, r1);
2804   ASSERT_EQUAL_32(0xb00f0010, r2);
2805 }
2806 
2807 
TEST(vcmp_s)2808 TEST(vcmp_s) {
2809   SETUP();
2810 
2811   START();
2812 
2813   __ Vmov(s0, 1.0);
2814   __ Vmov(s1, 2.0);
2815   __ Vmov(s2, 0.0);
2816 
2817   __ Vcmp(F32, s0, s1);
2818   __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR);
2819 
2820   __ Vcmp(F32, s0, 0.0f);
2821   __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
2822 
2823   __ Vcmp(F32, s2, 0.0f);
2824   __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
2825 
2826   END();
2827 
2828   RUN();
2829 
2830   // N is for less than.
2831   ASSERT_EQUAL_32(NFlag, r0);
2832   // C is for greater than.
2833   ASSERT_EQUAL_32(CFlag, r1);
2834   // ZC is for equal.
2835   ASSERT_EQUAL_32(ZCFlag, r2);
2836 }
2837 
2838 
TEST(vcmp_d)2839 TEST(vcmp_d) {
2840   SETUP();
2841 
2842   START();
2843 
2844   __ Vmov(d0, 1.0);
2845   __ Vmov(d1, 2.0);
2846   __ Vmov(d2, 0.0);
2847 
2848   __ Vcmp(F64, d0, d1);
2849   __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR);
2850 
2851   __ Vcmp(F64, d0, 0.0);
2852   __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
2853 
2854   __ Vcmp(F64, d2, 0.0);
2855   __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
2856 
2857   END();
2858 
2859   RUN();
2860 
2861   // N is for less than.
2862   ASSERT_EQUAL_32(NFlag, r0);
2863   // C is for greater than.
2864   ASSERT_EQUAL_32(CFlag, r1);
2865   // ZC is for equal.
2866   ASSERT_EQUAL_32(ZCFlag, r2);
2867 }
2868 
2869 
TEST(vcmpe_s)2870 TEST(vcmpe_s) {
2871   SETUP();
2872 
2873   START();
2874 
2875   __ Vmov(s0, 1.0);
2876   __ Vmov(s1, 2.0);
2877   __ Vmov(s2, 0.0);
2878 
2879   __ Vcmpe(F32, s0, s1);
2880   __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR);
2881 
2882   __ Vcmpe(F32, s0, 0.0f);
2883   __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
2884 
2885   __ Vcmpe(F32, s2, 0.0f);
2886   __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
2887 
2888   END();
2889 
2890   RUN();
2891 
2892   // N is for less than.
2893   ASSERT_EQUAL_32(NFlag, r0);
2894   // C is for greater than.
2895   ASSERT_EQUAL_32(CFlag, r1);
2896   // ZC is for equal.
2897   ASSERT_EQUAL_32(ZCFlag, r2);
2898 }
2899 
2900 
TEST(vcmpe_d)2901 TEST(vcmpe_d) {
2902   SETUP();
2903 
2904   START();
2905 
2906   __ Vmov(d0, 1.0);
2907   __ Vmov(d1, 2.0);
2908   __ Vmov(d2, 0.0);
2909 
2910   __ Vcmpe(F64, d0, d1);
2911   __ Vmrs(RegisterOrAPSR_nzcv(r0.GetCode()), FPSCR);
2912 
2913   __ Vcmpe(F64, d0, 0.0);
2914   __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
2915 
2916   __ Vcmpe(F64, d2, 0.0);
2917   __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
2918 
2919   END();
2920 
2921   RUN();
2922 
2923   // N is for less than.
2924   ASSERT_EQUAL_32(NFlag, r0);
2925   // C is for greater than.
2926   ASSERT_EQUAL_32(CFlag, r1);
2927   // ZC is for equal.
2928   ASSERT_EQUAL_32(ZCFlag, r2);
2929 }
2930 
2931 
TEST(vmrs_vmsr)2932 TEST(vmrs_vmsr) {
2933   SETUP();
2934 
2935   START();
2936   // Move some value to FPSCR and get them back to test vmsr/vmrs instructions.
2937   __ Mov(r0, 0x2a000000);
2938   __ Vmsr(FPSCR, r0);
2939   __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
2940 
2941   __ Mov(r0, 0x5a000000);
2942   __ Vmsr(FPSCR, r0);
2943   __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
2944 
2945   // Move to APSR_nzcv.
2946   __ Vmrs(RegisterOrAPSR_nzcv(pc.GetCode()), FPSCR);
2947   __ Mrs(r3, APSR);
2948   __ And(r3, r3, 0xf0000000);
2949 
2950   END();
2951 
2952   RUN();
2953 
2954   ASSERT_EQUAL_32(0x2a000000, r1);
2955   ASSERT_EQUAL_32(0x5a000000, r2);
2956   ASSERT_EQUAL_32(0x50000000, r3);
2957 }
2958 
2959 
TEST(printf)2960 TEST(printf) {
2961   SETUP();
2962 
2963   START();
2964   __ Mov(r0, 0xb00e0000);
2965   __ Msr(APSR_nzcvqg, r0);
2966   __ Mov(r0, sp);
2967   __ Printf("sp=%x\n", r0);
2968   //  __ Printf("Hello world!\n");
2969   __ Mov(r0, 0x1234);
2970   __ Mov(r1, 0x5678);
2971   StringLiteral literal("extra string");
2972   __ Adr(r2, &literal);
2973   __ Mov(r3, 5);
2974   __ Mov(r4, 0xdead4444);
2975   __ Mov(r5, 0xdead5555);
2976   __ Mov(r6, 0xdead6666);
2977   __ Mov(r7, 0xdead7777);
2978   __ Mov(r8, 0xdead8888);
2979   __ Mov(r9, 0xdead9999);
2980   __ Mov(r10, 0xdeadaaaa);
2981   __ Mov(r11, 0xdeadbbbb);
2982   __ Vldr(d0, 1.2345);
2983   __ Vldr(d1, 2.9876);
2984   __ Vldr(s4, 1.3333);
2985   __ Vldr(s5, 3.21);
2986   __ Vldr(d3, 3.333);
2987   __ Vldr(d4, 4.444);
2988   __ Vldr(d5, 5.555);
2989   __ Vldr(d6, 6.666);
2990   __ Vldr(d7, 7.777);
2991   __ Vldr(d8, 8.888);
2992   __ Vldr(d9, 9.999);
2993   __ Vldr(d10, 10.000);
2994   __ Vldr(d11, 11.111);
2995   __ Vldr(d12, 12.222);
2996   __ Vldr(d13, 13.333);
2997   __ Vldr(d14, 14.444);
2998   __ Vldr(d15, 15.555);
2999   __ Vldr(d16, 16.666);
3000   __ Vldr(d17, 17.777);
3001   __ Vldr(d18, 18.888);
3002   __ Vldr(d19, 19.999);
3003   __ Vldr(d20, 20.000);
3004   __ Vldr(d21, 21.111);
3005   __ Vldr(d22, 22.222);
3006   __ Vldr(d23, 23.333);
3007   __ Vldr(d24, 24.444);
3008   __ Vldr(d25, 25.555);
3009   __ Vldr(d26, 26.666);
3010   __ Vldr(d27, 27.777);
3011   __ Vldr(d28, 28.888);
3012   __ Vldr(d29, 29.999);
3013   __ Vldr(d30, 30.000);
3014   __ Vldr(d31, 31.111);
3015   {
3016     UseScratchRegisterScope temps(&masm);
3017     // For effective use as an inspection tool, Printf must work without any
3018     // scratch registers.
3019     VIXL_CHECK(r12.Is(temps.Acquire()));
3020     __ Mov(r12, 0xdeadcccc);
3021     VIXL_CHECK(masm.GetScratchRegisterList()->IsEmpty());
3022 
3023     __ Printf("%% r0=%x r1=%x str=<%.*s>\n", r0, r1, r3, r2);
3024     __ Printf("r0=%d r1=%d str=<%s>\n", r0, r1, r2);
3025     __ Printf("d0=%g\n", d0);
3026     __ Printf("s4=%g\n", s4);
3027     __ Printf("d0=%g d1=%g s4=%g s5=%g\n", d0, d1, s4, s5);
3028     __ Printf("d0=%g r0=%x s4=%g r1=%x\n", d0, r0, s4, r1);
3029     __ Printf("r0=%x d0=%g r1=%x s4=%g\n", r0, d0, r1, s4);
3030     __ Mov(r0, sp);
3031     __ Printf("sp=%x\n", r0);
3032     __ Mrs(r0, APSR);
3033     // Only keep R/W fields.
3034     __ Mov(r2, 0xf80f0200);
3035     __ And(r0, r0, r2);
3036   }
3037   END();
3038 
3039   RUN();
3040 
3041   ASSERT_EQUAL_32(0xb00e0000, r0);
3042   ASSERT_EQUAL_32(0x5678, r1);
3043   ASSERT_EQUAL_32(5, r3);
3044   ASSERT_EQUAL_32(0xdead4444, r4);
3045   ASSERT_EQUAL_32(0xdead5555, r5);
3046   ASSERT_EQUAL_32(0xdead6666, r6);
3047   ASSERT_EQUAL_32(0xdead7777, r7);
3048   ASSERT_EQUAL_32(0xdead8888, r8);
3049   ASSERT_EQUAL_32(0xdead9999, r9);
3050   ASSERT_EQUAL_32(0xdeadaaaa, r10);
3051   ASSERT_EQUAL_32(0xdeadbbbb, r11);
3052   ASSERT_EQUAL_32(0xdeadcccc, r12);
3053   ASSERT_EQUAL_FP64(1.2345, d0);
3054   ASSERT_EQUAL_FP64(2.9876, d1);
3055   ASSERT_EQUAL_FP32(1.3333, s4);
3056   ASSERT_EQUAL_FP32(3.21, s5);
3057   ASSERT_EQUAL_FP64(4.444, d4);
3058   ASSERT_EQUAL_FP64(5.555, d5);
3059   ASSERT_EQUAL_FP64(6.666, d6);
3060   ASSERT_EQUAL_FP64(7.777, d7);
3061   ASSERT_EQUAL_FP64(8.888, d8);
3062   ASSERT_EQUAL_FP64(9.999, d9);
3063   ASSERT_EQUAL_FP64(10.000, d10);
3064   ASSERT_EQUAL_FP64(11.111, d11);
3065   ASSERT_EQUAL_FP64(12.222, d12);
3066   ASSERT_EQUAL_FP64(13.333, d13);
3067   ASSERT_EQUAL_FP64(14.444, d14);
3068   ASSERT_EQUAL_FP64(15.555, d15);
3069   ASSERT_EQUAL_FP64(16.666, d16);
3070   ASSERT_EQUAL_FP64(17.777, d17);
3071   ASSERT_EQUAL_FP64(18.888, d18);
3072   ASSERT_EQUAL_FP64(19.999, d19);
3073   ASSERT_EQUAL_FP64(20.000, d20);
3074   ASSERT_EQUAL_FP64(21.111, d21);
3075   ASSERT_EQUAL_FP64(22.222, d22);
3076   ASSERT_EQUAL_FP64(23.333, d23);
3077   ASSERT_EQUAL_FP64(24.444, d24);
3078   ASSERT_EQUAL_FP64(25.555, d25);
3079   ASSERT_EQUAL_FP64(26.666, d26);
3080   ASSERT_EQUAL_FP64(27.777, d27);
3081   ASSERT_EQUAL_FP64(28.888, d28);
3082   ASSERT_EQUAL_FP64(29.999, d29);
3083   ASSERT_EQUAL_FP64(30.000, d30);
3084   ASSERT_EQUAL_FP64(31.111, d31);
3085 }
3086 
TEST(printf2)3087 TEST(printf2) {
3088   SETUP();
3089 
3090   START();
3091   __ Mov(r0, 0x1234);
3092   __ Mov(r1, 0x5678);
3093   __ Vldr(d0, 1.2345);
3094   __ Vldr(s2, 2.9876);
3095   __ Printf("d0=%g d1=%g r0=%x r1=%x\n", d0, s2, r0, r1);
3096   END();
3097 
3098   RUN();
3099 }
3100 
3101 
3102 template <typename T>
CheckInstructionSetA32(const T & assm)3103 void CheckInstructionSetA32(const T& assm) {
3104   VIXL_CHECK(assm.IsUsingA32());
3105   VIXL_CHECK(!assm.IsUsingT32());
3106   VIXL_CHECK(assm.GetInstructionSetInUse() == A32);
3107 }
3108 
3109 
3110 template <typename T>
CheckInstructionSetT32(const T & assm)3111 void CheckInstructionSetT32(const T& assm) {
3112   VIXL_CHECK(assm.IsUsingT32());
3113   VIXL_CHECK(!assm.IsUsingA32());
3114   VIXL_CHECK(assm.GetInstructionSetInUse() == T32);
3115 }
3116 
3117 
TEST_NOASM(set_isa_constructors)3118 TEST_NOASM(set_isa_constructors) {
3119   byte buffer[1024];
3120 
3121 #ifndef VIXL_INCLUDE_TARGET_T32_ONLY
3122   // A32 by default.
3123   CheckInstructionSetA32(Assembler());
3124   CheckInstructionSetA32(Assembler(1024));
3125   CheckInstructionSetA32(Assembler(buffer, sizeof(buffer)));
3126 
3127   CheckInstructionSetA32(MacroAssembler());
3128   CheckInstructionSetA32(MacroAssembler(1024));
3129   CheckInstructionSetA32(MacroAssembler(buffer, sizeof(buffer)));
3130 #else
3131   // T32 by default.
3132   CheckInstructionSetT32(Assembler());
3133   CheckInstructionSetT32(Assembler(1024));
3134   CheckInstructionSetT32(Assembler(buffer, sizeof(buffer)));
3135 
3136   CheckInstructionSetT32(MacroAssembler());
3137   CheckInstructionSetT32(MacroAssembler(1024));
3138   CheckInstructionSetT32(MacroAssembler(buffer, sizeof(buffer)));
3139 #endif
3140 
3141 #ifdef VIXL_INCLUDE_TARGET_A32
3142   // Explicit A32.
3143   CheckInstructionSetA32(Assembler(A32));
3144   CheckInstructionSetA32(Assembler(1024, A32));
3145   CheckInstructionSetA32(Assembler(buffer, sizeof(buffer), A32));
3146 
3147   CheckInstructionSetA32(MacroAssembler(A32));
3148   CheckInstructionSetA32(MacroAssembler(1024, A32));
3149   CheckInstructionSetA32(MacroAssembler(buffer, sizeof(buffer), A32));
3150 #endif
3151 
3152 #ifdef VIXL_INCLUDE_TARGET_T32
3153   // Explicit T32.
3154   CheckInstructionSetT32(Assembler(T32));
3155   CheckInstructionSetT32(Assembler(1024, T32));
3156   CheckInstructionSetT32(Assembler(buffer, sizeof(buffer), T32));
3157 
3158   CheckInstructionSetT32(MacroAssembler(T32));
3159   CheckInstructionSetT32(MacroAssembler(1024, T32));
3160   CheckInstructionSetT32(MacroAssembler(buffer, sizeof(buffer), T32));
3161 #endif
3162 }
3163 
3164 
TEST_NOASM(set_isa_empty)3165 TEST_NOASM(set_isa_empty) {
3166 // It is possible to change the instruction set if no instructions have yet
3167 // been generated. This test only makes sense when both A32 and T32 are
3168 // supported.
3169 #ifdef VIXL_INCLUDE_TARGET_AARCH32
3170   Assembler assm;
3171   CheckInstructionSetA32(assm);
3172   assm.UseT32();
3173   CheckInstructionSetT32(assm);
3174   assm.UseA32();
3175   CheckInstructionSetA32(assm);
3176   assm.UseInstructionSet(T32);
3177   CheckInstructionSetT32(assm);
3178   assm.UseInstructionSet(A32);
3179   CheckInstructionSetA32(assm);
3180 
3181   MacroAssembler masm;
3182   CheckInstructionSetA32(masm);
3183   masm.UseT32();
3184   CheckInstructionSetT32(masm);
3185   masm.UseA32();
3186   CheckInstructionSetA32(masm);
3187   masm.UseInstructionSet(T32);
3188   CheckInstructionSetT32(masm);
3189   masm.UseInstructionSet(A32);
3190   CheckInstructionSetA32(masm);
3191 #endif
3192 }
3193 
3194 
TEST_NOASM(set_isa_noop)3195 TEST_NOASM(set_isa_noop) {
3196 // It is possible to call a no-op UseA32/T32 or UseInstructionSet even if
3197 // one or more instructions have been generated.
3198 #ifdef VIXL_INCLUDE_TARGET_A32
3199   {
3200     Assembler assm(A32);
3201     CheckInstructionSetA32(assm);
3202     CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
3203     assm.bx(lr);
3204     VIXL_ASSERT(assm.GetCursorOffset() > 0);
3205     CheckInstructionSetA32(assm);
3206     assm.UseA32();
3207     CheckInstructionSetA32(assm);
3208     assm.UseInstructionSet(A32);
3209     CheckInstructionSetA32(assm);
3210     assm.FinalizeCode();
3211   }
3212   {
3213     MacroAssembler masm(A32);
3214     CheckInstructionSetA32(masm);
3215     masm.Bx(lr);
3216     VIXL_ASSERT(masm.GetCursorOffset() > 0);
3217     CheckInstructionSetA32(masm);
3218     masm.UseA32();
3219     CheckInstructionSetA32(masm);
3220     masm.UseInstructionSet(A32);
3221     CheckInstructionSetA32(masm);
3222     masm.FinalizeCode();
3223   }
3224 #endif
3225 
3226 #ifdef VIXL_INCLUDE_TARGET_T32
3227   {
3228     Assembler assm(T32);
3229     CheckInstructionSetT32(assm);
3230     CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
3231     assm.bx(lr);
3232     VIXL_ASSERT(assm.GetCursorOffset() > 0);
3233     CheckInstructionSetT32(assm);
3234     assm.UseT32();
3235     CheckInstructionSetT32(assm);
3236     assm.UseInstructionSet(T32);
3237     CheckInstructionSetT32(assm);
3238     assm.FinalizeCode();
3239   }
3240   {
3241     MacroAssembler masm(T32);
3242     CheckInstructionSetT32(masm);
3243     masm.Bx(lr);
3244     VIXL_ASSERT(masm.GetCursorOffset() > 0);
3245     CheckInstructionSetT32(masm);
3246     masm.UseT32();
3247     CheckInstructionSetT32(masm);
3248     masm.UseInstructionSet(T32);
3249     CheckInstructionSetT32(masm);
3250     masm.FinalizeCode();
3251   }
3252 #endif
3253 }
3254 
3255 
TEST(logical_arithmetic_identities)3256 TEST(logical_arithmetic_identities) {
3257   SETUP();
3258 
3259   START();
3260 
3261   Label blob_1;
3262   __ Bind(&blob_1);
3263   __ Add(r0, r0, 0);
3264   __ And(r0, r0, 0xffffffff);
3265   __ Bic(r0, r0, 0);
3266   __ Eor(r0, r0, 0);
3267   __ Orn(r0, r0, 0xffffffff);
3268   __ Orr(r0, r0, 0);
3269   __ Sub(r0, r0, 0);
3270   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_1) == 0);
3271 
3272   Label blob_2;
3273   __ Bind(&blob_2);
3274   __ Adds(r0, r0, 0);
3275   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_2) != 0);
3276 
3277   Label blob_3;
3278   __ Bind(&blob_3);
3279   __ Ands(r0, r0, 0);
3280   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_3) != 0);
3281 
3282   Label blob_4;
3283   __ Bind(&blob_4);
3284   __ Bics(r0, r0, 0);
3285   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_4) != 0);
3286 
3287   Label blob_5;
3288   __ Bind(&blob_5);
3289   __ Eors(r0, r0, 0);
3290   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_5) != 0);
3291 
3292   Label blob_6;
3293   __ Bind(&blob_6);
3294   __ Orns(r0, r0, 0);
3295   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_6) != 0);
3296 
3297   Label blob_7;
3298   __ Bind(&blob_7);
3299   __ Orrs(r0, r0, 0);
3300   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_7) != 0);
3301 
3302   Label blob_8;
3303   __ Bind(&blob_8);
3304   __ Subs(r0, r0, 0);
3305   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_8) != 0);
3306 
3307   __ Mov(r0, 0xbad);
3308   __ And(r1, r0, 0);
3309   __ Bic(r2, r0, 0xffffffff);
3310   __ Eor(r3, r0, 0xffffffff);
3311   __ Orn(r4, r0, 0);
3312   __ Orr(r5, r0, 0xffffffff);
3313 
3314   END();
3315 
3316   RUN();
3317 
3318   ASSERT_EQUAL_32(0xbad, r0);
3319   ASSERT_EQUAL_32(0, r1);
3320   ASSERT_EQUAL_32(0, r2);
3321   ASSERT_EQUAL_32(~0xbad, r3);
3322   ASSERT_EQUAL_32(0xffffffff, r4);
3323   ASSERT_EQUAL_32(0xffffffff, r5);
3324 }
3325 
3326 
TEST(scratch_register_checks)3327 TEST(scratch_register_checks) {
3328   // It is unsafe for users to use registers that the MacroAssembler is also
3329   // using as scratch registers. This test checks the MacroAssembler's checking
3330   // mechanism itself.
3331   SETUP();
3332   START();
3333   {
3334     UseScratchRegisterScope temps(&masm);
3335     // 'ip' is a scratch register by default.
3336     VIXL_CHECK(masm.GetScratchRegisterList()->GetList() ==
3337                (1u << ip.GetCode()));
3338     VIXL_CHECK(temps.IsAvailable(ip));
3339 
3340     // Integer registers have no complicated aliasing so
3341     // masm.AliasesAvailableScratchRegister(reg) == temps.IsAvailable(reg).
3342     for (unsigned i = 0; i < kNumberOfRegisters; i++) {
3343       Register reg(i);
3344       VIXL_CHECK(masm.AliasesAvailableScratchRegister(reg) ==
3345                  temps.IsAvailable(reg));
3346     }
3347   }
3348   END();
3349 }
3350 
3351 
TEST(scratch_register_checks_v)3352 TEST(scratch_register_checks_v) {
3353   // It is unsafe for users to use registers that the MacroAssembler is also
3354   // using as scratch registers. This test checks the MacroAssembler's checking
3355   // mechanism itself.
3356   SETUP();
3357   {
3358     UseScratchRegisterScope temps(&masm);
3359     // There is no default floating-point scratch register. Add temps of various
3360     // sizes to check handling of aliased registers.
3361     VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() == 0);
3362     temps.Include(q15);
3363     temps.Include(d15);
3364     temps.Include(s15);
3365     temps.Include(d4);
3366     temps.Include(d5);
3367     temps.Include(s24);
3368     temps.Include(s25);
3369     temps.Include(s26);
3370     temps.Include(s27);
3371     temps.Include(q0);
3372     // See VRegisterList for details of the list encoding.
3373     VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() ==
3374                UINT64_C(0xf0000000cf008f0f));
3375     //                    |       ||  || |
3376     //                   q15    d15|  || q0
3377     //                        s24-s27 |d4-d5
3378     //                               s15
3379 
3380     // Simple checks: Included registers are available.
3381     VIXL_CHECK(temps.IsAvailable(q15));
3382     VIXL_CHECK(temps.IsAvailable(d15));
3383     VIXL_CHECK(temps.IsAvailable(s15));
3384     VIXL_CHECK(temps.IsAvailable(d4));
3385     VIXL_CHECK(temps.IsAvailable(d5));
3386     VIXL_CHECK(temps.IsAvailable(s24));
3387     VIXL_CHECK(temps.IsAvailable(s25));
3388     VIXL_CHECK(temps.IsAvailable(s26));
3389     VIXL_CHECK(temps.IsAvailable(s27));
3390     VIXL_CHECK(temps.IsAvailable(q0));
3391 
3392     // Each available S register should mark the corresponding D and Q registers
3393     // as aliasing an available scratch register.
3394     for (unsigned s = 0; s < kNumberOfSRegisters; s++) {
3395       if (temps.IsAvailable(SRegister(s))) {
3396         VIXL_CHECK(masm.AliasesAvailableScratchRegister(SRegister(s)));
3397         VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(s / 2)));
3398         VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(s / 4)));
3399       } else {
3400         // AliasesAvailableScratchRegiters == IsAvailable for S registers.
3401         VIXL_CHECK(!masm.AliasesAvailableScratchRegister(SRegister(s)));
3402       }
3403     }
3404 
3405     // Similar checks for high D registers.
3406     unsigned first_high_d_register = kNumberOfSRegisters / 2;
3407     for (unsigned d = first_high_d_register; d < kMaxNumberOfDRegisters; d++) {
3408       if (temps.IsAvailable(DRegister(d))) {
3409         VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(d)));
3410         VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(d / 2)));
3411       } else {
3412         // AliasesAvailableScratchRegiters == IsAvailable for high D registers.
3413         VIXL_CHECK(!masm.AliasesAvailableScratchRegister(DRegister(d)));
3414       }
3415     }
3416   }
3417 }
3418 
3419 
TEST(nop)3420 TEST(nop) {
3421   SETUP();
3422 
3423   Label start;
3424   __ Bind(&start);
3425   __ Nop();
3426   size_t nop_size = (isa == T32) ? k16BitT32InstructionSizeInBytes
3427                                  : kA32InstructionSizeInBytes;
3428   // `MacroAssembler::Nop` must generate at least one nop.
3429   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) >= nop_size);
3430 
3431   masm.FinalizeCode();
3432 }
3433 
3434 // Check that `GetPoolCheckpoint()` is precise.
TEST(literal_pool_margin)3435 TEST(literal_pool_margin) {
3436   SETUP();
3437 
3438   START();
3439 
3440   VIXL_CHECK(test.PoolIsEmpty());
3441 
3442   // Create a single literal.
3443   __ Ldrd(r0, r1, 0x1234567890abcdef);
3444 
3445   VIXL_CHECK(!test.PoolIsEmpty());
3446 
3447   // Generate code to fill all the margin we have before generating the literal
3448   // pool.
3449   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
3450   int32_t end = test.GetPoolCheckpoint();
3451   {
3452     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
3453     // Opening the scope should not have triggered the emission of the literal
3454     // pool.
3455     VIXL_CHECK(!test.PoolIsEmpty());
3456     while (masm.GetCursorOffset() < end) {
3457       __ nop();
3458     }
3459     VIXL_CHECK(masm.GetCursorOffset() == end);
3460   }
3461 
3462   // There should be no margin left to emit the literal pool.
3463   VIXL_CHECK(!test.PoolIsEmpty());
3464   VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
3465 
3466   // So emitting a single instruction should force emission of the pool.
3467   __ Nop();
3468   VIXL_CHECK(test.PoolIsEmpty());
3469   END();
3470 
3471   RUN();
3472 
3473   // Check that the literals loaded correctly.
3474   ASSERT_EQUAL_32(0x90abcdef, r0);
3475   ASSERT_EQUAL_32(0x12345678, r1);
3476 }
3477 
3478 
3479 // Check that `GetPoolCheckpoint()` is precise.
TEST(veneer_pool_margin)3480 TEST(veneer_pool_margin) {
3481   SETUP();
3482 
3483   START();
3484 
3485   VIXL_CHECK(test.PoolIsEmpty());
3486 
3487   // Create a single veneer.
3488   Label target;
3489   __ B(eq, &target);
3490 
3491   VIXL_CHECK(!test.PoolIsEmpty());
3492 
3493   // Generate code to fill all the margin we have before generating the veneer
3494   // pool.
3495   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
3496   int32_t end = test.GetPoolCheckpoint();
3497   {
3498     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
3499     // Opening the scope should not have triggered the emission of the veneer
3500     // pool.
3501     VIXL_CHECK(!test.PoolIsEmpty());
3502     while (masm.GetCursorOffset() < end) {
3503       __ nop();
3504     }
3505     VIXL_CHECK(masm.GetCursorOffset() == end);
3506   }
3507   // There should be no margin left to emit the veneer pool.
3508   VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
3509 
3510   // So emitting a single instruction should force emission of the pool.
3511   // We cannot simply check that the veneer pool is empty, because the veneer
3512   // emitted for the CBZ instruction above is itself tracked by the veneer
3513   // mechanisms. Instead, check that some 'unexpected' code is generated.
3514   Label check;
3515   __ Bind(&check);
3516   {
3517     ExactAssemblyScope scope(&masm, 2, ExactAssemblyScope::kMaximumSize);
3518     // Do not actually generate any code.
3519   }
3520   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) > 0);
3521   __ Bind(&target);
3522   VIXL_CHECK(test.PoolIsEmpty());
3523 
3524   END();
3525 
3526   RUN();
3527 }
3528 
TEST_T32(near_branch_fuzz)3529 TEST_T32(near_branch_fuzz) {
3530   SETUP();
3531   START();
3532 
3533   uint16_t seed[3] = {1, 2, 3};
3534   seed48(seed);
3535 
3536   const int label_count = 31;
3537   bool allbound;
3538   Label* l;
3539 
3540   // Use multiple iterations, as each produces a different predictably random
3541   // sequence.
3542   const int iterations = 64;
3543 
3544   int loop_count = 0;
3545   __ Mov(r1, 0);
3546 
3547   // Initialise the status flags to Z set.
3548   __ Cmp(r1, r1);
3549 
3550   // Gradually increasing the number of cases effectively increases the
3551   // probability of nops being emitted in the sequence. The branch-to-bind
3552   // ratio in the sequence is fixed at 4:1 by the ratio of cases.
3553   for (int case_count = 6; case_count < 37; case_count++) {
3554     for (int iter = 0; iter < iterations; iter++) {
3555       // Reset local state.
3556       allbound = false;
3557       l = new Label[label_count];
3558 
3559       // Set r0 != 0 to force no branches to be taken. Also acts as a marker
3560       // between each iteration in the disassembly.
3561       __ Mov(r0, 1);
3562 
3563       for (;;) {
3564         uint32_t inst_case = static_cast<uint32_t>(mrand48()) % case_count;
3565         uint32_t label_index = static_cast<uint32_t>(mrand48()) % label_count;
3566 
3567         switch (inst_case) {
3568           case 0:  // Bind.
3569             if (!l[label_index].IsBound()) {
3570               __ Bind(&l[label_index]);
3571 
3572               // We should hit each label exactly once (because the branches are
3573               // never taken). Keep a counter to verify this.
3574               loop_count++;
3575               __ Add(r1, r1, 1);
3576             }
3577             break;
3578           case 1:  // Compare and branch if zero (untaken as r0 == 1).
3579             __ Cbz(r0, &l[label_index]);
3580             break;
3581           case 2: {  // Compare and branch if not zero.
3582             Label past_branch;
3583             __ B(eq, &past_branch, kNear);
3584             __ Cbnz(r0, &l[label_index]);
3585             __ Bind(&past_branch);
3586             break;
3587           }
3588           case 3: {  // Unconditional branch preferred near.
3589             Label past_branch;
3590             __ B(eq, &past_branch, kNear);
3591             __ B(&l[label_index], kNear);
3592             __ Bind(&past_branch);
3593             break;
3594           }
3595           case 4:  // Conditional branch (untaken as Z set) preferred near.
3596             __ B(ne, &l[label_index], kNear);
3597             break;
3598           default:  // Nop.
3599             __ Nop();
3600             break;
3601         }
3602 
3603         // If all labels have been bound, exit the inner loop and finalise the
3604         // code.
3605         allbound = true;
3606         for (int i = 0; i < label_count; i++) {
3607           allbound = allbound && l[i].IsBound();
3608         }
3609         if (allbound) break;
3610       }
3611 
3612       // Ensure that the veneer pools are emitted, to keep each branch/bind test
3613       // independent. We will generate more code following this.
3614       masm.FinalizeCode(MacroAssembler::kFallThrough);
3615       delete[] l;
3616     }
3617   }
3618 
3619   END();
3620   RUN();
3621 
3622   ASSERT_EQUAL_32(loop_count, r1);
3623 }
3624 
3625 
TEST_T32(near_branch_and_literal_fuzz)3626 TEST_T32(near_branch_and_literal_fuzz) {
3627   SETUP();
3628   START();
3629 
3630   uint16_t seed[3] = {1, 2, 3};
3631   seed48(seed);
3632 
3633   const int label_count = 15;
3634   const int literal_count = 31;
3635   bool allbound;
3636   Label* labels;
3637   uint64_t* literal_values;
3638   Literal<uint64_t>* literals[literal_count];
3639 
3640   // Use multiple iterations, as each produces a different predictably random
3641   // sequence.
3642   const int iterations = 128;
3643   const int n_cases = 20;
3644 
3645   int loop_count = 0;
3646   __ Mov(r1, 0);
3647 
3648   // If the value of r4 changes then the test fails.
3649   __ Mov(r4, 42);
3650 
3651   // This test generates a mix of 20 different code sequences (see switch case
3652   // below). The cases are split in 4 groups:
3653   //
3654   //   - 0..3: Generate various amount of nops.
3655   //   - 4..7: Generate various load intstructions with literals.
3656   //   - 8..14: Generate various branch instructions.
3657   //   - 15..19: Generate various amount of nops.
3658   //
3659   // The idea behind this is that we can have a window of size N which we can
3660   // slide across these cases. And as a result, randomly generate sequences with
3661   // a different ratio of:
3662   //   - "nops vs literals"
3663   //   - "literal vs veneers"
3664   //   - "veneers vs nops"
3665   //
3666   // In this test, we grow a window from 5 to 14, and then slide this window
3667   // across all cases each time. We call this sliding a "ratio", which is in
3668   // fact an offset from the first case of the switch.
3669 
3670   for (uint32_t window = 5; window < 14; window++) {
3671     for (uint32_t ratio = 0; ratio < static_cast<uint32_t>(n_cases - window);
3672          ratio++) {
3673       for (int iter = 0; iter < iterations; iter++) {
3674         Label fail;
3675         Label end;
3676 
3677         // Reset local state.
3678         allbound = false;
3679         labels = new Label[label_count];
3680 
3681         // Create new literal values.
3682         literal_values = new uint64_t[literal_count];
3683         for (int lit = 0; lit < literal_count; lit++) {
3684           // TODO: Generate pseudo-random data for literals. At the moment, the
3685           // disassembler breaks if we do this.
3686           literal_values[lit] = lit;
3687           literals[lit] = new Literal<uint64_t>(literal_values[lit]);
3688         }
3689 
3690         for (;;) {
3691           uint32_t inst_case =
3692               (static_cast<uint32_t>(mrand48()) % window) + ratio;
3693           uint32_t label_index = static_cast<uint32_t>(mrand48()) % label_count;
3694           uint32_t literal_index =
3695               static_cast<uint32_t>(mrand48()) % literal_count;
3696 
3697           if (inst_case == ratio) {
3698             if (!labels[label_index].IsBound()) {
3699               __ Bind(&labels[label_index]);
3700 
3701               // We should hit each label exactly once (because the branches are
3702               // never taken). Keep a counter to verify this.
3703               loop_count++;
3704               __ Add(r1, r1, 1);
3705               continue;
3706             }
3707           }
3708 
3709           switch (inst_case) {
3710             case 0:
3711               __ Nop();
3712               break;
3713             case 1:
3714               __ Nop();
3715               __ Nop();
3716               __ Nop();
3717               __ Nop();
3718               __ Nop();
3719               __ Nop();
3720               __ Nop();
3721               __ Nop();
3722               __ Nop();
3723               break;
3724             case 2:
3725               __ Nop();
3726               __ Nop();
3727               __ Nop();
3728               break;
3729             case 3:
3730               __ Nop();
3731               __ Nop();
3732               __ Nop();
3733               __ Nop();
3734               __ Nop();
3735               __ Nop();
3736               __ Nop();
3737               break;
3738             case 4:
3739               __ Ldr(r2, literals[literal_index]);
3740               __ Cmp(r2, static_cast<uint32_t>(literal_values[literal_index]));
3741               __ B(ne, &fail);
3742               __ Mov(r2, 0);
3743               break;
3744             case 5:
3745               __ Ldrb(r2, literals[literal_index]);
3746               __ Cmp(r2,
3747                      static_cast<uint32_t>(literal_values[literal_index]) &
3748                          0xff);
3749               __ B(ne, &fail);
3750               __ Mov(r2, 0);
3751               break;
3752             case 6:
3753               __ Ldrd(r2, r3, literals[literal_index]);
3754               __ Cmp(r2, static_cast<uint32_t>(literal_values[literal_index]));
3755               __ B(ne, &fail);
3756               __ Mov(r2, 0);
3757               __ Cmp(r3,
3758                      static_cast<uint32_t>(literal_values[literal_index] >>
3759                                            32));
3760               __ B(ne, &fail);
3761               __ Mov(r3, 0);
3762               break;
3763             case 7:
3764               __ Vldr(s0, literals[literal_index]);
3765               __ Vmov(s1, static_cast<uint32_t>(literal_values[literal_index]));
3766               __ Vcmp(s0, s1);
3767               __ B(ne, &fail);
3768               __ Vmov(s0, 0);
3769               break;
3770             case 8: {
3771               Label past_branch;
3772               __ B(&past_branch, kNear);
3773               __ Cbz(r0, &labels[label_index]);
3774               __ Bind(&past_branch);
3775               break;
3776             }
3777             case 9: {
3778               Label past_branch;
3779               __ B(&past_branch, kNear);
3780               __ Cbnz(r0, &labels[label_index]);
3781               __ Bind(&past_branch);
3782               break;
3783             }
3784             case 10: {
3785               Label past_branch;
3786               __ B(&past_branch, kNear);
3787               __ B(ne, &labels[label_index], kNear);
3788               __ Bind(&past_branch);
3789               break;
3790             }
3791             case 11: {
3792               Label past_branch;
3793               __ B(&past_branch, kNear);
3794               __ B(&labels[label_index], kNear);
3795               __ Bind(&past_branch);
3796               break;
3797             }
3798             case 12: {
3799               Label past_branch;
3800               __ B(&past_branch, kNear);
3801               __ B(ne, &labels[label_index]);
3802               __ Bind(&past_branch);
3803               break;
3804             }
3805             case 13: {
3806               Label past_branch;
3807               __ B(&past_branch, kNear);
3808               __ B(&labels[label_index]);
3809               __ Bind(&past_branch);
3810               break;
3811             }
3812             case 14: {
3813               Label past_branch;
3814               __ B(&past_branch, kNear);
3815               __ Bl(&labels[label_index]);
3816               __ Bind(&past_branch);
3817               break;
3818             }
3819             case 15:
3820               __ Nop();
3821               __ Nop();
3822               __ Nop();
3823               __ Nop();
3824               __ Nop();
3825               break;
3826             case 16:
3827               __ Nop();
3828               __ Nop();
3829               __ Nop();
3830               __ Nop();
3831               __ Nop();
3832               __ Nop();
3833               break;
3834             case 17:
3835               __ Nop();
3836               __ Nop();
3837               __ Nop();
3838               __ Nop();
3839               break;
3840             case 18:
3841               __ Nop();
3842               __ Nop();
3843               __ Nop();
3844               __ Nop();
3845               __ Nop();
3846               __ Nop();
3847               __ Nop();
3848               __ Nop();
3849               break;
3850             case 19:
3851               __ Nop();
3852               __ Nop();
3853               break;
3854             default:
3855               VIXL_UNREACHABLE();
3856               break;
3857           }
3858 
3859           // If all labels have been bound, exit the inner loop and finalise the
3860           // code.
3861           allbound = true;
3862           for (int i = 0; i < label_count; i++) {
3863             allbound = allbound && labels[i].IsBound();
3864           }
3865           if (allbound) break;
3866         }
3867 
3868         __ B(&end);
3869         __ Bind(&fail);
3870         __ Mov(r4, 0);
3871         __ Bind(&end);
3872 
3873         // Ensure that the veneer pools are emitted, to keep each branch/bind
3874         // test
3875         // independent.
3876         masm.FinalizeCode(MacroAssembler::kFallThrough);
3877         delete[] labels;
3878         for (int lit = 0; lit < literal_count; lit++) {
3879           delete literals[lit];
3880         }
3881       }
3882     }
3883   }
3884 
3885   END();
3886   RUN();
3887 
3888   ASSERT_EQUAL_32(loop_count, r1);
3889   ASSERT_EQUAL_32(42, r4);
3890 }
3891 
3892 
3893 #ifdef VIXL_INCLUDE_TARGET_T32
TEST_NOASM(code_buffer_precise_growth)3894 TEST_NOASM(code_buffer_precise_growth) {
3895   static const int kBaseBufferSize = 16;
3896   MacroAssembler masm(kBaseBufferSize, T32);
3897 
3898   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3899 
3900   {
3901     // Fill the buffer with nops.
3902     ExactAssemblyScope scope(&masm,
3903                              kBaseBufferSize,
3904                              ExactAssemblyScope::kExactSize);
3905     for (int i = 0; i < kBaseBufferSize; i += k16BitT32InstructionSizeInBytes) {
3906       __ nop();
3907     }
3908   }
3909 
3910   // The buffer should not have grown yet.
3911   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3912 
3913   // Generating a single instruction should force the buffer to grow.
3914   __ Nop();
3915 
3916   VIXL_CHECK(masm.GetBuffer()->GetCapacity() > kBaseBufferSize);
3917 
3918   masm.FinalizeCode();
3919 }
3920 #endif
3921 
3922 #ifdef VIXL_INCLUDE_TARGET_T32
TEST_NOASM(out_of_space_immediately_before_EnsureEmitFor)3923 TEST_NOASM(out_of_space_immediately_before_EnsureEmitFor) {
3924   static const int kBaseBufferSize = 64;
3925   MacroAssembler masm(kBaseBufferSize, T32);
3926   TestMacroAssembler test(&masm);
3927 
3928   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3929 
3930   VIXL_CHECK(test.PoolIsEmpty());
3931 
3932   // Create a veneer.
3933   Label target;
3934   __ Cbz(r0, &target);
3935 
3936   VIXL_CHECK(!test.PoolIsEmpty());
3937 
3938   VIXL_CHECK(IsUint32(masm.GetBuffer()->GetRemainingBytes()));
3939   uint32_t space = static_cast<uint32_t>(masm.GetBuffer()->GetRemainingBytes());
3940   {
3941     // Fill the buffer with nops.
3942     ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
3943     for (uint32_t i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
3944       __ nop();
3945     }
3946   }
3947 
3948   VIXL_CHECK(!test.PoolIsEmpty());
3949 
3950   // The buffer should not have grown yet, and there should be no space left.
3951   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3952   VIXL_CHECK(masm.GetBuffer()->GetRemainingBytes() == 0);
3953 
3954   // Force emission of the veneer, at a point where there is no space available
3955   // in the buffer.
3956   int32_t past_cbz_range =
3957       test.GetPoolCheckpoint() - masm.GetCursorOffset() + 1;
3958   masm.EnsureEmitFor(past_cbz_range);
3959 
3960   __ Bind(&target);
3961 
3962   VIXL_CHECK(test.PoolIsEmpty());
3963 
3964   masm.FinalizeCode();
3965 }
3966 #endif
3967 
3968 
TEST_NOASM(EnsureEmitFor)3969 TEST_NOASM(EnsureEmitFor) {
3970   static const int kBaseBufferSize = 32;
3971   MacroAssembler masm(kBaseBufferSize);
3972 
3973   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3974 
3975   VIXL_CHECK(IsUint32(masm.GetBuffer()->GetRemainingBytes()));
3976   int32_t space = static_cast<int32_t>(masm.GetBuffer()->GetRemainingBytes());
3977   int32_t end = __ GetCursorOffset() + space;
3978   {
3979     // Fill the buffer with nops.
3980     ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
3981     while (__ GetCursorOffset() != end) {
3982       __ nop();
3983     }
3984   }
3985 
3986   // Test that EnsureEmitFor works.
3987   VIXL_CHECK(!masm.GetBuffer()->HasSpaceFor(4));
3988   masm.EnsureEmitFor(4);
3989   VIXL_CHECK(masm.GetBuffer()->HasSpaceFor(4));
3990   __ Nop();
3991 
3992   masm.FinalizeCode();
3993 }
3994 
TEST_T32(distant_literal_references)3995 TEST_T32(distant_literal_references) {
3996   SETUP();
3997   START();
3998 
3999   Literal<uint64_t>* literal =
4000       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4001                             RawLiteral::kPlacedWhenUsed,
4002                             RawLiteral::kDeletedOnPoolDestruction);
4003   // Refer to the literal so that it is emitted early.
4004   __ Ldr(r0, literal);
4005 
4006   // Add enough nops to exceed the range of all loads.
4007   int space = 5000;
4008   {
4009     ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
4010     VIXL_ASSERT(masm.IsUsingT32());
4011     for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
4012       __ nop();
4013     }
4014   }
4015 
4016 #define ENSURE_ALIGNED()                                                      \
4017   do {                                                                        \
4018     if (!IsMultiple<k32BitT32InstructionSizeInBytes>(                         \
4019             masm.GetCursorOffset())) {                                        \
4020       ExactAssemblyScope scope(&masm,                                         \
4021                                k16BitT32InstructionSizeInBytes,               \
4022                                ExactAssemblyScope::kExactSize);               \
4023       __ nop();                                                               \
4024     }                                                                         \
4025     VIXL_ASSERT(                                                              \
4026         IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
4027   } while (0)
4028 
4029   // The literal has already been emitted, and is out of range of all of these
4030   // instructions. The delegates must generate fix-up code.
4031   ENSURE_ALIGNED();
4032   __ Ldr(r1, literal);
4033   ENSURE_ALIGNED();
4034   __ Ldrb(r2, literal);
4035   ENSURE_ALIGNED();
4036   __ Ldrsb(r3, literal);
4037   ENSURE_ALIGNED();
4038   __ Ldrh(r4, literal);
4039   ENSURE_ALIGNED();
4040   __ Ldrsh(r5, literal);
4041   ENSURE_ALIGNED();
4042   __ Ldrd(r6, r7, literal);
4043   ENSURE_ALIGNED();
4044   __ Vldr(d0, literal);
4045   ENSURE_ALIGNED();
4046   __ Vldr(s3, literal);
4047 
4048 #undef ENSURE_ALIGNED
4049 
4050   END();
4051   RUN();
4052 
4053   // Check that the literals loaded correctly.
4054   ASSERT_EQUAL_32(0x89abcdef, r0);
4055   ASSERT_EQUAL_32(0x89abcdef, r1);
4056   ASSERT_EQUAL_32(0xef, r2);
4057   ASSERT_EQUAL_32(0xffffffef, r3);
4058   ASSERT_EQUAL_32(0xcdef, r4);
4059   ASSERT_EQUAL_32(0xffffcdef, r5);
4060   ASSERT_EQUAL_32(0x89abcdef, r6);
4061   ASSERT_EQUAL_32(0x01234567, r7);
4062   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4063   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4064 }
4065 
4066 
TEST_T32(distant_literal_references_unaligned_pc)4067 TEST_T32(distant_literal_references_unaligned_pc) {
4068   SETUP();
4069   START();
4070 
4071   Literal<uint64_t>* literal =
4072       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4073                             RawLiteral::kPlacedWhenUsed,
4074                             RawLiteral::kDeletedOnPoolDestruction);
4075   // Refer to the literal so that it is emitted early.
4076   __ Ldr(r0, literal);
4077 
4078   // Add enough nops to exceed the range of all loads, leaving the PC aligned
4079   // to only a two-byte boundary.
4080   int space = 5002;
4081   {
4082     ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
4083     VIXL_ASSERT(masm.IsUsingT32());
4084     for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
4085       __ nop();
4086     }
4087   }
4088 
4089 #define ENSURE_NOT_ALIGNED()                                                   \
4090   do {                                                                         \
4091     if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
4092       ExactAssemblyScope scope(&masm,                                          \
4093                                k16BitT32InstructionSizeInBytes,                \
4094                                ExactAssemblyScope::kExactSize);                \
4095       __ nop();                                                                \
4096     }                                                                          \
4097     VIXL_ASSERT(                                                               \
4098         !IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
4099   } while (0)
4100 
4101   // The literal has already been emitted, and is out of range of all of these
4102   // instructions. The delegates must generate fix-up code.
4103   ENSURE_NOT_ALIGNED();
4104   __ Ldr(r1, literal);
4105   ENSURE_NOT_ALIGNED();
4106   __ Ldrb(r2, literal);
4107   ENSURE_NOT_ALIGNED();
4108   __ Ldrsb(r3, literal);
4109   ENSURE_NOT_ALIGNED();
4110   __ Ldrh(r4, literal);
4111   ENSURE_NOT_ALIGNED();
4112   __ Ldrsh(r5, literal);
4113   ENSURE_NOT_ALIGNED();
4114   __ Ldrd(r6, r7, literal);
4115   {
4116     // TODO: We currently require an extra scratch register for these cases
4117     // because MemOperandComputationHelper isn't able to fit add_sub_offset into
4118     // a single 'sub' instruction, so 'pc' gets preserved first. The same
4119     // problem technically exists for the other loads, but vldr is particularly
4120     // badly affected because vldr cannot set the low bits in its offset mask,
4121     // so the add/sub operand is likely to be difficult to encode.
4122     //
4123     // At the moment, we get this:
4124     //     mov r8, pc
4125     //     mov ip, #5118
4126     //     sub r8, pc
4127     //     vldr d0, [r8, #48]
4128     //
4129     // We should be able to generate something like this:
4130     //     sub ip, pc, #0x1300    // 5118 & 0xff00
4131     //     sub ip, #0xfe          // 5118 & 0x00ff
4132     //     vldr d0, [ip, #48]
4133     UseScratchRegisterScope temps(&masm);
4134     temps.Include(r8);
4135     ENSURE_NOT_ALIGNED();
4136     __ Vldr(d0, literal);
4137     ENSURE_NOT_ALIGNED();
4138     __ Vldr(s3, literal);
4139   }
4140 
4141 #undef ENSURE_NOT_ALIGNED
4142 
4143   END();
4144   RUN();
4145 
4146   // Check that the literals loaded correctly.
4147   ASSERT_EQUAL_32(0x89abcdef, r0);
4148   ASSERT_EQUAL_32(0x89abcdef, r1);
4149   ASSERT_EQUAL_32(0xef, r2);
4150   ASSERT_EQUAL_32(0xffffffef, r3);
4151   ASSERT_EQUAL_32(0xcdef, r4);
4152   ASSERT_EQUAL_32(0xffffcdef, r5);
4153   ASSERT_EQUAL_32(0x89abcdef, r6);
4154   ASSERT_EQUAL_32(0x01234567, r7);
4155   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4156   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4157 }
4158 
4159 
TEST_T32(distant_literal_references_short_range)4160 TEST_T32(distant_literal_references_short_range) {
4161   SETUP();
4162   START();
4163 
4164   Literal<uint64_t>* literal =
4165       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4166                             RawLiteral::kPlacedWhenUsed,
4167                             RawLiteral::kDeletedOnPoolDestruction);
4168   // Refer to the literal so that it is emitted early.
4169   __ Vldr(s4, literal);
4170 
4171   // Add enough nops to exceed the range of the loads, but not the adr that will
4172   // be generated to read the PC.
4173   int space = 4000;
4174   {
4175     ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
4176     VIXL_ASSERT(masm.IsUsingT32());
4177     for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
4178       __ nop();
4179     }
4180   }
4181 
4182 #define ENSURE_ALIGNED()                                                      \
4183   do {                                                                        \
4184     if (!IsMultiple<k32BitT32InstructionSizeInBytes>(                         \
4185             masm.GetCursorOffset())) {                                        \
4186       ExactAssemblyScope scope(&masm,                                         \
4187                                k16BitT32InstructionSizeInBytes,               \
4188                                ExactAssemblyScope::kExactSize);               \
4189       __ nop();                                                               \
4190     }                                                                         \
4191     VIXL_ASSERT(                                                              \
4192         IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
4193   } while (0)
4194 
4195   // The literal has already been emitted, and is out of range of all of these
4196   // instructions. The delegates must generate fix-up code.
4197   ENSURE_ALIGNED();
4198   __ Ldr(r1, literal);
4199   ENSURE_ALIGNED();
4200   __ Ldrb(r2, literal);
4201   ENSURE_ALIGNED();
4202   __ Ldrsb(r3, literal);
4203   ENSURE_ALIGNED();
4204   __ Ldrh(r4, literal);
4205   ENSURE_ALIGNED();
4206   __ Ldrsh(r5, literal);
4207   ENSURE_ALIGNED();
4208   __ Ldrd(r6, r7, literal);
4209   ENSURE_ALIGNED();
4210   __ Vldr(d0, literal);
4211   ENSURE_ALIGNED();
4212   __ Vldr(s3, literal);
4213 
4214 #undef ENSURE_ALIGNED
4215 
4216   END();
4217   RUN();
4218 
4219   // Check that the literals loaded correctly.
4220   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s4);
4221   ASSERT_EQUAL_32(0x89abcdef, r1);
4222   ASSERT_EQUAL_32(0xef, r2);
4223   ASSERT_EQUAL_32(0xffffffef, r3);
4224   ASSERT_EQUAL_32(0xcdef, r4);
4225   ASSERT_EQUAL_32(0xffffcdef, r5);
4226   ASSERT_EQUAL_32(0x89abcdef, r6);
4227   ASSERT_EQUAL_32(0x01234567, r7);
4228   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4229   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4230 }
4231 
4232 
TEST_T32(distant_literal_references_short_range_unaligned_pc)4233 TEST_T32(distant_literal_references_short_range_unaligned_pc) {
4234   SETUP();
4235   START();
4236 
4237   Literal<uint64_t>* literal =
4238       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4239                             RawLiteral::kPlacedWhenUsed,
4240                             RawLiteral::kDeletedOnPoolDestruction);
4241   // Refer to the literal so that it is emitted early.
4242   __ Vldr(s4, literal);
4243 
4244   // Add enough nops to exceed the range of the loads, but not the adr that will
4245   // be generated to read the PC.
4246   int space = 4000;
4247   {
4248     ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
4249     VIXL_ASSERT(masm.IsUsingT32());
4250     for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
4251       __ nop();
4252     }
4253   }
4254 
4255 #define ENSURE_NOT_ALIGNED()                                                   \
4256   do {                                                                         \
4257     if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
4258       ExactAssemblyScope scope(&masm,                                          \
4259                                k16BitT32InstructionSizeInBytes,                \
4260                                ExactAssemblyScope::kExactSize);                \
4261       __ nop();                                                                \
4262     }                                                                          \
4263     VIXL_ASSERT(                                                               \
4264         !IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
4265   } while (0)
4266 
4267   // The literal has already been emitted, and is out of range of all of these
4268   // instructions. The delegates must generate fix-up code.
4269   ENSURE_NOT_ALIGNED();
4270   __ Ldr(r1, literal);
4271   ENSURE_NOT_ALIGNED();
4272   __ Ldrb(r2, literal);
4273   ENSURE_NOT_ALIGNED();
4274   __ Ldrsb(r3, literal);
4275   ENSURE_NOT_ALIGNED();
4276   __ Ldrh(r4, literal);
4277   ENSURE_NOT_ALIGNED();
4278   __ Ldrsh(r5, literal);
4279   ENSURE_NOT_ALIGNED();
4280   __ Ldrd(r6, r7, literal);
4281   ENSURE_NOT_ALIGNED();
4282   __ Vldr(d0, literal);
4283   ENSURE_NOT_ALIGNED();
4284   __ Vldr(s3, literal);
4285 
4286 #undef ENSURE_NOT_ALIGNED
4287 
4288   END();
4289   RUN();
4290 
4291   // Check that the literals loaded correctly.
4292   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s4);
4293   ASSERT_EQUAL_32(0x89abcdef, r1);
4294   ASSERT_EQUAL_32(0xef, r2);
4295   ASSERT_EQUAL_32(0xffffffef, r3);
4296   ASSERT_EQUAL_32(0xcdef, r4);
4297   ASSERT_EQUAL_32(0xffffcdef, r5);
4298   ASSERT_EQUAL_32(0x89abcdef, r6);
4299   ASSERT_EQUAL_32(0x01234567, r7);
4300   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4301   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4302 }
4303 
4304 
TEST_T32(distant_literal_references_long_range)4305 TEST_T32(distant_literal_references_long_range) {
4306   SETUP();
4307   START();
4308 
4309   Literal<uint64_t>* literal =
4310       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4311                             RawLiteral::kPlacedWhenUsed,
4312                             RawLiteral::kDeletedOnPoolDestruction);
4313   // Refer to the literal so that it is emitted early.
4314   __ Ldr(r0, literal);
4315 
4316 #define PAD_WITH_NOPS(space)                                             \
4317   do {                                                                   \
4318     {                                                                    \
4319       ExactAssemblyScope scope(&masm,                                    \
4320                                space,                                    \
4321                                CodeBufferCheckScope::kExactSize);        \
4322       VIXL_ASSERT(masm.IsUsingT32());                                    \
4323       for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) { \
4324         __ nop();                                                        \
4325       }                                                                  \
4326     }                                                                    \
4327   } while (0)
4328 
4329   // Add enough nops to exceed the range of all loads.
4330   PAD_WITH_NOPS(5000);
4331 
4332   // The literal has already been emitted, and is out of range of all of these
4333   // instructions. The delegates must generate fix-up code.
4334   __ Ldr(r1, literal);
4335   __ Ldrb(r2, literal);
4336   __ Ldrsb(r3, literal);
4337   __ Ldrh(r4, literal);
4338   __ Ldrsh(r5, literal);
4339   __ Ldrd(r6, r7, literal);
4340   __ Vldr(d0, literal);
4341   __ Vldr(s3, literal);
4342 
4343   // Add enough nops to exceed the range of the adr+sub sequence.
4344   PAD_WITH_NOPS(0x421000);
4345 
4346   __ Ldr(r1, literal);
4347   __ Ldrb(r2, literal);
4348   __ Ldrsb(r3, literal);
4349   __ Ldrh(r4, literal);
4350   __ Ldrsh(r5, literal);
4351   __ Ldrd(r6, r7, literal);
4352   {
4353     // TODO: We currently require an extra scratch register for these cases. We
4354     // should be able to optimise the code generation to avoid this requirement
4355     // (and in many cases avoid a 32-bit instruction).
4356     UseScratchRegisterScope temps(&masm);
4357     temps.Include(r8);
4358     __ Vldr(d0, literal);
4359     __ Vldr(s3, literal);
4360   }
4361 
4362 #undef PAD_WITH_NOPS
4363 
4364   END();
4365   RUN();
4366 
4367   // Check that the literals loaded correctly.
4368   ASSERT_EQUAL_32(0x89abcdef, r0);
4369   ASSERT_EQUAL_32(0x89abcdef, r1);
4370   ASSERT_EQUAL_32(0xef, r2);
4371   ASSERT_EQUAL_32(0xffffffef, r3);
4372   ASSERT_EQUAL_32(0xcdef, r4);
4373   ASSERT_EQUAL_32(0xffffcdef, r5);
4374   ASSERT_EQUAL_32(0x89abcdef, r6);
4375   ASSERT_EQUAL_32(0x01234567, r7);
4376   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4377   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4378 }
4379 
4380 
TEST(barriers)4381 TEST(barriers) {
4382   // Generate all supported barriers, this is just a smoke test
4383   SETUP();
4384 
4385   START();
4386 
4387   // DMB
4388   __ Dmb(SY);
4389   __ Dmb(ST);
4390   __ Dmb(ISH);
4391   __ Dmb(ISHST);
4392   __ Dmb(NSH);
4393   __ Dmb(NSHST);
4394   __ Dmb(OSH);
4395   __ Dmb(OSHST);
4396 
4397   // DSB
4398   __ Dsb(SY);
4399   __ Dsb(ST);
4400   __ Dsb(ISH);
4401   __ Dsb(ISHST);
4402   __ Dsb(NSH);
4403   __ Dsb(NSHST);
4404   __ Dsb(OSH);
4405   __ Dsb(OSHST);
4406 
4407   // ISB
4408   __ Isb(SY);
4409 
4410   END();
4411 }
4412 
4413 
TEST(preloads)4414 TEST(preloads) {
4415   // Smoke test for various pld/pli forms.
4416   SETUP();
4417 
4418   START();
4419 
4420   // PLD immediate
4421   __ Pld(MemOperand(sp, 0));
4422   __ Pld(MemOperand(r0, 0));
4423   __ Pld(MemOperand(r1, 123));
4424   __ Pld(MemOperand(r2, 1234));
4425   __ Pld(MemOperand(r3, 4095));
4426   __ Pld(MemOperand(r4, -123));
4427   __ Pld(MemOperand(r5, -255));
4428 
4429   if (masm.IsUsingA32()) {
4430     __ Pld(MemOperand(r6, -1234));
4431     __ Pld(MemOperand(r7, -4095));
4432   }
4433 
4434 
4435   // PLDW immediate
4436   __ Pldw(MemOperand(sp, 0));
4437   __ Pldw(MemOperand(r0, 0));
4438   __ Pldw(MemOperand(r1, 123));
4439   __ Pldw(MemOperand(r2, 1234));
4440   __ Pldw(MemOperand(r3, 4095));
4441   __ Pldw(MemOperand(r4, -123));
4442   __ Pldw(MemOperand(r5, -255));
4443 
4444   if (masm.IsUsingA32()) {
4445     __ Pldw(MemOperand(r6, -1234));
4446     __ Pldw(MemOperand(r7, -4095));
4447   }
4448 
4449   // PLD register
4450   __ Pld(MemOperand(r0, r1));
4451   __ Pld(MemOperand(r0, r1, LSL, 1));
4452   __ Pld(MemOperand(r0, r1, LSL, 2));
4453   __ Pld(MemOperand(r0, r1, LSL, 3));
4454 
4455   if (masm.IsUsingA32()) {
4456     __ Pld(MemOperand(r0, r1, LSL, 4));
4457     __ Pld(MemOperand(r0, r1, LSL, 20));
4458   }
4459 
4460   // PLDW register
4461   __ Pldw(MemOperand(r0, r1));
4462   __ Pldw(MemOperand(r0, r1, LSL, 1));
4463   __ Pldw(MemOperand(r0, r1, LSL, 2));
4464   __ Pldw(MemOperand(r0, r1, LSL, 3));
4465 
4466   if (masm.IsUsingA32()) {
4467     __ Pldw(MemOperand(r0, r1, LSL, 4));
4468     __ Pldw(MemOperand(r0, r1, LSL, 20));
4469   }
4470 
4471   // PLI immediate
4472   __ Pli(MemOperand(sp, 0));
4473   __ Pli(MemOperand(r0, 0));
4474   __ Pli(MemOperand(r1, 123));
4475   __ Pli(MemOperand(r2, 1234));
4476   __ Pli(MemOperand(r3, 4095));
4477   __ Pli(MemOperand(r4, -123));
4478   __ Pli(MemOperand(r5, -255));
4479 
4480   if (masm.IsUsingA32()) {
4481     __ Pli(MemOperand(r6, -1234));
4482     __ Pli(MemOperand(r7, -4095));
4483   }
4484 
4485   // PLI register
4486   __ Pli(MemOperand(r0, r1));
4487   __ Pli(MemOperand(r0, r1, LSL, 1));
4488   __ Pli(MemOperand(r0, r1, LSL, 2));
4489   __ Pli(MemOperand(r0, r1, LSL, 3));
4490 
4491   if (masm.IsUsingA32()) {
4492     __ Pli(MemOperand(r0, r1, LSL, 4));
4493     __ Pli(MemOperand(r0, r1, LSL, 20));
4494   }
4495 
4496   END();
4497 }
4498 
4499 
TEST_T32(veneer_mirrored_branches)4500 TEST_T32(veneer_mirrored_branches) {
4501   SETUP();
4502 
4503   START();
4504 
4505   const int kMaxBranchCount = 256;
4506 
4507   for (int branch_count = 1; branch_count < kMaxBranchCount; branch_count++) {
4508     Label* targets = new Label[branch_count];
4509 
4510     for (int i = 0; i < branch_count; i++) {
4511       __ Cbz(r0, &targets[i]);
4512     }
4513 
4514     for (int i = 0; i < branch_count; i++) {
4515       __ Bind(&targets[branch_count - i - 1]);
4516       __ Orr(r0, r0, r0);
4517     }
4518 
4519     delete[] targets;
4520   }
4521 
4522   END();
4523 }
4524 
4525 
TEST_T32(branch_fuzz_example)4526 TEST_T32(branch_fuzz_example) {
4527   SETUP();
4528 
4529   START();
4530 
4531   Label l[64];
4532   __ And(r0, r0, r0);
4533   __ Cbz(r0, &l[30]);
4534   __ And(r0, r0, r0);
4535   __ Cbz(r0, &l[22]);
4536   __ And(r0, r0, r0);
4537   __ Cbz(r0, &l[1]);
4538   __ Cbz(r0, &l[15]);
4539   __ Cbz(r0, &l[9]);
4540   __ Cbz(r0, &l[6]);
4541   __ Bind(&l[26]);
4542   __ Cbz(r0, &l[29]);
4543   __ And(r0, r0, r0);
4544   __ And(r0, r0, r0);
4545   __ Cbz(r0, &l[22]);
4546   __ Bind(&l[12]);
4547   __ Bind(&l[22]);
4548   __ Cbz(r0, &l[10]);
4549   __ And(r0, r0, r0);
4550   __ Cbz(r0, &l[30]);
4551   __ Cbz(r0, &l[17]);
4552   __ Cbz(r0, &l[27]);
4553   __ Cbz(r0, &l[11]);
4554   __ Bind(&l[7]);
4555   __ Cbz(r0, &l[18]);
4556   __ Bind(&l[14]);
4557   __ Cbz(r0, &l[1]);
4558   __ Bind(&l[18]);
4559   __ Cbz(r0, &l[11]);
4560   __ Cbz(r0, &l[6]);
4561   __ Bind(&l[21]);
4562   __ Cbz(r0, &l[28]);
4563   __ And(r0, r0, r0);
4564   __ Cbz(r0, &l[28]);
4565   __ Cbz(r0, &l[22]);
4566   __ Bind(&l[23]);
4567   __ Cbz(r0, &l[21]);
4568   __ Cbz(r0, &l[28]);
4569   __ Cbz(r0, &l[9]);
4570   __ Bind(&l[9]);
4571   __ Cbz(r0, &l[4]);
4572   __ And(r0, r0, r0);
4573   __ Cbz(r0, &l[10]);
4574   __ And(r0, r0, r0);
4575   __ Bind(&l[8]);
4576   __ And(r0, r0, r0);
4577   __ Cbz(r0, &l[10]);
4578   __ And(r0, r0, r0);
4579   __ Cbz(r0, &l[17]);
4580   __ Bind(&l[10]);
4581   __ Cbz(r0, &l[8]);
4582   __ Cbz(r0, &l[25]);
4583   __ Cbz(r0, &l[4]);
4584   __ Bind(&l[28]);
4585   __ And(r0, r0, r0);
4586   __ Cbz(r0, &l[16]);
4587   __ Bind(&l[19]);
4588   __ Cbz(r0, &l[14]);
4589   __ Cbz(r0, &l[28]);
4590   __ Cbz(r0, &l[26]);
4591   __ Cbz(r0, &l[21]);
4592   __ And(r0, r0, r0);
4593   __ Bind(&l[24]);
4594   __ And(r0, r0, r0);
4595   __ Cbz(r0, &l[24]);
4596   __ Cbz(r0, &l[24]);
4597   __ Cbz(r0, &l[19]);
4598   __ Cbz(r0, &l[26]);
4599   __ Cbz(r0, &l[4]);
4600   __ And(r0, r0, r0);
4601   __ Cbz(r0, &l[27]);
4602   __ Cbz(r0, &l[14]);
4603   __ Cbz(r0, &l[5]);
4604   __ Cbz(r0, &l[18]);
4605   __ Cbz(r0, &l[5]);
4606   __ Cbz(r0, &l[6]);
4607   __ Cbz(r0, &l[28]);
4608   __ Cbz(r0, &l[15]);
4609   __ Cbz(r0, &l[0]);
4610   __ Cbz(r0, &l[10]);
4611   __ Cbz(r0, &l[16]);
4612   __ Cbz(r0, &l[30]);
4613   __ Cbz(r0, &l[8]);
4614   __ Cbz(r0, &l[16]);
4615   __ Cbz(r0, &l[22]);
4616   __ Cbz(r0, &l[27]);
4617   __ Cbz(r0, &l[12]);
4618   __ Cbz(r0, &l[0]);
4619   __ Cbz(r0, &l[23]);
4620   __ Cbz(r0, &l[27]);
4621   __ Cbz(r0, &l[16]);
4622   __ Cbz(r0, &l[24]);
4623   __ Cbz(r0, &l[17]);
4624   __ Cbz(r0, &l[4]);
4625   __ Cbz(r0, &l[11]);
4626   __ Cbz(r0, &l[6]);
4627   __ Cbz(r0, &l[23]);
4628   __ Bind(&l[16]);
4629   __ Cbz(r0, &l[10]);
4630   __ Cbz(r0, &l[17]);
4631   __ Cbz(r0, &l[12]);
4632   __ And(r0, r0, r0);
4633   __ Cbz(r0, &l[11]);
4634   __ Cbz(r0, &l[17]);
4635   __ Cbz(r0, &l[1]);
4636   __ Cbz(r0, &l[3]);
4637   __ Cbz(r0, &l[18]);
4638   __ Bind(&l[4]);
4639   __ Cbz(r0, &l[31]);
4640   __ Cbz(r0, &l[25]);
4641   __ Cbz(r0, &l[22]);
4642   __ And(r0, r0, r0);
4643   __ Cbz(r0, &l[19]);
4644   __ Cbz(r0, &l[16]);
4645   __ Cbz(r0, &l[21]);
4646   __ Cbz(r0, &l[27]);
4647   __ Bind(&l[1]);
4648   __ Cbz(r0, &l[9]);
4649   __ Cbz(r0, &l[13]);
4650   __ Cbz(r0, &l[10]);
4651   __ Cbz(r0, &l[6]);
4652   __ Cbz(r0, &l[30]);
4653   __ Cbz(r0, &l[28]);
4654   __ Cbz(r0, &l[7]);
4655   __ Cbz(r0, &l[17]);
4656   __ Bind(&l[0]);
4657   __ Cbz(r0, &l[13]);
4658   __ Cbz(r0, &l[11]);
4659   __ Cbz(r0, &l[19]);
4660   __ Cbz(r0, &l[22]);
4661   __ Cbz(r0, &l[9]);
4662   __ And(r0, r0, r0);
4663   __ Cbz(r0, &l[15]);
4664   __ Cbz(r0, &l[31]);
4665   __ Cbz(r0, &l[2]);
4666   __ And(r0, r0, r0);
4667   __ Cbz(r0, &l[6]);
4668   __ Bind(&l[27]);
4669   __ Bind(&l[13]);
4670   __ Cbz(r0, &l[23]);
4671   __ Cbz(r0, &l[7]);
4672   __ Bind(&l[2]);
4673   __ And(r0, r0, r0);
4674   __ Cbz(r0, &l[1]);
4675   __ Bind(&l[15]);
4676   __ Cbz(r0, &l[13]);
4677   __ Cbz(r0, &l[17]);
4678   __ Cbz(r0, &l[8]);
4679   __ Cbz(r0, &l[30]);
4680   __ Cbz(r0, &l[8]);
4681   __ Cbz(r0, &l[27]);
4682   __ Cbz(r0, &l[2]);
4683   __ Cbz(r0, &l[31]);
4684   __ Cbz(r0, &l[4]);
4685   __ Cbz(r0, &l[11]);
4686   __ Bind(&l[29]);
4687   __ Cbz(r0, &l[7]);
4688   __ Cbz(r0, &l[5]);
4689   __ Cbz(r0, &l[11]);
4690   __ Cbz(r0, &l[24]);
4691   __ Cbz(r0, &l[9]);
4692   __ Cbz(r0, &l[3]);
4693   __ Cbz(r0, &l[3]);
4694   __ Cbz(r0, &l[22]);
4695   __ Cbz(r0, &l[19]);
4696   __ Cbz(r0, &l[4]);
4697   __ Bind(&l[6]);
4698   __ And(r0, r0, r0);
4699   __ And(r0, r0, r0);
4700   __ Cbz(r0, &l[9]);
4701   __ Cbz(r0, &l[3]);
4702   __ Cbz(r0, &l[23]);
4703   __ Cbz(r0, &l[12]);
4704   __ Cbz(r0, &l[1]);
4705   __ Cbz(r0, &l[22]);
4706   __ Cbz(r0, &l[24]);
4707   __ And(r0, r0, r0);
4708   __ Cbz(r0, &l[16]);
4709   __ Cbz(r0, &l[19]);
4710   __ Cbz(r0, &l[20]);
4711   __ Cbz(r0, &l[1]);
4712   __ Cbz(r0, &l[4]);
4713   __ Cbz(r0, &l[1]);
4714   __ Cbz(r0, &l[25]);
4715   __ Cbz(r0, &l[21]);
4716   __ Cbz(r0, &l[20]);
4717   __ Cbz(r0, &l[29]);
4718   __ And(r0, r0, r0);
4719   __ Cbz(r0, &l[10]);
4720   __ Cbz(r0, &l[5]);
4721   __ And(r0, r0, r0);
4722   __ Cbz(r0, &l[25]);
4723   __ Cbz(r0, &l[26]);
4724   __ Cbz(r0, &l[28]);
4725   __ Cbz(r0, &l[19]);
4726   __ And(r0, r0, r0);
4727   __ Bind(&l[17]);
4728   __ And(r0, r0, r0);
4729   __ And(r0, r0, r0);
4730   __ And(r0, r0, r0);
4731   __ And(r0, r0, r0);
4732   __ Cbz(r0, &l[6]);
4733   __ And(r0, r0, r0);
4734   __ Cbz(r0, &l[5]);
4735   __ Cbz(r0, &l[26]);
4736   __ Cbz(r0, &l[28]);
4737   __ Cbz(r0, &l[24]);
4738   __ Bind(&l[20]);
4739   __ And(r0, r0, r0);
4740   __ Cbz(r0, &l[10]);
4741   __ Cbz(r0, &l[19]);
4742   __ Cbz(r0, &l[6]);
4743   __ And(r0, r0, r0);
4744   __ Cbz(r0, &l[13]);
4745   __ Cbz(r0, &l[15]);
4746   __ Cbz(r0, &l[22]);
4747   __ Cbz(r0, &l[8]);
4748   __ Cbz(r0, &l[6]);
4749   __ Cbz(r0, &l[23]);
4750   __ Cbz(r0, &l[6]);
4751   __ And(r0, r0, r0);
4752   __ Cbz(r0, &l[13]);
4753   __ Bind(&l[31]);
4754   __ Cbz(r0, &l[14]);
4755   __ Cbz(r0, &l[5]);
4756   __ Cbz(r0, &l[1]);
4757   __ Cbz(r0, &l[17]);
4758   __ Cbz(r0, &l[27]);
4759   __ Cbz(r0, &l[10]);
4760   __ Cbz(r0, &l[30]);
4761   __ Cbz(r0, &l[14]);
4762   __ Cbz(r0, &l[24]);
4763   __ Cbz(r0, &l[26]);
4764   __ And(r0, r0, r0);
4765   __ Cbz(r0, &l[2]);
4766   __ Cbz(r0, &l[21]);
4767   __ Cbz(r0, &l[5]);
4768   __ Cbz(r0, &l[24]);
4769   __ And(r0, r0, r0);
4770   __ Cbz(r0, &l[24]);
4771   __ Cbz(r0, &l[17]);
4772   __ And(r0, r0, r0);
4773   __ And(r0, r0, r0);
4774   __ Cbz(r0, &l[24]);
4775   __ And(r0, r0, r0);
4776   __ Cbz(r0, &l[17]);
4777   __ Cbz(r0, &l[12]);
4778   __ And(r0, r0, r0);
4779   __ Cbz(r0, &l[9]);
4780   __ Cbz(r0, &l[9]);
4781   __ Cbz(r0, &l[31]);
4782   __ Cbz(r0, &l[25]);
4783   __ And(r0, r0, r0);
4784   __ And(r0, r0, r0);
4785   __ Cbz(r0, &l[13]);
4786   __ Cbz(r0, &l[14]);
4787   __ Cbz(r0, &l[5]);
4788   __ Cbz(r0, &l[5]);
4789   __ Cbz(r0, &l[12]);
4790   __ Cbz(r0, &l[3]);
4791   __ Cbz(r0, &l[25]);
4792   __ Bind(&l[11]);
4793   __ Cbz(r0, &l[15]);
4794   __ Cbz(r0, &l[20]);
4795   __ Cbz(r0, &l[22]);
4796   __ Cbz(r0, &l[19]);
4797   __ And(r0, r0, r0);
4798   __ Cbz(r0, &l[19]);
4799   __ And(r0, r0, r0);
4800   __ Cbz(r0, &l[21]);
4801   __ Cbz(r0, &l[0]);
4802   __ And(r0, r0, r0);
4803   __ Cbz(r0, &l[16]);
4804   __ Cbz(r0, &l[28]);
4805   __ Cbz(r0, &l[18]);
4806   __ Cbz(r0, &l[3]);
4807   __ And(r0, r0, r0);
4808   __ Cbz(r0, &l[15]);
4809   __ Cbz(r0, &l[8]);
4810   __ Cbz(r0, &l[25]);
4811   __ Cbz(r0, &l[1]);
4812   __ Cbz(r0, &l[21]);
4813   __ Cbz(r0, &l[1]);
4814   __ Cbz(r0, &l[29]);
4815   __ Cbz(r0, &l[15]);
4816   __ And(r0, r0, r0);
4817   __ Cbz(r0, &l[24]);
4818   __ Cbz(r0, &l[3]);
4819   __ Cbz(r0, &l[9]);
4820   __ Cbz(r0, &l[9]);
4821   __ Cbz(r0, &l[24]);
4822   __ And(r0, r0, r0);
4823   __ Cbz(r0, &l[19]);
4824   __ And(r0, r0, r0);
4825   __ Cbz(r0, &l[30]);
4826   __ Bind(&l[25]);
4827   __ Bind(&l[3]);
4828   __ Bind(&l[30]);
4829   __ Bind(&l[5]);
4830 
4831   END();
4832 }
4833 
4834 
4835 // Generate a "B" and a "Cbz" which have the same checkpoint. Without proper
4836 // management (i.e. if the veneers were only generated at the shared
4837 // checkpoint), one one of the branches would be out of range.
TEST_T32(veneer_simultaneous)4838 TEST_T32(veneer_simultaneous) {
4839   SETUP();
4840 
4841   START();
4842 
4843   // `2046` max range - the size of the B.EQ itself.
4844   static const int kMaxBCondRange = 1048574;
4845 
4846   Label target_1;
4847   Label target_2;
4848 
4849   __ B(eq, &target_1);
4850 
4851   int target_1_size_1 =
4852       kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
4853   int end_1 = masm.GetCursorOffset() + target_1_size_1;
4854   while (masm.GetCursorOffset() < end_1) {
4855     __ Nop();
4856   }
4857 
4858   __ Cbz(r0, &target_2);
4859 
4860   int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
4861   int end_2 = masm.GetCursorOffset() + target_1_size_2;
4862   while (masm.GetCursorOffset() < end_2) {
4863     __ Nop();
4864   }
4865 
4866   __ Nop();
4867 
4868   __ Bind(&target_1);
4869   __ Bind(&target_2);
4870 
4871   END();
4872 }
4873 
4874 
4875 // Generate a "B" and a "Cbz" which have the same checkpoint and the same label.
TEST_T32(veneer_simultaneous_one_label)4876 TEST_T32(veneer_simultaneous_one_label) {
4877   SETUP();
4878 
4879   START();
4880 
4881   // `2046` max range - the size of the B.EQ itself.
4882   static const int kMaxBCondRange = 1048574;
4883 
4884   Label target;
4885 
4886   __ B(eq, &target);
4887 
4888   int target_1_size_1 =
4889       kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
4890   int end_1 = masm.GetCursorOffset() + target_1_size_1;
4891   while (masm.GetCursorOffset() < end_1) {
4892     __ Nop();
4893   }
4894 
4895   __ Cbz(r0, &target);
4896 
4897   int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
4898   int end_2 = masm.GetCursorOffset() + target_1_size_2;
4899   while (masm.GetCursorOffset() < end_2) {
4900     __ Nop();
4901   }
4902 
4903   __ Nop();
4904 
4905   __ Bind(&target);
4906 
4907   END();
4908 }
4909 
4910 // NOTE: This test has needed modifications for the new pool manager, as it
4911 // was testing a corner case of the previous pool managers. We keep it as
4912 // another testcase.
TEST_T32(veneer_and_literal)4913 TEST_T32(veneer_and_literal) {
4914   SETUP();
4915 
4916   START();
4917 
4918   VIXL_CHECK(test.PoolIsEmpty());
4919 
4920   const uint32_t ldrd_range = 1020;
4921   const uint32_t cbz_range = 126;
4922   const uint32_t kLabelsCount = 20;
4923   Label labels[kLabelsCount];
4924 
4925   // Create one literal pool entry.
4926   __ Ldrd(r0, r1, 0x1234567890abcdef);
4927 
4928   // Generate some nops.
4929   uint32_t i = 0;
4930   for (; i < ldrd_range - cbz_range - 40;
4931        i += k16BitT32InstructionSizeInBytes) {
4932     __ Nop();
4933   }
4934 
4935   // At this point, it remains cbz_range + 40 => 166 bytes before ldrd becomes
4936   // out of range.
4937   // We generate kLabelsCount * 4 => 80 bytes. We shouldn't generate the
4938   // literal pool.
4939   for (uint32_t j = 0; j < kLabelsCount; j++) {
4940     __ Cbz(r0, &labels[j]);
4941     __ Nop();
4942     i += 2 * k16BitT32InstructionSizeInBytes;
4943   }
4944 
4945   // We generate a few more instructions.
4946   for (; i < ldrd_range - 4 * kA32InstructionSizeInBytes;
4947        i += k16BitT32InstructionSizeInBytes) {
4948     __ Nop();
4949   }
4950 
4951   // Bind all the used labels.
4952   for (uint32_t j = 0; j < kLabelsCount; j++) {
4953     __ Bind(&labels[j]);
4954     __ Nop();
4955   }
4956 
4957   // Now that all the labels have been bound, we have no more veneers.
4958   VIXL_CHECK(test.PoolIsEmpty());
4959 
4960   END();
4961 
4962   RUN();
4963 
4964   // Check that the literals loaded correctly.
4965   ASSERT_EQUAL_32(0x90abcdef, r0);
4966   ASSERT_EQUAL_32(0x12345678, r1);
4967 }
4968 
4969 // NOTE: This test has needed modifications for the new pool manager, as it
4970 // was testing a corner case of the previous pool managers. We keep it as
4971 // another testcase.
TEST_T32(veneer_and_literal2)4972 TEST_T32(veneer_and_literal2) {
4973   SETUP();
4974 
4975   START();
4976 
4977   VIXL_CHECK(test.PoolIsEmpty());
4978 
4979   const uint32_t ldrd_range = 1020;
4980   const uint32_t cbz_range = 126;
4981   const uint32_t kLabelsCount = 20;
4982   const int32_t kTypicalMacroInstructionMaxSize =
4983       8 * kMaxInstructionSizeInBytes;
4984   Label labels[kLabelsCount];
4985 
4986   // Create one literal pool entry.
4987   __ Ldrd(r0, r1, 0x1234567890abcdef);
4988 
4989   for (uint32_t i = 0; i < ldrd_range - cbz_range - 4 * kLabelsCount;
4990        i += k16BitT32InstructionSizeInBytes) {
4991     __ Nop();
4992   }
4993 
4994   // Add entries to the veneer pool.
4995   for (uint32_t i = 0; i < kLabelsCount; i++) {
4996     __ Cbz(r0, &labels[i]);
4997     __ Nop();
4998   }
4999 
5000   // Generate nops up to the literal pool limit.
5001   while (test.GetPoolCheckpoint() - masm.GetCursorOffset() >=
5002          kTypicalMacroInstructionMaxSize) {
5003     __ Nop();
5004   }
5005 
5006   // At this point, no literals and no veneers have been generated.
5007   VIXL_ASSERT(!test.PoolIsEmpty());
5008   // The literal pool needs to be generated.
5009   VIXL_ASSERT(test.GetPoolCheckpoint() - masm.GetCursorOffset() <
5010               kTypicalMacroInstructionMaxSize);
5011 
5012   // This extra Nop will generate the pools.
5013   __ Nop();
5014 
5015   // Bind all the used labels.
5016   for (uint32_t j = 0; j < kLabelsCount; j++) {
5017     __ Bind(&labels[j]);
5018     __ Nop();
5019   }
5020 
5021   // Now that all the labels have been bound, we have no more veneers.
5022   VIXL_CHECK(test.PoolIsEmpty());
5023 
5024   END();
5025 
5026   RUN();
5027 
5028   // Check that the literals loaded correctly.
5029   ASSERT_EQUAL_32(0x90abcdef, r0);
5030   ASSERT_EQUAL_32(0x12345678, r1);
5031 }
5032 
5033 
5034 // Use a literal when we already have a veneer pool potential size greater than
5035 // the literal range => generate the literal immediately (not optimum but it
5036 // works).
TEST_T32(veneer_and_literal3)5037 TEST_T32(veneer_and_literal3) {
5038   SETUP();
5039 
5040   START();
5041 
5042   static const int kLabelsCount = 1000;
5043 
5044   Label labels[kLabelsCount];
5045 
5046   // Set the Z flag so that the following branches are not taken.
5047   __ Movs(r0, 0);
5048 
5049   for (int i = 0; i < kLabelsCount; i++) {
5050     __ B(ne, &labels[i]);
5051   }
5052 
5053   // Create one literal pool entry.
5054   __ Ldrd(r0, r1, 0x1234567890abcdef);
5055 
5056   for (int i = 0; i < 10; i++) {
5057     __ Nop();
5058   }
5059 
5060   for (int i = 0; i < kLabelsCount; i++) {
5061     __ Bind(&labels[i]);
5062   }
5063 
5064   END();
5065 
5066   RUN();
5067 
5068   // Check that the literals loaded correctly.
5069   ASSERT_EQUAL_32(0x90abcdef, r0);
5070   ASSERT_EQUAL_32(0x12345678, r1);
5071 }
5072 
5073 
5074 // Literal has to be generated sooner than veneers. However, as the literal
5075 // pool generation would make the veneers out of range, generate the veneers
5076 // first.
TEST_T32(veneer_and_literal4)5077 TEST_T32(veneer_and_literal4) {
5078   SETUP();
5079 
5080   START();
5081 
5082   Label end;
5083 
5084   // Set the Z flag so that the following branch is not taken.
5085   __ Movs(r0, 0);
5086   __ B(ne, &end);
5087 
5088   uint32_t value = 0x1234567;
5089   Literal<uint32_t>* literal =
5090       new Literal<uint32_t>(value,
5091                             RawLiteral::kPlacedWhenUsed,
5092                             RawLiteral::kDeletedOnPoolDestruction);
5093 
5094   __ Ldr(r11, literal);
5095 
5096   // The range for ldr is 4095, the range for cbz is 127. Generate nops
5097   // to have the ldr becomming out of range just before the cbz.
5098   const int NUM_NOPS = 2044;
5099   const int NUM_RANGE = 58;
5100 
5101   const int NUM1 = NUM_NOPS - NUM_RANGE;
5102   const int NUM2 = NUM_RANGE;
5103 
5104   {
5105     ExactAssemblyScope aas(&masm, 2 * NUM1, CodeBufferCheckScope::kMaximumSize);
5106     for (int i = 0; i < NUM1; i++) {
5107       __ nop();
5108     }
5109   }
5110 
5111   __ Cbz(r1, &end);
5112 
5113   {
5114     ExactAssemblyScope aas(&masm, 2 * NUM2, CodeBufferCheckScope::kMaximumSize);
5115     for (int i = 0; i < NUM2; i++) {
5116       __ nop();
5117     }
5118   }
5119 
5120   {
5121     ExactAssemblyScope aas(&masm, 4, CodeBufferCheckScope::kMaximumSize);
5122     __ add(r1, r1, 3);
5123   }
5124   __ Bind(&end);
5125 
5126   END();
5127 
5128   RUN();
5129 
5130   // Check that the literals loaded correctly.
5131   ASSERT_EQUAL_32(0x1234567, r11);
5132 }
5133 
5134 
5135 // Literal has to be generated sooner than veneers. However, as the literal
5136 // pool generation would make the veneers out of range, generate the veneers
5137 // first.
TEST_T32(veneer_and_literal5)5138 TEST_T32(veneer_and_literal5) {
5139   SETUP();
5140 
5141   START();
5142 
5143   static const int kTestCount = 100;
5144   Label labels[kTestCount];
5145 
5146   int first_test = 2000;
5147   // Test on both sizes of the Adr range which is 4095.
5148   for (int test = 0; test < kTestCount; test++) {
5149     const int string_size = 1000;  // A lot more than the cbz range.
5150     std::string test_string(string_size, 'x');
5151     StringLiteral big_literal(test_string.c_str());
5152 
5153     __ Adr(r11, &big_literal);
5154 
5155     {
5156       int num_nops = first_test + test;
5157       ExactAssemblyScope aas(&masm,
5158                              2 * num_nops,
5159                              CodeBufferCheckScope::kMaximumSize);
5160       for (int i = 0; i < num_nops; i++) {
5161         __ nop();
5162       }
5163     }
5164 
5165     __ Cbz(r1, &labels[test]);
5166 
5167     {
5168       ExactAssemblyScope aas(&masm, 4, CodeBufferCheckScope::kMaximumSize);
5169       __ add(r1, r1, 3);
5170     }
5171     __ Bind(&labels[test]);
5172     // Emit the literal pool if it has not beeen emitted (it's the case for
5173     // the lower values of test).
5174     __ EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
5175   }
5176 
5177   END();
5178 }
5179 
5180 // Check that veneer and literals are well generated when they are out of
5181 // range at the same time.
TEST_T32(veneer_and_literal6)5182 TEST_T32(veneer_and_literal6) {
5183   SETUP();
5184 
5185   START();
5186 
5187   Label t1, t2, t3, t4, t5;
5188   static const int kLdrdRange = 1020;
5189   static const int kSizeForCbz = k16BitT32InstructionSizeInBytes;
5190 
5191   __ Ldrd(r0, r1, 0x1111111111111111);
5192   __ Ldrd(r2, r3, 0x2222222222222222);
5193   __ Ldrd(r4, r5, 0x3333333333333333);
5194   __ Ldrd(r6, r7, 0x4444444444444444);
5195   __ Ldrd(r8, r9, 0x5555555555555555);
5196   __ Ldrd(r10, r11, 0x6666666666666666);
5197   __ Ldrd(r10, r11, 0x1234567890abcdef);
5198 
5199   // Ldrd has a bigger range that cbz. Generate some nops before the cbzs in
5200   // order to reach the maximum range of ldrd and cbz at the same time.
5201   {
5202     int nop_size = kLdrdRange - kCbzCbnzRange - 5 * kSizeForCbz;
5203     ExactAssemblyScope scope(&masm, nop_size, CodeBufferCheckScope::kExactSize);
5204     for (int i = 0; i < nop_size; i += k16BitT32InstructionSizeInBytes) {
5205       __ nop();
5206     }
5207   }
5208 
5209   __ Cbz(r2, &t1);
5210   __ Cbz(r2, &t2);
5211   __ Cbz(r2, &t3);
5212   __ Cbz(r2, &t4);
5213   __ Cbz(r2, &t5);
5214 
5215   // At this point, the ldrds are not out of range. It remains a kCbzCbnzRange
5216   // margin (minus the size of the veneers).
5217 
5218   // At this point, the literal and the veneer pools are not emitted.
5219   const int kLdrdLiteralSize = 8;
5220   const int kVeneerSize = 4;
5221   CHECK_POOL_SIZE(7 * kLdrdLiteralSize + 5 * kVeneerSize);
5222   VIXL_CHECK(test.GetPoolCheckpoint() - masm.GetCursorOffset() < kCbzCbnzRange);
5223 
5224   // This scope will generate both veneers (they are both out of range).
5225   {
5226     int nop_size = kCbzCbnzRange;
5227     ExactAssemblyScope scope(&masm, nop_size, CodeBufferCheckScope::kExactSize);
5228     for (int i = 0; i < nop_size; i += k16BitT32InstructionSizeInBytes) {
5229       __ nop();
5230     }
5231   }
5232 
5233   // Check that both literals and veneers have been emitted.
5234   CHECK_POOL_SIZE(5 * kVeneerSize);
5235   VIXL_CHECK(test.GetPoolCheckpoint() - masm.GetCursorOffset() > kCbzCbnzRange);
5236 
5237   __ Bind(&t1);
5238   __ Bind(&t2);
5239   __ Bind(&t3);
5240   __ Bind(&t4);
5241   __ Bind(&t5);
5242 
5243   CHECK_POOL_SIZE(0);
5244 
5245   END();
5246 
5247   RUN();
5248 
5249   // Check that the literals loaded correctly.
5250   ASSERT_EQUAL_32(0x11111111, r0);
5251   ASSERT_EQUAL_32(0x11111111, r1);
5252   ASSERT_EQUAL_32(0x22222222, r2);
5253   ASSERT_EQUAL_32(0x22222222, r3);
5254   ASSERT_EQUAL_32(0x33333333, r4);
5255   ASSERT_EQUAL_32(0x33333333, r5);
5256   ASSERT_EQUAL_32(0x44444444, r6);
5257   ASSERT_EQUAL_32(0x44444444, r7);
5258   ASSERT_EQUAL_32(0x55555555, r8);
5259   ASSERT_EQUAL_32(0x55555555, r9);
5260   ASSERT_EQUAL_32(0x90abcdef, r10);
5261   ASSERT_EQUAL_32(0x12345678, r11);
5262 }
5263 
5264 // Check that a label which is just bound during the MacroEmissionCheckScope
5265 // can be used.
TEST(ldr_label_bound_during_scope)5266 TEST(ldr_label_bound_during_scope) {
5267   SETUP();
5268   START();
5269 
5270   Literal<uint64_t>* literal =
5271       new Literal<uint64_t>(UINT64_C(0x1234567890abcdef),
5272                             RawLiteral::kPlacedWhenUsed,
5273                             RawLiteral::kDeletedOnPoolDestruction);
5274   __ Ldrd(r0, r1, literal);
5275 
5276   const int nop_size = masm.IsUsingA32() ? 4 : 2;
5277   while (test.GetPoolCheckpoint() >=
5278          (masm.GetCursorOffset() +
5279           static_cast<int32_t>(kMaxInstructionSizeInBytes))) {
5280     ExactAssemblyScope scope(&masm, nop_size, ExactAssemblyScope::kExactSize);
5281     __ nop();
5282   }
5283 
5284   VIXL_ASSERT(!test.PoolIsEmpty());
5285 
5286   // This Ldrd will first generate the pool and then use literal which has just
5287   // been bound.
5288   __ Ldrd(r2, r3, literal);
5289 
5290   VIXL_ASSERT(test.PoolIsEmpty());
5291 
5292   END();
5293 
5294   RUN();
5295 
5296   // Check that the literals loaded correctly.
5297   ASSERT_EQUAL_32(0x90abcdef, r0);
5298   ASSERT_EQUAL_32(0x12345678, r1);
5299   ASSERT_EQUAL_32(0x90abcdef, r2);
5300   ASSERT_EQUAL_32(0x12345678, r3);
5301 }
5302 
5303 
TEST_T32(test_it_scope_and_literal_pool)5304 TEST_T32(test_it_scope_and_literal_pool) {
5305   // This test stresses the ITScope to make sure the number of bytes it tries
5306   // to emit is in sync with the MacroEmissionCheckScope that is around it.
5307   SETUP();
5308 
5309   START();
5310 
5311   // Make sure the pool is empty.
5312   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
5313   VIXL_CHECK(test.PoolIsEmpty());
5314 
5315   Literal<uint64_t> l0(0xcafebeefdeadbaba);
5316   __ Ldrd(r0, r1, &l0);
5317   // Leave exactly as many bytes between cursor and pool emission checkpoint as
5318   // the typical macro instruction needs (and MacroEmissionCheckScope allows
5319   // for).
5320   const int32_t kTypicalMacroInstructionMaxSize =
5321       8 * kMaxInstructionSizeInBytes;
5322   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset() -
5323                    kTypicalMacroInstructionMaxSize;
5324   int32_t end = masm.GetCursorOffset() + margin;
5325 
5326   {
5327     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
5328     while (masm.GetCursorOffset() < end) {
5329       __ nop();
5330     }
5331   }
5332   VIXL_CHECK((test.GetPoolCheckpoint() - masm.GetCursorOffset()) ==
5333              kTypicalMacroInstructionMaxSize);
5334 
5335   // We cannot use an IT block for this instruction, hence ITScope will
5336   // generate a branch over it.
5337   __ Add(ne, r8, r9, 256);
5338 
5339   END();
5340 
5341   RUN();
5342 
5343   // Check that the literals loaded correctly.
5344   ASSERT_EQUAL_32(0xdeadbaba, r0);
5345   ASSERT_EQUAL_32(0xcafebeef, r1);
5346 }
5347 
5348 
5349 // TODO: Remove this limitation by having a sandboxing mechanism.
5350 #if defined(VIXL_HOST_POINTER_32)
TEST(ldm_stm_no_writeback)5351 TEST(ldm_stm_no_writeback) {
5352   SETUP();
5353 
5354   START();
5355 
5356   const uint32_t src[4] = {0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef};
5357   uint32_t dst1[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5358   uint32_t dst2[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5359 
5360   __ Mov(r0, reinterpret_cast<uintptr_t>(src));
5361   __ Ldm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));
5362   __ Ldm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
5363 
5364   __ Mov(r0, reinterpret_cast<uintptr_t>(dst1));
5365   __ Stm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));
5366 
5367   __ Mov(r0, reinterpret_cast<uintptr_t>(dst2));
5368   __ Stm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
5369 
5370   END();
5371 
5372   RUN();
5373 
5374   ASSERT_EQUAL_32(0x12345678, r1);
5375   ASSERT_EQUAL_32(0x09abcdef, r2);
5376   ASSERT_EQUAL_32(0xc001c0de, r3);
5377   ASSERT_EQUAL_32(0xdeadbeef, r4);
5378 
5379   ASSERT_EQUAL_32(0x12345678, r5);
5380   ASSERT_EQUAL_32(0x09abcdef, r6);
5381   ASSERT_EQUAL_32(0xc001c0de, r9);
5382   ASSERT_EQUAL_32(0xdeadbeef, r11);
5383 
5384   ASSERT_EQUAL_32(0x12345678, dst1[0]);
5385   ASSERT_EQUAL_32(0x09abcdef, dst1[1]);
5386   ASSERT_EQUAL_32(0xc001c0de, dst1[2]);
5387   ASSERT_EQUAL_32(0xdeadbeef, dst1[3]);
5388 
5389   ASSERT_EQUAL_32(0x12345678, dst2[0]);
5390   ASSERT_EQUAL_32(0x09abcdef, dst2[1]);
5391   ASSERT_EQUAL_32(0xc001c0de, dst2[2]);
5392   ASSERT_EQUAL_32(0xdeadbeef, dst2[3]);
5393 }
5394 
5395 
TEST(ldm_stm_writeback)5396 TEST(ldm_stm_writeback) {
5397   SETUP();
5398 
5399   START();
5400 
5401   const uint32_t src[4] = {0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef};
5402   uint32_t dst[8] = {0x00000000,
5403                      0x00000000,
5404                      0x00000000,
5405                      0x00000000,
5406                      0x00000000,
5407                      0x00000000,
5408                      0x00000000,
5409                      0x00000000};
5410 
5411   __ Mov(r0, reinterpret_cast<uintptr_t>(src));
5412   __ Ldm(r0, WRITE_BACK, RegisterList(r2, r3));
5413   __ Ldm(r0, WRITE_BACK, RegisterList(r4, r5));
5414 
5415   __ Mov(r1, reinterpret_cast<uintptr_t>(dst));
5416   __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
5417   __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
5418 
5419   END();
5420 
5421   RUN();
5422 
5423   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 4), r0);
5424   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 8), r1);
5425 
5426   ASSERT_EQUAL_32(0x12345678, r2);
5427   ASSERT_EQUAL_32(0x09abcdef, r3);
5428   ASSERT_EQUAL_32(0xc001c0de, r4);
5429   ASSERT_EQUAL_32(0xdeadbeef, r5);
5430 
5431   ASSERT_EQUAL_32(0x12345678, dst[0]);
5432   ASSERT_EQUAL_32(0x09abcdef, dst[1]);
5433   ASSERT_EQUAL_32(0xc001c0de, dst[2]);
5434   ASSERT_EQUAL_32(0xdeadbeef, dst[3]);
5435   ASSERT_EQUAL_32(0x12345678, dst[4]);
5436   ASSERT_EQUAL_32(0x09abcdef, dst[5]);
5437   ASSERT_EQUAL_32(0xc001c0de, dst[6]);
5438   ASSERT_EQUAL_32(0xdeadbeef, dst[7]);
5439 }
5440 
5441 
TEST_A32(ldm_stm_da_ib)5442 TEST_A32(ldm_stm_da_ib) {
5443   SETUP();
5444 
5445   START();
5446 
5447   const uint32_t src1[4] = {0x33333333, 0x44444444, 0x11111111, 0x22222222};
5448   const uint32_t src2[4] = {0x11111111, 0x22222222, 0x33333333, 0x44444444};
5449 
5450   uint32_t dst1[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5451   uint32_t dst2[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5452 
5453   __ Mov(r11, reinterpret_cast<uintptr_t>(src1 + 3));
5454   __ Ldmda(r11, WRITE_BACK, RegisterList(r0, r1));
5455   __ Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3));
5456 
5457   __ Mov(r10, reinterpret_cast<uintptr_t>(src2) - sizeof(src2[0]));
5458   __ Ldmib(r10, WRITE_BACK, RegisterList(r4, r5));
5459   __ Ldmib(r10, NO_WRITE_BACK, RegisterList(r6, r7));
5460 
5461   __ Mov(r9, reinterpret_cast<uintptr_t>(dst1 + 3));
5462   __ Stmda(r9, WRITE_BACK, RegisterList(r0, r1));
5463   __ Stmda(r9, NO_WRITE_BACK, RegisterList(r2, r3));
5464 
5465   __ Mov(r8, reinterpret_cast<uintptr_t>(dst2) - sizeof(dst2[0]));
5466   __ Stmib(r8, WRITE_BACK, RegisterList(r4, r5));
5467   __ Stmib(r8, NO_WRITE_BACK, RegisterList(r6, r7));
5468 
5469 
5470   END();
5471 
5472   RUN();
5473 
5474   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src1 + 1), r11);
5475   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src2 + 1), r10);
5476   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst1 + 1), r9);
5477   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst2 + 1), r8);
5478 
5479   ASSERT_EQUAL_32(0x11111111, r0);
5480   ASSERT_EQUAL_32(0x22222222, r1);
5481   ASSERT_EQUAL_32(0x33333333, r2);
5482   ASSERT_EQUAL_32(0x44444444, r3);
5483 
5484   ASSERT_EQUAL_32(0x11111111, r4);
5485   ASSERT_EQUAL_32(0x22222222, r5);
5486   ASSERT_EQUAL_32(0x33333333, r6);
5487   ASSERT_EQUAL_32(0x44444444, r7);
5488 
5489   ASSERT_EQUAL_32(0x33333333, dst1[0]);
5490   ASSERT_EQUAL_32(0x44444444, dst1[1]);
5491   ASSERT_EQUAL_32(0x11111111, dst1[2]);
5492   ASSERT_EQUAL_32(0x22222222, dst1[3]);
5493 
5494   ASSERT_EQUAL_32(0x11111111, dst2[0]);
5495   ASSERT_EQUAL_32(0x22222222, dst2[1]);
5496   ASSERT_EQUAL_32(0x33333333, dst2[2]);
5497   ASSERT_EQUAL_32(0x44444444, dst2[3]);
5498 }
5499 
5500 
TEST(ldmdb_stmdb)5501 TEST(ldmdb_stmdb) {
5502   SETUP();
5503 
5504   START();
5505 
5506   const uint32_t src[6] =
5507       {0x55555555, 0x66666666, 0x33333333, 0x44444444, 0x11111111, 0x22222222};
5508 
5509   uint32_t dst[6] =
5510       {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
5511 
5512   __ Mov(r11, reinterpret_cast<uintptr_t>(src + 6));
5513   __ Ldmdb(r11, WRITE_BACK, RegisterList(r1, r2));
5514   __ Ldmdb(r11, WRITE_BACK, RegisterList(r3, r4));
5515   __ Ldmdb(r11, NO_WRITE_BACK, RegisterList(r5, r6));
5516 
5517   __ Mov(r10, reinterpret_cast<uintptr_t>(dst + 6));
5518   __ Stmdb(r10, WRITE_BACK, RegisterList(r5, r6));
5519   __ Stmdb(r10, WRITE_BACK, RegisterList(r3, r4));
5520   __ Stmdb(r10, NO_WRITE_BACK, RegisterList(r1, r2));
5521 
5522   END();
5523 
5524   RUN();
5525 
5526   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 2), r11);
5527   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 2), r10);
5528 
5529   ASSERT_EQUAL_32(0x11111111, r1);
5530   ASSERT_EQUAL_32(0x22222222, r2);
5531   ASSERT_EQUAL_32(0x33333333, r3);
5532   ASSERT_EQUAL_32(0x44444444, r4);
5533   ASSERT_EQUAL_32(0x55555555, r5);
5534   ASSERT_EQUAL_32(0x66666666, r6);
5535 
5536   ASSERT_EQUAL_32(0x11111111, dst[0]);
5537   ASSERT_EQUAL_32(0x22222222, dst[1]);
5538   ASSERT_EQUAL_32(0x33333333, dst[2]);
5539   ASSERT_EQUAL_32(0x44444444, dst[3]);
5540   ASSERT_EQUAL_32(0x55555555, dst[4]);
5541   ASSERT_EQUAL_32(0x66666666, dst[5]);
5542 }
5543 #endif
5544 
5545 
TEST(blx)5546 TEST(blx) {
5547   SETUP();
5548 
5549   START();
5550 
5551   // TODO(all): Ideally this test should jump back and forth between ARM and
5552   // Thumb mode and should also cover BLX immediate. Update this test if we
5553   // allow VIXL assembler to change ISA anywhere in the code buffer.
5554 
5555   Label test_start;
5556   Label func1;
5557   Label func2;
5558 
5559   __ B(&test_start);
5560 
5561   __ Bind(&func1);
5562   __ Mov(r0, 0x11111111);
5563   __ Push(lr);
5564   {
5565     size_t size_of_generated_code;
5566     if (masm.IsUsingA32()) {
5567       size_of_generated_code = 7 * kA32InstructionSizeInBytes;
5568     } else {
5569       size_of_generated_code = 5 * k32BitT32InstructionSizeInBytes +
5570                                3 * k16BitT32InstructionSizeInBytes;
5571     }
5572     ExactAssemblyScope scope(&masm,
5573                              size_of_generated_code,
5574                              ExactAssemblyScope::kExactSize);
5575     __ adr(r11, &func2);
5576     if (masm.IsUsingT32()) {
5577       // The jump target needs to have its least significant bit set to indicate
5578       // that we are jumping into thumb mode.
5579       __ orr(r11, r11, 1);
5580     }
5581     __ blx(r11);
5582     __ pop(lr);
5583     __ bx(lr);
5584 
5585     __ bind(&func2);
5586     __ movw(r1, 0x2222);
5587     __ movt(r1, 0x2222);
5588     __ bx(lr);
5589   }
5590 
5591   __ Bind(&test_start);
5592   __ Mov(r0, 0xdeadc0de);
5593   __ Mov(r1, 0xdeadc0de);
5594   __ Bl(&func1);
5595 
5596   END();
5597 
5598   RUN();
5599 
5600   // Really basic test to check that we reached the different parts of the test.
5601   ASSERT_EQUAL_32(0x11111111, r0);
5602   ASSERT_EQUAL_32(0x22222222, r1);
5603 }
5604 
5605 // Check that B with a near hint use a narrow branch when it can.
TEST_T32(b_near_hint)5606 TEST_T32(b_near_hint) {
5607   SETUP();
5608   START();
5609 
5610   Label start;
5611   Label end;
5612 
5613   __ Bind(&start);
5614   __ Nop();
5615 
5616   {
5617     // Generate a branch which should be narrow.
5618     EmissionCheckScope scope(&masm,
5619                              k16BitT32InstructionSizeInBytes,
5620                              EmissionCheckScope::kExactSize);
5621     __ B(&start, kNear);
5622   }
5623   {
5624     ExactAssemblyScope scope(&masm,
5625                              kBNarrowRange,
5626                              ExactAssemblyScope::kExactSize);
5627     for (int32_t i = 0; i < kBNarrowRange;
5628          i += k16BitT32InstructionSizeInBytes) {
5629       __ nop();
5630     }
5631   }
5632   {
5633     // Generate a branch which should be wide.
5634     EmissionCheckScope scope(&masm,
5635                              k32BitT32InstructionSizeInBytes,
5636                              EmissionCheckScope::kExactSize);
5637     __ B(&start, kNear);
5638   }
5639   {
5640     // Generate a forward branch which should be narrow.
5641     EmissionCheckScope scope(&masm,
5642                              k16BitT32InstructionSizeInBytes,
5643                              EmissionCheckScope::kExactSize);
5644     __ B(&end, kNear);
5645   }
5646 
5647   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
5648   VIXL_CHECK(margin < kBNarrowRange);
5649 
5650   {
5651     ExactAssemblyScope scope(&masm,
5652                              kBNarrowRange,
5653                              ExactAssemblyScope::kExactSize);
5654     for (int32_t i = 0; i < kBNarrowRange;
5655          i += k16BitT32InstructionSizeInBytes) {
5656       __ nop();
5657     }
5658   }
5659 
5660   // A veneer should have been generated.
5661   margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
5662   VIXL_CHECK(margin > kBNarrowRange);
5663 
5664   __ Bind(&end);
5665 
5666   END();
5667 
5668   DISASSEMBLE();
5669 }
5670 
5671 // Check that B with a far hint use a narrow branch only for a near backward
5672 // branch.
TEST_T32(b_far_hint)5673 TEST_T32(b_far_hint) {
5674   SETUP();
5675   START();
5676 
5677   Label start;
5678   Label end;
5679 
5680   __ Bind(&start);
5681   __ Nop();
5682 
5683   {
5684     // Generate a branch which should be narrow.
5685     EmissionCheckScope scope(&masm,
5686                              k16BitT32InstructionSizeInBytes,
5687                              EmissionCheckScope::kExactSize);
5688     __ B(&start, kFar);
5689   }
5690   {
5691     ExactAssemblyScope scope(&masm,
5692                              kBNarrowRange,
5693                              ExactAssemblyScope::kExactSize);
5694     for (int32_t i = 0; i < kBNarrowRange;
5695          i += k16BitT32InstructionSizeInBytes) {
5696       __ nop();
5697     }
5698   }
5699   {
5700     // Generate a branch which should be wide.
5701     EmissionCheckScope scope(&masm,
5702                              k32BitT32InstructionSizeInBytes,
5703                              EmissionCheckScope::kExactSize);
5704     __ B(&start, kFar);
5705   }
5706   {
5707     // Generate a forward branch which should be wide.
5708     EmissionCheckScope scope(&masm,
5709                              k32BitT32InstructionSizeInBytes,
5710                              EmissionCheckScope::kExactSize);
5711     __ B(&end, kFar);
5712   }
5713 
5714   __ Bind(&end);
5715 
5716   END();
5717 
5718   DISASSEMBLE();
5719 }
5720 
5721 // Check that conditional B with a near hint use a narrow branch when it can.
TEST_T32(b_conditional_near_hint)5722 TEST_T32(b_conditional_near_hint) {
5723   SETUP();
5724   START();
5725 
5726   Label start;
5727   Label end;
5728 
5729   __ Bind(&start);
5730   __ Nop();
5731   {
5732     // Generate a branch which should be narrow.
5733     EmissionCheckScope scope(&masm,
5734                              k16BitT32InstructionSizeInBytes,
5735                              EmissionCheckScope::kExactSize);
5736     __ B(eq, &start, kNear);
5737   }
5738   {
5739     ExactAssemblyScope scope(&masm,
5740                              kBConditionalNarrowRange,
5741                              ExactAssemblyScope::kExactSize);
5742     for (int32_t i = 0; i < kBConditionalNarrowRange;
5743          i += k16BitT32InstructionSizeInBytes) {
5744       __ nop();
5745     }
5746   }
5747   {
5748     // Generate a branch which should be wide.
5749     EmissionCheckScope scope(&masm,
5750                              k32BitT32InstructionSizeInBytes,
5751                              EmissionCheckScope::kExactSize);
5752     __ B(eq, &start, kNear);
5753   }
5754   {
5755     // Generate a forward branch which should be narrow.
5756     EmissionCheckScope scope(&masm,
5757                              k16BitT32InstructionSizeInBytes,
5758                              EmissionCheckScope::kExactSize);
5759     __ B(eq, &end, kNear);
5760   }
5761 
5762   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
5763   VIXL_CHECK(margin < kBConditionalNarrowRange);
5764 
5765   {
5766     ExactAssemblyScope scope(&masm,
5767                              kBConditionalNarrowRange,
5768                              ExactAssemblyScope::kExactSize);
5769     for (int32_t i = 0; i < kBConditionalNarrowRange;
5770          i += k16BitT32InstructionSizeInBytes) {
5771       __ nop();
5772     }
5773   }
5774 
5775   // A veneer should have been generated.
5776   margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
5777   VIXL_CHECK(margin > kBConditionalNarrowRange);
5778 
5779   __ Bind(&end);
5780 
5781   END();
5782 
5783   DISASSEMBLE();
5784 }
5785 
5786 // Check that conditional B with a far hint use a narrow branch only for a
5787 // near backward branch.
TEST_T32(b_conditional_far_hint)5788 TEST_T32(b_conditional_far_hint) {
5789   SETUP();
5790   START();
5791 
5792   Label start;
5793   Label end;
5794 
5795   __ Bind(&start);
5796   __ Nop();
5797 
5798   {
5799     // Generate a branch which should be narrow.
5800     EmissionCheckScope scope(&masm,
5801                              k16BitT32InstructionSizeInBytes,
5802                              EmissionCheckScope::kExactSize);
5803     __ B(eq, &start, kFar);
5804   }
5805   {
5806     ExactAssemblyScope scope(&masm,
5807                              kBConditionalNarrowRange,
5808                              ExactAssemblyScope::kExactSize);
5809     for (int32_t i = 0; i < kBConditionalNarrowRange;
5810          i += k16BitT32InstructionSizeInBytes) {
5811       __ nop();
5812     }
5813   }
5814   {
5815     // Generate a branch which should be wide.
5816     EmissionCheckScope scope(&masm,
5817                              k32BitT32InstructionSizeInBytes,
5818                              EmissionCheckScope::kExactSize);
5819     __ B(eq, &start, kFar);
5820   }
5821   {
5822     // Generate a forward branch which should be wide.
5823     EmissionCheckScope scope(&masm,
5824                              k32BitT32InstructionSizeInBytes,
5825                              EmissionCheckScope::kExactSize);
5826     __ B(eq, &end, kFar);
5827   }
5828 
5829   __ Bind(&end);
5830 
5831   END();
5832 
5833   DISASSEMBLE();
5834 }
5835 
5836 
5837 // Check that the veneer pool is correctly emitted even if we do a lot of narrow
5838 // branches.
TEST_T32(b_narrow_many)5839 TEST_T32(b_narrow_many) {
5840   SETUP();
5841   START();
5842 
5843   static const int kLabelsCount = kBNarrowRange / 2;
5844 
5845   Label labels[kLabelsCount];
5846 
5847   __ Mov(r0, 0);
5848 
5849   for (int i = 0; i < kLabelsCount; i++) {
5850     __ B(&labels[i], kNear);
5851   }
5852 
5853   __ Mov(r0, 1);
5854   for (int i = 0; i < kLabelsCount; i++) {
5855     __ Bind(&labels[i]);
5856   }
5857   __ Nop();
5858 
5859   END();
5860 
5861   RUN();
5862 
5863   ASSERT_EQUAL_32(0, r0);
5864 }
5865 
5866 
5867 // Check that the veneer pool is correctly emitted even if we do a lot of narrow
5868 // branches and cbz.
TEST_T32(b_narrow_and_cbz)5869 TEST_T32(b_narrow_and_cbz) {
5870   SETUP();
5871   START();
5872 
5873   static const int kLabelsCount = kBNarrowRange / 4;
5874 
5875   Label b_labels[kLabelsCount];
5876   Label cbz_labels[kLabelsCount];
5877 
5878   __ Mov(r0, 0);
5879 
5880   for (int i = 0; i < kLabelsCount; i++) {
5881     __ B(&b_labels[i], kNear);
5882     __ Cbz(r0, &cbz_labels[i]);
5883   }
5884 
5885   __ Mov(r0, 1);
5886   for (int i = 0; i < kLabelsCount; i++) {
5887     __ Bind(&b_labels[i]);
5888   }
5889 
5890   __ Mov(r0, 2);
5891   for (int i = 0; i < kLabelsCount; i++) {
5892     __ Bind(&cbz_labels[i]);
5893   }
5894 
5895   __ Nop();
5896 
5897   END();
5898 
5899   RUN();
5900 
5901   ASSERT_EQUAL_32(2, r0);
5902 }
5903 
5904 
5905 #define CHECK_SIZE_MATCH(ASM1, ASM2)                                 \
5906   {                                                                  \
5907     MacroAssembler masm1(BUF_SIZE);                                  \
5908     masm1.UseInstructionSet(isa);                                    \
5909     VIXL_ASSERT(masm1.GetCursorOffset() == 0);                       \
5910     masm1.ASM1;                                                      \
5911     masm1.FinalizeCode();                                            \
5912     int size1 = masm1.GetCursorOffset();                             \
5913                                                                      \
5914     MacroAssembler masm2(BUF_SIZE);                                  \
5915     masm2.UseInstructionSet(isa);                                    \
5916     VIXL_ASSERT(masm2.GetCursorOffset() == 0);                       \
5917     masm2.ASM2;                                                      \
5918     masm2.FinalizeCode();                                            \
5919     int size2 = masm2.GetCursorOffset();                             \
5920                                                                      \
5921     bool disassemble = Test::disassemble();                          \
5922     if (size1 != size2) {                                            \
5923       printf("Sizes did not match:\n");                              \
5924       disassemble = true;                                            \
5925     }                                                                \
5926     if (disassemble) {                                               \
5927       PrintDisassembler dis(std::cout, 0);                           \
5928       printf("// " #ASM1 "\n");                                      \
5929       if (masm1.IsUsingT32()) {                                      \
5930         dis.DisassembleT32Buffer(masm1.GetBuffer()                   \
5931                                      ->GetStartAddress<uint16_t*>(), \
5932                                  size1);                             \
5933       } else {                                                       \
5934         dis.DisassembleA32Buffer(masm1.GetBuffer()                   \
5935                                      ->GetStartAddress<uint32_t*>(), \
5936                                  size1);                             \
5937       }                                                              \
5938       printf("\n");                                                  \
5939                                                                      \
5940       dis.SetCodeAddress(0);                                         \
5941       printf("// " #ASM2 "\n");                                      \
5942       if (masm2.IsUsingT32()) {                                      \
5943         dis.DisassembleT32Buffer(masm2.GetBuffer()                   \
5944                                      ->GetStartAddress<uint16_t*>(), \
5945                                  size2);                             \
5946       } else {                                                       \
5947         dis.DisassembleA32Buffer(masm2.GetBuffer()                   \
5948                                      ->GetStartAddress<uint32_t*>(), \
5949                                  size2);                             \
5950       }                                                              \
5951       printf("\n");                                                  \
5952     }                                                                \
5953     VIXL_CHECK(size1 == size2);                                      \
5954   }
5955 
5956 
TEST_T32(macro_assembler_commute)5957 TEST_T32(macro_assembler_commute) {
5958   // Test that the MacroAssembler will commute operands if it means it can use a
5959   // 16-bit instruction with the same effect.
5960 
5961   // TODO: The commented-out tests should pass, but don't. When they are fixed,
5962   // we should update this test.
5963 
5964   // CHECK_SIZE_MATCH(Adc(DontCare, r7, r6, r7),
5965   //                  Adc(DontCare, r7, r7, r6));
5966 
5967   // CHECK_SIZE_MATCH(Adc(DontCare, eq, r7, r6, r7),
5968   //                  Adc(DontCare, eq, r7, r7, r6));
5969 
5970   CHECK_SIZE_MATCH(Add(DontCare, r1, r2, r7), Add(DontCare, r1, r7, r2));
5971 
5972   CHECK_SIZE_MATCH(Add(DontCare, lt, r1, r2, r7),
5973                    Add(DontCare, lt, r1, r7, r2));
5974 
5975   // CHECK_SIZE_MATCH(Add(DontCare, r4, r4, r10),
5976   //                  Add(DontCare, r4, r10, r4));
5977 
5978   // CHECK_SIZE_MATCH(Add(DontCare, eq, r4, r4, r10),
5979   //                  Add(DontCare, eq, r4, r10, r4));
5980 
5981   // CHECK_SIZE_MATCH(Add(DontCare, r7, sp, r7),
5982   //                  Add(DontCare, r7, r7, sp));
5983 
5984   // CHECK_SIZE_MATCH(Add(DontCare, eq, r7, sp, r7),
5985   //                  Add(DontCare, eq, r7, r7, sp));
5986 
5987   // CHECK_SIZE_MATCH(Add(DontCare, sp, sp, r10),
5988   //                  Add(DontCare, sp, r10, sp));
5989 
5990   // CHECK_SIZE_MATCH(Add(DontCare, eq, sp, sp, r10),
5991   //                  Add(DontCare, eq, sp, r10, sp));
5992 
5993   // CHECK_SIZE_MATCH(And(DontCare, r7, r7, r6),
5994   //                  And(DontCare, r7, r6, r7));
5995 
5996   // CHECK_SIZE_MATCH(And(DontCare, eq, r7, r7, r6),
5997   //                  And(DontCare, eq, r7, r6, r7));
5998 
5999   // CHECK_SIZE_MATCH(Eor(DontCare, r7, r7, r6),
6000   //                  Eor(DontCare, r7, r6, r7));
6001 
6002   // CHECK_SIZE_MATCH(Eor(DontCare, eq, r7, r7, r6),
6003   //                  Eor(DontCare, eq, r7, r6, r7));
6004 
6005   // CHECK_SIZE_MATCH(Mul(DontCare, r0, r1, r0),
6006   //                  Mul(DontCare, r0, r0, r1));
6007 
6008   // CHECK_SIZE_MATCH(Mul(DontCare, eq, r0, r1, r0),
6009   //                  Mul(DontCare, eq, r0, r0, r1));
6010 
6011   // CHECK_SIZE_MATCH(Orr(DontCare, r7, r7, r6),
6012   //                  Orr(DontCare, r7, r6, r7));
6013 
6014   // CHECK_SIZE_MATCH(Orr(DontCare, eq, r7, r7, r6),
6015   //                  Orr(DontCare, eq, r7, r6, r7));
6016 
6017 
6018   CHECK_SIZE_MATCH(Adc(r7, r6, r7), Adc(r7, r7, r6));
6019 
6020   // CHECK_SIZE_MATCH(Adc(eq, r7, r6, r7),
6021   //                  Adc(eq, r7, r7, r6));
6022 
6023   CHECK_SIZE_MATCH(Add(r1, r2, r7), Add(r1, r7, r2));
6024 
6025   CHECK_SIZE_MATCH(Add(lt, r1, r2, r7), Add(lt, r1, r7, r2));
6026 
6027   // CHECK_SIZE_MATCH(Add(r4, r4, r10),
6028   //                  Add(r4, r10, r4));
6029 
6030   // CHECK_SIZE_MATCH(Add(eq, r4, r4, r10),
6031   //                  Add(eq, r4, r10, r4));
6032 
6033   // CHECK_SIZE_MATCH(Add(r7, sp, r7),
6034   //                  Add(r7, r7, sp));
6035 
6036   // CHECK_SIZE_MATCH(Add(eq, r7, sp, r7),
6037   //                  Add(eq, r7, r7, sp));
6038 
6039   // CHECK_SIZE_MATCH(Add(sp, sp, r10),
6040   //                  Add(sp, r10, sp));
6041 
6042   // CHECK_SIZE_MATCH(Add(eq, sp, sp, r10),
6043   //                  Add(eq, sp, r10, sp));
6044 
6045   CHECK_SIZE_MATCH(And(r7, r7, r6), And(r7, r6, r7));
6046 
6047   // CHECK_SIZE_MATCH(And(eq, r7, r7, r6),
6048   //                  And(eq, r7, r6, r7));
6049 
6050   CHECK_SIZE_MATCH(Eor(r7, r7, r6), Eor(r7, r6, r7));
6051 
6052   // CHECK_SIZE_MATCH(Eor(eq, r7, r7, r6),
6053   //                  Eor(eq, r7, r6, r7));
6054 
6055   CHECK_SIZE_MATCH(Mul(r0, r1, r0), Mul(r0, r0, r1));
6056 
6057   // CHECK_SIZE_MATCH(Mul(eq, r0, r1, r0),
6058   //                  Mul(eq, r0, r0, r1));
6059 
6060   CHECK_SIZE_MATCH(Orr(r7, r7, r6), Orr(r7, r6, r7));
6061 
6062   // CHECK_SIZE_MATCH(Orr(eq, r7, r7, r6),
6063   //                  Orr(eq, r7, r6, r7));
6064 
6065 
6066   // CHECK_SIZE_MATCH(Adcs(r7, r6, r7),
6067   //                  Adcs(r7, r7, r6));
6068 
6069   // CHECK_SIZE_MATCH(Adcs(eq, r7, r6, r7),
6070   //                  Adcs(eq, r7, r7, r6));
6071 
6072   CHECK_SIZE_MATCH(Adds(r1, r2, r7), Adds(r1, r7, r2));
6073 
6074   CHECK_SIZE_MATCH(Adds(lt, r1, r2, r7), Adds(lt, r1, r7, r2));
6075 
6076   CHECK_SIZE_MATCH(Adds(r4, r4, r10), Adds(r4, r10, r4));
6077 
6078   CHECK_SIZE_MATCH(Adds(eq, r4, r4, r10), Adds(eq, r4, r10, r4));
6079 
6080   CHECK_SIZE_MATCH(Adds(r7, sp, r7), Adds(r7, r7, sp));
6081 
6082   CHECK_SIZE_MATCH(Adds(eq, r7, sp, r7), Adds(eq, r7, r7, sp));
6083 
6084   CHECK_SIZE_MATCH(Adds(sp, sp, r10), Adds(sp, r10, sp));
6085 
6086   CHECK_SIZE_MATCH(Adds(eq, sp, sp, r10), Adds(eq, sp, r10, sp));
6087 
6088   // CHECK_SIZE_MATCH(Ands(r7, r7, r6),
6089   //                  Ands(r7, r6, r7));
6090 
6091   // CHECK_SIZE_MATCH(Ands(eq, r7, r7, r6),
6092   //                  Ands(eq, r7, r6, r7));
6093 
6094   // CHECK_SIZE_MATCH(Eors(r7, r7, r6),
6095   //                  Eors(r7, r6, r7));
6096 
6097   // CHECK_SIZE_MATCH(Eors(eq, r7, r7, r6),
6098   //                  Eors(eq, r7, r6, r7));
6099 
6100   // CHECK_SIZE_MATCH(Muls(r0, r1, r0),
6101   //                  Muls(r0, r0, r1));
6102 
6103   // CHECK_SIZE_MATCH(Muls(eq, r0, r1, r0),
6104   //                  Muls(eq, r0, r0, r1));
6105 
6106   // CHECK_SIZE_MATCH(Orrs(r7, r7, r6),
6107   //                  Orrs(r7, r6, r7));
6108 
6109   // CHECK_SIZE_MATCH(Orrs(eq, r7, r7, r6),
6110   //                  Orrs(eq, r7, r6, r7));
6111 }
6112 
TEST(emit_pool_when_manually_placing_literal)6113 TEST(emit_pool_when_manually_placing_literal) {
6114   SETUP();
6115   START();
6116 
6117   // Literal that will be manually placed.
6118   Literal<uint64_t> l0(0xcafebeefdeadbaba, RawLiteral::kManuallyPlaced);
6119 
6120   // Create one literal pool entry.
6121   __ Ldrd(r0, r1, 0x1234567890abcdef);
6122 
6123   // Branch using the assembler, to avoid introducing a veneer.
6124   Label over_literal;
6125   const int kBranchSize = 4;
6126   {
6127     ExactAssemblyScope scope(&masm,
6128                              kBranchSize,
6129                              ExactAssemblyScope::kExactSize);
6130     __ b(&over_literal);
6131   }
6132 
6133   // Almost reach the pool checkpoint.
6134   int32_t margin =
6135       test.GetPoolCheckpoint() - masm.GetCursorOffset() - l0.GetSize() / 2;
6136   int32_t end = masm.GetCursorOffset() + margin;
6137   {
6138     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
6139     while (masm.GetCursorOffset() < end) {
6140       __ nop();
6141     }
6142   }
6143 
6144   VIXL_CHECK(!test.PoolIsEmpty());
6145   __ Place(&l0);
6146   // The pool must now have been emitted.
6147   VIXL_CHECK(test.PoolIsEmpty());
6148 
6149   __ Bind(&over_literal);
6150 
6151   __ Ldrd(r2, r3, &l0);
6152 
6153   END();
6154 
6155   RUN();
6156 
6157   ASSERT_EQUAL_32(0x90abcdef, r0);
6158   ASSERT_EQUAL_32(0x12345678, r1);
6159   ASSERT_EQUAL_32(0xdeadbaba, r2);
6160   ASSERT_EQUAL_32(0xcafebeef, r3);
6161 }
6162 
6163 
6164 // The addition of padding only happens for T32.
TEST_T32(emit_pool_when_adding_padding_due_to_bind)6165 TEST_T32(emit_pool_when_adding_padding_due_to_bind) {
6166   SETUP();
6167   START();
6168 
6169   // Make sure we start with a 4-byte aligned address, in order for the
6170   // location where we will call Bind() to be 4-byte aligned.
6171   {
6172     ExactAssemblyScope scope(&masm,
6173                              k16BitT32InstructionSizeInBytes,
6174                              ExactAssemblyScope::kMaximumSize);
6175     while (masm.GetCursorOffset() % 4 != 0) {
6176       __ nop();
6177     }
6178   }
6179 
6180   // Create one literal pool entry.
6181   __ Ldrd(r0, r1, 0x1234567890abcdef);
6182 
6183   // Almost reach the pool checkpoint.
6184   const int kPaddingBytes = 2;
6185   int32_t margin =
6186       test.GetPoolCheckpoint() - masm.GetCursorOffset() - kPaddingBytes;
6187   int32_t end = masm.GetCursorOffset() + margin;
6188   {
6189     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
6190     while (masm.GetCursorOffset() < end) {
6191       __ nop();
6192     }
6193   }
6194 
6195   Label label;
6196   __ Cbz(r0, &label);
6197 
6198   VIXL_CHECK(!test.PoolIsEmpty());
6199   // In order to hit the case where binding the label needs to add padding,
6200   // we need this to be a 4-byte aligned address.
6201   VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 0);
6202 
6203   __ Bind(&label);
6204   // The pool must now have been emitted.
6205   VIXL_CHECK(test.PoolIsEmpty());
6206 
6207   END();
6208 
6209   RUN();
6210 
6211   ASSERT_EQUAL_32(0x90abcdef, r0);
6212   ASSERT_EQUAL_32(0x12345678, r1);
6213 }
6214 
AddBranchesAndGetCloseToCheckpoint(MacroAssembler * masm,TestMacroAssembler * test,const int kLabelsCount,Label b_labels[],int32_t margin)6215 static void AddBranchesAndGetCloseToCheckpoint(MacroAssembler* masm,
6216                                                TestMacroAssembler* test,
6217                                                const int kLabelsCount,
6218                                                Label b_labels[],
6219                                                int32_t margin) {
6220   // Add many veneers to the pool.
6221   for (int i = 0; i < kLabelsCount; i++) {
6222     masm->B(&b_labels[i]);
6223   }
6224 
6225   // Get close to the veneer emission margin (considering the heuristic).
6226   // Use add instead of nop to make viewing the disassembled code easier.
6227   const int kAddSize = masm->IsUsingT32() ? k16BitT32InstructionSizeInBytes
6228                                           : kA32InstructionSizeInBytes;
6229   int32_t end = test->GetPoolCheckpoint();
6230   int32_t space = end - masm->GetCursorOffset() - margin;
6231   {
6232     ExactAssemblyScope scope(masm, space, ExactAssemblyScope::kExactSize);
6233     while (space > 0) {
6234       masm->add(r0, r0, r0);
6235       space -= kAddSize;
6236     }
6237   }
6238 
6239   // Make sure the veneers have not yet been emitted.
6240   const int kVeneerSize = 4;
6241   VIXL_CHECK(test->GetPoolSize() == kLabelsCount * kVeneerSize);
6242 }
6243 
EmitIndividualNops(MacroAssembler * masm,const int kNops)6244 static void EmitIndividualNops(MacroAssembler* masm, const int kNops) {
6245   for (int i = 0; i < kNops; ++i) {
6246     masm->Nop();
6247   }
6248 }
6249 
EmitNopsInExactAssemblyScope(MacroAssembler * masm,const int kNops)6250 static void EmitNopsInExactAssemblyScope(MacroAssembler* masm,
6251                                          const int kNops) {
6252   const int kNopSize = masm->IsUsingT32() ? k16BitT32InstructionSizeInBytes
6253                                           : kA32InstructionSizeInBytes;
6254   {
6255     ExactAssemblyScope scope(masm,
6256                              kNops * kNopSize,
6257                              ExactAssemblyScope::kExactSize);
6258     for (int i = 0; i < kNops; i++) {
6259       masm->nop();
6260     }
6261   }
6262 }
6263 
TEST_A32(literal_and_veneer_interaction_1)6264 TEST_A32(literal_and_veneer_interaction_1) {
6265   SETUP();
6266   START();
6267 
6268   static const int kLabelsCount = 100;
6269 
6270   Label b_labels[kLabelsCount];
6271 
6272   AddBranchesAndGetCloseToCheckpoint(&masm,
6273                                      &test,
6274                                      kLabelsCount,
6275                                      b_labels,
6276                                      1 * KBytes);
6277 
6278   // Emit a load of a large string. In the past, we have attempted to emit
6279   // the literal load without emitting the veneers, which meant that we were
6280   // left with an impossible scheduling problem for the pool objects (due to
6281   // the short range of the ldrd).
6282   std::string test_string(2 * KBytes, 'x');
6283   StringLiteral big_literal(test_string.c_str());
6284   __ Ldrd(r0, r1, &big_literal);
6285 
6286   EmitIndividualNops(&masm, 1000);
6287 
6288   // We can now safely bind the labels.
6289   for (int i = 0; i < kLabelsCount; i++) {
6290     __ Bind(&b_labels[i]);
6291   }
6292 
6293   END();
6294 
6295   RUN();
6296 }
6297 
6298 
TEST_A32(literal_and_veneer_interaction_2)6299 TEST_A32(literal_and_veneer_interaction_2) {
6300   SETUP();
6301   START();
6302 
6303   static const int kLabelsCount = 100;
6304 
6305   Label b_labels[kLabelsCount];
6306 
6307   AddBranchesAndGetCloseToCheckpoint(&masm,
6308                                      &test,
6309                                      kLabelsCount,
6310                                      b_labels,
6311                                      1 * KBytes);
6312 
6313   // This is similar to the test above. The Ldr instruction can be emitted with
6314   // no problems. The Ldrd used to force emission of the literal pool, pushing
6315   // the veneers out of range - we make sure this does not happen anymore.
6316   std::string test_string(2 * KBytes, 'z');
6317   StringLiteral big_literal(test_string.c_str());
6318   __ Ldr(r2, &big_literal);
6319 
6320   const int kVeneerSize = 4;
6321   CHECK_POOL_SIZE(kLabelsCount * kVeneerSize + big_literal.GetSize());
6322 
6323   std::string test_string2(2 * KBytes, 'x');
6324   StringLiteral big_literal2(test_string.c_str());
6325   __ Ldrd(r0, r1, &big_literal2);
6326 
6327   EmitIndividualNops(&masm, 1000);
6328 
6329   for (int i = 0; i < kLabelsCount; i++) {
6330     __ Bind(&b_labels[i]);
6331   }
6332 
6333   END();
6334 
6335   RUN();
6336 }
6337 
6338 
TEST_A32(literal_and_veneer_interaction_3)6339 TEST_A32(literal_and_veneer_interaction_3) {
6340   SETUP();
6341   START();
6342 
6343   static const int kLabelsCount = 100;
6344   Label b_labels[kLabelsCount];
6345 
6346   AddBranchesAndGetCloseToCheckpoint(&masm,
6347                                      &test,
6348                                      kLabelsCount,
6349                                      b_labels,
6350                                      1 * KBytes);
6351 
6352   // Here, we used to emit the Ldrd instruction and then emit the veneers
6353   // before the literal is emitted, hence pushing the Ldrd out of range.
6354   // Make sure this does not happen anymore.
6355   __ Ldrd(r2, r3, 0x12345678);
6356 
6357   // The issue would only appear when emitting the nops in a single scope.
6358   EmitNopsInExactAssemblyScope(&masm, 4096);
6359 
6360   for (int i = 0; i < kLabelsCount; i++) {
6361     __ Bind(&b_labels[i]);
6362   }
6363 
6364   END();
6365 
6366   RUN();
6367 }
6368 
6369 
6370 // Equivalent to literal_and_veneer_interaction_1, but for T32.
TEST_T32(literal_and_veneer_interaction_4)6371 TEST_T32(literal_and_veneer_interaction_4) {
6372   SETUP();
6373   START();
6374 
6375   static const int kLabelsCount = 550;
6376 
6377   Label b_labels[kLabelsCount];
6378 
6379   AddBranchesAndGetCloseToCheckpoint(&masm,
6380                                      &test,
6381                                      kLabelsCount,
6382                                      b_labels,
6383                                      KBytes / 2);
6384 
6385   std::string test_string(3 * KBytes, 'x');
6386   StringLiteral big_literal(test_string.c_str());
6387   __ Ldrd(r0, r1, &big_literal);
6388 
6389   EmitIndividualNops(&masm, 2000);
6390 
6391   for (int i = 0; i < kLabelsCount; i++) {
6392     __ Bind(&b_labels[i]);
6393   }
6394 
6395   END();
6396 
6397   RUN();
6398 }
6399 
6400 // Equivalent to literal_and_veneer_interaction_3, but for T32.
TEST_T32(literal_and_veneer_interaction_5)6401 TEST_T32(literal_and_veneer_interaction_5) {
6402   SETUP();
6403   START();
6404 
6405   static const int kLabelsCount = 550;
6406   Label b_labels[kLabelsCount];
6407 
6408   AddBranchesAndGetCloseToCheckpoint(&masm,
6409                                      &test,
6410                                      kLabelsCount,
6411                                      b_labels,
6412                                      1 * KBytes);
6413 
6414   __ Ldrd(r2, r3, 0x12345678);
6415 
6416   EmitNopsInExactAssemblyScope(&masm, 4096);
6417 
6418   for (int i = 0; i < kLabelsCount; i++) {
6419     __ Bind(&b_labels[i]);
6420   }
6421 
6422   END();
6423 
6424   RUN();
6425 }
6426 
TEST_T32(assembler_bind_label)6427 TEST_T32(assembler_bind_label) {
6428   SETUP();
6429   START();
6430 
6431   Label label;
6432   __ B(eq, &label, kNear);
6433 
6434   // At this point we keep track of the veneer in the pool.
6435   VIXL_CHECK(!test.PoolIsEmpty());
6436 
6437   {
6438     // Bind the label with the assembler.
6439     ExactAssemblyScope scope(&masm, 2, ExactAssemblyScope::kMaximumSize);
6440     __ bind(&label);
6441   }
6442 
6443   // Make sure the pool is now empty.
6444   VIXL_CHECK(test.PoolIsEmpty());
6445 
6446   EmitNopsInExactAssemblyScope(&masm, 4096);
6447 
6448   END();
6449 
6450   RUN();
6451 }
6452 
6453 #ifdef VIXL_DEBUG
6454 #define TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)    \
6455   POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM) \
6456   NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)
6457 #else
6458 // Skip the negative tests for release builds, as they require debug-only checks
6459 // in ExactAssemblyScope.
6460 #define TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM) \
6461   POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)
6462 #endif
6463 
6464 #define POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)                \
6465   can_encode = masm.INFO;                                                    \
6466   VIXL_CHECK(can_encode);                                                    \
6467   {                                                                          \
6468     ExactAssemblyScope scope(&masm,                                          \
6469                              info->size,                                     \
6470                              ExactAssemblyScope::kExactSize);                \
6471     int32_t pc = masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
6472     if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {                \
6473       pc = AlignDown(pc, 4);                                                 \
6474     }                                                                        \
6475     Label label(pc + info->min_offset);                                      \
6476     masm.ASM;                                                                \
6477   }                                                                          \
6478   {                                                                          \
6479     ExactAssemblyScope scope(&masm,                                          \
6480                              info->size,                                     \
6481                              ExactAssemblyScope::kExactSize);                \
6482     int32_t pc = masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
6483     if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {                \
6484       pc = AlignDown(pc, 4);                                                 \
6485     }                                                                        \
6486     Label label(pc + info->max_offset);                                      \
6487     masm.ASM;                                                                \
6488   }
6489 
6490 #ifdef VIXL_NEGATIVE_TESTING
6491 #define NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)                      \
6492   try {                                                                      \
6493     ExactAssemblyScope scope(&masm,                                          \
6494                              info->size,                                     \
6495                              ExactAssemblyScope::kMaximumSize);              \
6496     int32_t pc = masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
6497     if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {                \
6498       pc = AlignDown(pc, 4);                                                 \
6499     }                                                                        \
6500     Label label(pc + info->max_offset + info->alignment);                    \
6501     masm.ASM;                                                                \
6502     printf("Negative test for forward reference failed for %s.\n", INST);    \
6503     abort();                                                                 \
6504   } catch (std::runtime_error) {                                             \
6505   }                                                                          \
6506   try {                                                                      \
6507     ExactAssemblyScope scope(&masm,                                          \
6508                              info->size,                                     \
6509                              ExactAssemblyScope::kMaximumSize);              \
6510     int32_t pc = masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
6511     if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {                \
6512       pc = AlignDown(pc, 4);                                                 \
6513     }                                                                        \
6514     Label label(pc + info->min_offset - info->alignment);                    \
6515     masm.ASM;                                                                \
6516     printf("Negative test for forward reference failed for %s.\n", INST);    \
6517     abort();                                                                 \
6518   } catch (std::runtime_error) {                                             \
6519   }
6520 #else
6521 #define NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)
6522 #endif
6523 
TEST_T32(forward_reference_info_T32)6524 TEST_T32(forward_reference_info_T32) {
6525   MacroAssembler masm(BUF_SIZE, T32);
6526 
6527   Label unbound;
6528   const ReferenceInfo* info;
6529   bool can_encode;
6530 
6531   // clang-format off
6532 
6533   TEST_FORWARD_REFERENCE_INFO(
6534     "adr",
6535     adr_info(al, Narrow, r0, &unbound, &info),
6536     adr(al, Narrow, r0, &label));
6537 
6538   TEST_FORWARD_REFERENCE_INFO(
6539     "adr",
6540     adr_info(al, Wide, r0, &unbound, &info),
6541     adr(al, Wide, r0, &label));
6542 
6543   TEST_FORWARD_REFERENCE_INFO(
6544     "adr",
6545     adr_info(al, Best, r0, &unbound, &info),
6546     adr(al, Best, r0, &label));
6547 
6548   TEST_FORWARD_REFERENCE_INFO(
6549     "b",
6550     b_info(al, Narrow, &unbound, &info),
6551     b(al, Narrow, &label));
6552 
6553   TEST_FORWARD_REFERENCE_INFO(
6554     "b",
6555     b_info(al, Wide, &unbound, &info),
6556     b(al, Wide, &label));
6557 
6558   TEST_FORWARD_REFERENCE_INFO(
6559     "b",
6560     b_info(al, Best, &unbound, &info),
6561     b(al, Best, &label));
6562 
6563   TEST_FORWARD_REFERENCE_INFO(
6564     "b",
6565     b_info(gt, Narrow, &unbound, &info),
6566     b(gt, Narrow, &label));
6567 
6568   TEST_FORWARD_REFERENCE_INFO(
6569     "b",
6570     b_info(gt, Wide, &unbound, &info),
6571     b(gt, Wide, &label));
6572 
6573   TEST_FORWARD_REFERENCE_INFO(
6574     "b",
6575     b_info(gt, Best, &unbound, &info),
6576     b(gt, Best, &label));
6577 
6578   TEST_FORWARD_REFERENCE_INFO(
6579     "bl",
6580     bl_info(al, &unbound, &info),
6581     bl(al, &label));
6582 
6583   TEST_FORWARD_REFERENCE_INFO(
6584     "blx",
6585     blx_info(al, &unbound, &info),
6586     blx(al, &label));
6587 
6588   TEST_FORWARD_REFERENCE_INFO(
6589     "cbnz",
6590     cbnz_info(r0, &unbound, &info),
6591     cbnz(r0, &label));
6592 
6593   TEST_FORWARD_REFERENCE_INFO(
6594     "cbz",
6595     cbz_info(r0, &unbound, &info),
6596     cbz(r0, &label));
6597 
6598   TEST_FORWARD_REFERENCE_INFO(
6599     "ldr",
6600     ldr_info(al, Narrow, r0, &unbound, &info),
6601     ldr(al, Narrow, r0, &label));
6602 
6603   TEST_FORWARD_REFERENCE_INFO(
6604     "ldr",
6605     ldr_info(al, Wide, r0, &unbound, &info),
6606     ldr(al, Wide, r0, &label));
6607 
6608   TEST_FORWARD_REFERENCE_INFO(
6609     "ldr",
6610     ldr_info(al, Best, r0, &unbound, &info),
6611     ldr(al, Best, r0, &label));
6612 
6613   TEST_FORWARD_REFERENCE_INFO(
6614     "ldrb",
6615     ldrb_info(al, r0, &unbound, &info),
6616     ldrb(al, r0, &label));
6617 
6618   TEST_FORWARD_REFERENCE_INFO(
6619     "ldrd",
6620     ldrd_info(al, r0, r1, &unbound, &info),
6621     ldrd(al, r0, r1, &label));
6622 
6623   TEST_FORWARD_REFERENCE_INFO(
6624     "ldrh",
6625     ldrh_info(al, r0, &unbound, &info),
6626     ldrh(al, r0, &label));
6627 
6628   TEST_FORWARD_REFERENCE_INFO(
6629     "ldrsb",
6630     ldrsb_info(al, r0, &unbound, &info),
6631     ldrsb(al, r0, &label));
6632 
6633   TEST_FORWARD_REFERENCE_INFO(
6634     "ldrsh",
6635     ldrsh_info(al, r0, &unbound, &info),
6636     ldrsh(al, r0, &label));
6637 
6638   TEST_FORWARD_REFERENCE_INFO(
6639     "pld",
6640     pld_info(al, &unbound, &info),
6641     pld(al, &label));
6642 
6643   TEST_FORWARD_REFERENCE_INFO(
6644     "pli",
6645     pli_info(al, &unbound, &info),
6646     pli(al, &label));
6647 
6648   TEST_FORWARD_REFERENCE_INFO(
6649     "vldr",
6650     vldr_info(al, Untyped64, d0, &unbound, &info),
6651     vldr(al, Untyped64, d0, &label));
6652 
6653   TEST_FORWARD_REFERENCE_INFO(
6654     "vldr",
6655     vldr_info(al, Untyped32, s0, &unbound, &info),
6656     vldr(al, Untyped32, s0, &label));
6657 
6658   // clang-format on
6659 
6660   masm.FinalizeCode();
6661 }
6662 
TEST_A32(forward_reference_info_A32)6663 TEST_A32(forward_reference_info_A32) {
6664   MacroAssembler masm(BUF_SIZE, A32);
6665   Label unbound;
6666   const ReferenceInfo* info;
6667   bool can_encode;
6668 
6669   // clang-format off
6670 
6671   TEST_FORWARD_REFERENCE_INFO(
6672     "adr",
6673     adr_info(al, Best, r0, &unbound, &info),
6674     adr(al, Best, r0, &label));
6675 
6676   TEST_FORWARD_REFERENCE_INFO(
6677     "b",
6678     b_info(al, Best, &unbound, &info),
6679     b(al, Best, &label));
6680 
6681   TEST_FORWARD_REFERENCE_INFO(
6682     "b",
6683     b_info(gt, Best, &unbound, &info),
6684     b(gt, Best, &label));
6685 
6686   TEST_FORWARD_REFERENCE_INFO(
6687     "bl",
6688     bl_info(al, &unbound, &info),
6689     bl(al, &label));
6690 
6691   TEST_FORWARD_REFERENCE_INFO(
6692     "blx",
6693     blx_info(al, &unbound, &info),
6694     blx(al, &label));
6695 
6696   TEST_FORWARD_REFERENCE_INFO(
6697     "ldr",
6698     ldr_info(al, Best, r0, &unbound, &info),
6699     ldr(al, Best, r0, &label));
6700 
6701   TEST_FORWARD_REFERENCE_INFO(
6702     "ldrb",
6703     ldrb_info(al, r0, &unbound, &info),
6704     ldrb(al, r0, &label));
6705 
6706   TEST_FORWARD_REFERENCE_INFO(
6707     "ldrd",
6708     ldrd_info(al, r0, r1, &unbound, &info),
6709     ldrd(al, r0, r1, &label));
6710 
6711   TEST_FORWARD_REFERENCE_INFO(
6712     "ldrh",
6713     ldrh_info(al, r0, &unbound, &info),
6714     ldrh(al, r0, &label));
6715 
6716   TEST_FORWARD_REFERENCE_INFO(
6717     "ldrsb",
6718     ldrsb_info(al, r0, &unbound, &info),
6719     ldrsb(al, r0, &label));
6720 
6721   TEST_FORWARD_REFERENCE_INFO(
6722     "ldrsh",
6723     ldrsh_info(al, r0, &unbound, &info),
6724     ldrsh(al, r0, &label));
6725 
6726   TEST_FORWARD_REFERENCE_INFO(
6727     "pld",
6728     pld_info(al, &unbound, &info),
6729     pld(al, &label));
6730 
6731   TEST_FORWARD_REFERENCE_INFO(
6732     "pli",
6733     pli_info(al, &unbound, &info),
6734     pli(al, &label));
6735 
6736   TEST_FORWARD_REFERENCE_INFO(
6737     "vldr",
6738     vldr_info(al, Untyped64, d0, &unbound, &info),
6739     vldr(al, Untyped64, d0, &label));
6740 
6741   TEST_FORWARD_REFERENCE_INFO(
6742     "vldr",
6743     vldr_info(al, Untyped32, s0, &unbound, &info),
6744     vldr(al, Untyped32, s0, &label));
6745 
6746   // clang-format on
6747 
6748   masm.FinalizeCode();
6749 }
6750 
6751 }  // namespace aarch32
6752 }  // namespace vixl
6753