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