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