test-assembler-aarch32.cc revision e44090587ff7104b4ad3f786e64940c82838387c
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// Tests declared with this macro will be run twice: once targeting A32 and
44// once targeting T32.
45#define TEST(Name)                                                \
46void Test##Name##Impl(InstructionSet isa);                        \
47void Test##Name() {                                               \
48  Test##Name##Impl(A32);                                          \
49  printf(" > A32 done\n");                                        \
50  Test##Name##Impl(T32);                                          \
51  printf(" > T32 done\n");                                        \
52}                                                                 \
53Test test_##Name(STRINGIFY(AARCH32_ASM_##Name), &Test##Name);     \
54void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
55
56// Test declared with this macro will only target A32.
57#define TEST_A32(Name)                                            \
58void Test##Name##Impl(InstructionSet isa);                        \
59void Test##Name() {                                               \
60  Test##Name##Impl(A32);                                          \
61}                                                                 \
62Test test_##Name(STRINGIFY(AARCH32_A32_##Name), &Test##Name);     \
63void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
64
65// Tests declared with this macro will only target T32.
66#define TEST_T32(Name)                                            \
67void Test##Name##Impl(InstructionSet isa);                        \
68void Test##Name() {                                               \
69  Test##Name##Impl(T32);                                          \
70}                                                                 \
71Test test_##Name(STRINGIFY(AARCH32_T32_##Name), &Test##Name);     \
72void Test##Name##Impl(InstructionSet isa __attribute__((unused)))
73
74// Tests declared with this macro are not expected to use any provided test
75// helpers such as SETUP, RUN, etc.
76#define TEST_NOASM(Name)                                   \
77void Test##Name();                                         \
78Test test_##Name(STRINGIFY(AARCH32_##Name), &Test##Name);  \
79void Test##Name()
80
81#define __ masm.
82#define BUF_SIZE (4096)
83
84#define ASSERT_LITERAL_POOL_SIZE(size) \
85    do { VIXL_CHECK(__ GetLiteralPoolSize() == size); } while (false)
86
87#ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
88// No simulator yet.
89
90#define SETUP()                                             \
91  MacroAssembler masm(BUF_SIZE, isa);                       \
92
93#define START() \
94  masm.GetBuffer()->Reset();
95
96#define END()                                                                  \
97  __ Hlt(0);                                                                   \
98  __ FinalizeCode();
99
100#define RUN()                                                                  \
101  DISASSEMBLE();
102
103#define TEARDOWN()
104
105#else  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32.
106
107#define SETUP()                                                                \
108  RegisterDump core;                                                           \
109  MacroAssembler masm(BUF_SIZE, isa);                                          \
110  UseScratchRegisterScope harness_scratch(&masm);                              \
111  harness_scratch.ExcludeAll();
112
113#define START()                                                                \
114  masm.GetBuffer()->Reset();                                                   \
115  __ Push(r4);                                                                 \
116  __ Push(r5);                                                                 \
117  __ Push(r6);                                                                 \
118  __ Push(r7);                                                                 \
119  __ Push(r8);                                                                 \
120  __ Push(r9);                                                                 \
121  __ Push(r10);                                                                \
122  __ Push(r11);                                                                \
123  __ Push(ip);                                                                 \
124  __ Push(lr);                                                                 \
125  __ Mov(r0, 0);                                                               \
126  __ Msr(APSR_nzcvq, r0);                                                      \
127  harness_scratch.Include(ip);
128
129#define END()                                                                  \
130  harness_scratch.Exclude(ip);                                                 \
131  core.Dump(&masm);                                                            \
132  __ Pop(lr);                                                                  \
133  __ Pop(ip);                                                                  \
134  __ Pop(r11);                                                                 \
135  __ Pop(r10);                                                                 \
136  __ Pop(r9);                                                                  \
137  __ Pop(r8);                                                                  \
138  __ Pop(r7);                                                                  \
139  __ Pop(r6);                                                                  \
140  __ Pop(r5);                                                                  \
141  __ Pop(r4);                                                                  \
142  __ Bx(lr);                                                                   \
143  __ FinalizeCode();
144
145// Execute the generated code from the MacroAssembler's automatic code buffer.
146// Note the offset for ExecuteMemory since the PCS requires that
147// the address be odd in the case of branching to T32 code.
148#define RUN()                                                                  \
149  DISASSEMBLE();                                                               \
150  {                                                                            \
151    int pcs_offset = masm.IsUsingT32() ? 1 : 0;                                \
152    masm.GetBuffer()->SetExecutable();                                         \
153    ExecuteMemory(masm.GetBuffer()->GetStartAddress<byte*>(),                  \
154                  masm.GetSizeOfCodeGenerated(),                               \
155                  pcs_offset);                                                 \
156    masm.GetBuffer()->SetWritable();                                           \
157  }
158
159#define TEARDOWN() \
160  harness_scratch.Close();
161
162#endif  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
163
164#ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
165// No simulator yet. We can't test the results.
166
167#define ASSERT_EQUAL_32(expected, result)
168
169#define ASSERT_EQUAL_64(expected, result)
170
171#define ASSERT_EQUAL_128(expected_h, expected_l, result)
172
173#define ASSERT_EQUAL_FP32(expected, result)
174
175#define ASSERT_EQUAL_FP64(expected, result)
176
177#define ASSERT_EQUAL_NZCV(expected)
178
179#else
180
181#define ASSERT_EQUAL_32(expected, result)                                      \
182  VIXL_CHECK(Equal32(expected, &core, result))
183
184#define ASSERT_EQUAL_64(expected, result)                                      \
185  VIXL_CHECK(Equal64(expected, &core, result))
186
187#define ASSERT_EQUAL_128(expected_h, expected_l, result)                       \
188  VIXL_CHECK(Equal128(expected_h, expected_l, &core, result))
189
190#define ASSERT_EQUAL_FP32(expected, result)                                    \
191  VIXL_CHECK(EqualFP32(expected, &core, result))
192
193#define ASSERT_EQUAL_FP64(expected, result)                                    \
194  VIXL_CHECK(EqualFP64(expected, &core, result))
195
196#define ASSERT_EQUAL_NZCV(expected)                                            \
197  VIXL_CHECK(EqualNzcv(expected, core.flags_nzcv()))
198
199#endif
200
201#define DISASSEMBLE() \
202  if (Test::disassemble()) {                                                   \
203    PrintDisassembler dis(std::cout, 0);                                       \
204    if (masm.IsUsingT32()) {                                                   \
205      dis.DisassembleT32Buffer(masm.GetBuffer()->GetStartAddress<uint16_t*>(), \
206                               masm.GetCursorOffset());                        \
207    } else {                                                                   \
208      dis.DisassembleA32Buffer(masm.GetBuffer()->GetStartAddress<uint32_t*>(), \
209                               masm.GetCursorOffset());                        \
210    }                                                                          \
211  }
212
213// TODO: Add SBC to the ADC tests.
214
215
216TEST(adc_shift) {
217  SETUP();
218
219  START();
220  // Initialize registers.
221  __ Mov(r0, 0);
222  __ Mov(r1, 1);
223  __ Mov(r2, 0x01234567);
224  __ Mov(r3, 0xfedcba98);
225
226  // Clear the C flag.
227  __ Adds(r0, r0, 0);
228
229  __ Adc(r4, r2, r3);
230  __ Adc(r5, r0, Operand(r1, LSL, 30));
231  __ Adc(r6, r0, Operand(r2, LSR, 16));
232  __ Adc(r7, r2, Operand(r3, ASR, 4));
233  __ Adc(r8, r2, Operand(r3, ROR, 8));
234  __ Adc(r9, r2, Operand(r3, RRX));
235  END();
236
237  RUN();
238
239  ASSERT_EQUAL_32(0xffffffff, r4);
240  ASSERT_EQUAL_32(INT32_C(1) << 30, r5);
241  ASSERT_EQUAL_32(0x00000123, r6);
242  ASSERT_EQUAL_32(0x01111110, r7);
243  ASSERT_EQUAL_32(0x9a222221, r8);
244  ASSERT_EQUAL_32(0x8091a2b3, r9);
245
246  START();
247  // Initialize registers.
248  __ Mov(r0, 0);
249  __ Mov(r1, 1);
250  __ Mov(r2, 0x01234567);
251  __ Mov(r3, 0xfedcba98);
252  __ Mov(r4, 0xffffffff);
253
254  // Set the C flag.
255  __ Adds(r0, r4, r1);
256
257  __ Adc(r5, r2, r3);
258  __ Adc(r6, r0, Operand(r1, LSL, 30));
259  __ Adc(r7, r0, Operand(r2, LSR, 16));
260  __ Adc(r8, r2, Operand(r3, ASR, 4));
261  __ Adc(r9, r2, Operand(r3, ROR, 8));
262  __ Adc(r10, r2, Operand(r3, RRX));
263  END();
264
265  RUN();
266
267  ASSERT_EQUAL_32(0xffffffff + 1, r5);
268  ASSERT_EQUAL_32((INT32_C(1) << 30) + 1, r6);
269  ASSERT_EQUAL_32(0x00000123 + 1, r7);
270  ASSERT_EQUAL_32(0x01111110 + 1, r8);
271  ASSERT_EQUAL_32(0x9a222221 + 1, r9);
272  ASSERT_EQUAL_32(0x0091a2b3 + 1, r10);
273
274  // Check that adc correctly sets the condition flags.
275  START();
276  __ Mov(r0, 0);
277  __ Mov(r1, 0xffffffff);
278  __ Mov(r2, 1);
279
280  // Clear the C flag.
281  __ Adds(r0, r0, 0);
282  __ Adcs(r3, r2, r1);
283  END();
284
285  RUN();
286
287  ASSERT_EQUAL_NZCV(ZCFlag);
288  ASSERT_EQUAL_32(0, r3);
289
290  START();
291  __ Mov(r0, 0);
292  __ Mov(r1, 0x80000000);
293  __ Mov(r2, 1);
294
295  // Clear the C flag.
296  __ Adds(r0, r0, 0);
297  __ Adcs(r3, r2, Operand(r1, ASR, 31));
298  END();
299
300  RUN();
301
302  ASSERT_EQUAL_NZCV(ZCFlag);
303  ASSERT_EQUAL_32(0, r3);
304
305  START();
306  __ Mov(r0, 0);
307  __ Mov(r1, 0x80000000);
308  __ Mov(r2, 0xffffffff);
309
310  // Clear the C flag.
311  __ Adds(r0, r0, 0);
312  __ Adcs(r3, r2, Operand(r1, LSR, 31));
313  END();
314
315  RUN();
316
317  ASSERT_EQUAL_NZCV(ZCFlag);
318  ASSERT_EQUAL_32(0, r3);
319
320  START();
321  __ Mov(r0, 0);
322  __ Mov(r1, 0x07ffffff);
323  __ Mov(r2, 0x10);
324
325  // Clear the C flag.
326  __ Adds(r0, r0, 0);
327  __ Adcs(r3, r2, Operand(r1, LSL, 4));
328  END();
329
330  RUN();
331
332  ASSERT_EQUAL_NZCV(NVFlag);
333  ASSERT_EQUAL_32(0x080000000, r3);
334
335  START();
336  __ Mov(r0, 0);
337  __ Mov(r1, 0xffffff00);
338  __ Mov(r2, 0xff000001);
339
340  // Clear the C flag.
341  __ Adds(r0, r0, 0);
342  __ Adcs(r3, r2, Operand(r1, ROR, 8));
343  END();
344
345  RUN();
346
347  ASSERT_EQUAL_NZCV(ZCFlag);
348  ASSERT_EQUAL_32(0, r3);
349
350  START();
351  __ Mov(r0, 0);
352  __ Mov(r1, 0xffffffff);
353  __ Mov(r2, 0x1);
354
355  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
356  __ Adds(r0, r0, 0);
357  __ Adcs(r3, r2, Operand(r1, RRX));
358  END();
359
360  RUN();
361
362  ASSERT_EQUAL_NZCV(NVFlag);
363  ASSERT_EQUAL_32(0x80000000, r3);
364
365  START();
366  __ Mov(r0, 0);
367  __ Mov(r1, 0xffffffff);
368  __ Mov(r2, 0x1);
369
370  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
371  __ Adds(r0, r1, r2);
372  __ Adcs(r3, r2, Operand(r1, RRX));
373  END();
374
375  RUN();
376
377  ASSERT_EQUAL_NZCV(CFlag);
378  ASSERT_EQUAL_32(1, r3);
379
380  TEARDOWN();
381}
382
383
384TEST(adc_wide_imm) {
385  SETUP();
386
387  START();
388  __ Mov(r0, 0);
389
390  // Clear the C flag.
391  __ Adds(r0, r0, 0);
392
393  __ Adc(r1, r0, 0x12345678);
394  __ Adc(r2, r0, 0xffffffff);
395
396  // Set the C flag.
397  __ Cmp(r0, r0);
398
399  __ Adc(r3, r0, 0x12345678);
400  __ Adc(r4, r0, 0xffffffff);
401  END();
402
403  RUN();
404
405  ASSERT_EQUAL_32(0x12345678, r1);
406  ASSERT_EQUAL_32(0xffffffff, r2);
407  ASSERT_EQUAL_32(0x12345678 + 1, r3);
408  ASSERT_EQUAL_32(0, r4);
409
410  TEARDOWN();
411}
412
413
414// TODO: Add SUB tests to the ADD tests.
415
416
417TEST(add_imm) {
418  SETUP();
419
420  START();
421  __ Mov(r0, 0);
422  __ Mov(r1, 0x1111);
423  __ Mov(r2, 0xffffffff);
424  __ Mov(r3, 0x80000000);
425
426  __ Add(r4, r0, 0x12);
427  __ Add(r5, r1, 0x120000);
428  __ Add(r6, r0, 0xab << 12);
429  __ Add(r7, r2, 1);
430
431  END();
432
433  RUN();
434
435  ASSERT_EQUAL_32(0x12, r4);
436  ASSERT_EQUAL_32(0x121111, r5);
437  ASSERT_EQUAL_32(0xab000, r6);
438  ASSERT_EQUAL_32(0x0, r7);
439
440  TEARDOWN();
441}
442
443
444TEST(add_wide_imm) {
445  SETUP();
446
447  START();
448  __ Mov(r0, 0);
449  __ Mov(r1, 1);
450
451  __ Add(r2, r0, 0x12345678);
452  __ Add(r3, r1, 0xffff);
453  END();
454
455  RUN();
456
457  ASSERT_EQUAL_32(0x12345678, r2);
458  ASSERT_EQUAL_32(0x00010000, r3);
459
460  TEARDOWN();
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  TEARDOWN();
500}
501
502
503TEST(and_) {
504  SETUP();
505
506  START();
507  __ Mov(r0, 0x0000fff0);
508  __ Mov(r1, 0xf00000ff);
509  __ Mov(r2, 0xffffffff);
510
511  __ And(r3, r0, r1);
512  __ And(r4, r0, Operand(r1, LSL, 4));
513  __ And(r5, r0, Operand(r1, LSR, 1));
514  __ And(r6, r0, Operand(r1, ASR, 20));
515  __ And(r7, r0, Operand(r1, ROR, 28));
516  __ And(r8, r0, 0xff);
517
518  // Set the C flag.
519  __ Adds(r9, r2, 1);
520  __ And(r9, r1, Operand(r1, RRX));
521
522  // Clear the C flag.
523  __ Adds(r10, r0, 0);
524  __ And(r10, r1, Operand(r1, RRX));
525  END();
526
527  RUN();
528
529  ASSERT_EQUAL_32(0x000000f0, r3);
530  ASSERT_EQUAL_32(0x00000ff0, r4);
531  ASSERT_EQUAL_32(0x00000070, r5);
532  ASSERT_EQUAL_32(0x0000ff00, r6);
533  ASSERT_EQUAL_32(0x00000ff0, r7);
534  ASSERT_EQUAL_32(0x000000f0, r8);
535  ASSERT_EQUAL_32(0xf000007f, r9);
536  ASSERT_EQUAL_32(0x7000007f, r10);
537
538  TEARDOWN();
539}
540
541
542TEST(ands) {
543  SETUP();
544
545  START();
546  __ Mov(r0, 0);
547  __ Mov(r1, 0xf00000ff);
548
549  __ Ands(r0, r1, r1);
550  END();
551
552  RUN();
553
554  ASSERT_EQUAL_NZCV(NFlag);
555  ASSERT_EQUAL_32(0xf00000ff, r0);
556
557  START();
558  __ Mov(r0, 0x00fff000);
559  __ Mov(r1, 0xf00000ff);
560
561  __ Ands(r0, r0, Operand(r1, LSL, 4));
562  END();
563
564  RUN();
565
566  ASSERT_EQUAL_NZCV(ZCFlag);
567  ASSERT_EQUAL_32(0x00000000, r0);
568
569  START();
570  __ Mov(r0, 0x0000fff0);
571  __ Mov(r1, 0xf00000ff);
572
573  __ Ands(r0, r0, Operand(r1, LSR, 4));
574  END();
575
576  RUN();
577
578  ASSERT_EQUAL_NZCV(ZCFlag);
579  ASSERT_EQUAL_32(0x00000000, r0);
580
581  START();
582  __ Mov(r0, 0xf000fff0);
583  __ Mov(r1, 0xf00000ff);
584
585  __ Ands(r0, r0, Operand(r1, ASR, 4));
586  END();
587
588  RUN();
589
590  ASSERT_EQUAL_NZCV(NCFlag);
591  ASSERT_EQUAL_32(0xf0000000, r0);
592
593  START();
594  __ Mov(r0, 0x80000000);
595  __ Mov(r1, 0x00000001);
596
597  __ Ands(r0, r0, Operand(r1, ROR, 1));
598  END();
599
600  RUN();
601
602  ASSERT_EQUAL_NZCV(NCFlag);
603  ASSERT_EQUAL_32(0x80000000, r0);
604
605  START();
606  __ Mov(r0, 0x80000000);
607  __ Mov(r1, 0x80000001);
608
609  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
610  __ Adds(r2, r0, 0);
611  __ Ands(r2, r0, Operand(r1, RRX));
612  END();
613
614  RUN();
615
616  ASSERT_EQUAL_NZCV(ZCFlag);
617  ASSERT_EQUAL_32(0, r2);
618
619  START();
620  __ Mov(r0, 0x80000000);
621  __ Mov(r1, 0x80000001);
622  __ Mov(r2, 0xffffffff);
623
624  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
625  __ Adds(r2, r2, 1);
626  __ Ands(r2, r0, Operand(r1, RRX));
627  END();
628
629  RUN();
630
631  ASSERT_EQUAL_NZCV(NCFlag);
632  ASSERT_EQUAL_32(0x80000000, r2);
633
634  START();
635  __ Mov(r0, 0xfff0);
636
637  __ Ands(r0, r0, 0xf);
638  END();
639
640  RUN();
641
642  ASSERT_EQUAL_NZCV(ZFlag);
643  ASSERT_EQUAL_32(0x00000000, r0);
644
645  START();
646  __ Mov(r0, 0xff000000);
647
648  __ Ands(r0, r0, 0x80000000);
649  END();
650
651  RUN();
652
653  ASSERT_EQUAL_NZCV(NCFlag);
654  ASSERT_EQUAL_32(0x80000000, r0);
655
656  TEARDOWN();
657}
658
659
660// TODO: fix this test in T32.
661TEST_A32(adr) {
662  SETUP();
663
664  Label label_1, label_2, label_3, label_4;
665
666  START();
667  __ Mov(r0, 0x0);
668  __ Adr(r1, &label_3);   // Set to zero to indicate success.
669
670  __ Adr(r2, &label_1);   // Multiple forward references to the same label.
671  __ Adr(r3, &label_1);
672  __ Adr(r4, &label_1);
673
674  __ Bind(&label_2);
675  __ Eor(r5, r2, r3);  // Ensure that r2,r3 and r4 are identical.
676  __ Eor(r6, r2, r4);
677  __ Mov(r0, r5);
678  __ Mov(r0, r6);
679  __ Bx(r2);  // label_1, label_3
680
681  __ Bind(&label_3);
682  __ Adr(r2, &label_3);   // Self-reference (offset 0).
683  __ Eor(r1, r1, r2);
684  __ Adr(r2, &label_4);   // Simple forward reference.
685  __ Bx(r2);  // label_4
686
687  __ Bind(&label_1);
688  __ Adr(r2, &label_3);   // Multiple reverse references to the same label.
689  __ Adr(r3, &label_3);
690  __ Adr(r4, &label_3);
691  __ Adr(r5, &label_2);   // Simple reverse reference.
692  __ Bx(r5);  // label_2
693
694  __ Bind(&label_4);
695  END();
696
697  RUN();
698
699  ASSERT_EQUAL_32(0x0, r0);
700  ASSERT_EQUAL_32(0x0, r1);
701
702  TEARDOWN();
703}
704
705
706TEST(shift_imm) {
707  SETUP();
708
709  START();
710  __ Mov(r0, 0);
711  __ Mov(r1, 0xfedcba98);
712  __ Mov(r2, 0xffffffff);
713
714  __ Lsl(r3, r1, 4);
715  __ Lsr(r4, r1, 8);
716  __ Asr(r5, r1, 16);
717  __ Ror(r6, r1, 20);
718  END();
719
720  RUN();
721
722  ASSERT_EQUAL_32(0xedcba980, r3);
723  ASSERT_EQUAL_32(0x00fedcba, r4);
724  ASSERT_EQUAL_32(0xfffffedc, r5);
725  ASSERT_EQUAL_32(0xcba98fed, r6);
726
727  TEARDOWN();
728}
729
730
731TEST(shift_reg) {
732  SETUP();
733
734  START();
735  __ Mov(r0, 0);
736  __ Mov(r1, 0xfedcba98);
737  __ Mov(r2, 0xffffffff);
738
739  __ Add(r9, r0, 4);
740  __ Lsl(r3, r1, r9);
741
742  __ Add(r9, r0, 8);
743  __ Lsr(r4, r1, r9);
744
745  __ Add(r9, r0, 16);
746  __ Asr(r5, r1, r9);
747
748  __ Add(r9, r0, 20);
749  __ Ror(r6, r1, r9);
750
751  // Set the C flag.
752  __ Adds(r7, r2, 1);
753  __ Rrx(r7, r1);
754
755  // Clear the C flag.
756  __ Adds(r8, r0, 0);
757  __ Rrx(r8, r1);
758  END();
759
760  RUN();
761
762  ASSERT_EQUAL_32(0xedcba980, r3);
763  ASSERT_EQUAL_32(0x00fedcba, r4);
764  ASSERT_EQUAL_32(0xfffffedc, r5);
765  ASSERT_EQUAL_32(0xcba98fed, r6);
766  ASSERT_EQUAL_32(0xff6e5d4c, r7);
767  ASSERT_EQUAL_32(0x7f6e5d4c, r8);
768
769  TEARDOWN();
770}
771
772
773TEST(branch_cond) {
774  SETUP();
775
776  Label done, wrong;
777
778  START();
779  __ Mov(r0, 0x0);
780  __ Mov(r1, 0x1);
781  __ Mov(r2, 0x80000000);
782  // TODO: Use r0 instead of r3 when r0 becomes available.
783  __ Mov(r3, 0x1);
784
785  // For each 'cmp' instruction below, condition codes other than the ones
786  // following it would branch.
787
788  __ Cmp(r1, 0);
789  __ B(eq, &wrong);
790  __ B(lo, &wrong);
791  __ B(mi, &wrong);
792  __ B(vs, &wrong);
793  __ B(ls, &wrong);
794  __ B(lt, &wrong);
795  __ B(le, &wrong);
796  Label ok_1;
797  __ B(ne, &ok_1);
798  // TODO: Use __ Mov(r0, 0x0) instead.
799  __ Add(r3, r0, 0x0);
800  __ Bind(&ok_1);
801
802  __ Cmp(r1, 1);
803  __ B(ne, &wrong);
804  __ B(lo, &wrong);
805  __ B(mi, &wrong);
806  __ B(vs, &wrong);
807  __ B(hi, &wrong);
808  __ B(lt, &wrong);
809  __ B(gt, &wrong);
810  Label ok_2;
811  __ B(pl, &ok_2);
812  // TODO: Use __ Mov(r0, 0x0) instead.
813  __ Add(r3, r0, 0x0);
814  __ Bind(&ok_2);
815
816  __ Cmp(r1, 2);
817  __ B(eq, &wrong);
818  __ B(hs, &wrong);
819  __ B(pl, &wrong);
820  __ B(vs, &wrong);
821  __ B(hi, &wrong);
822  __ B(ge, &wrong);
823  __ B(gt, &wrong);
824  Label ok_3;
825  __ B(vc, &ok_3);
826  // TODO: Use __ Mov(r0, 0x0) instead.
827  __ Add(r3, r0, 0x0);
828  __ Bind(&ok_3);
829
830  __ Cmp(r2, 1);
831  __ B(eq, &wrong);
832  __ B(lo, &wrong);
833  __ B(mi, &wrong);
834  __ B(vc, &wrong);
835  __ B(ls, &wrong);
836  __ B(ge, &wrong);
837  __ B(gt, &wrong);
838  Label ok_4;
839  __ B(le, &ok_4);
840  // TODO: Use __ Mov(r0, 0x0) instead.
841  __ Add(r3, r0, 0x0);
842  __ Bind(&ok_4);
843
844  Label ok_5;
845  __ B(&ok_5);
846  // TODO: Use __ Mov(r0, 0x0) instead.
847  __ Add(r3, r0, 0x0);
848  __ Bind(&ok_5);
849
850  __ B(&done);
851
852  __ Bind(&wrong);
853  // TODO: Use __ Mov(r0, 0x0) instead.
854  __ Add(r3, r0, 0x0);
855
856  __ Bind(&done);
857  END();
858
859  RUN();
860
861  // TODO: Use r0.
862  ASSERT_EQUAL_32(0x1, r3);
863
864  TEARDOWN();
865}
866
867
868TEST(bfc_bfi) {
869  SETUP();
870
871  START();
872  __ Mov(r0, 0xffffffff);
873  __ Mov(r1, 0x01234567);
874  __ Mov(r2, 0x0);
875
876  __ Bfc(r0, 0, 3);
877  __ Bfc(r0, 16, 5);
878
879  __ Bfi(r2, r1, 0, 8);
880  __ Bfi(r2, r1, 16, 16);
881  END();
882
883  RUN();
884
885  ASSERT_EQUAL_32(0xffe0fff8, r0);
886  ASSERT_EQUAL_32(0x45670067, r2);
887
888  TEARDOWN();
889}
890
891
892TEST(bic) {
893  SETUP();
894
895  START();
896  __ Mov(r0, 0xfff0);
897  __ Mov(r1, 0xf00000ff);
898  __ Mov(r2, 0xffffffff);
899
900  __ Bic(r3, r0, r1);
901  __ Bic(r4, r0, Operand(r1, LSL, 4));
902  __ Bic(r5, r0, Operand(r1, LSR, 1));
903  __ Bic(r6, r0, Operand(r1, ASR, 20));
904  __ Bic(r7, r0, Operand(r1, ROR, 28));
905  __ Bic(r8, r0, 0x1f);
906
907  // Set the C flag.
908  __ Adds(r9, r2, 1);
909  __ Bic(r9, r1, Operand(r1, RRX));
910
911  // Clear the C flag.
912  __ Adds(r10, r0, 0);
913  __ Bic(r10, r1, Operand(r1, RRX));
914  END();
915
916  RUN();
917
918  ASSERT_EQUAL_32(0x0000ff00, r3);
919  ASSERT_EQUAL_32(0x0000f000, r4);
920  ASSERT_EQUAL_32(0x0000ff80, r5);
921  ASSERT_EQUAL_32(0x000000f0, r6);
922  ASSERT_EQUAL_32(0x0000f000, r7);
923  ASSERT_EQUAL_32(0x0000ffe0, r8);
924  ASSERT_EQUAL_32(0x00000080, r9);
925  ASSERT_EQUAL_32(0x80000080, r10);
926
927  TEARDOWN();
928}
929
930
931TEST(bics) {
932  SETUP();
933
934  START();
935  __ Mov(r0, 0);
936  __ Mov(r1, 0xf00000ff);
937
938  __ Bics(r0, r1, r1);
939  END();
940
941  RUN();
942
943  ASSERT_EQUAL_NZCV(ZFlag);
944  ASSERT_EQUAL_32(0, r0);
945
946  START();
947  __ Mov(r0, 0x00fff000);
948  __ Mov(r1, 0x0fffff00);
949
950  __ Bics(r0, r0, Operand(r1, LSL, 4));
951  END();
952
953  RUN();
954
955  ASSERT_EQUAL_NZCV(ZFlag);
956  ASSERT_EQUAL_32(0x00000000, r0);
957
958  START();
959  __ Mov(r0, 0x0000fff0);
960  __ Mov(r1, 0x0fffff00);
961
962  __ Bics(r0, r0, Operand(r1, LSR, 4));
963  END();
964
965  RUN();
966
967  ASSERT_EQUAL_NZCV(ZFlag);
968  ASSERT_EQUAL_32(0x00000000, r0);
969
970  START();
971  __ Mov(r0, 0xf000fff0);
972  __ Mov(r1, 0x0fffff00);
973
974  __ Bics(r0, r0, Operand(r1, ASR, 4));
975  END();
976
977  RUN();
978
979  ASSERT_EQUAL_NZCV(NFlag);
980  ASSERT_EQUAL_32(0xf0000000, r0);
981
982  START();
983  __ Mov(r0, 0x80000000);
984  __ Mov(r1, 0xfffffffe);
985
986  __ Bics(r0, r0, Operand(r1, ROR, 1));
987  END();
988
989  RUN();
990
991  ASSERT_EQUAL_NZCV(NFlag);
992  ASSERT_EQUAL_32(0x80000000, r0);
993
994  START();
995  __ Mov(r0, 0x80000000);
996  __ Mov(r1, 0x80000001);
997
998  // Clear the C flag, forcing RRX to insert 0 in r1's most significant bit.
999  __ Adds(r2, r0, 0);
1000  __ Bics(r2, r0, Operand(r1, RRX));
1001  END();
1002
1003  RUN();
1004
1005  ASSERT_EQUAL_NZCV(NCFlag);
1006  ASSERT_EQUAL_32(0x80000000, r2);
1007
1008  START();
1009  __ Mov(r0, 0x80000000);
1010  __ Mov(r1, 0x80000001);
1011  __ Mov(r2, 0xffffffff);
1012
1013  // Set the C flag, forcing RRX to insert 1 in r1's most significant bit.
1014  __ Adds(r2, r2, 1);
1015  __ Bics(r2, r0, Operand(r1, RRX));
1016  END();
1017
1018  RUN();
1019
1020  ASSERT_EQUAL_NZCV(ZCFlag);
1021  ASSERT_EQUAL_32(0, r2);
1022
1023  START();
1024  __ Mov(r0, 0xf000);
1025
1026  __ Bics(r0, r0, 0xf000);
1027  END();
1028
1029  RUN();
1030
1031  ASSERT_EQUAL_NZCV(ZFlag);
1032  ASSERT_EQUAL_32(0x00000000, r0);
1033
1034  START();
1035  __ Mov(r0, 0xff000000);
1036
1037  __ Bics(r0, r0, 0x7fffffff);
1038  END();
1039
1040  RUN();
1041
1042  ASSERT_EQUAL_NZCV(NFlag);
1043  ASSERT_EQUAL_32(0x80000000, r0);
1044
1045  TEARDOWN();
1046}
1047
1048
1049TEST_T32(veneer_pool_in_delegate) {
1050  SETUP();
1051
1052  START();
1053
1054  Label end;
1055
1056  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1057  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1058
1059  __ Mov(r0, 1);
1060  __ Cbz(r0, &end);
1061
1062  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
1063  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1064
1065  // Generate enough code to have, after the loop, a margin of only one 16-bit
1066  // instruction that can be generated before we need to generate the veneer
1067  // pool.
1068  // Use `ExactAssemblyScope` and the assembler to generate the code.
1069  int32_t space =
1070      masm.GetMarginBeforeVeneerEmission() - k16BitT32InstructionSizeInBytes;
1071  {
1072    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1073    while (space > 0) {
1074      __ nop();
1075      space -= k16BitT32InstructionSizeInBytes;
1076    }
1077  }
1078
1079  // We should not have emitted the veneer pool at this point.
1080  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
1081  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1082  VIXL_CHECK(
1083      masm.GetMarginBeforeVeneerEmission() == k16BitT32InstructionSizeInBytes);
1084
1085  // Now generate `Mov(r1, 0x12345678)`. It needs to 16-bit assembler
1086  // instructions, so it has to go through the `MacroAssembler` delegate. Since
1087  // there is only margin for one instruction to be generated, the pool will
1088  // have to be generated from within the `MacroAssembler` delegate. That should
1089  // not fire.
1090  Label check;
1091  __ Bind(&check);
1092  __ Mov(r1, 0x12345678);
1093  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) >
1094             2 * kMaxInstructionSizeInBytes);
1095  __ Bind(&end);
1096
1097  END();
1098
1099  RUN();
1100
1101  ASSERT_EQUAL_32(0x12345678, r1);
1102
1103  TEARDOWN();
1104}
1105
1106
1107TEST_T32(literal_pool_in_delegate) {
1108  SETUP();
1109
1110  START();
1111
1112  PrintDisassembler disasm(std::cout);
1113
1114  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1115  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1116
1117  __ Ldrd(r0, r1, 0x1234567890abcdef);
1118
1119  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1120  VIXL_CHECK(!masm.LiteralPoolIsEmpty());
1121
1122  // Generate enough code to have, after the loop, a margin of only one 16-bit
1123  // instruction that can be generated before we need to generate the literal
1124  // pool.
1125  // Use `CodeBufferCheckScope` and the assembler to generate the code.
1126  int32_t space = masm.GetMarginBeforeLiteralEmission() -
1127      2 * k16BitT32InstructionSizeInBytes;
1128  {
1129    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1130    while (space > 0) {
1131      __ nop();
1132      space -= k16BitT32InstructionSizeInBytes;
1133    }
1134  }
1135
1136  // We should not have emitted the literal pool at this point.
1137  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1138  VIXL_CHECK(!masm.LiteralPoolIsEmpty());
1139  VIXL_CHECK(masm.GetMarginBeforeLiteralEmission() ==
1140             2 * k16BitT32InstructionSizeInBytes);
1141
1142  // Now generate `Mov(r1, 0x12345678)`. It needs to 16-bit assembler
1143  // instructions, so it has to go through the `MacroAssembler` delegate. Since
1144  // there is only margin for one instruction to be generated, the pool will
1145  // have to be generated from within the `MacroAssembler` delegate. That should
1146  // not fire.
1147  Label check;
1148  __ Bind(&check);
1149  __ Mov(r1, 0x12345678);
1150  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) >
1151             2 * kMaxInstructionSizeInBytes);
1152
1153  VIXL_CHECK(masm.VeneerPoolIsEmpty());
1154  VIXL_CHECK(masm.LiteralPoolIsEmpty());
1155
1156  END();
1157
1158  RUN();
1159
1160  ASSERT_EQUAL_32(0x12345678, r1);
1161
1162  TEARDOWN();
1163}
1164
1165
1166TEST(emit_single_literal) {
1167  SETUP();
1168
1169  START();
1170  // Make sure the pool is empty.
1171  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1172  ASSERT_LITERAL_POOL_SIZE(0);
1173
1174  // Create one literal pool entry.
1175  __ Ldrd(r0, r1, 0x1234567890abcdef);
1176  ASSERT_LITERAL_POOL_SIZE(8);
1177  __ Vldr(s0, 1.0);
1178  __ Vldr(d1, 2.0);
1179  __ Vmov(d2, 4.1);
1180  __ Vmov(s8, 8.2);
1181  ASSERT_LITERAL_POOL_SIZE(20);
1182  END();
1183
1184  RUN();
1185
1186  // Check that the literals loaded correctly.
1187  ASSERT_EQUAL_32(0x90abcdef, r0);
1188  ASSERT_EQUAL_32(0x12345678, r1);
1189  ASSERT_EQUAL_FP32(1.0f, s0);
1190  ASSERT_EQUAL_FP64(2.0, d1);
1191  ASSERT_EQUAL_FP64(4.1, d2);
1192  ASSERT_EQUAL_FP32(8.2f, s8);
1193
1194  TEARDOWN();
1195}
1196
1197
1198#undef __
1199#define __ masm->
1200
1201
1202void EmitLdrdLiteralTest(MacroAssembler* masm) {
1203  const int ldrd_range = masm->IsUsingA32() ? 255 : 1020;
1204  // We want to emit code up to the maximum literal load range and ensure the
1205  // pool has not been emitted. Compute the limit (end).
1206  ptrdiff_t end =
1207      AlignDown(
1208          // Align down the PC to 4 bytes as the instruction does when it's
1209          // executed.
1210          // The PC will be the cursor offset plus the architecture state PC
1211          // offset.
1212          AlignDown(masm->GetBuffer()->GetCursorOffset() +
1213                    masm->GetArchitectureStatePCOffset(), 4) +
1214          // Maximum range allowed to access the constant.
1215          ldrd_range -
1216          // The literal pool has a two instruction margin.
1217          2 * kMaxInstructionSizeInBytes,
1218          // AlignDown to 4 byte as the literals will be 4 byte aligned.
1219          4);
1220
1221  // Create one literal pool entry.
1222  __ Ldrd(r0, r1, 0x1234567890abcdef);
1223  ASSERT_LITERAL_POOL_SIZE(8);
1224
1225  int32_t margin = masm->GetMarginBeforeLiteralEmission();
1226  {
1227    ExactAssemblyScope scope(masm, margin, ExactAssemblyScope::kExactSize);
1228    // Opening the scope should not have triggered the emission of the literal
1229    // pool.
1230    VIXL_CHECK(!masm->LiteralPoolIsEmpty());
1231    while (masm->GetCursorOffset() < end) {
1232      __ nop();
1233    }
1234    VIXL_CHECK(masm->GetCursorOffset() == end);
1235  }
1236
1237  // Check that the pool has not been emited along the way.
1238  ASSERT_LITERAL_POOL_SIZE(8);
1239  // This extra instruction should trigger an emit of the pool.
1240  __ Nop();
1241  // The pool should have been emitted.
1242  ASSERT_LITERAL_POOL_SIZE(0);
1243}
1244
1245
1246#undef __
1247#define __ masm.
1248
1249
1250TEST(emit_literal) {
1251  SETUP();
1252
1253  START();
1254
1255  // Make sure the pool is empty.
1256  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1257  ASSERT_LITERAL_POOL_SIZE(0);
1258
1259  EmitLdrdLiteralTest(&masm);
1260
1261  const int ldrd_range = masm.IsUsingA32() ? 255 : 1020;
1262  const int string_size = AlignUp(ldrd_range + kMaxInstructionSizeInBytes, 4);
1263  std::string test_string(string_size, 'x');
1264  StringLiteral big_literal(test_string.c_str());
1265  __ Adr(r4, &big_literal);
1266  // This add will overflow the literal pool and force a rewind.
1267  // That means that the string will be generated then, then Ldrd and the
1268  // ldrd's value will be alone in the pool.
1269  __ Ldrd(r2, r3, 0xcafebeefdeadbaba);
1270  ASSERT_LITERAL_POOL_SIZE(8);
1271
1272  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1273  ASSERT_LITERAL_POOL_SIZE(0);
1274  __ Ldr(r4, MemOperand(r4));  // Load the first 4 characters in r4.
1275  END();
1276
1277  RUN();
1278
1279  // Check that the literals loaded correctly.
1280  ASSERT_EQUAL_32(0x90abcdef, r0);
1281  ASSERT_EQUAL_32(0x12345678, r1);
1282  ASSERT_EQUAL_32(0xdeadbaba, r2);
1283  ASSERT_EQUAL_32(0xcafebeef, r3);
1284  ASSERT_EQUAL_32(0x78787878, r4);
1285
1286  TEARDOWN();
1287}
1288
1289TEST_T32(emit_literal_unaligned) {
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  // Generate a nop to break the 4 bytes alignment.
1299  __ Nop();
1300
1301  EmitLdrdLiteralTest(&masm);
1302
1303  END();
1304
1305  RUN();
1306
1307  // Check that the literals loaded correctly.
1308  ASSERT_EQUAL_32(0x90abcdef, r0);
1309  ASSERT_EQUAL_32(0x12345678, r1);
1310
1311  TEARDOWN();
1312}
1313
1314
1315TEST(literal_multiple_uses) {
1316  SETUP();
1317
1318  START();
1319  Literal<int32_t> lit(42);
1320  __ Ldr(r0, &lit);
1321  ASSERT_LITERAL_POOL_SIZE(4);
1322
1323  // Multiple uses of the same literal object should not make the
1324  // pool grow.
1325  __ Ldrb(r1, &lit);
1326  __ Ldrsb(r2, &lit);
1327  __ Ldrh(r3, &lit);
1328  __ Ldrsh(r4, &lit);
1329  ASSERT_LITERAL_POOL_SIZE(4);
1330
1331  END();
1332
1333  RUN();
1334
1335  ASSERT_EQUAL_32(42, r0);
1336  ASSERT_EQUAL_32(42, r1);
1337  ASSERT_EQUAL_32(42, r2);
1338  ASSERT_EQUAL_32(42, r3);
1339  ASSERT_EQUAL_32(42, r4);
1340
1341  TEARDOWN();
1342}
1343
1344
1345// A test with two loads literal which go out of range at the same time.
1346TEST_A32(ldr_literal_range_same_time) {
1347  SETUP();
1348
1349  START();
1350  const int ldrd_range = 255;
1351  // We need to take into account the jump over the pool.
1352  const int ldrd_padding = ldrd_range - 2 * kA32InstructionSizeInBytes;
1353  const int ldr_range = 4095;
1354  // We need to take into account the ldrd padding and the ldrd instruction.
1355  const int ldr_padding = ldr_range - ldrd_padding - 2 * kA32InstructionSizeInBytes;
1356
1357  __ Ldr(r1, 0x12121212);
1358  ASSERT_LITERAL_POOL_SIZE(4);
1359
1360  {
1361    int space = AlignDown(ldr_padding, kA32InstructionSizeInBytes);
1362    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1363    int32_t end = masm.GetCursorOffset() + space;
1364    while (masm.GetCursorOffset() < end) {
1365      __ nop();
1366    }
1367  }
1368
1369  __ Ldrd(r2, r3, 0x1234567890abcdef);
1370  ASSERT_LITERAL_POOL_SIZE(12);
1371
1372  {
1373    int space = AlignDown(ldrd_padding, kA32InstructionSizeInBytes);
1374    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1375    for (int32_t end = masm.GetCursorOffset() + space;
1376         masm.GetCursorOffset() < end;) {
1377      __ nop();
1378    }
1379  }
1380  ASSERT_LITERAL_POOL_SIZE(12);
1381
1382  // This mov will put the two loads literal out of range and will force
1383  // the literal pool emission.
1384  __ Mov(r0, 0);
1385  ASSERT_LITERAL_POOL_SIZE(0);
1386  END();
1387
1388  RUN();
1389
1390  ASSERT_EQUAL_32(0x12121212, r1);
1391  ASSERT_EQUAL_32(0x90abcdef, r2);
1392  ASSERT_EQUAL_32(0x12345678, r3);
1393
1394  TEARDOWN();
1395}
1396
1397
1398TEST(ldr_literal_mix_types) {
1399  SETUP();
1400
1401  START();
1402  Literal<uint64_t> l0(0x1234567890abcdef);
1403  Literal<int32_t> l1(0x12345678);
1404  Literal<uint16_t> l2(1234);
1405  Literal<int16_t> l3(-678);
1406  Literal<uint8_t> l4(42);
1407  Literal<int8_t> l5(-12);
1408
1409  __ Ldrd(r0, r1, &l0);
1410  __ Ldr(r2, &l1);
1411  __ Ldrh(r3, &l2);
1412  __ Ldrsh(r4, &l3);
1413  __ Ldrb(r5, &l4);
1414  __ Ldrsb(r6, &l5);
1415  ASSERT_LITERAL_POOL_SIZE(28);
1416
1417  END();
1418
1419  RUN();
1420
1421  ASSERT_EQUAL_32(0x90abcdef, r0);
1422  ASSERT_EQUAL_32(0x12345678, r1);
1423  ASSERT_EQUAL_32(0x12345678, r2);
1424  ASSERT_EQUAL_32(1234, r3);
1425  ASSERT_EQUAL_32(-678, r4);
1426  ASSERT_EQUAL_32(42, r5);
1427  ASSERT_EQUAL_32(-12, r6);
1428
1429  TEARDOWN();
1430}
1431
1432
1433struct LdrLiteralRangeTest {
1434  void (MacroAssembler::*instruction)(Register, RawLiteral*);
1435  Register result_reg;
1436  int a32_range;
1437  int t32_range;
1438  uint32_t literal_value;
1439  uint32_t test_value;
1440};
1441
1442
1443const LdrLiteralRangeTest kLdrLiteralRangeTestData[] = {
1444  {&MacroAssembler::Ldr, r1, 4095, 4095, 0x12345678, 0x12345678 },
1445  {&MacroAssembler::Ldrh, r2, 255, 4095, 0xabcdefff, 0x0000efff },
1446  {&MacroAssembler::Ldrsh, r3, 255, 4095, 0x00008765, 0xffff8765 },
1447  {&MacroAssembler::Ldrb, r4, 4095, 4095, 0x12345678, 0x00000078 },
1448  {&MacroAssembler::Ldrsb, r5, 255, 4095, 0x00000087, 0xffffff87 }
1449};
1450
1451
1452void GenerateLdrLiteralTriggerPoolEmission(InstructionSet isa,
1453                                           bool unaligned_ldr) {
1454  SETUP();
1455
1456  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
1457    const LdrLiteralRangeTest& test = kLdrLiteralRangeTestData[i];
1458
1459    START();
1460
1461    if (unaligned_ldr) {
1462      // Generate a nop to break the 4-byte alignment.
1463      __ Nop();
1464      VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
1465    }
1466
1467    __ Ldr(r6, 0x12345678);
1468    ASSERT_LITERAL_POOL_SIZE(4);
1469
1470    // TODO: The MacroAssembler currently checks for more space than required
1471    // when emitting macro instructions, triggering emission of the pool before
1472    // absolutely required. For now we keep a buffer. Fix this test when the
1473    // MacroAssembler becomes precise again.
1474    int masm_check_margin = 10 * kMaxInstructionSizeInBytes;
1475    size_t expected_pool_size = 4;
1476    while ((masm.GetMarginBeforeLiteralEmission() - masm_check_margin) >=
1477           static_cast<int32_t>(kMaxInstructionSizeInBytes)) {
1478      __ Ldr(r7, 0x90abcdef);
1479      // Each ldr instruction will force a new literal value to be added
1480      // to the pool. Check that the literal pool grows accordingly.
1481      expected_pool_size += 4;
1482      ASSERT_LITERAL_POOL_SIZE(expected_pool_size);
1483    }
1484
1485    int space = masm.GetMarginBeforeLiteralEmission();
1486    int end = masm.GetCursorOffset() + space;
1487    {
1488      // Generate nops precisely to fill the buffer.
1489      ExactAssemblyScope accurate_scope(&masm, space); // This should not trigger emission of the pool.
1490      VIXL_CHECK(!masm.LiteralPoolIsEmpty());
1491      while (masm.GetCursorOffset() < end) {
1492        __ nop();
1493      }
1494    }
1495
1496    // This ldr will force the literal pool to be emitted before emitting
1497    // the load and will create a new pool for the new literal used by this ldr.
1498    VIXL_CHECK(!masm.LiteralPoolIsEmpty());
1499    Literal<uint32_t> literal(test.literal_value);
1500    (masm.*test.instruction)(test.result_reg, &literal);
1501    ASSERT_LITERAL_POOL_SIZE(4);
1502
1503    END();
1504
1505    RUN();
1506
1507    ASSERT_EQUAL_32(0x12345678, r6);
1508    ASSERT_EQUAL_32(0x90abcdef, r7);
1509    ASSERT_EQUAL_32(test.test_value, test.result_reg);
1510  }
1511
1512  TEARDOWN();
1513}
1514
1515
1516TEST(ldr_literal_trigger_pool_emission) {
1517  GenerateLdrLiteralTriggerPoolEmission(isa, false);
1518}
1519
1520
1521TEST_T32(ldr_literal_trigger_pool_emission_unaligned) {
1522  GenerateLdrLiteralTriggerPoolEmission(isa, true);
1523}
1524
1525
1526void GenerateLdrLiteralRangeTest(InstructionSet isa, bool unaligned_ldr) {
1527  SETUP();
1528
1529  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
1530    const LdrLiteralRangeTest& test = kLdrLiteralRangeTestData[i];
1531
1532    START();
1533
1534    // Make sure the pool is empty.
1535    masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1536    ASSERT_LITERAL_POOL_SIZE(0);
1537
1538    if (unaligned_ldr) {
1539      // Generate a nop to break the 4-byte alignment.
1540      __ Nop();
1541      VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
1542    }
1543
1544    Literal<uint32_t> literal(test.literal_value);
1545    (masm.*test.instruction)(test.result_reg, &literal);
1546    ASSERT_LITERAL_POOL_SIZE(4);
1547
1548    // Generate enough instruction so that we go out of range for the load
1549    // literal we just emitted.
1550    ptrdiff_t end =
1551        masm.GetBuffer()->GetCursorOffset() +
1552        ((masm.IsUsingA32()) ? test.a32_range : test.t32_range);
1553    while (masm.GetBuffer()->GetCursorOffset() < end) {
1554      __ Mov(r0, 0);
1555    }
1556
1557    // The literal pool should have been emitted now.
1558    VIXL_CHECK(literal.IsBound());
1559    ASSERT_LITERAL_POOL_SIZE(0);
1560
1561    END();
1562
1563    RUN();
1564
1565    ASSERT_EQUAL_32(test.test_value, test.result_reg);
1566  }
1567
1568  TEARDOWN();
1569}
1570
1571
1572TEST(ldr_literal_range) {
1573  GenerateLdrLiteralRangeTest(isa, false);
1574}
1575
1576
1577TEST_T32(ldr_literal_range_unaligned) {
1578  GenerateLdrLiteralRangeTest(isa, true);
1579}
1580
1581
1582TEST(string_literal) {
1583  SETUP();
1584
1585  START();
1586  // Make sure the pool is empty.
1587  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1588  ASSERT_LITERAL_POOL_SIZE(0);
1589
1590  StringLiteral hello_string("hello");
1591
1592  __ Ldrb(r1, &hello_string);
1593
1594  __ Adr(r0, &hello_string);
1595  __ Ldrb(r2, MemOperand(r0));
1596  END();
1597
1598  RUN();
1599
1600  ASSERT_EQUAL_32('h', r1);
1601  ASSERT_EQUAL_32('h', r2);
1602
1603  TEARDOWN();
1604}
1605
1606
1607TEST(custom_literal_in_pool) {
1608  SETUP();
1609
1610  START();
1611  // Make sure the pool is empty.
1612  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1613  ASSERT_LITERAL_POOL_SIZE(0);
1614
1615  Literal<uint32_t> l0(static_cast<uint32_t>(0x12345678));
1616  __ Ldr(r0, &l0);
1617  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1618  __ Ldr(r1, &l0);
1619  ASSERT_LITERAL_POOL_SIZE(0);
1620
1621  Literal<uint64_t> cafebeefdeadbaba(0xcafebeefdeadbaba);
1622  __ Ldrd(r8, r9, &cafebeefdeadbaba);
1623  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1624  __ Ldrd(r2, r3, &cafebeefdeadbaba);
1625  ASSERT_LITERAL_POOL_SIZE(0);
1626
1627  Literal<uint32_t> l1(0x09abcdef);
1628  __ Adr(r4, &l1);
1629  __ Ldr(r4, MemOperand(r4));
1630  masm.EmitLiteralPool();
1631  __ Adr(r5, &l1);
1632  __ Ldr(r5, MemOperand(r5));
1633  ASSERT_LITERAL_POOL_SIZE(0);
1634
1635  END();
1636
1637  RUN();
1638
1639  // Check that the literals loaded correctly.
1640  ASSERT_EQUAL_32(0x12345678, r0);
1641  ASSERT_EQUAL_32(0x12345678, r1);
1642  ASSERT_EQUAL_32(0xdeadbaba, r2);
1643  ASSERT_EQUAL_32(0xcafebeef, r3);
1644  ASSERT_EQUAL_32(0xdeadbaba, r8);
1645  ASSERT_EQUAL_32(0xcafebeef, r9);
1646  ASSERT_EQUAL_32(0x09abcdef, r4);
1647  ASSERT_EQUAL_32(0x09abcdef, r5);
1648}
1649
1650
1651TEST(custom_literal_place) {
1652  SETUP();
1653
1654  START();
1655  // Make sure the pool is empty.
1656  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1657  ASSERT_LITERAL_POOL_SIZE(0);
1658
1659  Literal<uint64_t> l0(0xcafebeefdeadbaba, RawLiteral::kManuallyPlaced);
1660  Literal<int32_t> l1(0x12345678, RawLiteral::kManuallyPlaced);
1661  Literal<uint16_t>l2(4567, RawLiteral::kManuallyPlaced);
1662  Literal<int16_t> l3(-4567, RawLiteral::kManuallyPlaced);
1663  Literal<uint8_t> l4(123, RawLiteral::kManuallyPlaced);
1664  Literal<int8_t> l5(-123, RawLiteral::kManuallyPlaced);
1665
1666  __ Ldrd(r0, r1, &l0);
1667  __ Ldr(r2, &l1);
1668  __ Ldrh(r3, &l2);
1669  __ Ldrsh(r4, &l3);
1670  __ Ldrb(r5, &l4);
1671  __ Ldrsb(r6, &l5);
1672
1673  ASSERT_LITERAL_POOL_SIZE(0);
1674
1675  // Manually generate a literal pool.
1676  Label after_pool;
1677  __ B(&after_pool);
1678  __ Place(&l0);
1679  __ Place(&l1);
1680  __ Place(&l2);
1681  __ Place(&l3);
1682  __ Place(&l4);
1683  __ Place(&l5);
1684  __ Bind(&after_pool);
1685
1686  UseScratchRegisterScope temps(&masm);
1687  Register temp = temps.Acquire();
1688  VIXL_CHECK(temp.Is(r12));
1689
1690  __ Ldrd(r8, r9, &l0);
1691  __ Ldr(r7, &l1);
1692  __ Ldrh(r10, &l2);
1693  __ Ldrsh(r11, &l3);
1694  __ Ldrb(temp, &l4);
1695  // We don't use any function call so we can use lr as an extra register.
1696  __ Ldrsb(lr, &l5);
1697
1698  ASSERT_LITERAL_POOL_SIZE(0);
1699
1700  END();
1701
1702  RUN();
1703
1704  // Check that the literals loaded correctly.
1705  ASSERT_EQUAL_32(0xdeadbaba, r0);
1706  ASSERT_EQUAL_32(0xcafebeef, r1);
1707  ASSERT_EQUAL_32(0x12345678, r2);
1708  ASSERT_EQUAL_32(4567, r3);
1709  ASSERT_EQUAL_32(-4567, r4);
1710  ASSERT_EQUAL_32(123, r5);
1711  ASSERT_EQUAL_32(-123, r6);
1712
1713  ASSERT_EQUAL_32(0xdeadbaba, r8);
1714  ASSERT_EQUAL_32(0xcafebeef, r9);
1715  ASSERT_EQUAL_32(0x12345678, r7);
1716  ASSERT_EQUAL_32(4567, r10);
1717  ASSERT_EQUAL_32(-4567, r11);
1718  ASSERT_EQUAL_32(123, temp);
1719  ASSERT_EQUAL_32(-123, lr);
1720
1721  TEARDOWN();
1722}
1723
1724
1725TEST(custom_literal_place_shared) {
1726  SETUP();
1727
1728  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
1729    const LdrLiteralRangeTest& test = kLdrLiteralRangeTestData[i];
1730
1731    START();
1732
1733    // Make sure the pool is empty.
1734    masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
1735    ASSERT_LITERAL_POOL_SIZE(0);
1736
1737    Literal<uint32_t> before(test.literal_value, RawLiteral::kManuallyPlaced);
1738    Literal<uint32_t> after(test.literal_value, RawLiteral::kManuallyPlaced);
1739
1740    VIXL_CHECK(!before.IsBound());
1741    VIXL_CHECK(!after.IsBound());
1742
1743    // Manually generate a pool.
1744    Label end_of_pool_before;
1745    __ B(&end_of_pool_before);
1746    __ Place(&before);
1747    __ Bind(&end_of_pool_before);
1748
1749    ASSERT_LITERAL_POOL_SIZE(0);
1750    VIXL_CHECK(before.IsBound());
1751    VIXL_CHECK(!after.IsBound());
1752
1753  // Load the entries several times to test that literals can be shared.
1754    for (int i = 0; i < 20; i++) {
1755      (masm.*test.instruction)(r0, &before);
1756      (masm.*test.instruction)(r1, &after);
1757    }
1758
1759    ASSERT_LITERAL_POOL_SIZE(0);
1760    VIXL_CHECK(before.IsBound());
1761    VIXL_CHECK(!after.IsBound());
1762
1763    // Manually generate a pool.
1764    Label end_of_pool_after;
1765    __ B(&end_of_pool_after);
1766    __ Place(&after);
1767    __ Bind(&end_of_pool_after);
1768
1769    ASSERT_LITERAL_POOL_SIZE(0);
1770    VIXL_CHECK(before.IsBound());
1771    VIXL_CHECK(after.IsBound());
1772
1773    END();
1774
1775    RUN();
1776
1777    ASSERT_EQUAL_32(test.test_value, r0);
1778    ASSERT_EQUAL_32(test.test_value, r1);
1779  }
1780
1781  TEARDOWN();
1782}
1783
1784
1785TEST(custom_literal_place_range) {
1786  SETUP();
1787
1788  for (size_t i = 0; i < ARRAY_SIZE(kLdrLiteralRangeTestData); ++i) {
1789    const LdrLiteralRangeTest& test = kLdrLiteralRangeTestData[i];
1790    const int nop_size = masm.IsUsingA32() ? kA32InstructionSizeInBytes
1791                                           : k16BitT32InstructionSizeInBytes;
1792    const int range = masm.IsUsingA32() ? test.a32_range : test.t32_range;
1793    // On T32 the PC will be 4-byte aligned to compute the range. The
1794    // MacroAssembler might also need to align the code buffer before emitting
1795    // the literal when placing it. We keep a margin to account for this.
1796    const int margin = masm.IsUsingT32() ? 4 : 0;
1797
1798    // Take PC offset into account and make sure the literal is in the range.
1799    const int padding_before =
1800        range - masm.GetArchitectureStatePCOffset() - sizeof(uint32_t) - margin;
1801
1802    // The margin computation below is correct because the ranges are not
1803    // 4-byte aligned. Otherwise this test would insert the exact number of
1804    // instructions to cover the range and the literal would end up being
1805    // placed outside the range.
1806    VIXL_ASSERT((range % 4) != 0);
1807
1808    // The range is extended by the PC offset but we need to consider the ldr
1809    // instruction itself and the branch over the pool.
1810    const int padding_after = range + masm.GetArchitectureStatePCOffset() -
1811                              (2 * kMaxInstructionSizeInBytes) - margin;
1812    START();
1813
1814    Literal<uint32_t> before(test.literal_value, RawLiteral::kManuallyPlaced);
1815    Literal<uint32_t> after(test.literal_value, RawLiteral::kManuallyPlaced);
1816
1817    Label test_start;
1818    __ B(&test_start);
1819    __ Place(&before);
1820
1821    {
1822      int space = AlignDown(padding_before, nop_size);
1823      ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1824      for (int32_t end = masm.GetCursorOffset() + space;
1825           masm.GetCursorOffset() < end;) {
1826        __ nop();
1827      }
1828    }
1829
1830    __ Bind(&test_start);
1831    (masm.*test.instruction)(r0, &before);
1832    (masm.*test.instruction)(r1, &after);
1833
1834    {
1835      int space = AlignDown(padding_after, nop_size);
1836      ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
1837      for (int32_t end = masm.GetCursorOffset() + space;
1838           masm.GetCursorOffset() < end;) {
1839        __ nop();
1840      }
1841    }
1842
1843    Label after_pool;
1844    __ B(&after_pool);
1845    __ Place(&after);
1846    __ Bind(&after_pool);
1847
1848    END();
1849
1850    RUN();
1851
1852    ASSERT_EQUAL_32(test.test_value, r0);
1853    ASSERT_EQUAL_32(test.test_value, r1);
1854  }
1855
1856  TEARDOWN();
1857}
1858
1859
1860TEST(emit_big_pool) {
1861  SETUP();
1862
1863  START();
1864  // Make sure the pool is empty.
1865  ASSERT_LITERAL_POOL_SIZE(0);
1866
1867  Label start;
1868  __ Bind(&start);
1869  for (int i = 1000; i > 0; --i) {
1870    __ Ldr(r0, i);
1871  }
1872
1873  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&start) == 4000);
1874
1875  ASSERT_LITERAL_POOL_SIZE(4000);
1876  END();
1877
1878  RUN();
1879
1880  // Check that the literals loaded correctly.
1881  ASSERT_EQUAL_32(1, r0);
1882
1883  TEARDOWN();
1884}
1885
1886
1887TEST_T32(too_far_cbz) {
1888  SETUP();
1889
1890  START();
1891  Label start;
1892  Label end;
1893  Label exit;
1894  __ Mov(r0, 0);
1895  __ B(&start);
1896  __ Bind(&end);
1897  __ Mov(r0, 1);
1898  __ B(&exit);
1899  __ Bind(&start);
1900  // Cbz is only defined for forward jump. Check that it will work (substituted
1901  // by Cbnz/B).
1902  __ Cbz(r0, &end);
1903  __ Bind(&exit);
1904  END();
1905
1906  RUN();
1907
1908  ASSERT_EQUAL_32(1, r0);
1909}
1910
1911
1912TEST_T32(close_cbz) {
1913  SETUP();
1914
1915  START();
1916  Label first;
1917  Label second;
1918  __ Mov(r0, 0);
1919  __ Mov(r1, 0);
1920  __ Mov(r2, 0);
1921  __ Cbz(r0, &first);
1922  __ Bind(&first);
1923  __ Mov(r1, 1);
1924  __ Cbnz(r0, &second);
1925  __ Bind(&second);
1926  __ Mov(r2, 2);
1927  END();
1928
1929  RUN();
1930
1931  ASSERT_EQUAL_32(0, r0);
1932  ASSERT_EQUAL_32(1, r1);
1933  ASSERT_EQUAL_32(2, r2);
1934}
1935
1936
1937TEST_T32(close_cbz2) {
1938  SETUP();
1939
1940  START();
1941  Label first;
1942  Label second;
1943  __ Mov(r0, 0);
1944  __ Mov(r1, 0);
1945  __ Mov(r2, 0);
1946  __ Cmp(r0, 0);
1947  __ B(ne, &first);
1948  __ B(gt, &second);
1949  __ Cbz(r0, &first);
1950  __ Bind(&first);
1951  __ Mov(r1, 1);
1952  __ Cbnz(r0, &second);
1953  __ Bind(&second);
1954  __ Mov(r2, 2);
1955  END();
1956
1957  RUN();
1958
1959  ASSERT_EQUAL_32(0, r0);
1960  ASSERT_EQUAL_32(1, r1);
1961  ASSERT_EQUAL_32(2, r2);
1962}
1963
1964
1965TEST_T32(not_close_cbz) {
1966  SETUP();
1967
1968  START();
1969  Label first;
1970  Label second;
1971  __ Cbz(r0, &first);
1972  __ B(ne, &first);
1973  __ Bind(&first);
1974  __ Cbnz(r0, &second);
1975  __ B(gt, &second);
1976  __ Bind(&second);
1977  END();
1978
1979  RUN();
1980}
1981
1982
1983TEST_T32(veneers) {
1984  SETUP();
1985
1986  START();
1987  Label zero;
1988  Label exit;
1989  __ Mov(r0, 0);
1990  // Create one literal pool entry.
1991  __ Ldr(r1, 0x12345678);
1992  ASSERT_LITERAL_POOL_SIZE(4);
1993  __ Cbz(r0, &zero);
1994  __ Mov(r0, 1);
1995  __ B(&exit);
1996  for (int i = 32; i > 0; i--) {
1997    __ Mov(r1, 0);
1998  }
1999  // Assert that the literal pool has been generated with the veneers.
2000  ASSERT_LITERAL_POOL_SIZE(0);
2001  __ Bind(&zero);
2002  __ Mov(r0, 2);
2003  __ Bind(&exit);
2004  END();
2005
2006  RUN();
2007
2008  ASSERT_EQUAL_32(2, r0);
2009  ASSERT_EQUAL_32(0x12345678, r1);
2010}
2011
2012
2013// This test checks that veneers are sorted. If not, the test failed as the
2014// veneer for "exit" is emitted before the veneer for "zero" and the "zero"
2015// veneer is out of range for Cbz.
2016TEST_T32(veneers_labels_sort) {
2017  SETUP();
2018
2019  START();
2020  Label start;
2021  Label zero;
2022  Label exit;
2023  __ Movs(r0, 0);
2024  __ B(ne, &exit);
2025  __ B(&start);
2026  for (int i = 1048400; i > 0; i -= 4) {
2027    __ Mov(r1, 0);
2028  }
2029  __ Bind(&start);
2030  __ Cbz(r0, &zero);
2031  __ Mov(r0, 1);
2032  __ B(&exit);
2033  for (int i = 32; i > 0; i--) {
2034    __ Mov(r1, 0);
2035  }
2036  __ Bind(&zero);
2037  __ Mov(r0, 2);
2038  __ Bind(&exit);
2039  END();
2040
2041  RUN();
2042
2043  ASSERT_EQUAL_32(2, r0);
2044}
2045
2046// Check that a label bound within the assembler is effectively removed from
2047// the veneer pool.
2048TEST_T32(veneer_bind) {
2049  SETUP();
2050  Label target;
2051  __ Cbz(r0, &target);
2052  __ Nop();
2053
2054  {
2055    // Bind the target label using the `Assembler`.
2056    ExactAssemblyScope scope(&masm,
2057                             kMaxInstructionSizeInBytes,
2058                             ExactAssemblyScope::kMaximumSize);
2059    __ bind(&target);
2060    __ nop();
2061  }
2062
2063  VIXL_CHECK(target.IsBound());
2064  VIXL_CHECK(masm.VeneerPoolIsEmpty());
2065
2066  END();
2067}
2068
2069
2070TEST_T32(unaligned_branch_after_literal) {
2071  SETUP();
2072
2073  START();
2074
2075  // This test manually places a 32-bit literal after a 16-bit branch
2076  // which branches over the literal to an unaligned PC.
2077  Literal<int32_t> l0(0x01234567, RawLiteral::kManuallyPlaced);
2078
2079  __ Ldr(r0, &l0);
2080  ASSERT_LITERAL_POOL_SIZE(0);
2081
2082  masm.EmitLiteralPool(MacroAssembler::kBranchRequired);
2083  ASSERT_LITERAL_POOL_SIZE(0);
2084
2085  // Manually generate a literal pool.
2086  {
2087    Label after_pool;
2088    ExactAssemblyScope scope(&masm,
2089                             k16BitT32InstructionSizeInBytes + sizeof(int32_t),
2090                             CodeBufferCheckScope::kMaximumSize);
2091    __ b(Narrow, &after_pool);
2092    __ place(&l0);
2093    VIXL_ASSERT((masm.GetBuffer()->GetCursorOffset() % 4) == 2);
2094    __ bind(&after_pool);
2095  }
2096
2097  ASSERT_LITERAL_POOL_SIZE(0);
2098
2099  END();
2100
2101  RUN();
2102
2103  // Check that the literal was loaded correctly.
2104  ASSERT_EQUAL_32(0x01234567, r0);
2105
2106  TEARDOWN();
2107}
2108
2109
2110
2111// This test check that we can update a Literal after usage.
2112TEST(literal_update) {
2113  SETUP();
2114
2115  START();
2116  Label exit;
2117  Literal<uint32_t>* a32 =
2118      new Literal<uint32_t>(0xabcdef01, RawLiteral::kDeletedOnPoolDestruction);
2119  Literal<uint64_t>* a64 =
2120      new Literal<uint64_t>(
2121          UINT64_C(0xabcdef01abcdef01), RawLiteral::kDeletedOnPoolDestruction);
2122  __ Ldr(r0, a32);
2123  __ Ldrd(r2, r3, a64);
2124  __ EmitLiteralPool();
2125  Literal<uint32_t>* b32 =
2126      new Literal<uint32_t>(0x10fedcba, RawLiteral::kDeletedOnPoolDestruction);
2127  Literal<uint64_t>* b64 =
2128      new Literal<uint64_t>(
2129          UINT64_C(0x10fedcba10fedcba), RawLiteral::kDeletedOnPoolDestruction);
2130  __ Ldr(r1, b32);
2131  __ Ldrd(r4, r5, b64);
2132  // Update literals' values. "a32" and "a64" are already emitted. "b32" and
2133  // "b64" will only be emitted when "END()" will be called.
2134  a32->UpdateValue(0x12345678, masm.GetBuffer());
2135  a64->UpdateValue(UINT64_C(0x13579bdf02468ace), masm.GetBuffer());
2136  b32->UpdateValue(0x87654321, masm.GetBuffer());
2137  b64->UpdateValue(UINT64_C(0x1032547698badcfe), masm.GetBuffer());
2138  END();
2139
2140  RUN();
2141
2142  ASSERT_EQUAL_32(0x12345678, r0);
2143  ASSERT_EQUAL_32(0x87654321, r1);
2144  ASSERT_EQUAL_32(0x02468ace, r2);
2145  ASSERT_EQUAL_32(0x13579bdf, r3);
2146  ASSERT_EQUAL_32(0x98badcfe, r4);
2147  ASSERT_EQUAL_32(0x10325476, r5);
2148}
2149
2150
2151void SwitchCase(JumpTableBase* switch_, uint32_t case_index,
2152                InstructionSet isa, bool bind_default = true) {
2153  SETUP();
2154
2155  START();
2156
2157  __ Mov(r0, case_index);
2158  __ Mov(r1, case_index);
2159  __ Switch(r1, switch_);
2160
2161  __ Case(switch_, 0);
2162  __ Mov(r0, 1);
2163  __ Break(switch_);
2164
2165  __ Case(switch_, 1);
2166  __ Mov(r0, 2);
2167  __ Break(switch_);
2168
2169  __ Case(switch_, 2);
2170  __ Mov(r0, 4);
2171  __ Break(switch_);
2172
2173  __ Case(switch_, 3);
2174  __ Mov(r0, 8);
2175  __ Break(switch_);
2176
2177  if (bind_default) {
2178    __ Default(switch_);
2179    __ Mov(r0, -1);
2180  }
2181
2182  __ EndSwitch(switch_);
2183
2184
2185  END();
2186
2187  RUN();
2188
2189  if (case_index < 4) {
2190    ASSERT_EQUAL_32(1 << case_index, r0);
2191  } else if (bind_default) {
2192    ASSERT_EQUAL_32(-1, r0);
2193  } else {
2194    ASSERT_EQUAL_32(case_index, r0);
2195  }
2196}
2197
2198
2199TEST(switch_case_8) {
2200  for (int i = 0; i < 5; i++) {
2201    JumpTable8bitOffset switch_(5);
2202    SwitchCase(&switch_, i, isa);
2203  }
2204}
2205
2206
2207TEST(switch_case_16) {
2208  for (int i = 0; i < 5; i++) {
2209    JumpTable16bitOffset switch_(5);
2210    SwitchCase(&switch_, i, isa);
2211  }
2212}
2213
2214
2215TEST(switch_case_32) {
2216  for (int i = 0; i < 5; i++) {
2217    JumpTable32bitOffset switch_(5);
2218    SwitchCase(&switch_, i, isa);
2219  }
2220}
2221
2222
2223TEST(switch_case_8_omit_default) {
2224  for (int i = 0; i < 5; i++) {
2225    JumpTable8bitOffset switch_(5);
2226    SwitchCase(&switch_, i, isa, false);
2227  }
2228}
2229
2230
2231TEST(switch_case_16_omit_default) {
2232  for (int i = 0; i < 5; i++) {
2233    JumpTable16bitOffset switch_(5);
2234    SwitchCase(&switch_, i, isa, false);
2235  }
2236}
2237
2238
2239TEST(switch_case_32_omit_default) {
2240  for (int i = 0; i < 5; i++) {
2241    JumpTable32bitOffset switch_(5);
2242    SwitchCase(&switch_, i, isa, false);
2243  }
2244}
2245
2246TEST(claim_peek_poke) {
2247  SETUP();
2248
2249  START();
2250
2251  Label start;
2252  __ Bind(&start);
2253  __ Claim(0);
2254  __ Drop(0);
2255  VIXL_CHECK((masm.GetCursorOffset() - start.GetLocation()) == 0);
2256
2257  __ Claim(32);
2258  __ Ldr(r0, 0xcafe0000);
2259  __ Ldr(r1, 0xcafe0001);
2260  __ Ldr(r2, 0xcafe0002);
2261  __ Poke(r0, 0);
2262  __ Poke(r1, 4);
2263  __ Poke(r2, 8);
2264  __ Peek(r2, 0);
2265  __ Peek(r0, 4);
2266  __ Peek(r1, 8);
2267  __ Drop(32);
2268
2269  END();
2270
2271  RUN();
2272
2273  ASSERT_EQUAL_32(0xcafe0001, r0);
2274  ASSERT_EQUAL_32(0xcafe0002, r1);
2275  ASSERT_EQUAL_32(0xcafe0000, r2);
2276
2277  TEARDOWN();
2278}
2279
2280
2281TEST(msr_i) {
2282  SETUP();
2283
2284  START();
2285  __ Mov(r0, 0xdead);
2286  __ Mov(r1, 0xdead);
2287  __ Mov(r2, 0xdead);
2288  __ Mov(r3, 0xb);
2289  __ Msr(APSR_nzcvqg, 0);
2290  __ Mrs(r0, APSR);
2291  __ Msr(APSR_nzcvqg, 0xffffffff);
2292  __ Mrs(r1, APSR);
2293  // Only modify nzcvq => keep previous g.
2294  __ Lsl(r4, r3, 28);
2295  __ Msr(APSR_nzcvq, r4);
2296  __ Mrs(r2, APSR);
2297  END();
2298
2299  RUN();
2300
2301  ASSERT_EQUAL_32(0x10, r0);
2302  ASSERT_EQUAL_32(0xf80f0010, r1);
2303  ASSERT_EQUAL_32(0xb00f0010, r2);
2304
2305  TEARDOWN();
2306}
2307
2308
2309TEST(vmrs_vmsr) {
2310  SETUP();
2311
2312  START();
2313  // Move some value to FPSCR and get them back to test vmsr/vmrs instructions.
2314  __ Mov(r0, 0x2a000000);
2315  __ Vmsr(FPSCR, r0);
2316  __ Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR);
2317
2318  __ Mov(r0, 0x5a000000);
2319  __ Vmsr(FPSCR, r0);
2320  __ Vmrs(RegisterOrAPSR_nzcv(r2.GetCode()), FPSCR);
2321
2322  // Move to APSR_nzcv.
2323  __ Vmrs(RegisterOrAPSR_nzcv(pc.GetCode()), FPSCR);
2324  __ Mrs(r3, APSR);
2325  __ And(r3, r3, 0xf0000000);
2326
2327  END();
2328
2329  RUN();
2330
2331  ASSERT_EQUAL_32(0x2a000000, r1);
2332  ASSERT_EQUAL_32(0x5a000000, r2);
2333  ASSERT_EQUAL_32(0x50000000, r3);
2334
2335  TEARDOWN();
2336}
2337
2338
2339TEST(printf) {
2340  SETUP();
2341
2342  START();
2343  __ Mov(r0, 0xb00e0000);
2344  __ Msr(APSR_nzcvqg, r0);
2345  __ Mov(r0, sp);
2346  __ Printf("sp=%x\n", r0);
2347//  __ Printf("Hello world!\n");
2348  __ Mov(r0, 0x1234);
2349  __ Mov(r1, 0x5678);
2350  StringLiteral literal("extra string");
2351  __ Adr(r2, &literal);
2352  __ Mov(r3, 5);
2353  __ Mov(r4, 0xdead4444);
2354  __ Mov(r5, 0xdead5555);
2355  __ Mov(r6, 0xdead6666);
2356  __ Mov(r7, 0xdead7777);
2357  __ Mov(r8, 0xdead8888);
2358  __ Mov(r9, 0xdead9999);
2359  __ Mov(r10, 0xdeadaaaa);
2360  __ Mov(r11, 0xdeadbbbb);
2361  __ Vldr(d0, 1.2345);
2362  __ Vldr(d1, 2.9876);
2363  __ Vldr(s4, 1.3333);
2364  __ Vldr(s5, 3.21);
2365  __ Vldr(d3, 3.333);
2366  __ Vldr(d4, 4.444);
2367  __ Vldr(d5, 5.555);
2368  __ Vldr(d6, 6.666);
2369  __ Vldr(d7, 7.777);
2370  __ Vldr(d8, 8.888);
2371  __ Vldr(d9, 9.999);
2372  __ Vldr(d10, 10.000);
2373  __ Vldr(d11, 11.111);
2374  __ Vldr(d12, 12.222);
2375  __ Vldr(d13, 13.333);
2376  __ Vldr(d14, 14.444);
2377  __ Vldr(d15, 15.555);
2378  __ Vldr(d16, 16.666);
2379  __ Vldr(d17, 17.777);
2380  __ Vldr(d18, 18.888);
2381  __ Vldr(d19, 19.999);
2382  __ Vldr(d20, 20.000);
2383  __ Vldr(d21, 21.111);
2384  __ Vldr(d22, 22.222);
2385  __ Vldr(d23, 23.333);
2386  __ Vldr(d24, 24.444);
2387  __ Vldr(d25, 25.555);
2388  __ Vldr(d26, 26.666);
2389  __ Vldr(d27, 27.777);
2390  __ Vldr(d28, 28.888);
2391  __ Vldr(d29, 29.999);
2392  __ Vldr(d30, 30.000);
2393  __ Vldr(d31, 31.111);
2394  {
2395    UseScratchRegisterScope temps(&masm);
2396    // For effective use as an inspection tool, Printf must work without any
2397    // scratch registers.
2398    VIXL_CHECK(r12.Is(temps.Acquire()));
2399    __ Mov(r12, 0xdeadcccc);
2400    VIXL_CHECK(masm.GetScratchRegisterList()->IsEmpty());
2401
2402    __ Printf("%% r0=%x r1=%x str=<%.*s>\n", r0, r1, r3, r2);
2403    __ Printf("r0=%d r1=%d str=<%s>\n", r0, r1, r2);
2404    __ Printf("d0=%g\n", d0);
2405    __ Printf("s4=%g\n", s4);
2406    __ Printf("d0=%g d1=%g s4=%g s5=%g\n", d0, d1, s4, s5);
2407    __ Printf("d0=%g r0=%x s4=%g r1=%x\n", d0, r0, s4, r1);
2408    __ Printf("r0=%x d0=%g r1=%x s4=%g\n", r0, d0, r1, s4);
2409    __ Mov(r0, sp);
2410    __ Printf("sp=%x\n", r0);
2411    __ Mrs(r0, APSR);
2412    // Only keep R/W fields.
2413    __ Mov(r2, 0xf80f0200);
2414    __ And(r0, r0, r2);
2415  }
2416  END();
2417
2418  RUN();
2419
2420  ASSERT_EQUAL_32(0xb00e0000, r0);
2421  ASSERT_EQUAL_32(0x5678, r1);
2422  ASSERT_EQUAL_32(5, r3);
2423  ASSERT_EQUAL_32(0xdead4444, r4);
2424  ASSERT_EQUAL_32(0xdead5555, r5);
2425  ASSERT_EQUAL_32(0xdead6666, r6);
2426  ASSERT_EQUAL_32(0xdead7777, r7);
2427  ASSERT_EQUAL_32(0xdead8888, r8);
2428  ASSERT_EQUAL_32(0xdead9999, r9);
2429  ASSERT_EQUAL_32(0xdeadaaaa, r10);
2430  ASSERT_EQUAL_32(0xdeadbbbb, r11);
2431  ASSERT_EQUAL_32(0xdeadcccc, r12);
2432  ASSERT_EQUAL_FP64(1.2345, d0);
2433  ASSERT_EQUAL_FP64(2.9876, d1);
2434  ASSERT_EQUAL_FP32(1.3333, s4);
2435  ASSERT_EQUAL_FP32(3.21, s5);
2436  ASSERT_EQUAL_FP64(4.444, d4);
2437  ASSERT_EQUAL_FP64(5.555, d5);
2438  ASSERT_EQUAL_FP64(6.666, d6);
2439  ASSERT_EQUAL_FP64(7.777, d7);
2440  ASSERT_EQUAL_FP64(8.888, d8);
2441  ASSERT_EQUAL_FP64(9.999, d9);
2442  ASSERT_EQUAL_FP64(10.000, d10);
2443  ASSERT_EQUAL_FP64(11.111, d11);
2444  ASSERT_EQUAL_FP64(12.222, d12);
2445  ASSERT_EQUAL_FP64(13.333, d13);
2446  ASSERT_EQUAL_FP64(14.444, d14);
2447  ASSERT_EQUAL_FP64(15.555, d15);
2448  ASSERT_EQUAL_FP64(16.666, d16);
2449  ASSERT_EQUAL_FP64(17.777, d17);
2450  ASSERT_EQUAL_FP64(18.888, d18);
2451  ASSERT_EQUAL_FP64(19.999, d19);
2452  ASSERT_EQUAL_FP64(20.000, d20);
2453  ASSERT_EQUAL_FP64(21.111, d21);
2454  ASSERT_EQUAL_FP64(22.222, d22);
2455  ASSERT_EQUAL_FP64(23.333, d23);
2456  ASSERT_EQUAL_FP64(24.444, d24);
2457  ASSERT_EQUAL_FP64(25.555, d25);
2458  ASSERT_EQUAL_FP64(26.666, d26);
2459  ASSERT_EQUAL_FP64(27.777, d27);
2460  ASSERT_EQUAL_FP64(28.888, d28);
2461  ASSERT_EQUAL_FP64(29.999, d29);
2462  ASSERT_EQUAL_FP64(30.000, d30);
2463  ASSERT_EQUAL_FP64(31.111, d31);
2464
2465  TEARDOWN();
2466}
2467
2468TEST(printf2) {
2469  SETUP();
2470
2471  START();
2472  __ Mov(r0, 0x1234);
2473  __ Mov(r1, 0x5678);
2474  __ Vldr(d0, 1.2345);
2475  __ Vldr(s2, 2.9876);
2476  __ Printf("d0=%g d1=%g r0=%x r1=%x\n", d0, s2, r0, r1);
2477  END();
2478
2479  RUN();
2480
2481  TEARDOWN();
2482}
2483
2484
2485TEST(use_scratch_register_scope_v_registers) {
2486  SETUP();
2487  {
2488    UseScratchRegisterScope temps(&masm);
2489    temps.Include(VRegisterList(q0, q1, q2, q3));
2490
2491    // This test assumes that low-numbered registers are allocated first. The
2492    // implementation is allowed to use a different strategy; if it does, the
2493    // test will need to be updated.
2494    // TODO: Write more flexible (and thorough) tests.
2495
2496    VIXL_CHECK(q0.Is(temps.AcquireQ()));
2497    VIXL_CHECK(!temps.IsAvailable(q0));
2498    VIXL_CHECK(!temps.IsAvailable(d0));
2499    VIXL_CHECK(!temps.IsAvailable(d1));
2500    VIXL_CHECK(!temps.IsAvailable(s0));
2501    VIXL_CHECK(!temps.IsAvailable(s1));
2502    VIXL_CHECK(!temps.IsAvailable(s2));
2503    VIXL_CHECK(!temps.IsAvailable(s3));
2504
2505    VIXL_CHECK(d2.Is(temps.AcquireV(64)));
2506    VIXL_CHECK(!temps.IsAvailable(q1));
2507    VIXL_CHECK(!temps.IsAvailable(d2));
2508    VIXL_CHECK(temps.IsAvailable(d3));
2509    VIXL_CHECK(!temps.IsAvailable(s4));
2510    VIXL_CHECK(!temps.IsAvailable(s5));
2511    VIXL_CHECK(temps.IsAvailable(s6));
2512    VIXL_CHECK(temps.IsAvailable(s7));
2513
2514    VIXL_CHECK(s6.Is(temps.AcquireS()));
2515    VIXL_CHECK(!temps.IsAvailable(d3));
2516    VIXL_CHECK(!temps.IsAvailable(s6));
2517    VIXL_CHECK(temps.IsAvailable(s7));
2518
2519    VIXL_CHECK(q2.Is(temps.AcquireV(128)));
2520    VIXL_CHECK(!temps.IsAvailable(q2));
2521    VIXL_CHECK(!temps.IsAvailable(d4));
2522    VIXL_CHECK(!temps.IsAvailable(d5));
2523    VIXL_CHECK(!temps.IsAvailable(s8));
2524    VIXL_CHECK(!temps.IsAvailable(s9));
2525    VIXL_CHECK(!temps.IsAvailable(s10));
2526    VIXL_CHECK(!temps.IsAvailable(s11));
2527    VIXL_CHECK(temps.IsAvailable(s7));
2528
2529    VIXL_CHECK(d6.Is(temps.AcquireD()));
2530    VIXL_CHECK(!temps.IsAvailable(q3));
2531    VIXL_CHECK(!temps.IsAvailable(d6));
2532    VIXL_CHECK(temps.IsAvailable(d7));
2533    VIXL_CHECK(!temps.IsAvailable(s12));
2534    VIXL_CHECK(!temps.IsAvailable(s13));
2535    VIXL_CHECK(temps.IsAvailable(s14));
2536    VIXL_CHECK(temps.IsAvailable(s15));
2537    VIXL_CHECK(temps.IsAvailable(s7));
2538
2539    VIXL_CHECK(s7.Is(temps.AcquireS()));
2540  }
2541  TEARDOWN();
2542}
2543
2544
2545TEST(scratch_register_scope_include_exclude) {
2546  SETUP();
2547  {
2548    UseScratchRegisterScope temps(&masm);
2549    temps.Include(r0, r1, r2, r3);
2550    temps.Include(s0, s1, d1, q1);
2551
2552    VIXL_CHECK(temps.IsAvailable(r0));
2553    VIXL_CHECK(temps.IsAvailable(r1));
2554    VIXL_CHECK(temps.IsAvailable(r2));
2555    VIXL_CHECK(temps.IsAvailable(r3));
2556
2557    VIXL_CHECK(temps.IsAvailable(s0));
2558
2559    VIXL_CHECK(temps.IsAvailable(s1));
2560
2561    VIXL_CHECK(temps.IsAvailable(d1));
2562    VIXL_CHECK(temps.IsAvailable(s2));
2563    VIXL_CHECK(temps.IsAvailable(s3));
2564
2565    VIXL_CHECK(temps.IsAvailable(q1));
2566    VIXL_CHECK(temps.IsAvailable(d2));
2567    VIXL_CHECK(temps.IsAvailable(d3));
2568    VIXL_CHECK(temps.IsAvailable(s4));
2569    VIXL_CHECK(temps.IsAvailable(s5));
2570    VIXL_CHECK(temps.IsAvailable(s6));
2571    VIXL_CHECK(temps.IsAvailable(s7));
2572
2573    // Test local exclusion.
2574    {
2575      UseScratchRegisterScope local_temps(&masm);
2576      local_temps.Exclude(r1, r2);
2577      local_temps.Exclude(s1, q1);
2578
2579      VIXL_CHECK(temps.IsAvailable(r0));
2580      VIXL_CHECK(!temps.IsAvailable(r1));
2581      VIXL_CHECK(!temps.IsAvailable(r2));
2582      VIXL_CHECK(temps.IsAvailable(r3));
2583
2584      VIXL_CHECK(temps.IsAvailable(s0));
2585
2586      VIXL_CHECK(!temps.IsAvailable(s1));
2587
2588      VIXL_CHECK(temps.IsAvailable(d1));
2589      VIXL_CHECK(temps.IsAvailable(s2));
2590      VIXL_CHECK(temps.IsAvailable(s3));
2591
2592      VIXL_CHECK(!temps.IsAvailable(q1));
2593      VIXL_CHECK(!temps.IsAvailable(d2));
2594      VIXL_CHECK(!temps.IsAvailable(d3));
2595      VIXL_CHECK(!temps.IsAvailable(s4));
2596      VIXL_CHECK(!temps.IsAvailable(s5));
2597      VIXL_CHECK(!temps.IsAvailable(s6));
2598      VIXL_CHECK(!temps.IsAvailable(s7));
2599    }
2600
2601    // This time, exclude part of included registers, making sure the entire
2602    // register gets excluded.
2603    {
2604      UseScratchRegisterScope local_temps(&masm);
2605      local_temps.Exclude(s2, d3);
2606
2607      VIXL_CHECK(temps.IsAvailable(r0));
2608      VIXL_CHECK(temps.IsAvailable(r1));
2609      VIXL_CHECK(temps.IsAvailable(r2));
2610      VIXL_CHECK(temps.IsAvailable(r3));
2611
2612      VIXL_CHECK(temps.IsAvailable(s0));
2613
2614      VIXL_CHECK(temps.IsAvailable(s1));
2615
2616      // Excluding s2 should exclude d1 but not s3.
2617      VIXL_CHECK(!temps.IsAvailable(d1));
2618      VIXL_CHECK(!temps.IsAvailable(s2));
2619      VIXL_CHECK(temps.IsAvailable(s3));
2620
2621      // Excluding d3 should exclude q1, s7 and s6 but not d2, s5, s4.
2622      VIXL_CHECK(!temps.IsAvailable(q1));
2623      VIXL_CHECK(temps.IsAvailable(d2));
2624      VIXL_CHECK(!temps.IsAvailable(d3));
2625      VIXL_CHECK(temps.IsAvailable(s4));
2626      VIXL_CHECK(temps.IsAvailable(s5));
2627      VIXL_CHECK(!temps.IsAvailable(s6));
2628      VIXL_CHECK(!temps.IsAvailable(s7));
2629    }
2630
2631    // Make sure the initial state was restored.
2632
2633    VIXL_CHECK(temps.IsAvailable(r0));
2634    VIXL_CHECK(temps.IsAvailable(r1));
2635    VIXL_CHECK(temps.IsAvailable(r2));
2636    VIXL_CHECK(temps.IsAvailable(r3));
2637
2638    VIXL_CHECK(temps.IsAvailable(s0));
2639
2640    VIXL_CHECK(temps.IsAvailable(s1));
2641
2642    VIXL_CHECK(temps.IsAvailable(d1));
2643    VIXL_CHECK(temps.IsAvailable(s2));
2644    VIXL_CHECK(temps.IsAvailable(s3));
2645
2646    VIXL_CHECK(temps.IsAvailable(q1));
2647    VIXL_CHECK(temps.IsAvailable(d2));
2648    VIXL_CHECK(temps.IsAvailable(d3));
2649    VIXL_CHECK(temps.IsAvailable(s4));
2650    VIXL_CHECK(temps.IsAvailable(s5));
2651    VIXL_CHECK(temps.IsAvailable(s6));
2652    VIXL_CHECK(temps.IsAvailable(s7));
2653  }
2654  TEARDOWN();
2655}
2656
2657
2658template<typename T>
2659void CheckInstructionSetA32(const T& assm) {
2660  VIXL_CHECK(assm.IsUsingA32());
2661  VIXL_CHECK(!assm.IsUsingT32());
2662  VIXL_CHECK(assm.GetInstructionSetInUse() == A32);
2663}
2664
2665
2666template<typename T>
2667void CheckInstructionSetT32(const T& assm) {
2668  VIXL_CHECK(assm.IsUsingT32());
2669  VIXL_CHECK(!assm.IsUsingA32());
2670  VIXL_CHECK(assm.GetInstructionSetInUse() == T32);
2671}
2672
2673
2674TEST_NOASM(set_isa_constructors) {
2675  byte buffer[1024];
2676
2677  // A32 by default.
2678  CheckInstructionSetA32(Assembler());
2679  CheckInstructionSetA32(Assembler(1024));
2680  CheckInstructionSetA32(Assembler(buffer, sizeof(buffer)));
2681  // Explicit A32.
2682  CheckInstructionSetA32(Assembler(A32));
2683  CheckInstructionSetA32(Assembler(1024, A32));
2684  CheckInstructionSetA32(Assembler(buffer, sizeof(buffer), A32));
2685  // Explicit T32.
2686  CheckInstructionSetT32(Assembler(T32));
2687  CheckInstructionSetT32(Assembler(1024, T32));
2688  CheckInstructionSetT32(Assembler(buffer, sizeof(buffer), T32));
2689
2690  // A32 by default.
2691  CheckInstructionSetA32(MacroAssembler());
2692  CheckInstructionSetA32(MacroAssembler(1024));
2693  CheckInstructionSetA32(MacroAssembler(buffer, sizeof(buffer)));
2694  // Explicit A32.
2695  CheckInstructionSetA32(MacroAssembler(A32));
2696  CheckInstructionSetA32(MacroAssembler(1024, A32));
2697  CheckInstructionSetA32(MacroAssembler(buffer, sizeof(buffer), A32));
2698  // Explicit T32.
2699  CheckInstructionSetT32(MacroAssembler(T32));
2700  CheckInstructionSetT32(MacroAssembler(1024, T32));
2701  CheckInstructionSetT32(MacroAssembler(buffer, sizeof(buffer), T32));
2702}
2703
2704
2705TEST_NOASM(set_isa_empty) {
2706  // It is possible to change the instruction set if no instructions have yet
2707  // been generated.
2708  Assembler assm;
2709  CheckInstructionSetA32(assm);
2710  assm.UseT32();
2711  CheckInstructionSetT32(assm);
2712  assm.UseA32();
2713  CheckInstructionSetA32(assm);
2714  assm.UseInstructionSet(T32);
2715  CheckInstructionSetT32(assm);
2716  assm.UseInstructionSet(A32);
2717  CheckInstructionSetA32(assm);
2718
2719  MacroAssembler masm;
2720  CheckInstructionSetA32(masm);
2721  masm.UseT32();
2722  CheckInstructionSetT32(masm);
2723  masm.UseA32();
2724  CheckInstructionSetA32(masm);
2725  masm.UseInstructionSet(T32);
2726  CheckInstructionSetT32(masm);
2727  masm.UseInstructionSet(A32);
2728  CheckInstructionSetA32(masm);
2729}
2730
2731
2732TEST_NOASM(set_isa_noop) {
2733  // It is possible to call a no-op UseA32/T32 or UseInstructionSet even if
2734  // one or more instructions have been generated.
2735  {
2736    Assembler assm(A32);
2737    CheckInstructionSetA32(assm);
2738    CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
2739    assm.bx(lr);
2740    VIXL_ASSERT(assm.GetCursorOffset() > 0);
2741    CheckInstructionSetA32(assm);
2742    assm.UseA32();
2743    CheckInstructionSetA32(assm);
2744    assm.UseInstructionSet(A32);
2745    CheckInstructionSetA32(assm);
2746    assm.FinalizeCode();
2747  }
2748  {
2749    Assembler assm(T32);
2750    CheckInstructionSetT32(assm);
2751    CodeBufferCheckScope scope(&assm, kMaxInstructionSizeInBytes);
2752    assm.bx(lr);
2753    VIXL_ASSERT(assm.GetCursorOffset() > 0);
2754    CheckInstructionSetT32(assm);
2755    assm.UseT32();
2756    CheckInstructionSetT32(assm);
2757    assm.UseInstructionSet(T32);
2758    CheckInstructionSetT32(assm);
2759    assm.FinalizeCode();
2760  }
2761  {
2762    MacroAssembler masm(A32);
2763    CheckInstructionSetA32(masm);
2764    masm.Bx(lr);
2765    VIXL_ASSERT(masm.GetCursorOffset() > 0);
2766    CheckInstructionSetA32(masm);
2767    masm.UseA32();
2768    CheckInstructionSetA32(masm);
2769    masm.UseInstructionSet(A32);
2770    CheckInstructionSetA32(masm);
2771    masm.FinalizeCode();
2772  }
2773  {
2774    MacroAssembler masm(T32);
2775    CheckInstructionSetT32(masm);
2776    masm.Bx(lr);
2777    VIXL_ASSERT(masm.GetCursorOffset() > 0);
2778    CheckInstructionSetT32(masm);
2779    masm.UseT32();
2780    CheckInstructionSetT32(masm);
2781    masm.UseInstructionSet(T32);
2782    CheckInstructionSetT32(masm);
2783    masm.FinalizeCode();
2784  }
2785}
2786
2787
2788TEST(logical_arithmetic_identities) {
2789  SETUP();
2790
2791  START();
2792
2793  Label blob_1;
2794  __ Bind(&blob_1);
2795  __ Add(r0, r0, 0);
2796  __ And(r0, r0, 0xffffffff);
2797  __ Bic(r0, r0, 0);
2798  __ Eor(r0, r0, 0);
2799  __ Orn(r0, r0, 0xffffffff);
2800  __ Orr(r0, r0, 0);
2801  __ Sub(r0, r0, 0);
2802  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_1) == 0);
2803
2804  Label blob_2;
2805  __ Bind(&blob_2);
2806  __ Adds(r0, r0, 0);
2807  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_2) != 0);
2808
2809  Label blob_3;
2810  __ Bind(&blob_3);
2811  __ Ands(r0, r0, 0);
2812  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_3) != 0);
2813
2814  Label blob_4;
2815  __ Bind(&blob_4);
2816  __ Bics(r0, r0, 0);
2817  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_4) != 0);
2818
2819  Label blob_5;
2820  __ Bind(&blob_5);
2821  __ Eors(r0, r0, 0);
2822  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_5) != 0);
2823
2824  Label blob_6;
2825  __ Bind(&blob_6);
2826  __ Orns(r0, r0, 0);
2827  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_6) != 0);
2828
2829  Label blob_7;
2830  __ Bind(&blob_7);
2831  __ Orrs(r0, r0, 0);
2832  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_7) != 0);
2833
2834  Label blob_8;
2835  __ Bind(&blob_8);
2836  __ Subs(r0, r0, 0);
2837  VIXL_ASSERT(masm.GetSizeOfCodeGeneratedSince(&blob_8) != 0);
2838
2839  __ Mov(r0, 0xbad);
2840  __ And(r1, r0, 0);
2841  __ Bic(r2, r0, 0xffffffff);
2842  __ Eor(r3, r0, 0xffffffff);
2843  __ Orn(r4, r0, 0);
2844  __ Orr(r5, r0, 0xffffffff);
2845
2846  END();
2847
2848  RUN();
2849
2850  ASSERT_EQUAL_32(0xbad, r0);
2851  ASSERT_EQUAL_32(0, r1);
2852  ASSERT_EQUAL_32(0, r2);
2853  ASSERT_EQUAL_32(~0xbad, r3);
2854  ASSERT_EQUAL_32(0xffffffff, r4);
2855  ASSERT_EQUAL_32(0xffffffff, r5);
2856
2857  TEARDOWN();
2858}
2859
2860
2861TEST(scratch_register_checks) {
2862  // It is unsafe for users to use registers that the MacroAssembler is also
2863  // using as scratch registers. This test checks the MacroAssembler's checking
2864  // mechanism itself.
2865  SETUP();
2866  START();
2867  {
2868    UseScratchRegisterScope temps(&masm);
2869    // 'ip' is a scratch register by default.
2870    VIXL_CHECK(
2871        masm.GetScratchRegisterList()->GetList() == (1u << ip.GetCode()));
2872    VIXL_CHECK(temps.IsAvailable(ip));
2873
2874    // Integer registers have no complicated aliasing so
2875    // masm.AliasesAvailableScratchRegister(reg) == temps.IsAvailable(reg).
2876    for (unsigned i = 0; i < kNumberOfRegisters; i++) {
2877      Register reg(i);
2878      VIXL_CHECK(masm.AliasesAvailableScratchRegister(reg) ==
2879                 temps.IsAvailable(reg));
2880    }
2881  }
2882  END();
2883  TEARDOWN();
2884}
2885
2886
2887TEST(scratch_register_checks_v) {
2888  // It is unsafe for users to use registers that the MacroAssembler is also
2889  // using as scratch registers. This test checks the MacroAssembler's checking
2890  // mechanism itself.
2891  SETUP();
2892  {
2893    UseScratchRegisterScope temps(&masm);
2894    // There is no default floating-point scratch register. Add temps of various
2895    // sizes to check handling of aliased registers.
2896    VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() == 0);
2897    temps.Include(q15);
2898    temps.Include(d15);
2899    temps.Include(s15);
2900    temps.Include(d4);
2901    temps.Include(d5);
2902    temps.Include(s24);
2903    temps.Include(s25);
2904    temps.Include(s26);
2905    temps.Include(s27);
2906    temps.Include(q0);
2907    // See VRegisterList for details of the list encoding.
2908    VIXL_CHECK(masm.GetScratchVRegisterList()->GetList() ==
2909               UINT64_C(0xf0000000cf008f0f));
2910    //                    |       ||  || |
2911    //                   q15    d15|  || q0
2912    //                        s24-s27 |d4-d5
2913    //                               s15
2914
2915    // Simple checks: Included registers are available.
2916    VIXL_CHECK(temps.IsAvailable(q15));
2917    VIXL_CHECK(temps.IsAvailable(d15));
2918    VIXL_CHECK(temps.IsAvailable(s15));
2919    VIXL_CHECK(temps.IsAvailable(d4));
2920    VIXL_CHECK(temps.IsAvailable(d5));
2921    VIXL_CHECK(temps.IsAvailable(s24));
2922    VIXL_CHECK(temps.IsAvailable(s25));
2923    VIXL_CHECK(temps.IsAvailable(s26));
2924    VIXL_CHECK(temps.IsAvailable(s27));
2925    VIXL_CHECK(temps.IsAvailable(q0));
2926
2927    // Each available S register should mark the corresponding D and Q registers
2928    // as aliasing an available scratch register.
2929    for (unsigned s = 0; s < kNumberOfSRegisters; s++) {
2930      if (temps.IsAvailable(SRegister(s))) {
2931        VIXL_CHECK(masm.AliasesAvailableScratchRegister(SRegister(s)));
2932        VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(s / 2)));
2933        VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(s / 4)));
2934      } else {
2935        // AliasesAvailableScratchRegiters == IsAvailable for S registers.
2936        VIXL_CHECK(!masm.AliasesAvailableScratchRegister(SRegister(s)));
2937      }
2938    }
2939
2940    // Similar checks for high D registers.
2941    unsigned first_high_d_register = kNumberOfSRegisters / 2;
2942    for (unsigned d = first_high_d_register; d < kMaxNumberOfDRegisters; d++) {
2943      if (temps.IsAvailable(DRegister(d))) {
2944        VIXL_CHECK(masm.AliasesAvailableScratchRegister(DRegister(d)));
2945        VIXL_CHECK(masm.AliasesAvailableScratchRegister(QRegister(d / 2)));
2946      } else {
2947        // AliasesAvailableScratchRegiters == IsAvailable for high D registers.
2948        VIXL_CHECK(!masm.AliasesAvailableScratchRegister(DRegister(d)));
2949      }
2950    }
2951  }
2952  TEARDOWN();
2953}
2954
2955
2956TEST(nop) {
2957  SETUP();
2958
2959  Label start;
2960  __ Bind(&start);
2961  __ Nop();
2962  size_t nop_size = (isa == T32) ? k16BitT32InstructionSizeInBytes
2963                                 : kA32InstructionSizeInBytes;
2964  // `MacroAssembler::Nop` must generate at least one nop.
2965  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&start) >= nop_size);
2966
2967  masm.FinalizeCode();
2968
2969  TEARDOWN();
2970}
2971
2972
2973// Check that `GetMarginBeforeLiteralEmission()` is precise.
2974TEST(literal_pool_margin) {
2975  SETUP();
2976
2977  START();
2978
2979  VIXL_CHECK(masm.VeneerPoolIsEmpty());
2980  VIXL_CHECK(masm.LiteralPoolIsEmpty());
2981
2982  // Create a single literal.
2983  __ Ldrd(r0, r1, 0x1234567890abcdef);
2984
2985  VIXL_CHECK(!masm.LiteralPoolIsEmpty());
2986
2987  // Generate code to fill all the margin we have before generating the literal
2988  // pool.
2989  int32_t margin = masm.GetMarginBeforeLiteralEmission();
2990  int32_t end = masm.GetCursorOffset() + margin;
2991  {
2992    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
2993    // Opening the scope should not have triggered the emission of the literal
2994    // pool.
2995    VIXL_CHECK(!masm.LiteralPoolIsEmpty());
2996    while (masm.GetCursorOffset() < end) {
2997      __ nop();
2998    }
2999    VIXL_CHECK(masm.GetCursorOffset() == end);
3000  }
3001
3002  // There should be no margin left to emit the literal pool.
3003  VIXL_CHECK(!masm.LiteralPoolIsEmpty());
3004  VIXL_CHECK(masm.GetMarginBeforeLiteralEmission() == 0);
3005
3006  // So emitting a single instruction should force emission of the pool.
3007  __ Nop();
3008  VIXL_CHECK(masm.LiteralPoolIsEmpty());
3009  END();
3010
3011  RUN();
3012
3013  // Check that the literals loaded correctly.
3014  ASSERT_EQUAL_32(0x90abcdef, r0);
3015  ASSERT_EQUAL_32(0x12345678, r1);
3016
3017  TEARDOWN();
3018}
3019
3020
3021// Check that `GetMarginBeforeVeneerEmission()` is precise.
3022TEST(veneer_pool_margin) {
3023  SETUP();
3024
3025  START();
3026
3027  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3028  VIXL_CHECK(masm.LiteralPoolIsEmpty());
3029
3030  // Create a single veneer.
3031  Label target;
3032  __ B(eq, &target);
3033
3034  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
3035
3036  // Generate code to fill all the margin we have before generating the veneer
3037  // pool.
3038  int32_t margin = masm.GetMarginBeforeVeneerEmission();
3039  int32_t end = masm.GetCursorOffset() + margin;
3040  {
3041    ExactAssemblyScope scope(&masm, margin, ExactAssemblyScope::kExactSize);
3042    // Opening the scope should not have triggered the emission of the veneer
3043    // pool.
3044    VIXL_CHECK(!masm.VeneerPoolIsEmpty());
3045    while (masm.GetCursorOffset() < end) {
3046      __ nop();
3047    }
3048    VIXL_CHECK(masm.GetCursorOffset() == end);
3049  }
3050  // There should be no margin left to emit the veneer pool.
3051  VIXL_CHECK(masm.GetMarginBeforeVeneerEmission() == 0);
3052
3053  // So emitting a single instruction should force emission of the pool.
3054  // We cannot simply check that the veneer pool is empty, because the veneer
3055  // emitted for the CBZ instruction above is itself tracked by the veneer
3056  // mechanisms. Instead, check that some 'unexpected' code is generated.
3057  Label check;
3058  __ Bind(&check);
3059  {
3060    ExactAssemblyScope scope(&masm, 2, ExactAssemblyScope::kMaximumSize);
3061    // Do not actually generate any code.
3062  }
3063  VIXL_CHECK(masm.GetSizeOfCodeGeneratedSince(&check) > 0);
3064  __ Bind(&target);
3065  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3066
3067  END();
3068
3069  RUN();
3070
3071  TEARDOWN();
3072}
3073
3074
3075TEST_NOASM(code_buffer_precise_growth) {
3076  static const int kBaseBufferSize = 16;
3077  MacroAssembler masm(kBaseBufferSize, T32);
3078
3079  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3080
3081  {
3082    // Fill the buffer with nops.
3083    ExactAssemblyScope scope(&masm, kBaseBufferSize, ExactAssemblyScope::kExactSize);
3084    for (int i = 0; i < kBaseBufferSize; i += k16BitT32InstructionSizeInBytes) {
3085      __ nop();
3086    }
3087  }
3088
3089  // The buffer should not have grown yet.
3090  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3091
3092  // Generating a single instruction should force the buffer to grow.
3093  __ Nop();
3094
3095  VIXL_CHECK(masm.GetBuffer()->GetCapacity() > kBaseBufferSize);
3096
3097  masm.FinalizeCode();
3098}
3099
3100
3101TEST_NOASM(out_of_space_immediately_before_PerformEnsureEmit) {
3102  static const int kBaseBufferSize = 64;
3103  MacroAssembler masm(kBaseBufferSize, T32);
3104
3105  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3106
3107  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3108  VIXL_CHECK(masm.LiteralPoolIsEmpty());
3109
3110  // Create a veneer.
3111  Label target;
3112  __ Cbz(r0, &target);
3113
3114  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
3115
3116  VIXL_CHECK(IsUint32(masm.GetBuffer()->GetRemainingBytes()));
3117  uint32_t space = static_cast<uint32_t>(masm.GetBuffer()->GetRemainingBytes());
3118  {
3119    // Fill the buffer with nops.
3120    ExactAssemblyScope scope(&masm, space, ExactAssemblyScope::kExactSize);
3121    for (uint32_t i = 0; i < space; i += k16BitT32InstructionSizeInBytes) {
3122      __ nop();
3123    }
3124  }
3125
3126  VIXL_CHECK(!masm.VeneerPoolIsEmpty());
3127
3128  // The buffer should not have grown yet, and there should be no space left.
3129  VIXL_CHECK(masm.GetBuffer()->GetCapacity() == kBaseBufferSize);
3130  VIXL_CHECK(masm.GetBuffer()->GetRemainingBytes() == 0);
3131
3132  // Force emission of the veneer, at a point where there is no space available
3133  // in the buffer.
3134  int32_t past_cbz_range = masm.GetMarginBeforeVeneerEmission() + 1;
3135  masm.EnsureEmitFor(past_cbz_range);
3136
3137  __ Bind(&target);
3138
3139  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3140
3141  masm.FinalizeCode();
3142}
3143
3144
3145TEST_T32(two_distant_literal_references) {
3146  SETUP();
3147  START();
3148
3149  Label end;
3150
3151  vixl::aarch32::Literal<uint64_t>* literal =
3152      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
3153                            RawLiteral::kPlacedWhenUsed,
3154                            RawLiteral::kDeletedOnPoolDestruction);
3155  // Refer to the literal so that it is emitted early.
3156  __ Ldr(r0, literal);
3157
3158  // Add enough nops to exceed the range of both loads.
3159  int space = 5000;
3160  {
3161    ExactAssemblyScope scope(&masm,
3162                             space,
3163                             CodeBufferCheckScope::kExactSize);
3164    int nop_size = masm.IsUsingT32() ? k16BitT32InstructionSizeInBytes
3165                                     : kA32InstructionSizeInBytes;
3166    for (int i = 0; i < space; i += nop_size) {
3167      __ nop();
3168    }
3169  }
3170
3171  __ Bind(&end);
3172
3173#define ENSURE_ALIGNED() do {                                                 \
3174  if (!IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
3175    ExactAssemblyScope scope(&masm, k16BitT32InstructionSizeInBytes,          \
3176                             ExactAssemblyScope::kExactSize);                 \
3177    __ nop();                                                                 \
3178  }                                                                           \
3179  VIXL_ASSERT(IsMultiple<k32BitT32InstructionSizeInBytes>(                    \
3180      masm.GetCursorOffset()));                                               \
3181} while(0)
3182
3183  // The literal has already been emitted, and is out of range of all of these
3184  // instructions. The delegates must generate fix-up code.
3185  ENSURE_ALIGNED();
3186  __ Ldr(r1, literal);
3187  ENSURE_ALIGNED();
3188  __ Ldrb(r2, literal);
3189  ENSURE_ALIGNED();
3190  __ Ldrsb(r3, literal);
3191  ENSURE_ALIGNED();
3192  __ Ldrh(r4, literal);
3193  ENSURE_ALIGNED();
3194  __ Ldrsh(r5, literal);
3195  ENSURE_ALIGNED();
3196  __ Ldrd(r6, r7, literal);
3197  ENSURE_ALIGNED();
3198  __ Vldr(d0, literal);
3199  ENSURE_ALIGNED();
3200  __ Vldr(s3, literal);
3201
3202#undef ENSURE_ALIGNED
3203
3204  END();
3205  RUN();
3206
3207  // Check that the literals loaded correctly.
3208  ASSERT_EQUAL_32(0x89abcdef, r0);
3209  ASSERT_EQUAL_32(0x89abcdef, r1);
3210  ASSERT_EQUAL_32(0xef, r2);
3211  ASSERT_EQUAL_32(0xffffffef, r3);
3212  ASSERT_EQUAL_32(0xcdef, r4);
3213  ASSERT_EQUAL_32(0xffffcdef, r5);
3214  ASSERT_EQUAL_32(0x89abcdef, r6);
3215  ASSERT_EQUAL_32(0x01234567, r7);
3216  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
3217  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
3218
3219  TEARDOWN();
3220}
3221
3222
3223TEST_T32(two_distant_literal_references_unaligned_pc) {
3224  SETUP();
3225  START();
3226
3227  Label end;
3228
3229  vixl::aarch32::Literal<uint64_t>* literal =
3230      new Literal<uint64_t>(UINT64_C(0x0123456789abcdef),
3231                            RawLiteral::kPlacedWhenUsed,
3232                            RawLiteral::kDeletedOnPoolDestruction);
3233  // Refer to the literal so that it is emitted early.
3234  __ Ldr(r0, literal);
3235
3236  // Add enough nops to exceed the range of both loads, leaving the PC aligned
3237  // to only a two-byte boundary.
3238  int space = 5002;
3239  {
3240    ExactAssemblyScope scope(&masm,
3241                             space,
3242                             CodeBufferCheckScope::kExactSize);
3243    int nop_size = masm.IsUsingT32() ? k16BitT32InstructionSizeInBytes
3244                                     : kA32InstructionSizeInBytes;
3245    for (int i = 0; i < space; i += nop_size) {
3246      __ nop();
3247    }
3248  }
3249
3250  __ Bind(&end);
3251
3252#define ENSURE_NOT_ALIGNED() do {                                            \
3253  if (IsMultiple<k32BitT32InstructionSizeInBytes>(masm.GetCursorOffset())) { \
3254    ExactAssemblyScope scope(&masm, k16BitT32InstructionSizeInBytes,         \
3255                             ExactAssemblyScope::kExactSize);                \
3256    __ nop();                                                                \
3257  }                                                                          \
3258  VIXL_ASSERT(!IsMultiple<k32BitT32InstructionSizeInBytes>(                  \
3259      masm.GetCursorOffset()));                                              \
3260} while(0)
3261
3262  // The literal has already been emitted, and is out of range of all of these
3263  // instructions. The delegates must generate fix-up code.
3264  ENSURE_NOT_ALIGNED();
3265  __ Ldr(r1, literal);
3266  ENSURE_NOT_ALIGNED();
3267  __ Ldrb(r2, literal);
3268  ENSURE_NOT_ALIGNED();
3269  __ Ldrsb(r3, literal);
3270  ENSURE_NOT_ALIGNED();
3271  __ Ldrh(r4, literal);
3272  ENSURE_NOT_ALIGNED();
3273  __ Ldrsh(r5, literal);
3274  ENSURE_NOT_ALIGNED();
3275  __ Ldrd(r6, r7, literal);
3276  {
3277    // TODO: We currently require an extra scratch register for these cases
3278    // because MemOperandComputationHelper isn't able to fit add_sub_offset into
3279    // a single 'sub' instruction, so 'pc' gets preserved first. The same
3280    // problem technically exists for the other loads, but vldr is particularly
3281    // badly affected because vldr cannot set the low bits in its offset mask,
3282    // so the add/sub operand is likely to be difficult to encode.
3283    //
3284    // At the moment, we get this:
3285    //     mov r8, pc
3286    //     mov ip, #5118
3287    //     sub r8, pc
3288    //     vldr d0, [r8, #48]
3289    //
3290    // We should be able to generate something like this:
3291    //     sub ip, pc, #0x1300    // 5118 & 0xff00
3292    //     sub ip, #0xfe          // 5118 & 0x00ff
3293    //     vldr d0, [ip, #48]
3294    UseScratchRegisterScope temps(&masm);
3295    temps.Include(r8);
3296    ENSURE_NOT_ALIGNED();
3297    __ Vldr(d0, literal);
3298    ENSURE_NOT_ALIGNED();
3299    __ Vldr(s3, literal);
3300  }
3301
3302#undef ENSURE_NOT_ALIGNED
3303
3304  END();
3305  RUN();
3306
3307  // Check that the literals loaded correctly.
3308  ASSERT_EQUAL_32(0x89abcdef, r0);
3309  ASSERT_EQUAL_32(0x89abcdef, r1);
3310  ASSERT_EQUAL_32(0xef, r2);
3311  ASSERT_EQUAL_32(0xffffffef, r3);
3312  ASSERT_EQUAL_32(0xcdef, r4);
3313  ASSERT_EQUAL_32(0xffffcdef, r5);
3314  ASSERT_EQUAL_32(0x89abcdef, r6);
3315  ASSERT_EQUAL_32(0x01234567, r7);
3316  ASSERT_EQUAL_FP64(RawbitsToDouble(0x0123456789abcdef), d0);
3317  ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s3);
3318
3319  TEARDOWN();
3320}
3321
3322
3323TEST(barriers) {
3324  // Generate all supported barriers, this is just a smoke test
3325  SETUP();
3326
3327  START();
3328
3329  // DMB
3330  __ Dmb(SY);
3331  __ Dmb(ST);
3332  __ Dmb(ISH);
3333  __ Dmb(ISHST);
3334  __ Dmb(NSH);
3335  __ Dmb(NSHST);
3336  __ Dmb(OSH);
3337  __ Dmb(OSHST);
3338
3339  // DSB
3340  __ Dsb(SY);
3341  __ Dsb(ST);
3342  __ Dsb(ISH);
3343  __ Dsb(ISHST);
3344  __ Dsb(NSH);
3345  __ Dsb(NSHST);
3346  __ Dsb(OSH);
3347  __ Dsb(OSHST);
3348
3349  // ISB
3350  __ Isb(SY);
3351
3352  END();
3353
3354  TEARDOWN();
3355}
3356
3357
3358TEST(preloads) {
3359  // Smoke test for various pld/pli forms.
3360  SETUP();
3361
3362  START();
3363
3364  // PLD immediate
3365  __ Pld(MemOperand(sp, 0));
3366  __ Pld(MemOperand(r0, 0));
3367  __ Pld(MemOperand(r1, 123));
3368  __ Pld(MemOperand(r2, 1234));
3369  __ Pld(MemOperand(r3, 4095));
3370  __ Pld(MemOperand(r4, -123));
3371  __ Pld(MemOperand(r5, -255));
3372
3373  if (masm.IsUsingA32()) {
3374    __ Pld(MemOperand(r6, -1234));
3375    __ Pld(MemOperand(r7, -4095));
3376  }
3377
3378
3379  // PLDW immediate
3380  __ Pldw(MemOperand(sp, 0));
3381  __ Pldw(MemOperand(r0, 0));
3382  __ Pldw(MemOperand(r1, 123));
3383  __ Pldw(MemOperand(r2, 1234));
3384  __ Pldw(MemOperand(r3, 4095));
3385  __ Pldw(MemOperand(r4, -123));
3386  __ Pldw(MemOperand(r5, -255));
3387
3388  if (masm.IsUsingA32()) {
3389    __ Pldw(MemOperand(r6, -1234));
3390    __ Pldw(MemOperand(r7, -4095));
3391  }
3392
3393  // PLD register
3394  __ Pld(MemOperand(r0, r1));
3395  __ Pld(MemOperand(r0, r1, LSL, 1));
3396  __ Pld(MemOperand(r0, r1, LSL, 2));
3397  __ Pld(MemOperand(r0, r1, LSL, 3));
3398
3399  if (masm.IsUsingA32()) {
3400    __ Pld(MemOperand(r0, r1, LSL, 4));
3401    __ Pld(MemOperand(r0, r1, LSL, 20));
3402  }
3403
3404  // PLDW register
3405  __ Pldw(MemOperand(r0, r1));
3406  __ Pldw(MemOperand(r0, r1, LSL, 1));
3407  __ Pldw(MemOperand(r0, r1, LSL, 2));
3408  __ Pldw(MemOperand(r0, r1, LSL, 3));
3409
3410  if (masm.IsUsingA32()) {
3411    __ Pldw(MemOperand(r0, r1, LSL, 4));
3412    __ Pldw(MemOperand(r0, r1, LSL, 20));
3413  }
3414
3415  // PLD literal
3416  Label pld_label;
3417  __ Pld(&pld_label);
3418  __ Bind(&pld_label);
3419
3420  // PLI immediate
3421  __ Pli(MemOperand(sp, 0));
3422  __ Pli(MemOperand(r0, 0));
3423  __ Pli(MemOperand(r1, 123));
3424  __ Pli(MemOperand(r2, 1234));
3425  __ Pli(MemOperand(r3, 4095));
3426  __ Pli(MemOperand(r4, -123));
3427  __ Pli(MemOperand(r5, -255));
3428
3429  if (masm.IsUsingA32()) {
3430    __ Pli(MemOperand(r6, -1234));
3431    __ Pli(MemOperand(r7, -4095));
3432  }
3433
3434  // PLI register
3435  __ Pli(MemOperand(r0, r1));
3436  __ Pli(MemOperand(r0, r1, LSL, 1));
3437  __ Pli(MemOperand(r0, r1, LSL, 2));
3438  __ Pli(MemOperand(r0, r1, LSL, 3));
3439
3440  if (masm.IsUsingA32()) {
3441    __ Pli(MemOperand(r0, r1, LSL, 4));
3442    __ Pli(MemOperand(r0, r1, LSL, 20));
3443  }
3444
3445  // PLI literal
3446  Label pli_label;
3447  __ Pli(&pli_label);
3448  __ Bind(&pli_label);
3449
3450  END();
3451
3452  TEARDOWN();
3453}
3454
3455
3456TEST_T32(veneer_mirrored_branches) {
3457  SETUP();
3458
3459  START();
3460
3461  const int kMaxBranchCount = 256;
3462
3463  for (int branch_count = 1; branch_count < kMaxBranchCount; branch_count++) {
3464    Label* targets = new Label[branch_count];
3465
3466    for (int i = 0; i < branch_count; i++) {
3467      __ Cbz(r0, &targets[i]);
3468    }
3469
3470    for (int i = 0; i < branch_count; i++) {
3471      __ Bind(&targets[branch_count - i - 1]);
3472      __ Orr(r0, r0, r0);
3473    }
3474
3475    delete[] targets;
3476  }
3477
3478  END();
3479
3480  TEARDOWN();
3481}
3482
3483
3484TEST_T32(branch_fuzz_example) {
3485  SETUP();
3486
3487  START();
3488
3489  Label l[64];
3490  __ And(r0, r0, r0);
3491  __ Cbz(r0, &l[30]);
3492  __ And(r0, r0, r0);
3493  __ Cbz(r0, &l[22]);
3494  __ And(r0, r0, r0);
3495  __ Cbz(r0, &l[1]);
3496  __ Cbz(r0, &l[15]);
3497  __ Cbz(r0, &l[9]);
3498  __ Cbz(r0, &l[6]);
3499  __ Bind(&l[26]);
3500  __ Cbz(r0, &l[29]);
3501  __ And(r0, r0, r0);
3502  __ And(r0, r0, r0);
3503  __ Cbz(r0, &l[22]);
3504  __ Bind(&l[12]);
3505  __ Bind(&l[22]);
3506  __ Cbz(r0, &l[10]);
3507  __ And(r0, r0, r0);
3508  __ Cbz(r0, &l[30]);
3509  __ Cbz(r0, &l[17]);
3510  __ Cbz(r0, &l[27]);
3511  __ Cbz(r0, &l[11]);
3512  __ Bind(&l[7]);
3513  __ Cbz(r0, &l[18]);
3514  __ Bind(&l[14]);
3515  __ Cbz(r0, &l[1]);
3516  __ Bind(&l[18]);
3517  __ Cbz(r0, &l[11]);
3518  __ Cbz(r0, &l[6]);
3519  __ Bind(&l[21]);
3520  __ Cbz(r0, &l[28]);
3521  __ And(r0, r0, r0);
3522  __ Cbz(r0, &l[28]);
3523  __ Cbz(r0, &l[22]);
3524  __ Bind(&l[23]);
3525  __ Cbz(r0, &l[21]);
3526  __ Cbz(r0, &l[28]);
3527  __ Cbz(r0, &l[9]);
3528  __ Bind(&l[9]);
3529  __ Cbz(r0, &l[4]);
3530  __ And(r0, r0, r0);
3531  __ Cbz(r0, &l[10]);
3532  __ And(r0, r0, r0);
3533  __ Bind(&l[8]);
3534  __ And(r0, r0, r0);
3535  __ Cbz(r0, &l[10]);
3536  __ And(r0, r0, r0);
3537  __ Cbz(r0, &l[17]);
3538  __ Bind(&l[10]);
3539  __ Cbz(r0, &l[8]);
3540  __ Cbz(r0, &l[25]);
3541  __ Cbz(r0, &l[4]);
3542  __ Bind(&l[28]);
3543  __ And(r0, r0, r0);
3544  __ Cbz(r0, &l[16]);
3545  __ Bind(&l[19]);
3546  __ Cbz(r0, &l[14]);
3547  __ Cbz(r0, &l[28]);
3548  __ Cbz(r0, &l[26]);
3549  __ Cbz(r0, &l[21]);
3550  __ And(r0, r0, r0);
3551  __ Bind(&l[24]);
3552  __ And(r0, r0, r0);
3553  __ Cbz(r0, &l[24]);
3554  __ Cbz(r0, &l[24]);
3555  __ Cbz(r0, &l[19]);
3556  __ Cbz(r0, &l[26]);
3557  __ Cbz(r0, &l[4]);
3558  __ And(r0, r0, r0);
3559  __ Cbz(r0, &l[27]);
3560  __ Cbz(r0, &l[14]);
3561  __ Cbz(r0, &l[5]);
3562  __ Cbz(r0, &l[18]);
3563  __ Cbz(r0, &l[5]);
3564  __ Cbz(r0, &l[6]);
3565  __ Cbz(r0, &l[28]);
3566  __ Cbz(r0, &l[15]);
3567  __ Cbz(r0, &l[0]);
3568  __ Cbz(r0, &l[10]);
3569  __ Cbz(r0, &l[16]);
3570  __ Cbz(r0, &l[30]);
3571  __ Cbz(r0, &l[8]);
3572  __ Cbz(r0, &l[16]);
3573  __ Cbz(r0, &l[22]);
3574  __ Cbz(r0, &l[27]);
3575  __ Cbz(r0, &l[12]);
3576  __ Cbz(r0, &l[0]);
3577  __ Cbz(r0, &l[23]);
3578  __ Cbz(r0, &l[27]);
3579  __ Cbz(r0, &l[16]);
3580  __ Cbz(r0, &l[24]);
3581  __ Cbz(r0, &l[17]);
3582  __ Cbz(r0, &l[4]);
3583  __ Cbz(r0, &l[11]);
3584  __ Cbz(r0, &l[6]);
3585  __ Cbz(r0, &l[23]);
3586  __ Bind(&l[16]);
3587  __ Cbz(r0, &l[10]);
3588  __ Cbz(r0, &l[17]);
3589  __ Cbz(r0, &l[12]);
3590  __ And(r0, r0, r0);
3591  __ Cbz(r0, &l[11]);
3592  __ Cbz(r0, &l[17]);
3593  __ Cbz(r0, &l[1]);
3594  __ Cbz(r0, &l[3]);
3595  __ Cbz(r0, &l[18]);
3596  __ Bind(&l[4]);
3597  __ Cbz(r0, &l[31]);
3598  __ Cbz(r0, &l[25]);
3599  __ Cbz(r0, &l[22]);
3600  __ And(r0, r0, r0);
3601  __ Cbz(r0, &l[19]);
3602  __ Cbz(r0, &l[16]);
3603  __ Cbz(r0, &l[21]);
3604  __ Cbz(r0, &l[27]);
3605  __ Bind(&l[1]);
3606  __ Cbz(r0, &l[9]);
3607  __ Cbz(r0, &l[13]);
3608  __ Cbz(r0, &l[10]);
3609  __ Cbz(r0, &l[6]);
3610  __ Cbz(r0, &l[30]);
3611  __ Cbz(r0, &l[28]);
3612  __ Cbz(r0, &l[7]);
3613  __ Cbz(r0, &l[17]);
3614  __ Bind(&l[0]);
3615  __ Cbz(r0, &l[13]);
3616  __ Cbz(r0, &l[11]);
3617  __ Cbz(r0, &l[19]);
3618  __ Cbz(r0, &l[22]);
3619  __ Cbz(r0, &l[9]);
3620  __ And(r0, r0, r0);
3621  __ Cbz(r0, &l[15]);
3622  __ Cbz(r0, &l[31]);
3623  __ Cbz(r0, &l[2]);
3624  __ And(r0, r0, r0);
3625  __ Cbz(r0, &l[6]);
3626  __ Bind(&l[27]);
3627  __ Bind(&l[13]);
3628  __ Cbz(r0, &l[23]);
3629  __ Cbz(r0, &l[7]);
3630  __ Bind(&l[2]);
3631  __ And(r0, r0, r0);
3632  __ Cbz(r0, &l[1]);
3633  __ Bind(&l[15]);
3634  __ Cbz(r0, &l[13]);
3635  __ Cbz(r0, &l[17]);
3636  __ Cbz(r0, &l[8]);
3637  __ Cbz(r0, &l[30]);
3638  __ Cbz(r0, &l[8]);
3639  __ Cbz(r0, &l[27]);
3640  __ Cbz(r0, &l[2]);
3641  __ Cbz(r0, &l[31]);
3642  __ Cbz(r0, &l[4]);
3643  __ Cbz(r0, &l[11]);
3644  __ Bind(&l[29]);
3645  __ Cbz(r0, &l[7]);
3646  __ Cbz(r0, &l[5]);
3647  __ Cbz(r0, &l[11]);
3648  __ Cbz(r0, &l[24]);
3649  __ Cbz(r0, &l[9]);
3650  __ Cbz(r0, &l[3]);
3651  __ Cbz(r0, &l[3]);
3652  __ Cbz(r0, &l[22]);
3653  __ Cbz(r0, &l[19]);
3654  __ Cbz(r0, &l[4]);
3655  __ Bind(&l[6]);
3656  __ And(r0, r0, r0);
3657  __ And(r0, r0, r0);
3658  __ Cbz(r0, &l[9]);
3659  __ Cbz(r0, &l[3]);
3660  __ Cbz(r0, &l[23]);
3661  __ Cbz(r0, &l[12]);
3662  __ Cbz(r0, &l[1]);
3663  __ Cbz(r0, &l[22]);
3664  __ Cbz(r0, &l[24]);
3665  __ And(r0, r0, r0);
3666  __ Cbz(r0, &l[16]);
3667  __ Cbz(r0, &l[19]);
3668  __ Cbz(r0, &l[20]);
3669  __ Cbz(r0, &l[1]);
3670  __ Cbz(r0, &l[4]);
3671  __ Cbz(r0, &l[1]);
3672  __ Cbz(r0, &l[25]);
3673  __ Cbz(r0, &l[21]);
3674  __ Cbz(r0, &l[20]);
3675  __ Cbz(r0, &l[29]);
3676  __ And(r0, r0, r0);
3677  __ Cbz(r0, &l[10]);
3678  __ Cbz(r0, &l[5]);
3679  __ And(r0, r0, r0);
3680  __ Cbz(r0, &l[25]);
3681  __ Cbz(r0, &l[26]);
3682  __ Cbz(r0, &l[28]);
3683  __ Cbz(r0, &l[19]);
3684  __ And(r0, r0, r0);
3685  __ Bind(&l[17]);
3686  __ And(r0, r0, r0);
3687  __ And(r0, r0, r0);
3688  __ And(r0, r0, r0);
3689  __ And(r0, r0, r0);
3690  __ Cbz(r0, &l[6]);
3691  __ And(r0, r0, r0);
3692  __ Cbz(r0, &l[5]);
3693  __ Cbz(r0, &l[26]);
3694  __ Cbz(r0, &l[28]);
3695  __ Cbz(r0, &l[24]);
3696  __ Bind(&l[20]);
3697  __ And(r0, r0, r0);
3698  __ Cbz(r0, &l[10]);
3699  __ Cbz(r0, &l[19]);
3700  __ Cbz(r0, &l[6]);
3701  __ And(r0, r0, r0);
3702  __ Cbz(r0, &l[13]);
3703  __ Cbz(r0, &l[15]);
3704  __ Cbz(r0, &l[22]);
3705  __ Cbz(r0, &l[8]);
3706  __ Cbz(r0, &l[6]);
3707  __ Cbz(r0, &l[23]);
3708  __ Cbz(r0, &l[6]);
3709  __ And(r0, r0, r0);
3710  __ Cbz(r0, &l[13]);
3711  __ Bind(&l[31]);
3712  __ Cbz(r0, &l[14]);
3713  __ Cbz(r0, &l[5]);
3714  __ Cbz(r0, &l[1]);
3715  __ Cbz(r0, &l[17]);
3716  __ Cbz(r0, &l[27]);
3717  __ Cbz(r0, &l[10]);
3718  __ Cbz(r0, &l[30]);
3719  __ Cbz(r0, &l[14]);
3720  __ Cbz(r0, &l[24]);
3721  __ Cbz(r0, &l[26]);
3722  __ And(r0, r0, r0);
3723  __ Cbz(r0, &l[2]);
3724  __ Cbz(r0, &l[21]);
3725  __ Cbz(r0, &l[5]);
3726  __ Cbz(r0, &l[24]);
3727  __ And(r0, r0, r0);
3728  __ Cbz(r0, &l[24]);
3729  __ Cbz(r0, &l[17]);
3730  __ And(r0, r0, r0);
3731  __ And(r0, r0, r0);
3732  __ Cbz(r0, &l[24]);
3733  __ And(r0, r0, r0);
3734  __ Cbz(r0, &l[17]);
3735  __ Cbz(r0, &l[12]);
3736  __ And(r0, r0, r0);
3737  __ Cbz(r0, &l[9]);
3738  __ Cbz(r0, &l[9]);
3739  __ Cbz(r0, &l[31]);
3740  __ Cbz(r0, &l[25]);
3741  __ And(r0, r0, r0);
3742  __ And(r0, r0, r0);
3743  __ Cbz(r0, &l[13]);
3744  __ Cbz(r0, &l[14]);
3745  __ Cbz(r0, &l[5]);
3746  __ Cbz(r0, &l[5]);
3747  __ Cbz(r0, &l[12]);
3748  __ Cbz(r0, &l[3]);
3749  __ Cbz(r0, &l[25]);
3750  __ Bind(&l[11]);
3751  __ Cbz(r0, &l[15]);
3752  __ Cbz(r0, &l[20]);
3753  __ Cbz(r0, &l[22]);
3754  __ Cbz(r0, &l[19]);
3755  __ And(r0, r0, r0);
3756  __ Cbz(r0, &l[19]);
3757  __ And(r0, r0, r0);
3758  __ Cbz(r0, &l[21]);
3759  __ Cbz(r0, &l[0]);
3760  __ And(r0, r0, r0);
3761  __ Cbz(r0, &l[16]);
3762  __ Cbz(r0, &l[28]);
3763  __ Cbz(r0, &l[18]);
3764  __ Cbz(r0, &l[3]);
3765  __ And(r0, r0, r0);
3766  __ Cbz(r0, &l[15]);
3767  __ Cbz(r0, &l[8]);
3768  __ Cbz(r0, &l[25]);
3769  __ Cbz(r0, &l[1]);
3770  __ Cbz(r0, &l[21]);
3771  __ Cbz(r0, &l[1]);
3772  __ Cbz(r0, &l[29]);
3773  __ Cbz(r0, &l[15]);
3774  __ And(r0, r0, r0);
3775  __ Cbz(r0, &l[24]);
3776  __ Cbz(r0, &l[3]);
3777  __ Cbz(r0, &l[9]);
3778  __ Cbz(r0, &l[9]);
3779  __ Cbz(r0, &l[24]);
3780  __ And(r0, r0, r0);
3781  __ Cbz(r0, &l[19]);
3782  __ And(r0, r0, r0);
3783  __ Cbz(r0, &l[30]);
3784  __ Bind(&l[25]);
3785  __ Bind(&l[3]);
3786  __ Bind(&l[30]);
3787  __ Bind(&l[5]);
3788
3789  END();
3790
3791  TEARDOWN();
3792}
3793
3794
3795// Generate a "B" and a "Cbz" which have the same checkpoint. Without proper
3796// management (i.e. if the veneers were only generated at the shared
3797// checkpoint), one one of the branches would be out of range.
3798TEST_T32(veneer_simultaneous) {
3799  SETUP();
3800
3801  START();
3802
3803  // `2046` max range - the size of the B.EQ itself.
3804  static const int kMaxBCondRange = 1048574;
3805
3806  Label target_1;
3807  Label target_2;
3808
3809  __ B(eq, &target_1);
3810
3811  int target_1_size_1 =
3812      kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
3813  int end_1 = masm.GetCursorOffset() + target_1_size_1;
3814  while (masm.GetCursorOffset() < end_1) {
3815    __ Nop();
3816  }
3817
3818  __ Cbz(r0, &target_2);
3819
3820  int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
3821  int end_2 = masm.GetCursorOffset() + target_1_size_2;
3822  while (masm.GetCursorOffset() < end_2) {
3823    __ Nop();
3824  }
3825
3826  __ Nop();
3827
3828  __ Bind(&target_1);
3829  __ Bind(&target_2);
3830
3831  END();
3832
3833  TEARDOWN();
3834}
3835
3836
3837// Generate a "B" and a "Cbz" which have the same checkpoint and the same label.
3838TEST_T32(veneer_simultaneous_one_label) {
3839  SETUP();
3840
3841  START();
3842
3843  // `2046` max range - the size of the B.EQ itself.
3844  static const int kMaxBCondRange = 1048574;
3845
3846  Label target;
3847
3848  __ B(eq, &target);
3849
3850  int target_1_size_1 =
3851      kMaxBCondRange - kCbzCbnzRange - k32BitT32InstructionSizeInBytes;
3852  int end_1 = masm.GetCursorOffset() + target_1_size_1;
3853  while (masm.GetCursorOffset() < end_1) {
3854    __ Nop();
3855  }
3856
3857  __ Cbz(r0, &target);
3858
3859  int target_1_size_2 = kCbzCbnzRange - k16BitT32InstructionSizeInBytes;
3860  int end_2 = masm.GetCursorOffset() + target_1_size_2;
3861  while (masm.GetCursorOffset() < end_2) {
3862    __ Nop();
3863  }
3864
3865  __ Nop();
3866
3867  __ Bind(&target);
3868
3869  END();
3870
3871  TEARDOWN();
3872}
3873
3874
3875// The literal pool will be emitted early because we keep a margin to always be
3876// able to generate the veneers before the literal.
3877TEST_T32(veneer_and_literal) {
3878  SETUP();
3879
3880  START();
3881
3882  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3883  VIXL_CHECK(masm.LiteralPoolIsEmpty());
3884
3885  const uint32_t ldrd_range = 1020;
3886  const uint32_t cbz_range = 126;
3887  const uint32_t kLabelsCount = 20;
3888  Label labels[kLabelsCount];
3889
3890  // Create one literal pool entry.
3891  __ Ldrd(r0, r1, 0x1234567890abcdef);
3892
3893  // Generate some nops.
3894  uint32_t i = 0;
3895  for (; i < ldrd_range - cbz_range - 40;
3896       i += k16BitT32InstructionSizeInBytes) {
3897    __ Nop();
3898  }
3899
3900  // At this point, it remains cbz_range + 40 => 166 bytes before ldrd becomes
3901  // out of range.
3902  // We generate kLabelsCount * 4 => 80 bytes. We shouldn't generate the
3903  // literal pool.
3904  for (uint32_t j = 0; j < kLabelsCount; j++) {
3905    __ Cbz(r0, &labels[j]);
3906    __ Nop();
3907    i += 2 * k16BitT32InstructionSizeInBytes;
3908  }
3909
3910  // However as we have pending veneer, the range is shrinken and the literal
3911  // pool is generated.
3912  VIXL_ASSERT(masm.LiteralPoolIsEmpty());
3913  // However, we didn't generate the veneer pool.
3914  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() <
3915              static_cast<int32_t>(cbz_range));
3916
3917  // We generate a few more instructions.
3918  for (; i < ldrd_range - 4 * kA32InstructionSizeInBytes;
3919       i += k16BitT32InstructionSizeInBytes) {
3920    __ Nop();
3921  }
3922
3923  // And a veneer pool has been generated.
3924  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() >
3925              static_cast<int32_t>(cbz_range));
3926
3927  // Bind all the used labels.
3928  for (uint32_t j = 0; j < kLabelsCount; j++) {
3929    __ Bind(&labels[j]);
3930    __ Nop();
3931  }
3932
3933  // Now that all the labels have been bound, we have no more veneer.
3934  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3935
3936  END();
3937
3938  RUN();
3939
3940  // Check that the literals loaded correctly.
3941  ASSERT_EQUAL_32(0x90abcdef, r0);
3942  ASSERT_EQUAL_32(0x12345678, r1);
3943
3944  TEARDOWN();
3945}
3946
3947
3948// The literal pool will be emitted early and, as the emission of the literal
3949// pool would have put veneer out of range, the veneers are emitted first.
3950TEST_T32(veneer_and_literal2) {
3951  SETUP();
3952
3953  START();
3954
3955  VIXL_CHECK(masm.VeneerPoolIsEmpty());
3956  VIXL_CHECK(masm.LiteralPoolIsEmpty());
3957
3958  const uint32_t ldrd_range = 1020;
3959  const uint32_t cbz_range = 126;
3960  const uint32_t kLabelsCount = 20;
3961  const int32_t kTypicalMacroInstructionMaxSize =
3962      8 * kMaxInstructionSizeInBytes;
3963  Label labels[kLabelsCount];
3964
3965  // Create one literal pool entry.
3966  __ Ldrd(r0, r1, 0x1234567890abcdef);
3967
3968  for (uint32_t i = 0; i < ldrd_range - cbz_range - 4 * kLabelsCount;
3969       i += k16BitT32InstructionSizeInBytes) {
3970    __ Nop();
3971  }
3972
3973  // Add entries to the veneer pool.
3974  for (uint32_t i = 0; i < kLabelsCount; i++) {
3975    __ Cbz(r0, &labels[i]);
3976    __ Nop();
3977  }
3978
3979  // Generate nops up to the literal pool limit.
3980  while (masm.GetMarginBeforeLiteralEmission() >=
3981         kTypicalMacroInstructionMaxSize) {
3982    __ Nop();
3983  }
3984
3985  // At this point, no literals and no veneers have been generated.
3986  VIXL_ASSERT(!masm.LiteralPoolIsEmpty());
3987  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() <
3988              static_cast<int32_t>(cbz_range));
3989  // The literal pool needs to be generated.
3990  VIXL_ASSERT(masm.GetMarginBeforeLiteralEmission() <
3991              kTypicalMacroInstructionMaxSize);
3992  // But not the veneer pool.
3993  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() >=
3994              kTypicalMacroInstructionMaxSize);
3995  // However, as the literal emission would put veneers out of range.
3996  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() <
3997              kTypicalMacroInstructionMaxSize +
3998              static_cast<int32_t>(masm.GetLiteralPoolSize()));
3999
4000  // This extra Nop will generate the literal pool and before that the veneer
4001  // pool.
4002  __ Nop();
4003  // Now the literal pool has been generated.
4004  VIXL_ASSERT(masm.LiteralPoolIsEmpty());
4005  // And also the veneer pool.
4006  VIXL_ASSERT(masm.GetMarginBeforeVeneerEmission() > 1000);
4007
4008  // Bind all the used labels.
4009  for (uint32_t j = 0; j < kLabelsCount; j++) {
4010    __ Bind(&labels[j]);
4011    __ Nop();
4012  }
4013
4014  // Now that all the labels have been bound, we have no more veneer.
4015  VIXL_CHECK(masm.VeneerPoolIsEmpty());
4016
4017  END();
4018
4019  RUN();
4020
4021  // Check that the literals loaded correctly.
4022  ASSERT_EQUAL_32(0x90abcdef, r0);
4023  ASSERT_EQUAL_32(0x12345678, r1);
4024
4025  TEARDOWN();
4026}
4027
4028
4029// Use a literal when we already have a veneer pool potential size greater than
4030// the literal range => generate the literal immediately (not optimum but it
4031// works).
4032TEST_T32(veneer_and_literal3) {
4033  SETUP();
4034
4035  START();
4036
4037  static const int kLabelsCount = 1000;
4038
4039  Label labels[kLabelsCount];
4040
4041  // Set the Z flag so that the following branches are not taken.
4042  __ Movs(r0, 0);
4043
4044  for (int i = 0; i < kLabelsCount; i++) {
4045    __ B(ne, &labels[i]);
4046  }
4047
4048  // Create one literal pool entry.
4049  __ Ldrd(r0, r1, 0x1234567890abcdef);
4050
4051  for (int i = 0; i < 10; i++) {
4052    __ Nop();
4053  }
4054
4055  for (int i = 0; i < kLabelsCount; i++) {
4056    __ Bind(&labels[i]);
4057  }
4058
4059  END();
4060
4061  RUN();
4062
4063  // Check that the literals loaded correctly.
4064  ASSERT_EQUAL_32(0x90abcdef, r0);
4065  ASSERT_EQUAL_32(0x12345678, r1);
4066
4067  TEARDOWN();
4068}
4069
4070
4071// Literal has to be generated sooner than veneers. However, as the literal
4072// pool generation would make the veneers out of range, generate the veneers
4073// first.
4074TEST_T32(veneer_and_literal4) {
4075  SETUP();
4076
4077  START();
4078
4079  Label end;
4080
4081  // Set the Z flag so that the following branch is not taken.
4082  __ Movs(r0, 0);
4083  __ B(ne, &end);
4084
4085  uint32_t value = 0x1234567;
4086  vixl::aarch32::Literal<uint32_t>* literal =
4087      new Literal<uint32_t>(value, RawLiteral::kPlacedWhenUsed, RawLiteral::kDeletedOnPoolDestruction);
4088
4089  __ Ldr(r11, literal);
4090
4091  // The range for ldr is 4095, the range for cbz is 127. Generate nops
4092  // to have the ldr becomming out of range just before the cbz.
4093  const int NUM_NOPS = 2044;
4094  const int NUM_RANGE = 58;
4095
4096  const int NUM1 = NUM_NOPS - NUM_RANGE;
4097  const int NUM2 = NUM_RANGE ;
4098
4099  {
4100    ExactAssemblyScope aas(&masm,
4101                           2 * NUM1,
4102                           CodeBufferCheckScope::kMaximumSize);
4103    for (int i = 0; i < NUM1; i++) {
4104      __ nop();
4105    }
4106  }
4107
4108  __ Cbz(r1, &end);
4109
4110  {
4111    ExactAssemblyScope aas(&masm,
4112                           2 * NUM2,
4113                           CodeBufferCheckScope::kMaximumSize);
4114    for (int i = 0; i < NUM2; i++) {
4115      __ nop();
4116    }
4117  }
4118
4119  {
4120    ExactAssemblyScope aas(&masm,
4121                           4,
4122                           CodeBufferCheckScope::kMaximumSize);
4123    __ add(r1, r1, 3);
4124  }
4125  __ Bind(&end);
4126
4127  END();
4128
4129  RUN();
4130
4131  // Check that the literals loaded correctly.
4132  ASSERT_EQUAL_32(0x1234567, r11);
4133
4134  TEARDOWN();
4135}
4136
4137
4138// Literal has to be generated sooner than veneers. However, as the literal
4139// pool generation would make the veneers out of range, generate the veneers
4140// first.
4141TEST_T32(veneer_and_literal5) {
4142  SETUP();
4143
4144  START();
4145
4146  static const int kTestCount = 100;
4147  Label labels[kTestCount];
4148
4149  int first_test = 2000;
4150  // Test on both sizes of the Adr range which is 4095.
4151  for (int test = 0; test < kTestCount; test++) {
4152
4153    const int string_size = 1000;  // A lot more than the cbz range.
4154    std::string test_string(string_size, 'x');
4155    StringLiteral big_literal(test_string.c_str());
4156
4157    __ Adr(r11, &big_literal);
4158
4159    {
4160      int num_nops = first_test + test;
4161      ExactAssemblyScope aas(&masm,
4162                             2 * num_nops,
4163                             CodeBufferCheckScope::kMaximumSize);
4164      for (int i = 0; i < num_nops; i++) {
4165        __ nop();
4166      }
4167    }
4168
4169    __ Cbz(r1, &labels[test]);
4170
4171    {
4172      ExactAssemblyScope aas(&masm,
4173                             4,
4174                             CodeBufferCheckScope::kMaximumSize);
4175      __ add(r1, r1, 3);
4176    }
4177    __ Bind(&labels[test]);
4178    // Emit the literal pool if it has not beeen emitted (it's the case for
4179    // the lower values of test).
4180    __ EmitLiteralPool(MacroAssembler::kBranchRequired);
4181  }
4182
4183  END();
4184
4185  TEARDOWN();
4186}
4187
4188
4189// Check that a label which is just bound during the MacroEmissionCheckScope
4190// can be used.
4191TEST(ldr_label_bound_during_scope) {
4192  SETUP();
4193  START();
4194
4195  const int32_t kTypicalMacroInstructionMaxSize =
4196      8 * kMaxInstructionSizeInBytes;
4197
4198  vixl::aarch32::Literal<uint64_t>* literal =
4199      new Literal<uint64_t>(UINT64_C(0x1234567890abcdef),
4200                            RawLiteral::kPlacedWhenUsed,
4201                            RawLiteral::kDeletedOnPoolDestruction);
4202  __ Ldrd(r0, r1, literal);
4203
4204  while (masm.GetMarginBeforeLiteralEmission() >=
4205         kTypicalMacroInstructionMaxSize) {
4206    __ Nop();
4207  }
4208
4209  VIXL_ASSERT(!masm.LiteralPoolIsEmpty());
4210
4211  // This Ldrd will first generate the pool and then use literal which has just
4212  // been bound.
4213  __ Ldrd(r2, r3, literal);
4214
4215  VIXL_ASSERT(masm.LiteralPoolIsEmpty());
4216
4217  END();
4218
4219  RUN();
4220
4221  // Check that the literals loaded correctly.
4222  ASSERT_EQUAL_32(0x90abcdef, r0);
4223  ASSERT_EQUAL_32(0x12345678, r1);
4224  ASSERT_EQUAL_32(0x90abcdef, r2);
4225  ASSERT_EQUAL_32(0x12345678, r3);
4226
4227  TEARDOWN();
4228}
4229
4230
4231// TODO: Remove this limitation by having a sandboxing mechanism.
4232#if defined(VIXL_HOST_POINTER_32)
4233TEST(ldm_stm_no_writeback) {
4234  SETUP();
4235
4236  START();
4237
4238  const uint32_t src[4] = { 0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef };
4239  uint32_t dst1[4] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
4240  uint32_t dst2[4] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
4241
4242  __ Mov(r0, reinterpret_cast<uintptr_t>(src));
4243  __ Ldm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));;
4244  __ Ldm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
4245
4246  __ Mov(r0, reinterpret_cast<uintptr_t>(dst1));
4247  __ Stm(r0, NO_WRITE_BACK, RegisterList(r1, r2, r3, r4));;
4248
4249  __ Mov(r0, reinterpret_cast<uintptr_t>(dst2));
4250  __ Stm(r0, NO_WRITE_BACK, RegisterList(r5, r6, r9, r11));
4251
4252  END();
4253
4254  RUN();
4255
4256  ASSERT_EQUAL_32(0x12345678, r1);
4257  ASSERT_EQUAL_32(0x09abcdef, r2);
4258  ASSERT_EQUAL_32(0xc001c0de, r3);
4259  ASSERT_EQUAL_32(0xdeadbeef, r4);
4260
4261  ASSERT_EQUAL_32(0x12345678, r5);
4262  ASSERT_EQUAL_32(0x09abcdef, r6);
4263  ASSERT_EQUAL_32(0xc001c0de, r9);
4264  ASSERT_EQUAL_32(0xdeadbeef, r11);
4265
4266  ASSERT_EQUAL_32(0x12345678, dst1[0]);
4267  ASSERT_EQUAL_32(0x09abcdef, dst1[1]);
4268  ASSERT_EQUAL_32(0xc001c0de, dst1[2]);
4269  ASSERT_EQUAL_32(0xdeadbeef, dst1[3]);
4270
4271  ASSERT_EQUAL_32(0x12345678, dst2[0]);
4272  ASSERT_EQUAL_32(0x09abcdef, dst2[1]);
4273  ASSERT_EQUAL_32(0xc001c0de, dst2[2]);
4274  ASSERT_EQUAL_32(0xdeadbeef, dst2[3]);
4275
4276  TEARDOWN();
4277}
4278
4279
4280TEST(ldm_stm_writeback) {
4281  SETUP();
4282
4283  START();
4284
4285  const uint32_t src[4] = { 0x12345678, 0x09abcdef, 0xc001c0de, 0xdeadbeef };
4286  uint32_t dst[8] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000,
4287		      0x00000000, 0x00000000, 0x00000000, 0x00000000 };
4288
4289  __ Mov(r0, reinterpret_cast<uintptr_t>(src));
4290  __ Ldm(r0, WRITE_BACK, RegisterList(r2, r3));;
4291  __ Ldm(r0, WRITE_BACK, RegisterList(r4, r5));;
4292
4293  __ Mov(r1, reinterpret_cast<uintptr_t>(dst));
4294  __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
4295  __ Stm(r1, WRITE_BACK, RegisterList(r2, r3, r4, r5));
4296
4297  END();
4298
4299  RUN();
4300
4301  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 4), r0);
4302  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 8), r1);
4303
4304  ASSERT_EQUAL_32(0x12345678, r2);
4305  ASSERT_EQUAL_32(0x09abcdef, r3);
4306  ASSERT_EQUAL_32(0xc001c0de, r4);
4307  ASSERT_EQUAL_32(0xdeadbeef, r5);
4308
4309  ASSERT_EQUAL_32(0x12345678, dst[0]);
4310  ASSERT_EQUAL_32(0x09abcdef, dst[1]);
4311  ASSERT_EQUAL_32(0xc001c0de, dst[2]);
4312  ASSERT_EQUAL_32(0xdeadbeef, dst[3]);
4313  ASSERT_EQUAL_32(0x12345678, dst[4]);
4314  ASSERT_EQUAL_32(0x09abcdef, dst[5]);
4315  ASSERT_EQUAL_32(0xc001c0de, dst[6]);
4316  ASSERT_EQUAL_32(0xdeadbeef, dst[7]);
4317
4318  TEARDOWN();
4319}
4320
4321
4322TEST_A32(ldm_stm_da_ib) {
4323  SETUP();
4324
4325  START();
4326
4327  const uint32_t src1[4] = { 0x33333333, 0x44444444, 0x11111111, 0x22222222 };
4328  const uint32_t src2[4] = { 0x11111111, 0x22222222, 0x33333333, 0x44444444 };
4329
4330  uint32_t dst1[4] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
4331  uint32_t dst2[4] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
4332
4333  __ Mov(r11, reinterpret_cast<uintptr_t>(src1 + 3));
4334  __ Ldmda(r11, WRITE_BACK, RegisterList(r0, r1));
4335  __ Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3));
4336
4337  __ Mov(r10, reinterpret_cast<uintptr_t>(src2 - 1));
4338  __ Ldmib(r10, WRITE_BACK, RegisterList(r4, r5));
4339  __ Ldmib(r10, NO_WRITE_BACK, RegisterList(r6, r7));
4340
4341  __ Mov(r9, reinterpret_cast<uintptr_t>(dst1 + 3));
4342  __ Stmda(r9, WRITE_BACK, RegisterList(r0, r1));
4343  __ Stmda(r9, NO_WRITE_BACK, RegisterList(r2, r3));
4344
4345  __ Mov(r8, reinterpret_cast<uintptr_t>(dst2 - 1));
4346  __ Stmib(r8, WRITE_BACK, RegisterList(r4, r5));
4347  __ Stmib(r8, NO_WRITE_BACK, RegisterList(r6, r7));
4348
4349
4350  END();
4351
4352  RUN();
4353
4354  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src1 + 1), r11);
4355  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src2  + 1), r10);
4356  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst1 + 1), r9);
4357  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst2 + 1), r8);
4358
4359  ASSERT_EQUAL_32(0x11111111, r0);
4360  ASSERT_EQUAL_32(0x22222222, r1);
4361  ASSERT_EQUAL_32(0x33333333, r2);
4362  ASSERT_EQUAL_32(0x44444444, r3);
4363
4364  ASSERT_EQUAL_32(0x11111111, r4);
4365  ASSERT_EQUAL_32(0x22222222, r5);
4366  ASSERT_EQUAL_32(0x33333333, r6);
4367  ASSERT_EQUAL_32(0x44444444, r7);
4368
4369  ASSERT_EQUAL_32(0x33333333, dst1[0]);
4370  ASSERT_EQUAL_32(0x44444444, dst1[1]);
4371  ASSERT_EQUAL_32(0x11111111, dst1[2]);
4372  ASSERT_EQUAL_32(0x22222222, dst1[3]);
4373
4374  ASSERT_EQUAL_32(0x11111111, dst2[0]);
4375  ASSERT_EQUAL_32(0x22222222, dst2[1]);
4376  ASSERT_EQUAL_32(0x33333333, dst2[2]);
4377  ASSERT_EQUAL_32(0x44444444, dst2[3]);
4378
4379  TEARDOWN();
4380}
4381
4382
4383TEST(ldmdb_stmdb) {
4384  SETUP();
4385
4386  START();
4387
4388  const uint32_t src[6] = { 0x55555555, 0x66666666,
4389			    0x33333333, 0x44444444,
4390			    0x11111111, 0x22222222 };
4391
4392  uint32_t dst[6] = { 0x00000000, 0x00000000, 0x00000000,
4393		      0x00000000, 0x00000000, 0x00000000 };
4394
4395  __ Mov(r11, reinterpret_cast<uintptr_t>(src + 6));
4396  __ Ldmdb(r11, WRITE_BACK, RegisterList(r1, r2));
4397  __ Ldmdb(r11, WRITE_BACK, RegisterList(r3, r4));
4398  __ Ldmdb(r11, NO_WRITE_BACK, RegisterList(r5, r6));
4399
4400  __ Mov(r10, reinterpret_cast<uintptr_t>(dst + 6));
4401  __ Stmdb(r10, WRITE_BACK, RegisterList(r5, r6));
4402  __ Stmdb(r10, WRITE_BACK, RegisterList(r3, r4));
4403  __ Stmdb(r10, NO_WRITE_BACK, RegisterList(r1, r2));
4404
4405  END();
4406
4407  RUN();
4408
4409  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(src + 2), r11);
4410  ASSERT_EQUAL_32(reinterpret_cast<uintptr_t>(dst + 2), r10);
4411
4412  ASSERT_EQUAL_32(0x11111111, r1);
4413  ASSERT_EQUAL_32(0x22222222, r2);
4414  ASSERT_EQUAL_32(0x33333333, r3);
4415  ASSERT_EQUAL_32(0x44444444, r4);
4416  ASSERT_EQUAL_32(0x55555555, r5);
4417  ASSERT_EQUAL_32(0x66666666, r6);
4418
4419  ASSERT_EQUAL_32(0x11111111, dst[0]);
4420  ASSERT_EQUAL_32(0x22222222, dst[1]);
4421  ASSERT_EQUAL_32(0x33333333, dst[2]);
4422  ASSERT_EQUAL_32(0x44444444, dst[3]);
4423  ASSERT_EQUAL_32(0x55555555, dst[4]);
4424  ASSERT_EQUAL_32(0x66666666, dst[5]);
4425
4426  TEARDOWN();
4427}
4428#endif
4429
4430
4431}  // namespace aarch32
4432}  // namespace vixl
4433