• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include <list>
28 #include <sstream>
29 #include <string>
30 
31 #include "test-runner.h"
32 #include "test-utils.h"
33 
34 #include "aarch32/disasm-aarch32.h"
35 #include "aarch32/macro-assembler-aarch32.h"
36 
37 #ifdef VIXL_NEGATIVE_TESTING
38 #include <stdexcept>
39 #endif
40 
41 namespace vixl {
42 namespace aarch32 {
43 
44 #define __ masm.
45 #define TEST(name) TEST_(AARCH32_DISASM_##name)
46 
47 #ifdef VIXL_INCLUDE_TARGET_T32
48 #define TEST_T32(name) TEST_(AARCH32_DISASM_##name)
49 #else
50 #define TEST_T32(name) void Test##name()
51 #endif
52 
53 #ifdef VIXL_INCLUDE_TARGET_A32
54 #define TEST_A32(name) TEST_(AARCH32_DISASM_##name)
55 #else
56 #define TEST_A32(name) void Test##name()
57 #endif
58 
59 #define BUF_SIZE (4096)
60 
61 #define SETUP() MacroAssembler masm(BUF_SIZE);
62 
63 #define CLEANUP()
64 
65 #ifdef VIXL_NEGATIVE_TESTING
66 #define START_COMPARE() \
67   {                     \
68     try {               \
69       int32_t start = masm.GetCursorOffset();
70 
71 #define END_COMPARE_CHECK_SIZE(EXP, SIZE)                       \
72   int32_t end = masm.GetCursorOffset();                         \
73   masm.FinalizeCode();                                          \
74   std::ostringstream ss;                                        \
75   TestDisassembler disassembler(ss, 0);                         \
76   if (masm.IsUsingT32()) {                                      \
77     disassembler.DisassembleT32(*masm.GetBuffer(), start, end); \
78   } else {                                                      \
79     disassembler.DisassembleA32(*masm.GetBuffer(), start, end); \
80   }                                                             \
81   masm.GetBuffer()->Reset();                                    \
82   if (Test::disassemble()) {                                    \
83     printf("----\n");                                           \
84     printf("%s", ss.str().c_str());                             \
85   }                                                             \
86   if (std::string(EXP) != ss.str()) {                           \
87     printf("\n%s:%d:%s\nFound:\n%sExpected:\n%s",               \
88            __FILE__,                                            \
89            __LINE__,                                            \
90            masm.IsUsingT32() ? "T32" : "A32",                   \
91            ss.str().c_str(),                                    \
92            EXP);                                                \
93     abort();                                                    \
94   }                                                             \
95   if ((SIZE) != -1 && ((end - start) != (SIZE))) {              \
96     printf("\nExpected %d bits, found %d bits\n",               \
97            8 * (SIZE),                                          \
98            8 * (end - start));                                  \
99     abort();                                                    \
100   }                                                             \
101   }                                                             \
102   catch (const std::runtime_error& e) {                         \
103     const char* msg = e.what();                                 \
104     printf("\n%s:%d:%s\nFound:\n%sExpected:\n%s",               \
105            __FILE__,                                            \
106            __LINE__,                                            \
107            masm.IsUsingT32() ? "T32" : "A32",                   \
108            msg,                                                 \
109            EXP);                                                \
110     abort();                                                    \
111   }                                                             \
112   }
113 #else
114 #define START_COMPARE() \
115   {                     \
116     int32_t start = masm.GetCursorOffset();
117 
118 #define END_COMPARE_CHECK_SIZE(EXP, SIZE)                       \
119   int32_t end = masm.GetCursorOffset();                         \
120   masm.FinalizeCode();                                          \
121   std::ostringstream ss;                                        \
122   TestDisassembler disassembler(ss, 0);                         \
123   if (masm.IsUsingT32()) {                                      \
124     disassembler.DisassembleT32(*masm.GetBuffer(), start, end); \
125   } else {                                                      \
126     disassembler.DisassembleA32(*masm.GetBuffer(), start, end); \
127   }                                                             \
128   masm.GetBuffer()->Reset();                                    \
129   if (Test::disassemble()) {                                    \
130     printf("----\n");                                           \
131     printf("%s", ss.str().c_str());                             \
132   }                                                             \
133   if (std::string(EXP) != ss.str()) {                           \
134     printf("\n%s:%d:%s\nFound:\n%sExpected:\n%s",               \
135            __FILE__,                                            \
136            __LINE__,                                            \
137            masm.IsUsingT32() ? "T32" : "A32",                   \
138            ss.str().c_str(),                                    \
139            EXP);                                                \
140     abort();                                                    \
141   }                                                             \
142   if ((SIZE) != -1 && ((end - start) != (SIZE))) {              \
143     printf("\nExpected %d bits, found %d bits\n",               \
144            8 * (SIZE),                                          \
145            8 * (end - start));                                  \
146     abort();                                                    \
147   }                                                             \
148   }
149 #endif
150 
151 #define END_COMPARE(EXP) END_COMPARE_CHECK_SIZE(EXP, -1)
152 
153 #ifdef VIXL_INCLUDE_TARGET_A32
154 #define COMPARE_A32(ASM, EXP) \
155   masm.UseA32();              \
156   START_COMPARE()             \
157   masm.ASM;                   \
158   END_COMPARE(EXP)
159 #else
160 #define COMPARE_A32(ASM, EXP)
161 #endif
162 
163 #ifdef VIXL_INCLUDE_TARGET_T32
164 #define COMPARE_T32(ASM, EXP) \
165   masm.UseT32();              \
166   START_COMPARE()             \
167   masm.ASM;                   \
168   END_COMPARE(EXP)
169 #else
170 #define COMPARE_T32(ASM, EXP)
171 #endif
172 
173 #ifdef VIXL_INCLUDE_TARGET_T32
174 #define COMPARE_T32_CHECK_SIZE(ASM, EXP, SIZE) \
175   masm.UseT32();                               \
176   START_COMPARE()                              \
177   masm.ASM;                                    \
178   END_COMPARE_CHECK_SIZE(EXP, SIZE)
179 #else
180 #define COMPARE_T32_CHECK_SIZE(ASM, EXP, SIZE)
181 #endif
182 
183 #define COMPARE_BOTH(ASM, EXP) \
184   COMPARE_A32(ASM, EXP)        \
185   COMPARE_T32(ASM, EXP)
186 
187 #ifdef VIXL_NEGATIVE_TESTING
188 #define NEGATIVE_TEST(ASM, EXP, TEMPORARILY_ACCEPTED)                          \
189   {                                                                            \
190     try {                                                                      \
191       int32_t start = masm.GetCursorOffset();                                  \
192       ASM int32_t end = masm.GetCursorOffset();                                \
193       masm.FinalizeCode();                                                     \
194       if (!TEMPORARILY_ACCEPTED) {                                             \
195         std::ostringstream ss;                                                 \
196         PrintDisassembler disassembler(ss, 0);                                 \
197         if (masm.IsUsingT32()) {                                               \
198           disassembler.DisassembleT32Buffer(masm.GetBuffer()                   \
199                                                 ->GetOffsetAddress<uint16_t*>( \
200                                                     start),                    \
201                                             end);                              \
202         } else {                                                               \
203           disassembler.DisassembleA32Buffer(masm.GetBuffer()                   \
204                                                 ->GetOffsetAddress<uint32_t*>( \
205                                                     start),                    \
206                                             end);                              \
207         }                                                                      \
208         printf("\n%s:%d:%s\nNo exception raised.\n",                           \
209                __FILE__,                                                       \
210                __LINE__,                                                       \
211                masm.IsUsingT32() ? "T32" : "A32");                             \
212         printf("Found:\n%sExpected:\n%s", ss.str().c_str(), EXP);              \
213         abort();                                                               \
214       }                                                                        \
215     } catch (const std::runtime_error& e) {                                    \
216       const char* msg = e.what();                                              \
217       size_t exp_len = strlen(EXP);                                            \
218       if (TEMPORARILY_ACCEPTED) {                                              \
219         printf(                                                                \
220             "\nNegative MacroAssembler test that was temporarily "             \
221             "assembling a deprecated or unpredictable instruction is now "     \
222             "correctly raising an exception. Please update the "               \
223             "test to reflect this.\n");                                        \
224         printf("at: %s:%d:%s\n",                                               \
225                __FILE__,                                                       \
226                __LINE__,                                                       \
227                masm.IsUsingT32() ? "T32" : "A32");                             \
228         abort();                                                               \
229       } else if (std::strncmp(EXP, msg, exp_len) != 0) {                       \
230         printf("\n%s:%d:%s\nFound:\n%sExpected:\n%s...",                       \
231                __FILE__,                                                       \
232                __LINE__,                                                       \
233                masm.IsUsingT32() ? "T32" : "A32",                              \
234                msg,                                                            \
235                EXP);                                                           \
236         abort();                                                               \
237       }                                                                        \
238     }                                                                          \
239   }
240 
241 #ifdef VIXL_INCLUDE_TARGET_A32
242 #define MUST_FAIL_TEST_A32(ASM, EXP)       \
243   masm.UseA32();                           \
244   NEGATIVE_TEST({ masm.ASM; }, EXP, false) \
245   masm.GetBuffer()->Reset();
246 #else
247 #define MUST_FAIL_TEST_A32(ASM, EXP)
248 #endif
249 
250 #ifdef VIXL_INCLUDE_TARGET_T32
251 #define MUST_FAIL_TEST_T32(ASM, EXP)       \
252   masm.UseT32();                           \
253   NEGATIVE_TEST({ masm.ASM; }, EXP, false) \
254   masm.GetBuffer()->Reset();
255 #else
256 #define MUST_FAIL_TEST_T32(ASM, EXP)
257 #endif
258 
259 #define MUST_FAIL_TEST_BOTH(ASM, EXP) \
260   MUST_FAIL_TEST_A32(ASM, EXP)        \
261   MUST_FAIL_TEST_T32(ASM, EXP)
262 
263 #ifdef VIXL_INCLUDE_TARGET_A32
264 #define MUST_FAIL_TEST_A32_BLOCK(ASM, EXP) \
265   masm.UseA32();                           \
266   NEGATIVE_TEST(ASM, EXP, false)           \
267   masm.GetBuffer()->Reset();
268 #else
269 #define MUST_FAIL_TEST_A32_BLOCK(ASM, EXP)
270 #endif
271 
272 #ifdef VIXL_INCLUDE_TARGET_T32
273 #define MUST_FAIL_TEST_T32_BLOCK(ASM, EXP) \
274   masm.UseT32();                           \
275   NEGATIVE_TEST(ASM, EXP, false)           \
276   masm.GetBuffer()->Reset();
277 #else
278 #define MUST_FAIL_TEST_T32_BLOCK(ASM, EXP)
279 #endif
280 
281 #define MUST_FAIL_TEST_BOTH_BLOCK(ASM, EXP) \
282   MUST_FAIL_TEST_A32_BLOCK(ASM, EXP)        \
283   MUST_FAIL_TEST_T32_BLOCK(ASM, EXP)
284 #else
285 // Skip negative tests.
286 #define MUST_FAIL_TEST_A32(ASM, EXP)                         \
287   printf(                                                    \
288       "Skipping negative tests. To enable them, build with " \
289       "'negative_testing=on'.\n");
290 #define MUST_FAIL_TEST_T32(ASM, EXP)                         \
291   printf(                                                    \
292       "Skipping negative tests. To enable them, build with " \
293       "'negative_testing=on'.\n");
294 #define MUST_FAIL_TEST_BOTH(ASM, EXP)                        \
295   printf(                                                    \
296       "Skipping negative tests. To enable them, build with " \
297       "'negative_testing=on'.\n");
298 #define MUST_FAIL_TEST_A32_BLOCK(ASM, EXP)                   \
299   printf(                                                    \
300       "Skipping negative tests. To enable them, build with " \
301       "'negative_testing=on'.\n");
302 #define MUST_FAIL_TEST_T32_BLOCK(ASM, EXP)                   \
303   printf(                                                    \
304       "Skipping negative tests. To enable them, build with " \
305       "'negative_testing=on'.\n");
306 #define MUST_FAIL_TEST_BOTH_BLOCK(ASM, EXP)                  \
307   printf(                                                    \
308       "Skipping negative tests. To enable them, build with " \
309       "'negative_testing=on'.\n");
310 #endif
311 
312 #ifdef VIXL_NEGATIVE_TESTING
313 #ifdef VIXL_INCLUDE_TARGET_A32
314 #define SHOULD_FAIL_TEST_A32(ASM)        \
315   masm.UseA32();                         \
316   NEGATIVE_TEST({ masm.ASM; }, "", true) \
317   masm.GetBuffer()->Reset();
318 #else
319 #define SHOULD_FAIL_TEST_A32(ASM)
320 #endif
321 
322 #ifdef VIXL_INCLUDE_TARGET_T32
323 #define SHOULD_FAIL_TEST_T32(ASM)        \
324   masm.UseT32();                         \
325   NEGATIVE_TEST({ masm.ASM; }, "", true) \
326   masm.GetBuffer()->Reset();
327 #else
328 #define SHOULD_FAIL_TEST_T32(ASM)
329 #endif
330 
331 #define SHOULD_FAIL_TEST_BOTH(ASM) \
332   SHOULD_FAIL_TEST_A32(ASM)        \
333   SHOULD_FAIL_TEST_T32(ASM)
334 #else
335 #define SHOULD_FAIL_TEST_A32(ASM)                            \
336   printf(                                                    \
337       "Skipping negative tests. To enable them, build with " \
338       "'negative_testing=on'.\n");
339 #define SHOULD_FAIL_TEST_T32(ASM)                            \
340   printf(                                                    \
341       "Skipping negative tests. To enable them, build with " \
342       "'negative_testing=on'.\n");
343 #define SHOULD_FAIL_TEST_BOTH(ASM)                           \
344   printf(                                                    \
345       "Skipping negative tests. To enable them, build with " \
346       "'negative_testing=on'.\n");
347 #endif
348 
349 class TestDisassembler : public PrintDisassembler {
350  public:
TestDisassembler(std::ostream & os,uint32_t program_counter)351   TestDisassembler(std::ostream& os,
352                    uint32_t program_counter)  // NOLINT(runtime/references)
353       : PrintDisassembler(os, program_counter) {}
354 
PrintCodeAddress(uint32_t code_address)355   virtual void PrintCodeAddress(uint32_t code_address) VIXL_OVERRIDE {
356     USE(code_address);
357   }
358 
PrintOpcode16(uint32_t opcode)359   virtual void PrintOpcode16(uint32_t opcode) VIXL_OVERRIDE { USE(opcode); }
360 
PrintOpcode32(uint32_t opcode)361   virtual void PrintOpcode32(uint32_t opcode) VIXL_OVERRIDE { USE(opcode); }
362 
DisassembleA32(const CodeBuffer & buffer,ptrdiff_t start,ptrdiff_t end)363   void DisassembleA32(const CodeBuffer& buffer,
364                       ptrdiff_t start,
365                       ptrdiff_t end) {
366     DisassembleA32Buffer(buffer.GetOffsetAddress<const uint32_t*>(start),
367                          end - start);
368   }
369 
DisassembleT32(const CodeBuffer & buffer,ptrdiff_t start,ptrdiff_t end)370   void DisassembleT32(const CodeBuffer& buffer,
371                       ptrdiff_t start,
372                       ptrdiff_t end) {
373     DisassembleT32Buffer(buffer.GetOffsetAddress<const uint16_t*>(start),
374                          end - start);
375   }
376 };
377 
378 
TEST_T32(t32_disassembler_limit1)379 TEST_T32(t32_disassembler_limit1) {
380   SETUP();
381 
382   masm.UseT32();
383   START_COMPARE()
384   masm.Add(r9, r10, r11);
385   masm.GetBuffer()->Emit16(kLowestT32_32Opcode >> 16);
386   END_COMPARE(
387       "add r9, r10, r11\n"
388       "?\n");
389 
390   CLEANUP();
391 }
392 
393 
TEST_T32(t32_disassembler_limit2)394 TEST_T32(t32_disassembler_limit2) {
395   SETUP();
396 
397   masm.UseT32();
398   START_COMPARE()
399   masm.Add(r9, r10, r11);
400   masm.Add(r0, r0, r1);
401   END_COMPARE(
402       "add r9, r10, r11\n"
403       "add r0, r1\n");
404 
405   CLEANUP();
406 }
407 
408 
TEST(macro_assembler_orn)409 TEST(macro_assembler_orn) {
410   SETUP();
411 
412   // - Identities.
413 
414   COMPARE_BOTH(Orn(r0, r1, 0), "mvn r0, #0\n");
415   COMPARE_BOTH(Orn(r0, r0, 0xffffffff), "");
416 
417   // - Immediate form. This form does not need macro-assembler support
418   //   for T32.
419 
420   // Use r0 as the temporary register.
421   COMPARE_A32(Orn(r0, r1, 1),
422               "mvn r0, #1\n"
423               "orr r0, r1, r0\n");
424   // Use ip as the temporary register.
425   COMPARE_A32(Orns(r0, r0, 1),
426               "mvn ip, #1\n"
427               "orrs r0, ip\n");
428 
429   //  - Too large immediate form.
430   COMPARE_BOTH(Orn(r0, r1, 0x00ffffff), "orr r0, r1, #0xff000000\n");
431   COMPARE_BOTH(Orn(r0, r1, 0xff00ffff), "orr r0, r1, #0xff0000\n");
432   COMPARE_BOTH(Orns(r0, r1, 0x00ffffff), "orrs r0, r1, #0xff000000\n");
433 
434   COMPARE_A32(Orns(r0, r1, 0xabcd2345),
435               "mov ip, #9029\n"
436               "movt ip, #43981\n"
437               "mvn r0, ip\n"
438               "orrs r0, r1, r0\n");
439   COMPARE_T32(Orn(r0, r1, 0xabcd2345),
440               "mov r0, #9029\n"
441               "movt r0, #43981\n"
442               "orn r0, r1, r0\n");
443 
444   // - Plain register form. This form does not need macro-assembler
445   //   support for T32.
446 
447   // Use r0 as the temporary register.
448   COMPARE_A32(Orn(r0, r1, r2),
449               "mvn r0, r2\n"
450               "orr r0, r1, r0\n");
451   // Use ip as the temporary register.
452   COMPARE_A32(Orn(r0, r0, r1),
453               "mvn ip, r1\n"
454               "orr r0, ip\n");
455   // Use r0 as the temporary register.
456   COMPARE_A32(Orn(r0, r1, r0),
457               "mvn r0, r0\n"
458               "orr r0, r1, r0\n");
459   // Use ip as the temporary register.
460   COMPARE_A32(Orn(r0, r0, r0),
461               "mvn ip, r0\n"
462               "orr r0, ip\n");
463 
464   // - Shifted register form. This form does not need macro-assembler
465   //   support for T32.
466 
467   // Use r0 as the temporary register.
468   COMPARE_A32(Orn(r0, r1, Operand(r2, LSL, 1)),
469               "mvn r0, r2, lsl #1\n"
470               "orr r0, r1, r0\n");
471   // Use ip as the temporary register.
472   COMPARE_A32(Orns(r0, r0, Operand(r2, LSR, 2)),
473               "mvn ip, r2, lsr #2\n"
474               "orrs r0, ip\n");
475 
476   // - Register shifted register form.
477 
478   // Use r0 as the temporary register.
479   COMPARE_A32(Orn(r0, r1, Operand(r2, LSL, r3)),
480               "mvn r0, r2, lsl r3\n"
481               "orr r0, r1, r0\n");
482   COMPARE_T32(Orn(r0, r1, Operand(r2, LSL, r3)),
483               "lsl r0, r2, r3\n"
484               "orn r0, r1, r0\n");
485   // Use ip as the temporary register.
486   COMPARE_A32(Orns(r0, r0, Operand(r2, LSR, r3)),
487               "mvn ip, r2, lsr r3\n"
488               "orrs r0, ip\n");
489   COMPARE_T32(Orns(r0, r0, Operand(r2, LSR, r3)),
490               "lsr ip, r2, r3\n"
491               "orns r0, ip\n");
492   // Use ip as the temporary register.
493   COMPARE_A32(Orn(r0, r0, Operand(r0, ASR, r3)),
494               "mvn ip, r0, asr r3\n"
495               "orr r0, ip\n");
496   COMPARE_T32(Orn(r0, r0, Operand(r0, ASR, r3)),
497               "asr ip, r0, r3\n"
498               "orn r0, ip\n");
499   CLEANUP();
500 }
501 
502 
TEST(macro_assembler_t32_rsc)503 TEST(macro_assembler_t32_rsc) {
504   SETUP();
505 
506   // - Immediate form. We can always re-use `rn`.
507 
508   // No need for temporay registers.
509   COMPARE_T32(Rsc(r0, r1, 1),
510               "mvn r0, r1\n"
511               "adc r0, #1\n");
512   // No need for temporay registers.
513   COMPARE_T32(Rscs(r0, r0, 2),
514               "mvn r0, r0\n"
515               "adcs r0, #2\n");
516 
517   //  - Too large immediate form.
518 
519   // TODO: optimize this.
520   COMPARE_A32(Rsc(r0, r1, 0x00ffffff),
521               "mvn r0, #4278190080\n"
522               "rsc r0, r1, r0\n");
523   COMPARE_T32(Rscs(r0, r1, 0x00ffffff),
524               "mvn r0, r1\n"
525               "mvn ip, #4278190080\n"
526               "adcs r0, ip\n");
527   COMPARE_A32(Rsc(r0, r0, 0x00ffffff),
528               "mvn ip, #4278190080\n"
529               "rsc r0, ip\n");
530   COMPARE_T32(Rscs(r0, r0, 0x00ffffff),
531               "mvn r0, r0\n"
532               "mvn ip, #4278190080\n"
533               "adcs r0, ip\n");
534 
535   COMPARE_A32(Rsc(r0, r1, 0xabcd2345),
536               "mov r0, #9029\n"
537               "movt r0, #43981\n"
538               "rsc r0, r1, r0\n");
539   COMPARE_T32(Rscs(r0, r1, 0xabcd2345),
540               "mvn r0, r1\n"
541               "mov ip, #56506\n"
542               "movt ip, #21554\n"
543               "sbcs r0, ip\n");
544   COMPARE_A32(Rsc(r0, r0, 0xabcd2345),
545               "mov ip, #9029\n"
546               "movt ip, #43981\n"
547               "rsc r0, ip\n");
548   COMPARE_T32(Rscs(r0, r0, 0xabcd2345),
549               "mvn r0, r0\n"
550               "mov ip, #56506\n"
551               "movt ip, #21554\n"
552               "sbcs r0, ip\n");
553 
554   // - Plain register form.
555 
556   // No need for temporary registers.
557   COMPARE_T32(Rscs(r0, r1, r2),
558               "mvn r0, r1\n"
559               "adcs r0, r2\n");
560   // Use r0 as the temporary register.
561   COMPARE_T32(Rscs(r0, r1, r1),
562               "mvn r0, r1\n"
563               "adcs r0, r1\n");
564   // Use ip as the temporary register.
565   COMPARE_T32(Rscs(r0, r0, r0),
566               "mvn ip, r0\n"
567               "adcs r0, ip, r0\n");
568 
569   // - Shifted register form.
570 
571   // No need for temporay registers.
572   COMPARE_T32(Rsc(r0, r1, Operand(r2, LSL, 1)),
573               "mvn r0, r1\n"
574               "adc r0, r2, lsl #1\n");
575   // Use ip as the temporary register.
576   COMPARE_T32(Rscs(r0, r1, Operand(r0, LSR, 2)),
577               "mvn ip, r1\n"
578               "adcs r0, ip, r0, lsr #2\n");
579   // Use r0 as the temporary register.
580   COMPARE_T32(Rsc(r0, r1, Operand(r1, ASR, 3)),
581               "mvn r0, r1\n"
582               "adc r0, r1, asr #3\n");
583   // Use ip as the temporary register.
584   COMPARE_T32(Rscs(r0, r0, Operand(r0, ROR, 4)),
585               "mvn ip, r0\n"
586               "adcs r0, ip, r0, ror #4\n");
587 
588   // - Register shifted register form. The macro-assembler handles this form in
589   //   two steps. First, a shift instruction is generated from the operand. And
590   //   finally the operation is reduced to its plain register form.
591 
592   COMPARE_T32(Rsc(r0, r1, Operand(r2, LSL, r3)),
593               "lsl r0, r2, r3\n"
594               "mvn ip, r1\n"
595               "adc r0, ip, r0\n");
596   // Use r0 and ip as the temporary register.
597   COMPARE_T32(Rscs(r0, r1, Operand(r1, LSR, r3)),
598               "lsr r0, r1, r3\n"
599               "mvn ip, r1\n"
600               "adcs r0, ip, r0\n");
601   // Use ip and r0 as the temporary register.
602   COMPARE_T32(Rsc(r0, r0, Operand(r2, ASR, r3)),
603               "asr ip, r2, r3\n"
604               "mvn r0, r0\n"
605               "adc r0, ip\n");
606   // Use ip and r0 as the temporary register.
607   COMPARE_T32(Rscs(r0, r0, Operand(r0, ROR, r3)),
608               "ror ip, r0, r3\n"
609               "mvn r0, r0\n"
610               "adcs r0, ip\n");
611   // Use ip and r0 as the temporary register.
612   COMPARE_T32(Rsc(r0, r0, Operand(r0, LSL, r0)),
613               "lsl ip, r0, r0\n"
614               "mvn r0, r0\n"
615               "adc r0, ip\n");
616 
617   CLEANUP();
618 }
619 
620 
TEST(macro_assembler_t32_register_shift_register)621 TEST(macro_assembler_t32_register_shift_register) {
622   SETUP();
623 
624   COMPARE_T32(Adc(r0, r1, Operand(r2, LSL, r3)),
625               "lsl r0, r2, r3\n"
626               "adc r0, r1, r0\n");
627   COMPARE_T32(Adcs(r0, r0, Operand(r2, LSR, r3)),
628               "lsr ip, r2, r3\n"
629               "adcs r0, ip\n");
630   COMPARE_T32(Add(r0, r0, Operand(r0, ASR, r3)),
631               "asr ip, r0, r3\n"
632               "add r0, ip\n");
633   COMPARE_T32(Adds(r0, r0, Operand(r0, ROR, r0)),
634               "ror ip, r0, r0\n"
635               "adds r0, ip\n");
636 
637   CLEANUP();
638 }
639 
640 
TEST(macro_assembler_big_offset)641 TEST(macro_assembler_big_offset) {
642   SETUP();
643 
644   COMPARE_BOTH(Ldr(r0, MemOperand(r1, 0xfff123)),
645                "add r0, r1, #1044480\n"  // #0xff000
646                "add r0, #15728640\n"     // #0x00f00000
647                "ldr r0, [r0, #291]\n");  // #0x123
648   COMPARE_BOTH(Ldr(r0, MemOperand(r1, 0xff123)),
649                "add r0, r1, #1044480\n"  // #0xff000
650                "ldr r0, [r0, #291]\n");  // #0x123
651   COMPARE_BOTH(Ldr(r0, MemOperand(r1, -0xff123)),
652                "sub r0, r1, #1048576\n"   // #0x100000
653                "ldr r0, [r0, #3805]\n");  // #0xedd
654 
655   COMPARE_A32(Ldr(r0, MemOperand(r1, 0xfff123, PreIndex)),
656               "add r1, #1044480\n"       // #0xff000
657               "add r1, #15728640\n"      // #0x00f00000
658               "ldr r0, [r1, #291]!\n");  // #0x123
659   COMPARE_A32(Ldr(r0, MemOperand(r1, 0xff123, PreIndex)),
660               "add r1, #1044480\n"       // #0xff000
661               "ldr r0, [r1, #291]!\n");  // #0x123
662   COMPARE_A32(Ldr(r0, MemOperand(r1, -0xff123, PreIndex)),
663               "sub r1, #1048576\n"        // #0x100000
664               "ldr r0, [r1, #3805]!\n");  // #0xedd
665 
666   COMPARE_T32(Ldr(r0, MemOperand(r1, 0xfff12, PreIndex)),
667               "add r1, #65280\n"        // #0xff00
668               "add r1, #983040\n"       // #0x000f0000
669               "ldr r0, [r1, #18]!\n");  // #0x12
670   COMPARE_T32(Ldr(r0, MemOperand(r1, 0xff12, PreIndex)),
671               "add r1, #65280\n"        // #0xff00
672               "ldr r0, [r1, #18]!\n");  // #0x12
673   COMPARE_T32(Ldr(r0, MemOperand(r1, -0xff12, PreIndex)),
674               "sub r1, #65536\n"         // #0x10000
675               "ldr r0, [r1, #238]!\n");  // #0xee
676 
677   COMPARE_A32(Ldr(r0, MemOperand(r1, 0xfff123, PostIndex)),
678               "ldr r0, [r1], #291\n"   // #0x123
679               "add r1, #1044480\n"     // #0xff000
680               "add r1, #15728640\n");  // #0x00f00000
681   COMPARE_A32(Ldr(r0, MemOperand(r1, 0xff123, PostIndex)),
682               "ldr r0, [r1], #291\n"  // #0x123
683               "add r1, #1044480\n");  // #0xff000
684   COMPARE_A32(Ldr(r0, MemOperand(r1, -0xff123, PostIndex)),
685               "ldr r0, [r1], #3805\n"  // #0xedd
686               "sub r1, #1048576\n");   // #0x100000
687 
688   COMPARE_T32(Ldr(r0, MemOperand(r1, 0xfff12, PostIndex)),
689               "ldr r0, [r1], #18\n"  // #0x12
690               "add r1, #65280\n"     // #0xff00
691               "add r1, #983040\n");  // #0x000f0000
692   COMPARE_T32(Ldr(r0, MemOperand(r1, 0xff12, PostIndex)),
693               "ldr r0, [r1], #18\n"  // #0x12
694               "add r1, #65280\n");   // #0xff00
695   COMPARE_T32(Ldr(r0, MemOperand(r1, -0xff12, PostIndex)),
696               "ldr r0, [r1], #238\n"  // #0xee
697               "sub r1, #65536\n");    // #0x10000
698 
699   COMPARE_A32(Ldrh(r0, MemOperand(r1, 0xfff123)),
700               "add r0, r1, #61696\n"    // #0xf100
701               "add r0, #16711680\n"     // #0x00ff0000
702               "ldrh r0, [r0, #35]\n");  // #0x23
703   COMPARE_T32(Ldrh(r0, MemOperand(r1, 0xfff123)),
704               "add r0, r1, #1044480\n"   // #0xff000
705               "add r0, #15728640\n"      // #0x00f00000
706               "ldrh r0, [r0, #291]\n");  // #0x123
707 
708   COMPARE_A32(Ldrh(r0, MemOperand(r1, 0xff123)),
709               "add r0, r1, #61696\n"    // #0xf100
710               "add r0, #983040\n"       // #0x000f0000
711               "ldrh r0, [r0, #35]\n");  // #0x23
712   COMPARE_T32(Ldrh(r0, MemOperand(r1, 0xff123)),
713               "add r0, r1, #1044480\n"   // #0xff000
714               "ldrh r0, [r0, #291]\n");  // #0x123
715   COMPARE_A32(Ldrh(r0, MemOperand(r1, -0xff123)),
716               "sub r0, r1, #61952\n"     // #0xf200
717               "sub r0, #983040\n"        // #0x000f0000
718               "ldrh r0, [r0, #221]\n");  // #0xdd
719   COMPARE_T32(Ldrh(r0, MemOperand(r1, -0xff123)),
720               "sub r0, r1, #1048576\n"    // #0x100000
721               "ldrh r0, [r0, #3805]\n");  // #0xedd
722 
723   MUST_FAIL_TEST_BOTH(Ldr(r0, MemOperand(r0, 0xfff12, PreIndex)),
724                       "Ill-formed 'ldr' instruction.\n");
725   MUST_FAIL_TEST_BOTH(Ldr(r0, MemOperand(r0, 0xfff12, PostIndex)),
726                       "Ill-formed 'ldr' instruction.\n");
727   CLEANUP();
728 }
729 
730 
TEST(macro_assembler_load)731 TEST(macro_assembler_load) {
732   SETUP();
733 
734   // Register base and offset that we can encode in both A1 and T1.
735   COMPARE_BOTH(Ldr(r0, MemOperand(r1, r8, Offset)), "ldr r0, [r1, r8]\n");
736 
737   // Negative register offset. Use the destination as a scratch register,
738   // regardless of the values of the base and offset register.
739   COMPARE_T32(Ldr(r0, MemOperand(r0, minus, r0, Offset)),
740               "sub r0, r0\n"
741               "ldr r0, [r0]\n");
742 
743   COMPARE_T32(Ldr(r0, MemOperand(r0, minus, r1, Offset)),
744               "sub r0, r1\n"
745               "ldr r0, [r0]\n");
746 
747   COMPARE_T32(Ldr(r0, MemOperand(r1, minus, r0, Offset)),
748               "sub r0, r1, r0\n"
749               "ldr r0, [r0]\n");
750 
751   COMPARE_T32(Ldr(r0, MemOperand(r1, minus, r2, Offset)),
752               "sub r0, r1, r2\n"
753               "ldr r0, [r0]\n");
754 
755   // Pre-index negative offset.
756   COMPARE_T32(Ldr(r0, MemOperand(r1, minus, r2, PreIndex)),
757               "sub r1, r2\n"
758               "ldr r0, [r1]\n");
759 
760   // Post-index negative offset.
761   COMPARE_T32(Ldr(r0, MemOperand(r1, minus, r2, PostIndex)),
762               "ldr r0, [r1]\n"
763               "sub r1, r2\n");
764 
765   // SP is allowed as base, offset and destination.
766   COMPARE_BOTH(Ldr(sp, MemOperand(sp, sp, Offset)), "ldr sp, [sp, sp]\n");
767 
768   // PC is allowed as destination - make sure it is not used as a temporary
769   // register.
770   COMPARE_BOTH(Ldr(pc, MemOperand(r0, r0, Offset)), "ldr pc, [r0, r0]\n");
771   COMPARE_A32(Ldr(pc, MemOperand(r0, r0, PreIndex)), "ldr pc, [r0, r0]!\n");
772   COMPARE_T32(Ldr(pc, MemOperand(r0, r0, PreIndex)),
773               "add r0, r0\n"
774               "ldr pc, [r0]\n");
775   COMPARE_A32(Ldr(pc, MemOperand(r0, r0, PostIndex)), "ldr pc, [r0], r0\n");
776   COMPARE_T32(Ldr(pc, MemOperand(r0, r0, PostIndex)),
777               "ldr pc, [r0]\n"
778               "add r0, r0\n");
779 
780   // PC is allowed as register base in the offset variant only for A32.
781   COMPARE_A32(Ldr(r0, MemOperand(pc, r0, Offset)), "ldr r0, [pc, r0]\n");
782   MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(pc, r0, Offset)),
783                      "The MacroAssembler does not convert loads and stores with"
784                      " a PC base register for T32.\n");
785 
786   // PC is not allowed as register base in the pre-index and post-index
787   // variants.
788   MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(pc, r0, PreIndex)),
789                      "The MacroAssembler does not convert loads and stores "
790                      "with a PC base register in pre-index or post-index "
791                      "mode.\n");
792   MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(pc, r0, PostIndex)),
793                      "The MacroAssembler does not convert loads and stores "
794                      "with a PC base register in pre-index or post-index "
795                      "mode.\n");
796 
797   // We don't convert loads with PC as the register offset.
798   MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, minus, pc, Offset)),
799                      "The MacroAssembler does not convert loads and stores "
800                      "with a PC offset register.\n");
801   MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, pc, PreIndex)),
802                      "The MacroAssembler does not convert loads and stores "
803                      "with a PC offset register.\n");
804   MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, pc, PostIndex)),
805                      "The MacroAssembler does not convert loads and stores "
806                      "with a PC offset register.\n");
807 
808   MUST_FAIL_TEST_BOTH(Ldr(r0, MemOperand(r0, Sign(plus), pc, Offset)),
809                       "Unpredictable instruction.\n");
810 
811   // TODO: PC should not be allowed as register base in A32 with pre-index
812   //       and post-index (unpredictable).
813   SHOULD_FAIL_TEST_A32(Ldr(r0, MemOperand(pc, r0, PreIndex)));
814   SHOULD_FAIL_TEST_A32(Ldr(r0, MemOperand(pc, r0, PostIndex)));
815 
816   // TODO: load with the same register used as base and as destination
817   //       should fail to assemble (unpredictable).
818   SHOULD_FAIL_TEST_A32(Ldr(r0, MemOperand(r0, r1, PreIndex)));
819   SHOULD_FAIL_TEST_A32(Ldr(r0, MemOperand(r0, r1, PostIndex)));
820   MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, r1, PreIndex)),
821                      "Ill-formed 'ldr' instruction.\n");
822   MUST_FAIL_TEST_T32(Ldr(r0, MemOperand(r0, r1, PostIndex)),
823                      "Ill-formed 'ldr' instruction.\n");
824 
825   CLEANUP();
826 }
827 
828 
TEST(macro_assembler_store)829 TEST(macro_assembler_store) {
830   SETUP();
831 
832   // Register base and offset that we can encode in both A1 and T1.
833   COMPARE_BOTH(Str(r0, MemOperand(r1, r8, Offset)), "str r0, [r1, r8]\n");
834 
835   // Negative register offset.
836   COMPARE_T32(Str(r0, MemOperand(r0, minus, r0, Offset)),
837               "sub ip, r0, r0\n"
838               "str r0, [ip]\n");
839 
840   COMPARE_T32(Str(r0, MemOperand(r0, minus, r1, Offset)),
841               "sub ip, r0, r1\n"
842               "str r0, [ip]\n");
843 
844   COMPARE_T32(Str(r0, MemOperand(r1, minus, r0, Offset)),
845               "sub ip, r1, r0\n"
846               "str r0, [ip]\n");
847 
848   COMPARE_T32(Str(r0, MemOperand(r1, minus, r2, Offset)),
849               "sub ip, r1, r2\n"
850               "str r0, [ip]\n");
851 
852   // Pre-index negative offset.
853   COMPARE_T32(Str(r0, MemOperand(r1, minus, r2, PreIndex)),
854               "sub r1, r2\n"
855               "str r0, [r1]\n");
856 
857   // Post-index negative offset.
858   COMPARE_T32(Str(r0, MemOperand(r1, minus, r2, PostIndex)),
859               "str r0, [r1]\n"
860               "sub r1, r2\n");
861 
862   // SP is allowed as base, offset and source.
863   COMPARE_BOTH(Str(sp, MemOperand(sp, sp, Offset)), "str sp, [sp, sp]\n");
864 
865   COMPARE_A32(Str(pc, MemOperand(r0, r0, Offset)), "str pc, [r0, r0]\n");
866   COMPARE_A32(Str(pc, MemOperand(r0, r0, PreIndex)), "str pc, [r0, r0]!\n");
867   COMPARE_A32(Str(pc, MemOperand(r0, r0, PostIndex)), "str pc, [r0], r0\n");
868   MUST_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, Offset)),
869                      "Unpredictable instruction.\n");
870   MUST_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, PreIndex)),
871                      "Unpredictable instruction.\n");
872   MUST_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, PostIndex)),
873                      "Unpredictable instruction.\n");
874 
875   // PC is allowed as register base in the offset variant only for A32.
876   COMPARE_A32(Str(r0, MemOperand(pc, r0, Offset)), "str r0, [pc, r0]\n");
877   MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, Offset)),
878                      "The MacroAssembler does not convert loads and stores with"
879                      " a PC base register for T32.\n");
880 
881   // PC is not allowed as register base in the pre-index and post-index
882   // variants.
883   MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, PreIndex)),
884                      "The MacroAssembler does not convert loads and stores "
885                      "with a PC base register in pre-index or post-index "
886                      "mode.\n");
887   MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, PostIndex)),
888                      "The MacroAssembler does not convert loads and stores "
889                      "with a PC base register in pre-index or post-index "
890                      "mode.\n");
891 
892   // We don't convert loads with PC as the register offset.
893   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, minus, pc, Offset)),
894                      "The MacroAssembler does not convert loads and stores "
895                      "with a PC offset register.\n");
896   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, pc, PreIndex)),
897                      "The MacroAssembler does not convert loads and stores "
898                      "with a PC offset register.\n");
899   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, pc, PostIndex)),
900                      "The MacroAssembler does not convert loads and stores "
901                      "with a PC offset register.\n");
902 
903   MUST_FAIL_TEST_BOTH(Str(r0, MemOperand(r0, Sign(plus), pc, Offset)),
904                       "Unpredictable instruction.\n");
905 
906   // TODO: PC should not be allowed as register base in A32 with pre-index
907   //       and post-index (unpredictable).
908   SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(pc, r0, PreIndex)));
909   SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(pc, r0, PostIndex)));
910 
911   // TODO: store with the same register used as base and as source
912   //       should fail to assemble (unpredictable).
913   SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(r0, r1, PreIndex)));
914   SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(r0, r1, PostIndex)));
915   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, r1, PreIndex)),
916                      "Ill-formed 'str' instruction.\n");
917   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, r1, PostIndex)),
918                      "Ill-formed 'str' instruction.\n");
919 
920   CLEANUP();
921 }
922 
923 
TEST(macro_assembler_ldrd)924 TEST(macro_assembler_ldrd) {
925   SETUP();
926 
927   // - Tests with no offset.
928 
929   COMPARE_BOTH(Ldrd(r0, r1, MemOperand(r3)), "ldrd r0, r1, [r3]\n");
930   // Destination registers need to start with a even numbered register on A32.
931   MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r3)),
932                      "Unpredictable instruction.\n");
933   COMPARE_T32(Ldrd(r1, r2, MemOperand(r3)), "ldrd r1, r2, [r3]\n");
934   // Registers need to be adjacent on A32.
935   MUST_FAIL_TEST_A32(Ldrd(r0, r2, MemOperand(r1)),
936                      "Ill-formed 'ldrd' instruction.\n");
937   COMPARE_T32(Ldrd(r0, r2, MemOperand(r1)), "ldrd r0, r2, [r1]\n");
938 
939   COMPARE_BOTH(Ldrd(r0, r1, MemOperand(r2)), "ldrd r0, r1, [r2]\n");
940 
941   // - Tests with immediate offsets.
942 
943   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 1020)),
944               "add r0, r2, #1020\n"
945               "ldrd r0, r1, [r0]\n");
946   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 1020)), "ldrd r0, r1, [r2, #1020]\n");
947   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -1020)),
948               "sub r0, r2, #1020\n"
949               "ldrd r0, r1, [r0]\n");
950   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -1020)),
951               "ldrd r0, r1, [r2, #-1020]\n");
952 
953   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc)),
954               "add r0, r2, #43776\n"
955               "ldrd r0, r1, [r0, #204]\n");
956   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc)),
957               "add r0, r2, #43008\n"
958               "ldrd r0, r1, [r0, #972]\n");
959   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc)),
960               "sub r0, r2, #44032\n"
961               "ldrd r0, r1, [r0, #52]\n");
962   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc)),
963               "sub r0, r2, #44032\n"
964               "ldrd r0, r1, [r0, #52]\n");
965   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec)),
966               "add r0, r2, #52480\n"
967               "add r0, #11206656\n"
968               "ldrd r0, r1, [r0, #236]\n");
969   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec)),
970               "add r0, r2, #248832\n"
971               "add r0, #11010048\n"
972               "ldrd r0, r1, [r0, #492]\n");
973   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec)),
974               "sub r0, r2, #52736\n"
975               "sub r0, #11206656\n"
976               "ldrd r0, r1, [r0, #20]\n");
977   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec)),
978               "sub r0, r2, #774144\n"
979               "sub r0, #10485760\n"
980               "ldrd r0, r1, [r0, #532]\n");
981 
982   COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, 0xabcc)),
983               "add r1, r0, #43776\n"
984               "ldrd r0, r1, [r1, #204]\n");
985   COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, 0xabcc)),
986               "add r1, r0, #43008\n"
987               "ldrd r0, r1, [r1, #972]\n");
988   COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, -0xabcc)),
989               "sub r1, r0, #44032\n"
990               "ldrd r0, r1, [r1, #52]\n");
991   COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, -0xabcc)),
992               "sub r1, r0, #44032\n"
993               "ldrd r0, r1, [r1, #52]\n");
994   COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, 0xabcdec)),
995               "add r1, r0, #52480\n"
996               "add r1, #11206656\n"
997               "ldrd r0, r1, [r1, #236]\n");
998   COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, 0xabcdec)),
999               "add r1, r0, #248832\n"
1000               "add r1, #11010048\n"
1001               "ldrd r0, r1, [r1, #492]\n");
1002   COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, -0xabcdec)),
1003               "sub r1, r0, #52736\n"
1004               "sub r1, #11206656\n"
1005               "ldrd r0, r1, [r1, #20]\n");
1006   COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, -0xabcdec)),
1007               "sub r1, r0, #774144\n"
1008               "sub r1, #10485760\n"
1009               "ldrd r0, r1, [r1, #532]\n");
1010 
1011   COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, 0xabcc)),
1012               "add r0, r1, #43776\n"
1013               "ldrd r0, r1, [r0, #204]\n");
1014   COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, 0xabcc)),
1015               "add r0, r1, #43008\n"
1016               "ldrd r0, r1, [r0, #972]\n");
1017   COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, -0xabcc)),
1018               "sub r0, r1, #44032\n"
1019               "ldrd r0, r1, [r0, #52]\n");
1020   COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, -0xabcc)),
1021               "sub r0, r1, #44032\n"
1022               "ldrd r0, r1, [r0, #52]\n");
1023   COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, 0xabcdec)),
1024               "add r0, r1, #52480\n"
1025               "add r0, #11206656\n"
1026               "ldrd r0, r1, [r0, #236]\n");
1027   COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, 0xabcdec)),
1028               "add r0, r1, #248832\n"
1029               "add r0, #11010048\n"
1030               "ldrd r0, r1, [r0, #492]\n");
1031   COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, -0xabcdec)),
1032               "sub r0, r1, #52736\n"
1033               "sub r0, #11206656\n"
1034               "ldrd r0, r1, [r0, #20]\n");
1035   COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, -0xabcdec)),
1036               "sub r0, r1, #774144\n"
1037               "sub r0, #10485760\n"
1038               "ldrd r0, r1, [r0, #532]\n");
1039 
1040   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)),
1041               "ldrd r0, r1, [r2], #204\n"
1042               "add r2, #43776\n");
1043   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)),
1044               "ldrd r0, r1, [r2], #972\n"
1045               "add r2, #43008\n");
1046   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)),
1047               "ldrd r0, r1, [r2], #52\n"
1048               "sub r2, #44032\n");
1049   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)),
1050               "ldrd r0, r1, [r2], #52\n"
1051               "sub r2, #44032\n");
1052   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)),
1053               "ldrd r0, r1, [r2], #236\n"
1054               "add r2, #52480\n"
1055               "add r2, #11206656\n");
1056   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)),
1057               "ldrd r0, r1, [r2], #492\n"
1058               "add r2, #248832\n"
1059               "add r2, #11010048\n");
1060   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)),
1061               "ldrd r0, r1, [r2], #20\n"
1062               "sub r2, #52736\n"
1063               "sub r2, #11206656\n");
1064   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)),
1065               "ldrd r0, r1, [r2], #532\n"
1066               "sub r2, #774144\n"
1067               "sub r2, #10485760\n");
1068 
1069   // PostIndex with the same register as base and destination is invalid.
1070   MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r0, 0xabcd, PostIndex)),
1071                       "Ill-formed 'ldrd' instruction.\n");
1072   MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r1, 0xabcdef, PostIndex)),
1073                       "Ill-formed 'ldrd' instruction.\n");
1074 
1075   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)),
1076               "add r2, #43776\n"
1077               "ldrd r0, r1, [r2, #204]!\n");
1078   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)),
1079               "add r2, #43008\n"
1080               "ldrd r0, r1, [r2, #972]!\n");
1081   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)),
1082               "sub r2, #44032\n"
1083               "ldrd r0, r1, [r2, #52]!\n");
1084   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)),
1085               "sub r2, #44032\n"
1086               "ldrd r0, r1, [r2, #52]!\n");
1087   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)),
1088               "add r2, #52480\n"
1089               "add r2, #11206656\n"
1090               "ldrd r0, r1, [r2, #236]!\n");
1091   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)),
1092               "add r2, #248832\n"
1093               "add r2, #11010048\n"
1094               "ldrd r0, r1, [r2, #492]!\n");
1095   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)),
1096               "sub r2, #52736\n"
1097               "sub r2, #11206656\n"
1098               "ldrd r0, r1, [r2, #20]!\n");
1099   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)),
1100               "sub r2, #774144\n"
1101               "sub r2, #10485760\n"
1102               "ldrd r0, r1, [r2, #532]!\n");
1103 
1104   // - Tests with register offsets.
1105 
1106   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3)), "ldrd r0, r1, [r2, r3]\n");
1107   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3)),
1108               "add r0, r2, r3\n"
1109               "ldrd r0, r1, [r0]\n");
1110 
1111   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3)),
1112               "ldrd r0, r1, [r2, -r3]\n");
1113   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3)),
1114               "sub r0, r2, r3\n"
1115               "ldrd r0, r1, [r0]\n");
1116 
1117   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3, PostIndex)),
1118               "ldrd r0, r1, [r2], r3\n");
1119   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3, PostIndex)),
1120               "ldrd r0, r1, [r2]\n"
1121               "add r2, r3\n");
1122 
1123   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PostIndex)),
1124               "ldrd r0, r1, [r2], -r3\n");
1125   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PostIndex)),
1126               "ldrd r0, r1, [r2]\n"
1127               "sub r2, r3\n");
1128 
1129   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3, PreIndex)),
1130               "ldrd r0, r1, [r2, r3]!\n");
1131   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3, PreIndex)),
1132               "add r2, r3\n"
1133               "ldrd r0, r1, [r2]\n");
1134 
1135   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PreIndex)),
1136               "ldrd r0, r1, [r2, -r3]!\n");
1137   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PreIndex)),
1138               "sub r2, r3\n"
1139               "ldrd r0, r1, [r2]\n");
1140 
1141   // - We do not support register shifted base register operands with LDRD.
1142 
1143   MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r2, r3, LSL, 4)),
1144                       "Ill-formed 'ldrd' instruction.\n");
1145 
1146   // First register is odd - rejected by the Assembler.
1147   MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0)),
1148                      "Unpredictable instruction.\n");
1149   MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0, r0, PreIndex)),
1150                      "Unpredictable instruction.\n");
1151   // First register is odd - rejected by the MacroAssembler.
1152   MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0, 0xabcd, PreIndex)),
1153                      "Ill-formed 'ldrd' instruction.\n");
1154 
1155   // First register is lr - rejected by the Assembler.
1156   MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0)),
1157                      "Unpredictable instruction.\n");
1158   MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0, r0, PreIndex)),
1159                      "Unpredictable instruction.\n");
1160   // First register is lr - rejected by the MacroAssembler.
1161   MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0, 0xabcd, PreIndex)),
1162                      "Ill-formed 'ldrd' instruction.\n");
1163 
1164   // Non-adjacent registers.
1165   MUST_FAIL_TEST_A32(Ldrd(r0, r2, MemOperand(r0)),
1166                      "Ill-formed 'ldrd' instruction.\n");
1167 
1168   CLEANUP();
1169 }
1170 
TEST(macro_assembler_strd)1171 TEST(macro_assembler_strd) {
1172   SETUP();
1173 
1174   // - Tests with no offset.
1175 
1176   COMPARE_BOTH(Strd(r0, r1, MemOperand(r3)), "strd r0, r1, [r3]\n");
1177   // Destination registers need to start with a even numbered register on A32.
1178   MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r3)),
1179                      "Unpredictable instruction.\n");
1180   COMPARE_T32(Strd(r1, r2, MemOperand(r3)), "strd r1, r2, [r3]\n");
1181   // Registers need to be adjacent on A32.
1182   MUST_FAIL_TEST_A32(Strd(r0, r2, MemOperand(r1)),
1183                      "Ill-formed 'strd' instruction.\n");
1184   COMPARE_T32(Strd(r0, r2, MemOperand(r1)), "strd r0, r2, [r1]\n");
1185 
1186   COMPARE_BOTH(Strd(r0, r1, MemOperand(r2)), "strd r0, r1, [r2]\n");
1187 
1188   // - Tests with immediate offsets.
1189 
1190   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 1020)),
1191               "add ip, r2, #1020\n"
1192               "strd r0, r1, [ip]\n");
1193   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 1020)), "strd r0, r1, [r2, #1020]\n");
1194   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -1020)),
1195               "sub ip, r2, #1020\n"
1196               "strd r0, r1, [ip]\n");
1197   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -1020)),
1198               "strd r0, r1, [r2, #-1020]\n");
1199 
1200   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc)),
1201               "add ip, r2, #43776\n"
1202               "strd r0, r1, [ip, #204]\n");
1203   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc)),
1204               "add ip, r2, #43008\n"
1205               "strd r0, r1, [ip, #972]\n");
1206   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc)),
1207               "sub ip, r2, #44032\n"
1208               "strd r0, r1, [ip, #52]\n");
1209   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc)),
1210               "sub ip, r2, #44032\n"
1211               "strd r0, r1, [ip, #52]\n");
1212   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec)),
1213               "add ip, r2, #52480\n"
1214               "add ip, #11206656\n"
1215               "strd r0, r1, [ip, #236]\n");
1216   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec)),
1217               "add ip, r2, #248832\n"
1218               "add ip, #11010048\n"
1219               "strd r0, r1, [ip, #492]\n");
1220   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec)),
1221               "sub ip, r2, #52736\n"
1222               "sub ip, #11206656\n"
1223               "strd r0, r1, [ip, #20]\n");
1224   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec)),
1225               "sub ip, r2, #774144\n"
1226               "sub ip, #10485760\n"
1227               "strd r0, r1, [ip, #532]\n");
1228 
1229   COMPARE_A32(Strd(r0, r1, MemOperand(r0, 0xabcc)),
1230               "add ip, r0, #43776\n"
1231               "strd r0, r1, [ip, #204]\n");
1232   COMPARE_T32(Strd(r0, r1, MemOperand(r0, 0xabcc)),
1233               "add ip, r0, #43008\n"
1234               "strd r0, r1, [ip, #972]\n");
1235   COMPARE_A32(Strd(r0, r1, MemOperand(r0, -0xabcc)),
1236               "sub ip, r0, #44032\n"
1237               "strd r0, r1, [ip, #52]\n");
1238   COMPARE_T32(Strd(r0, r1, MemOperand(r0, -0xabcc)),
1239               "sub ip, r0, #44032\n"
1240               "strd r0, r1, [ip, #52]\n");
1241   COMPARE_A32(Strd(r0, r1, MemOperand(r0, 0xabcdec)),
1242               "add ip, r0, #52480\n"
1243               "add ip, #11206656\n"
1244               "strd r0, r1, [ip, #236]\n");
1245   COMPARE_T32(Strd(r0, r1, MemOperand(r0, 0xabcdec)),
1246               "add ip, r0, #248832\n"
1247               "add ip, #11010048\n"
1248               "strd r0, r1, [ip, #492]\n");
1249   COMPARE_A32(Strd(r0, r1, MemOperand(r0, -0xabcdec)),
1250               "sub ip, r0, #52736\n"
1251               "sub ip, #11206656\n"
1252               "strd r0, r1, [ip, #20]\n");
1253   COMPARE_T32(Strd(r0, r1, MemOperand(r0, -0xabcdec)),
1254               "sub ip, r0, #774144\n"
1255               "sub ip, #10485760\n"
1256               "strd r0, r1, [ip, #532]\n");
1257 
1258   COMPARE_A32(Strd(r0, r1, MemOperand(r1, 0xabcc)),
1259               "add ip, r1, #43776\n"
1260               "strd r0, r1, [ip, #204]\n");
1261   COMPARE_T32(Strd(r0, r1, MemOperand(r1, 0xabcc)),
1262               "add ip, r1, #43008\n"
1263               "strd r0, r1, [ip, #972]\n");
1264   COMPARE_A32(Strd(r0, r1, MemOperand(r1, -0xabcc)),
1265               "sub ip, r1, #44032\n"
1266               "strd r0, r1, [ip, #52]\n");
1267   COMPARE_T32(Strd(r0, r1, MemOperand(r1, -0xabcc)),
1268               "sub ip, r1, #44032\n"
1269               "strd r0, r1, [ip, #52]\n");
1270   COMPARE_A32(Strd(r0, r1, MemOperand(r1, 0xabcdec)),
1271               "add ip, r1, #52480\n"
1272               "add ip, #11206656\n"
1273               "strd r0, r1, [ip, #236]\n");
1274   COMPARE_T32(Strd(r0, r1, MemOperand(r1, 0xabcdec)),
1275               "add ip, r1, #248832\n"
1276               "add ip, #11010048\n"
1277               "strd r0, r1, [ip, #492]\n");
1278   COMPARE_A32(Strd(r0, r1, MemOperand(r1, -0xabcdec)),
1279               "sub ip, r1, #52736\n"
1280               "sub ip, #11206656\n"
1281               "strd r0, r1, [ip, #20]\n");
1282   COMPARE_T32(Strd(r0, r1, MemOperand(r1, -0xabcdec)),
1283               "sub ip, r1, #774144\n"
1284               "sub ip, #10485760\n"
1285               "strd r0, r1, [ip, #532]\n");
1286 
1287   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)),
1288               "strd r0, r1, [r2], #204\n"
1289               "add r2, #43776\n");
1290   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)),
1291               "strd r0, r1, [r2], #972\n"
1292               "add r2, #43008\n");
1293   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)),
1294               "strd r0, r1, [r2], #52\n"
1295               "sub r2, #44032\n");
1296   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)),
1297               "strd r0, r1, [r2], #52\n"
1298               "sub r2, #44032\n");
1299   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)),
1300               "strd r0, r1, [r2], #236\n"
1301               "add r2, #52480\n"
1302               "add r2, #11206656\n");
1303   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)),
1304               "strd r0, r1, [r2], #492\n"
1305               "add r2, #248832\n"
1306               "add r2, #11010048\n");
1307   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)),
1308               "strd r0, r1, [r2], #20\n"
1309               "sub r2, #52736\n"
1310               "sub r2, #11206656\n");
1311   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)),
1312               "strd r0, r1, [r2], #532\n"
1313               "sub r2, #774144\n"
1314               "sub r2, #10485760\n");
1315 
1316   // PostIndex with the same register as base and source is invalid.
1317   MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r0, 0xabcd, PostIndex)),
1318                       "Ill-formed 'strd' instruction.\n");
1319   MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r1, 0xabcdef, PostIndex)),
1320                       "Ill-formed 'strd' instruction.\n");
1321 
1322   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)),
1323               "add r2, #43776\n"
1324               "strd r0, r1, [r2, #204]!\n");
1325   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)),
1326               "add r2, #43008\n"
1327               "strd r0, r1, [r2, #972]!\n");
1328   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)),
1329               "sub r2, #44032\n"
1330               "strd r0, r1, [r2, #52]!\n");
1331   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)),
1332               "sub r2, #44032\n"
1333               "strd r0, r1, [r2, #52]!\n");
1334   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)),
1335               "add r2, #52480\n"
1336               "add r2, #11206656\n"
1337               "strd r0, r1, [r2, #236]!\n");
1338   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)),
1339               "add r2, #248832\n"
1340               "add r2, #11010048\n"
1341               "strd r0, r1, [r2, #492]!\n");
1342   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)),
1343               "sub r2, #52736\n"
1344               "sub r2, #11206656\n"
1345               "strd r0, r1, [r2, #20]!\n");
1346   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)),
1347               "sub r2, #774144\n"
1348               "sub r2, #10485760\n"
1349               "strd r0, r1, [r2, #532]!\n");
1350 
1351   // - Tests with register offsets.
1352 
1353   COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3)), "strd r0, r1, [r2, r3]\n");
1354   COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3)),
1355               "add ip, r2, r3\n"
1356               "strd r0, r1, [ip]\n");
1357 
1358   COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3)),
1359               "strd r0, r1, [r2, -r3]\n");
1360   COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3)),
1361               "sub ip, r2, r3\n"
1362               "strd r0, r1, [ip]\n");
1363 
1364   COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3, PostIndex)),
1365               "strd r0, r1, [r2], r3\n");
1366   COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3, PostIndex)),
1367               "strd r0, r1, [r2]\n"
1368               "add r2, r3\n");
1369 
1370   COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3, PostIndex)),
1371               "strd r0, r1, [r2], -r3\n");
1372   COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3, PostIndex)),
1373               "strd r0, r1, [r2]\n"
1374               "sub r2, r3\n");
1375 
1376   COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3, PreIndex)),
1377               "strd r0, r1, [r2, r3]!\n");
1378   COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3, PreIndex)),
1379               "add r2, r3\n"
1380               "strd r0, r1, [r2]\n");
1381 
1382   COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3, PreIndex)),
1383               "strd r0, r1, [r2, -r3]!\n");
1384   COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3, PreIndex)),
1385               "sub r2, r3\n"
1386               "strd r0, r1, [r2]\n");
1387 
1388   // - We do not support register shifted base register operands with LDRD.
1389 
1390   MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r2, r3, LSL, 4)),
1391                       "Ill-formed 'strd' instruction.\n");
1392 
1393   // First register is odd - rejected by the Assembler.
1394   MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0)),
1395                      "Unpredictable instruction.\n");
1396   MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0, r0, PreIndex)),
1397                      "Unpredictable instruction.\n");
1398   // First register is odd - rejected by the MacroAssembler.
1399   MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0, 0xabcd, PreIndex)),
1400                      "Ill-formed 'strd' instruction.\n");
1401 
1402   // First register is lr - rejected by the Assembler.
1403   MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0)),
1404                      "Unpredictable instruction.\n");
1405   MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0, r0, PreIndex)),
1406                      "Unpredictable instruction.\n");
1407   // First register is lr - rejected by the MacroAssembler.
1408   MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0, 0xabcd, PreIndex)),
1409                      "Ill-formed 'strd' instruction.\n");
1410 
1411   // Non-adjacent registers.
1412   MUST_FAIL_TEST_A32(Strd(r0, r2, MemOperand(r0)),
1413                      "Ill-formed 'strd' instruction.\n");
1414 
1415   CLEANUP();
1416 }
1417 
1418 
TEST(macro_assembler_wide_immediate)1419 TEST(macro_assembler_wide_immediate) {
1420   SETUP();
1421 
1422   COMPARE_BOTH(Adc(r0, r1, 0xbadbeef),
1423                "mov r0, #48879\n"
1424                "movt r0, #2989\n"
1425                "adc r0, r1, r0\n");
1426 
1427   COMPARE_BOTH(Add(r0, r0, 0xbadbeef),
1428                "mov ip, #48879\n"
1429                "movt ip, #2989\n"
1430                "add r0, ip\n");
1431 
1432   COMPARE_BOTH(Mov(r0, 0xbadbeef),
1433                "mov r0, #48879\n"
1434                "movt r0, #2989\n");
1435   COMPARE_A32(Mov(eq, r0, 0xbadbeef),
1436               "moveq r0, #48879\n"
1437               "movteq r0, #2989\n");
1438   COMPARE_T32(Mov(eq, r0, 0xbadbeef),
1439               "bne 0x0000000a\n"
1440               "mov r0, #48879\n"
1441               "movt r0, #2989\n");
1442 
1443   COMPARE_BOTH(Movs(r0, 0xbadbeef),
1444                "mov r0, #48879\n"
1445                "movt r0, #2989\n"
1446                "tst r0, r0\n");
1447   COMPARE_A32(Movs(eq, r0, 0xbadbeef),
1448               "moveq r0, #48879\n"
1449               "movteq r0, #2989\n"
1450               "tsteq r0, r0\n");
1451   COMPARE_T32(Movs(eq, r0, 0xbadbeef),
1452               "bne 0x0000000c\n"
1453               "mov r0, #48879\n"
1454               "movt r0, #2989\n"
1455               "tst r0, r0\n");
1456   COMPARE_A32(Movs(pc, 0x1), "movs pc, #1\n");
1457   MUST_FAIL_TEST_T32(Movs(pc, 0x1), "Unpredictable instruction.\n");
1458   MUST_FAIL_TEST_BOTH(Movs(pc, 0xbadbeed), "Ill-formed 'movs' instruction.\n");
1459 
1460   COMPARE_BOTH(Mov(pc, 0xbadbeef),
1461                "mov ip, #48879\n"
1462                "movt ip, #2989\n"
1463                "bx ip\n");
1464   COMPARE_A32(Mov(eq, pc, 0xbadbeef),
1465               "mov ip, #48879\n"
1466               "movt ip, #2989\n"
1467               "bxeq ip\n");
1468   COMPARE_T32(Mov(eq, pc, 0xbadbeef),
1469               "bne 0x0000000c\n"
1470               "mov ip, #48879\n"
1471               "movt ip, #2989\n"
1472               "bx ip\n");
1473 
1474   CLEANUP();
1475 }
1476 
1477 
TEST(macro_assembler_And)1478 TEST(macro_assembler_And) {
1479   SETUP();
1480 
1481   // Identities.
1482   COMPARE_BOTH(And(r0, r1, 0), "mov r0, #0\n");
1483   COMPARE_BOTH(And(r0, r0, 0xffffffff), "");
1484   CLEANUP();
1485 }
1486 
1487 
TEST(macro_assembler_Bic)1488 TEST(macro_assembler_Bic) {
1489   SETUP();
1490 
1491   // Identities.
1492   COMPARE_BOTH(Bic(r0, r1, 0xffffffff), "mov r0, #0\n");
1493   COMPARE_BOTH(Bic(r0, r0, 0), "");
1494   CLEANUP();
1495 }
1496 
1497 
TEST(macro_assembler_Orr)1498 TEST(macro_assembler_Orr) {
1499   SETUP();
1500 
1501   // Identities.
1502   COMPARE_BOTH(Orr(r0, r1, 0xffffffff), "mvn r0, #0\n");
1503   COMPARE_BOTH(Orr(r0, r0, 0), "");
1504   CLEANUP();
1505 }
1506 
1507 
TEST(macro_assembler_InstructionCondSizeRROp)1508 TEST(macro_assembler_InstructionCondSizeRROp) {
1509   SETUP();
1510 
1511   // Special case for Orr <-> Orn correspondance.
1512 
1513   COMPARE_T32(Orr(r0, r1, 0x00ffffff), "orn r0, r1, #0xff000000\n");
1514   COMPARE_T32(Orrs(r0, r1, 0x00ffffff), "orns r0, r1, #0xff000000\n");
1515 
1516   // Encodable immediates.
1517 
1518   COMPARE_A32(Add(r0, r1, -1), "sub r0, r1, #1\n");
1519   COMPARE_A32(Adds(r0, r1, -1), "subs r0, r1, #1\n");
1520   // 0xffffffff is encodable in a T32 ADD.
1521   COMPARE_T32(Add(r0, r1, -1), "add r0, r1, #4294967295\n");
1522   COMPARE_T32(Adds(r0, r1, -1), "adds r0, r1, #4294967295\n");
1523 
1524   COMPARE_BOTH(Add(r0, r1, -4), "sub r0, r1, #4\n");
1525   COMPARE_BOTH(Adds(r0, r1, -4), "subs r0, r1, #4\n");
1526 
1527   COMPARE_BOTH(Adc(r0, r1, -2), "sbc r0, r1, #1\n");
1528   COMPARE_BOTH(Adcs(r0, r1, -2), "sbcs r0, r1, #1\n");
1529 
1530   COMPARE_A32(Sub(r0, r1, -1), "add r0, r1, #1\n");
1531   COMPARE_A32(Subs(r0, r1, -1), "adds r0, r1, #1\n");
1532   // 0xffffffff is encodable in a T32 SUB.
1533   COMPARE_T32(Sub(r0, r1, -1), "sub r0, r1, #4294967295\n");
1534   COMPARE_T32(Subs(r0, r1, -1), "subs r0, r1, #4294967295\n");
1535 
1536   COMPARE_BOTH(Sub(r0, r1, -4), "add r0, r1, #4\n");
1537   COMPARE_BOTH(Subs(r0, r1, -4), "adds r0, r1, #4\n");
1538 
1539   COMPARE_BOTH(Sbc(r0, r1, -5), "adc r0, r1, #4\n");
1540   COMPARE_BOTH(Sbcs(r0, r1, -5), "adcs r0, r1, #4\n");
1541 
1542   // Non-encodable immediates
1543 
1544   COMPARE_BOTH(Adc(r0, r1, 0xabcd),
1545                "mov r0, #43981\n"
1546                "adc r0, r1, r0\n");
1547 
1548   COMPARE_BOTH(Adc(r0, r1, -0xabcd),
1549                "mov r0, #43980\n"  // This represents #0xabcd - 1.
1550                "sbc r0, r1, r0\n");
1551 
1552   COMPARE_BOTH(Adc(r0, r1, 0x1234abcd),
1553                "mov r0, #43981\n"
1554                "movt r0, #4660\n"
1555                "adc r0, r1, r0\n");
1556 
1557   COMPARE_BOTH(Adc(r0, r1, -0x1234abcd),
1558                "mov r0, #43980\n"  // This represents #0x1234abcd - 1.
1559                "movt r0, #4660\n"
1560                "sbc r0, r1, r0\n");
1561 
1562   // Non-encodable immediates with the same source and destination registers.
1563 
1564   COMPARE_BOTH(Sbc(r0, r0, 0xabcd),
1565                "mov ip, #43981\n"
1566                "sbc r0, ip\n");
1567 
1568   COMPARE_BOTH(Sbc(r0, r0, -0xabcd),
1569                "mov ip, #43980\n"  // This represents #0xabcd - 1.
1570                "adc r0, ip\n");
1571 
1572   COMPARE_BOTH(Sbc(r0, r0, 0x1234abcd),
1573                "mov ip, #43981\n"
1574                "movt ip, #4660\n"
1575                "sbc r0, ip\n");
1576 
1577   COMPARE_BOTH(Sbc(r0, r0, -0x1234abcd),
1578                "mov ip, #43980\n"  // This represents #0x1234abcd - 1.
1579                "movt ip, #4660\n"
1580                "adc r0, ip\n");
1581 
1582 
1583   // Test that we can pass a register shifted register operand in T32.
1584 
1585   COMPARE_T32(Adc(r0, r1, Operand(r2, LSL, r3)),
1586               "lsl r0, r2, r3\n"
1587               "adc r0, r1, r0\n");
1588 
1589   COMPARE_T32(Add(r3, r2, Operand(r2, ASR, r3)),
1590               "asr r3, r2, r3\n"
1591               "add r3, r2, r3\n");
1592 
1593   COMPARE_T32(Ands(r3, r2, Operand(r2, LSR, r2)),
1594               "lsr r3, r2, r2\n"
1595               "ands r3, r2, r3\n");
1596 
1597   COMPARE_T32(Asr(r2, r2, Operand(r2, ROR, r2)),
1598               "ror ip, r2, r2\n"
1599               "asr r2, ip\n");
1600 
1601   COMPARE_T32(Asr(r2, r2, Operand(r2, ROR, r2)),
1602               "ror ip, r2, r2\n"
1603               "asr r2, ip\n");
1604 
1605 
1606   CLEANUP();
1607 }
1608 
1609 
TEST(macro_assembler_InstructionCondRO)1610 TEST(macro_assembler_InstructionCondRO) {
1611   SETUP();
1612 
1613   COMPARE_BOTH(Teq(r0, 0xbad),
1614                "mov ip, #2989\n"
1615                "teq r0, ip\n");
1616   COMPARE_BOTH(Teq(r0, 0xbadbeef),
1617                "mov ip, #48879\n"
1618                "movt ip, #2989\n"
1619                "teq r0, ip\n");
1620   MUST_FAIL_TEST_T32(Teq(r0, Operand(r1, LSL, r2)),
1621                      "Ill-formed 'teq' instruction.\n");
1622 
1623   CLEANUP();
1624 }
1625 
1626 
TEST(macro_assembler_too_large_immediate)1627 TEST(macro_assembler_too_large_immediate) {
1628   SETUP();
1629 
1630   // Attempting to use a 17-bit immediate with movt.
1631   MUST_FAIL_TEST_BOTH(Movt(r0, 0x10000), "`Movt` expects a 16-bit immediate.");
1632 
1633   CLEANUP();
1634 }
1635 
1636 
TEST(macro_assembler_Cbz)1637 TEST(macro_assembler_Cbz) {
1638   SETUP();
1639 
1640 #ifdef VIXL_INCLUDE_TARGET_A32
1641   // Cbz/Cbnz are not available in A32 mode.
1642   // Make sure GetArchitectureStatePCOffset() returns the correct value.
1643   __ UseA32();
1644   Label label_64(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() + 64);
1645   MUST_FAIL_TEST_A32(Cbz(r0, &label_64), "Cbz is only available for T32.\n");
1646   MUST_FAIL_TEST_A32(Cbnz(r0, &label_64), "Cbnz is only available for T32.\n");
1647 #endif
1648 
1649 #ifdef VIXL_INCLUDE_TARGET_T32
1650   // Make sure GetArchitectureStatePCOffset() returns the correct value.
1651   __ UseT32();
1652   // Largest encodable offset.
1653   Label label_126(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() +
1654                   126);
1655   COMPARE_T32(Cbz(r0, &label_126), "cbz r0, 0x00000082\n");
1656   COMPARE_T32(Cbnz(r0, &label_126), "cbnz r0, 0x00000082\n");
1657 
1658   // Offset cannot be encoded.
1659   Label label_128(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() +
1660                   128);
1661   COMPARE_T32(Cbz(r0, &label_128),
1662               "cbnz r0, 0x00000004\n"
1663               "b 0x00000084\n");
1664   COMPARE_T32(Cbnz(r0, &label_128),
1665               "cbz r0, 0x00000004\n"
1666               "b 0x00000084\n");
1667 
1668   // Offset that cannot be encoded and needs 32-bit branch instruction.
1669   Label label_8192(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() +
1670                    8192);
1671   COMPARE_T32(Cbz(r0, &label_8192),
1672               "cbnz r0, 0x00000006\n"
1673               "b 0x00002004\n");
1674   COMPARE_T32(Cbnz(r0, &label_8192),
1675               "cbz r0, 0x00000006\n"
1676               "b 0x00002004\n");
1677 
1678   // Negative offset.
1679   Label label_neg(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() +
1680                   -8);
1681   COMPARE_T32(Cbz(r0, &label_neg),
1682               "cbnz r0, 0x00000004\n"
1683               "b 0xfffffffc\n");
1684   COMPARE_T32(Cbnz(r0, &label_neg),
1685               "cbz r0, 0x00000004\n"
1686               "b 0xfffffffc\n");
1687 
1688   // Large negative offset.
1689   Label label_neg128(__ GetCursorOffset() + __ GetArchitectureStatePCOffset() +
1690                      -128);
1691   COMPARE_T32(Cbz(r0, &label_neg128),
1692               "cbnz r0, 0x00000004\n"
1693               "b 0xffffff84\n");
1694   COMPARE_T32(Cbnz(r0, &label_neg128),
1695               "cbz r0, 0x00000004\n"
1696               "b 0xffffff84\n");
1697 #endif
1698 
1699   CLEANUP();
1700 }
1701 
1702 
1703 #ifdef VIXL_NEGATIVE_TESTING
TEST(assembler_crc_negative)1704 TEST(assembler_crc_negative) {
1705   SETUP();
1706 
1707   ExactAssemblyScope scope(&masm, 2, CodeBufferCheckScope::kMaximumSize);
1708 
1709   masm.it(eq);
1710 
1711   MUST_FAIL_TEST_T32(crc32b(eq, r0, r1, r2), "Unpredictable instruction.\n");
1712   MUST_FAIL_TEST_T32(crc32cb(eq, r0, r1, r2), "Unpredictable instruction.\n");
1713   MUST_FAIL_TEST_T32(crc32ch(eq, r0, r1, r2), "Unpredictable instruction.\n");
1714   MUST_FAIL_TEST_T32(crc32cw(eq, r0, r1, r2), "Unpredictable instruction.\n");
1715   MUST_FAIL_TEST_T32(crc32h(eq, r0, r1, r2), "Unpredictable instruction.\n");
1716   MUST_FAIL_TEST_T32(crc32w(eq, r0, r1, r2), "Unpredictable instruction.\n");
1717 
1718   CLEANUP();
1719 }
1720 #endif
1721 
1722 
1723 #ifdef VIXL_NEGATIVE_TESTING
TEST(assembler_hvc_negative)1724 TEST(assembler_hvc_negative) {
1725   SETUP();
1726 
1727   ExactAssemblyScope scope(&masm, 2, CodeBufferCheckScope::kMaximumSize);
1728 
1729   masm.it(eq);
1730 
1731   MUST_FAIL_TEST_T32(hvc(eq, 0), "Unpredictable instruction.\n");
1732 
1733   CLEANUP();
1734 }
1735 #endif
1736 
1737 
TEST(macro_assembler_vld)1738 TEST(macro_assembler_vld) {
1739   SETUP();
1740 
1741   COMPARE_BOTH(Vld1(Untyped8,
1742                     NeonRegisterList(d0, kMultipleLanes),
1743                     AlignedMemOperand(r1, kNoAlignment)),
1744                "vld1.8 {d0}, [r1]\n");
1745   COMPARE_BOTH(Vld1(Untyped8,
1746                     NeonRegisterList(d0, kMultipleLanes),
1747                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1748                "vld1.8 {d0}, [r1]!\n");
1749   COMPARE_BOTH(Vld1(Untyped8,
1750                     NeonRegisterList(d0, kMultipleLanes),
1751                     AlignedMemOperand(r8, kNoAlignment, r2, PostIndex)),
1752                "vld1.8 {d0}, [r8], r2\n");
1753   COMPARE_BOTH(Vld1(Untyped8,
1754                     NeonRegisterList(d0, kAllLanes),
1755                     AlignedMemOperand(r1, kNoAlignment)),
1756                "vld1.8 {d0[]}, [r1]\n");
1757   COMPARE_BOTH(Vld1(Untyped8,
1758                     NeonRegisterList(d0, kAllLanes),
1759                     AlignedMemOperand(r9, kNoAlignment, PostIndex)),
1760                "vld1.8 {d0[]}, [r9]!\n");
1761   COMPARE_BOTH(Vld1(Untyped8,
1762                     NeonRegisterList(d0, kAllLanes),
1763                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1764                "vld1.8 {d0[]}, [r1], r2\n");
1765   COMPARE_BOTH(Vld1(Untyped8,
1766                     NeonRegisterList(d0, 0),
1767                     AlignedMemOperand(r10, kNoAlignment)),
1768                "vld1.8 {d0[0]}, [r10]\n");
1769   COMPARE_BOTH(Vld1(Untyped8,
1770                     NeonRegisterList(d0, 1),
1771                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1772                "vld1.8 {d0[1]}, [r1]!\n");
1773   COMPARE_BOTH(Vld1(Untyped8,
1774                     NeonRegisterList(d0, 2),
1775                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1776                "vld1.8 {d0[2]}, [r1], r2\n");
1777 
1778   COMPARE_BOTH(Vld2(Untyped8,
1779                     NeonRegisterList(d0, d1, kSingle, kMultipleLanes),
1780                     AlignedMemOperand(r1, kNoAlignment)),
1781                "vld2.8 {d0,d1}, [r1]\n");
1782   COMPARE_BOTH(Vld2(Untyped8,
1783                     NeonRegisterList(d0, d1, kSingle, kMultipleLanes),
1784                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1785                "vld2.8 {d0,d1}, [r1]!\n");
1786   COMPARE_BOTH(Vld2(Untyped8,
1787                     NeonRegisterList(d0, d1, kSingle, kMultipleLanes),
1788                     AlignedMemOperand(r1, kNoAlignment, r8, PostIndex)),
1789                "vld2.8 {d0,d1}, [r1], r8\n");
1790   COMPARE_BOTH(Vld2(Untyped8,
1791                     NeonRegisterList(d0, d1, kSingle, kAllLanes),
1792                     AlignedMemOperand(r1, kNoAlignment)),
1793                "vld2.8 {d0[],d1[]}, [r1]\n");
1794   COMPARE_BOTH(Vld2(Untyped8,
1795                     NeonRegisterList(d0, d1, kSingle, kAllLanes),
1796                     AlignedMemOperand(r9, kNoAlignment, PostIndex)),
1797                "vld2.8 {d0[],d1[]}, [r9]!\n");
1798   COMPARE_BOTH(Vld2(Untyped8,
1799                     NeonRegisterList(d0, d1, kSingle, kAllLanes),
1800                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1801                "vld2.8 {d0[],d1[]}, [r1], r2\n");
1802   COMPARE_BOTH(Vld2(Untyped8,
1803                     NeonRegisterList(d0, d1, kSingle, 0),
1804                     AlignedMemOperand(r10, kNoAlignment)),
1805                "vld2.8 {d0[0],d1[0]}, [r10]\n");
1806   COMPARE_BOTH(Vld2(Untyped8,
1807                     NeonRegisterList(d0, d1, kSingle, 1),
1808                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1809                "vld2.8 {d0[1],d1[1]}, [r1]!\n");
1810   COMPARE_BOTH(Vld2(Untyped8,
1811                     NeonRegisterList(d0, d1, kSingle, 2),
1812                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1813                "vld2.8 {d0[2],d1[2]}, [r1], r2\n");
1814 
1815   COMPARE_BOTH(Vld3(Untyped8,
1816                     NeonRegisterList(d0, d2, kSingle, kMultipleLanes),
1817                     AlignedMemOperand(r1, kNoAlignment)),
1818                "vld3.8 {d0,d1,d2}, [r1]\n");
1819   COMPARE_BOTH(Vld3(Untyped8,
1820                     NeonRegisterList(d0, d2, kSingle, kMultipleLanes),
1821                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1822                "vld3.8 {d0,d1,d2}, [r1]!\n");
1823   COMPARE_BOTH(Vld3(Untyped8,
1824                     NeonRegisterList(d0, d2, kSingle, kMultipleLanes),
1825                     AlignedMemOperand(r11, kNoAlignment, r2, PostIndex)),
1826                "vld3.8 {d0,d1,d2}, [r11], r2\n");
1827   COMPARE_BOTH(Vld3(Untyped8,
1828                     NeonRegisterList(d0, d2, kSingle, kAllLanes),
1829                     MemOperand(r1)),
1830                "vld3.8 {d0[],d1[],d2[]}, [r1]\n");
1831   COMPARE_BOTH(Vld3(Untyped8,
1832                     NeonRegisterList(d0, d2, kSingle, kAllLanes),
1833                     MemOperand(r11, PostIndex)),
1834                "vld3.8 {d0[],d1[],d2[]}, [r11]!\n");
1835   COMPARE_BOTH(Vld3(Untyped8,
1836                     NeonRegisterList(d0, d2, kSingle, kAllLanes),
1837                     MemOperand(r1, r2, PostIndex)),
1838                "vld3.8 {d0[],d1[],d2[]}, [r1], r2\n");
1839   COMPARE_BOTH(Vld3(Untyped8,
1840                     NeonRegisterList(d0, d2, kSingle, 0),
1841                     MemOperand(sp)),
1842                "vld3.8 {d0[0],d1[0],d2[0]}, [sp]\n");
1843   COMPARE_BOTH(Vld3(Untyped8,
1844                     NeonRegisterList(d0, d2, kSingle, 1),
1845                     MemOperand(r1, PostIndex)),
1846                "vld3.8 {d0[1],d1[1],d2[1]}, [r1]!\n");
1847   COMPARE_BOTH(Vld3(Untyped8,
1848                     NeonRegisterList(d0, d2, kSingle, 2),
1849                     MemOperand(r1, r2, PostIndex)),
1850                "vld3.8 {d0[2],d1[2],d2[2]}, [r1], r2\n");
1851 
1852   COMPARE_BOTH(Vld4(Untyped8,
1853                     NeonRegisterList(d0, d6, kDouble, kMultipleLanes),
1854                     AlignedMemOperand(r1, kNoAlignment)),
1855                "vld4.8 {d0,d2,d4,d6}, [r1]\n");
1856   COMPARE_BOTH(Vld4(Untyped8,
1857                     NeonRegisterList(d0, d3, kSingle, kMultipleLanes),
1858                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1859                "vld4.8 {d0,d1,d2,d3}, [r1]!\n");
1860   COMPARE_BOTH(Vld4(Untyped8,
1861                     NeonRegisterList(d0, d3, kSingle, kMultipleLanes),
1862                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1863                "vld4.8 {d0,d1,d2,d3}, [r1], r2\n");
1864   COMPARE_BOTH(Vld4(Untyped8,
1865                     NeonRegisterList(d0, d3, kSingle, kAllLanes),
1866                     AlignedMemOperand(r1, kNoAlignment)),
1867                "vld4.8 {d0[],d1[],d2[],d3[]}, [r1]\n");
1868   COMPARE_BOTH(Vld4(Untyped8,
1869                     NeonRegisterList(d0, d6, kDouble, kAllLanes),
1870                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1871                "vld4.8 {d0[],d2[],d4[],d6[]}, [r1]!\n");
1872   COMPARE_BOTH(Vld4(Untyped8,
1873                     NeonRegisterList(d0, d3, kSingle, kAllLanes),
1874                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1875                "vld4.8 {d0[],d1[],d2[],d3[]}, [r1], r2\n");
1876   COMPARE_BOTH(Vld4(Untyped16,
1877                     NeonRegisterList(d0, d6, kDouble, 3),
1878                     AlignedMemOperand(r1, kNoAlignment)),
1879                "vld4.16 {d0[3],d2[3],d4[3],d6[3]}, [r1]\n");
1880   COMPARE_BOTH(Vld4(Untyped8,
1881                     NeonRegisterList(d0, d3, kSingle, 6),
1882                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1883                "vld4.8 {d0[6],d1[6],d2[6],d3[6]}, [r1]!\n");
1884   COMPARE_BOTH(Vld4(Untyped8,
1885                     NeonRegisterList(d0, d3, kSingle, 7),
1886                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1887                "vld4.8 {d0[7],d1[7],d2[7],d3[7]}, [r1], r2\n");
1888 
1889   CLEANUP();
1890 }
1891 
1892 
TEST(macro_assembler_vst)1893 TEST(macro_assembler_vst) {
1894   SETUP();
1895 
1896   COMPARE_BOTH(Vst1(Untyped8,
1897                     NeonRegisterList(d0, kMultipleLanes),
1898                     AlignedMemOperand(r1, kNoAlignment)),
1899                "vst1.8 {d0}, [r1]\n");
1900   COMPARE_BOTH(Vst1(Untyped8,
1901                     NeonRegisterList(d0, kMultipleLanes),
1902                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1903                "vst1.8 {d0}, [r1]!\n");
1904   COMPARE_BOTH(Vst1(Untyped8,
1905                     NeonRegisterList(d0, kMultipleLanes),
1906                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1907                "vst1.8 {d0}, [r1], r2\n");
1908   COMPARE_BOTH(Vst1(Untyped8,
1909                     NeonRegisterList(d0, 0),
1910                     AlignedMemOperand(r1, kNoAlignment)),
1911                "vst1.8 {d0[0]}, [r1]\n");
1912   COMPARE_BOTH(Vst1(Untyped8,
1913                     NeonRegisterList(d0, 1),
1914                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1915                "vst1.8 {d0[1]}, [r1]!\n");
1916   COMPARE_BOTH(Vst1(Untyped8,
1917                     NeonRegisterList(d0, 2),
1918                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1919                "vst1.8 {d0[2]}, [r1], r2\n");
1920 
1921   COMPARE_BOTH(Vst2(Untyped8,
1922                     NeonRegisterList(d0, d1, kSingle, kMultipleLanes),
1923                     AlignedMemOperand(r1, kNoAlignment)),
1924                "vst2.8 {d0,d1}, [r1]\n");
1925   COMPARE_BOTH(Vst2(Untyped8,
1926                     NeonRegisterList(d0, d1, kSingle, kMultipleLanes),
1927                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1928                "vst2.8 {d0,d1}, [r1]!\n");
1929   COMPARE_BOTH(Vst2(Untyped8,
1930                     NeonRegisterList(d0, d1, kSingle, kMultipleLanes),
1931                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1932                "vst2.8 {d0,d1}, [r1], r2\n");
1933   COMPARE_BOTH(Vst2(Untyped8,
1934                     NeonRegisterList(d0, d1, kSingle, 3),
1935                     AlignedMemOperand(r1, kNoAlignment)),
1936                "vst2.8 {d0[3],d1[3]}, [r1]\n");
1937   COMPARE_BOTH(Vst2(Untyped8,
1938                     NeonRegisterList(d0, d1, kSingle, 4),
1939                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1940                "vst2.8 {d0[4],d1[4]}, [r1]!\n");
1941   COMPARE_BOTH(Vst2(Untyped8,
1942                     NeonRegisterList(d0, d1, kSingle, 5),
1943                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1944                "vst2.8 {d0[5],d1[5]}, [r1], r2\n");
1945 
1946   COMPARE_BOTH(Vst3(Untyped8,
1947                     NeonRegisterList(d0, d2, kSingle, kMultipleLanes),
1948                     AlignedMemOperand(r1, kNoAlignment)),
1949                "vst3.8 {d0,d1,d2}, [r1]\n");
1950   COMPARE_BOTH(Vst3(Untyped8,
1951                     NeonRegisterList(d0, d2, kSingle, kMultipleLanes),
1952                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1953                "vst3.8 {d0,d1,d2}, [r1]!\n");
1954   COMPARE_BOTH(Vst3(Untyped8,
1955                     NeonRegisterList(d0, d2, kSingle, kMultipleLanes),
1956                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1957                "vst3.8 {d0,d1,d2}, [r1], r2\n");
1958   COMPARE_BOTH(Vst3(Untyped8,
1959                     NeonRegisterList(d0, d2, kSingle, 0),
1960                     MemOperand(r1)),
1961                "vst3.8 {d0[0],d1[0],d2[0]}, [r1]\n");
1962   COMPARE_BOTH(Vst3(Untyped8,
1963                     NeonRegisterList(d0, d2, kSingle, 6),
1964                     MemOperand(r1, PostIndex)),
1965                "vst3.8 {d0[6],d1[6],d2[6]}, [r1]!\n");
1966   COMPARE_BOTH(Vst3(Untyped8,
1967                     NeonRegisterList(d0, d2, kSingle, 7),
1968                     MemOperand(r1, r2, PostIndex)),
1969                "vst3.8 {d0[7],d1[7],d2[7]}, [r1], r2\n");
1970 
1971   COMPARE_BOTH(Vst4(Untyped8,
1972                     NeonRegisterList(d10, d13, kSingle, kMultipleLanes),
1973                     AlignedMemOperand(r1, kNoAlignment)),
1974                "vst4.8 {d10,d11,d12,d13}, [r1]\n");
1975   COMPARE_BOTH(Vst4(Untyped8,
1976                     NeonRegisterList(d10, d13, kSingle, kMultipleLanes),
1977                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1978                "vst4.8 {d10,d11,d12,d13}, [r1]!\n");
1979   COMPARE_BOTH(Vst4(Untyped8,
1980                     NeonRegisterList(d0, d3, kSingle, kMultipleLanes),
1981                     AlignedMemOperand(r8, kNoAlignment, r9, PostIndex)),
1982                "vst4.8 {d0,d1,d2,d3}, [r8], r9\n");
1983   COMPARE_BOTH(Vst4(Untyped8,
1984                     NeonRegisterList(d0, d3, kSingle, 0),
1985                     AlignedMemOperand(r1, kNoAlignment)),
1986                "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [r1]\n");
1987   COMPARE_BOTH(Vst4(Untyped8,
1988                     NeonRegisterList(d0, d3, kSingle, 0),
1989                     AlignedMemOperand(r1, kNoAlignment, PostIndex)),
1990                "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [r1]!\n");
1991   COMPARE_BOTH(Vst4(Untyped8,
1992                     NeonRegisterList(d0, d3, kSingle, 0),
1993                     AlignedMemOperand(r1, kNoAlignment, r2, PostIndex)),
1994                "vst4.8 {d0[0],d1[0],d2[0],d3[0]}, [r1], r2\n");
1995 
1996   CLEANUP();
1997 }
1998 
1999 
TEST(assembler_vldm_vstm_negative)2000 TEST(assembler_vldm_vstm_negative) {
2001   SETUP();
2002 
2003   ExactAssemblyScope scope(&masm, 0, CodeBufferCheckScope::kMaximumSize);
2004 
2005   MUST_FAIL_TEST_BOTH(fldmdbx(pc, WRITE_BACK, DRegisterList(d0)),
2006                       "Unpredictable instruction.\n");
2007   MUST_FAIL_TEST_BOTH(fldmiax(pc, WRITE_BACK, DRegisterList(d0)),
2008                       "Unpredictable instruction.\n");
2009   MUST_FAIL_TEST_T32(fldmiax(pc, NO_WRITE_BACK, DRegisterList(d0)),
2010                      "Unpredictable instruction.\n");
2011 
2012   MUST_FAIL_TEST_BOTH(fstmdbx(pc, WRITE_BACK, DRegisterList(d0)),
2013                       "Unpredictable instruction.\n");
2014   MUST_FAIL_TEST_BOTH(fstmiax(pc, WRITE_BACK, DRegisterList(d0)),
2015                       "Unpredictable instruction.\n");
2016   MUST_FAIL_TEST_T32(fstmiax(pc, NO_WRITE_BACK, DRegisterList(d0)),
2017                      "Unpredictable instruction.\n");
2018 
2019   MUST_FAIL_TEST_BOTH(vldmdb(pc, WRITE_BACK, SRegisterList(s0)),
2020                       "Unpredictable instruction.\n");
2021   MUST_FAIL_TEST_BOTH(vldm(pc, WRITE_BACK, SRegisterList(s0)),
2022                       "Unpredictable instruction.\n");
2023   MUST_FAIL_TEST_T32(vldm(pc, NO_WRITE_BACK, SRegisterList(s0)),
2024                      "Unpredictable instruction.\n");
2025   MUST_FAIL_TEST_BOTH(vldmia(pc, WRITE_BACK, SRegisterList(s0)),
2026                       "Unpredictable instruction.\n");
2027   MUST_FAIL_TEST_T32(vldmia(pc, NO_WRITE_BACK, SRegisterList(s0)),
2028                      "Unpredictable instruction.\n");
2029 
2030   MUST_FAIL_TEST_BOTH(vldmdb(pc, WRITE_BACK, DRegisterList(d0)),
2031                       "Unpredictable instruction.\n");
2032   MUST_FAIL_TEST_BOTH(vldm(pc, WRITE_BACK, DRegisterList(d0)),
2033                       "Unpredictable instruction.\n");
2034   MUST_FAIL_TEST_T32(vldm(pc, NO_WRITE_BACK, DRegisterList(d0)),
2035                      "Unpredictable instruction.\n");
2036   MUST_FAIL_TEST_BOTH(vldmia(pc, WRITE_BACK, DRegisterList(d0)),
2037                       "Unpredictable instruction.\n");
2038   MUST_FAIL_TEST_T32(vldmia(pc, NO_WRITE_BACK, DRegisterList(d0)),
2039                      "Unpredictable instruction.\n");
2040 
2041   MUST_FAIL_TEST_BOTH(vstmdb(pc, WRITE_BACK, SRegisterList(s0)),
2042                       "Unpredictable instruction.\n");
2043   MUST_FAIL_TEST_BOTH(vstm(pc, WRITE_BACK, SRegisterList(s0)),
2044                       "Unpredictable instruction.\n");
2045   MUST_FAIL_TEST_T32(vstm(pc, NO_WRITE_BACK, SRegisterList(s0)),
2046                      "Unpredictable instruction.\n");
2047   MUST_FAIL_TEST_BOTH(vstmia(pc, WRITE_BACK, SRegisterList(s0)),
2048                       "Unpredictable instruction.\n");
2049   MUST_FAIL_TEST_T32(vstmia(pc, NO_WRITE_BACK, SRegisterList(s0)),
2050                      "Unpredictable instruction.\n");
2051 
2052   MUST_FAIL_TEST_BOTH(vstmdb(pc, WRITE_BACK, DRegisterList(d0)),
2053                       "Unpredictable instruction.\n");
2054   MUST_FAIL_TEST_BOTH(vstm(pc, WRITE_BACK, DRegisterList(d0)),
2055                       "Unpredictable instruction.\n");
2056   MUST_FAIL_TEST_T32(vstm(pc, NO_WRITE_BACK, DRegisterList(d0)),
2057                      "Unpredictable instruction.\n");
2058   MUST_FAIL_TEST_BOTH(vstmia(pc, WRITE_BACK, DRegisterList(d0)),
2059                       "Unpredictable instruction.\n");
2060   MUST_FAIL_TEST_T32(vstmia(pc, NO_WRITE_BACK, DRegisterList(d0)),
2061                      "Unpredictable instruction.\n");
2062 
2063   CLEANUP();
2064 }
2065 
2066 
2067 #define TEST_VMEMOP(MACRO_OP, STRING_OP, DST_REG)                    \
2068   SETUP();                                                           \
2069                                                                      \
2070   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 1024)),               \
2071               "add ip, r8, #1024\n" STRING_OP #DST_REG ", [ip]\n");  \
2072   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 1371)),               \
2073               "add ip, r8, #1371\n" STRING_OP #DST_REG ", [ip]\n");  \
2074   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 4113)),               \
2075               "add ip, r8, #17\n"                                    \
2076               "add ip, #4096\n" STRING_OP #DST_REG ", [ip]\n");      \
2077   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 65808)),              \
2078               "add ip, r8, #272\n"                                   \
2079               "add ip, #65536\n" STRING_OP #DST_REG ", [ip]\n");     \
2080                                                                      \
2081   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -1024)),              \
2082               "sub ip, r8, #1024\n" STRING_OP #DST_REG ", [ip]\n");  \
2083   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -1371)),              \
2084               "sub ip, r8, #1371\n" STRING_OP #DST_REG ", [ip]\n");  \
2085   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -4113)),              \
2086               "sub ip, r8, #17\n"                                    \
2087               "sub ip, #4096\n" STRING_OP #DST_REG ", [ip]\n");      \
2088   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -65808)),             \
2089               "sub ip, r8, #272\n"                                   \
2090               "sub ip, #65536\n" STRING_OP #DST_REG ", [ip]\n");     \
2091                                                                      \
2092   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 0, PreIndex)),        \
2093               STRING_OP #DST_REG ", [r9]\n");                        \
2094   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 137, PreIndex)),      \
2095               "add r9, #137\n" STRING_OP #DST_REG ", [r9]\n");       \
2096   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 4110, PreIndex)),     \
2097               "add r9, #14\n"                                        \
2098               "add r9, #4096\n" STRING_OP #DST_REG ", [r9]\n");      \
2099   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 65623, PreIndex)),    \
2100               "add r9, #87\n"                                        \
2101               "add r9, #65536\n" STRING_OP #DST_REG ", [r9]\n");     \
2102                                                                      \
2103   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -137, PreIndex)),     \
2104               "sub r9, #137\n" STRING_OP #DST_REG ", [r9]\n");       \
2105   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -4110, PreIndex)),    \
2106               "sub r9, #14\n"                                        \
2107               "sub r9, #4096\n" STRING_OP #DST_REG ", [r9]\n");      \
2108   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -65623, PreIndex)),   \
2109               "sub r9, #87\n"                                        \
2110               "sub r9, #65536\n" STRING_OP #DST_REG ", [r9]\n");     \
2111                                                                      \
2112   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 0, PostIndex)),      \
2113               STRING_OP #DST_REG ", [r10]\n");                       \
2114   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 137, PostIndex)),    \
2115               STRING_OP #DST_REG                                     \
2116               ", [r10]\n"                                            \
2117               "add r10, #137\n");                                    \
2118   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 4110, PostIndex)),   \
2119               STRING_OP #DST_REG                                     \
2120               ", [r10]\n"                                            \
2121               "add r10, #14\n"                                       \
2122               "add r10, #4096\n");                                   \
2123   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 65623, PostIndex)),  \
2124               STRING_OP #DST_REG                                     \
2125               ", [r10]\n"                                            \
2126               "add r10, #87\n"                                       \
2127               "add r10, #65536\n");                                  \
2128                                                                      \
2129   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -137, PostIndex)),   \
2130               STRING_OP #DST_REG                                     \
2131               ", [r10]\n"                                            \
2132               "sub r10, #137\n");                                    \
2133   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -4110, PostIndex)),  \
2134               STRING_OP #DST_REG                                     \
2135               ", [r10]\n"                                            \
2136               "sub r10, #14\n"                                       \
2137               "sub r10, #4096\n");                                   \
2138   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -65623, PostIndex)), \
2139               STRING_OP #DST_REG                                     \
2140               ", [r10]\n"                                            \
2141               "sub r10, #87\n"                                       \
2142               "sub r10, #65536\n");                                  \
2143   CLEANUP();
2144 
TEST(macro_assembler_T32_Vldr_d)2145 TEST(macro_assembler_T32_Vldr_d) { TEST_VMEMOP(Vldr, "vldr ", d0); }
2146 
TEST(macro_assembler_T32_Vstr_d)2147 TEST(macro_assembler_T32_Vstr_d) { TEST_VMEMOP(Vstr, "vstr ", d1); }
2148 
TEST(macro_assembler_T32_Vldr_s)2149 TEST(macro_assembler_T32_Vldr_s) { TEST_VMEMOP(Vldr, "vldr ", s2); }
2150 
TEST(macro_assembler_T32_Vstr_s)2151 TEST(macro_assembler_T32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); }
2152 
2153 #undef TEST_VMEMOP
2154 
2155 #define TEST_VMEMOP(MACRO_OP, STRING_OP, DST_REG)                    \
2156   SETUP();                                                           \
2157                                                                      \
2158   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 137)),                \
2159               "add ip, r8, #137\n" STRING_OP #DST_REG ", [ip]\n");   \
2160   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 274)),                \
2161               "add ip, r8, #18\n"                                    \
2162               "add ip, #256\n" STRING_OP #DST_REG ", [ip]\n");       \
2163   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 65623)),              \
2164               "add ip, r8, #87\n"                                    \
2165               "add ip, #65536\n" STRING_OP #DST_REG ", [ip]\n");     \
2166                                                                      \
2167   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -137)),               \
2168               "sub ip, r8, #137\n" STRING_OP #DST_REG ", [ip]\n");   \
2169   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -274)),               \
2170               "sub ip, r8, #18\n"                                    \
2171               "sub ip, #256\n" STRING_OP #DST_REG ", [ip]\n");       \
2172   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -65623)),             \
2173               "sub ip, r8, #87\n"                                    \
2174               "sub ip, #65536\n" STRING_OP #DST_REG ", [ip]\n");     \
2175                                                                      \
2176   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 0, PreIndex)),        \
2177               STRING_OP #DST_REG ", [r9]\n");                        \
2178   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 137, PreIndex)),      \
2179               "add r9, #137\n" STRING_OP #DST_REG ", [r9]\n");       \
2180   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 274, PreIndex)),      \
2181               "add r9, #18\n"                                        \
2182               "add r9, #256\n" STRING_OP #DST_REG ", [r9]\n");       \
2183   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 65623, PreIndex)),    \
2184               "add r9, #87\n"                                        \
2185               "add r9, #65536\n" STRING_OP #DST_REG ", [r9]\n");     \
2186                                                                      \
2187   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -137, PreIndex)),     \
2188               "sub r9, #137\n" STRING_OP #DST_REG ", [r9]\n");       \
2189   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -274, PreIndex)),     \
2190               "sub r9, #18\n"                                        \
2191               "sub r9, #256\n" STRING_OP #DST_REG ", [r9]\n");       \
2192   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -65623, PreIndex)),   \
2193               "sub r9, #87\n"                                        \
2194               "sub r9, #65536\n" STRING_OP #DST_REG ", [r9]\n");     \
2195                                                                      \
2196   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 0, PostIndex)),      \
2197               STRING_OP #DST_REG ", [r10]\n");                       \
2198   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 137, PostIndex)),    \
2199               STRING_OP #DST_REG                                     \
2200               ", [r10]\n"                                            \
2201               "add r10, #137\n");                                    \
2202   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 274, PostIndex)),    \
2203               STRING_OP #DST_REG                                     \
2204               ", [r10]\n"                                            \
2205               "add r10, #18\n"                                       \
2206               "add r10, #256\n");                                    \
2207   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 65623, PostIndex)),  \
2208               STRING_OP #DST_REG                                     \
2209               ", [r10]\n"                                            \
2210               "add r10, #87\n"                                       \
2211               "add r10, #65536\n");                                  \
2212                                                                      \
2213   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -137, PostIndex)),   \
2214               STRING_OP #DST_REG                                     \
2215               ", [r10]\n"                                            \
2216               "sub r10, #137\n");                                    \
2217   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -274, PostIndex)),   \
2218               STRING_OP #DST_REG                                     \
2219               ", [r10]\n"                                            \
2220               "sub r10, #18\n"                                       \
2221               "sub r10, #256\n");                                    \
2222   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -65623, PostIndex)), \
2223               STRING_OP #DST_REG                                     \
2224               ", [r10]\n"                                            \
2225               "sub r10, #87\n"                                       \
2226               "sub r10, #65536\n");                                  \
2227   CLEANUP();
2228 
2229 
TEST(macro_assembler_A32_Vldr_d)2230 TEST(macro_assembler_A32_Vldr_d) { TEST_VMEMOP(Vldr, "vldr ", d0); }
2231 
TEST(macro_assembler_A32_Vstr_d)2232 TEST(macro_assembler_A32_Vstr_d) { TEST_VMEMOP(Vstr, "vstr ", d1); }
2233 
TEST(macro_assembler_A32_Vldr_s)2234 TEST(macro_assembler_A32_Vldr_s) { TEST_VMEMOP(Vldr, "vldr ", s2); }
2235 
TEST(macro_assembler_A32_Vstr_s)2236 TEST(macro_assembler_A32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); }
2237 
2238 #undef TEST_VMEMOP
2239 
TEST(assembler_vstr_negative)2240 TEST(assembler_vstr_negative) {
2241   SETUP();
2242 
2243   ExactAssemblyScope scope(&masm, 8, CodeBufferCheckScope::kMaximumSize);
2244 
2245   MUST_FAIL_TEST_T32(vstr(s0, MemOperand(pc, 0)),
2246                      "Unpredictable instruction.\n");
2247 
2248   MUST_FAIL_TEST_T32(vstr(d0, MemOperand(pc, 0)),
2249                      "Unpredictable instruction.\n");
2250 
2251   CLEANUP();
2252 }
2253 
TEST(macro_assembler_Vldr_Vstr_negative)2254 TEST(macro_assembler_Vldr_Vstr_negative) {
2255   SETUP();
2256 
2257   MUST_FAIL_TEST_BOTH(Vldr(s0, MemOperand(pc, 1, PreIndex)),
2258                       "The MacroAssembler does not convert vldr or vstr"
2259                       " with a PC base register.\n");
2260 
2261   MUST_FAIL_TEST_BOTH(Vldr(s0, MemOperand(pc, r0, PreIndex)),
2262                       "Ill-formed 'vldr' instruction.\n");
2263 
2264   MUST_FAIL_TEST_BOTH(Vstr(s0, MemOperand(pc, 1, PreIndex)),
2265                       "The MacroAssembler does not convert vldr or vstr"
2266                       " with a PC base register.\n");
2267 
2268   MUST_FAIL_TEST_BOTH(Vstr(s0, MemOperand(pc, r0, PreIndex)),
2269                       "Ill-formed 'vstr' instruction.\n");
2270 
2271   MUST_FAIL_TEST_BOTH(Vldr(d0, MemOperand(pc, 1, PreIndex)),
2272                       "The MacroAssembler does not convert vldr or vstr"
2273                       " with a PC base register.\n");
2274 
2275   MUST_FAIL_TEST_BOTH(Vldr(d0, MemOperand(pc, r0, PreIndex)),
2276                       "Ill-formed 'vldr' instruction.\n");
2277 
2278   MUST_FAIL_TEST_BOTH(Vstr(d0, MemOperand(pc, 1, PreIndex)),
2279                       "The MacroAssembler does not convert vldr or vstr"
2280                       " with a PC base register.\n");
2281 
2282   MUST_FAIL_TEST_BOTH(Vstr(d0, MemOperand(pc, r0, PreIndex)),
2283                       "Ill-formed 'vstr' instruction.\n");
2284   CLEANUP();
2285 }
2286 
2287 #define TEST_SHIFT_T32(Inst, name, offset)          \
2288   COMPARE_T32(Inst(r0, Operand(r1, LSL, r2)),       \
2289               "lsl ip, r1, r2\n" name " r0, ip\n"); \
2290   COMPARE_T32(Inst(r0, Operand(r1, LSR, r2)),       \
2291               "lsr ip, r1, r2\n" name " r0, ip\n"); \
2292   COMPARE_T32(Inst(r0, Operand(r1, ASR, r2)),       \
2293               "asr ip, r1, r2\n" name " r0, ip\n"); \
2294   COMPARE_T32(Inst(r0, Operand(r1, ROR, r2)),       \
2295               "ror ip, r1, r2\n" name " r0, ip\n"); \
2296   COMPARE_T32(Inst(eq, r0, Operand(r1, LSL, r2)),   \
2297               "bne " #offset                        \
2298               "\n"                                  \
2299               "lsl ip, r1, r2\n" name " r0, ip\n"); \
2300   COMPARE_T32(Inst(le, r0, Operand(r1, LSL, r2)),   \
2301               "bgt " #offset                        \
2302               "\n"                                  \
2303               "lsl ip, r1, r2\n" name " r0, ip\n");
2304 
2305 #define TEST_MOV_SHIFT_T32(Inst, s, offset)                             \
2306   COMPARE_T32(Inst(r0, Operand(r1, LSL, r2)), "lsl" s " r0, r1, r2\n"); \
2307   COMPARE_T32(Inst(r0, Operand(r1, LSR, r2)), "lsr" s " r0, r1, r2\n"); \
2308   COMPARE_T32(Inst(r0, Operand(r1, ASR, r2)), "asr" s " r0, r1, r2\n"); \
2309   COMPARE_T32(Inst(r0, Operand(r1, ROR, r2)), "ror" s " r0, r1, r2\n"); \
2310   COMPARE_T32(Inst(eq, r0, Operand(r1, LSL, r2)),                       \
2311               "bne " #offset                                            \
2312               "\n"                                                      \
2313               "lsl" s " r0, r1, r2\n");                                 \
2314   COMPARE_T32(Inst(le, r0, Operand(r1, LSL, r2)),                       \
2315               "bgt " #offset                                            \
2316               "\n"                                                      \
2317               "lsl" s " r0, r1, r2\n");
2318 
2319 #define TEST_WIDE_IMMEDIATE(Inst, name, offset)         \
2320   COMPARE_BOTH(Inst(r0, 0xbadbeef),                     \
2321                "mov ip, #48879\n"                       \
2322                "movt ip, #2989\n" name " r0, ip\n");    \
2323   COMPARE_A32(Inst(eq, r0, 0xbadbeef),                  \
2324               "moveq ip, #48879\n"                      \
2325               "movteq ip, #2989\n" name "eq r0, ip\n"); \
2326   COMPARE_T32(Inst(eq, r0, 0xbadbeef),                  \
2327               "bne " #offset                            \
2328               "\n"                                      \
2329               "mov ip, #48879\n"                        \
2330               "movt ip, #2989\n" name " r0, ip\n");
2331 
2332 #define TEST_WIDE_IMMEDIATE_PC(Inst, name, offset)            \
2333   COMPARE_A32(Inst(pc, 0xbadbeef),                            \
2334               "mov ip, #48879\n"                              \
2335               "movt ip, #2989\n" name " pc, ip\n");           \
2336   COMPARE_A32(Inst(eq, pc, 0xbadbeef),                        \
2337               "moveq ip, #48879\n"                            \
2338               "movteq ip, #2989\n" name "eq pc, ip\n");       \
2339   MUST_FAIL_TEST_T32(Inst(pc, 0xbadbeef),                     \
2340                      "Ill-formed '" name "' instruction.\n"); \
2341   MUST_FAIL_TEST_T32(Inst(eq, pc, 0xbadbeef),                 \
2342                      "Ill-formed '" name "' instruction.\n");
2343 
TEST(macro_assembler_InstructionCondSizeROp)2344 TEST(macro_assembler_InstructionCondSizeROp) {
2345   SETUP();
2346 
2347   // T32 register shifted register.
2348   TEST_SHIFT_T32(Cmn, "cmn", 0x0000000a)
2349   TEST_SHIFT_T32(Cmp, "cmp", 0x00000008)
2350   TEST_SHIFT_T32(Mvn, "mvn", 0x0000000a)
2351   TEST_SHIFT_T32(Mvns, "mvns", 0x0000000a)
2352   TEST_SHIFT_T32(Sxtb, "sxtb", 0x0000000a)
2353   TEST_SHIFT_T32(Sxth, "sxth", 0x0000000a)
2354   TEST_SHIFT_T32(Tst, "tst", 0x0000000a)
2355   TEST_SHIFT_T32(Uxtb, "uxtb", 0x0000000a)
2356   TEST_SHIFT_T32(Uxth, "uxth", 0x0000000a)
2357 
2358   TEST_MOV_SHIFT_T32(Mov, "", 0x00000006)
2359   TEST_MOV_SHIFT_T32(Movs, "s", 0x00000006)
2360 
2361   MUST_FAIL_TEST_BOTH(Movs(pc, r0), "Unpredictable instruction.\n");
2362   MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, LSL, 0x4)),
2363                       "Unpredictable instruction.\n");
2364   MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, ASR, r2)),
2365                       "Unpredictable instruction.\n");
2366 
2367   // Wide immediates (Mov and Movs are tested in
2368   // "macro_assembler_wide_immediate").
2369   TEST_WIDE_IMMEDIATE(Cmp, "cmp", 0x0000000c);
2370   TEST_WIDE_IMMEDIATE(Cmn, "cmn", 0x0000000e);
2371   TEST_WIDE_IMMEDIATE(Tst, "tst", 0x0000000e);
2372   TEST_WIDE_IMMEDIATE_PC(Cmp, "cmp", 0x0000000c);
2373   TEST_WIDE_IMMEDIATE_PC(Cmn, "cmn", 0x0000000e);
2374   TEST_WIDE_IMMEDIATE_PC(Tst, "tst", 0x0000000e);
2375 
2376   // For Mvn and Mvns, we don't allow PC as a destination.
2377   TEST_WIDE_IMMEDIATE(Mvn, "mvn", 0x0000000e);
2378   TEST_WIDE_IMMEDIATE(Mvns, "mvns", 0x0000000e);
2379   MUST_FAIL_TEST_BOTH(Mvn(pc, 0xbadbeef), "Ill-formed 'mvn' instruction.\n");
2380   MUST_FAIL_TEST_BOTH(Mvn(eq, pc, 0xbadbeef),
2381                       "Ill-formed 'mvn' instruction.\n");
2382   MUST_FAIL_TEST_BOTH(Mvns(pc, 0xbadbeef), "Ill-formed 'mvns' instruction.\n");
2383   MUST_FAIL_TEST_BOTH(Mvns(eq, pc, 0xbadbeef),
2384                       "Ill-formed 'mvns' instruction.\n");
2385 
2386   MUST_FAIL_TEST_BOTH(Sxtb(r0, 0x1), "Ill-formed 'sxtb' instruction.\n");
2387   MUST_FAIL_TEST_BOTH(Sxth(r0, 0x1), "Ill-formed 'sxth' instruction.\n");
2388   MUST_FAIL_TEST_BOTH(Uxtb(r0, 0x1), "Ill-formed 'uxtb' instruction.\n");
2389   MUST_FAIL_TEST_BOTH(Uxth(r0, 0x1), "Ill-formed 'uxth' instruction.\n");
2390 
2391   CLEANUP();
2392 }
2393 
2394 #undef TEST_SHIFT_T32
2395 #undef TEST_MOV_SHIFT_T32
2396 #undef TEST_WIDE_IMMEDIATE
2397 #undef TEST_WIDE_IMMEDIATE_PC
2398 
TEST(macro_assembler_Msr)2399 TEST(macro_assembler_Msr) {
2400   SETUP();
2401 
2402   // Msr with immediate for T32.
2403   COMPARE_T32(Msr(APSR_nzcvq, 0x0),
2404               "mov ip, #0\n"
2405               "msr APSR_nzcvq, ip\n");
2406 
2407   // Wide immediate.
2408   COMPARE_BOTH(Msr(APSR_nzcvq, 0xbadbeef),
2409                "mov ip, #48879\n"
2410                "movt ip, #2989\n"
2411                "msr APSR_nzcvq, ip\n");
2412 
2413   // Other types of operands are not handled.
2414   MUST_FAIL_TEST_BOTH(Msr(APSR_nzcvq, Operand(r0, LSR, r1)),
2415                       "Ill-formed 'msr' instruction.\n");
2416   CLEANUP();
2417 }
2418 
2419 
TEST(macro_assembler_Vmov_imm)2420 TEST(macro_assembler_Vmov_imm) {
2421   SETUP();
2422 
2423   COMPARE_BOTH(Vmov(s0, 0.0f),
2424                "mov ip, #0\n"
2425                "vmov s0, ip\n");
2426   COMPARE_BOTH(Vmov(s1, 1.0f), "vmov.f32 s1, #1\n");
2427   COMPARE_BOTH(Vmov(s2, RawbitsToFloat(0x0000db6c)),
2428                "mov ip, #56172\n"
2429                "vmov s2, ip\n");
2430   COMPARE_BOTH(Vmov(s3, RawbitsToFloat(0x327b23c6)),
2431                "mov ip, #9158\n"
2432                "movt ip, #12923\n"
2433                "vmov s3, ip\n");
2434   COMPARE_BOTH(Vmov(s4, RawbitsToFloat(0xffcc7fff)),
2435                "mvn ip, #3375104\n"
2436                "vmov s4, ip\n");
2437   COMPARE_BOTH(Vmov(s5, RawbitsToFloat(0xb72df575)),
2438                "mov ip, #62837\n"
2439                "movt ip, #46893\n"
2440                "vmov s5, ip\n");
2441 
2442   COMPARE_BOTH(Vmov(d6, 0.0), "vmov.i64 d6, #0x0000000000000000\n");
2443   COMPARE_BOTH(Vmov(d7, 1.0), "vmov.f64 d7, #1\n");
2444   COMPARE_BOTH(Vmov(d8, RawbitsToDouble(0x000000000000af8e)),
2445                "mov ip, #44942\n"
2446                "vdup.32 d8, ip\n"
2447                "mov ip, #0\n"
2448                "vmov.32 d8[1], ip\n");
2449   COMPARE_BOTH(Vmov(d9, RawbitsToDouble(0x000070210000af8e)),
2450                "mov ip, #44942\n"
2451                "vdup.32 d9, ip\n"
2452                "mov ip, #28705\n"
2453                "vmov.32 d9[1], ip\n");
2454   COMPARE_BOTH(Vmov(d10, RawbitsToDouble(0x7021000000000000)),
2455                "mov ip, #0\n"
2456                "vdup.32 d10, ip\n"
2457                "mov ip, #0\n"
2458                "movt ip, #28705\n"
2459                "vmov.32 d10[1], ip\n");
2460   COMPARE_BOTH(Vmov(d11, RawbitsToDouble(0x7021da4b0000af8e)),
2461                "mov ip, #44942\n"
2462                "vdup.32 d11, ip\n"
2463                "mov ip, #55883\n"
2464                "movt ip, #28705\n"
2465                "vmov.32 d11[1], ip\n");
2466   COMPARE_BOTH(Vmov(d12, RawbitsToDouble(0x0cff553204ec4a3f)),
2467                "mov ip, #19007\n"
2468                "movt ip, #1260\n"
2469                "vdup.32 d12, ip\n"
2470                "mov ip, #21810\n"
2471                "movt ip, #3327\n"
2472                "vmov.32 d12[1], ip\n");
2473   COMPARE_BOTH(Vmov(d13, RawbitsToDouble(0xa2037ad20000f592)),
2474                "mov ip, #62866\n"
2475                "vdup.32 d13, ip\n"
2476                "mov ip, #31442\n"
2477                "movt ip, #41475\n"
2478                "vmov.32 d13[1], ip\n");
2479   COMPARE_BOTH(Vmov(d14, RawbitsToDouble(0xe62556c325a59470)),
2480                "mov ip, #38000\n"
2481                "movt ip, #9637\n"
2482                "vdup.32 d14, ip\n"
2483                "mov ip, #22211\n"
2484                "movt ip, #58917\n"
2485                "vmov.32 d14[1], ip\n");
2486   CLEANUP();
2487 }
2488 
TEST(macro_assembler_PushRegisterList)2489 TEST(macro_assembler_PushRegisterList) {
2490   SETUP();
2491 
2492   // Allow the test to use all registers.
2493   UseScratchRegisterScope temps(&masm);
2494   temps.ExcludeAll();
2495 
2496   COMPARE_BOTH(Push(RegisterList(0x1111)), "push {r0,r4,r8,ip}\n");
2497 
2498   COMPARE_BOTH(Push(RegisterList(0x1fff)),
2499                "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2500 
2501   COMPARE_BOTH(Push(RegisterList(0x5fff)),
2502                "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip,lr}\n");
2503 
2504   COMPARE_A32(Push(ne, RegisterList(0x1fff)),
2505               "pushne {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2506 
2507   COMPARE_T32(Push(ne, RegisterList(0x1fff)),
2508               "beq 0x00000006\n"
2509               "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2510 
2511   // Narrow form, T1.
2512   COMPARE_T32(Pop(RegisterList(r0)), "pop {r0}\n");
2513   // <single_register_list> form, T4
2514   COMPARE_T32(Pop(RegisterList(r10)), "pop {r10}\n");
2515 
2516   // It is usually UNPREDICTABLE to push sp.
2517   MUST_FAIL_TEST_BOTH(Push(RegisterList(r0, sp)),
2518                       "Unpredictable instruction.\n");
2519   MUST_FAIL_TEST_T32(Push(RegisterList(sp)), "Unpredictable instruction.\n");
2520   MUST_FAIL_TEST_T32(Push(sp), "Unpredictable instruction.\n");
2521   // A32 can push sp if it is the first register in the list.
2522   COMPARE_A32(Push(sp), "stmdb sp!, {sp}\n");
2523   COMPARE_A32(Push(RegisterList(sp)), "stmdb sp!, {sp}\n");
2524   COMPARE_A32(Push(RegisterList(sp, lr)), "push {sp,lr}\n");
2525 
2526   // Deprecated, but accepted:
2527   SHOULD_FAIL_TEST_A32(Push(pc));
2528   SHOULD_FAIL_TEST_A32(Push(RegisterList(pc)));
2529   SHOULD_FAIL_TEST_A32(Push(RegisterList(r0, pc)));
2530 
2531   MUST_FAIL_TEST_T32(Push(pc), "Unpredictable instruction.\n");
2532   MUST_FAIL_TEST_T32(Push(RegisterList(pc)), "Unpredictable instruction.\n");
2533   // The multiple-register T32 push can't encode PC at all.
2534   MUST_FAIL_TEST_T32(Push(RegisterList(r0, pc)),
2535                      "Ill-formed 'push' instruction.\n");
2536 
2537   // The following use the PUSH (T1) and PUSH (single register) (A1) encodings
2538   // for T32 and A32 respectively:
2539   COMPARE_BOTH(Push(RegisterList(r0)), "push {r0}\n");
2540   COMPARE_BOTH(Push(RegisterList(r7)), "push {r7}\n");
2541   COMPARE_BOTH(Push(RegisterList(lr)), "push {lr}\n");
2542 
2543   // PUSH (single register), T4 and A1 encodings:
2544   COMPARE_BOTH(Push(RegisterList(r8)), "push {r8}\n");
2545 
2546   // Pushing zero registers should produce no instructions.
2547   COMPARE_BOTH(Push(RegisterList()), "");
2548 
2549   CLEANUP();
2550 }
2551 
TEST(macro_assembler_PopRegisterList)2552 TEST(macro_assembler_PopRegisterList) {
2553   SETUP();
2554 
2555   // Allow the test to use all registers.
2556   UseScratchRegisterScope temps(&masm);
2557   temps.ExcludeAll();
2558 
2559   COMPARE_BOTH(Pop(RegisterList(0x1111)), "pop {r0,r4,r8,ip}\n");
2560 
2561   COMPARE_BOTH(Pop(RegisterList(0x1fff)),
2562                "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2563 
2564   COMPARE_BOTH(Pop(RegisterList(0x5fff)),
2565                "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip,lr}\n");
2566 
2567   COMPARE_A32(Pop(ne, RegisterList(0x1fff)),
2568               "popne {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2569 
2570   COMPARE_T32(Pop(ne, RegisterList(0x1fff)),
2571               "beq 0x00000006\n"
2572               "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2573 
2574   // Narrow form, T1.
2575   COMPARE_T32(Pop(RegisterList(r0)), "pop {r0}\n");
2576   // <single_register_list> form, T4.
2577   COMPARE_T32(Pop(RegisterList(r10)), "pop {r10}\n");
2578 
2579   // It is UNPREDICTABLE to pop sp.
2580   MUST_FAIL_TEST_BOTH(Pop(RegisterList(r0, sp)),
2581                       "Unpredictable instruction.\n");
2582   MUST_FAIL_TEST_BOTH(Pop(RegisterList(sp)), "Unpredictable instruction.\n");
2583   MUST_FAIL_TEST_BOTH(Pop(sp), "Unpredictable instruction.\n");
2584 
2585   // The following use the POP (T1) and POP (single register) (A1) encodings for
2586   // T32 and A32 respectively:
2587   COMPARE_BOTH(Pop(RegisterList(pc)), "pop {pc}\n");
2588   COMPARE_BOTH(Pop(RegisterList(r0)), "pop {r0}\n");
2589   COMPARE_BOTH(Pop(RegisterList(r7)), "pop {r7}\n");
2590 
2591   // POP (single register), T4 and A1 encodings:
2592   COMPARE_BOTH(Pop(RegisterList(r8)), "pop {r8}\n");
2593   COMPARE_BOTH(Pop(RegisterList(lr)), "pop {lr}\n");
2594 
2595   MUST_FAIL_TEST_T32(Pop(RegisterList(lr, pc)), "Unpredictable instruction.\n");
2596   // Deprecated, but allowed.
2597   COMPARE_A32(Pop(RegisterList(lr, pc)), "pop {lr,pc}\n");
2598 
2599   // Popping zero registers should produce no instructions.
2600   COMPARE_BOTH(Pop(RegisterList()), "");
2601 
2602   CLEANUP();
2603 }
2604 
2605 
TEST(macro_assembler_unpredictable)2606 TEST(macro_assembler_unpredictable) {
2607   SETUP();
2608 
2609   // ADC, ADCS (immediate).
2610   COMPARE_A32(Adc(pc, r0, 1), "adc pc, r0, #1\n");
2611   COMPARE_A32(Adc(r0, pc, 1), "adc r0, pc, #1\n");
2612   MUST_FAIL_TEST_T32(Adc(pc, r0, 1), "Unpredictable instruction.\n");
2613   MUST_FAIL_TEST_T32(Adc(r0, pc, 1), "Unpredictable instruction.\n");
2614   COMPARE_A32(Adcs(pc, r0, 1), "adcs pc, r0, #1\n");
2615   COMPARE_A32(Adcs(r0, pc, 1), "adcs r0, pc, #1\n");
2616   MUST_FAIL_TEST_T32(Adcs(pc, r0, 1), "Unpredictable instruction.\n");
2617   MUST_FAIL_TEST_T32(Adcs(r0, pc, 1), "Unpredictable instruction.\n");
2618 
2619   // ADC, ADCS (register).
2620   COMPARE_A32(Adc(pc, r0, r1), "adc pc, r0, r1\n");
2621   COMPARE_A32(Adc(r0, pc, r1), "adc r0, pc, r1\n");
2622   COMPARE_A32(Adc(r0, r1, pc), "adc r0, r1, pc\n");
2623   MUST_FAIL_TEST_T32(Adc(pc, r0, r1), "Unpredictable instruction.\n");
2624   MUST_FAIL_TEST_T32(Adc(r0, pc, r1), "Unpredictable instruction.\n");
2625   MUST_FAIL_TEST_T32(Adc(r0, r1, pc), "Unpredictable instruction.\n");
2626   COMPARE_A32(Adcs(pc, r0, r1), "adcs pc, r0, r1\n");
2627   COMPARE_A32(Adcs(r0, pc, r1), "adcs r0, pc, r1\n");
2628   COMPARE_A32(Adcs(r0, r1, pc), "adcs r0, r1, pc\n");
2629   MUST_FAIL_TEST_T32(Adcs(pc, r0, r1), "Unpredictable instruction.\n");
2630   MUST_FAIL_TEST_T32(Adcs(r0, pc, r1), "Unpredictable instruction.\n");
2631   MUST_FAIL_TEST_T32(Adcs(r0, r1, pc), "Unpredictable instruction.\n");
2632 
2633   // ADC, ADCS (register-shifted register).
2634   MUST_FAIL_TEST_A32(Adc(pc, r0, Operand(r1, LSL, r2)),
2635                      "Unpredictable instruction.\n");
2636   MUST_FAIL_TEST_A32(Adc(r0, pc, Operand(r1, LSL, r2)),
2637                      "Unpredictable instruction.\n");
2638   MUST_FAIL_TEST_A32(Adc(r0, r1, Operand(pc, LSL, r2)),
2639                      "Unpredictable instruction.\n");
2640   MUST_FAIL_TEST_A32(Adc(r0, r1, Operand(r2, LSL, pc)),
2641                      "Unpredictable instruction.\n");
2642   MUST_FAIL_TEST_A32(Adcs(pc, r0, Operand(r1, LSL, r2)),
2643                      "Unpredictable instruction.\n");
2644   MUST_FAIL_TEST_A32(Adcs(r0, pc, Operand(r1, LSL, r2)),
2645                      "Unpredictable instruction.\n");
2646   MUST_FAIL_TEST_A32(Adcs(r0, r1, Operand(pc, LSL, r2)),
2647                      "Unpredictable instruction.\n");
2648   MUST_FAIL_TEST_A32(Adcs(r0, r1, Operand(r2, LSL, pc)),
2649                      "Unpredictable instruction.\n");
2650 
2651   // ADD (immediate, to PC).
2652   COMPARE_A32(Add(r0, pc, 1), "adr r0, 0x00000009\n");
2653   COMPARE_T32(Add(r0, pc, 1), "adr r0, 0x00000005\n");
2654   COMPARE_A32(Add(pc, pc, 1), "adr pc, 0x00000009\n");
2655   MUST_FAIL_TEST_T32(Add(pc, pc, 1), "Unpredictable instruction.\n");
2656 
2657   // ADD, ADDS (immediate).
2658   COMPARE_A32(Add(pc, r0, 1), "add pc, r0, #1\n");
2659   MUST_FAIL_TEST_T32(Add(pc, r0, 1), "Unpredictable instruction.\n");
2660   MUST_FAIL_TEST_T32(Add(pc, r0, 0x123), "Unpredictable instruction.\n");
2661   COMPARE_A32(Adds(pc, r0, 1), "adds pc, r0, #1\n");
2662   COMPARE_A32(Adds(r0, pc, 1), "adds r0, pc, #1\n");
2663   // TODO: Try to make these error messages more consistent.
2664   MUST_FAIL_TEST_T32(Adds(r0, pc, 1), "Unpredictable instruction.\n");
2665   MUST_FAIL_TEST_T32(Adds(r0, pc, 0x123), "Ill-formed 'adds' instruction.\n");
2666 
2667   // ADD, ADDS (register).
2668   COMPARE_A32(Add(pc, r0, r1), "add pc, r0, r1\n");
2669   COMPARE_A32(Add(r0, pc, r1), "add r0, pc, r1\n");
2670   COMPARE_A32(Add(r0, r1, pc), "add r0, r1, pc\n");
2671   COMPARE_T32(Add(r0, r0, pc), "add r0, pc\n");
2672   COMPARE_T32(Add(pc, pc, r0), "add pc, r0\n");
2673   MUST_FAIL_TEST_T32(Add(pc, pc, pc), "Unpredictable instruction.\n");
2674   MUST_FAIL_TEST_T32(Add(pc, r0, r1), "Unpredictable instruction.\n");
2675   MUST_FAIL_TEST_T32(Add(r0, pc, r1), "Unpredictable instruction.\n");
2676   MUST_FAIL_TEST_T32(Add(r0, r1, pc), "Unpredictable instruction.\n");
2677   COMPARE_A32(Adds(pc, r0, r1), "adds pc, r0, r1\n");
2678   COMPARE_A32(Adds(r0, pc, r1), "adds r0, pc, r1\n");
2679   COMPARE_A32(Adds(r0, r1, pc), "adds r0, r1, pc\n");
2680   MUST_FAIL_TEST_T32(Adds(r0, pc, r1), "Unpredictable instruction.\n");
2681   MUST_FAIL_TEST_T32(Adds(r0, r1, pc), "Unpredictable instruction.\n");
2682 
2683   // ADD, ADDS (register-shifted register)
2684   MUST_FAIL_TEST_A32(Add(pc, r0, Operand(r1, LSL, r2)),
2685                      "Unpredictable instruction.\n");
2686   MUST_FAIL_TEST_A32(Add(r0, pc, Operand(r1, LSL, r2)),
2687                      "Unpredictable instruction.\n");
2688   MUST_FAIL_TEST_A32(Add(r0, r1, Operand(pc, LSL, r2)),
2689                      "Unpredictable instruction.\n");
2690   MUST_FAIL_TEST_A32(Add(r0, r1, Operand(r2, LSL, pc)),
2691                      "Unpredictable instruction.\n");
2692   COMPARE_A32(Add(pc, sp, 1), "add pc, sp, #1\n");
2693   MUST_FAIL_TEST_T32(Add(pc, sp, 1), "Unpredictable instruction.\n");
2694   MUST_FAIL_TEST_A32(Adds(pc, r0, Operand(r1, LSL, r2)),
2695                      "Unpredictable instruction.\n");
2696   MUST_FAIL_TEST_A32(Adds(r0, pc, Operand(r1, LSL, r2)),
2697                      "Unpredictable instruction.\n");
2698   MUST_FAIL_TEST_A32(Adds(r0, r1, Operand(pc, LSL, r2)),
2699                      "Unpredictable instruction.\n");
2700   MUST_FAIL_TEST_A32(Adds(r0, r1, Operand(r2, LSL, pc)),
2701                      "Unpredictable instruction.\n");
2702 
2703   // ADD, ADDS (SP plus immediate).
2704   COMPARE_A32(Add(pc, sp, 1), "add pc, sp, #1\n");
2705   MUST_FAIL_TEST_T32(Add(pc, sp, 1), "Unpredictable instruction.\n");
2706   COMPARE_A32(Adds(pc, sp, 1), "adds pc, sp, #1\n");
2707   MUST_FAIL_TEST_T32(Adds(pc, sp, 1), "Ill-formed 'adds' instruction.\n");
2708 
2709   // ADD, ADDS (SP plus register).
2710   COMPARE_A32(Add(pc, sp, r0), "add pc, sp, r0\n");
2711   MUST_FAIL_TEST_T32(Add(pc, sp, r0), "Unpredictable instruction.\n");
2712   COMPARE_A32(Add(r0, sp, pc), "add r0, sp, pc\n");
2713   MUST_FAIL_TEST_T32(Add(r0, sp, pc), "Unpredictable instruction.\n");
2714   COMPARE_BOTH(Add(pc, sp, pc), "add pc, sp, pc\n");
2715   COMPARE_BOTH(Add(sp, sp, pc), "add sp, pc\n");
2716   COMPARE_A32(Adds(pc, sp, r0), "adds pc, sp, r0\n");
2717   MUST_FAIL_TEST_T32(Adds(pc, sp, r0), "Ill-formed 'adds' instruction.\n");
2718   COMPARE_A32(Adds(r0, sp, pc), "adds r0, sp, pc\n");
2719   MUST_FAIL_TEST_T32(Adds(r0, sp, pc), "Unpredictable instruction.\n");
2720   COMPARE_A32(Adds(pc, sp, pc), "adds pc, sp, pc\n");
2721   MUST_FAIL_TEST_T32(Adds(pc, sp, pc), "Ill-formed 'adds' instruction.\n");
2722   COMPARE_A32(Adds(sp, sp, pc), "adds sp, pc\n");
2723   MUST_FAIL_TEST_T32(Adds(sp, sp, pc), "Unpredictable instruction.\n");
2724 
2725   // ADR.
2726   {
2727     Literal<uint32_t> literal(0x12345678);
2728     // The address is 0x4 and not 0x0 because of the branch over the literal.
2729     // TODO: Consider disallowing this instruction.
2730     COMPARE_A32(Adr(pc, &literal), "adr pc, 0x00000004\n");
2731     MUST_FAIL_TEST_T32(Adr(pc, &literal), "Unpredictable instruction.\n");
2732   }
2733 
2734   // CLZ.
2735   MUST_FAIL_TEST_BOTH(Clz(pc, r0), "Unpredictable instruction.\n");
2736   MUST_FAIL_TEST_BOTH(Clz(r0, pc), "Unpredictable instruction.\n");
2737 
2738   // MOV, MOVS (immediate).
2739   COMPARE_A32(Mov(pc, 1), "mov pc, #1\n");
2740   MUST_FAIL_TEST_T32(Mov(pc, 1), "Unpredictable instruction.\n");
2741   MUST_FAIL_TEST_T32(Mov(pc, 0xfff), "Unpredictable instruction.\n");
2742   COMPARE_A32(Mov(pc, 0xf000), "mov pc, #61440\n");
2743   MUST_FAIL_TEST_T32(Mov(pc, 0xf000), "Unpredictable instruction.\n");
2744   COMPARE_A32(Movs(pc, 1), "movs pc, #1\n");
2745   MUST_FAIL_TEST_T32(Movs(pc, 1), "Unpredictable instruction.\n");
2746   MUST_FAIL_TEST_BOTH(Movs(pc, 0xfff), "Ill-formed 'movs' instruction.\n");
2747   COMPARE_A32(Movs(pc, 0xf000), "movs pc, #61440\n");
2748   MUST_FAIL_TEST_T32(Movs(pc, 0xf000), "Unpredictable instruction.\n");
2749 
2750   // MOV, MOVS (register).
2751   COMPARE_BOTH(Mov(pc, r0), "mov pc, r0\n");
2752   COMPARE_BOTH(Mov(r0, pc), "mov r0, pc\n");
2753   MUST_FAIL_TEST_BOTH(Movs(pc, r0), "Unpredictable instruction.\n");
2754   COMPARE_A32(Movs(r0, pc), "movs r0, pc\n");
2755   MUST_FAIL_TEST_T32(Movs(r0, pc), "Unpredictable instruction.\n");
2756 
2757   // MOV, MOVS (register-shifted register).
2758   MUST_FAIL_TEST_BOTH(Mov(pc, Operand(r0, ASR, r1)),
2759                       "Unpredictable instruction.\n");
2760   MUST_FAIL_TEST_BOTH(Mov(r0, Operand(pc, ASR, r1)),
2761                       "Unpredictable instruction.\n");
2762   MUST_FAIL_TEST_BOTH(Mov(r0, Operand(r1, ASR, pc)),
2763                       "Unpredictable instruction.\n");
2764   MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, ASR, r1)),
2765                       "Unpredictable instruction.\n");
2766   MUST_FAIL_TEST_BOTH(Movs(r0, Operand(pc, ASR, r1)),
2767                       "Unpredictable instruction.\n");
2768   MUST_FAIL_TEST_BOTH(Movs(r0, Operand(r1, ASR, pc)),
2769                       "Unpredictable instruction.\n");
2770 
2771   CLEANUP();
2772 }
2773 
2774 
TEST(macro_assembler_pc_rel_A32)2775 TEST(macro_assembler_pc_rel_A32) {
2776   SETUP();
2777   // Simple cases alias adr.
2778   COMPARE_A32(Add(r0, pc, -8), "adr r0, 0x00000000\n");
2779   COMPARE_A32(Add(r0, pc, 255), "adr r0, 0x00000107\n");
2780   COMPARE_A32(Add(r0, pc, 256), "adr r0, 0x00000108\n");
2781   COMPARE_A32(Add(r0, pc, 1024), "adr r0, 0x00000408\n");
2782   COMPARE_A32(Add(r0, pc, -9), "adr r0, 0xffffffff\n");
2783   COMPARE_A32(Add(r0, pc, -1024), "adr r0, 0xfffffc08\n");
2784   COMPARE_A32(Add(r0, pc, UINT32_C(0x80000000)), "adr r0, 0x80000008\n");
2785   COMPARE_A32(Add(r0, pc, -0x7fffffff), "adr r0, 0x80000009\n");
2786 
2787   COMPARE_A32(Sub(r0, pc, 8), "adr r0, 0x00000000\n");
2788   COMPARE_A32(Sub(r0, pc, -255), "adr r0, 0x00000107\n");
2789   COMPARE_A32(Sub(r0, pc, -256), "adr r0, 0x00000108\n");
2790   COMPARE_A32(Sub(r0, pc, -1024), "adr r0, 0x00000408\n");
2791   COMPARE_A32(Sub(r0, pc, 9), "adr r0, 0xffffffff\n");
2792   COMPARE_A32(Sub(r0, pc, 1024), "adr r0, 0xfffffc08\n");
2793   COMPARE_A32(Sub(r0, pc, UINT32_C(0x80000000)), "adr r0, 0x80000008\n");
2794   COMPARE_A32(Sub(r0, pc, -0x7fffffff), "adr r0, 0x80000007\n");
2795 
2796   // Cases out of range.
2797   // Only negative offsets are supported, because the proper behaviour for
2798   // positive offsets is not clear.
2799   MUST_FAIL_TEST_A32(Add(r0, pc, 1025), "Ill-formed 'add' instruction.\n");
2800   MUST_FAIL_TEST_A32(Add(r0, pc, 0xffff), "Ill-formed 'add' instruction.\n");
2801   MUST_FAIL_TEST_A32(Add(r0, pc, 0x10001), "Ill-formed 'add' instruction.\n");
2802   MUST_FAIL_TEST_A32(Add(r0, pc, 0x12345678),
2803                      "Ill-formed 'add' instruction.\n");
2804   MUST_FAIL_TEST_A32(Add(r0, pc, 0x7fffffff),
2805                      "Ill-formed 'add' instruction.\n");
2806   COMPARE_A32(Add(r0, pc, -1025),
2807               "adr r0, 0x00000007\n"
2808               "sub r0, #1024\n");
2809   COMPARE_A32(Add(r0, pc, -0xffff),
2810               "adr r0, 0xffffff09\n"
2811               "sub r0, #65280\n");
2812   COMPARE_A32(Add(r0, pc, -0x10001),
2813               "adr r0, 0x00000007\n"
2814               "sub r0, #65536\n");
2815   COMPARE_A32(Add(r0, pc, -0x2345678),
2816               "adr r0, 0xfffffd90\n"
2817               "sub r0, #21504\n"
2818               "sub r0, #36962304\n");
2819   COMPARE_A32(Add(r0, pc, -0x12345678),
2820               "adr r0, 0xfffffd90\n"
2821               "mov ip, #21504\n"
2822               "movt ip, #4660\n"
2823               "sub r0, ip\n");
2824 
2825   MUST_FAIL_TEST_A32(Sub(r0, pc, -1025), "Ill-formed 'add' instruction.\n");
2826   MUST_FAIL_TEST_A32(Sub(r0, pc, -0xffff), "Ill-formed 'add' instruction.\n");
2827   MUST_FAIL_TEST_A32(Sub(r0, pc, -0x10001), "Ill-formed 'add' instruction.\n");
2828   MUST_FAIL_TEST_A32(Sub(r0, pc, -0x12345678),
2829                      "Ill-formed 'add' instruction.\n");
2830   COMPARE_A32(Sub(r0, pc, 1025),
2831               "adr r0, 0x00000007\n"
2832               "sub r0, #1024\n");
2833   COMPARE_A32(Sub(r0, pc, 0xffff),
2834               "adr r0, 0xffffff09\n"
2835               "sub r0, #65280\n");
2836   COMPARE_A32(Sub(r0, pc, 0x10001),
2837               "adr r0, 0x00000007\n"
2838               "sub r0, #65536\n");
2839   COMPARE_A32(Sub(r0, pc, 0x2345678),
2840               "adr r0, 0xfffffd90\n"
2841               "sub r0, #21504\n"
2842               "sub r0, #36962304\n");
2843   COMPARE_A32(Sub(r0, pc, 0x12345678),
2844               "adr r0, 0xfffffd90\n"
2845               "mov ip, #21504\n"
2846               "movt ip, #4660\n"
2847               "sub r0, ip\n");
2848   COMPARE_A32(Sub(r0, pc, 0x7fffffff),
2849               "adr r0, 0xffffff09\n"
2850               "add r0, #256\n"
2851               "add r0, #2147483648\n");
2852 
2853   CLEANUP();
2854 }
2855 
2856 
TEST(macro_assembler_pc_rel_T32)2857 TEST(macro_assembler_pc_rel_T32) {
2858   SETUP();
2859   // Simple cases alias adr.
2860   COMPARE_T32(Add(r0, pc, -4), "adr r0, 0x00000000\n");     // T1
2861   COMPARE_T32(Add(r0, pc, 1020), "adr r0, 0x00000400\n");   // T1
2862   COMPARE_T32(Add(r0, pc, -5), "adr r0, 0xffffffff\n");     // T2
2863   COMPARE_T32(Add(r0, pc, -4095), "adr r0, 0xfffff005\n");  // T2
2864   COMPARE_T32(Add(r0, pc, -3), "adr r0, 0x00000001\n");     // T3
2865   COMPARE_T32(Add(r0, pc, 1021), "adr r0, 0x00000401\n");   // T3
2866   COMPARE_T32(Add(r0, pc, 1019), "adr r0, 0x000003ff\n");   // T3
2867   COMPARE_T32(Add(r0, pc, 4095), "adr r0, 0x00001003\n");   // T3
2868 
2869   COMPARE_T32(Sub(r0, pc, 4), "adr r0, 0x00000000\n");      // T1
2870   COMPARE_T32(Sub(r0, pc, -1020), "adr r0, 0x00000400\n");  // T1
2871   COMPARE_T32(Sub(r0, pc, 5), "adr r0, 0xffffffff\n");      // T2
2872   COMPARE_T32(Sub(r0, pc, 4095), "adr r0, 0xfffff005\n");   // T2
2873   COMPARE_T32(Sub(r0, pc, 3), "adr r0, 0x00000001\n");      // T3
2874   COMPARE_T32(Sub(r0, pc, -1021), "adr r0, 0x00000401\n");  // T3
2875   COMPARE_T32(Sub(r0, pc, -1019), "adr r0, 0x000003ff\n");  // T3
2876   COMPARE_T32(Sub(r0, pc, -4095), "adr r0, 0x00001003\n");  // T3
2877 
2878   // Cases out of range.
2879   // Only negative offsets are supported, because the proper behaviour for
2880   // positive offsets is not clear.
2881 
2882   MUST_FAIL_TEST_T32(Add(r0, pc, 4096), "Unpredictable instruction.\n");
2883 
2884   MUST_FAIL_TEST_T32(Add(r0, pc, -4096), "Unpredictable instruction.\n");
2885 
2886   MUST_FAIL_TEST_T32(Add(r0, pc, 0xffff), "Ill-formed 'add' instruction.\n");
2887   MUST_FAIL_TEST_T32(Add(r0, pc, 0x10002), "Ill-formed 'add' instruction.\n");
2888   MUST_FAIL_TEST_T32(Add(r0, pc, 0x12345678),
2889                      "Ill-formed 'add' instruction.\n");
2890   MUST_FAIL_TEST_T32(Add(r0, pc, 0x7fffffff),
2891                      "Ill-formed 'add' instruction.\n");
2892   COMPARE_T32(Add(r0, pc, -0x12345678),
2893               "mov r0, pc\n"
2894               "mov ip, #22136\n"
2895               "movt ip, #4660\n"
2896               "sub r0, ip\n");
2897   COMPARE_T32(Add(r0, pc, -0x7fffffff),
2898               "mov r0, pc\n"
2899               "add r0, #1\n"
2900               "add r0, #2147483648\n");
2901 
2902   // TODO: This test aborts in the Assembler (with unpredictable instruction
2903   // errors) before the MacroAssembler gets a chance to do something
2904   // predictable.
2905   // COMPARE_T32(Sub(r0, pc, -4096), "mov r0, pc\n"
2906   //                                 "add r0, #4096\n");
2907 
2908   MUST_FAIL_TEST_T32(Sub(r0, pc, 4096), "Unpredictable instruction.\n");
2909 
2910   MUST_FAIL_TEST_T32(Sub(r0, pc, -0xffff), "Ill-formed 'add' instruction.\n");
2911   MUST_FAIL_TEST_T32(Sub(r0, pc, -0x10002), "Ill-formed 'add' instruction.\n");
2912   MUST_FAIL_TEST_T32(Sub(r0, pc, -0x12345678),
2913                      "Ill-formed 'add' instruction.\n");
2914   MUST_FAIL_TEST_T32(Sub(r0, pc, -0x7fffffff),
2915                      "Ill-formed 'add' instruction.\n");
2916   COMPARE_T32(Sub(r0, pc, 0x12345678),
2917               "mov r0, pc\n"
2918               "mov ip, #22136\n"
2919               "movt ip, #4660\n"
2920               "sub r0, ip\n");
2921   COMPARE_T32(Sub(r0, pc, 0x7fffffff),
2922               "mov r0, pc\n"
2923               "add r0, #1\n"
2924               "add r0, #2147483648\n");
2925   CLEANUP();
2926 }
2927 
2928 
TEST(macro_assembler_unsupported)2929 TEST(macro_assembler_unsupported) {
2930   SETUP();
2931 
2932   MUST_FAIL_TEST_BOTH(Sxtab(r0, r1, Operand(r2, ROR, 1)),
2933                       "Ill-formed 'sxtab' instruction.\n");
2934   MUST_FAIL_TEST_BOTH(Sxtab16(r0, r1, Operand(r0, ASR, 2)),
2935                       "Ill-formed 'sxtab16' instruction.\n");
2936   MUST_FAIL_TEST_BOTH(Sxtah(r0, r1, Operand(r0, LSL, r1)),
2937                       "Ill-formed 'sxtah' instruction.\n");
2938   MUST_FAIL_TEST_BOTH(Uxtab(r0, r1, Operand(r0, LSR, r2)),
2939                       "Ill-formed 'uxtab' instruction.\n");
2940   MUST_FAIL_TEST_BOTH(Uxtab16(r0, r1, Operand(r0, ROR, 1)),
2941                       "Ill-formed 'uxtab16' instruction.\n");
2942   MUST_FAIL_TEST_BOTH(Uxtah(r0, r1, Operand(r0, ASR, 2)),
2943                       "Ill-formed 'uxtah' instruction.\n");
2944   MUST_FAIL_TEST_BOTH(Pkhbt(r0, r1, Operand(r0, LSL, r1)),
2945                       "Ill-formed 'pkhbt' instruction.\n");
2946   MUST_FAIL_TEST_BOTH(Pkhtb(r0, r1, Operand(r0, LSR, r2)),
2947                       "Ill-formed 'pkhtb' instruction.\n");
2948 
2949   MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, 1, PreIndex)),
2950                       "Ill-formed 'pld' instruction.\n");
2951   MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, 1, PostIndex)),
2952                       "Ill-formed 'pldw' instruction.\n");
2953   MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, 1, PreIndex)),
2954                       "Ill-formed 'pli' instruction.\n");
2955 
2956   MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, r0, PreIndex)),
2957                       "Ill-formed 'pld' instruction.\n");
2958   MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, r1, PostIndex)),
2959                       "Ill-formed 'pldw' instruction.\n");
2960   MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, r2, PreIndex)),
2961                       "Ill-formed 'pli' instruction.\n");
2962 
2963   MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, r0, LSL, 1, PreIndex)),
2964                       "Ill-formed 'pld' instruction.\n");
2965   MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, r1, LSR, 2, PostIndex)),
2966                       "Ill-formed 'pldw' instruction.\n");
2967   MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, r2, ASR, 3, PreIndex)),
2968                       "Ill-formed 'pli' instruction.\n");
2969 
2970   MUST_FAIL_TEST_BOTH(Lda(r0, MemOperand(r0, 1)),
2971                       "Ill-formed 'lda' instruction.\n");
2972   MUST_FAIL_TEST_BOTH(Ldab(r0, MemOperand(r0, 1)),
2973                       "Ill-formed 'ldab' instruction.\n");
2974   MUST_FAIL_TEST_BOTH(Ldaex(r0, MemOperand(r0, 1)),
2975                       "Ill-formed 'ldaex' instruction.\n");
2976   MUST_FAIL_TEST_BOTH(Ldaexb(r0, MemOperand(r0, 1)),
2977                       "Ill-formed 'ldaexb' instruction.\n");
2978   MUST_FAIL_TEST_BOTH(Ldaexh(r0, MemOperand(r0, 1)),
2979                       "Ill-formed 'ldaexh' instruction.\n");
2980   MUST_FAIL_TEST_BOTH(Ldah(r0, MemOperand(r0, 1)),
2981                       "Ill-formed 'ldah' instruction.\n");
2982   MUST_FAIL_TEST_BOTH(Ldrex(r0, MemOperand(r0, 1)),
2983                       "Ill-formed 'ldrex' instruction.\n");
2984   MUST_FAIL_TEST_BOTH(Ldrexb(r0, MemOperand(r0, 1)),
2985                       "Ill-formed 'ldrexb' instruction.\n");
2986   MUST_FAIL_TEST_BOTH(Ldrexh(r0, MemOperand(r0, 1)),
2987                       "Ill-formed 'ldrexh' instruction.\n");
2988   MUST_FAIL_TEST_BOTH(Stl(r0, MemOperand(r0, 1)),
2989                       "Ill-formed 'stl' instruction.\n");
2990   MUST_FAIL_TEST_BOTH(Stlb(r0, MemOperand(r0, 1)),
2991                       "Ill-formed 'stlb' instruction.\n");
2992   MUST_FAIL_TEST_BOTH(Stlh(r0, MemOperand(r0, 1)),
2993                       "Ill-formed 'stlh' instruction.\n");
2994 
2995   MUST_FAIL_TEST_BOTH(Ldaexd(r0, r1, MemOperand(r0, 1)),
2996                       "Ill-formed 'ldaexd' instruction.\n");
2997   MUST_FAIL_TEST_BOTH(Ldrexd(r0, r1, MemOperand(r0, 1)),
2998                       "Ill-formed 'ldrexd' instruction.\n");
2999   MUST_FAIL_TEST_BOTH(Stlex(r0, r1, MemOperand(r0, 1)),
3000                       "Ill-formed 'stlex' instruction.\n");
3001   MUST_FAIL_TEST_BOTH(Stlexb(r0, r1, MemOperand(r0, 1)),
3002                       "Ill-formed 'stlexb' instruction.\n");
3003   MUST_FAIL_TEST_BOTH(Stlexh(r0, r1, MemOperand(r0, 1)),
3004                       "Ill-formed 'stlexh' instruction.\n");
3005   MUST_FAIL_TEST_BOTH(Strex(r0, r1, MemOperand(r0, 1)),
3006                       "Ill-formed 'strex' instruction.\n");
3007   MUST_FAIL_TEST_BOTH(Strexb(r0, r1, MemOperand(r0, 1)),
3008                       "Ill-formed 'strexb' instruction.\n");
3009   MUST_FAIL_TEST_BOTH(Strexh(r0, r1, MemOperand(r0, 1)),
3010                       "Ill-formed 'strexh' instruction.\n");
3011 
3012   MUST_FAIL_TEST_BOTH(Stlexd(r0, r1, r2, MemOperand(r0, 1)),
3013                       "Ill-formed 'stlexd' instruction.\n");
3014   MUST_FAIL_TEST_BOTH(Strexd(r0, r1, r2, MemOperand(r0, 1)),
3015                       "Ill-formed 'strexd' instruction.\n");
3016 
3017   CLEANUP();
3018 }
3019 
TEST(macro_assembler_Vmov_neon_immediate)3020 TEST(macro_assembler_Vmov_neon_immediate) {
3021   SETUP();
3022 
3023   // Move 8, 16 and 32-bit immediates into D registers, duplicated across the
3024   // destination.
3025   COMPARE_BOTH(Vmov(I8, d0, 0xac), "vmov.i8 d0, #172\n");
3026 
3027   COMPARE_BOTH(Vmov(I16, d0, 0xa4), "vmov.i16 d0, #164\n");
3028   COMPARE_BOTH(Vmov(I16, d0, 0x9797), "vmov.i8 d0, #151\n");
3029   COMPARE_BOTH(Vmov(I16, d0, 0x9ef6),
3030                "mov ip, #40694\n"
3031                "vdup.16 d0, ip\n");
3032 
3033   COMPARE_BOTH(Vmov(I32, d0, 0x6d0000), "vmov.i32 d0, #7143424\n");
3034   COMPARE_BOTH(Vmov(I32, d0, 0x15ffffff), "vmvn.i32 d0, #3925868544\n");
3035   COMPARE_BOTH(Vmov(I32, d0, 0x74747474), "vmov.i8 d0, #116\n");
3036   COMPARE_BOTH(Vmov(I32, d0, 0xff0000ff), "vmov.i64 d0, #0xff0000ffff0000ff\n");
3037   COMPARE_BOTH(Vmov(I32, d0, 0x1ecb9ef6),
3038                "mov ip, #40694\n"
3039                "movt ip, #7883\n"
3040                "vdup.32 d0, ip\n");
3041   COMPARE_BOTH(Vmov(I32, d0, 0x006d0000), "vmov.i32 d0, #7143424\n");
3042   COMPARE_BOTH(Vmov(I32, d0, 0x00004da6),
3043                "mov ip, #19878\n"
3044                "vdup.32 d0, ip\n");
3045   COMPARE_BOTH(Vmov(I32, d0, 0xffffff55), "vmvn.i32 d0, #170\n");
3046   COMPARE_BOTH(Vmov(I32, d0, 0xffff55ff), "vmvn.i32 d0, #43520\n");
3047   COMPARE_BOTH(Vmov(I32, d0, 0xff55ffff), "vmvn.i32 d0, #11141120\n");
3048 
3049   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0xa5a5a5a5a5a5a5a5)),
3050                "vmov.i8 d0, #165\n");
3051   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x0a01248315ffffff)),
3052                "mvn ip, #3925868544\n"
3053                "vdup.32 d0, ip\n"
3054                "mov ip, #9347\n"
3055                "movt ip, #2561\n"
3056                "vmov.32 d0[1], ip\n");
3057   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x6fe1a7a779e33af2)),
3058                "mov ip, #15090\n"
3059                "movt ip, #31203\n"
3060                "vdup.32 d0, ip\n"
3061                "mov ip, #42919\n"
3062                "movt ip, #28641\n"
3063                "vmov.32 d0[1], ip\n");
3064   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x2efa8b440000c1da)),
3065                "mov ip, #49626\n"
3066                "vdup.32 d0, ip\n"
3067                "mov ip, #35652\n"
3068                "movt ip, #12026\n"
3069                "vmov.32 d0[1], ip\n");
3070   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x00008bb75c3036fd)),
3071                "mov ip, #14077\n"
3072                "movt ip, #23600\n"
3073                "vdup.32 d0, ip\n"
3074                "mov ip, #35767\n"
3075                "vmov.32 d0[1], ip\n");
3076 
3077   COMPARE_BOTH(Vmov(F32, d0, 0.5), "vmov.f32 d0, #0.5\n");
3078   COMPARE_BOTH(Vmov(F32, d0, 1.1),
3079                "mov ip, #52429\n"
3080                "movt ip, #16268\n"
3081                "vdup.32 d0, ip\n");
3082 
3083   COMPARE_T32(Vmov(I64, d0, UINT64_C(0x2fff2fff3e2869e7)),
3084               "mov ip, #27111\n"
3085               "movt ip, #15912\n"
3086               "vdup.32 d0, ip\n"
3087               "mvn ip, #3489714176\n"
3088               "vmov.32 d0[1], ip\n");
3089 
3090   COMPARE_A32(Vmov(I32, d0, 0x0ffffffa),
3091               "mvn ip, #4026531845\n"
3092               "vdup.32 d0, ip\n");
3093   COMPARE_A32(Vmov(I64, d0, UINT64_C(0x65ffffff16a0ef46)),
3094               "mov ip, #61254\n"
3095               "movt ip, #5792\n"
3096               "vdup.32 d0, ip\n"
3097               "mvn ip, #2583691264\n"
3098               "vmov.32 d0[1], ip\n");
3099 
3100   // Move 8, 16 and 32-bit immediates into Q registers, duplicated across the
3101   // destination.
3102   COMPARE_BOTH(Vmov(I8, q0, 0xac), "vmov.i8 q0, #172\n");
3103 
3104   COMPARE_BOTH(Vmov(I16, q0, 0xa4), "vmov.i16 q0, #164\n");
3105   COMPARE_BOTH(Vmov(I16, q0, 0x9797), "vmov.i8 q0, #151\n");
3106   COMPARE_BOTH(Vmov(I16, q0, 0x9ef6),
3107                "mov ip, #40694\n"
3108                "vdup.16 q0, ip\n");
3109 
3110   COMPARE_BOTH(Vmov(I32, q0, 0x6d0000), "vmov.i32 q0, #7143424\n");
3111   COMPARE_BOTH(Vmov(I32, q0, 0x15ffffff), "vmvn.i32 q0, #3925868544\n");
3112   COMPARE_BOTH(Vmov(I32, q0, 0x74747474), "vmov.i8 q0, #116\n");
3113   COMPARE_BOTH(Vmov(I32, q0, 0xff0000ff), "vmov.i64 q0, #0xff0000ffff0000ff\n");
3114   COMPARE_BOTH(Vmov(I32, q0, 0x1ecb9ef6),
3115                "mov ip, #40694\n"
3116                "movt ip, #7883\n"
3117                "vdup.32 q0, ip\n");
3118   COMPARE_BOTH(Vmov(I32, q0, 0x006d0000), "vmov.i32 q0, #7143424\n");
3119   COMPARE_BOTH(Vmov(I32, q0, 0x00004da6),
3120                "mov ip, #19878\n"
3121                "vdup.32 q0, ip\n");
3122 
3123   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0xa5a5a5a5a5a5a5a5)),
3124                "vmov.i8 q0, #165\n");
3125   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x0a01248315ffffff)),
3126                "mvn ip, #3925868544\n"
3127                "vdup.32 q0, ip\n"
3128                "mov ip, #9347\n"
3129                "movt ip, #2561\n"
3130                "vmov.32 d0[1], ip\n"
3131                "vmov.f64 d1, d0\n");
3132   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x6fe1a7a779e33af2)),
3133                "mov ip, #15090\n"
3134                "movt ip, #31203\n"
3135                "vdup.32 q0, ip\n"
3136                "mov ip, #42919\n"
3137                "movt ip, #28641\n"
3138                "vmov.32 d0[1], ip\n"
3139                "vmov.f64 d1, d0\n");
3140   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x2efa8b440000c1da)),
3141                "mov ip, #49626\n"
3142                "vdup.32 q0, ip\n"
3143                "mov ip, #35652\n"
3144                "movt ip, #12026\n"
3145                "vmov.32 d0[1], ip\n"
3146                "vmov.f64 d1, d0\n");
3147   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x00008bb75c3036fd)),
3148                "mov ip, #14077\n"
3149                "movt ip, #23600\n"
3150                "vdup.32 q0, ip\n"
3151                "mov ip, #35767\n"
3152                "vmov.32 d0[1], ip\n"
3153                "vmov.f64 d1, d0\n");
3154 
3155   COMPARE_BOTH(Vmov(F32, q0, 0.5), "vmov.f32 q0, #0.5\n");
3156   COMPARE_BOTH(Vmov(F32, q0, 1.1),
3157                "mov ip, #52429\n"
3158                "movt ip, #16268\n"
3159                "vdup.32 q0, ip\n");
3160   COMPARE_BOTH(Vmov(F64, q0, 0.5),
3161                "vmov.f64 d0, #0.5\n"
3162                "vmov.f64 d1, d0\n");
3163   COMPARE_BOTH(Vmov(F64, q0, 1.1),
3164                "mov ip, #39322\n"
3165                "movt ip, #39321\n"
3166                "vdup.32 d0, ip\n"
3167                "mov ip, #39321\n"
3168                "movt ip, #16369\n"
3169                "vmov.32 d0[1], ip\n"
3170                "vmov.f64 d1, d0\n");
3171 
3172   COMPARE_T32(Vmov(I64, q0, UINT64_C(0x2fff2fff3e2869e7)),
3173               "mov ip, #27111\n"
3174               "movt ip, #15912\n"
3175               "vdup.32 q0, ip\n"
3176               "mvn ip, #3489714176\n"
3177               "vmov.32 d0[1], ip\n"
3178               "vmov.f64 d1, d0\n");
3179 
3180   COMPARE_A32(Vmov(I32, q0, 0x0ffffffa),
3181               "mvn ip, #4026531845\n"
3182               "vdup.32 q0, ip\n");
3183   COMPARE_A32(Vmov(I64, q0, UINT64_C(0x65ffffff16a0ef46)),
3184               "mov ip, #61254\n"
3185               "movt ip, #5792\n"
3186               "vdup.32 q0, ip\n"
3187               "mvn ip, #2583691264\n"
3188               "vmov.32 d0[1], ip\n"
3189               "vmov.f64 d1, d0\n");
3190   CLEANUP();
3191 }
3192 
TEST(macro_assembler_T32_IT)3193 TEST(macro_assembler_T32_IT) {
3194   SETUP();
3195 
3196   // ADC (register) T1
3197   COMPARE_T32(Adc(eq, r0, r0, r1),
3198               "it eq\n"
3199               "adceq r0, r1\n");
3200 
3201   COMPARE_T32(Adc(eq, r0, r1, r2),
3202               "bne 0x00000006\n"
3203               "adc r0, r1, r2\n");
3204 
3205   // ADD (immediate) T1
3206   COMPARE_T32(Add(eq, r0, r1, 0x1),
3207               "it eq\n"
3208               "addeq r0, r1, #1\n");
3209 
3210   COMPARE_T32(Add(eq, r0, r1, 0x8),
3211               "bne 0x00000006\n"
3212               "add r0, r1, #8\n");
3213 
3214   // ADD (immediate) T2
3215   COMPARE_T32(Add(eq, r0, r0, 0xff),
3216               "it eq\n"
3217               "addeq r0, #255\n");
3218 
3219   // ADD (register) T1
3220   COMPARE_T32(Add(eq, r0, r1, r7),
3221               "it eq\n"
3222               "addeq r0, r1, r7\n");
3223 
3224   // ADD (register) T2
3225   COMPARE_T32(Add(eq, r5, r5, r8),
3226               "it eq\n"
3227               "addeq r5, r8\n");
3228 
3229   // ADD (SP plus immediate) T1
3230   COMPARE_T32(Add(eq, r7, sp, 1020),
3231               "it eq\n"
3232               "addeq r7, sp, #1020\n");
3233 
3234   COMPARE_T32(Add(eq, r7, sp, 1),
3235               "bne 0x00000006\n"
3236               "add r7, sp, #1\n");
3237 
3238   COMPARE_T32(Add(eq, r7, sp, 1024),
3239               "bne 0x00000006\n"
3240               "add r7, sp, #1024\n");
3241 
3242   COMPARE_T32(Add(eq, sp, sp, 32),
3243               "bne 0x00000004\n"
3244               "add sp, #32\n");
3245 
3246   // ADD (SP plus register) T1
3247   COMPARE_T32(Add(eq, r7, sp, r7),
3248               "it eq\n"
3249               "addeq r7, sp, r7\n");
3250 
3251   // ADD (SP plus register) T2
3252   COMPARE_T32(Add(eq, sp, sp, r10),
3253               "it eq\n"
3254               "addeq sp, r10\n");
3255 
3256   COMPARE_T32(Add(eq, r5, r5, sp),
3257               "bne 0x00000006\n"
3258               "add.w r5, sp\n");
3259 
3260   // AND (register) T1
3261   COMPARE_T32(And(eq, r7, r7, r0),
3262               "it eq\n"
3263               "andeq r7, r0\n");
3264 
3265   COMPARE_T32(And(eq, r8, r8, r0),
3266               "bne 0x00000006\n"
3267               "and r8, r0\n");
3268 
3269   // ASR (immediate) T2
3270   COMPARE_T32(Asr(eq, r0, r1, 16),
3271               "it eq\n"
3272               "asreq r0, r1, #16\n");
3273 
3274   COMPARE_T32(Asr(eq, r0, r1, 32),
3275               "it eq\n"
3276               "asreq r0, r1, #32\n");
3277 
3278   COMPARE_T32(Asr(eq, r0, r1, 0),
3279               "bne 0x0000000a\n"
3280               "mov r0, #0\n"
3281               "asr r0, r1, r0\n");
3282 
3283   // ASR (register) T1
3284   COMPARE_T32(Asr(eq, r7, r7, r3),
3285               "it eq\n"
3286               "asreq r7, r3\n");
3287 
3288   COMPARE_T32(Asr(eq, r8, r8, r3),
3289               "bne 0x00000006\n"
3290               "asr r8, r3\n");
3291 
3292   // BIC (register) T1
3293   COMPARE_T32(Bic(eq, r7, r7, r6),
3294               "it eq\n"
3295               "biceq r7, r6\n");
3296 
3297   COMPARE_T32(Bic(eq, r8, r8, r6),
3298               "bne 0x00000006\n"
3299               "bic r8, r6\n");
3300 
3301   Label l;
3302   __ Bind(&l);
3303 
3304   // BLX (register) T1
3305   COMPARE_T32(Blx(eq, lr),
3306               "it eq\n"
3307               "blxeq lr\n");
3308   COMPARE_T32(Blx(eq, &l),
3309               "bne 0x00000006\n"
3310               "blx 0x00000000\n");
3311 
3312   // BX (register) T1
3313   COMPARE_T32(Bx(eq, lr),
3314               "it eq\n"
3315               "bxeq lr\n");
3316 
3317   // CMN (register) T1
3318   COMPARE_T32(Cmn(eq, r0, r1),
3319               "it eq\n"
3320               "cmneq r0, r1\n");
3321 
3322   COMPARE_T32(Cmn(eq, r0, r8),
3323               "bne 0x00000006\n"
3324               "cmn r0, r8\n");
3325 
3326   // CMP (immediate) T1
3327   COMPARE_T32(Cmp(eq, r7, 0xff),
3328               "it eq\n"
3329               "cmpeq r7, #255\n");
3330 
3331   // CMP (register) T1
3332   COMPARE_T32(Cmp(eq, r6, r7),
3333               "it eq\n"
3334               "cmpeq r6, r7\n");
3335 
3336   // CMP (register) T2
3337   COMPARE_T32(Cmp(eq, r9, r10),
3338               "it eq\n"
3339               "cmpeq r9, r10\n");
3340 
3341   COMPARE_T32(Cmp(eq, r0, 0x100),
3342               "bne 0x00000006\n"
3343               "cmp r0, #256\n");
3344 
3345   // EOR (register) T1
3346   COMPARE_T32(Eor(eq, r0, r0, r7),
3347               "it eq\n"
3348               "eoreq r0, r7\n");
3349 
3350   COMPARE_T32(Eor(eq, r0, r0, 0x1),
3351               "bne 0x00000006\n"
3352               "eor r0, #0x1\n");
3353 
3354   // LDR (immediate) T1
3355   COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 124)),
3356               "it eq\n"
3357               "ldreq r4, [r7, #124]\n");
3358 
3359   COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 1)),
3360               "bne 0x00000006\n"
3361               "ldr r4, [r7, #1]\n");
3362 
3363   COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 128)),
3364               "bne 0x00000006\n"
3365               "ldr r4, [r7, #128]\n");
3366 
3367   // LDR (immediate) T2
3368   COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1020)),
3369               "it eq\n"
3370               "ldreq r4, [sp, #1020]\n");
3371 
3372   COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1)),
3373               "bne 0x00000006\n"
3374               "ldr r4, [sp, #1]\n");
3375 
3376   COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1024)),
3377               "bne 0x00000006\n"
3378               "ldr r4, [sp, #1024]\n");
3379 
3380   // LDR (register) T1
3381   COMPARE_T32(Ldr(eq, r5, MemOperand(r6, r7)),
3382               "it eq\n"
3383               "ldreq r5, [r6, r7]\n");
3384 
3385   COMPARE_T32(Ldr(eq, r5, MemOperand(r6, r8)),
3386               "bne 0x00000006\n"
3387               "ldr r5, [r6, r8]\n");
3388 
3389   // LDRB (immediate) T1
3390   COMPARE_T32(Ldrb(eq, r6, MemOperand(r7, 31)),
3391               "it eq\n"
3392               "ldrbeq r6, [r7, #31]\n");
3393 
3394   COMPARE_T32(Ldrb(eq, r6, MemOperand(r7, 32)),
3395               "bne 0x00000006\n"
3396               "ldrb r6, [r7, #32]\n");
3397 
3398   // LDRB (register) T1
3399   COMPARE_T32(Ldrb(eq, r5, MemOperand(r6, r7)),
3400               "it eq\n"
3401               "ldrbeq r5, [r6, r7]\n");
3402 
3403   COMPARE_T32(Ldrb(eq, r6, MemOperand(r9)),
3404               "bne 0x00000006\n"
3405               "ldrb r6, [r9]\n");
3406 
3407   // LDRH (immediate) T1
3408   COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 62)),
3409               "it eq\n"
3410               "ldrheq r6, [r7, #62]\n");
3411 
3412   COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 64)),
3413               "bne 0x00000006\n"
3414               "ldrh r6, [r7, #64]\n");
3415 
3416   COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 1)),
3417               "bne 0x00000006\n"
3418               "ldrh r6, [r7, #1]\n");
3419 
3420   // LDRH (register) T1
3421   COMPARE_T32(Ldrh(eq, r5, MemOperand(r6, r7)),
3422               "it eq\n"
3423               "ldrheq r5, [r6, r7]\n");
3424 
3425   COMPARE_T32(Ldrh(eq, r6, MemOperand(r9)),
3426               "bne 0x00000006\n"
3427               "ldrh r6, [r9]\n");
3428 
3429   // LDRSB (register) T1
3430   COMPARE_T32(Ldrsb(eq, r5, MemOperand(r6, r7)),
3431               "it eq\n"
3432               "ldrsbeq r5, [r6, r7]\n");
3433 
3434   COMPARE_T32(Ldrsb(eq, r6, MemOperand(r9)),
3435               "bne 0x00000006\n"
3436               "ldrsb r6, [r9]\n");
3437 
3438   // LDRSH (register) T1
3439   COMPARE_T32(Ldrsh(eq, r5, MemOperand(r6, r7)),
3440               "it eq\n"
3441               "ldrsheq r5, [r6, r7]\n");
3442 
3443   COMPARE_T32(Ldrsh(eq, r6, MemOperand(r9)),
3444               "bne 0x00000006\n"
3445               "ldrsh r6, [r9]\n");
3446 
3447   // LSL (immediate) T2
3448   COMPARE_T32(Lsl(eq, r0, r1, 16),
3449               "it eq\n"
3450               "lsleq r0, r1, #16\n");
3451 
3452   COMPARE_T32(Lsl(eq, r0, r1, 0),
3453               "bne 0x0000000a\n"
3454               "mov r0, #0\n"
3455               "lsl r0, r1, r0\n");
3456 
3457   COMPARE_T32(Lsl(eq, r0, r1, 32),
3458               "bne 0x0000000a\n"
3459               "mov r0, #32\n"
3460               "lsl r0, r1, r0\n");
3461 
3462   // LSL (register) T1
3463   COMPARE_T32(Lsl(eq, r7, r7, r3),
3464               "it eq\n"
3465               "lsleq r7, r3\n");
3466 
3467   COMPARE_T32(Lsl(eq, r8, r8, r3),
3468               "bne 0x00000006\n"
3469               "lsl r8, r3\n");
3470 
3471   // LSR (immediate) T2
3472   COMPARE_T32(Lsr(eq, r0, r1, 16),
3473               "it eq\n"
3474               "lsreq r0, r1, #16\n");
3475 
3476   COMPARE_T32(Lsr(eq, r0, r1, 32),
3477               "it eq\n"
3478               "lsreq r0, r1, #32\n");
3479 
3480   COMPARE_T32(Lsr(eq, r0, r1, 0),
3481               "bne 0x0000000a\n"
3482               "mov r0, #0\n"
3483               "lsr r0, r1, r0\n");
3484 
3485   // LSR (register) T1
3486   COMPARE_T32(Lsr(eq, r7, r7, r3),
3487               "it eq\n"
3488               "lsreq r7, r3\n");
3489 
3490   COMPARE_T32(Lsr(eq, r8, r8, r3),
3491               "bne 0x00000006\n"
3492               "lsr r8, r3\n");
3493 
3494   // MOV (immediate) T1
3495   COMPARE_T32(Mov(eq, r7, 0xff),
3496               "it eq\n"
3497               "moveq r7, #255\n");
3498 
3499   // MOV (register) T1
3500   COMPARE_T32(Mov(eq, r9, r8),
3501               "it eq\n"
3502               "moveq r9, r8\n");
3503 
3504   // MOV (register) T2
3505   COMPARE_T32(Mov(eq, r0, Operand(r1, LSR, 16)),
3506               "it eq\n"
3507               "lsreq r0, r1, #16\n");
3508 
3509   COMPARE_T32(Mov(eq, r0, Operand(r1, ROR, 16)),
3510               "bne 0x00000006\n"
3511               "ror r0, r1, #16\n");
3512 
3513   // MOV (register-shifted register) T1
3514   COMPARE_T32(Mov(eq, r0, Operand(r0, LSR, r1)),
3515               "it eq\n"
3516               "lsreq r0, r1\n");
3517 
3518   COMPARE_T32(Mov(eq, r0, Operand(r1, LSR, r2)),
3519               "bne 0x00000006\n"
3520               "lsr r0, r1, r2\n");
3521 
3522   // MUL (T1)
3523   COMPARE_T32(Mul(eq, r0, r1, r0),
3524               "it eq\n"
3525               "muleq r0, r1, r0\n");
3526 
3527   COMPARE_T32(Mul(eq, r0, r1, r2),
3528               "bne 0x00000006\n"
3529               "mul r0, r1, r2\n");
3530 
3531   // MVN (register) T1
3532   COMPARE_T32(Mvn(eq, r4, r6),
3533               "it eq\n"
3534               "mvneq r4, r6\n");
3535 
3536   COMPARE_T32(Mvn(eq, r8, r6),
3537               "bne 0x00000006\n"
3538               "mvn r8, r6\n");
3539 
3540   // ORR (register) T1
3541   COMPARE_T32(Orr(eq, r0, r0, r1),
3542               "it eq\n"
3543               "orreq r0, r1\n");
3544 
3545   COMPARE_T32(Orr(eq, r0, r1, r2),
3546               "bne 0x00000006\n"
3547               "orr r0, r1, r2\n");
3548 
3549   // ROR (register) T1
3550   COMPARE_T32(Ror(eq, r7, r7, r3),
3551               "it eq\n"
3552               "roreq r7, r3\n");
3553 
3554   COMPARE_T32(Ror(eq, r8, r8, r3),
3555               "bne 0x00000006\n"
3556               "ror r8, r3\n");
3557 
3558   COMPARE_T32(Ror(eq, r0, r1, 16),
3559               "bne 0x00000006\n"
3560               "ror r0, r1, #16\n");
3561 
3562   // RSB (immediate) T1
3563   COMPARE_T32(Rsb(eq, r0, r1, 0),
3564               "it eq\n"
3565               "rsbeq r0, r1, #0\n");
3566 
3567   COMPARE_T32(Rsb(eq, r0, r1, 1),
3568               "bne 0x00000006\n"
3569               "rsb r0, r1, #1\n");
3570 
3571   // SBC (register) T1
3572   COMPARE_T32(Sbc(eq, r0, r0, r1),
3573               "it eq\n"
3574               "sbceq r0, r1\n");
3575 
3576   COMPARE_T32(Sbc(eq, r0, r1, r2),
3577               "bne 0x00000006\n"
3578               "sbc r0, r1, r2\n");
3579 
3580   // STR (immediate) T1
3581   COMPARE_T32(Str(eq, r4, MemOperand(r7, 124)),
3582               "it eq\n"
3583               "streq r4, [r7, #124]\n");
3584 
3585   COMPARE_T32(Str(eq, r4, MemOperand(r7, 1)),
3586               "bne 0x00000006\n"
3587               "str r4, [r7, #1]\n");
3588 
3589   COMPARE_T32(Str(eq, r4, MemOperand(r7, 128)),
3590               "bne 0x00000006\n"
3591               "str r4, [r7, #128]\n");
3592 
3593   // STR (immediate) T2
3594   COMPARE_T32(Str(eq, r4, MemOperand(sp, 1020)),
3595               "it eq\n"
3596               "streq r4, [sp, #1020]\n");
3597 
3598   COMPARE_T32(Str(eq, r4, MemOperand(sp, 1)),
3599               "bne 0x00000006\n"
3600               "str r4, [sp, #1]\n");
3601 
3602   COMPARE_T32(Str(eq, r4, MemOperand(sp, 1024)),
3603               "bne 0x00000006\n"
3604               "str r4, [sp, #1024]\n");
3605 
3606   // STR (register) T1
3607   COMPARE_T32(Str(eq, r5, MemOperand(r6, r7)),
3608               "it eq\n"
3609               "streq r5, [r6, r7]\n");
3610 
3611   COMPARE_T32(Str(eq, r5, MemOperand(r6, r8)),
3612               "bne 0x00000006\n"
3613               "str r5, [r6, r8]\n");
3614 
3615   // STRB (immediate) T1
3616   COMPARE_T32(Strb(eq, r6, MemOperand(r7, 31)),
3617               "it eq\n"
3618               "strbeq r6, [r7, #31]\n");
3619 
3620   COMPARE_T32(Strb(eq, r6, MemOperand(r7, 32)),
3621               "bne 0x00000006\n"
3622               "strb r6, [r7, #32]\n");
3623 
3624   // STRB (register) T1
3625   COMPARE_T32(Strb(eq, r5, MemOperand(r6, r7)),
3626               "it eq\n"
3627               "strbeq r5, [r6, r7]\n");
3628 
3629   COMPARE_T32(Strb(eq, r6, MemOperand(r9)),
3630               "bne 0x00000006\n"
3631               "strb r6, [r9]\n");
3632 
3633   // STRH (immediate) T1
3634   COMPARE_T32(Strh(eq, r6, MemOperand(r7, 62)),
3635               "it eq\n"
3636               "strheq r6, [r7, #62]\n");
3637 
3638   COMPARE_T32(Strh(eq, r6, MemOperand(r7, 64)),
3639               "bne 0x00000006\n"
3640               "strh r6, [r7, #64]\n");
3641 
3642   COMPARE_T32(Strh(eq, r6, MemOperand(r7, 1)),
3643               "bne 0x00000006\n"
3644               "strh r6, [r7, #1]\n");
3645 
3646   // STRH (register) T1
3647   COMPARE_T32(Strh(eq, r5, MemOperand(r6, r7)),
3648               "it eq\n"
3649               "strheq r5, [r6, r7]\n");
3650 
3651   COMPARE_T32(Strh(eq, r6, MemOperand(r9)),
3652               "bne 0x00000006\n"
3653               "strh r6, [r9]\n");
3654 
3655   // SUB (immediate) T1
3656   COMPARE_T32(Sub(eq, r0, r1, 0x1),
3657               "it eq\n"
3658               "subeq r0, r1, #1\n");
3659 
3660   COMPARE_T32(Sub(eq, r0, r1, 0x8),
3661               "bne 0x00000006\n"
3662               "sub r0, r1, #8\n");
3663 
3664   // SUB (immediate) T2
3665   COMPARE_T32(Sub(eq, r0, r0, 0xff),
3666               "it eq\n"
3667               "subeq r0, #255\n");
3668 
3669   // SUB (register) T1
3670   COMPARE_T32(Sub(eq, r0, r1, r7),
3671               "it eq\n"
3672               "subeq r0, r1, r7\n");
3673 
3674   COMPARE_T32(Sub(eq, r5, r5, r8),
3675               "bne 0x00000006\n"
3676               "sub r5, r8\n");
3677 
3678   COMPARE_T32(Sub(eq, r7, sp, 1),
3679               "bne 0x00000006\n"
3680               "sub r7, sp, #1\n");
3681 
3682   MUST_FAIL_TEST_T32(Sub(eq, pc, pc, 0), "Unpredictable instruction.\n");
3683 
3684   // TST (register) T1
3685   COMPARE_T32(Tst(eq, r0, r1),
3686               "it eq\n"
3687               "tsteq r0, r1\n");
3688 
3689   COMPARE_T32(Tst(eq, r8, r9),
3690               "bne 0x00000006\n"
3691               "tst r8, r9\n");
3692 
3693   CLEANUP();
3694 }
3695 
3696 
TEST(unbound_label)3697 TEST(unbound_label) {
3698   SETUP();
3699 
3700 #ifdef VIXL_DEBUG
3701   MUST_FAIL_TEST_BOTH_BLOCK(
3702       {
3703         Label label;
3704         masm.B(&label);
3705       },
3706       "Location, label or literal used but not bound.\n")
3707 
3708   MUST_FAIL_TEST_BOTH_BLOCK(
3709       {
3710         Label label;
3711         masm.B(eq, &label);
3712       },
3713       "Location, label or literal used but not bound.\n")
3714 
3715   MUST_FAIL_TEST_T32_BLOCK(
3716       {
3717         Label label;
3718         masm.Cbz(r0, &label);
3719       },
3720       "Location, label or literal used but not bound.\n")
3721 
3722   MUST_FAIL_TEST_T32_BLOCK(
3723       {
3724         Label label;
3725         masm.Cbnz(r1, &label);
3726       },
3727       "Location, label or literal used but not bound.\n")
3728 #endif
3729 
3730   CLEANUP();
3731 }
3732 
3733 
TEST(macro_assembler_AddressComputationHelper)3734 TEST(macro_assembler_AddressComputationHelper) {
3735   SETUP();
3736 
3737   // Simple cases: the address fits in the mask.
3738   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0xfff, 0xfff)),
3739               "ldr r0, [r1, #4095]\n");
3740   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 1, 0xfff)),
3741               "ldr r0, [r1, #1]\n");
3742   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0, 0xfff)),
3743               "ldr r0, [r1]\n");
3744 
3745   // Similar, but the base register must be preserved. (This has no effect for
3746   // encodable cases.)
3747   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r2, r1, 0xfff, 0xfff)),
3748               "ldr r0, [r1, #4095]\n");
3749 
3750   // Cases where the extra offset has to be aligned.
3751   COMPARE_A32(Vldr(d0, masm.MemOperandComputationHelper(r1, r1, 0x3fc, 0x3fc)),
3752               "vldr d0, [r1, #1020]\n");
3753 
3754   // Out-of-range offsets.
3755   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0x1000, 0xfff)),
3756               "add r1, #4096\n"
3757               "ldr r0, [r1]\n");
3758   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r2, r1, 0x1000, 0xfff)),
3759               "add r2, r1, #4096\n"
3760               "ldr r0, [r2]\n");
3761   COMPARE_A32(Ldr(r0,
3762                   masm.MemOperandComputationHelper(r2, r1, 0xffffffff, 0xfff)),
3763               "sub r2, r1, #1\n"
3764               "ldr r0, [r2]\n");
3765 
3766   // TODO: Improve the code generation for these cases.
3767 
3768   COMPARE_A32(Ldr(r0,
3769                   masm.MemOperandComputationHelper(r2, r1, 0x12345678, 0xfff)),
3770               "mov r2, #20480\n"
3771               "movt r2, #4660\n"
3772               "add r2, r1, r2\n"
3773               "ldr r0, [r2, #1656]\n");
3774   COMPARE_A32(Ldr(r0,
3775                   masm.MemOperandComputationHelper(r2, r1, 0x7fffffff, 0xfff)),
3776               "sub r2, r1, #1\n"
3777               "sub r2, #2147483648\n"
3778               "ldr r0, [r2]\n");
3779   COMPARE_A32(Ldr(r0,
3780                   masm.MemOperandComputationHelper(r2, r1, 0xffcba000, 0xfff)),
3781               "sub r2, r1, #286720\n"
3782               "sub r2, #3145728\n"
3783               "ldr r0, [r2]\n");
3784 
3785   CLEANUP();
3786 }
3787 
3788 
TEST(barriers)3789 TEST(barriers) {
3790   SETUP();
3791 
3792   // DMB
3793   COMPARE_BOTH(Dmb(SY), "dmb sy\n");
3794   COMPARE_BOTH(Dmb(ST), "dmb st\n");
3795   COMPARE_BOTH(Dmb(ISH), "dmb ish\n");
3796   COMPARE_BOTH(Dmb(ISHST), "dmb ishst\n");
3797   COMPARE_BOTH(Dmb(NSH), "dmb nsh\n");
3798   COMPARE_BOTH(Dmb(NSHST), "dmb nshst\n");
3799   COMPARE_BOTH(Dmb(OSH), "dmb osh\n");
3800   COMPARE_BOTH(Dmb(OSHST), "dmb oshst\n");
3801 
3802   // DSB
3803   COMPARE_BOTH(Dsb(SY), "dsb sy\n");
3804   COMPARE_BOTH(Dsb(ST), "dsb st\n");
3805   COMPARE_BOTH(Dsb(ISH), "dsb ish\n");
3806   COMPARE_BOTH(Dsb(ISHST), "dsb ishst\n");
3807   COMPARE_BOTH(Dsb(NSH), "dsb nsh\n");
3808   COMPARE_BOTH(Dsb(NSHST), "dsb nshst\n");
3809   COMPARE_BOTH(Dsb(OSH), "dsb osh\n");
3810   COMPARE_BOTH(Dsb(OSHST), "dsb oshst\n");
3811 
3812   // ISB
3813   COMPARE_BOTH(Isb(SY), "isb sy\n");
3814 
3815   CLEANUP();
3816 }
3817 
3818 
TEST(preloads)3819 TEST(preloads) {
3820   // Smoke test for various pld/pli forms.
3821   SETUP();
3822 
3823   // PLD immediate
3824   COMPARE_BOTH(Pld(MemOperand(r0, 0)), "pld [r0]\n");
3825   COMPARE_BOTH(Pld(MemOperand(r1, 123)), "pld [r1, #123]\n");
3826   COMPARE_BOTH(Pld(MemOperand(r4, -123)), "pld [r4, #-123]\n");
3827 
3828   COMPARE_A32(Pld(MemOperand(r7, -4095)), "pld [r7, #-4095]\n");
3829 
3830   // PLDW immediate
3831   COMPARE_BOTH(Pldw(MemOperand(r0, 0)), "pldw [r0]\n");
3832   COMPARE_BOTH(Pldw(MemOperand(r1, 123)), "pldw [r1, #123]\n");
3833   COMPARE_BOTH(Pldw(MemOperand(r4, -123)), "pldw [r4, #-123]\n");
3834 
3835   COMPARE_A32(Pldw(MemOperand(r7, -4095)), "pldw [r7, #-4095]\n");
3836 
3837   // PLD register
3838   COMPARE_BOTH(Pld(MemOperand(r0, r1)), "pld [r0, r1]\n");
3839   COMPARE_BOTH(Pld(MemOperand(r0, r1, LSL, 1)), "pld [r0, r1, lsl #1]\n");
3840 
3841   COMPARE_A32(Pld(MemOperand(r0, r1, LSL, 20)), "pld [r0, r1, lsl #20]\n");
3842 
3843   // PLDW register
3844   COMPARE_BOTH(Pldw(MemOperand(r0, r1)), "pldw [r0, r1]\n");
3845   COMPARE_BOTH(Pldw(MemOperand(r0, r1, LSL, 1)), "pldw [r0, r1, lsl #1]\n");
3846 
3847   COMPARE_A32(Pldw(MemOperand(r0, r1, LSL, 20)), "pldw [r0, r1, lsl #20]\n");
3848 
3849   // PLD literal
3850   COMPARE_BOTH(Pld(MemOperand(pc, minus, 0)), "pld [pc, #-0]\n");
3851 
3852   // PLI immediate
3853   COMPARE_BOTH(Pli(MemOperand(r0, 0)), "pli [r0]\n");
3854   COMPARE_BOTH(Pli(MemOperand(r1, 123)), "pli [r1, #123]\n");
3855   COMPARE_BOTH(Pli(MemOperand(r4, -123)), "pli [r4, #-123]\n");
3856 
3857   COMPARE_A32(Pli(MemOperand(r7, -4095)), "pli [r7, #-4095]\n");
3858 
3859   // PLI register
3860   COMPARE_BOTH(Pli(MemOperand(r0, r1)), "pli [r0, r1]\n");
3861   COMPARE_BOTH(Pli(MemOperand(r0, r1, LSL, 1)), "pli [r0, r1, lsl #1]\n");
3862 
3863   COMPARE_A32(Pli(MemOperand(r0, r1, LSL, 20)), "pli [r0, r1, lsl #20]\n");
3864 
3865   // PLI literal
3866   COMPARE_BOTH(Pli(MemOperand(pc, minus, 0)), "pli [pc, #-0]\n");
3867 
3868   CLEANUP();
3869 }
3870 
3871 
TEST(vcmp_vcmpe)3872 TEST(vcmp_vcmpe) {
3873   SETUP();
3874 
3875   COMPARE_BOTH(Vcmp(F32, s0, s1), "vcmp.f32 s0, s1\n");
3876   COMPARE_BOTH(Vcmp(F64, d0, d1), "vcmp.f64 d0, d1\n");
3877   COMPARE_BOTH(Vcmp(F32, s0, 0.0f), "vcmp.f32 s0, #0.0\n");
3878   COMPARE_BOTH(Vcmp(F64, d0, 0.0), "vcmp.f64 d0, #0.0\n");
3879 
3880   COMPARE_BOTH(Vcmpe(F32, s0, s1), "vcmpe.f32 s0, s1\n");
3881   COMPARE_BOTH(Vcmpe(F64, d0, d1), "vcmpe.f64 d0, d1\n");
3882   COMPARE_BOTH(Vcmpe(F32, s0, 0.0f), "vcmpe.f32 s0, #0.0\n");
3883   COMPARE_BOTH(Vcmpe(F64, d0, 0.0), "vcmpe.f64 d0, #0.0\n");
3884 
3885   CLEANUP();
3886 }
3887 
3888 
TEST(vmrs_vmsr)3889 TEST(vmrs_vmsr) {
3890   SETUP();
3891 
3892   COMPARE_BOTH(Vmsr(FPSCR, r0), "vmsr FPSCR, r0\n");
3893 
3894   COMPARE_BOTH(Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR),
3895                "vmrs r1, FPSCR\n");
3896 
3897   COMPARE_BOTH(Vmrs(RegisterOrAPSR_nzcv(pc.GetCode()), FPSCR),
3898                "vmrs APSR_nzcv, FPSCR\n");
3899 
3900   CLEANUP();
3901 }
3902 
3903 
TEST(ldm_stm)3904 TEST(ldm_stm) {
3905   SETUP();
3906 
3907   // ldm/stm
3908   COMPARE_BOTH(Ldm(r0, NO_WRITE_BACK, RegisterList(r1)), "ldm r0, {r1}\n");
3909 
3910   COMPARE_BOTH(Ldm(r1, NO_WRITE_BACK, RegisterList(r2, r5, r9, r10)),
3911                "ldm r1, {r2,r5,r9,r10}\n");
3912 
3913   COMPARE_BOTH(Ldm(r0, WRITE_BACK, RegisterList(r1, r2)), "ldm r0!, {r1,r2}\n");
3914 
3915   COMPARE_BOTH(Stm(r1, NO_WRITE_BACK, RegisterList(r2, r5, r9, r10)),
3916                "stm r1, {r2,r5,r9,r10}\n");
3917 
3918   COMPARE_BOTH(Stm(r0, WRITE_BACK, RegisterList(r1, r2)), "stm r0!, {r1,r2}\n");
3919 
3920   // ldmda/stmda
3921   COMPARE_A32(Ldmda(r11, WRITE_BACK, RegisterList(r0, r1)),
3922               "ldmda r11!, {r0,r1}\n");
3923 
3924   COMPARE_A32(Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3925               "ldmda r11, {r2,r3}\n");
3926 
3927   COMPARE_A32(Stmda(r11, WRITE_BACK, RegisterList(r0, r1)),
3928               "stmda r11!, {r0,r1}\n");
3929 
3930   COMPARE_A32(Stmda(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3931               "stmda r11, {r2,r3}\n");
3932 
3933   // ldmib/stmib
3934   COMPARE_A32(Ldmib(r11, WRITE_BACK, RegisterList(r0, r1)),
3935               "ldmib r11!, {r0,r1}\n");
3936 
3937   COMPARE_A32(Ldmib(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3938               "ldmib r11, {r2,r3}\n");
3939 
3940   COMPARE_A32(Stmib(r11, WRITE_BACK, RegisterList(r0, r1)),
3941               "stmib r11!, {r0,r1}\n");
3942 
3943   COMPARE_A32(Stmib(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3944               "stmib r11, {r2,r3}\n");
3945 
3946   // ldmdb/stmdb
3947   COMPARE_BOTH(Ldmdb(r11, WRITE_BACK, RegisterList(r0, r1)),
3948                "ldmdb r11!, {r0,r1}\n");
3949 
3950   COMPARE_BOTH(Ldmdb(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3951                "ldmdb r11, {r2,r3}\n");
3952 
3953   COMPARE_BOTH(Stmdb(r11, WRITE_BACK, RegisterList(r0, r1)),
3954                "stmdb r11!, {r0,r1}\n");
3955 
3956   COMPARE_BOTH(Stmdb(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3957                "stmdb r11, {r2,r3}\n");
3958 
3959   CLEANUP();
3960 }
3961 
3962 
3963 #define CHECK_T32_16(ASM, EXP) COMPARE_T32_CHECK_SIZE(ASM, EXP, 2)
3964 // For instructions inside an IT block, we need to account for the IT
3965 // instruction as well (another 16 bits).
3966 #define CHECK_T32_16_IT_BLOCK(ASM, EXP) COMPARE_T32_CHECK_SIZE(ASM, EXP, 4)
3967 
TEST(macro_assembler_T32_16bit)3968 TEST(macro_assembler_T32_16bit) {
3969   SETUP();
3970 
3971   // Allow the test to use all registers.
3972   UseScratchRegisterScope temps(&masm);
3973   temps.ExcludeAll();
3974 
3975   CHECK_T32_16(Adc(DontCare, r7, r7, r6), "adcs r7, r6\n");
3976 
3977   CHECK_T32_16_IT_BLOCK(Adc(DontCare, eq, r7, r7, r6),
3978                         "it eq\n"
3979                         "adceq r7, r6\n");
3980 
3981   CHECK_T32_16(Add(DontCare, r6, r7, 7), "adds r6, r7, #7\n");
3982 
3983   CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r6, r7, 7),
3984                         "it lt\n"
3985                         "addlt r6, r7, #7\n");
3986 
3987   CHECK_T32_16(Add(DontCare, r5, r5, 255), "adds r5, #255\n");
3988 
3989   CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r5, r5, 255),
3990                         "it lt\n"
3991                         "addlt r5, #255\n");
3992 
3993   // Make sure we select the non flag-setting version here, since
3994   // this can have two potential encodings.
3995   CHECK_T32_16(Add(DontCare, r1, r1, r2), "add r1, r2\n");
3996 
3997   CHECK_T32_16(Add(DontCare, r1, r2, r7), "adds r1, r2, r7\n");
3998 
3999   CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r1, r2, r7),
4000                         "it lt\n"
4001                         "addlt r1, r2, r7\n");
4002 
4003   CHECK_T32_16(Add(DontCare, r4, r4, r12), "add r4, ip\n");
4004 
4005   CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, r4, r4, r12),
4006                         "it eq\n"
4007                         "addeq r4, ip\n");
4008 
4009   CHECK_T32_16(Add(DontCare, r0, sp, 1020), "add r0, sp, #1020\n");
4010 
4011   CHECK_T32_16_IT_BLOCK(Add(DontCare, ge, r0, sp, 1020),
4012                         "it ge\n"
4013                         "addge r0, sp, #1020\n");
4014 
4015   // The equivalent inside an IT block is deprecated.
4016   CHECK_T32_16(Add(DontCare, sp, sp, 508), "add sp, #508\n");
4017 
4018   CHECK_T32_16(Add(DontCare, r7, sp, r7), "add r7, sp, r7\n");
4019 
4020   CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, r7, sp, r7),
4021                         "it eq\n"
4022                         "addeq r7, sp, r7\n");
4023 
4024   CHECK_T32_16(Add(DontCare, sp, sp, r10), "add sp, r10\n");
4025 
4026   CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, sp, sp, r10),
4027                         "it eq\n"
4028                         "addeq sp, r10\n");
4029 
4030   CHECK_T32_16(And(DontCare, r7, r7, r6), "ands r7, r6\n");
4031 
4032   CHECK_T32_16_IT_BLOCK(And(DontCare, eq, r7, r7, r6),
4033                         "it eq\n"
4034                         "andeq r7, r6\n");
4035 
4036   CHECK_T32_16(Asr(DontCare, r0, r1, 32), "asrs r0, r1, #32\n");
4037 
4038   CHECK_T32_16_IT_BLOCK(Asr(DontCare, eq, r0, r1, 32),
4039                         "it eq\n"
4040                         "asreq r0, r1, #32\n");
4041 
4042   CHECK_T32_16(Asr(DontCare, r0, r0, r1), "asrs r0, r1\n");
4043 
4044   CHECK_T32_16_IT_BLOCK(Asr(DontCare, eq, r0, r0, r1),
4045                         "it eq\n"
4046                         "asreq r0, r1\n");
4047 
4048   CHECK_T32_16(Bic(DontCare, r7, r7, r6), "bics r7, r6\n");
4049 
4050   CHECK_T32_16_IT_BLOCK(Bic(DontCare, eq, r7, r7, r6),
4051                         "it eq\n"
4052                         "biceq r7, r6\n");
4053 
4054   CHECK_T32_16(Eor(DontCare, r7, r7, r6), "eors r7, r6\n");
4055 
4056   CHECK_T32_16_IT_BLOCK(Eor(DontCare, eq, r7, r7, r6),
4057                         "it eq\n"
4058                         "eoreq r7, r6\n");
4059 
4060   CHECK_T32_16(Lsl(DontCare, r0, r1, 31), "lsls r0, r1, #31\n");
4061 
4062   CHECK_T32_16_IT_BLOCK(Lsl(DontCare, eq, r0, r1, 31),
4063                         "it eq\n"
4064                         "lsleq r0, r1, #31\n");
4065 
4066   CHECK_T32_16(Lsl(DontCare, r0, r0, r1), "lsls r0, r1\n");
4067 
4068   CHECK_T32_16_IT_BLOCK(Lsl(DontCare, eq, r0, r0, r1),
4069                         "it eq\n"
4070                         "lsleq r0, r1\n");
4071 
4072   CHECK_T32_16(Lsr(DontCare, r0, r1, 32), "lsrs r0, r1, #32\n");
4073 
4074   CHECK_T32_16_IT_BLOCK(Lsr(DontCare, eq, r0, r1, 32),
4075                         "it eq\n"
4076                         "lsreq r0, r1, #32\n");
4077 
4078   CHECK_T32_16(Lsr(DontCare, r0, r0, r1), "lsrs r0, r1\n");
4079 
4080   CHECK_T32_16_IT_BLOCK(Lsr(DontCare, eq, r0, r0, r1),
4081                         "it eq\n"
4082                         "lsreq r0, r1\n");
4083 
4084   CHECK_T32_16(Mov(DontCare, r7, 255), "movs r7, #255\n");
4085 
4086   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, 255),
4087                         "it eq\n"
4088                         "moveq r7, #255\n");
4089 
4090   CHECK_T32_16(Mov(DontCare, r9, r8), "mov r9, r8\n");
4091 
4092   // Check that we don't try to pick the MOVS register-shifted register variant.
4093   CHECK_T32_16(Mov(DontCare, r5, r6), "mov r5, r6\n");
4094 
4095   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r9, r8),
4096                         "it eq\n"
4097                         "moveq r9, r8\n");
4098 
4099   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, ASR, 1)), "asrs r5, r6, #1\n");
4100 
4101   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, ASR, 32)), "asrs r5, r6, #32\n");
4102 
4103   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSR, 1)), "lsrs r5, r6, #1\n");
4104 
4105   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSR, 32)), "lsrs r5, r6, #32\n");
4106 
4107   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSL, 1)), "lsls r5, r6, #1\n");
4108 
4109   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSL, 31)), "lsls r5, r6, #31\n");
4110 
4111   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, ASR, 1)),
4112                         "it eq\n"
4113                         "asreq r5, r6, #1\n");
4114 
4115   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, ASR, 32)),
4116                         "it eq\n"
4117                         "asreq r5, r6, #32\n");
4118 
4119   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSR, 1)),
4120                         "it eq\n"
4121                         "lsreq r5, r6, #1\n");
4122 
4123   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSR, 32)),
4124                         "it eq\n"
4125                         "lsreq r5, r6, #32\n");
4126 
4127   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSL, 1)),
4128                         "it eq\n"
4129                         "lsleq r5, r6, #1\n");
4130 
4131   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSL, 31)),
4132                         "it eq\n"
4133                         "lsleq r5, r6, #31\n");
4134 
4135   CHECK_T32_16(Mov(DontCare, r7, Operand(r7, ASR, r6)), "asrs r7, r6\n");
4136 
4137   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, ASR, r6)),
4138                         "it eq\n"
4139                         "asreq r7, r6\n");
4140 
4141   CHECK_T32_16(Mov(DontCare, r7, Operand(r7, LSR, r6)), "lsrs r7, r6\n");
4142 
4143   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, LSR, r6)),
4144                         "it eq\n"
4145                         "lsreq r7, r6\n");
4146 
4147   CHECK_T32_16(Mov(DontCare, r7, Operand(r7, LSL, r6)), "lsls r7, r6\n");
4148 
4149   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, LSL, r6)),
4150                         "it eq\n"
4151                         "lsleq r7, r6\n");
4152 
4153   CHECK_T32_16(Mov(DontCare, r7, Operand(r7, ROR, r6)), "rors r7, r6\n");
4154 
4155   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, ROR, r6)),
4156                         "it eq\n"
4157                         "roreq r7, r6\n");
4158 
4159   CHECK_T32_16(Mul(DontCare, r0, r1, r0), "muls r0, r1, r0\n");
4160 
4161   CHECK_T32_16_IT_BLOCK(Mul(DontCare, eq, r0, r1, r0),
4162                         "it eq\n"
4163                         "muleq r0, r1, r0\n");
4164 
4165   CHECK_T32_16(Mvn(DontCare, r6, r7), "mvns r6, r7\n");
4166 
4167   CHECK_T32_16_IT_BLOCK(Mvn(DontCare, eq, r6, r7),
4168                         "it eq\n"
4169                         "mvneq r6, r7\n");
4170 
4171   CHECK_T32_16(Orr(DontCare, r7, r7, r6), "orrs r7, r6\n");
4172 
4173   CHECK_T32_16_IT_BLOCK(Orr(DontCare, eq, r7, r7, r6),
4174                         "it eq\n"
4175                         "orreq r7, r6\n");
4176 
4177   CHECK_T32_16(Ror(DontCare, r0, r0, r1), "rors r0, r1\n");
4178 
4179   CHECK_T32_16_IT_BLOCK(Ror(DontCare, eq, r0, r0, r1),
4180                         "it eq\n"
4181                         "roreq r0, r1\n");
4182 
4183   CHECK_T32_16(Rsb(DontCare, r7, r6, 0), "rsbs r7, r6, #0\n");
4184 
4185   CHECK_T32_16_IT_BLOCK(Rsb(DontCare, eq, r7, r6, 0),
4186                         "it eq\n"
4187                         "rsbeq r7, r6, #0\n");
4188 
4189   CHECK_T32_16(Sbc(DontCare, r7, r7, r6), "sbcs r7, r6\n");
4190 
4191   CHECK_T32_16_IT_BLOCK(Sbc(DontCare, eq, r7, r7, r6),
4192                         "it eq\n"
4193                         "sbceq r7, r6\n");
4194 
4195   CHECK_T32_16(Sub(DontCare, r6, r7, 7), "subs r6, r7, #7\n");
4196 
4197   CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r6, r7, 7),
4198                         "it lt\n"
4199                         "sublt r6, r7, #7\n");
4200 
4201   CHECK_T32_16(Sub(DontCare, r5, r5, 255), "subs r5, #255\n");
4202 
4203   CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r5, r5, 255),
4204                         "it lt\n"
4205                         "sublt r5, #255\n");
4206 
4207   CHECK_T32_16(Sub(DontCare, r1, r2, r7), "subs r1, r2, r7\n");
4208 
4209   CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r1, r2, r7),
4210                         "it lt\n"
4211                         "sublt r1, r2, r7\n");
4212 
4213   // The equivalent inside an IT block is deprecated.
4214   CHECK_T32_16(Sub(DontCare, sp, sp, 508), "sub sp, #508\n");
4215 
4216   // Generate SUBS for ADD.
4217   CHECK_T32_16(Add(DontCare, r0, r1, -1), "subs r0, r1, #1\n");
4218 
4219   CHECK_T32_16(Add(DontCare, r0, r1, -7), "subs r0, r1, #7\n");
4220 
4221   CHECK_T32_16(Add(DontCare, r6, r6, -1), "subs r6, #1\n");
4222 
4223   CHECK_T32_16(Add(DontCare, r6, r6, -255), "subs r6, #255\n");
4224 
4225   // Generate ADDS for SUB.
4226   CHECK_T32_16(Sub(DontCare, r0, r1, -1), "adds r0, r1, #1\n");
4227 
4228   CHECK_T32_16(Sub(DontCare, r0, r1, -7), "adds r0, r1, #7\n");
4229 
4230   CHECK_T32_16(Sub(DontCare, r6, r6, -1), "adds r6, #1\n");
4231 
4232   CHECK_T32_16(Sub(DontCare, r6, r6, -255), "adds r6, #255\n");
4233 
4234   // Check that we don't change the opcode for INT_MIN.
4235   COMPARE_T32(Add(DontCare, r6, r6, 0x80000000), "add r6, #2147483648\n");
4236 
4237   COMPARE_T32(Sub(DontCare, r6, r6, 0x80000000), "sub r6, #2147483648\n");
4238 
4239   CLEANUP();
4240 }
4241 #undef CHECK_T32_16
4242 #undef CHECK_T32_16_IT_BLOCK
4243 
TEST(nop_code)4244 TEST(nop_code) {
4245   SETUP();
4246 
4247   COMPARE_BOTH(Nop(), "nop\n");
4248 
4249   COMPARE_BOTH(And(r0, r0, r0), "");
4250   COMPARE_BOTH(And(DontCare, r0, r0, r0), "");
4251 
4252   COMPARE_BOTH(Mov(r0, r0), "");
4253   COMPARE_BOTH(Mov(DontCare, r0, r0), "");
4254 
4255   COMPARE_BOTH(Orr(r0, r0, r0), "");
4256   COMPARE_BOTH(Orr(DontCare, r0, r0, r0), "");
4257 
4258   CLEANUP();
4259 }
4260 
4261 
TEST(minus_zero_offsets)4262 TEST(minus_zero_offsets) {
4263   SETUP();
4264 
4265   COMPARE_A32(Ldr(r0, MemOperand(pc, minus, 0)), "ldr r0, [pc, #-0]\n");
4266   COMPARE_T32(Ldr(r0, MemOperand(pc, minus, 0)), "ldr.w r0, [pc, #-0]\n");
4267   COMPARE_BOTH(Ldrb(r0, MemOperand(pc, minus, 0)), "ldrb r0, [pc, #-0]\n");
4268   COMPARE_BOTH(Ldrh(r0, MemOperand(pc, minus, 0)), "ldrh r0, [pc, #-0]\n");
4269   COMPARE_BOTH(Ldrd(r0, r1, MemOperand(pc, minus, 0)),
4270                "ldrd r0, r1, [pc, #-0]\n");
4271   COMPARE_BOTH(Ldrsb(r0, MemOperand(pc, minus, 0)), "ldrsb r0, [pc, #-0]\n");
4272   COMPARE_BOTH(Ldrsh(r0, MemOperand(pc, minus, 0)), "ldrsh r0, [pc, #-0]\n");
4273   COMPARE_BOTH(Pld(MemOperand(pc, minus, 0)), "pld [pc, #-0]\n");
4274   COMPARE_BOTH(Pli(MemOperand(pc, minus, 0)), "pli [pc, #-0]\n");
4275   COMPARE_BOTH(Vldr(s0, MemOperand(pc, minus, 0)), "vldr s0, [pc, #-0]\n");
4276   COMPARE_BOTH(Vldr(d0, MemOperand(pc, minus, 0)), "vldr d0, [pc, #-0]\n");
4277 
4278   // This is an alias of ADR with a minus zero offset.
4279   COMPARE_BOTH(Sub(r0, pc, 0), "sub r0, pc, #0\n");
4280 
4281   CLEANUP();
4282 }
4283 
4284 
TEST(big_add_sub)4285 TEST(big_add_sub) {
4286   SETUP();
4287 
4288   COMPARE_A32(Add(r0, r1, 0x4321),
4289               "add r0, r1, #33\n"
4290               "add r0, #17152\n");
4291   COMPARE_T32(Add(r0, r1, 0x4321),
4292               "add r0, r1, #801\n"
4293               "add r0, #16384\n");
4294   COMPARE_BOTH(Add(r0, r1, 0x432100),
4295                "add r0, r1, #8448\n"
4296                "add r0, #4390912\n");
4297   COMPARE_BOTH(Add(r0, r1, 0x43000210),
4298                "add r0, r1, #528\n"
4299                "add r0, #1124073472\n");
4300   COMPARE_BOTH(Add(r0, r1, 0x30c00210),
4301                "add r0, r1, #528\n"
4302                "add r0, #817889280\n");
4303   COMPARE_BOTH(Add(r0, r1, 0x43000021),
4304                "add r0, r1, #33\n"
4305                "add r0, #1124073472\n");
4306   COMPARE_T32(Add(r0, r1, 0x54321),
4307               "add r0, r1, #801\n"
4308               "add r0, #344064\n");
4309   COMPARE_T32(Add(r0, r1, 0x54000321),
4310               "add r0, r1, #801\n"
4311               "add r0, #1409286144\n");
4312 
4313   COMPARE_A32(Sub(r0, r1, 0x4321),
4314               "sub r0, r1, #33\n"
4315               "sub r0, #17152\n");
4316   COMPARE_T32(Sub(r0, r1, 0x4321),
4317               "sub r0, r1, #801\n"
4318               "sub r0, #16384\n");
4319   COMPARE_BOTH(Sub(r0, r1, 0x432100),
4320                "sub r0, r1, #8448\n"
4321                "sub r0, #4390912\n");
4322   COMPARE_BOTH(Sub(r0, r1, 0x43000210),
4323                "sub r0, r1, #528\n"
4324                "sub r0, #1124073472\n");
4325   COMPARE_BOTH(Sub(r0, r1, 0x30c00210),
4326                "sub r0, r1, #528\n"
4327                "sub r0, #817889280\n");
4328   COMPARE_BOTH(Sub(r0, r1, 0x43000021),
4329                "sub r0, r1, #33\n"
4330                "sub r0, #1124073472\n");
4331   COMPARE_T32(Sub(r0, r1, 0x54321),
4332               "sub r0, r1, #801\n"
4333               "sub r0, #344064\n");
4334   COMPARE_T32(Sub(r0, r1, 0x54000321),
4335               "sub r0, r1, #801\n"
4336               "sub r0, #1409286144\n");
4337 
4338   CLEANUP();
4339 }
4340 
4341 }  // namespace aarch32
4342 }  // namespace vixl
4343