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