• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 j = 0; j < 20; j++) {
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 
3195 // clang-format off
TEST_NOASM(set_isa_noop)3196 TEST_NOASM(set_isa_noop) {
3197 // It is possible to call a no-op UseA32/T32 or UseInstructionSet even if
3198 // one or more instructions have been generated.
3199 #ifdef VIXL_INCLUDE_TARGET_A32
3200   {
3201     Assembler assm(A32);
3202     CheckInstructionSetA32(assm);
3203     CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
3204     assm.bx(lr);
3205     VIXL_ASSERT(assm.GetCursorOffset() > 0);
3206     CheckInstructionSetA32(assm);
3207     assm.UseA32();
3208     CheckInstructionSetA32(assm);
3209     assm.UseInstructionSet(A32);
3210     CheckInstructionSetA32(assm);
3211     assm.FinalizeCode();
3212   }
3213   {
3214     MacroAssembler masm(A32);
3215     CheckInstructionSetA32(masm);
3216     masm.Bx(lr);
3217     VIXL_ASSERT(masm.GetCursorOffset() > 0);
3218     CheckInstructionSetA32(masm);
3219     masm.UseA32();
3220     CheckInstructionSetA32(masm);
3221     masm.UseInstructionSet(A32);
3222     CheckInstructionSetA32(masm);
3223     masm.FinalizeCode();
3224   }
3225 #endif
3226 
3227 #ifdef VIXL_INCLUDE_TARGET_T32
3228   {
3229     Assembler assm(T32);
3230     CheckInstructionSetT32(assm);
3231     CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
3232     assm.bx(lr);
3233     VIXL_ASSERT(assm.GetCursorOffset() > 0);
3234     CheckInstructionSetT32(assm);
3235     assm.UseT32();
3236     CheckInstructionSetT32(assm);
3237     assm.UseInstructionSet(T32);
3238     CheckInstructionSetT32(assm);
3239     assm.FinalizeCode();
3240   }
3241   {
3242     MacroAssembler masm(T32);
3243     CheckInstructionSetT32(masm);
3244     masm.Bx(lr);
3245     VIXL_ASSERT(masm.GetCursorOffset() > 0);
3246     CheckInstructionSetT32(masm);
3247     masm.UseT32();
3248     CheckInstructionSetT32(masm);
3249     masm.UseInstructionSet(T32);
3250     CheckInstructionSetT32(masm);
3251     masm.FinalizeCode();
3252   }
3253 #endif
3254 }
3255 // clang-format on
3256 
3257 
TEST(logical_arithmetic_identities)3258 TEST(logical_arithmetic_identities) {
3259   SETUP();
3260 
3261   START();
3262 
3263   Label blob_1;
3264   __ Bind(&blob_1);
3265   __ Add(r0, r0, 0);
3266   __ And(r0, r0, 0xffffffff);
3267   __ Bic(r0, r0, 0);
3268   __ Eor(r0, r0, 0);
3269   __ Orn(r0, r0, 0xffffffff);
3270   __ Orr(r0, r0, 0);
3271   __ Sub(r0, r0, 0);
3272   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_1) == 0);
3273 
3274   Label blob_2;
3275   __ Bind(&blob_2);
3276   __ Adds(r0, r0, 0);
3277   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_2) != 0);
3278 
3279   Label blob_3;
3280   __ Bind(&blob_3);
3281   __ Ands(r0, r0, 0);
3282   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_3) != 0);
3283 
3284   Label blob_4;
3285   __ Bind(&blob_4);
3286   __ Bics(r0, r0, 0);
3287   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_4) != 0);
3288 
3289   Label blob_5;
3290   __ Bind(&blob_5);
3291   __ Eors(r0, r0, 0);
3292   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_5) != 0);
3293 
3294   Label blob_6;
3295   __ Bind(&blob_6);
3296   __ Orns(r0, r0, 0);
3297   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_6) != 0);
3298 
3299   Label blob_7;
3300   __ Bind(&blob_7);
3301   __ Orrs(r0, r0, 0);
3302   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_7) != 0);
3303 
3304   Label blob_8;
3305   __ Bind(&blob_8);
3306   __ Subs(r0, r0, 0);
3307   VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_8) != 0);
3308 
3309   __ Mov(r0, 0xbad);
3310   __ And(r1, r0, 0);
3311   __ Bic(r2, r0, 0xffffffff);
3312   __ Eor(r3, r0, 0xffffffff);
3313   __ Orn(r4, r0, 0);
3314   __ Orr(r5, r0, 0xffffffff);
3315 
3316   END();
3317 
3318   RUN();
3319 
3320   ASSERT_EQUAL_32(0xbad, r0);
3321   ASSERT_EQUAL_32(0, r1);
3322   ASSERT_EQUAL_32(0, r2);
3323   ASSERT_EQUAL_32(~0xbad, r3);
3324   ASSERT_EQUAL_32(0xffffffff, r4);
3325   ASSERT_EQUAL_32(0xffffffff, r5);
3326 }
3327 
3328 
TEST(scratch_register_checks)3329 TEST(scratch_register_checks) {
3330   // It is unsafe for users to use registers that the MacroAssembler is also
3331   // using as scratch registers. This test checks the MacroAssembler's checking
3332   // mechanism itself.
3333   SETUP();
3334   START();
3335   {
3336     UseScratchRegisterScope temps(&masm);
3337     // 'ip' is a scratch register by default.
3338     VIXL_CHECK(masm.GetScratchRegisterList()->GetList() ==
3339                (1u << ip.GetCode()));
3340     VIXL_CHECK(temps.IsAvailable(ip));
3341 
3342     // Integer registers have no complicated aliasing so
3343     // masm.AliasesAvailableScratchRegister(reg) == temps.IsAvailable(reg).
3344     for (unsigned i = 0; i < kNumberOfRegisters; i++) {
3345       Register reg(i);
3346       VIXL_CHECK(masm.AliasesAvailableScratchRegister(reg) ==
3347                  temps.IsAvailable(reg));
3348     }
3349   }
3350   END();
3351 }
3352 
3353 
TEST(scratch_register_checks_v)3354 TEST(scratch_register_checks_v) {
3355   // It is unsafe for users to use registers that the MacroAssembler is also
3356   // using as scratch registers. This test checks the MacroAssembler's checking
3357   // mechanism itself.
3358   SETUP();
3359   {
3360     UseScratchRegisterScope temps(&masm);
3361     // There is no default floating-point scratch register. Add temps of various
3362     // sizes to check handling of aliased registers.
3363     VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() == 0);
3364     temps.Include(q15);
3365     temps.Include(d15);
3366     temps.Include(s15);
3367     temps.Include(d4);
3368     temps.Include(d5);
3369     temps.Include(s24);
3370     temps.Include(s25);
3371     temps.Include(s26);
3372     temps.Include(s27);
3373     temps.Include(q0);
3374     // See VRegisterList for details of the list encoding.
3375     VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() ==
3376                UINT64_C(0xf0000000cf008f0f));
3377     //                    |       ||  || |
3378     //                   q15    d15|  || q0
3379     //                        s24-s27 |d4-d5
3380     //                               s15
3381 
3382     // Simple checks: Included registers are available.
3383     VIXL_CHECK(temps.IsAvailable(q15));
3384     VIXL_CHECK(temps.IsAvailable(d15));
3385     VIXL_CHECK(temps.IsAvailable(s15));
3386     VIXL_CHECK(temps.IsAvailable(d4));
3387     VIXL_CHECK(temps.IsAvailable(d5));
3388     VIXL_CHECK(temps.IsAvailable(s24));
3389     VIXL_CHECK(temps.IsAvailable(s25));
3390     VIXL_CHECK(temps.IsAvailable(s26));
3391     VIXL_CHECK(temps.IsAvailable(s27));
3392     VIXL_CHECK(temps.IsAvailable(q0));
3393 
3394     // Each available S register should mark the corresponding D and Q registers
3395     // as aliasing an available scratch register.
3396     for (unsigned s = 0; s < kNumberOfSRegisters; s++) {
3397       if (temps.IsAvailable(SRegister(s))) {
3398         VIXL_CHECK(masm.AliasesAvailableScratchRegister(SRegister(s)));
3399         VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(s / 2)));
3400         VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(s / 4)));
3401       } else {
3402         // AliasesAvailableScratchRegiters == IsAvailable for S registers.
3403         VIXL_CHECK(!masm.AliasesAvailableScratchRegister(SRegister(s)));
3404       }
3405     }
3406 
3407     // Similar checks for high D registers.
3408     unsigned first_high_d_register = kNumberOfSRegisters / 2;
3409     for (unsigned d = first_high_d_register; d < kMaxNumberOfDRegisters; d++) {
3410       if (temps.IsAvailable(DRegister(d))) {
3411         VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(d)));
3412         VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(d / 2)));
3413       } else {
3414         // AliasesAvailableScratchRegiters == IsAvailable for high D registers.
3415         VIXL_CHECK(!masm.AliasesAvailableScratchRegister(DRegister(d)));
3416       }
3417     }
3418   }
3419 }
3420 
3421 
TEST(nop)3422 TEST(nop) {
3423   SETUP();
3424 
3425   Label start;
3426   __ Bind(&start);
3427   __ Nop();
3428   size_t nop_size = (isa == T32) ? k16BitT32InstructionSizeInBytes
3429                                  : kA32InstructionSizeInBytes;
3430   // `MacroAssembler::Nop` must generate at least one nop.
3431   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) >= nop_size);
3432 
3433   masm.FinalizeCode();
3434 }
3435 
3436 // Check that `GetPoolCheckpoint()` is precise.
TEST(literal_pool_margin)3437 TEST(literal_pool_margin) {
3438   SETUP();
3439 
3440   START();
3441 
3442   VIXL_CHECK(test.PoolIsEmpty());
3443 
3444   // Create a single literal.
3445   __ Ldrd(r0, r1, 0x1234567890abcdef);
3446 
3447   VIXL_CHECK(!test.PoolIsEmpty());
3448 
3449   // Generate code to fill all the margin we have before generating the literal
3450   // pool.
3451   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
3452   int32_t end = test.GetPoolCheckpoint();
3453   {
3454     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
3455     // Opening the scope should not have triggered the emission of the literal
3456     // pool.
3457     VIXL_CHECK(!test.PoolIsEmpty());
3458     while (masm.GetCursorOffset() < end) {
3459       __ nop();
3460     }
3461     VIXL_CHECK(masm.GetCursorOffset() == end);
3462   }
3463 
3464   // There should be no margin left to emit the literal pool.
3465   VIXL_CHECK(!test.PoolIsEmpty());
3466   VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
3467 
3468   // So emitting a single instruction should force emission of the pool.
3469   __ Nop();
3470   VIXL_CHECK(test.PoolIsEmpty());
3471   END();
3472 
3473   RUN();
3474 
3475   // Check that the literals loaded correctly.
3476   ASSERT_EQUAL_32(0x90abcdef, r0);
3477   ASSERT_EQUAL_32(0x12345678, r1);
3478 }
3479 
3480 
3481 // Check that `GetPoolCheckpoint()` is precise.
TEST(veneer_pool_margin)3482 TEST(veneer_pool_margin) {
3483   SETUP();
3484 
3485   START();
3486 
3487   VIXL_CHECK(test.PoolIsEmpty());
3488 
3489   // Create a single veneer.
3490   Label target;
3491   __ B(eq, &target);
3492 
3493   VIXL_CHECK(!test.PoolIsEmpty());
3494 
3495   // Generate code to fill all the margin we have before generating the veneer
3496   // pool.
3497   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
3498   int32_t end = test.GetPoolCheckpoint();
3499   {
3500     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
3501     // Opening the scope should not have triggered the emission of the veneer
3502     // pool.
3503     VIXL_CHECK(!test.PoolIsEmpty());
3504     while (masm.GetCursorOffset() < end) {
3505       __ nop();
3506     }
3507     VIXL_CHECK(masm.GetCursorOffset() == end);
3508   }
3509   // There should be no margin left to emit the veneer pool.
3510   VIXL_CHECK(test.GetPoolCheckpoint() == masm.GetCursorOffset());
3511 
3512   // So emitting a single instruction should force emission of the pool.
3513   // We cannot simply check that the veneer pool is empty, because the veneer
3514   // emitted for the CBZ instruction above is itself tracked by the veneer
3515   // mechanisms. Instead, check that some 'unexpected' code is generated.
3516   Label check;
3517   __ Bind(&check);
3518   {
3519     ExactAssemblyScope scope(&masm, 2, ExactAssemblyScope::kMaximumSize);
3520     // Do not actually generate any code.
3521   }
3522   VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) > 0);
3523   __ Bind(&target);
3524   VIXL_CHECK(test.PoolIsEmpty());
3525 
3526   END();
3527 
3528   RUN();
3529 }
3530 
TEST_T32(near_branch_fuzz)3531 TEST_T32(near_branch_fuzz) {
3532   SETUP();
3533   START();
3534 
3535   uint16_t seed[3] = {1, 2, 3};
3536   seed48(seed);
3537 
3538   const int label_count = 31;
3539   Label* l;
3540 
3541   // Use multiple iterations, as each produces a different predictably random
3542   // sequence.
3543   const int iterations = 64;
3544 
3545   int loop_count = 0;
3546   __ Mov(r1, 0);
3547 
3548   // Initialise the status flags to Z set.
3549   __ Cmp(r1, r1);
3550 
3551   // Gradually increasing the number of cases effectively increases the
3552   // probability of nops being emitted in the sequence. The branch-to-bind
3553   // ratio in the sequence is fixed at 4:1 by the ratio of cases.
3554   for (int case_count = 6; case_count < 37; case_count++) {
3555     for (int iter = 0; iter < iterations; iter++) {
3556       l = new Label[label_count];
3557 
3558       // Set r0 != 0 to force no branches to be taken. Also acts as a marker
3559       // between each iteration in the disassembly.
3560       __ Mov(r0, 1);
3561 
3562       for (;;) {
3563         uint32_t inst_case = static_cast<uint32_t>(mrand48()) % case_count;
3564         uint32_t label_index = static_cast<uint32_t>(mrand48()) % label_count;
3565 
3566         switch (inst_case) {
3567           case 0:  // Bind.
3568             if (!l[label_index].IsBound()) {
3569               __ Bind(&l[label_index]);
3570 
3571               // We should hit each label exactly once (because the branches are
3572               // never taken). Keep a counter to verify this.
3573               loop_count++;
3574               __ Add(r1, r1, 1);
3575             }
3576             break;
3577           case 1:  // Compare and branch if zero (untaken as r0 == 1).
3578             __ Cbz(r0, &l[label_index]);
3579             break;
3580           case 2: {  // Compare and branch if not zero.
3581             Label past_branch;
3582             __ B(eq, &past_branch, kNear);
3583             __ Cbnz(r0, &l[label_index]);
3584             __ Bind(&past_branch);
3585             break;
3586           }
3587           case 3: {  // Unconditional branch preferred near.
3588             Label past_branch;
3589             __ B(eq, &past_branch, kNear);
3590             __ B(&l[label_index], kNear);
3591             __ Bind(&past_branch);
3592             break;
3593           }
3594           case 4:  // Conditional branch (untaken as Z set) preferred near.
3595             __ B(ne, &l[label_index], kNear);
3596             break;
3597           default:  // Nop.
3598             __ Nop();
3599             break;
3600         }
3601 
3602         // If all labels have been bound, exit the inner loop and finalise the
3603         // code.
3604         bool all_bound = true;
3605         for (int i = 0; i < label_count; i++) {
3606           all_bound = all_bound && l[i].IsBound();
3607         }
3608         if (all_bound) break;
3609       }
3610 
3611       // Ensure that the veneer pools are emitted, to keep each branch/bind test
3612       // independent. We will generate more code following this.
3613       masm.FinalizeCode(MacroAssembler::kFallThrough);
3614       delete[] l;
3615     }
3616   }
3617 
3618   END();
3619   RUN();
3620 
3621   ASSERT_EQUAL_32(loop_count, r1);
3622 }
3623 
3624 
NearBranchAndLiteralFuzzHelper(InstructionSet isa,int shard_count,int shard_offset)3625 static void NearBranchAndLiteralFuzzHelper(InstructionSet isa,
3626                                            int shard_count,
3627                                            int shard_offset) {
3628   SETUP();
3629   START();
3630 
3631   uint16_t seed[3] = {1, 2, 3};
3632   seed48(seed);
3633 
3634   const int label_count = 15;
3635   const int literal_count = 31;
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   VIXL_CHECK((iterations % shard_count) == 0);
3645 
3646   int loop_count = 0;
3647   __ Mov(r1, 0);
3648 
3649   // If the value of r4 changes then the test fails.
3650   __ Mov(r4, 42);
3651 
3652   // This test generates a mix of 20 different code sequences (see switch case
3653   // below). The cases are split in 4 groups:
3654   //
3655   //   - 0..3: Generate various amount of nops.
3656   //   - 4..7: Generate various load intstructions with literals.
3657   //   - 8..14: Generate various branch instructions.
3658   //   - 15..19: Generate various amount of nops.
3659   //
3660   // The idea behind this is that we can have a window of size N which we can
3661   // slide across these cases. And as a result, randomly generate sequences with
3662   // a different ratio of:
3663   //   - "nops vs literals"
3664   //   - "literal vs veneers"
3665   //   - "veneers vs nops"
3666   //
3667   // In this test, we grow a window from 5 to 14, and then slide this window
3668   // across all cases each time. We call this sliding a "ratio", which is in
3669   // fact an offset from the first case of the switch.
3670 
3671   for (uint32_t window = 5; window < 14; window++) {
3672     for (uint32_t ratio = 0; ratio < static_cast<uint32_t>(n_cases - window);
3673          ratio++) {
3674       for (int iter = shard_offset; iter < iterations; iter += shard_count) {
3675         Label fail;
3676         Label end;
3677 
3678         // Reset local state.
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           bool all_bound = true;
3862           for (int i = 0; i < label_count; i++) {
3863             all_bound = all_bound && labels[i].IsBound();
3864           }
3865           if (all_bound) 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 
TEST_T32(near_branch_and_literal_fuzz_0)3892 TEST_T32(near_branch_and_literal_fuzz_0) {
3893   NearBranchAndLiteralFuzzHelper(isa, 4, 0);
3894 }
3895 
TEST_T32(near_branch_and_literal_fuzz_1)3896 TEST_T32(near_branch_and_literal_fuzz_1) {
3897   NearBranchAndLiteralFuzzHelper(isa, 4, 1);
3898 }
3899 
TEST_T32(near_branch_and_literal_fuzz_2)3900 TEST_T32(near_branch_and_literal_fuzz_2) {
3901   NearBranchAndLiteralFuzzHelper(isa, 4, 2);
3902 }
3903 
TEST_T32(near_branch_and_literal_fuzz_3)3904 TEST_T32(near_branch_and_literal_fuzz_3) {
3905   NearBranchAndLiteralFuzzHelper(isa, 4, 3);
3906 }
3907 
3908 #ifdef VIXL_INCLUDE_TARGET_T32
TEST_NOASM(code_buffer_precise_growth)3909 TEST_NOASM(code_buffer_precise_growth) {
3910   static const int kBaseBufferSize = 16;
3911   MacroAssembler masm(kBaseBufferSize, T32);
3912 
3913   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3914 
3915   {
3916     // Fill the buffer with nops.
3917     ExactAssemblyScope scope(&masm,
3918                              kBaseBufferSize,
3919                              ExactAssemblyScope::kExactSize);
3920     for (int i = 0; i < kBaseBufferSize; i += k16BitT32InstructionSizeInBytes) {
3921       __ nop();
3922     }
3923   }
3924 
3925   // The buffer should not have grown yet.
3926   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3927 
3928   // Generating a single instruction should force the buffer to grow.
3929   __ Nop();
3930 
3931   VIXL_CHECK(masm.GetBuffer()->GetCapacity() > kBaseBufferSize);
3932 
3933   masm.FinalizeCode();
3934 }
3935 #endif
3936 
3937 #ifdef VIXL_INCLUDE_TARGET_T32
TEST_NOASM(out_of_space_immediately_before_EnsureEmitFor)3938 TEST_NOASM(out_of_space_immediately_before_EnsureEmitFor) {
3939   static const int kBaseBufferSize = 64;
3940   MacroAssembler masm(kBaseBufferSize, T32);
3941   TestMacroAssembler test(&masm);
3942 
3943   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3944 
3945   VIXL_CHECK(test.PoolIsEmpty());
3946 
3947   // Create a veneer.
3948   Label target;
3949   __ Cbz(r0, &target);
3950 
3951   VIXL_CHECK(!test.PoolIsEmpty());
3952 
3953   VIXL_CHECK(IsUint32(masm.GetBuffer()->GetRemainingBytes()));
3954   uint32_t space = static_cast<uint32_t>(masm.GetBuffer()->GetRemainingBytes());
3955   {
3956     // Fill the buffer with nops.
3957     ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
3958     for (uint32_t i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
3959       __ nop();
3960     }
3961   }
3962 
3963   VIXL_CHECK(!test.PoolIsEmpty());
3964 
3965   // The buffer should not have grown yet, and there should be no space left.
3966   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3967   VIXL_CHECK(masm.GetBuffer()->GetRemainingBytes() == 0);
3968 
3969   // Force emission of the veneer, at a point where there is no space available
3970   // in the buffer.
3971   int32_t past_cbz_range =
3972       test.GetPoolCheckpoint() - masm.GetCursorOffset() + 1;
3973   masm.EnsureEmitFor(past_cbz_range);
3974 
3975   __ Bind(&target);
3976 
3977   VIXL_CHECK(test.PoolIsEmpty());
3978 
3979   masm.FinalizeCode();
3980 }
3981 #endif
3982 
3983 
TEST_NOASM(EnsureEmitFor)3984 TEST_NOASM(EnsureEmitFor) {
3985   static const int kBaseBufferSize = 32;
3986   MacroAssembler masm(kBaseBufferSize);
3987 
3988   VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3989 
3990   VIXL_CHECK(IsUint32(masm.GetBuffer()->GetRemainingBytes()));
3991   int32_t space = static_cast<int32_t>(masm.GetBuffer()->GetRemainingBytes());
3992   int32_t end = __ GetCursorOffset() + space;
3993   {
3994     // Fill the buffer with nops.
3995     ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
3996     while (__ GetCursorOffset() != end) {
3997       __ nop();
3998     }
3999   }
4000 
4001   // Test that EnsureEmitFor works.
4002   VIXL_CHECK(!masm.GetBuffer()->HasSpaceFor(4));
4003   masm.EnsureEmitFor(4);
4004   VIXL_CHECK(masm.GetBuffer()->HasSpaceFor(4));
4005   __ Nop();
4006 
4007   masm.FinalizeCode();
4008 }
4009 
TEST_T32(distant_literal_references)4010 TEST_T32(distant_literal_references) {
4011   SETUP();
4012   START();
4013 
4014   Literal<uint64_t>* literal =
4015       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4016                             RawLiteral::kPlacedWhenUsed,
4017                             RawLiteral::kDeletedOnPoolDestruction);
4018   // Refer to the literal so that it is emitted early.
4019   __ Ldr(r0, literal);
4020 
4021   // Add enough nops to exceed the range of all loads.
4022   int space = 5000;
4023   {
4024     ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
4025     VIXL_ASSERT(masm.IsUsingT32());
4026     for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
4027       __ nop();
4028     }
4029   }
4030 
4031 #define ENSURE_ALIGNED()                                                      \
4032   do {                                                                        \
4033     if (!IsMultiple<k32BitT32InstructionSizeInBytes>(                         \
4034             masm.GetCursorOffset())) {                                        \
4035       ExactAssemblyScope scope(&masm,                                         \
4036                                k16BitT32InstructionSizeInBytes,               \
4037                                ExactAssemblyScope::kExactSize);               \
4038       __ nop();                                                               \
4039     }                                                                         \
4040     VIXL_ASSERT(                                                              \
4041         IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
4042   } while (0)
4043 
4044   // The literal has already been emitted, and is out of range of all of these
4045   // instructions. The delegates must generate fix-up code.
4046   ENSURE_ALIGNED();
4047   __ Ldr(r1, literal);
4048   ENSURE_ALIGNED();
4049   __ Ldrb(r2, literal);
4050   ENSURE_ALIGNED();
4051   __ Ldrsb(r3, literal);
4052   ENSURE_ALIGNED();
4053   __ Ldrh(r4, literal);
4054   ENSURE_ALIGNED();
4055   __ Ldrsh(r5, literal);
4056   ENSURE_ALIGNED();
4057   __ Ldrd(r6, r7, literal);
4058   ENSURE_ALIGNED();
4059   __ Vldr(d0, literal);
4060   ENSURE_ALIGNED();
4061   __ Vldr(s3, literal);
4062 
4063 #undef ENSURE_ALIGNED
4064 
4065   END();
4066   RUN();
4067 
4068   // Check that the literals loaded correctly.
4069   ASSERT_EQUAL_32(0x89abcdef, r0);
4070   ASSERT_EQUAL_32(0x89abcdef, r1);
4071   ASSERT_EQUAL_32(0xef, r2);
4072   ASSERT_EQUAL_32(0xffffffef, r3);
4073   ASSERT_EQUAL_32(0xcdef, r4);
4074   ASSERT_EQUAL_32(0xffffcdef, r5);
4075   ASSERT_EQUAL_32(0x89abcdef, r6);
4076   ASSERT_EQUAL_32(0x01234567, r7);
4077   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4078   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4079 }
4080 
4081 
TEST_T32(distant_literal_references_unaligned_pc)4082 TEST_T32(distant_literal_references_unaligned_pc) {
4083   SETUP();
4084   START();
4085 
4086   Literal<uint64_t>* literal =
4087       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4088                             RawLiteral::kPlacedWhenUsed,
4089                             RawLiteral::kDeletedOnPoolDestruction);
4090   // Refer to the literal so that it is emitted early.
4091   __ Ldr(r0, literal);
4092 
4093   // Add enough nops to exceed the range of all loads, leaving the PC aligned
4094   // to only a two-byte boundary.
4095   int space = 5002;
4096   {
4097     ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
4098     VIXL_ASSERT(masm.IsUsingT32());
4099     for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
4100       __ nop();
4101     }
4102   }
4103 
4104 #define ENSURE_NOT_ALIGNED()                                                   \
4105   do {                                                                         \
4106     if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
4107       ExactAssemblyScope scope(&masm,                                          \
4108                                k16BitT32InstructionSizeInBytes,                \
4109                                ExactAssemblyScope::kExactSize);                \
4110       __ nop();                                                                \
4111     }                                                                          \
4112     VIXL_ASSERT(                                                               \
4113         !IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
4114   } while (0)
4115 
4116   // The literal has already been emitted, and is out of range of all of these
4117   // instructions. The delegates must generate fix-up code.
4118   ENSURE_NOT_ALIGNED();
4119   __ Ldr(r1, literal);
4120   ENSURE_NOT_ALIGNED();
4121   __ Ldrb(r2, literal);
4122   ENSURE_NOT_ALIGNED();
4123   __ Ldrsb(r3, literal);
4124   ENSURE_NOT_ALIGNED();
4125   __ Ldrh(r4, literal);
4126   ENSURE_NOT_ALIGNED();
4127   __ Ldrsh(r5, literal);
4128   ENSURE_NOT_ALIGNED();
4129   __ Ldrd(r6, r7, literal);
4130   {
4131     // TODO: We currently require an extra scratch register for these cases
4132     // because MemOperandComputationHelper isn't able to fit add_sub_offset into
4133     // a single 'sub' instruction, so 'pc' gets preserved first. The same
4134     // problem technically exists for the other loads, but vldr is particularly
4135     // badly affected because vldr cannot set the low bits in its offset mask,
4136     // so the add/sub operand is likely to be difficult to encode.
4137     //
4138     // At the moment, we get this:
4139     //     mov r8, pc
4140     //     mov ip, #5118
4141     //     sub r8, pc
4142     //     vldr d0, [r8, #48]
4143     //
4144     // We should be able to generate something like this:
4145     //     sub ip, pc, #0x1300    // 5118 & 0xff00
4146     //     sub ip, #0xfe          // 5118 & 0x00ff
4147     //     vldr d0, [ip, #48]
4148     UseScratchRegisterScope temps(&masm);
4149     temps.Include(r8);
4150     ENSURE_NOT_ALIGNED();
4151     __ Vldr(d0, literal);
4152     ENSURE_NOT_ALIGNED();
4153     __ Vldr(s3, literal);
4154   }
4155 
4156 #undef ENSURE_NOT_ALIGNED
4157 
4158   END();
4159   RUN();
4160 
4161   // Check that the literals loaded correctly.
4162   ASSERT_EQUAL_32(0x89abcdef, r0);
4163   ASSERT_EQUAL_32(0x89abcdef, r1);
4164   ASSERT_EQUAL_32(0xef, r2);
4165   ASSERT_EQUAL_32(0xffffffef, r3);
4166   ASSERT_EQUAL_32(0xcdef, r4);
4167   ASSERT_EQUAL_32(0xffffcdef, r5);
4168   ASSERT_EQUAL_32(0x89abcdef, r6);
4169   ASSERT_EQUAL_32(0x01234567, r7);
4170   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4171   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4172 }
4173 
4174 
TEST_T32(distant_literal_references_short_range)4175 TEST_T32(distant_literal_references_short_range) {
4176   SETUP();
4177   START();
4178 
4179   Literal<uint64_t>* literal =
4180       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4181                             RawLiteral::kPlacedWhenUsed,
4182                             RawLiteral::kDeletedOnPoolDestruction);
4183   // Refer to the literal so that it is emitted early.
4184   __ Vldr(s4, literal);
4185 
4186   // Add enough nops to exceed the range of the loads, but not the adr that will
4187   // be generated to read the PC.
4188   int space = 4000;
4189   {
4190     ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
4191     VIXL_ASSERT(masm.IsUsingT32());
4192     for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
4193       __ nop();
4194     }
4195   }
4196 
4197 #define ENSURE_ALIGNED()                                                      \
4198   do {                                                                        \
4199     if (!IsMultiple<k32BitT32InstructionSizeInBytes>(                         \
4200             masm.GetCursorOffset())) {                                        \
4201       ExactAssemblyScope scope(&masm,                                         \
4202                                k16BitT32InstructionSizeInBytes,               \
4203                                ExactAssemblyScope::kExactSize);               \
4204       __ nop();                                                               \
4205     }                                                                         \
4206     VIXL_ASSERT(                                                              \
4207         IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
4208   } while (0)
4209 
4210   // The literal has already been emitted, and is out of range of all of these
4211   // instructions. The delegates must generate fix-up code.
4212   ENSURE_ALIGNED();
4213   __ Ldr(r1, literal);
4214   ENSURE_ALIGNED();
4215   __ Ldrb(r2, literal);
4216   ENSURE_ALIGNED();
4217   __ Ldrsb(r3, literal);
4218   ENSURE_ALIGNED();
4219   __ Ldrh(r4, literal);
4220   ENSURE_ALIGNED();
4221   __ Ldrsh(r5, literal);
4222   ENSURE_ALIGNED();
4223   __ Ldrd(r6, r7, literal);
4224   ENSURE_ALIGNED();
4225   __ Vldr(d0, literal);
4226   ENSURE_ALIGNED();
4227   __ Vldr(s3, literal);
4228 
4229 #undef ENSURE_ALIGNED
4230 
4231   END();
4232   RUN();
4233 
4234   // Check that the literals loaded correctly.
4235   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s4);
4236   ASSERT_EQUAL_32(0x89abcdef, r1);
4237   ASSERT_EQUAL_32(0xef, r2);
4238   ASSERT_EQUAL_32(0xffffffef, r3);
4239   ASSERT_EQUAL_32(0xcdef, r4);
4240   ASSERT_EQUAL_32(0xffffcdef, r5);
4241   ASSERT_EQUAL_32(0x89abcdef, r6);
4242   ASSERT_EQUAL_32(0x01234567, r7);
4243   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4244   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4245 }
4246 
4247 
TEST_T32(distant_literal_references_short_range_unaligned_pc)4248 TEST_T32(distant_literal_references_short_range_unaligned_pc) {
4249   SETUP();
4250   START();
4251 
4252   Literal<uint64_t>* literal =
4253       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4254                             RawLiteral::kPlacedWhenUsed,
4255                             RawLiteral::kDeletedOnPoolDestruction);
4256   // Refer to the literal so that it is emitted early.
4257   __ Vldr(s4, literal);
4258 
4259   // Add enough nops to exceed the range of the loads, but not the adr that will
4260   // be generated to read the PC.
4261   int space = 4000;
4262   {
4263     ExactAssemblyScope scope(&masm, space, CodeBufferCheckScope::kExactSize);
4264     VIXL_ASSERT(masm.IsUsingT32());
4265     for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
4266       __ nop();
4267     }
4268   }
4269 
4270 #define ENSURE_NOT_ALIGNED()                                                   \
4271   do {                                                                         \
4272     if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
4273       ExactAssemblyScope scope(&masm,                                          \
4274                                k16BitT32InstructionSizeInBytes,                \
4275                                ExactAssemblyScope::kExactSize);                \
4276       __ nop();                                                                \
4277     }                                                                          \
4278     VIXL_ASSERT(                                                               \
4279         !IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())); \
4280   } while (0)
4281 
4282   // The literal has already been emitted, and is out of range of all of these
4283   // instructions. The delegates must generate fix-up code.
4284   ENSURE_NOT_ALIGNED();
4285   __ Ldr(r1, literal);
4286   ENSURE_NOT_ALIGNED();
4287   __ Ldrb(r2, literal);
4288   ENSURE_NOT_ALIGNED();
4289   __ Ldrsb(r3, literal);
4290   ENSURE_NOT_ALIGNED();
4291   __ Ldrh(r4, literal);
4292   ENSURE_NOT_ALIGNED();
4293   __ Ldrsh(r5, literal);
4294   ENSURE_NOT_ALIGNED();
4295   __ Ldrd(r6, r7, literal);
4296   ENSURE_NOT_ALIGNED();
4297   __ Vldr(d0, literal);
4298   ENSURE_NOT_ALIGNED();
4299   __ Vldr(s3, literal);
4300 
4301 #undef ENSURE_NOT_ALIGNED
4302 
4303   END();
4304   RUN();
4305 
4306   // Check that the literals loaded correctly.
4307   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s4);
4308   ASSERT_EQUAL_32(0x89abcdef, r1);
4309   ASSERT_EQUAL_32(0xef, r2);
4310   ASSERT_EQUAL_32(0xffffffef, r3);
4311   ASSERT_EQUAL_32(0xcdef, r4);
4312   ASSERT_EQUAL_32(0xffffcdef, r5);
4313   ASSERT_EQUAL_32(0x89abcdef, r6);
4314   ASSERT_EQUAL_32(0x01234567, r7);
4315   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4316   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4317 }
4318 
4319 
TEST_T32(distant_literal_references_long_range)4320 TEST_T32(distant_literal_references_long_range) {
4321   SETUP();
4322   START();
4323 
4324   Literal<uint64_t>* literal =
4325       new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
4326                             RawLiteral::kPlacedWhenUsed,
4327                             RawLiteral::kDeletedOnPoolDestruction);
4328   // Refer to the literal so that it is emitted early.
4329   __ Ldr(r0, literal);
4330 
4331 #define PAD_WITH_NOPS(space)                                             \
4332   do {                                                                   \
4333     {                                                                    \
4334       ExactAssemblyScope scope(&masm,                                    \
4335                                space,                                    \
4336                                CodeBufferCheckScope::kExactSize);        \
4337       VIXL_ASSERT(masm.IsUsingT32());                                    \
4338       for (int i = 0; i < space; i += k16BitT32InstructionSizeInBytes) { \
4339         __ nop();                                                        \
4340       }                                                                  \
4341     }                                                                    \
4342   } while (0)
4343 
4344   // Add enough nops to exceed the range of all loads.
4345   PAD_WITH_NOPS(5000);
4346 
4347   // The literal has already been emitted, and is out of range of all of these
4348   // instructions. The delegates must generate fix-up code.
4349   __ Ldr(r1, literal);
4350   __ Ldrb(r2, literal);
4351   __ Ldrsb(r3, literal);
4352   __ Ldrh(r4, literal);
4353   __ Ldrsh(r5, literal);
4354   __ Ldrd(r6, r7, literal);
4355   __ Vldr(d0, literal);
4356   __ Vldr(s3, literal);
4357 
4358   // Add enough nops to exceed the range of the adr+sub sequence.
4359   PAD_WITH_NOPS(0x421000);
4360 
4361   __ Ldr(r1, literal);
4362   __ Ldrb(r2, literal);
4363   __ Ldrsb(r3, literal);
4364   __ Ldrh(r4, literal);
4365   __ Ldrsh(r5, literal);
4366   __ Ldrd(r6, r7, literal);
4367   {
4368     // TODO: We currently require an extra scratch register for these cases. We
4369     // should be able to optimise the code generation to avoid this requirement
4370     // (and in many cases avoid a 32-bit instruction).
4371     UseScratchRegisterScope temps(&masm);
4372     temps.Include(r8);
4373     __ Vldr(d0, literal);
4374     __ Vldr(s3, literal);
4375   }
4376 
4377 #undef PAD_WITH_NOPS
4378 
4379   END();
4380   RUN();
4381 
4382   // Check that the literals loaded correctly.
4383   ASSERT_EQUAL_32(0x89abcdef, r0);
4384   ASSERT_EQUAL_32(0x89abcdef, r1);
4385   ASSERT_EQUAL_32(0xef, r2);
4386   ASSERT_EQUAL_32(0xffffffef, r3);
4387   ASSERT_EQUAL_32(0xcdef, r4);
4388   ASSERT_EQUAL_32(0xffffcdef, r5);
4389   ASSERT_EQUAL_32(0x89abcdef, r6);
4390   ASSERT_EQUAL_32(0x01234567, r7);
4391   ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
4392   ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
4393 }
4394 
4395 
TEST(barriers)4396 TEST(barriers) {
4397   // Generate all supported barriers, this is just a smoke test
4398   SETUP();
4399 
4400   START();
4401 
4402   // DMB
4403   __ Dmb(SY);
4404   __ Dmb(ST);
4405   __ Dmb(ISH);
4406   __ Dmb(ISHST);
4407   __ Dmb(NSH);
4408   __ Dmb(NSHST);
4409   __ Dmb(OSH);
4410   __ Dmb(OSHST);
4411 
4412   // DSB
4413   __ Dsb(SY);
4414   __ Dsb(ST);
4415   __ Dsb(ISH);
4416   __ Dsb(ISHST);
4417   __ Dsb(NSH);
4418   __ Dsb(NSHST);
4419   __ Dsb(OSH);
4420   __ Dsb(OSHST);
4421 
4422   // ISB
4423   __ Isb(SY);
4424 
4425   END();
4426 }
4427 
4428 
TEST(preloads)4429 TEST(preloads) {
4430   // Smoke test for various pld/pli forms.
4431   SETUP();
4432 
4433   START();
4434 
4435   // PLD immediate
4436   __ Pld(MemOperand(sp, 0));
4437   __ Pld(MemOperand(r0, 0));
4438   __ Pld(MemOperand(r1, 123));
4439   __ Pld(MemOperand(r2, 1234));
4440   __ Pld(MemOperand(r3, 4095));
4441   __ Pld(MemOperand(r4, -123));
4442   __ Pld(MemOperand(r5, -255));
4443 
4444   if (masm.IsUsingA32()) {
4445     __ Pld(MemOperand(r6, -1234));
4446     __ Pld(MemOperand(r7, -4095));
4447   }
4448 
4449 
4450   // PLDW immediate
4451   __ Pldw(MemOperand(sp, 0));
4452   __ Pldw(MemOperand(r0, 0));
4453   __ Pldw(MemOperand(r1, 123));
4454   __ Pldw(MemOperand(r2, 1234));
4455   __ Pldw(MemOperand(r3, 4095));
4456   __ Pldw(MemOperand(r4, -123));
4457   __ Pldw(MemOperand(r5, -255));
4458 
4459   if (masm.IsUsingA32()) {
4460     __ Pldw(MemOperand(r6, -1234));
4461     __ Pldw(MemOperand(r7, -4095));
4462   }
4463 
4464   // PLD register
4465   __ Pld(MemOperand(r0, r1));
4466   __ Pld(MemOperand(r0, r1, LSL, 1));
4467   __ Pld(MemOperand(r0, r1, LSL, 2));
4468   __ Pld(MemOperand(r0, r1, LSL, 3));
4469 
4470   if (masm.IsUsingA32()) {
4471     __ Pld(MemOperand(r0, r1, LSL, 4));
4472     __ Pld(MemOperand(r0, r1, LSL, 20));
4473   }
4474 
4475   // PLDW register
4476   __ Pldw(MemOperand(r0, r1));
4477   __ Pldw(MemOperand(r0, r1, LSL, 1));
4478   __ Pldw(MemOperand(r0, r1, LSL, 2));
4479   __ Pldw(MemOperand(r0, r1, LSL, 3));
4480 
4481   if (masm.IsUsingA32()) {
4482     __ Pldw(MemOperand(r0, r1, LSL, 4));
4483     __ Pldw(MemOperand(r0, r1, LSL, 20));
4484   }
4485 
4486   // PLI immediate
4487   __ Pli(MemOperand(sp, 0));
4488   __ Pli(MemOperand(r0, 0));
4489   __ Pli(MemOperand(r1, 123));
4490   __ Pli(MemOperand(r2, 1234));
4491   __ Pli(MemOperand(r3, 4095));
4492   __ Pli(MemOperand(r4, -123));
4493   __ Pli(MemOperand(r5, -255));
4494 
4495   if (masm.IsUsingA32()) {
4496     __ Pli(MemOperand(r6, -1234));
4497     __ Pli(MemOperand(r7, -4095));
4498   }
4499 
4500   // PLI register
4501   __ Pli(MemOperand(r0, r1));
4502   __ Pli(MemOperand(r0, r1, LSL, 1));
4503   __ Pli(MemOperand(r0, r1, LSL, 2));
4504   __ Pli(MemOperand(r0, r1, LSL, 3));
4505 
4506   if (masm.IsUsingA32()) {
4507     __ Pli(MemOperand(r0, r1, LSL, 4));
4508     __ Pli(MemOperand(r0, r1, LSL, 20));
4509   }
4510 
4511   END();
4512 }
4513 
4514 
TEST_T32(veneer_mirrored_branches)4515 TEST_T32(veneer_mirrored_branches) {
4516   SETUP();
4517 
4518   START();
4519 
4520   const int kMaxBranchCount = 256;
4521 
4522   for (int branch_count = 1; branch_count < kMaxBranchCount; branch_count++) {
4523     Label* targets = new Label[branch_count];
4524 
4525     for (int i = 0; i < branch_count; i++) {
4526       __ Cbz(r0, &targets[i]);
4527     }
4528 
4529     for (int i = 0; i < branch_count; i++) {
4530       __ Bind(&targets[branch_count - i - 1]);
4531       __ Orr(r0, r0, r0);
4532     }
4533 
4534     delete[] targets;
4535   }
4536 
4537   END();
4538 }
4539 
4540 
TEST_T32(branch_fuzz_example)4541 TEST_T32(branch_fuzz_example) {
4542   SETUP();
4543 
4544   START();
4545 
4546   Label l[64];
4547   __ And(r0, r0, r0);
4548   __ Cbz(r0, &l[30]);
4549   __ And(r0, r0, r0);
4550   __ Cbz(r0, &l[22]);
4551   __ And(r0, r0, r0);
4552   __ Cbz(r0, &l[1]);
4553   __ Cbz(r0, &l[15]);
4554   __ Cbz(r0, &l[9]);
4555   __ Cbz(r0, &l[6]);
4556   __ Bind(&l[26]);
4557   __ Cbz(r0, &l[29]);
4558   __ And(r0, r0, r0);
4559   __ And(r0, r0, r0);
4560   __ Cbz(r0, &l[22]);
4561   __ Bind(&l[12]);
4562   __ Bind(&l[22]);
4563   __ Cbz(r0, &l[10]);
4564   __ And(r0, r0, r0);
4565   __ Cbz(r0, &l[30]);
4566   __ Cbz(r0, &l[17]);
4567   __ Cbz(r0, &l[27]);
4568   __ Cbz(r0, &l[11]);
4569   __ Bind(&l[7]);
4570   __ Cbz(r0, &l[18]);
4571   __ Bind(&l[14]);
4572   __ Cbz(r0, &l[1]);
4573   __ Bind(&l[18]);
4574   __ Cbz(r0, &l[11]);
4575   __ Cbz(r0, &l[6]);
4576   __ Bind(&l[21]);
4577   __ Cbz(r0, &l[28]);
4578   __ And(r0, r0, r0);
4579   __ Cbz(r0, &l[28]);
4580   __ Cbz(r0, &l[22]);
4581   __ Bind(&l[23]);
4582   __ Cbz(r0, &l[21]);
4583   __ Cbz(r0, &l[28]);
4584   __ Cbz(r0, &l[9]);
4585   __ Bind(&l[9]);
4586   __ Cbz(r0, &l[4]);
4587   __ And(r0, r0, r0);
4588   __ Cbz(r0, &l[10]);
4589   __ And(r0, r0, r0);
4590   __ Bind(&l[8]);
4591   __ And(r0, r0, r0);
4592   __ Cbz(r0, &l[10]);
4593   __ And(r0, r0, r0);
4594   __ Cbz(r0, &l[17]);
4595   __ Bind(&l[10]);
4596   __ Cbz(r0, &l[8]);
4597   __ Cbz(r0, &l[25]);
4598   __ Cbz(r0, &l[4]);
4599   __ Bind(&l[28]);
4600   __ And(r0, r0, r0);
4601   __ Cbz(r0, &l[16]);
4602   __ Bind(&l[19]);
4603   __ Cbz(r0, &l[14]);
4604   __ Cbz(r0, &l[28]);
4605   __ Cbz(r0, &l[26]);
4606   __ Cbz(r0, &l[21]);
4607   __ And(r0, r0, r0);
4608   __ Bind(&l[24]);
4609   __ And(r0, r0, r0);
4610   __ Cbz(r0, &l[24]);
4611   __ Cbz(r0, &l[24]);
4612   __ Cbz(r0, &l[19]);
4613   __ Cbz(r0, &l[26]);
4614   __ Cbz(r0, &l[4]);
4615   __ And(r0, r0, r0);
4616   __ Cbz(r0, &l[27]);
4617   __ Cbz(r0, &l[14]);
4618   __ Cbz(r0, &l[5]);
4619   __ Cbz(r0, &l[18]);
4620   __ Cbz(r0, &l[5]);
4621   __ Cbz(r0, &l[6]);
4622   __ Cbz(r0, &l[28]);
4623   __ Cbz(r0, &l[15]);
4624   __ Cbz(r0, &l[0]);
4625   __ Cbz(r0, &l[10]);
4626   __ Cbz(r0, &l[16]);
4627   __ Cbz(r0, &l[30]);
4628   __ Cbz(r0, &l[8]);
4629   __ Cbz(r0, &l[16]);
4630   __ Cbz(r0, &l[22]);
4631   __ Cbz(r0, &l[27]);
4632   __ Cbz(r0, &l[12]);
4633   __ Cbz(r0, &l[0]);
4634   __ Cbz(r0, &l[23]);
4635   __ Cbz(r0, &l[27]);
4636   __ Cbz(r0, &l[16]);
4637   __ Cbz(r0, &l[24]);
4638   __ Cbz(r0, &l[17]);
4639   __ Cbz(r0, &l[4]);
4640   __ Cbz(r0, &l[11]);
4641   __ Cbz(r0, &l[6]);
4642   __ Cbz(r0, &l[23]);
4643   __ Bind(&l[16]);
4644   __ Cbz(r0, &l[10]);
4645   __ Cbz(r0, &l[17]);
4646   __ Cbz(r0, &l[12]);
4647   __ And(r0, r0, r0);
4648   __ Cbz(r0, &l[11]);
4649   __ Cbz(r0, &l[17]);
4650   __ Cbz(r0, &l[1]);
4651   __ Cbz(r0, &l[3]);
4652   __ Cbz(r0, &l[18]);
4653   __ Bind(&l[4]);
4654   __ Cbz(r0, &l[31]);
4655   __ Cbz(r0, &l[25]);
4656   __ Cbz(r0, &l[22]);
4657   __ And(r0, r0, r0);
4658   __ Cbz(r0, &l[19]);
4659   __ Cbz(r0, &l[16]);
4660   __ Cbz(r0, &l[21]);
4661   __ Cbz(r0, &l[27]);
4662   __ Bind(&l[1]);
4663   __ Cbz(r0, &l[9]);
4664   __ Cbz(r0, &l[13]);
4665   __ Cbz(r0, &l[10]);
4666   __ Cbz(r0, &l[6]);
4667   __ Cbz(r0, &l[30]);
4668   __ Cbz(r0, &l[28]);
4669   __ Cbz(r0, &l[7]);
4670   __ Cbz(r0, &l[17]);
4671   __ Bind(&l[0]);
4672   __ Cbz(r0, &l[13]);
4673   __ Cbz(r0, &l[11]);
4674   __ Cbz(r0, &l[19]);
4675   __ Cbz(r0, &l[22]);
4676   __ Cbz(r0, &l[9]);
4677   __ And(r0, r0, r0);
4678   __ Cbz(r0, &l[15]);
4679   __ Cbz(r0, &l[31]);
4680   __ Cbz(r0, &l[2]);
4681   __ And(r0, r0, r0);
4682   __ Cbz(r0, &l[6]);
4683   __ Bind(&l[27]);
4684   __ Bind(&l[13]);
4685   __ Cbz(r0, &l[23]);
4686   __ Cbz(r0, &l[7]);
4687   __ Bind(&l[2]);
4688   __ And(r0, r0, r0);
4689   __ Cbz(r0, &l[1]);
4690   __ Bind(&l[15]);
4691   __ Cbz(r0, &l[13]);
4692   __ Cbz(r0, &l[17]);
4693   __ Cbz(r0, &l[8]);
4694   __ Cbz(r0, &l[30]);
4695   __ Cbz(r0, &l[8]);
4696   __ Cbz(r0, &l[27]);
4697   __ Cbz(r0, &l[2]);
4698   __ Cbz(r0, &l[31]);
4699   __ Cbz(r0, &l[4]);
4700   __ Cbz(r0, &l[11]);
4701   __ Bind(&l[29]);
4702   __ Cbz(r0, &l[7]);
4703   __ Cbz(r0, &l[5]);
4704   __ Cbz(r0, &l[11]);
4705   __ Cbz(r0, &l[24]);
4706   __ Cbz(r0, &l[9]);
4707   __ Cbz(r0, &l[3]);
4708   __ Cbz(r0, &l[3]);
4709   __ Cbz(r0, &l[22]);
4710   __ Cbz(r0, &l[19]);
4711   __ Cbz(r0, &l[4]);
4712   __ Bind(&l[6]);
4713   __ And(r0, r0, r0);
4714   __ And(r0, r0, r0);
4715   __ Cbz(r0, &l[9]);
4716   __ Cbz(r0, &l[3]);
4717   __ Cbz(r0, &l[23]);
4718   __ Cbz(r0, &l[12]);
4719   __ Cbz(r0, &l[1]);
4720   __ Cbz(r0, &l[22]);
4721   __ Cbz(r0, &l[24]);
4722   __ And(r0, r0, r0);
4723   __ Cbz(r0, &l[16]);
4724   __ Cbz(r0, &l[19]);
4725   __ Cbz(r0, &l[20]);
4726   __ Cbz(r0, &l[1]);
4727   __ Cbz(r0, &l[4]);
4728   __ Cbz(r0, &l[1]);
4729   __ Cbz(r0, &l[25]);
4730   __ Cbz(r0, &l[21]);
4731   __ Cbz(r0, &l[20]);
4732   __ Cbz(r0, &l[29]);
4733   __ And(r0, r0, r0);
4734   __ Cbz(r0, &l[10]);
4735   __ Cbz(r0, &l[5]);
4736   __ And(r0, r0, r0);
4737   __ Cbz(r0, &l[25]);
4738   __ Cbz(r0, &l[26]);
4739   __ Cbz(r0, &l[28]);
4740   __ Cbz(r0, &l[19]);
4741   __ And(r0, r0, r0);
4742   __ Bind(&l[17]);
4743   __ And(r0, r0, r0);
4744   __ And(r0, r0, r0);
4745   __ And(r0, r0, r0);
4746   __ And(r0, r0, r0);
4747   __ Cbz(r0, &l[6]);
4748   __ And(r0, r0, r0);
4749   __ Cbz(r0, &l[5]);
4750   __ Cbz(r0, &l[26]);
4751   __ Cbz(r0, &l[28]);
4752   __ Cbz(r0, &l[24]);
4753   __ Bind(&l[20]);
4754   __ And(r0, r0, r0);
4755   __ Cbz(r0, &l[10]);
4756   __ Cbz(r0, &l[19]);
4757   __ Cbz(r0, &l[6]);
4758   __ And(r0, r0, r0);
4759   __ Cbz(r0, &l[13]);
4760   __ Cbz(r0, &l[15]);
4761   __ Cbz(r0, &l[22]);
4762   __ Cbz(r0, &l[8]);
4763   __ Cbz(r0, &l[6]);
4764   __ Cbz(r0, &l[23]);
4765   __ Cbz(r0, &l[6]);
4766   __ And(r0, r0, r0);
4767   __ Cbz(r0, &l[13]);
4768   __ Bind(&l[31]);
4769   __ Cbz(r0, &l[14]);
4770   __ Cbz(r0, &l[5]);
4771   __ Cbz(r0, &l[1]);
4772   __ Cbz(r0, &l[17]);
4773   __ Cbz(r0, &l[27]);
4774   __ Cbz(r0, &l[10]);
4775   __ Cbz(r0, &l[30]);
4776   __ Cbz(r0, &l[14]);
4777   __ Cbz(r0, &l[24]);
4778   __ Cbz(r0, &l[26]);
4779   __ And(r0, r0, r0);
4780   __ Cbz(r0, &l[2]);
4781   __ Cbz(r0, &l[21]);
4782   __ Cbz(r0, &l[5]);
4783   __ Cbz(r0, &l[24]);
4784   __ And(r0, r0, r0);
4785   __ Cbz(r0, &l[24]);
4786   __ Cbz(r0, &l[17]);
4787   __ And(r0, r0, r0);
4788   __ And(r0, r0, r0);
4789   __ Cbz(r0, &l[24]);
4790   __ And(r0, r0, r0);
4791   __ Cbz(r0, &l[17]);
4792   __ Cbz(r0, &l[12]);
4793   __ And(r0, r0, r0);
4794   __ Cbz(r0, &l[9]);
4795   __ Cbz(r0, &l[9]);
4796   __ Cbz(r0, &l[31]);
4797   __ Cbz(r0, &l[25]);
4798   __ And(r0, r0, r0);
4799   __ And(r0, r0, r0);
4800   __ Cbz(r0, &l[13]);
4801   __ Cbz(r0, &l[14]);
4802   __ Cbz(r0, &l[5]);
4803   __ Cbz(r0, &l[5]);
4804   __ Cbz(r0, &l[12]);
4805   __ Cbz(r0, &l[3]);
4806   __ Cbz(r0, &l[25]);
4807   __ Bind(&l[11]);
4808   __ Cbz(r0, &l[15]);
4809   __ Cbz(r0, &l[20]);
4810   __ Cbz(r0, &l[22]);
4811   __ Cbz(r0, &l[19]);
4812   __ And(r0, r0, r0);
4813   __ Cbz(r0, &l[19]);
4814   __ And(r0, r0, r0);
4815   __ Cbz(r0, &l[21]);
4816   __ Cbz(r0, &l[0]);
4817   __ And(r0, r0, r0);
4818   __ Cbz(r0, &l[16]);
4819   __ Cbz(r0, &l[28]);
4820   __ Cbz(r0, &l[18]);
4821   __ Cbz(r0, &l[3]);
4822   __ And(r0, r0, r0);
4823   __ Cbz(r0, &l[15]);
4824   __ Cbz(r0, &l[8]);
4825   __ Cbz(r0, &l[25]);
4826   __ Cbz(r0, &l[1]);
4827   __ Cbz(r0, &l[21]);
4828   __ Cbz(r0, &l[1]);
4829   __ Cbz(r0, &l[29]);
4830   __ Cbz(r0, &l[15]);
4831   __ And(r0, r0, r0);
4832   __ Cbz(r0, &l[24]);
4833   __ Cbz(r0, &l[3]);
4834   __ Cbz(r0, &l[9]);
4835   __ Cbz(r0, &l[9]);
4836   __ Cbz(r0, &l[24]);
4837   __ And(r0, r0, r0);
4838   __ Cbz(r0, &l[19]);
4839   __ And(r0, r0, r0);
4840   __ Cbz(r0, &l[30]);
4841   __ Bind(&l[25]);
4842   __ Bind(&l[3]);
4843   __ Bind(&l[30]);
4844   __ Bind(&l[5]);
4845 
4846   END();
4847 }
4848 
4849 
4850 // Generate a "B" and a "Cbz" which have the same checkpoint. Without proper
4851 // management (i.e. if the veneers were only generated at the shared
4852 // checkpoint), one one of the branches would be out of range.
TEST_T32(veneer_simultaneous)4853 TEST_T32(veneer_simultaneous) {
4854   SETUP();
4855 
4856   START();
4857 
4858   // `2046` max range - the size of the B.EQ itself.
4859   static const int kMaxBCondRange = 1048574;
4860 
4861   Label target_1;
4862   Label target_2;
4863 
4864   __ B(eq, &target_1);
4865 
4866   int target_1_size_1 =
4867       kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
4868   int end_1 = masm.GetCursorOffset() + target_1_size_1;
4869   while (masm.GetCursorOffset() < end_1) {
4870     __ Nop();
4871   }
4872 
4873   __ Cbz(r0, &target_2);
4874 
4875   int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
4876   int end_2 = masm.GetCursorOffset() + target_1_size_2;
4877   while (masm.GetCursorOffset() < end_2) {
4878     __ Nop();
4879   }
4880 
4881   __ Nop();
4882 
4883   __ Bind(&target_1);
4884   __ Bind(&target_2);
4885 
4886   END();
4887 }
4888 
4889 
4890 // Generate a "B" and a "Cbz" which have the same checkpoint and the same label.
TEST_T32(veneer_simultaneous_one_label)4891 TEST_T32(veneer_simultaneous_one_label) {
4892   SETUP();
4893 
4894   START();
4895 
4896   // `2046` max range - the size of the B.EQ itself.
4897   static const int kMaxBCondRange = 1048574;
4898 
4899   Label target;
4900 
4901   __ B(eq, &target);
4902 
4903   int target_1_size_1 =
4904       kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
4905   int end_1 = masm.GetCursorOffset() + target_1_size_1;
4906   while (masm.GetCursorOffset() < end_1) {
4907     __ Nop();
4908   }
4909 
4910   __ Cbz(r0, &target);
4911 
4912   int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
4913   int end_2 = masm.GetCursorOffset() + target_1_size_2;
4914   while (masm.GetCursorOffset() < end_2) {
4915     __ Nop();
4916   }
4917 
4918   __ Nop();
4919 
4920   __ Bind(&target);
4921 
4922   END();
4923 }
4924 
4925 // NOTE: This test has needed modifications for the new pool manager, as it
4926 // was testing a corner case of the previous pool managers. We keep it as
4927 // another testcase.
TEST_T32(veneer_and_literal)4928 TEST_T32(veneer_and_literal) {
4929   SETUP();
4930 
4931   START();
4932 
4933   VIXL_CHECK(test.PoolIsEmpty());
4934 
4935   const uint32_t ldrd_range = 1020;
4936   const uint32_t cbz_range = 126;
4937   const uint32_t kLabelsCount = 20;
4938   Label labels[kLabelsCount];
4939 
4940   // Create one literal pool entry.
4941   __ Ldrd(r0, r1, 0x1234567890abcdef);
4942 
4943   // Generate some nops.
4944   uint32_t i = 0;
4945   for (; i < ldrd_range - cbz_range - 40;
4946        i += k16BitT32InstructionSizeInBytes) {
4947     __ Nop();
4948   }
4949 
4950   // At this point, it remains cbz_range + 40 => 166 bytes before ldrd becomes
4951   // out of range.
4952   // We generate kLabelsCount * 4 => 80 bytes. We shouldn't generate the
4953   // literal pool.
4954   for (uint32_t j = 0; j < kLabelsCount; j++) {
4955     __ Cbz(r0, &labels[j]);
4956     __ Nop();
4957     i += 2 * k16BitT32InstructionSizeInBytes;
4958   }
4959 
4960   // We generate a few more instructions.
4961   for (; i < ldrd_range - 4 * kA32InstructionSizeInBytes;
4962        i += k16BitT32InstructionSizeInBytes) {
4963     __ Nop();
4964   }
4965 
4966   // Bind all the used labels.
4967   for (uint32_t j = 0; j < kLabelsCount; j++) {
4968     __ Bind(&labels[j]);
4969     __ Nop();
4970   }
4971 
4972   // Now that all the labels have been bound, we have no more veneers.
4973   VIXL_CHECK(test.PoolIsEmpty());
4974 
4975   END();
4976 
4977   RUN();
4978 
4979   // Check that the literals loaded correctly.
4980   ASSERT_EQUAL_32(0x90abcdef, r0);
4981   ASSERT_EQUAL_32(0x12345678, r1);
4982 }
4983 
4984 // NOTE: This test has needed modifications for the new pool manager, as it
4985 // was testing a corner case of the previous pool managers. We keep it as
4986 // another testcase.
TEST_T32(veneer_and_literal2)4987 TEST_T32(veneer_and_literal2) {
4988   SETUP();
4989 
4990   START();
4991 
4992   VIXL_CHECK(test.PoolIsEmpty());
4993 
4994   const uint32_t ldrd_range = 1020;
4995   const uint32_t cbz_range = 126;
4996   const uint32_t kLabelsCount = 20;
4997   const int32_t kTypicalMacroInstructionMaxSize =
4998       8 * kMaxInstructionSizeInBytes;
4999   Label labels[kLabelsCount];
5000 
5001   // Create one literal pool entry.
5002   __ Ldrd(r0, r1, 0x1234567890abcdef);
5003 
5004   for (uint32_t i = 0; i < ldrd_range - cbz_range - 4 * kLabelsCount;
5005        i += k16BitT32InstructionSizeInBytes) {
5006     __ Nop();
5007   }
5008 
5009   // Add entries to the veneer pool.
5010   for (uint32_t i = 0; i < kLabelsCount; i++) {
5011     __ Cbz(r0, &labels[i]);
5012     __ Nop();
5013   }
5014 
5015   // Generate nops up to the literal pool limit.
5016   while (test.GetPoolCheckpoint() - masm.GetCursorOffset() >=
5017          kTypicalMacroInstructionMaxSize) {
5018     __ Nop();
5019   }
5020 
5021   // At this point, no literals and no veneers have been generated.
5022   VIXL_ASSERT(!test.PoolIsEmpty());
5023   // The literal pool needs to be generated.
5024   VIXL_ASSERT(test.GetPoolCheckpoint() - masm.GetCursorOffset() <
5025               kTypicalMacroInstructionMaxSize);
5026 
5027   // This extra Nop will generate the pools.
5028   __ Nop();
5029 
5030   // Bind all the used labels.
5031   for (uint32_t j = 0; j < kLabelsCount; j++) {
5032     __ Bind(&labels[j]);
5033     __ Nop();
5034   }
5035 
5036   // Now that all the labels have been bound, we have no more veneers.
5037   VIXL_CHECK(test.PoolIsEmpty());
5038 
5039   END();
5040 
5041   RUN();
5042 
5043   // Check that the literals loaded correctly.
5044   ASSERT_EQUAL_32(0x90abcdef, r0);
5045   ASSERT_EQUAL_32(0x12345678, r1);
5046 }
5047 
5048 
5049 // Use a literal when we already have a veneer pool potential size greater than
5050 // the literal range => generate the literal immediately (not optimum but it
5051 // works).
TEST_T32(veneer_and_literal3)5052 TEST_T32(veneer_and_literal3) {
5053   SETUP();
5054 
5055   START();
5056 
5057   static const int kLabelsCount = 1000;
5058 
5059   Label labels[kLabelsCount];
5060 
5061   // Set the Z flag so that the following branches are not taken.
5062   __ Movs(r0, 0);
5063 
5064   for (int i = 0; i < kLabelsCount; i++) {
5065     __ B(ne, &labels[i]);
5066   }
5067 
5068   // Create one literal pool entry.
5069   __ Ldrd(r0, r1, 0x1234567890abcdef);
5070 
5071   for (int i = 0; i < 10; i++) {
5072     __ Nop();
5073   }
5074 
5075   for (int i = 0; i < kLabelsCount; i++) {
5076     __ Bind(&labels[i]);
5077   }
5078 
5079   END();
5080 
5081   RUN();
5082 
5083   // Check that the literals loaded correctly.
5084   ASSERT_EQUAL_32(0x90abcdef, r0);
5085   ASSERT_EQUAL_32(0x12345678, r1);
5086 }
5087 
5088 
5089 // Literal has to be generated sooner than veneers. However, as the literal
5090 // pool generation would make the veneers out of range, generate the veneers
5091 // first.
TEST_T32(veneer_and_literal4)5092 TEST_T32(veneer_and_literal4) {
5093   SETUP();
5094 
5095   START();
5096 
5097   Label end;
5098 
5099   // Set the Z flag so that the following branch is not taken.
5100   __ Movs(r0, 0);
5101   __ B(ne, &end);
5102 
5103   uint32_t value = 0x1234567;
5104   Literal<uint32_t>* literal =
5105       new Literal<uint32_t>(value,
5106                             RawLiteral::kPlacedWhenUsed,
5107                             RawLiteral::kDeletedOnPoolDestruction);
5108 
5109   __ Ldr(r11, literal);
5110 
5111   // The range for ldr is 4095, the range for cbz is 127. Generate nops
5112   // to have the ldr becomming out of range just before the cbz.
5113   const int NUM_NOPS = 2044;
5114   const int NUM_RANGE = 58;
5115 
5116   const int NUM1 = NUM_NOPS - NUM_RANGE;
5117   const int NUM2 = NUM_RANGE;
5118 
5119   {
5120     ExactAssemblyScope aas(&masm, 2 * NUM1, CodeBufferCheckScope::kMaximumSize);
5121     for (int i = 0; i < NUM1; i++) {
5122       __ nop();
5123     }
5124   }
5125 
5126   __ Cbz(r1, &end);
5127 
5128   {
5129     ExactAssemblyScope aas(&masm, 2 * NUM2, CodeBufferCheckScope::kMaximumSize);
5130     for (int i = 0; i < NUM2; i++) {
5131       __ nop();
5132     }
5133   }
5134 
5135   {
5136     ExactAssemblyScope aas(&masm, 4, CodeBufferCheckScope::kMaximumSize);
5137     __ add(r1, r1, 3);
5138   }
5139   __ Bind(&end);
5140 
5141   END();
5142 
5143   RUN();
5144 
5145   // Check that the literals loaded correctly.
5146   ASSERT_EQUAL_32(0x1234567, r11);
5147 }
5148 
5149 
5150 // Literal has to be generated sooner than veneers. However, as the literal
5151 // pool generation would make the veneers out of range, generate the veneers
5152 // first.
TEST_T32(veneer_and_literal5)5153 TEST_T32(veneer_and_literal5) {
5154   SETUP();
5155 
5156   START();
5157 
5158   static const int kTestCount = 100;
5159   Label labels[kTestCount];
5160 
5161   int first_test = 2000;
5162   // Test on both sizes of the Adr range which is 4095.
5163   for (int test_num = 0; test_num < kTestCount; test_num++) {
5164     const int string_size = 1000;  // A lot more than the cbz range.
5165     std::string test_string(string_size, 'x');
5166     StringLiteral big_literal(test_string.c_str());
5167 
5168     __ Adr(r11, &big_literal);
5169 
5170     {
5171       int num_nops = first_test + test_num;
5172       ExactAssemblyScope aas(&masm,
5173                              2 * num_nops,
5174                              CodeBufferCheckScope::kMaximumSize);
5175       for (int i = 0; i < num_nops; i++) {
5176         __ nop();
5177       }
5178     }
5179 
5180     __ Cbz(r1, &labels[test_num]);
5181 
5182     {
5183       ExactAssemblyScope aas(&masm, 4, CodeBufferCheckScope::kMaximumSize);
5184       __ add(r1, r1, 3);
5185     }
5186     __ Bind(&labels[test_num]);
5187     // Emit the literal pool if it has not beeen emitted (it's the case for
5188     // the lower values of test_num).
5189     __ EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
5190   }
5191 
5192   END();
5193 }
5194 
5195 // Check that veneer and literals are well generated when they are out of
5196 // range at the same time.
TEST_T32(veneer_and_literal6)5197 TEST_T32(veneer_and_literal6) {
5198   SETUP();
5199 
5200   START();
5201 
5202   Label t1, t2, t3, t4, t5;
5203   static const int kLdrdRange = 1020;
5204   static const int kSizeForCbz = k16BitT32InstructionSizeInBytes;
5205 
5206   __ Ldrd(r0, r1, 0x1111111111111111);
5207   __ Ldrd(r2, r3, 0x2222222222222222);
5208   __ Ldrd(r4, r5, 0x3333333333333333);
5209   __ Ldrd(r6, r7, 0x4444444444444444);
5210   __ Ldrd(r8, r9, 0x5555555555555555);
5211   __ Ldrd(r10, r11, 0x6666666666666666);
5212   __ Ldrd(r10, r11, 0x1234567890abcdef);
5213 
5214   // Ldrd has a bigger range that cbz. Generate some nops before the cbzs in
5215   // order to reach the maximum range of ldrd and cbz at the same time.
5216   {
5217     int nop_size = kLdrdRange - kCbzCbnzRange - 5 * kSizeForCbz;
5218     ExactAssemblyScope scope(&masm, nop_size, CodeBufferCheckScope::kExactSize);
5219     for (int i = 0; i < nop_size; i += k16BitT32InstructionSizeInBytes) {
5220       __ nop();
5221     }
5222   }
5223 
5224   __ Cbz(r2, &t1);
5225   __ Cbz(r2, &t2);
5226   __ Cbz(r2, &t3);
5227   __ Cbz(r2, &t4);
5228   __ Cbz(r2, &t5);
5229 
5230   // At this point, the ldrds are not out of range. It remains a kCbzCbnzRange
5231   // margin (minus the size of the veneers).
5232 
5233   // At this point, the literal and the veneer pools are not emitted.
5234   const int kLdrdLiteralSize = 8;
5235   const int kVeneerSize = 4;
5236   CHECK_POOL_SIZE(7 * kLdrdLiteralSize + 5 * kVeneerSize);
5237   VIXL_CHECK(test.GetPoolCheckpoint() - masm.GetCursorOffset() < kCbzCbnzRange);
5238 
5239   // This scope will generate both veneers (they are both out of range).
5240   {
5241     int nop_size = kCbzCbnzRange;
5242     ExactAssemblyScope scope(&masm, nop_size, CodeBufferCheckScope::kExactSize);
5243     for (int i = 0; i < nop_size; i += k16BitT32InstructionSizeInBytes) {
5244       __ nop();
5245     }
5246   }
5247 
5248   // Check that both literals and veneers have been emitted.
5249   CHECK_POOL_SIZE(5 * kVeneerSize);
5250   VIXL_CHECK(test.GetPoolCheckpoint() - masm.GetCursorOffset() > kCbzCbnzRange);
5251 
5252   __ Bind(&t1);
5253   __ Bind(&t2);
5254   __ Bind(&t3);
5255   __ Bind(&t4);
5256   __ Bind(&t5);
5257 
5258   CHECK_POOL_SIZE(0);
5259 
5260   END();
5261 
5262   RUN();
5263 
5264   // Check that the literals loaded correctly.
5265   ASSERT_EQUAL_32(0x11111111, r0);
5266   ASSERT_EQUAL_32(0x11111111, r1);
5267   ASSERT_EQUAL_32(0x22222222, r2);
5268   ASSERT_EQUAL_32(0x22222222, r3);
5269   ASSERT_EQUAL_32(0x33333333, r4);
5270   ASSERT_EQUAL_32(0x33333333, r5);
5271   ASSERT_EQUAL_32(0x44444444, r6);
5272   ASSERT_EQUAL_32(0x44444444, r7);
5273   ASSERT_EQUAL_32(0x55555555, r8);
5274   ASSERT_EQUAL_32(0x55555555, r9);
5275   ASSERT_EQUAL_32(0x90abcdef, r10);
5276   ASSERT_EQUAL_32(0x12345678, r11);
5277 }
5278 
5279 // Check that a label which is just bound during the MacroEmissionCheckScope
5280 // can be used.
TEST(ldr_label_bound_during_scope)5281 TEST(ldr_label_bound_during_scope) {
5282   SETUP();
5283   START();
5284 
5285   Literal<uint64_t>* literal =
5286       new Literal<uint64_t>(UINT64_C(0x1234567890abcdef),
5287                             RawLiteral::kPlacedWhenUsed,
5288                             RawLiteral::kDeletedOnPoolDestruction);
5289   __ Ldrd(r0, r1, literal);
5290 
5291   const int nop_size = masm.IsUsingA32() ? 4 : 2;
5292   while (test.GetPoolCheckpoint() >=
5293          (masm.GetCursorOffset() +
5294           static_cast<int32_t>(kMaxInstructionSizeInBytes))) {
5295     ExactAssemblyScope scope(&masm, nop_size, ExactAssemblyScope::kExactSize);
5296     __ nop();
5297   }
5298 
5299   VIXL_ASSERT(!test.PoolIsEmpty());
5300 
5301   // This Ldrd will first generate the pool and then use literal which has just
5302   // been bound.
5303   __ Ldrd(r2, r3, literal);
5304 
5305   VIXL_ASSERT(test.PoolIsEmpty());
5306 
5307   END();
5308 
5309   RUN();
5310 
5311   // Check that the literals loaded correctly.
5312   ASSERT_EQUAL_32(0x90abcdef, r0);
5313   ASSERT_EQUAL_32(0x12345678, r1);
5314   ASSERT_EQUAL_32(0x90abcdef, r2);
5315   ASSERT_EQUAL_32(0x12345678, r3);
5316 }
5317 
5318 
TEST_T32(test_it_scope_and_literal_pool)5319 TEST_T32(test_it_scope_and_literal_pool) {
5320   // This test stresses the ITScope to make sure the number of bytes it tries
5321   // to emit is in sync with the MacroEmissionCheckScope that is around it.
5322   SETUP();
5323 
5324   START();
5325 
5326   // Make sure the pool is empty.
5327   masm.EmitLiteralPool(PoolManager<int32_t>::kBranchRequired);
5328   VIXL_CHECK(test.PoolIsEmpty());
5329 
5330   Literal<uint64_t> l0(0xcafebeefdeadbaba);
5331   __ Ldrd(r0, r1, &l0);
5332   // Leave exactly as many bytes between cursor and pool emission checkpoint as
5333   // the typical macro instruction needs (and MacroEmissionCheckScope allows
5334   // for).
5335   const int32_t kTypicalMacroInstructionMaxSize =
5336       8 * kMaxInstructionSizeInBytes;
5337   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset() -
5338                    kTypicalMacroInstructionMaxSize;
5339   int32_t end = masm.GetCursorOffset() + margin;
5340 
5341   {
5342     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
5343     while (masm.GetCursorOffset() < end) {
5344       __ nop();
5345     }
5346   }
5347   VIXL_CHECK((test.GetPoolCheckpoint() - masm.GetCursorOffset()) ==
5348              kTypicalMacroInstructionMaxSize);
5349 
5350   // We cannot use an IT block for this instruction, hence ITScope will
5351   // generate a branch over it.
5352   __ Add(ne, r8, r9, 256);
5353 
5354   END();
5355 
5356   RUN();
5357 
5358   // Check that the literals loaded correctly.
5359   ASSERT_EQUAL_32(0xdeadbaba, r0);
5360   ASSERT_EQUAL_32(0xcafebeef, r1);
5361 }
5362 
5363 
5364 // TODO: Remove this limitation by having a sandboxing mechanism.
5365 #if defined(VIXL_HOST_POINTER_32)
TEST(ldm_stm_no_writeback)5366 TEST(ldm_stm_no_writeback) {
5367   SETUP();
5368 
5369   START();
5370 
5371   const uint32_t src[4] = {0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef};
5372   uint32_t dst1[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5373   uint32_t dst2[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5374 
5375   __ Mov(r0, reinterpret_cast<uintptr_t>(src));
5376   __ Ldm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));
5377   __ Ldm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
5378 
5379   __ Mov(r0, reinterpret_cast<uintptr_t>(dst1));
5380   __ Stm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));
5381 
5382   __ Mov(r0, reinterpret_cast<uintptr_t>(dst2));
5383   __ Stm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
5384 
5385   END();
5386 
5387   RUN();
5388 
5389   ASSERT_EQUAL_32(0x12345678, r1);
5390   ASSERT_EQUAL_32(0x09abcdef, r2);
5391   ASSERT_EQUAL_32(0xc001c0de, r3);
5392   ASSERT_EQUAL_32(0xdeadbeef, r4);
5393 
5394   ASSERT_EQUAL_32(0x12345678, r5);
5395   ASSERT_EQUAL_32(0x09abcdef, r6);
5396   ASSERT_EQUAL_32(0xc001c0de, r9);
5397   ASSERT_EQUAL_32(0xdeadbeef, r11);
5398 
5399   ASSERT_EQUAL_32(0x12345678, dst1[0]);
5400   ASSERT_EQUAL_32(0x09abcdef, dst1[1]);
5401   ASSERT_EQUAL_32(0xc001c0de, dst1[2]);
5402   ASSERT_EQUAL_32(0xdeadbeef, dst1[3]);
5403 
5404   ASSERT_EQUAL_32(0x12345678, dst2[0]);
5405   ASSERT_EQUAL_32(0x09abcdef, dst2[1]);
5406   ASSERT_EQUAL_32(0xc001c0de, dst2[2]);
5407   ASSERT_EQUAL_32(0xdeadbeef, dst2[3]);
5408 }
5409 
5410 
TEST(ldm_stm_writeback)5411 TEST(ldm_stm_writeback) {
5412   SETUP();
5413 
5414   START();
5415 
5416   const uint32_t src[4] = {0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef};
5417   uint32_t dst[8] = {0x00000000,
5418                      0x00000000,
5419                      0x00000000,
5420                      0x00000000,
5421                      0x00000000,
5422                      0x00000000,
5423                      0x00000000,
5424                      0x00000000};
5425 
5426   __ Mov(r0, reinterpret_cast<uintptr_t>(src));
5427   __ Ldm(r0, WRITE_BACK, RegisterList(r2, r3));
5428   __ Ldm(r0, WRITE_BACK, RegisterList(r4, r5));
5429 
5430   __ Mov(r1, reinterpret_cast<uintptr_t>(dst));
5431   __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
5432   __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
5433 
5434   END();
5435 
5436   RUN();
5437 
5438   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 4), r0);
5439   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 8), r1);
5440 
5441   ASSERT_EQUAL_32(0x12345678, r2);
5442   ASSERT_EQUAL_32(0x09abcdef, r3);
5443   ASSERT_EQUAL_32(0xc001c0de, r4);
5444   ASSERT_EQUAL_32(0xdeadbeef, r5);
5445 
5446   ASSERT_EQUAL_32(0x12345678, dst[0]);
5447   ASSERT_EQUAL_32(0x09abcdef, dst[1]);
5448   ASSERT_EQUAL_32(0xc001c0de, dst[2]);
5449   ASSERT_EQUAL_32(0xdeadbeef, dst[3]);
5450   ASSERT_EQUAL_32(0x12345678, dst[4]);
5451   ASSERT_EQUAL_32(0x09abcdef, dst[5]);
5452   ASSERT_EQUAL_32(0xc001c0de, dst[6]);
5453   ASSERT_EQUAL_32(0xdeadbeef, dst[7]);
5454 }
5455 
5456 
TEST_A32(ldm_stm_da_ib)5457 TEST_A32(ldm_stm_da_ib) {
5458   SETUP();
5459 
5460   START();
5461 
5462   const uint32_t src1[4] = {0x33333333, 0x44444444, 0x11111111, 0x22222222};
5463   const uint32_t src2[4] = {0x11111111, 0x22222222, 0x33333333, 0x44444444};
5464 
5465   uint32_t dst1[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5466   uint32_t dst2[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
5467 
5468   __ Mov(r11, reinterpret_cast<uintptr_t>(src1 + 3));
5469   __ Ldmda(r11, WRITE_BACK, RegisterList(r0, r1));
5470   __ Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3));
5471 
5472   __ Mov(r10, reinterpret_cast<uintptr_t>(src2) - sizeof(src2[0]));
5473   __ Ldmib(r10, WRITE_BACK, RegisterList(r4, r5));
5474   __ Ldmib(r10, NO_WRITE_BACK, RegisterList(r6, r7));
5475 
5476   __ Mov(r9, reinterpret_cast<uintptr_t>(dst1 + 3));
5477   __ Stmda(r9, WRITE_BACK, RegisterList(r0, r1));
5478   __ Stmda(r9, NO_WRITE_BACK, RegisterList(r2, r3));
5479 
5480   __ Mov(r8, reinterpret_cast<uintptr_t>(dst2) - sizeof(dst2[0]));
5481   __ Stmib(r8, WRITE_BACK, RegisterList(r4, r5));
5482   __ Stmib(r8, NO_WRITE_BACK, RegisterList(r6, r7));
5483 
5484 
5485   END();
5486 
5487   RUN();
5488 
5489   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src1 + 1), r11);
5490   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src2 + 1), r10);
5491   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst1 + 1), r9);
5492   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst2 + 1), r8);
5493 
5494   ASSERT_EQUAL_32(0x11111111, r0);
5495   ASSERT_EQUAL_32(0x22222222, r1);
5496   ASSERT_EQUAL_32(0x33333333, r2);
5497   ASSERT_EQUAL_32(0x44444444, r3);
5498 
5499   ASSERT_EQUAL_32(0x11111111, r4);
5500   ASSERT_EQUAL_32(0x22222222, r5);
5501   ASSERT_EQUAL_32(0x33333333, r6);
5502   ASSERT_EQUAL_32(0x44444444, r7);
5503 
5504   ASSERT_EQUAL_32(0x33333333, dst1[0]);
5505   ASSERT_EQUAL_32(0x44444444, dst1[1]);
5506   ASSERT_EQUAL_32(0x11111111, dst1[2]);
5507   ASSERT_EQUAL_32(0x22222222, dst1[3]);
5508 
5509   ASSERT_EQUAL_32(0x11111111, dst2[0]);
5510   ASSERT_EQUAL_32(0x22222222, dst2[1]);
5511   ASSERT_EQUAL_32(0x33333333, dst2[2]);
5512   ASSERT_EQUAL_32(0x44444444, dst2[3]);
5513 }
5514 
5515 
TEST(ldmdb_stmdb)5516 TEST(ldmdb_stmdb) {
5517   SETUP();
5518 
5519   START();
5520 
5521   const uint32_t src[6] =
5522       {0x55555555, 0x66666666, 0x33333333, 0x44444444, 0x11111111, 0x22222222};
5523 
5524   uint32_t dst[6] =
5525       {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
5526 
5527   __ Mov(r11, reinterpret_cast<uintptr_t>(src + 6));
5528   __ Ldmdb(r11, WRITE_BACK, RegisterList(r1, r2));
5529   __ Ldmdb(r11, WRITE_BACK, RegisterList(r3, r4));
5530   __ Ldmdb(r11, NO_WRITE_BACK, RegisterList(r5, r6));
5531 
5532   __ Mov(r10, reinterpret_cast<uintptr_t>(dst + 6));
5533   __ Stmdb(r10, WRITE_BACK, RegisterList(r5, r6));
5534   __ Stmdb(r10, WRITE_BACK, RegisterList(r3, r4));
5535   __ Stmdb(r10, NO_WRITE_BACK, RegisterList(r1, r2));
5536 
5537   END();
5538 
5539   RUN();
5540 
5541   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 2), r11);
5542   ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 2), r10);
5543 
5544   ASSERT_EQUAL_32(0x11111111, r1);
5545   ASSERT_EQUAL_32(0x22222222, r2);
5546   ASSERT_EQUAL_32(0x33333333, r3);
5547   ASSERT_EQUAL_32(0x44444444, r4);
5548   ASSERT_EQUAL_32(0x55555555, r5);
5549   ASSERT_EQUAL_32(0x66666666, r6);
5550 
5551   ASSERT_EQUAL_32(0x11111111, dst[0]);
5552   ASSERT_EQUAL_32(0x22222222, dst[1]);
5553   ASSERT_EQUAL_32(0x33333333, dst[2]);
5554   ASSERT_EQUAL_32(0x44444444, dst[3]);
5555   ASSERT_EQUAL_32(0x55555555, dst[4]);
5556   ASSERT_EQUAL_32(0x66666666, dst[5]);
5557 }
5558 #endif
5559 
5560 
TEST(blx)5561 TEST(blx) {
5562   SETUP();
5563 
5564   START();
5565 
5566   // TODO(all): Ideally this test should jump back and forth between ARM and
5567   // Thumb mode and should also cover BLX immediate. Update this test if we
5568   // allow VIXL assembler to change ISA anywhere in the code buffer.
5569 
5570   Label test_start;
5571   Label func1;
5572   Label func2;
5573 
5574   __ B(&test_start);
5575 
5576   __ Bind(&func1);
5577   __ Mov(r0, 0x11111111);
5578   __ Push(lr);
5579   {
5580     size_t size_of_generated_code;
5581     if (masm.IsUsingA32()) {
5582       size_of_generated_code = 7 * kA32InstructionSizeInBytes;
5583     } else {
5584       size_of_generated_code = 5 * k32BitT32InstructionSizeInBytes +
5585                                3 * k16BitT32InstructionSizeInBytes;
5586     }
5587     ExactAssemblyScope scope(&masm,
5588                              size_of_generated_code,
5589                              ExactAssemblyScope::kExactSize);
5590     __ adr(r11, &func2);
5591     if (masm.IsUsingT32()) {
5592       // The jump target needs to have its least significant bit set to indicate
5593       // that we are jumping into thumb mode.
5594       __ orr(r11, r11, 1);
5595     }
5596     __ blx(r11);
5597     __ pop(lr);
5598     __ bx(lr);
5599 
5600     __ bind(&func2);
5601     __ movw(r1, 0x2222);
5602     __ movt(r1, 0x2222);
5603     __ bx(lr);
5604   }
5605 
5606   __ Bind(&test_start);
5607   __ Mov(r0, 0xdeadc0de);
5608   __ Mov(r1, 0xdeadc0de);
5609   __ Bl(&func1);
5610 
5611   END();
5612 
5613   RUN();
5614 
5615   // Really basic test to check that we reached the different parts of the test.
5616   ASSERT_EQUAL_32(0x11111111, r0);
5617   ASSERT_EQUAL_32(0x22222222, r1);
5618 }
5619 
5620 // Check that B with a near hint use a narrow branch when it can.
TEST_T32(b_near_hint)5621 TEST_T32(b_near_hint) {
5622   SETUP();
5623   START();
5624 
5625   Label start;
5626   Label end;
5627 
5628   __ Bind(&start);
5629   __ Nop();
5630 
5631   {
5632     // Generate a branch which should be narrow.
5633     EmissionCheckScope scope(&masm,
5634                              k16BitT32InstructionSizeInBytes,
5635                              EmissionCheckScope::kExactSize);
5636     __ B(&start, kNear);
5637   }
5638   {
5639     ExactAssemblyScope scope(&masm,
5640                              kBNarrowRange,
5641                              ExactAssemblyScope::kExactSize);
5642     for (int32_t i = 0; i < kBNarrowRange;
5643          i += k16BitT32InstructionSizeInBytes) {
5644       __ nop();
5645     }
5646   }
5647   {
5648     // Generate a branch which should be wide.
5649     EmissionCheckScope scope(&masm,
5650                              k32BitT32InstructionSizeInBytes,
5651                              EmissionCheckScope::kExactSize);
5652     __ B(&start, kNear);
5653   }
5654   {
5655     // Generate a forward branch which should be narrow.
5656     EmissionCheckScope scope(&masm,
5657                              k16BitT32InstructionSizeInBytes,
5658                              EmissionCheckScope::kExactSize);
5659     __ B(&end, kNear);
5660   }
5661 
5662   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
5663   VIXL_CHECK(margin < kBNarrowRange);
5664 
5665   {
5666     ExactAssemblyScope scope(&masm,
5667                              kBNarrowRange,
5668                              ExactAssemblyScope::kExactSize);
5669     for (int32_t i = 0; i < kBNarrowRange;
5670          i += k16BitT32InstructionSizeInBytes) {
5671       __ nop();
5672     }
5673   }
5674 
5675   // A veneer should have been generated.
5676   margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
5677   VIXL_CHECK(margin > kBNarrowRange);
5678 
5679   __ Bind(&end);
5680 
5681   END();
5682 
5683   DISASSEMBLE();
5684 }
5685 
5686 // Check that B with a far hint use a narrow branch only for a near backward
5687 // branch.
TEST_T32(b_far_hint)5688 TEST_T32(b_far_hint) {
5689   SETUP();
5690   START();
5691 
5692   Label start;
5693   Label end;
5694 
5695   __ Bind(&start);
5696   __ Nop();
5697 
5698   {
5699     // Generate a branch which should be narrow.
5700     EmissionCheckScope scope(&masm,
5701                              k16BitT32InstructionSizeInBytes,
5702                              EmissionCheckScope::kExactSize);
5703     __ B(&start, kFar);
5704   }
5705   {
5706     ExactAssemblyScope scope(&masm,
5707                              kBNarrowRange,
5708                              ExactAssemblyScope::kExactSize);
5709     for (int32_t i = 0; i < kBNarrowRange;
5710          i += k16BitT32InstructionSizeInBytes) {
5711       __ nop();
5712     }
5713   }
5714   {
5715     // Generate a branch which should be wide.
5716     EmissionCheckScope scope(&masm,
5717                              k32BitT32InstructionSizeInBytes,
5718                              EmissionCheckScope::kExactSize);
5719     __ B(&start, kFar);
5720   }
5721   {
5722     // Generate a forward branch which should be wide.
5723     EmissionCheckScope scope(&masm,
5724                              k32BitT32InstructionSizeInBytes,
5725                              EmissionCheckScope::kExactSize);
5726     __ B(&end, kFar);
5727   }
5728 
5729   __ Bind(&end);
5730 
5731   END();
5732 
5733   DISASSEMBLE();
5734 }
5735 
5736 // Check that conditional B with a near hint use a narrow branch when it can.
TEST_T32(b_conditional_near_hint)5737 TEST_T32(b_conditional_near_hint) {
5738   SETUP();
5739   START();
5740 
5741   Label start;
5742   Label end;
5743 
5744   __ Bind(&start);
5745   __ Nop();
5746   {
5747     // Generate a branch which should be narrow.
5748     EmissionCheckScope scope(&masm,
5749                              k16BitT32InstructionSizeInBytes,
5750                              EmissionCheckScope::kExactSize);
5751     __ B(eq, &start, kNear);
5752   }
5753   {
5754     ExactAssemblyScope scope(&masm,
5755                              kBConditionalNarrowRange,
5756                              ExactAssemblyScope::kExactSize);
5757     for (int32_t i = 0; i < kBConditionalNarrowRange;
5758          i += k16BitT32InstructionSizeInBytes) {
5759       __ nop();
5760     }
5761   }
5762   {
5763     // Generate a branch which should be wide.
5764     EmissionCheckScope scope(&masm,
5765                              k32BitT32InstructionSizeInBytes,
5766                              EmissionCheckScope::kExactSize);
5767     __ B(eq, &start, kNear);
5768   }
5769   {
5770     // Generate a forward branch which should be narrow.
5771     EmissionCheckScope scope(&masm,
5772                              k16BitT32InstructionSizeInBytes,
5773                              EmissionCheckScope::kExactSize);
5774     __ B(eq, &end, kNear);
5775   }
5776 
5777   int32_t margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
5778   VIXL_CHECK(margin < kBConditionalNarrowRange);
5779 
5780   {
5781     ExactAssemblyScope scope(&masm,
5782                              kBConditionalNarrowRange,
5783                              ExactAssemblyScope::kExactSize);
5784     for (int32_t i = 0; i < kBConditionalNarrowRange;
5785          i += k16BitT32InstructionSizeInBytes) {
5786       __ nop();
5787     }
5788   }
5789 
5790   // A veneer should have been generated.
5791   margin = test.GetPoolCheckpoint() - masm.GetCursorOffset();
5792   VIXL_CHECK(margin > kBConditionalNarrowRange);
5793 
5794   __ Bind(&end);
5795 
5796   END();
5797 
5798   DISASSEMBLE();
5799 }
5800 
5801 // Check that conditional B with a far hint use a narrow branch only for a
5802 // near backward branch.
TEST_T32(b_conditional_far_hint)5803 TEST_T32(b_conditional_far_hint) {
5804   SETUP();
5805   START();
5806 
5807   Label start;
5808   Label end;
5809 
5810   __ Bind(&start);
5811   __ Nop();
5812 
5813   {
5814     // Generate a branch which should be narrow.
5815     EmissionCheckScope scope(&masm,
5816                              k16BitT32InstructionSizeInBytes,
5817                              EmissionCheckScope::kExactSize);
5818     __ B(eq, &start, kFar);
5819   }
5820   {
5821     ExactAssemblyScope scope(&masm,
5822                              kBConditionalNarrowRange,
5823                              ExactAssemblyScope::kExactSize);
5824     for (int32_t i = 0; i < kBConditionalNarrowRange;
5825          i += k16BitT32InstructionSizeInBytes) {
5826       __ nop();
5827     }
5828   }
5829   {
5830     // Generate a branch which should be wide.
5831     EmissionCheckScope scope(&masm,
5832                              k32BitT32InstructionSizeInBytes,
5833                              EmissionCheckScope::kExactSize);
5834     __ B(eq, &start, kFar);
5835   }
5836   {
5837     // Generate a forward branch which should be wide.
5838     EmissionCheckScope scope(&masm,
5839                              k32BitT32InstructionSizeInBytes,
5840                              EmissionCheckScope::kExactSize);
5841     __ B(eq, &end, kFar);
5842   }
5843 
5844   __ Bind(&end);
5845 
5846   END();
5847 
5848   DISASSEMBLE();
5849 }
5850 
5851 
5852 // Check that the veneer pool is correctly emitted even if we do a lot of narrow
5853 // branches.
TEST_T32(b_narrow_many)5854 TEST_T32(b_narrow_many) {
5855   SETUP();
5856   START();
5857 
5858   static const int kLabelsCount = kBNarrowRange / 2;
5859 
5860   Label labels[kLabelsCount];
5861 
5862   __ Mov(r0, 0);
5863 
5864   for (int i = 0; i < kLabelsCount; i++) {
5865     __ B(&labels[i], kNear);
5866   }
5867 
5868   __ Mov(r0, 1);
5869   for (int i = 0; i < kLabelsCount; i++) {
5870     __ Bind(&labels[i]);
5871   }
5872   __ Nop();
5873 
5874   END();
5875 
5876   RUN();
5877 
5878   ASSERT_EQUAL_32(0, r0);
5879 }
5880 
5881 
5882 // Check that the veneer pool is correctly emitted even if we do a lot of narrow
5883 // branches and cbz.
TEST_T32(b_narrow_and_cbz)5884 TEST_T32(b_narrow_and_cbz) {
5885   SETUP();
5886   START();
5887 
5888   static const int kLabelsCount = kBNarrowRange / 4;
5889 
5890   Label b_labels[kLabelsCount];
5891   Label cbz_labels[kLabelsCount];
5892 
5893   __ Mov(r0, 0);
5894 
5895   for (int i = 0; i < kLabelsCount; i++) {
5896     __ B(&b_labels[i], kNear);
5897     __ Cbz(r0, &cbz_labels[i]);
5898   }
5899 
5900   __ Mov(r0, 1);
5901   for (int i = 0; i < kLabelsCount; i++) {
5902     __ Bind(&b_labels[i]);
5903   }
5904 
5905   __ Mov(r0, 2);
5906   for (int i = 0; i < kLabelsCount; i++) {
5907     __ Bind(&cbz_labels[i]);
5908   }
5909 
5910   __ Nop();
5911 
5912   END();
5913 
5914   RUN();
5915 
5916   ASSERT_EQUAL_32(2, r0);
5917 }
5918 
5919 
5920 #define CHECK_SIZE_MATCH(ASM1, ASM2)                                 \
5921   {                                                                  \
5922     MacroAssembler masm1(BUF_SIZE);                                  \
5923     masm1.UseInstructionSet(isa);                                    \
5924     VIXL_ASSERT(masm1.GetCursorOffset() == 0);                       \
5925     masm1.ASM1;                                                      \
5926     masm1.FinalizeCode();                                            \
5927     int size1 = masm1.GetCursorOffset();                             \
5928                                                                      \
5929     MacroAssembler masm2(BUF_SIZE);                                  \
5930     masm2.UseInstructionSet(isa);                                    \
5931     VIXL_ASSERT(masm2.GetCursorOffset() == 0);                       \
5932     masm2.ASM2;                                                      \
5933     masm2.FinalizeCode();                                            \
5934     int size2 = masm2.GetCursorOffset();                             \
5935                                                                      \
5936     bool disassemble = Test::disassemble();                          \
5937     if (size1 != size2) {                                            \
5938       printf("Sizes did not match:\n");                              \
5939       disassemble = true;                                            \
5940     }                                                                \
5941     if (disassemble) {                                               \
5942       PrintDisassembler dis(std::cout, 0);                           \
5943       printf("// " #ASM1 "\n");                                      \
5944       if (masm1.IsUsingT32()) {                                      \
5945         dis.DisassembleT32Buffer(masm1.GetBuffer()                   \
5946                                      ->GetStartAddress<uint16_t*>(), \
5947                                  size1);                             \
5948       } else {                                                       \
5949         dis.DisassembleA32Buffer(masm1.GetBuffer()                   \
5950                                      ->GetStartAddress<uint32_t*>(), \
5951                                  size1);                             \
5952       }                                                              \
5953       printf("\n");                                                  \
5954                                                                      \
5955       dis.SetCodeAddress(0);                                         \
5956       printf("// " #ASM2 "\n");                                      \
5957       if (masm2.IsUsingT32()) {                                      \
5958         dis.DisassembleT32Buffer(masm2.GetBuffer()                   \
5959                                      ->GetStartAddress<uint16_t*>(), \
5960                                  size2);                             \
5961       } else {                                                       \
5962         dis.DisassembleA32Buffer(masm2.GetBuffer()                   \
5963                                      ->GetStartAddress<uint32_t*>(), \
5964                                  size2);                             \
5965       }                                                              \
5966       printf("\n");                                                  \
5967     }                                                                \
5968     VIXL_CHECK(size1 == size2);                                      \
5969   }
5970 
5971 
TEST_T32(macro_assembler_commute)5972 TEST_T32(macro_assembler_commute) {
5973   // Test that the MacroAssembler will commute operands if it means it can use a
5974   // 16-bit instruction with the same effect.
5975 
5976   // TODO: The commented-out tests should pass, but don't. When they are fixed,
5977   // we should update this test.
5978 
5979   // CHECK_SIZE_MATCH(Adc(DontCare, r7, r6, r7),
5980   //                  Adc(DontCare, r7, r7, r6));
5981 
5982   // CHECK_SIZE_MATCH(Adc(DontCare, eq, r7, r6, r7),
5983   //                  Adc(DontCare, eq, r7, r7, r6));
5984 
5985   CHECK_SIZE_MATCH(Add(DontCare, r1, r2, r7), Add(DontCare, r1, r7, r2));
5986 
5987   CHECK_SIZE_MATCH(Add(DontCare, lt, r1, r2, r7),
5988                    Add(DontCare, lt, r1, r7, r2));
5989 
5990   // CHECK_SIZE_MATCH(Add(DontCare, r4, r4, r10),
5991   //                  Add(DontCare, r4, r10, r4));
5992 
5993   // CHECK_SIZE_MATCH(Add(DontCare, eq, r4, r4, r10),
5994   //                  Add(DontCare, eq, r4, r10, r4));
5995 
5996   // CHECK_SIZE_MATCH(Add(DontCare, r7, sp, r7),
5997   //                  Add(DontCare, r7, r7, sp));
5998 
5999   // CHECK_SIZE_MATCH(Add(DontCare, eq, r7, sp, r7),
6000   //                  Add(DontCare, eq, r7, r7, sp));
6001 
6002   // CHECK_SIZE_MATCH(Add(DontCare, sp, sp, r10),
6003   //                  Add(DontCare, sp, r10, sp));
6004 
6005   // CHECK_SIZE_MATCH(Add(DontCare, eq, sp, sp, r10),
6006   //                  Add(DontCare, eq, sp, r10, sp));
6007 
6008   // CHECK_SIZE_MATCH(And(DontCare, r7, r7, r6),
6009   //                  And(DontCare, r7, r6, r7));
6010 
6011   // CHECK_SIZE_MATCH(And(DontCare, eq, r7, r7, r6),
6012   //                  And(DontCare, eq, r7, r6, r7));
6013 
6014   // CHECK_SIZE_MATCH(Eor(DontCare, r7, r7, r6),
6015   //                  Eor(DontCare, r7, r6, r7));
6016 
6017   // CHECK_SIZE_MATCH(Eor(DontCare, eq, r7, r7, r6),
6018   //                  Eor(DontCare, eq, r7, r6, r7));
6019 
6020   // CHECK_SIZE_MATCH(Mul(DontCare, r0, r1, r0),
6021   //                  Mul(DontCare, r0, r0, r1));
6022 
6023   // CHECK_SIZE_MATCH(Mul(DontCare, eq, r0, r1, r0),
6024   //                  Mul(DontCare, eq, r0, r0, r1));
6025 
6026   // CHECK_SIZE_MATCH(Orr(DontCare, r7, r7, r6),
6027   //                  Orr(DontCare, r7, r6, r7));
6028 
6029   // CHECK_SIZE_MATCH(Orr(DontCare, eq, r7, r7, r6),
6030   //                  Orr(DontCare, eq, r7, r6, r7));
6031 
6032 
6033   CHECK_SIZE_MATCH(Adc(r7, r6, r7), Adc(r7, r7, r6));
6034 
6035   // CHECK_SIZE_MATCH(Adc(eq, r7, r6, r7),
6036   //                  Adc(eq, r7, r7, r6));
6037 
6038   CHECK_SIZE_MATCH(Add(r1, r2, r7), Add(r1, r7, r2));
6039 
6040   CHECK_SIZE_MATCH(Add(lt, r1, r2, r7), Add(lt, r1, r7, r2));
6041 
6042   // CHECK_SIZE_MATCH(Add(r4, r4, r10),
6043   //                  Add(r4, r10, r4));
6044 
6045   // CHECK_SIZE_MATCH(Add(eq, r4, r4, r10),
6046   //                  Add(eq, r4, r10, r4));
6047 
6048   // CHECK_SIZE_MATCH(Add(r7, sp, r7),
6049   //                  Add(r7, r7, sp));
6050 
6051   // CHECK_SIZE_MATCH(Add(eq, r7, sp, r7),
6052   //                  Add(eq, r7, r7, sp));
6053 
6054   // CHECK_SIZE_MATCH(Add(sp, sp, r10),
6055   //                  Add(sp, r10, sp));
6056 
6057   // CHECK_SIZE_MATCH(Add(eq, sp, sp, r10),
6058   //                  Add(eq, sp, r10, sp));
6059 
6060   CHECK_SIZE_MATCH(And(r7, r7, r6), And(r7, r6, r7));
6061 
6062   // CHECK_SIZE_MATCH(And(eq, r7, r7, r6),
6063   //                  And(eq, r7, r6, r7));
6064 
6065   CHECK_SIZE_MATCH(Eor(r7, r7, r6), Eor(r7, r6, r7));
6066 
6067   // CHECK_SIZE_MATCH(Eor(eq, r7, r7, r6),
6068   //                  Eor(eq, r7, r6, r7));
6069 
6070   CHECK_SIZE_MATCH(Mul(r0, r1, r0), Mul(r0, r0, r1));
6071 
6072   // CHECK_SIZE_MATCH(Mul(eq, r0, r1, r0),
6073   //                  Mul(eq, r0, r0, r1));
6074 
6075   CHECK_SIZE_MATCH(Orr(r7, r7, r6), Orr(r7, r6, r7));
6076 
6077   // CHECK_SIZE_MATCH(Orr(eq, r7, r7, r6),
6078   //                  Orr(eq, r7, r6, r7));
6079 
6080 
6081   // CHECK_SIZE_MATCH(Adcs(r7, r6, r7),
6082   //                  Adcs(r7, r7, r6));
6083 
6084   // CHECK_SIZE_MATCH(Adcs(eq, r7, r6, r7),
6085   //                  Adcs(eq, r7, r7, r6));
6086 
6087   CHECK_SIZE_MATCH(Adds(r1, r2, r7), Adds(r1, r7, r2));
6088 
6089   CHECK_SIZE_MATCH(Adds(lt, r1, r2, r7), Adds(lt, r1, r7, r2));
6090 
6091   CHECK_SIZE_MATCH(Adds(r4, r4, r10), Adds(r4, r10, r4));
6092 
6093   CHECK_SIZE_MATCH(Adds(eq, r4, r4, r10), Adds(eq, r4, r10, r4));
6094 
6095   CHECK_SIZE_MATCH(Adds(r7, sp, r7), Adds(r7, r7, sp));
6096 
6097   CHECK_SIZE_MATCH(Adds(eq, r7, sp, r7), Adds(eq, r7, r7, sp));
6098 
6099   CHECK_SIZE_MATCH(Adds(sp, sp, r10), Adds(sp, r10, sp));
6100 
6101   CHECK_SIZE_MATCH(Adds(eq, sp, sp, r10), Adds(eq, sp, r10, sp));
6102 
6103   // CHECK_SIZE_MATCH(Ands(r7, r7, r6),
6104   //                  Ands(r7, r6, r7));
6105 
6106   // CHECK_SIZE_MATCH(Ands(eq, r7, r7, r6),
6107   //                  Ands(eq, r7, r6, r7));
6108 
6109   // CHECK_SIZE_MATCH(Eors(r7, r7, r6),
6110   //                  Eors(r7, r6, r7));
6111 
6112   // CHECK_SIZE_MATCH(Eors(eq, r7, r7, r6),
6113   //                  Eors(eq, r7, r6, r7));
6114 
6115   // CHECK_SIZE_MATCH(Muls(r0, r1, r0),
6116   //                  Muls(r0, r0, r1));
6117 
6118   // CHECK_SIZE_MATCH(Muls(eq, r0, r1, r0),
6119   //                  Muls(eq, r0, r0, r1));
6120 
6121   // CHECK_SIZE_MATCH(Orrs(r7, r7, r6),
6122   //                  Orrs(r7, r6, r7));
6123 
6124   // CHECK_SIZE_MATCH(Orrs(eq, r7, r7, r6),
6125   //                  Orrs(eq, r7, r6, r7));
6126 }
6127 
TEST(emit_pool_when_manually_placing_literal)6128 TEST(emit_pool_when_manually_placing_literal) {
6129   SETUP();
6130   START();
6131 
6132   // Literal that will be manually placed.
6133   Literal<uint64_t> l0(0xcafebeefdeadbaba, RawLiteral::kManuallyPlaced);
6134 
6135   // Create one literal pool entry.
6136   __ Ldrd(r0, r1, 0x1234567890abcdef);
6137 
6138   // Branch using the assembler, to avoid introducing a veneer.
6139   Label over_literal;
6140   const int kBranchSize = 4;
6141   {
6142     ExactAssemblyScope scope(&masm,
6143                              kBranchSize,
6144                              ExactAssemblyScope::kExactSize);
6145     __ b(&over_literal);
6146   }
6147 
6148   // Almost reach the pool checkpoint.
6149   int32_t margin =
6150       test.GetPoolCheckpoint() - masm.GetCursorOffset() - l0.GetSize() / 2;
6151   int32_t end = masm.GetCursorOffset() + margin;
6152   {
6153     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
6154     while (masm.GetCursorOffset() < end) {
6155       __ nop();
6156     }
6157   }
6158 
6159   VIXL_CHECK(!test.PoolIsEmpty());
6160   __ Place(&l0);
6161   // The pool must now have been emitted.
6162   VIXL_CHECK(test.PoolIsEmpty());
6163 
6164   __ Bind(&over_literal);
6165 
6166   __ Ldrd(r2, r3, &l0);
6167 
6168   END();
6169 
6170   RUN();
6171 
6172   ASSERT_EQUAL_32(0x90abcdef, r0);
6173   ASSERT_EQUAL_32(0x12345678, r1);
6174   ASSERT_EQUAL_32(0xdeadbaba, r2);
6175   ASSERT_EQUAL_32(0xcafebeef, r3);
6176 }
6177 
6178 
6179 // The addition of padding only happens for T32.
TEST_T32(emit_pool_when_adding_padding_due_to_bind)6180 TEST_T32(emit_pool_when_adding_padding_due_to_bind) {
6181   SETUP();
6182   START();
6183 
6184   // Make sure we start with a 4-byte aligned address, in order for the
6185   // location where we will call Bind() to be 4-byte aligned.
6186   {
6187     ExactAssemblyScope scope(&masm,
6188                              k16BitT32InstructionSizeInBytes,
6189                              ExactAssemblyScope::kMaximumSize);
6190     while (masm.GetCursorOffset() % 4 != 0) {
6191       __ nop();
6192     }
6193   }
6194 
6195   // Create one literal pool entry.
6196   __ Ldrd(r0, r1, 0x1234567890abcdef);
6197 
6198   // Almost reach the pool checkpoint.
6199   const int kPaddingBytes = 2;
6200   int32_t margin =
6201       test.GetPoolCheckpoint() - masm.GetCursorOffset() - kPaddingBytes;
6202   int32_t end = masm.GetCursorOffset() + margin;
6203   {
6204     ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
6205     while (masm.GetCursorOffset() < end) {
6206       __ nop();
6207     }
6208   }
6209 
6210   Label label;
6211   __ Cbz(r0, &label);
6212 
6213   VIXL_CHECK(!test.PoolIsEmpty());
6214   // In order to hit the case where binding the label needs to add padding,
6215   // we need this to be a 4-byte aligned address.
6216   VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 0);
6217 
6218   __ Bind(&label);
6219   // The pool must now have been emitted.
6220   VIXL_CHECK(test.PoolIsEmpty());
6221 
6222   END();
6223 
6224   RUN();
6225 
6226   ASSERT_EQUAL_32(0x90abcdef, r0);
6227   ASSERT_EQUAL_32(0x12345678, r1);
6228 }
6229 
AddBranchesAndGetCloseToCheckpoint(MacroAssembler * masm,TestMacroAssembler * test,const int kLabelsCount,Label b_labels[],int32_t margin)6230 static void AddBranchesAndGetCloseToCheckpoint(MacroAssembler* masm,
6231                                                TestMacroAssembler* test,
6232                                                const int kLabelsCount,
6233                                                Label b_labels[],
6234                                                int32_t margin) {
6235   // Add many veneers to the pool.
6236   for (int i = 0; i < kLabelsCount; i++) {
6237     masm->B(&b_labels[i]);
6238   }
6239 
6240   // Get close to the veneer emission margin (considering the heuristic).
6241   // Use add instead of nop to make viewing the disassembled code easier.
6242   const int kAddSize = masm->IsUsingT32() ? k16BitT32InstructionSizeInBytes
6243                                           : kA32InstructionSizeInBytes;
6244   int32_t end = test->GetPoolCheckpoint();
6245   int32_t space = end - masm->GetCursorOffset() - margin;
6246   {
6247     ExactAssemblyScope scope(masm, space, ExactAssemblyScope::kExactSize);
6248     while (space > 0) {
6249       masm->add(r0, r0, r0);
6250       space -= kAddSize;
6251     }
6252   }
6253 
6254   // Make sure the veneers have not yet been emitted.
6255   const int kVeneerSize = 4;
6256   VIXL_CHECK(test->GetPoolSize() == kLabelsCount * kVeneerSize);
6257 }
6258 
EmitIndividualNops(MacroAssembler * masm,const int kNops)6259 static void EmitIndividualNops(MacroAssembler* masm, const int kNops) {
6260   for (int i = 0; i < kNops; ++i) {
6261     masm->Nop();
6262   }
6263 }
6264 
EmitNopsInExactAssemblyScope(MacroAssembler * masm,const int kNops)6265 static void EmitNopsInExactAssemblyScope(MacroAssembler* masm,
6266                                          const int kNops) {
6267   const int kNopSize = masm->IsUsingT32() ? k16BitT32InstructionSizeInBytes
6268                                           : kA32InstructionSizeInBytes;
6269   {
6270     ExactAssemblyScope scope(masm,
6271                              kNops * kNopSize,
6272                              ExactAssemblyScope::kExactSize);
6273     for (int i = 0; i < kNops; i++) {
6274       masm->nop();
6275     }
6276   }
6277 }
6278 
TEST_A32(literal_and_veneer_interaction_1)6279 TEST_A32(literal_and_veneer_interaction_1) {
6280   SETUP();
6281   START();
6282 
6283   static const int kLabelsCount = 100;
6284 
6285   Label b_labels[kLabelsCount];
6286 
6287   AddBranchesAndGetCloseToCheckpoint(&masm,
6288                                      &test,
6289                                      kLabelsCount,
6290                                      b_labels,
6291                                      1 * KBytes);
6292 
6293   // Emit a load of a large string. In the past, we have attempted to emit
6294   // the literal load without emitting the veneers, which meant that we were
6295   // left with an impossible scheduling problem for the pool objects (due to
6296   // the short range of the ldrd).
6297   std::string test_string(2 * KBytes, 'x');
6298   StringLiteral big_literal(test_string.c_str());
6299   __ Ldrd(r0, r1, &big_literal);
6300 
6301   EmitIndividualNops(&masm, 1000);
6302 
6303   // We can now safely bind the labels.
6304   for (int i = 0; i < kLabelsCount; i++) {
6305     __ Bind(&b_labels[i]);
6306   }
6307 
6308   END();
6309 
6310   RUN();
6311 }
6312 
6313 
TEST_A32(literal_and_veneer_interaction_2)6314 TEST_A32(literal_and_veneer_interaction_2) {
6315   SETUP();
6316   START();
6317 
6318   static const int kLabelsCount = 100;
6319 
6320   Label b_labels[kLabelsCount];
6321 
6322   AddBranchesAndGetCloseToCheckpoint(&masm,
6323                                      &test,
6324                                      kLabelsCount,
6325                                      b_labels,
6326                                      1 * KBytes);
6327 
6328   // This is similar to the test above. The Ldr instruction can be emitted with
6329   // no problems. The Ldrd used to force emission of the literal pool, pushing
6330   // the veneers out of range - we make sure this does not happen anymore.
6331   std::string test_string(2 * KBytes, 'z');
6332   StringLiteral big_literal(test_string.c_str());
6333   __ Ldr(r2, &big_literal);
6334 
6335   const int kVeneerSize = 4;
6336   CHECK_POOL_SIZE(kLabelsCount * kVeneerSize + big_literal.GetSize());
6337 
6338   std::string test_string2(2 * KBytes, 'x');
6339   StringLiteral big_literal2(test_string.c_str());
6340   __ Ldrd(r0, r1, &big_literal2);
6341 
6342   EmitIndividualNops(&masm, 1000);
6343 
6344   for (int i = 0; i < kLabelsCount; i++) {
6345     __ Bind(&b_labels[i]);
6346   }
6347 
6348   END();
6349 
6350   RUN();
6351 }
6352 
6353 
TEST_A32(literal_and_veneer_interaction_3)6354 TEST_A32(literal_and_veneer_interaction_3) {
6355   SETUP();
6356   START();
6357 
6358   static const int kLabelsCount = 100;
6359   Label b_labels[kLabelsCount];
6360 
6361   AddBranchesAndGetCloseToCheckpoint(&masm,
6362                                      &test,
6363                                      kLabelsCount,
6364                                      b_labels,
6365                                      1 * KBytes);
6366 
6367   // Here, we used to emit the Ldrd instruction and then emit the veneers
6368   // before the literal is emitted, hence pushing the Ldrd out of range.
6369   // Make sure this does not happen anymore.
6370   __ Ldrd(r2, r3, 0x12345678);
6371 
6372   // The issue would only appear when emitting the nops in a single scope.
6373   EmitNopsInExactAssemblyScope(&masm, 4096);
6374 
6375   for (int i = 0; i < kLabelsCount; i++) {
6376     __ Bind(&b_labels[i]);
6377   }
6378 
6379   END();
6380 
6381   RUN();
6382 }
6383 
6384 
6385 // Equivalent to literal_and_veneer_interaction_1, but for T32.
TEST_T32(literal_and_veneer_interaction_4)6386 TEST_T32(literal_and_veneer_interaction_4) {
6387   SETUP();
6388   START();
6389 
6390   static const int kLabelsCount = 550;
6391 
6392   Label b_labels[kLabelsCount];
6393 
6394   AddBranchesAndGetCloseToCheckpoint(&masm,
6395                                      &test,
6396                                      kLabelsCount,
6397                                      b_labels,
6398                                      KBytes / 2);
6399 
6400   std::string test_string(3 * KBytes, 'x');
6401   StringLiteral big_literal(test_string.c_str());
6402   __ Ldrd(r0, r1, &big_literal);
6403 
6404   EmitIndividualNops(&masm, 2000);
6405 
6406   for (int i = 0; i < kLabelsCount; i++) {
6407     __ Bind(&b_labels[i]);
6408   }
6409 
6410   END();
6411 
6412   RUN();
6413 }
6414 
6415 // Equivalent to literal_and_veneer_interaction_3, but for T32.
TEST_T32(literal_and_veneer_interaction_5)6416 TEST_T32(literal_and_veneer_interaction_5) {
6417   SETUP();
6418   START();
6419 
6420   static const int kLabelsCount = 550;
6421   Label b_labels[kLabelsCount];
6422 
6423   AddBranchesAndGetCloseToCheckpoint(&masm,
6424                                      &test,
6425                                      kLabelsCount,
6426                                      b_labels,
6427                                      1 * KBytes);
6428 
6429   __ Ldrd(r2, r3, 0x12345678);
6430 
6431   EmitNopsInExactAssemblyScope(&masm, 4096);
6432 
6433   for (int i = 0; i < kLabelsCount; i++) {
6434     __ Bind(&b_labels[i]);
6435   }
6436 
6437   END();
6438 
6439   RUN();
6440 }
6441 
TEST_T32(assembler_bind_label)6442 TEST_T32(assembler_bind_label) {
6443   SETUP();
6444   START();
6445 
6446   Label label;
6447   __ B(eq, &label, kNear);
6448 
6449   // At this point we keep track of the veneer in the pool.
6450   VIXL_CHECK(!test.PoolIsEmpty());
6451 
6452   {
6453     // Bind the label with the assembler.
6454     ExactAssemblyScope scope(&masm, 2, ExactAssemblyScope::kMaximumSize);
6455     __ bind(&label);
6456   }
6457 
6458   // Make sure the pool is now empty.
6459   VIXL_CHECK(test.PoolIsEmpty());
6460 
6461   EmitNopsInExactAssemblyScope(&masm, 4096);
6462 
6463   END();
6464 
6465   RUN();
6466 }
6467 
6468 #ifdef VIXL_DEBUG
6469 #define TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)    \
6470   POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM) \
6471   NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)
6472 #else
6473 // Skip the negative tests for release builds, as they require debug-only checks
6474 // in ExactAssemblyScope.
6475 #define TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM) \
6476   POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)
6477 #endif
6478 
6479 #define POSITIVE_TEST_FORWARD_REFERENCE_INFO(INST, INFO, ASM)       \
6480   can_encode = masm.INFO;                                           \
6481   VIXL_CHECK(can_encode);                                           \
6482   {                                                                 \
6483     ExactAssemblyScope scope(&masm,                                 \
6484                              info->size,                            \
6485                              ExactAssemblyScope::kExactSize);       \
6486     int32_t program_counter =                                       \
6487         masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
6488     if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {       \
6489       program_counter = AlignDown(program_counter, 4);              \
6490     }                                                               \
6491     Label label(program_counter + info->min_offset);                \
6492     masm.ASM;                                                       \
6493   }                                                                 \
6494   {                                                                 \
6495     ExactAssemblyScope scope(&masm,                                 \
6496                              info->size,                            \
6497                              ExactAssemblyScope::kExactSize);       \
6498     int32_t program_counter =                                       \
6499         masm.GetCursorOffset() + __ GetArchitectureStatePCOffset(); \
6500     if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {       \
6501       program_counter = AlignDown(program_counter, 4);              \
6502     }                                                               \
6503     Label label(program_counter + info->max_offset);                \
6504     masm.ASM;                                                       \
6505   }
6506 
6507 #ifdef VIXL_NEGATIVE_TESTING
6508 #define NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)                   \
6509   try {                                                                   \
6510     ExactAssemblyScope scope(&masm,                                       \
6511                              info->size,                                  \
6512                              ExactAssemblyScope::kMaximumSize);           \
6513     int32_t program_counter =                                             \
6514         masm.GetCursorOffset() + __ GetArchitectureStatePCOffset();       \
6515     if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {             \
6516       program_counter = AlignDown(program_counter, 4);                    \
6517     }                                                                     \
6518     Label label(program_counter + info->max_offset + info->alignment);    \
6519     masm.ASM;                                                             \
6520     printf("Negative test for forward reference failed for %s.\n", INST); \
6521     abort();                                                              \
6522   } catch (const std::runtime_error&) {                                   \
6523   }                                                                       \
6524   try {                                                                   \
6525     ExactAssemblyScope scope(&masm,                                       \
6526                              info->size,                                  \
6527                              ExactAssemblyScope::kMaximumSize);           \
6528     int32_t program_counter =                                             \
6529         masm.GetCursorOffset() + __ GetArchitectureStatePCOffset();       \
6530     if (info->pc_needs_aligning == ReferenceInfo::kAlignPc) {             \
6531       program_counter = AlignDown(program_counter, 4);                    \
6532     }                                                                     \
6533     Label label(program_counter + info->min_offset - info->alignment);    \
6534     masm.ASM;                                                             \
6535     printf("Negative test for forward reference failed for %s.\n", INST); \
6536     abort();                                                              \
6537   } catch (const std::runtime_error&) {                                   \
6538   }
6539 #else
6540 #define NEGATIVE_TEST_FORWARD_REFERENCE_INFO(INST, ASM)
6541 #endif
6542 
TEST_T32(forward_reference_info_T32)6543 TEST_T32(forward_reference_info_T32) {
6544   MacroAssembler masm(BUF_SIZE, T32);
6545 
6546   Label unbound;
6547   const ReferenceInfo* info;
6548   bool can_encode;
6549 
6550   // clang-format off
6551 
6552   TEST_FORWARD_REFERENCE_INFO(
6553     "adr",
6554     adr_info(al, Narrow, r0, &unbound, &info),
6555     adr(al, Narrow, r0, &label));
6556 
6557   TEST_FORWARD_REFERENCE_INFO(
6558     "adr",
6559     adr_info(al, Wide, r0, &unbound, &info),
6560     adr(al, Wide, r0, &label));
6561 
6562   TEST_FORWARD_REFERENCE_INFO(
6563     "adr",
6564     adr_info(al, Best, r0, &unbound, &info),
6565     adr(al, Best, r0, &label));
6566 
6567   TEST_FORWARD_REFERENCE_INFO(
6568     "b",
6569     b_info(al, Narrow, &unbound, &info),
6570     b(al, Narrow, &label));
6571 
6572   TEST_FORWARD_REFERENCE_INFO(
6573     "b",
6574     b_info(al, Wide, &unbound, &info),
6575     b(al, Wide, &label));
6576 
6577   TEST_FORWARD_REFERENCE_INFO(
6578     "b",
6579     b_info(al, Best, &unbound, &info),
6580     b(al, Best, &label));
6581 
6582   TEST_FORWARD_REFERENCE_INFO(
6583     "b",
6584     b_info(gt, Narrow, &unbound, &info),
6585     b(gt, Narrow, &label));
6586 
6587   TEST_FORWARD_REFERENCE_INFO(
6588     "b",
6589     b_info(gt, Wide, &unbound, &info),
6590     b(gt, Wide, &label));
6591 
6592   TEST_FORWARD_REFERENCE_INFO(
6593     "b",
6594     b_info(gt, Best, &unbound, &info),
6595     b(gt, Best, &label));
6596 
6597   TEST_FORWARD_REFERENCE_INFO(
6598     "bl",
6599     bl_info(al, &unbound, &info),
6600     bl(al, &label));
6601 
6602   TEST_FORWARD_REFERENCE_INFO(
6603     "blx",
6604     blx_info(al, &unbound, &info),
6605     blx(al, &label));
6606 
6607   TEST_FORWARD_REFERENCE_INFO(
6608     "cbnz",
6609     cbnz_info(r0, &unbound, &info),
6610     cbnz(r0, &label));
6611 
6612   TEST_FORWARD_REFERENCE_INFO(
6613     "cbz",
6614     cbz_info(r0, &unbound, &info),
6615     cbz(r0, &label));
6616 
6617   TEST_FORWARD_REFERENCE_INFO(
6618     "ldr",
6619     ldr_info(al, Narrow, r0, &unbound, &info),
6620     ldr(al, Narrow, r0, &label));
6621 
6622   TEST_FORWARD_REFERENCE_INFO(
6623     "ldr",
6624     ldr_info(al, Wide, r0, &unbound, &info),
6625     ldr(al, Wide, r0, &label));
6626 
6627   TEST_FORWARD_REFERENCE_INFO(
6628     "ldr",
6629     ldr_info(al, Best, r0, &unbound, &info),
6630     ldr(al, Best, r0, &label));
6631 
6632   TEST_FORWARD_REFERENCE_INFO(
6633     "ldrb",
6634     ldrb_info(al, r0, &unbound, &info),
6635     ldrb(al, r0, &label));
6636 
6637   TEST_FORWARD_REFERENCE_INFO(
6638     "ldrd",
6639     ldrd_info(al, r0, r1, &unbound, &info),
6640     ldrd(al, r0, r1, &label));
6641 
6642   TEST_FORWARD_REFERENCE_INFO(
6643     "ldrh",
6644     ldrh_info(al, r0, &unbound, &info),
6645     ldrh(al, r0, &label));
6646 
6647   TEST_FORWARD_REFERENCE_INFO(
6648     "ldrsb",
6649     ldrsb_info(al, r0, &unbound, &info),
6650     ldrsb(al, r0, &label));
6651 
6652   TEST_FORWARD_REFERENCE_INFO(
6653     "ldrsh",
6654     ldrsh_info(al, r0, &unbound, &info),
6655     ldrsh(al, r0, &label));
6656 
6657   TEST_FORWARD_REFERENCE_INFO(
6658     "pld",
6659     pld_info(al, &unbound, &info),
6660     pld(al, &label));
6661 
6662   TEST_FORWARD_REFERENCE_INFO(
6663     "pli",
6664     pli_info(al, &unbound, &info),
6665     pli(al, &label));
6666 
6667   TEST_FORWARD_REFERENCE_INFO(
6668     "vldr",
6669     vldr_info(al, Untyped64, d0, &unbound, &info),
6670     vldr(al, Untyped64, d0, &label));
6671 
6672   TEST_FORWARD_REFERENCE_INFO(
6673     "vldr",
6674     vldr_info(al, Untyped32, s0, &unbound, &info),
6675     vldr(al, Untyped32, s0, &label));
6676 
6677   // clang-format on
6678 
6679   masm.FinalizeCode();
6680 }
6681 
TEST_A32(forward_reference_info_A32)6682 TEST_A32(forward_reference_info_A32) {
6683   MacroAssembler masm(BUF_SIZE, A32);
6684   Label unbound;
6685   const ReferenceInfo* info;
6686   bool can_encode;
6687 
6688   // clang-format off
6689 
6690   TEST_FORWARD_REFERENCE_INFO(
6691     "adr",
6692     adr_info(al, Best, r0, &unbound, &info),
6693     adr(al, Best, r0, &label));
6694 
6695   TEST_FORWARD_REFERENCE_INFO(
6696     "b",
6697     b_info(al, Best, &unbound, &info),
6698     b(al, Best, &label));
6699 
6700   TEST_FORWARD_REFERENCE_INFO(
6701     "b",
6702     b_info(gt, Best, &unbound, &info),
6703     b(gt, Best, &label));
6704 
6705   TEST_FORWARD_REFERENCE_INFO(
6706     "bl",
6707     bl_info(al, &unbound, &info),
6708     bl(al, &label));
6709 
6710   TEST_FORWARD_REFERENCE_INFO(
6711     "blx",
6712     blx_info(al, &unbound, &info),
6713     blx(al, &label));
6714 
6715   TEST_FORWARD_REFERENCE_INFO(
6716     "ldr",
6717     ldr_info(al, Best, r0, &unbound, &info),
6718     ldr(al, Best, r0, &label));
6719 
6720   TEST_FORWARD_REFERENCE_INFO(
6721     "ldrb",
6722     ldrb_info(al, r0, &unbound, &info),
6723     ldrb(al, r0, &label));
6724 
6725   TEST_FORWARD_REFERENCE_INFO(
6726     "ldrd",
6727     ldrd_info(al, r0, r1, &unbound, &info),
6728     ldrd(al, r0, r1, &label));
6729 
6730   TEST_FORWARD_REFERENCE_INFO(
6731     "ldrh",
6732     ldrh_info(al, r0, &unbound, &info),
6733     ldrh(al, r0, &label));
6734 
6735   TEST_FORWARD_REFERENCE_INFO(
6736     "ldrsb",
6737     ldrsb_info(al, r0, &unbound, &info),
6738     ldrsb(al, r0, &label));
6739 
6740   TEST_FORWARD_REFERENCE_INFO(
6741     "ldrsh",
6742     ldrsh_info(al, r0, &unbound, &info),
6743     ldrsh(al, r0, &label));
6744 
6745   TEST_FORWARD_REFERENCE_INFO(
6746     "pld",
6747     pld_info(al, &unbound, &info),
6748     pld(al, &label));
6749 
6750   TEST_FORWARD_REFERENCE_INFO(
6751     "pli",
6752     pli_info(al, &unbound, &info),
6753     pli(al, &label));
6754 
6755   TEST_FORWARD_REFERENCE_INFO(
6756     "vldr",
6757     vldr_info(al, Untyped64, d0, &unbound, &info),
6758     vldr(al, Untyped64, d0, &label));
6759 
6760   TEST_FORWARD_REFERENCE_INFO(
6761     "vldr",
6762     vldr_info(al, Untyped32, s0, &unbound, &info),
6763     vldr(al, Untyped32, s0, &label));
6764 
6765   // clang-format on
6766 
6767   masm.FinalizeCode();
6768 }
6769 
6770 }  // namespace aarch32
6771 }  // namespace vixl
6772