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