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