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