• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // Copyright 2016, 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 "test-runner.h"
28  
29  #ifdef VIXL_INCLUDE_TARGET_AARCH32
30  #include "aarch32/macro-assembler-aarch32.h"
31  #endif
32  
33  #ifdef VIXL_INCLUDE_TARGET_AARCH64
34  #include "aarch64/macro-assembler-aarch64.h"
35  #endif
36  
37  #define TEST(name) TEST_(SCOPES_##name)
38  
39  #ifdef VIXL_INCLUDE_TARGET_A32
40  #define TEST_A32(name) TEST(name)
41  #else
42  // Do not add this test to the harness.
43  #define TEST_A32(name) void Test##name()
44  #endif
45  
46  #define __ masm.
47  
48  namespace vixl {
49  
50  // This file contains tests for code generation scopes.
51  
52  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(CodeBufferCheckScope_basic_32)53  TEST(CodeBufferCheckScope_basic_32) {
54    aarch32::MacroAssembler masm;
55  
56    {
57      CodeBufferCheckScope scope(&masm, aarch32::kA32InstructionSizeInBytes);
58      __ Mov(aarch32::r0, 0);
59    }
60  
61    masm.FinalizeCode();
62  }
63  #endif  // VIXL_INCLUDE_TARGET_AARCH32
64  
65  
66  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(CodeBufferCheckScope_basic_64)67  TEST(CodeBufferCheckScope_basic_64) {
68    aarch64::MacroAssembler masm;
69  
70    {
71      CodeBufferCheckScope scope(&masm, aarch64::kInstructionSize);
72      __ Mov(aarch64::x0, 0);
73    }
74  
75    masm.FinalizeCode();
76  }
77  #endif  // VIXL_INCLUDE_TARGET_AARCH64
78  
79  
80  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(CodeBufferCheckScope_assembler_use_32)81  TEST(CodeBufferCheckScope_assembler_use_32) {
82    aarch32::MacroAssembler masm;
83  
84    {
85      CodeBufferCheckScope scope(&masm, 2 * aarch32::kA32InstructionSizeInBytes);
86      __ Mov(aarch32::r0, 0);
87      __ mov(aarch32::r1, 1);
88    }
89  
90    masm.FinalizeCode();
91  }
92  #endif  // VIXL_INCLUDE_TARGET_AARCH32
93  
94  
95  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(CodeBufferCheckScope_assembler_use_64)96  TEST(CodeBufferCheckScope_assembler_use_64) {
97    aarch64::MacroAssembler masm;
98  
99    {
100      CodeBufferCheckScope scope(&masm, 2 * aarch64::kInstructionSize);
101      __ Mov(aarch64::x0, 0);
102      __ movz(aarch64::x1, 1);
103    }
104  
105    masm.FinalizeCode();
106  }
107  #endif  // VIXL_INCLUDE_TARGET_AARCH64
108  
109  
110  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(CodeBufferCheckScope_Open_32)111  TEST(CodeBufferCheckScope_Open_32) {
112    aarch32::MacroAssembler masm;
113  
114    {
115      CodeBufferCheckScope scope;
116      __ Mov(aarch32::r0, 0);
117      scope.Open(&masm, aarch32::kA32InstructionSizeInBytes);
118      __ Mov(aarch32::r1, 1);
119    }
120  
121    masm.FinalizeCode();
122  }
123  #endif  // VIXL_INCLUDE_TARGET_AARCH32
124  
125  
126  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(CodeBufferCheckScope_Open_64)127  TEST(CodeBufferCheckScope_Open_64) {
128    aarch64::MacroAssembler masm;
129  
130    {
131      CodeBufferCheckScope scope;
132      __ Mov(aarch64::x0, 0);
133      scope.Open(&masm, aarch64::kInstructionSize);
134      __ Mov(aarch64::x1, 1);
135    }
136  
137    masm.FinalizeCode();
138  }
139  #endif  // VIXL_INCLUDE_TARGET_AARCH64
140  
141  
142  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(CodeBufferCheckScope_Close_32)143  TEST(CodeBufferCheckScope_Close_32) {
144    aarch32::MacroAssembler masm;
145  
146    {
147      CodeBufferCheckScope scope(&masm, aarch32::kA32InstructionSizeInBytes);
148      __ Mov(aarch32::r0, 0);
149      scope.Close();
150      __ Mov(aarch32::r1, 1);
151    }
152  
153    masm.FinalizeCode();
154  }
155  #endif  // VIXL_INCLUDE_TARGET_AARCH32
156  
157  
158  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(CodeBufferCheckScope_Close_64)159  TEST(CodeBufferCheckScope_Close_64) {
160    aarch64::MacroAssembler masm;
161  
162    {
163      CodeBufferCheckScope scope(&masm, aarch64::kInstructionSize);
164      __ Mov(aarch64::x0, 0);
165      scope.Close();
166      __ Mov(aarch64::x1, 1);
167    }
168  
169    masm.FinalizeCode();
170  }
171  #endif  // VIXL_INCLUDE_TARGET_AARCH64
172  
173  
174  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(CodeBufferCheckScope_Open_Close_32)175  TEST(CodeBufferCheckScope_Open_Close_32) {
176    aarch32::MacroAssembler masm;
177  
178    {
179      CodeBufferCheckScope scope;
180      __ Mov(aarch32::r0, 0);
181      scope.Open(&masm, aarch32::kA32InstructionSizeInBytes);
182      __ Mov(aarch32::r1, 1);
183      scope.Close();
184      __ Mov(aarch32::r2, 2);
185    }
186  
187    masm.FinalizeCode();
188  }
189  #endif  // VIXL_INCLUDE_TARGET_AARCH32
190  
191  
192  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(CodeBufferCheckScope_Open_Close_64)193  TEST(CodeBufferCheckScope_Open_Close_64) {
194    aarch64::MacroAssembler masm;
195  
196    {
197      CodeBufferCheckScope scope;
198      __ Mov(aarch64::x0, 0);
199      scope.Open(&masm, aarch64::kInstructionSize);
200      __ Mov(aarch64::x1, 1);
201      scope.Close();
202      __ Mov(aarch64::x2, 2);
203    }
204  
205    masm.FinalizeCode();
206  }
207  #endif  // VIXL_INCLUDE_TARGET_AARCH64
208  
209  
210  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(EmissionCheckScope_basic_32)211  TEST(EmissionCheckScope_basic_32) {
212    aarch32::MacroAssembler masm;
213  
214    {
215      EmissionCheckScope scope(&masm, aarch32::kA32InstructionSizeInBytes);
216      __ Mov(aarch32::r0, 0);
217    }
218  
219    masm.FinalizeCode();
220  }
221  #endif  // VIXL_INCLUDE_TARGET_AARCH32
222  
223  
224  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(EmissionCheckScope_basic_64)225  TEST(EmissionCheckScope_basic_64) {
226    aarch64::MacroAssembler masm;
227  
228    {
229      EmissionCheckScope scope(&masm, aarch64::kInstructionSize);
230      __ Mov(aarch64::x0, 0);
231    }
232  
233    masm.FinalizeCode();
234  }
235  #endif  // VIXL_INCLUDE_TARGET_AARCH64
236  
237  
238  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(EmissionCheckScope_Open_32)239  TEST(EmissionCheckScope_Open_32) {
240    aarch32::MacroAssembler masm;
241  
242    {
243      EmissionCheckScope scope;
244      __ Mov(aarch32::r0, 0);
245      scope.Open(&masm, aarch32::kA32InstructionSizeInBytes);
246      __ Mov(aarch32::r1, 1);
247    }
248  
249    masm.FinalizeCode();
250  }
251  #endif  // VIXL_INCLUDE_TARGET_AARCH32
252  
253  
254  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(EmissionCheckScope_Open_64)255  TEST(EmissionCheckScope_Open_64) {
256    aarch64::MacroAssembler masm;
257  
258    {
259      EmissionCheckScope scope;
260      __ Mov(aarch64::x0, 0);
261      scope.Open(&masm, aarch64::kInstructionSize);
262      __ Mov(aarch64::x1, 1);
263    }
264  
265    masm.FinalizeCode();
266  }
267  #endif  // VIXL_INCLUDE_TARGET_AARCH64
268  
269  
270  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(EmissionCheckScope_Close_32)271  TEST(EmissionCheckScope_Close_32) {
272    aarch32::MacroAssembler masm;
273  
274    {
275      EmissionCheckScope scope(&masm, aarch32::kA32InstructionSizeInBytes);
276      __ Mov(aarch32::r0, 0);
277      scope.Close();
278      __ Mov(aarch32::r1, 1);
279    }
280  
281    masm.FinalizeCode();
282  }
283  #endif  // VIXL_INCLUDE_TARGET_AARCH32
284  
285  
286  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(EmissionCheckScope_Close_64)287  TEST(EmissionCheckScope_Close_64) {
288    aarch64::MacroAssembler masm;
289  
290    {
291      EmissionCheckScope scope(&masm, aarch64::kInstructionSize);
292      __ Mov(aarch64::x0, 0);
293      scope.Close();
294      __ Mov(aarch64::x1, 1);
295    }
296  
297    masm.FinalizeCode();
298  }
299  #endif  // VIXL_INCLUDE_TARGET_AARCH64
300  
301  
302  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST(EmissionCheckScope_Open_Close_32)303  TEST(EmissionCheckScope_Open_Close_32) {
304    aarch32::MacroAssembler masm;
305  
306    {
307      EmissionCheckScope scope;
308      __ Mov(aarch32::r0, 0);
309      scope.Open(&masm, aarch32::kA32InstructionSizeInBytes);
310      __ Mov(aarch32::r1, 1);
311      scope.Close();
312      __ Mov(aarch32::r2, 2);
313    }
314  
315    masm.FinalizeCode();
316  }
317  #endif  // VIXL_INCLUDE_TARGET_AARCH32
318  
319  
320  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(EmissionCheckScope_Open_Close_64)321  TEST(EmissionCheckScope_Open_Close_64) {
322    aarch64::MacroAssembler masm;
323  
324    {
325      EmissionCheckScope scope;
326      __ Mov(aarch64::x0, 0);
327      scope.Open(&masm, aarch64::kInstructionSize);
328      __ Mov(aarch64::x1, 1);
329      scope.Close();
330      __ Mov(aarch64::x2, 2);
331    }
332  
333    masm.FinalizeCode();
334  }
335  #endif  // VIXL_INCLUDE_TARGET_AARCH64
336  
337  
338  #ifdef VIXL_INCLUDE_TARGET_AARCH32
339  
340  #define ASSERT_LITERAL_POOL_SIZE_32(expected) \
341    VIXL_CHECK((expected) == masm.GetLiteralPoolSize())
342  
TEST_A32(EmissionCheckScope_emit_pool_32)343  TEST_A32(EmissionCheckScope_emit_pool_32) {
344    aarch32::MacroAssembler masm;
345  
346    // Make sure the pool is empty;
347    masm.EmitLiteralPool(aarch32::MacroAssembler::kBranchRequired);
348    ASSERT_LITERAL_POOL_SIZE_32(0);
349  
350    __ Ldrd(aarch32::r0, aarch32::r1, 0x1234567890abcdef);
351    ASSERT_LITERAL_POOL_SIZE_32(8);
352  
353    const int kLdrdRange = 255;
354    const int kLessThanLdrdRange = 100;
355  
356    {
357      // Check that opening the scope with a reserved space well below the limit
358      // at which can generate the literal pool does not force the emission of
359      // the pool.
360      EmissionCheckScope scope(&masm,
361                               kLessThanLdrdRange,
362                               EmissionCheckScope::kMaximumSize);
363      ASSERT_LITERAL_POOL_SIZE_32(8);
364    }
365  
366    {
367      // Check that the scope forces emission of the pool if necessary.
368      EmissionCheckScope scope(&masm,
369                               kLdrdRange + 1,
370                               EmissionCheckScope::kMaximumSize);
371      ASSERT_LITERAL_POOL_SIZE_32(0);
372    }
373  
374    masm.FinalizeCode();
375  }
376  #endif  // VIXL_INCLUDE_TARGET_AARCH32
377  
378  
379  #ifdef VIXL_INCLUDE_TARGET_AARCH64
380  
381  #define ASSERT_LITERAL_POOL_SIZE_64(expected)          \
382    VIXL_CHECK((expected + aarch64::kInstructionSize) == \
383               masm.GetLiteralPoolSize())
384  
TEST(EmissionCheckScope_emit_pool_64)385  TEST(EmissionCheckScope_emit_pool_64) {
386    aarch64::MacroAssembler masm;
387  
388    // Make sure the pool is empty;
389    masm.EmitLiteralPool(aarch64::LiteralPool::kBranchRequired);
390    ASSERT_LITERAL_POOL_SIZE_64(0);
391  
392    __ Ldr(aarch64::x0, 0x1234567890abcdef);
393    ASSERT_LITERAL_POOL_SIZE_64(8);
394  
395    {
396      // Check that opening the scope with a reserved space well below the limit
397      // at which can generate the literal pool does not force the emission of
398      // the pool.
399      EmissionCheckScope scope(&masm,
400                               10 * aarch64::kInstructionSize,
401                               EmissionCheckScope::kMaximumSize);
402      ASSERT_LITERAL_POOL_SIZE_64(8);
403    }
404  
405    {
406      // Check that the scope forces emission of the pool if necessary.
407      EmissionCheckScope scope(&masm,
408                               aarch64::kMaxLoadLiteralRange + 1,
409                               EmissionCheckScope::kMaximumSize);
410      ASSERT_LITERAL_POOL_SIZE_64(0);
411    }
412  
413    masm.FinalizeCode();
414  }
415  #endif  // VIXL_INCLUDE_TARGET_AARCH64
416  
417  
418  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST_A32(EmissionCheckScope_emit_pool_on_Open_32)419  TEST_A32(EmissionCheckScope_emit_pool_on_Open_32) {
420    aarch32::MacroAssembler masm;
421  
422    // Make sure the pool is empty;
423    masm.EmitLiteralPool(aarch32::MacroAssembler::kBranchRequired);
424    ASSERT_LITERAL_POOL_SIZE_32(0);
425  
426    __ Ldrd(aarch32::r0, aarch32::r1, 0x1234567890abcdef);
427    ASSERT_LITERAL_POOL_SIZE_32(8);
428  
429    const int kLdrdRange = 255;
430    const int kLessThanLdrdRange = 100;
431  
432    {
433      // Check that opening the scope with a reserved space well below the limit
434      // at which can generate the literal pool does not force the emission of
435      // the pool.
436      EmissionCheckScope scope(&masm,
437                               kLessThanLdrdRange,
438                               EmissionCheckScope::kMaximumSize);
439      ASSERT_LITERAL_POOL_SIZE_32(8);
440    }
441  
442    {
443      // Check that the scope forces emission of the pool if necessary.
444      EmissionCheckScope scope(&masm,
445                               kLdrdRange + 1,
446                               EmissionCheckScope::kMaximumSize);
447      ASSERT_LITERAL_POOL_SIZE_32(0);
448    }
449  
450    masm.FinalizeCode();
451  }
452  #endif  // VIXL_INCLUDE_TARGET_AARCH32
453  
454  
455  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(EmissionCheckScope_emit_pool_on_Open_64)456  TEST(EmissionCheckScope_emit_pool_on_Open_64) {
457    aarch64::MacroAssembler masm;
458  
459    // Make sure the pool is empty;
460    masm.EmitLiteralPool(aarch64::LiteralPool::kBranchRequired);
461    ASSERT_LITERAL_POOL_SIZE_64(0);
462  
463    __ Ldr(aarch64::x0, 0x1234567890abcdef);
464    ASSERT_LITERAL_POOL_SIZE_64(8);
465  
466    {
467      // Check that opening the scope with a reserved space well below the limit
468      // at which can generate the literal pool does not force the emission of
469      // the pool.
470      EmissionCheckScope scope;
471      scope.Open(&masm,
472                 10 * aarch64::kInstructionSize,
473                 EmissionCheckScope::kMaximumSize);
474      ASSERT_LITERAL_POOL_SIZE_64(8);
475    }
476  
477    {
478      // Check that the scope forces emission of the pool if necessary.
479      EmissionCheckScope scope;
480      scope.Open(&masm,
481                 aarch64::kMaxLoadLiteralRange + 1,
482                 EmissionCheckScope::kMaximumSize);
483      ASSERT_LITERAL_POOL_SIZE_64(0);
484    }
485  
486    masm.FinalizeCode();
487  }
488  #endif  // VIXL_INCLUDE_TARGET_AARCH64
489  
490  
491  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST_A32(ExactAssemblyScope_basic_32)492  TEST_A32(ExactAssemblyScope_basic_32) {
493    aarch32::MacroAssembler masm;
494  
495    {
496      ExactAssemblyScope scope(&masm, aarch32::kA32InstructionSizeInBytes);
497      __ nop();
498    }
499  
500    masm.FinalizeCode();
501  }
502  #endif  // VIXL_INCLUDE_TARGET_AARCH32
503  
504  
505  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(ExactAssemblyScope_basic_64)506  TEST(ExactAssemblyScope_basic_64) {
507    aarch64::MacroAssembler masm;
508  
509    {
510      ExactAssemblyScope scope(&masm, aarch64::kInstructionSize);
511      __ nop();
512    }
513  
514    masm.FinalizeCode();
515  }
516  #endif  // VIXL_INCLUDE_TARGET_AARCH64
517  
518  
519  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST_A32(ExactAssemblyScope_Open_32)520  TEST_A32(ExactAssemblyScope_Open_32) {
521    aarch32::MacroAssembler masm;
522  
523    {
524      ExactAssemblyScope scope;
525      __ Mov(aarch32::r0, 0);
526      scope.Open(&masm, aarch32::kA32InstructionSizeInBytes);
527      __ mov(aarch32::r1, 1);
528    }
529  
530    masm.FinalizeCode();
531  }
532  #endif  // VIXL_INCLUDE_TARGET_AARCH32
533  
534  
535  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(ExactAssemblyScope_Open_64)536  TEST(ExactAssemblyScope_Open_64) {
537    aarch64::MacroAssembler masm;
538  
539    {
540      ExactAssemblyScope scope;
541      __ Mov(aarch64::x0, 0);
542      scope.Open(&masm, aarch64::kInstructionSize);
543      __ movz(aarch64::x1, 1);
544    }
545  
546    masm.FinalizeCode();
547  }
548  #endif  // VIXL_INCLUDE_TARGET_AARCH64
549  
550  
551  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST_A32(ExactAssemblyScope_Close_32)552  TEST_A32(ExactAssemblyScope_Close_32) {
553    aarch32::MacroAssembler masm;
554  
555    {
556      ExactAssemblyScope scope(&masm, aarch32::kA32InstructionSizeInBytes);
557      __ mov(aarch32::r0, 0);
558      scope.Close();
559      __ Mov(aarch32::r1, 1);
560    }
561  
562    masm.FinalizeCode();
563  }
564  #endif  // VIXL_INCLUDE_TARGET_AARCH32
565  
566  
567  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(ExactAssemblyScope_Close_64)568  TEST(ExactAssemblyScope_Close_64) {
569    aarch64::MacroAssembler masm;
570  
571    {
572      ExactAssemblyScope scope(&masm, aarch64::kInstructionSize);
573      __ movz(aarch64::x0, 0);
574      scope.Close();
575      __ Mov(aarch64::x1, 1);
576    }
577  
578    masm.FinalizeCode();
579  }
580  #endif  // VIXL_INCLUDE_TARGET_AARCH64
581  
582  
583  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST_A32(ExactAssemblyScope_Open_Close_32)584  TEST_A32(ExactAssemblyScope_Open_Close_32) {
585    aarch32::MacroAssembler masm;
586  
587    {
588      ExactAssemblyScope scope;
589      __ Mov(aarch32::r0, 0);
590      scope.Open(&masm, aarch32::kA32InstructionSizeInBytes);
591      __ mov(aarch32::r1, 1);
592      scope.Close();
593      __ Mov(aarch32::r2, 2);
594    }
595  
596    masm.FinalizeCode();
597  }
598  #endif  // VIXL_INCLUDE_TARGET_AARCH32
599  
600  
601  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(ExactAssemblyScope_Open_Close_64)602  TEST(ExactAssemblyScope_Open_Close_64) {
603    aarch64::MacroAssembler masm;
604  
605    {
606      ExactAssemblyScope scope;
607      __ Mov(aarch64::x0, 0);
608      scope.Open(&masm, aarch64::kInstructionSize);
609      __ movz(aarch64::x1, 1);
610      scope.Close();
611      __ Mov(aarch64::x2, 2);
612    }
613  
614    masm.FinalizeCode();
615  }
616  #endif  // VIXL_INCLUDE_TARGET_AARCH64
617  
618  
619  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST_A32(ExactAssemblyScope_32)620  TEST_A32(ExactAssemblyScope_32) {
621    aarch32::MacroAssembler masm;
622  
623    // By default macro instructions are allowed.
624    VIXL_CHECK(!masm.ArePoolsBlocked());
625    VIXL_ASSERT(!masm.AllowAssembler());
626    VIXL_ASSERT(masm.AllowMacroInstructions());
627    {
628      ExactAssemblyScope scope1(&masm, 2 * aarch32::kA32InstructionSizeInBytes);
629      VIXL_CHECK(masm.ArePoolsBlocked());
630      VIXL_ASSERT(masm.AllowAssembler());
631      VIXL_ASSERT(!masm.AllowMacroInstructions());
632      __ nop();
633      {
634        ExactAssemblyScope scope2(&masm, 1 * aarch32::kA32InstructionSizeInBytes);
635        VIXL_CHECK(masm.ArePoolsBlocked());
636        VIXL_ASSERT(masm.AllowAssembler());
637        VIXL_ASSERT(!masm.AllowMacroInstructions());
638        __ nop();
639      }
640      VIXL_CHECK(masm.ArePoolsBlocked());
641      VIXL_ASSERT(masm.AllowAssembler());
642      VIXL_ASSERT(!masm.AllowMacroInstructions());
643    }
644    VIXL_CHECK(!masm.ArePoolsBlocked());
645    VIXL_ASSERT(!masm.AllowAssembler());
646    VIXL_ASSERT(masm.AllowMacroInstructions());
647  
648    {
649      ExactAssemblyScope scope(&masm, 2 * aarch32::kA32InstructionSizeInBytes);
650      __ add(aarch32::r0, aarch32::r0, aarch32::r0);
651      __ sub(aarch32::r0, aarch32::r0, aarch32::r0);
652    }
653  
654    masm.FinalizeCode();
655  }
656  #endif  // VIXL_INCLUDE_TARGET_AARCH32
657  
658  
659  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(ExactAssemblyScope_64)660  TEST(ExactAssemblyScope_64) {
661    aarch64::MacroAssembler masm;
662  
663    // By default macro instructions are allowed.
664    VIXL_CHECK(!masm.ArePoolsBlocked());
665    VIXL_ASSERT(!masm.AllowAssembler());
666    VIXL_ASSERT(masm.AllowMacroInstructions());
667    {
668      ExactAssemblyScope scope1(&masm, 2 * aarch64::kInstructionSize);
669      VIXL_CHECK(masm.ArePoolsBlocked());
670      VIXL_ASSERT(masm.AllowAssembler());
671      VIXL_ASSERT(!masm.AllowMacroInstructions());
672      __ nop();
673      {
674        ExactAssemblyScope scope2(&masm, 1 * aarch64::kInstructionSize);
675        VIXL_CHECK(masm.ArePoolsBlocked());
676        VIXL_ASSERT(masm.AllowAssembler());
677        VIXL_ASSERT(!masm.AllowMacroInstructions());
678        __ nop();
679      }
680      VIXL_CHECK(masm.ArePoolsBlocked());
681      VIXL_ASSERT(masm.AllowAssembler());
682      VIXL_ASSERT(!masm.AllowMacroInstructions());
683    }
684    VIXL_CHECK(!masm.ArePoolsBlocked());
685    VIXL_ASSERT(!masm.AllowAssembler());
686    VIXL_ASSERT(masm.AllowMacroInstructions());
687  
688    {
689      ExactAssemblyScope scope(&masm, 2 * aarch64::kInstructionSize);
690      __ add(aarch64::x0, aarch64::x0, aarch64::x0);
691      __ sub(aarch64::x0, aarch64::x0, aarch64::x0);
692    }
693  
694    masm.FinalizeCode();
695  }
696  #endif  // VIXL_INCLUDE_TARGET_AARCH64
697  
698  
699  #ifdef VIXL_INCLUDE_TARGET_AARCH32
TEST_A32(ExactAssemblyScope_scope_with_pools_32)700  TEST_A32(ExactAssemblyScope_scope_with_pools_32) {
701    aarch32::MacroAssembler masm;
702  
703    ASSERT_LITERAL_POOL_SIZE_32(0);
704  
705    __ Ldrd(aarch32::r0, aarch32::r1, 0x1234567890abcdef);
706  
707    ASSERT_LITERAL_POOL_SIZE_32(8);
708  
709    const int32_t kLdrdRange = 255;
710    const int32_t n_nops = (kLdrdRange / aarch32::kA32InstructionSizeInBytes) + 1;
711    {
712      // The literal pool should be generated when opening this scope, as
713      // otherwise the `Ldrd` will run out of range when we generate the `nop`
714      // instructions below.
715      ExactAssemblyScope scope(&masm,
716                               n_nops * aarch32::kA32InstructionSizeInBytes);
717  
718      // Although it must be, we do not check that the literal pool size is zero
719      // here, because we want this regression test to fail while or after we
720      // generate the nops.
721  
722      for (int32_t i = 0; i < n_nops; ++i) {
723        __ nop();
724      }
725    }
726  
727    ASSERT_LITERAL_POOL_SIZE_32(0);
728  
729    masm.FinalizeCode();
730  }
731  #endif  // VIXL_INCLUDE_TARGET_AARCH32
732  
733  
734  #ifdef VIXL_INCLUDE_TARGET_AARCH64
TEST(ExactAssemblyScope_scope_with_pools_64)735  TEST(ExactAssemblyScope_scope_with_pools_64) {
736    aarch64::MacroAssembler masm;
737  
738    ASSERT_LITERAL_POOL_SIZE_64(0);
739  
740    __ Ldr(aarch64::x10, 0x1234567890abcdef);
741  
742    ASSERT_LITERAL_POOL_SIZE_64(8);
743  
744    const int64_t n_nops =
745        aarch64::kMaxLoadLiteralRange / aarch64::kInstructionSize;
746    {
747      // The literal pool should be generated when opening this scope, as
748      // otherwise the `Ldr` will run out of range when we generate the `nop`
749      // instructions below.
750      ExactAssemblyScope scope(&masm, n_nops * aarch64::kInstructionSize);
751  
752      // Although it must be, we do not check that the literal pool size is zero
753      // here, because we want this regression test to fail while or after we
754      // generate the nops.
755  
756      for (int64_t i = 0; i < n_nops; ++i) {
757        __ nop();
758      }
759    }
760  
761    ASSERT_LITERAL_POOL_SIZE_64(0);
762  
763    masm.FinalizeCode();
764  }
765  #endif  // VIXL_INCLUDE_TARGET_AARCH64
766  
767  
768  }  // namespace vixl
769