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