• 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 <sstream>
28 #include <string>
29 #include <list>
30 
31 #include "test-runner.h"
32 #include "test-utils.h"
33 
34 #include "aarch32/macro-assembler-aarch32.h"
35 #include "aarch32/disasm-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   // TODO: PC should not be allowed as register offset (unpredictable).
808   SHOULD_FAIL_TEST_BOTH(Ldr(r0, MemOperand(r0, Sign(plus), pc, Offset)));
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   // TODO: PC is allowed as the value we are storing for A32, but
865   //       should not be allowed for T32 (unpredictable).
866   COMPARE_A32(Str(pc, MemOperand(r0, r0, Offset)), "str pc, [r0, r0]\n");
867   COMPARE_A32(Str(pc, MemOperand(r0, r0, PreIndex)), "str pc, [r0, r0]!\n");
868   COMPARE_A32(Str(pc, MemOperand(r0, r0, PostIndex)), "str pc, [r0], r0\n");
869   SHOULD_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, Offset)));
870   SHOULD_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, PreIndex)));
871   SHOULD_FAIL_TEST_T32(Str(pc, MemOperand(r0, r0, PostIndex)));
872 
873   // PC is allowed as register base in the offset variant only for A32.
874   COMPARE_A32(Str(r0, MemOperand(pc, r0, Offset)), "str r0, [pc, r0]\n");
875   MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, Offset)),
876                      "The MacroAssembler does not convert loads and stores with"
877                      " a PC base register for T32.\n");
878 
879   // PC is not allowed as register base in the pre-index and post-index
880   // variants.
881   MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, PreIndex)),
882                      "The MacroAssembler does not convert loads and stores "
883                      "with a PC base register in pre-index or post-index "
884                      "mode.\n");
885   MUST_FAIL_TEST_T32(Str(r0, MemOperand(pc, r0, PostIndex)),
886                      "The MacroAssembler does not convert loads and stores "
887                      "with a PC base register in pre-index or post-index "
888                      "mode.\n");
889 
890   // We don't convert loads with PC as the register offset.
891   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, minus, pc, Offset)),
892                      "The MacroAssembler does not convert loads and stores "
893                      "with a PC offset register.\n");
894   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, pc, PreIndex)),
895                      "The MacroAssembler does not convert loads and stores "
896                      "with a PC offset register.\n");
897   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, pc, PostIndex)),
898                      "The MacroAssembler does not convert loads and stores "
899                      "with a PC offset register.\n");
900 
901   // TODO: PC should not be allowed as register offset (unpredictable).
902   SHOULD_FAIL_TEST_BOTH(Str(r0, MemOperand(r0, Sign(plus), pc, Offset)));
903 
904   // TODO: PC should not be allowed as register base in A32 with pre-index
905   //       and post-index (unpredictable).
906   SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(pc, r0, PreIndex)));
907   SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(pc, r0, PostIndex)));
908 
909   // TODO: store with the same register used as base and as source
910   //       should fail to assemble (unpredictable).
911   SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(r0, r1, PreIndex)));
912   SHOULD_FAIL_TEST_A32(Str(r0, MemOperand(r0, r1, PostIndex)));
913   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, r1, PreIndex)),
914                      "Ill-formed 'str' instruction.\n");
915   MUST_FAIL_TEST_T32(Str(r0, MemOperand(r0, r1, PostIndex)),
916                      "Ill-formed 'str' instruction.\n");
917 
918   CLEANUP();
919 }
920 
921 
TEST(macro_assembler_ldrd)922 TEST(macro_assembler_ldrd) {
923   SETUP();
924 
925   // - Tests with no offset.
926 
927   COMPARE_BOTH(Ldrd(r0, r1, MemOperand(r3)), "ldrd r0, r1, [r3]\n");
928   // Destination registers need to start with a even numbered register on A32.
929   MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r3)),
930                      "Unpredictable instruction.\n");
931   COMPARE_T32(Ldrd(r1, r2, MemOperand(r3)), "ldrd r1, r2, [r3]\n");
932   // Registers need to be adjacent on A32.
933   MUST_FAIL_TEST_A32(Ldrd(r0, r2, MemOperand(r1)),
934                      "Ill-formed 'ldrd' instruction.\n");
935   COMPARE_T32(Ldrd(r0, r2, MemOperand(r1)), "ldrd r0, r2, [r1]\n");
936 
937   COMPARE_BOTH(Ldrd(r0, r1, MemOperand(r2)), "ldrd r0, r1, [r2]\n");
938 
939   // - Tests with immediate offsets.
940 
941   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 1020)),
942               "add r0, r2, #1020\n"
943               "ldrd r0, r1, [r0]\n");
944   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 1020)), "ldrd r0, r1, [r2, #1020]\n");
945   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -1020)),
946               "sub r0, r2, #1020\n"
947               "ldrd r0, r1, [r0]\n");
948   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -1020)),
949               "ldrd r0, r1, [r2, #-1020]\n");
950 
951   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc)),
952               "add r0, r2, #43776\n"
953               "ldrd r0, r1, [r0, #204]\n");
954   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc)),
955               "add r0, r2, #43008\n"
956               "ldrd r0, r1, [r0, #972]\n");
957   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc)),
958               "sub r0, r2, #44032\n"
959               "ldrd r0, r1, [r0, #52]\n");
960   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc)),
961               "sub r0, r2, #44032\n"
962               "ldrd r0, r1, [r0, #52]\n");
963   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec)),
964               "add r0, r2, #52480\n"
965               "add r0, #11206656\n"
966               "ldrd r0, r1, [r0, #236]\n");
967   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec)),
968               "add r0, r2, #248832\n"
969               "add r0, #11010048\n"
970               "ldrd r0, r1, [r0, #492]\n");
971   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec)),
972               "sub r0, r2, #52736\n"
973               "sub r0, #11206656\n"
974               "ldrd r0, r1, [r0, #20]\n");
975   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec)),
976               "sub r0, r2, #774144\n"
977               "sub r0, #10485760\n"
978               "ldrd r0, r1, [r0, #532]\n");
979 
980   COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, 0xabcc)),
981               "add r1, r0, #43776\n"
982               "ldrd r0, r1, [r1, #204]\n");
983   COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, 0xabcc)),
984               "add r1, r0, #43008\n"
985               "ldrd r0, r1, [r1, #972]\n");
986   COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, -0xabcc)),
987               "sub r1, r0, #44032\n"
988               "ldrd r0, r1, [r1, #52]\n");
989   COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, -0xabcc)),
990               "sub r1, r0, #44032\n"
991               "ldrd r0, r1, [r1, #52]\n");
992   COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, 0xabcdec)),
993               "add r1, r0, #52480\n"
994               "add r1, #11206656\n"
995               "ldrd r0, r1, [r1, #236]\n");
996   COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, 0xabcdec)),
997               "add r1, r0, #248832\n"
998               "add r1, #11010048\n"
999               "ldrd r0, r1, [r1, #492]\n");
1000   COMPARE_A32(Ldrd(r0, r1, MemOperand(r0, -0xabcdec)),
1001               "sub r1, r0, #52736\n"
1002               "sub r1, #11206656\n"
1003               "ldrd r0, r1, [r1, #20]\n");
1004   COMPARE_T32(Ldrd(r0, r1, MemOperand(r0, -0xabcdec)),
1005               "sub r1, r0, #774144\n"
1006               "sub r1, #10485760\n"
1007               "ldrd r0, r1, [r1, #532]\n");
1008 
1009   COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, 0xabcc)),
1010               "add r0, r1, #43776\n"
1011               "ldrd r0, r1, [r0, #204]\n");
1012   COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, 0xabcc)),
1013               "add r0, r1, #43008\n"
1014               "ldrd r0, r1, [r0, #972]\n");
1015   COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, -0xabcc)),
1016               "sub r0, r1, #44032\n"
1017               "ldrd r0, r1, [r0, #52]\n");
1018   COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, -0xabcc)),
1019               "sub r0, r1, #44032\n"
1020               "ldrd r0, r1, [r0, #52]\n");
1021   COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, 0xabcdec)),
1022               "add r0, r1, #52480\n"
1023               "add r0, #11206656\n"
1024               "ldrd r0, r1, [r0, #236]\n");
1025   COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, 0xabcdec)),
1026               "add r0, r1, #248832\n"
1027               "add r0, #11010048\n"
1028               "ldrd r0, r1, [r0, #492]\n");
1029   COMPARE_A32(Ldrd(r0, r1, MemOperand(r1, -0xabcdec)),
1030               "sub r0, r1, #52736\n"
1031               "sub r0, #11206656\n"
1032               "ldrd r0, r1, [r0, #20]\n");
1033   COMPARE_T32(Ldrd(r0, r1, MemOperand(r1, -0xabcdec)),
1034               "sub r0, r1, #774144\n"
1035               "sub r0, #10485760\n"
1036               "ldrd r0, r1, [r0, #532]\n");
1037 
1038   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)),
1039               "ldrd r0, r1, [r2], #204\n"
1040               "add r2, #43776\n");
1041   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)),
1042               "ldrd r0, r1, [r2], #972\n"
1043               "add r2, #43008\n");
1044   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)),
1045               "ldrd r0, r1, [r2], #52\n"
1046               "sub r2, #44032\n");
1047   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)),
1048               "ldrd r0, r1, [r2], #52\n"
1049               "sub r2, #44032\n");
1050   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)),
1051               "ldrd r0, r1, [r2], #236\n"
1052               "add r2, #52480\n"
1053               "add r2, #11206656\n");
1054   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)),
1055               "ldrd r0, r1, [r2], #492\n"
1056               "add r2, #248832\n"
1057               "add r2, #11010048\n");
1058   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)),
1059               "ldrd r0, r1, [r2], #20\n"
1060               "sub r2, #52736\n"
1061               "sub r2, #11206656\n");
1062   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)),
1063               "ldrd r0, r1, [r2], #532\n"
1064               "sub r2, #774144\n"
1065               "sub r2, #10485760\n");
1066 
1067   // PostIndex with the same register as base and destination is invalid.
1068   MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r0, 0xabcd, PostIndex)),
1069                       "Ill-formed 'ldrd' instruction.\n");
1070   MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r1, 0xabcdef, PostIndex)),
1071                       "Ill-formed 'ldrd' instruction.\n");
1072 
1073   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)),
1074               "add r2, #43776\n"
1075               "ldrd r0, r1, [r2, #204]!\n");
1076   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)),
1077               "add r2, #43008\n"
1078               "ldrd r0, r1, [r2, #972]!\n");
1079   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)),
1080               "sub r2, #44032\n"
1081               "ldrd r0, r1, [r2, #52]!\n");
1082   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)),
1083               "sub r2, #44032\n"
1084               "ldrd r0, r1, [r2, #52]!\n");
1085   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)),
1086               "add r2, #52480\n"
1087               "add r2, #11206656\n"
1088               "ldrd r0, r1, [r2, #236]!\n");
1089   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)),
1090               "add r2, #248832\n"
1091               "add r2, #11010048\n"
1092               "ldrd r0, r1, [r2, #492]!\n");
1093   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)),
1094               "sub r2, #52736\n"
1095               "sub r2, #11206656\n"
1096               "ldrd r0, r1, [r2, #20]!\n");
1097   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)),
1098               "sub r2, #774144\n"
1099               "sub r2, #10485760\n"
1100               "ldrd r0, r1, [r2, #532]!\n");
1101 
1102   // - Tests with register offsets.
1103 
1104   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3)), "ldrd r0, r1, [r2, r3]\n");
1105   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3)),
1106               "add r0, r2, r3\n"
1107               "ldrd r0, r1, [r0]\n");
1108 
1109   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3)),
1110               "ldrd r0, r1, [r2, -r3]\n");
1111   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3)),
1112               "sub r0, r2, r3\n"
1113               "ldrd r0, r1, [r0]\n");
1114 
1115   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3, PostIndex)),
1116               "ldrd r0, r1, [r2], r3\n");
1117   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3, PostIndex)),
1118               "ldrd r0, r1, [r2]\n"
1119               "add r2, r3\n");
1120 
1121   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PostIndex)),
1122               "ldrd r0, r1, [r2], -r3\n");
1123   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PostIndex)),
1124               "ldrd r0, r1, [r2]\n"
1125               "sub r2, r3\n");
1126 
1127   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, r3, PreIndex)),
1128               "ldrd r0, r1, [r2, r3]!\n");
1129   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, r3, PreIndex)),
1130               "add r2, r3\n"
1131               "ldrd r0, r1, [r2]\n");
1132 
1133   COMPARE_A32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PreIndex)),
1134               "ldrd r0, r1, [r2, -r3]!\n");
1135   COMPARE_T32(Ldrd(r0, r1, MemOperand(r2, minus, r3, PreIndex)),
1136               "sub r2, r3\n"
1137               "ldrd r0, r1, [r2]\n");
1138 
1139   // - We do not support register shifted base register operands with LDRD.
1140 
1141   MUST_FAIL_TEST_BOTH(Ldrd(r0, r1, MemOperand(r2, r3, LSL, 4)),
1142                       "Ill-formed 'ldrd' instruction.\n");
1143 
1144   // First register is odd - rejected by the Assembler.
1145   MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0)),
1146                      "Unpredictable instruction.\n");
1147   MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0, r0, PreIndex)),
1148                      "Unpredictable instruction.\n");
1149   // First register is odd - rejected by the MacroAssembler.
1150   MUST_FAIL_TEST_A32(Ldrd(r1, r2, MemOperand(r0, 0xabcd, PreIndex)),
1151                      "Ill-formed 'ldrd' instruction.\n");
1152 
1153   // First register is lr - rejected by the Assembler.
1154   MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0)),
1155                      "Unpredictable instruction.\n");
1156   MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0, r0, PreIndex)),
1157                      "Unpredictable instruction.\n");
1158   // First register is lr - rejected by the MacroAssembler.
1159   MUST_FAIL_TEST_A32(Ldrd(lr, pc, MemOperand(r0, 0xabcd, PreIndex)),
1160                      "Ill-formed 'ldrd' instruction.\n");
1161 
1162   // Non-adjacent registers.
1163   MUST_FAIL_TEST_A32(Ldrd(r0, r2, MemOperand(r0)),
1164                      "Ill-formed 'ldrd' instruction.\n");
1165 
1166   CLEANUP();
1167 }
1168 
TEST(macro_assembler_strd)1169 TEST(macro_assembler_strd) {
1170   SETUP();
1171 
1172   // - Tests with no offset.
1173 
1174   COMPARE_BOTH(Strd(r0, r1, MemOperand(r3)), "strd r0, r1, [r3]\n");
1175   // Destination registers need to start with a even numbered register on A32.
1176   MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r3)),
1177                      "Unpredictable instruction.\n");
1178   COMPARE_T32(Strd(r1, r2, MemOperand(r3)), "strd r1, r2, [r3]\n");
1179   // Registers need to be adjacent on A32.
1180   MUST_FAIL_TEST_A32(Strd(r0, r2, MemOperand(r1)),
1181                      "Ill-formed 'strd' instruction.\n");
1182   COMPARE_T32(Strd(r0, r2, MemOperand(r1)), "strd r0, r2, [r1]\n");
1183 
1184   COMPARE_BOTH(Strd(r0, r1, MemOperand(r2)), "strd r0, r1, [r2]\n");
1185 
1186   // - Tests with immediate offsets.
1187 
1188   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 1020)),
1189               "add ip, r2, #1020\n"
1190               "strd r0, r1, [ip]\n");
1191   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 1020)), "strd r0, r1, [r2, #1020]\n");
1192   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -1020)),
1193               "sub ip, r2, #1020\n"
1194               "strd r0, r1, [ip]\n");
1195   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -1020)),
1196               "strd r0, r1, [r2, #-1020]\n");
1197 
1198   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc)),
1199               "add ip, r2, #43776\n"
1200               "strd r0, r1, [ip, #204]\n");
1201   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc)),
1202               "add ip, r2, #43008\n"
1203               "strd r0, r1, [ip, #972]\n");
1204   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc)),
1205               "sub ip, r2, #44032\n"
1206               "strd r0, r1, [ip, #52]\n");
1207   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc)),
1208               "sub ip, r2, #44032\n"
1209               "strd r0, r1, [ip, #52]\n");
1210   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec)),
1211               "add ip, r2, #52480\n"
1212               "add ip, #11206656\n"
1213               "strd r0, r1, [ip, #236]\n");
1214   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec)),
1215               "add ip, r2, #248832\n"
1216               "add ip, #11010048\n"
1217               "strd r0, r1, [ip, #492]\n");
1218   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec)),
1219               "sub ip, r2, #52736\n"
1220               "sub ip, #11206656\n"
1221               "strd r0, r1, [ip, #20]\n");
1222   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec)),
1223               "sub ip, r2, #774144\n"
1224               "sub ip, #10485760\n"
1225               "strd r0, r1, [ip, #532]\n");
1226 
1227   COMPARE_A32(Strd(r0, r1, MemOperand(r0, 0xabcc)),
1228               "add ip, r0, #43776\n"
1229               "strd r0, r1, [ip, #204]\n");
1230   COMPARE_T32(Strd(r0, r1, MemOperand(r0, 0xabcc)),
1231               "add ip, r0, #43008\n"
1232               "strd r0, r1, [ip, #972]\n");
1233   COMPARE_A32(Strd(r0, r1, MemOperand(r0, -0xabcc)),
1234               "sub ip, r0, #44032\n"
1235               "strd r0, r1, [ip, #52]\n");
1236   COMPARE_T32(Strd(r0, r1, MemOperand(r0, -0xabcc)),
1237               "sub ip, r0, #44032\n"
1238               "strd r0, r1, [ip, #52]\n");
1239   COMPARE_A32(Strd(r0, r1, MemOperand(r0, 0xabcdec)),
1240               "add ip, r0, #52480\n"
1241               "add ip, #11206656\n"
1242               "strd r0, r1, [ip, #236]\n");
1243   COMPARE_T32(Strd(r0, r1, MemOperand(r0, 0xabcdec)),
1244               "add ip, r0, #248832\n"
1245               "add ip, #11010048\n"
1246               "strd r0, r1, [ip, #492]\n");
1247   COMPARE_A32(Strd(r0, r1, MemOperand(r0, -0xabcdec)),
1248               "sub ip, r0, #52736\n"
1249               "sub ip, #11206656\n"
1250               "strd r0, r1, [ip, #20]\n");
1251   COMPARE_T32(Strd(r0, r1, MemOperand(r0, -0xabcdec)),
1252               "sub ip, r0, #774144\n"
1253               "sub ip, #10485760\n"
1254               "strd r0, r1, [ip, #532]\n");
1255 
1256   COMPARE_A32(Strd(r0, r1, MemOperand(r1, 0xabcc)),
1257               "add ip, r1, #43776\n"
1258               "strd r0, r1, [ip, #204]\n");
1259   COMPARE_T32(Strd(r0, r1, MemOperand(r1, 0xabcc)),
1260               "add ip, r1, #43008\n"
1261               "strd r0, r1, [ip, #972]\n");
1262   COMPARE_A32(Strd(r0, r1, MemOperand(r1, -0xabcc)),
1263               "sub ip, r1, #44032\n"
1264               "strd r0, r1, [ip, #52]\n");
1265   COMPARE_T32(Strd(r0, r1, MemOperand(r1, -0xabcc)),
1266               "sub ip, r1, #44032\n"
1267               "strd r0, r1, [ip, #52]\n");
1268   COMPARE_A32(Strd(r0, r1, MemOperand(r1, 0xabcdec)),
1269               "add ip, r1, #52480\n"
1270               "add ip, #11206656\n"
1271               "strd r0, r1, [ip, #236]\n");
1272   COMPARE_T32(Strd(r0, r1, MemOperand(r1, 0xabcdec)),
1273               "add ip, r1, #248832\n"
1274               "add ip, #11010048\n"
1275               "strd r0, r1, [ip, #492]\n");
1276   COMPARE_A32(Strd(r0, r1, MemOperand(r1, -0xabcdec)),
1277               "sub ip, r1, #52736\n"
1278               "sub ip, #11206656\n"
1279               "strd r0, r1, [ip, #20]\n");
1280   COMPARE_T32(Strd(r0, r1, MemOperand(r1, -0xabcdec)),
1281               "sub ip, r1, #774144\n"
1282               "sub ip, #10485760\n"
1283               "strd r0, r1, [ip, #532]\n");
1284 
1285   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)),
1286               "strd r0, r1, [r2], #204\n"
1287               "add r2, #43776\n");
1288   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc, PostIndex)),
1289               "strd r0, r1, [r2], #972\n"
1290               "add r2, #43008\n");
1291   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)),
1292               "strd r0, r1, [r2], #52\n"
1293               "sub r2, #44032\n");
1294   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc, PostIndex)),
1295               "strd r0, r1, [r2], #52\n"
1296               "sub r2, #44032\n");
1297   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)),
1298               "strd r0, r1, [r2], #236\n"
1299               "add r2, #52480\n"
1300               "add r2, #11206656\n");
1301   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PostIndex)),
1302               "strd r0, r1, [r2], #492\n"
1303               "add r2, #248832\n"
1304               "add r2, #11010048\n");
1305   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)),
1306               "strd r0, r1, [r2], #20\n"
1307               "sub r2, #52736\n"
1308               "sub r2, #11206656\n");
1309   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PostIndex)),
1310               "strd r0, r1, [r2], #532\n"
1311               "sub r2, #774144\n"
1312               "sub r2, #10485760\n");
1313 
1314   // PostIndex with the same register as base and source is invalid.
1315   MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r0, 0xabcd, PostIndex)),
1316                       "Ill-formed 'strd' instruction.\n");
1317   MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r1, 0xabcdef, PostIndex)),
1318                       "Ill-formed 'strd' instruction.\n");
1319 
1320   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)),
1321               "add r2, #43776\n"
1322               "strd r0, r1, [r2, #204]!\n");
1323   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcc, PreIndex)),
1324               "add r2, #43008\n"
1325               "strd r0, r1, [r2, #972]!\n");
1326   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)),
1327               "sub r2, #44032\n"
1328               "strd r0, r1, [r2, #52]!\n");
1329   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcc, PreIndex)),
1330               "sub r2, #44032\n"
1331               "strd r0, r1, [r2, #52]!\n");
1332   COMPARE_A32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)),
1333               "add r2, #52480\n"
1334               "add r2, #11206656\n"
1335               "strd r0, r1, [r2, #236]!\n");
1336   COMPARE_T32(Strd(r0, r1, MemOperand(r2, 0xabcdec, PreIndex)),
1337               "add r2, #248832\n"
1338               "add r2, #11010048\n"
1339               "strd r0, r1, [r2, #492]!\n");
1340   COMPARE_A32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)),
1341               "sub r2, #52736\n"
1342               "sub r2, #11206656\n"
1343               "strd r0, r1, [r2, #20]!\n");
1344   COMPARE_T32(Strd(r0, r1, MemOperand(r2, -0xabcdec, PreIndex)),
1345               "sub r2, #774144\n"
1346               "sub r2, #10485760\n"
1347               "strd r0, r1, [r2, #532]!\n");
1348 
1349   // - Tests with register offsets.
1350 
1351   COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3)), "strd r0, r1, [r2, r3]\n");
1352   COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3)),
1353               "add ip, r2, r3\n"
1354               "strd r0, r1, [ip]\n");
1355 
1356   COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3)),
1357               "strd r0, r1, [r2, -r3]\n");
1358   COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3)),
1359               "sub ip, r2, r3\n"
1360               "strd r0, r1, [ip]\n");
1361 
1362   COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3, PostIndex)),
1363               "strd r0, r1, [r2], r3\n");
1364   COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3, PostIndex)),
1365               "strd r0, r1, [r2]\n"
1366               "add r2, r3\n");
1367 
1368   COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3, PostIndex)),
1369               "strd r0, r1, [r2], -r3\n");
1370   COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3, PostIndex)),
1371               "strd r0, r1, [r2]\n"
1372               "sub r2, r3\n");
1373 
1374   COMPARE_A32(Strd(r0, r1, MemOperand(r2, r3, PreIndex)),
1375               "strd r0, r1, [r2, r3]!\n");
1376   COMPARE_T32(Strd(r0, r1, MemOperand(r2, r3, PreIndex)),
1377               "add r2, r3\n"
1378               "strd r0, r1, [r2]\n");
1379 
1380   COMPARE_A32(Strd(r0, r1, MemOperand(r2, minus, r3, PreIndex)),
1381               "strd r0, r1, [r2, -r3]!\n");
1382   COMPARE_T32(Strd(r0, r1, MemOperand(r2, minus, r3, PreIndex)),
1383               "sub r2, r3\n"
1384               "strd r0, r1, [r2]\n");
1385 
1386   // - We do not support register shifted base register operands with LDRD.
1387 
1388   MUST_FAIL_TEST_BOTH(Strd(r0, r1, MemOperand(r2, r3, LSL, 4)),
1389                       "Ill-formed 'strd' instruction.\n");
1390 
1391   // First register is odd - rejected by the Assembler.
1392   MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0)),
1393                      "Unpredictable instruction.\n");
1394   MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0, r0, PreIndex)),
1395                      "Unpredictable instruction.\n");
1396   // First register is odd - rejected by the MacroAssembler.
1397   MUST_FAIL_TEST_A32(Strd(r1, r2, MemOperand(r0, 0xabcd, PreIndex)),
1398                      "Ill-formed 'strd' instruction.\n");
1399 
1400   // First register is lr - rejected by the Assembler.
1401   MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0)),
1402                      "Unpredictable instruction.\n");
1403   MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0, r0, PreIndex)),
1404                      "Unpredictable instruction.\n");
1405   // First register is lr - rejected by the MacroAssembler.
1406   MUST_FAIL_TEST_A32(Strd(lr, pc, MemOperand(r0, 0xabcd, PreIndex)),
1407                      "Ill-formed 'strd' instruction.\n");
1408 
1409   // Non-adjacent registers.
1410   MUST_FAIL_TEST_A32(Strd(r0, r2, MemOperand(r0)),
1411                      "Ill-formed 'strd' instruction.\n");
1412 
1413   CLEANUP();
1414 }
1415 
1416 
TEST(macro_assembler_wide_immediate)1417 TEST(macro_assembler_wide_immediate) {
1418   SETUP();
1419 
1420   COMPARE_BOTH(Adc(r0, r1, 0xbadbeef),
1421                "mov r0, #48879\n"
1422                "movt r0, #2989\n"
1423                "adc r0, r1, r0\n");
1424 
1425   COMPARE_BOTH(Add(r0, r0, 0xbadbeef),
1426                "mov ip, #48879\n"
1427                "movt ip, #2989\n"
1428                "add r0, ip\n");
1429 
1430   COMPARE_BOTH(Mov(r0, 0xbadbeef),
1431                "mov r0, #48879\n"
1432                "movt r0, #2989\n");
1433   COMPARE_A32(Mov(eq, r0, 0xbadbeef),
1434               "moveq r0, #48879\n"
1435               "movteq r0, #2989\n");
1436   COMPARE_T32(Mov(eq, r0, 0xbadbeef),
1437               "bne 0x0000000a\n"
1438               "mov r0, #48879\n"
1439               "movt r0, #2989\n");
1440 
1441   COMPARE_BOTH(Movs(r0, 0xbadbeef),
1442                "mov r0, #48879\n"
1443                "movt r0, #2989\n"
1444                "tst r0, r0\n");
1445   COMPARE_A32(Movs(eq, r0, 0xbadbeef),
1446               "moveq r0, #48879\n"
1447               "movteq r0, #2989\n"
1448               "tsteq r0, r0\n");
1449   COMPARE_T32(Movs(eq, r0, 0xbadbeef),
1450               "bne 0x0000000c\n"
1451               "mov r0, #48879\n"
1452               "movt r0, #2989\n"
1453               "tst r0, r0\n");
1454   COMPARE_A32(Movs(pc, 0x1), "movs pc, #1\n");
1455   MUST_FAIL_TEST_T32(Movs(pc, 0x1), "Unpredictable instruction.\n");
1456   MUST_FAIL_TEST_BOTH(Movs(pc, 0xbadbeed), "Ill-formed 'movs' instruction.\n");
1457 
1458   COMPARE_BOTH(Mov(pc, 0xbadbeef),
1459                "mov ip, #48879\n"
1460                "movt ip, #2989\n"
1461                "bx ip\n");
1462   COMPARE_A32(Mov(eq, pc, 0xbadbeef),
1463               "mov ip, #48879\n"
1464               "movt ip, #2989\n"
1465               "bxeq ip\n");
1466   COMPARE_T32(Mov(eq, pc, 0xbadbeef),
1467               "bne 0x0000000c\n"
1468               "mov ip, #48879\n"
1469               "movt ip, #2989\n"
1470               "bx ip\n");
1471 
1472   CLEANUP();
1473 }
1474 
1475 
TEST(macro_assembler_And)1476 TEST(macro_assembler_And) {
1477   SETUP();
1478 
1479   // Identities.
1480   COMPARE_BOTH(And(r0, r1, 0), "mov r0, #0\n");
1481   COMPARE_BOTH(And(r0, r0, 0xffffffff), "");
1482   CLEANUP();
1483 }
1484 
1485 
TEST(macro_assembler_Bic)1486 TEST(macro_assembler_Bic) {
1487   SETUP();
1488 
1489   // Identities.
1490   COMPARE_BOTH(Bic(r0, r1, 0xffffffff), "mov r0, #0\n");
1491   COMPARE_BOTH(Bic(r0, r0, 0), "");
1492   CLEANUP();
1493 }
1494 
1495 
TEST(macro_assembler_Orr)1496 TEST(macro_assembler_Orr) {
1497   SETUP();
1498 
1499   // Identities.
1500   COMPARE_BOTH(Orr(r0, r1, 0xffffffff), "mvn r0, #0\n");
1501   COMPARE_BOTH(Orr(r0, r0, 0), "");
1502   CLEANUP();
1503 }
1504 
1505 
TEST(macro_assembler_InstructionCondSizeRROp)1506 TEST(macro_assembler_InstructionCondSizeRROp) {
1507   SETUP();
1508 
1509   // Special case for Orr <-> Orn correspondance.
1510 
1511   COMPARE_T32(Orr(r0, r1, 0x00ffffff), "orn r0, r1, #0xff000000\n");
1512   COMPARE_T32(Orrs(r0, r1, 0x00ffffff), "orns r0, r1, #0xff000000\n");
1513 
1514   // Encodable immediates.
1515 
1516   COMPARE_A32(Add(r0, r1, -1), "sub r0, r1, #1\n");
1517   COMPARE_A32(Adds(r0, r1, -1), "subs r0, r1, #1\n");
1518   // 0xffffffff is encodable in a T32 ADD.
1519   COMPARE_T32(Add(r0, r1, -1), "add r0, r1, #4294967295\n");
1520   COMPARE_T32(Adds(r0, r1, -1), "adds r0, r1, #4294967295\n");
1521 
1522   COMPARE_BOTH(Add(r0, r1, -4), "sub r0, r1, #4\n");
1523   COMPARE_BOTH(Adds(r0, r1, -4), "subs r0, r1, #4\n");
1524 
1525   COMPARE_BOTH(Adc(r0, r1, -2), "sbc r0, r1, #1\n");
1526   COMPARE_BOTH(Adcs(r0, r1, -2), "sbcs r0, r1, #1\n");
1527 
1528   COMPARE_A32(Sub(r0, r1, -1), "add r0, r1, #1\n");
1529   COMPARE_A32(Subs(r0, r1, -1), "adds r0, r1, #1\n");
1530   // 0xffffffff is encodable in a T32 SUB.
1531   COMPARE_T32(Sub(r0, r1, -1), "sub r0, r1, #4294967295\n");
1532   COMPARE_T32(Subs(r0, r1, -1), "subs r0, r1, #4294967295\n");
1533 
1534   COMPARE_BOTH(Sub(r0, r1, -4), "add r0, r1, #4\n");
1535   COMPARE_BOTH(Subs(r0, r1, -4), "adds r0, r1, #4\n");
1536 
1537   COMPARE_BOTH(Sbc(r0, r1, -5), "adc r0, r1, #4\n");
1538   COMPARE_BOTH(Sbcs(r0, r1, -5), "adcs r0, r1, #4\n");
1539 
1540   // Non-encodable immediates
1541 
1542   COMPARE_BOTH(Adc(r0, r1, 0xabcd),
1543                "mov r0, #43981\n"
1544                "adc r0, r1, r0\n");
1545 
1546   COMPARE_BOTH(Adc(r0, r1, -0xabcd),
1547                "mov r0, #43980\n"  // This represents #0xabcd - 1.
1548                "sbc r0, r1, r0\n");
1549 
1550   COMPARE_BOTH(Adc(r0, r1, 0x1234abcd),
1551                "mov r0, #43981\n"
1552                "movt r0, #4660\n"
1553                "adc r0, r1, r0\n");
1554 
1555   COMPARE_BOTH(Adc(r0, r1, -0x1234abcd),
1556                "mov r0, #43980\n"  // This represents #0x1234abcd - 1.
1557                "movt r0, #4660\n"
1558                "sbc r0, r1, r0\n");
1559 
1560   // Non-encodable immediates with the same source and destination registers.
1561 
1562   COMPARE_BOTH(Sbc(r0, r0, 0xabcd),
1563                "mov ip, #43981\n"
1564                "sbc r0, ip\n");
1565 
1566   COMPARE_BOTH(Sbc(r0, r0, -0xabcd),
1567                "mov ip, #43980\n"  // This represents #0xabcd - 1.
1568                "adc r0, ip\n");
1569 
1570   COMPARE_BOTH(Sbc(r0, r0, 0x1234abcd),
1571                "mov ip, #43981\n"
1572                "movt ip, #4660\n"
1573                "sbc r0, ip\n");
1574 
1575   COMPARE_BOTH(Sbc(r0, r0, -0x1234abcd),
1576                "mov ip, #43980\n"  // This represents #0x1234abcd - 1.
1577                "movt ip, #4660\n"
1578                "adc r0, ip\n");
1579 
1580 
1581   // Test that we can pass a register shifted register operand in T32.
1582 
1583   COMPARE_T32(Adc(r0, r1, Operand(r2, LSL, r3)),
1584               "lsl r0, r2, r3\n"
1585               "adc r0, r1, r0\n");
1586 
1587   COMPARE_T32(Add(r3, r2, Operand(r2, ASR, r3)),
1588               "asr r3, r2, r3\n"
1589               "add r3, r2, r3\n");
1590 
1591   COMPARE_T32(Ands(r3, r2, Operand(r2, LSR, r2)),
1592               "lsr r3, r2, r2\n"
1593               "ands r3, r2, r3\n");
1594 
1595   COMPARE_T32(Asr(r2, r2, Operand(r2, ROR, r2)),
1596               "ror ip, r2, r2\n"
1597               "asr r2, ip\n");
1598 
1599   COMPARE_T32(Asr(r2, r2, Operand(r2, ROR, r2)),
1600               "ror ip, r2, r2\n"
1601               "asr r2, ip\n");
1602 
1603 
1604   CLEANUP();
1605 }
1606 
1607 
TEST(macro_assembler_InstructionCondRO)1608 TEST(macro_assembler_InstructionCondRO) {
1609   SETUP();
1610 
1611   COMPARE_BOTH(Teq(r0, 0xbad),
1612                "mov ip, #2989\n"
1613                "teq r0, ip\n");
1614   COMPARE_BOTH(Teq(r0, 0xbadbeef),
1615                "mov ip, #48879\n"
1616                "movt ip, #2989\n"
1617                "teq r0, ip\n");
1618   MUST_FAIL_TEST_T32(Teq(r0, Operand(r1, LSL, r2)),
1619                      "Ill-formed 'teq' instruction.\n");
1620 
1621   CLEANUP();
1622 }
1623 
1624 
TEST(macro_assembler_too_large_immediate)1625 TEST(macro_assembler_too_large_immediate) {
1626   SETUP();
1627 
1628   // Attempting to use a 17-bit immediate with movt.
1629   MUST_FAIL_TEST_BOTH(Movt(r0, 0x10000), "`Movt` expects a 16-bit immediate.");
1630 
1631   CLEANUP();
1632 }
1633 
TEST(macro_assembler_Cbz)1634 TEST(macro_assembler_Cbz) {
1635   SETUP();
1636 
1637 #ifdef VIXL_INCLUDE_TARGET_A32
1638   // Cbz/Cbnz are not available in A32 mode.
1639   // Make sure GetArchitectureStatePCOffset() returns the correct value.
1640   __ UseA32();
1641   Label label_64(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(), 64);
1642   MUST_FAIL_TEST_A32(Cbz(r0, &label_64), "Cbz is only available for T32.\n");
1643   MUST_FAIL_TEST_A32(Cbnz(r0, &label_64), "Cbnz is only available for T32.\n");
1644 #endif
1645 
1646 #ifdef VIXL_INCLUDE_TARGET_T32
1647   // Make sure GetArchitectureStatePCOffset() returns the correct value.
1648   __ UseT32();
1649   // Largest encodable offset.
1650   Label label_126(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(),
1651                   126);
1652   COMPARE_T32(Cbz(r0, &label_126), "cbz r0, 0x00000082\n");
1653   COMPARE_T32(Cbnz(r0, &label_126), "cbnz r0, 0x00000082\n");
1654 
1655   // Offset cannot be encoded.
1656   Label label_128(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(),
1657                   128);
1658   COMPARE_T32(Cbz(r0, &label_128),
1659               "cbnz r0, 0x00000004\n"
1660               "b 0x00000084\n");
1661   COMPARE_T32(Cbnz(r0, &label_128),
1662               "cbz r0, 0x00000004\n"
1663               "b 0x00000084\n");
1664 
1665   // Offset that cannot be encoded and needs 32-bit branch instruction.
1666   Label label_8192(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(),
1667                    8192);
1668   COMPARE_T32(Cbz(r0, &label_8192),
1669               "cbnz r0, 0x00000006\n"
1670               "b 0x00002004\n");
1671   COMPARE_T32(Cbnz(r0, &label_8192),
1672               "cbz r0, 0x00000006\n"
1673               "b 0x00002004\n");
1674 
1675   // Negative offset.
1676   Label label_neg(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(), -8);
1677   COMPARE_T32(Cbz(r0, &label_neg),
1678               "cbnz r0, 0x00000004\n"
1679               "b 0xfffffffc\n");
1680   COMPARE_T32(Cbnz(r0, &label_neg),
1681               "cbz r0, 0x00000004\n"
1682               "b 0xfffffffc\n");
1683 
1684   // Large negative offset.
1685   Label label_neg128(__ GetCursorOffset() + __ GetArchitectureStatePCOffset(),
1686                      -128);
1687   COMPARE_T32(Cbz(r0, &label_neg128),
1688               "cbnz r0, 0x00000004\n"
1689               "b 0xffffff84\n");
1690   COMPARE_T32(Cbnz(r0, &label_neg128),
1691               "cbz r0, 0x00000004\n"
1692               "b 0xffffff84\n");
1693 #endif
1694 
1695   CLEANUP();
1696 }
1697 
1698 
1699 #define TEST_VMEMOP(MACRO_OP, STRING_OP, DST_REG)                    \
1700   SETUP();                                                           \
1701                                                                      \
1702   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 1024)),               \
1703               "add ip, r8, #1024\n" STRING_OP #DST_REG ", [ip]\n");  \
1704   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 1371)),               \
1705               "add ip, r8, #1371\n" STRING_OP #DST_REG ", [ip]\n");  \
1706   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 4113)),               \
1707               "add ip, r8, #17\n"                                    \
1708               "add ip, #4096\n" STRING_OP #DST_REG ", [ip]\n");      \
1709   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, 65808)),              \
1710               "add ip, r8, #272\n"                                   \
1711               "add ip, #65536\n" STRING_OP #DST_REG ", [ip]\n");     \
1712                                                                      \
1713   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -1024)),              \
1714               "sub ip, r8, #1024\n" STRING_OP #DST_REG ", [ip]\n");  \
1715   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -1371)),              \
1716               "sub ip, r8, #1371\n" STRING_OP #DST_REG ", [ip]\n");  \
1717   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -4113)),              \
1718               "sub ip, r8, #17\n"                                    \
1719               "sub ip, #4096\n" STRING_OP #DST_REG ", [ip]\n");      \
1720   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r8, -65808)),             \
1721               "sub ip, r8, #272\n"                                   \
1722               "sub ip, #65536\n" STRING_OP #DST_REG ", [ip]\n");     \
1723                                                                      \
1724   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 0, PreIndex)),        \
1725               STRING_OP #DST_REG ", [r9]\n");                        \
1726   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 137, PreIndex)),      \
1727               "add r9, #137\n" STRING_OP #DST_REG ", [r9]\n");       \
1728   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 4110, PreIndex)),     \
1729               "add r9, #14\n"                                        \
1730               "add r9, #4096\n" STRING_OP #DST_REG ", [r9]\n");      \
1731   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, 65623, PreIndex)),    \
1732               "add r9, #87\n"                                        \
1733               "add r9, #65536\n" STRING_OP #DST_REG ", [r9]\n");     \
1734                                                                      \
1735   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -137, PreIndex)),     \
1736               "sub r9, #137\n" STRING_OP #DST_REG ", [r9]\n");       \
1737   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -4110, PreIndex)),    \
1738               "sub r9, #14\n"                                        \
1739               "sub r9, #4096\n" STRING_OP #DST_REG ", [r9]\n");      \
1740   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r9, -65623, PreIndex)),   \
1741               "sub r9, #87\n"                                        \
1742               "sub r9, #65536\n" STRING_OP #DST_REG ", [r9]\n");     \
1743                                                                      \
1744   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 0, PostIndex)),      \
1745               STRING_OP #DST_REG ", [r10]\n");                       \
1746   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 137, PostIndex)),    \
1747               STRING_OP #DST_REG                                     \
1748               ", [r10]\n"                                            \
1749               "add r10, #137\n");                                    \
1750   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 4110, PostIndex)),   \
1751               STRING_OP #DST_REG                                     \
1752               ", [r10]\n"                                            \
1753               "add r10, #14\n"                                       \
1754               "add r10, #4096\n");                                   \
1755   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, 65623, PostIndex)),  \
1756               STRING_OP #DST_REG                                     \
1757               ", [r10]\n"                                            \
1758               "add r10, #87\n"                                       \
1759               "add r10, #65536\n");                                  \
1760                                                                      \
1761   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -137, PostIndex)),   \
1762               STRING_OP #DST_REG                                     \
1763               ", [r10]\n"                                            \
1764               "sub r10, #137\n");                                    \
1765   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -4110, PostIndex)),  \
1766               STRING_OP #DST_REG                                     \
1767               ", [r10]\n"                                            \
1768               "sub r10, #14\n"                                       \
1769               "sub r10, #4096\n");                                   \
1770   COMPARE_T32(MACRO_OP(DST_REG, MemOperand(r10, -65623, PostIndex)), \
1771               STRING_OP #DST_REG                                     \
1772               ", [r10]\n"                                            \
1773               "sub r10, #87\n"                                       \
1774               "sub r10, #65536\n");                                  \
1775   CLEANUP();
1776 
TEST(macro_assembler_T32_Vldr_d)1777 TEST(macro_assembler_T32_Vldr_d) { TEST_VMEMOP(Vldr, "vldr ", d0); }
1778 
TEST(macro_assembler_T32_Vstr_d)1779 TEST(macro_assembler_T32_Vstr_d) { TEST_VMEMOP(Vstr, "vstr ", d1); }
1780 
TEST(macro_assembler_T32_Vldr_s)1781 TEST(macro_assembler_T32_Vldr_s) { TEST_VMEMOP(Vldr, "vldr ", s2); }
1782 
TEST(macro_assembler_T32_Vstr_s)1783 TEST(macro_assembler_T32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); }
1784 
1785 #undef TEST_VMEMOP
1786 
1787 #define TEST_VMEMOP(MACRO_OP, STRING_OP, DST_REG)                    \
1788   SETUP();                                                           \
1789                                                                      \
1790   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 137)),                \
1791               "add ip, r8, #137\n" STRING_OP #DST_REG ", [ip]\n");   \
1792   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 274)),                \
1793               "add ip, r8, #18\n"                                    \
1794               "add ip, #256\n" STRING_OP #DST_REG ", [ip]\n");       \
1795   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, 65623)),              \
1796               "add ip, r8, #87\n"                                    \
1797               "add ip, #65536\n" STRING_OP #DST_REG ", [ip]\n");     \
1798                                                                      \
1799   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -137)),               \
1800               "sub ip, r8, #137\n" STRING_OP #DST_REG ", [ip]\n");   \
1801   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -274)),               \
1802               "sub ip, r8, #18\n"                                    \
1803               "sub ip, #256\n" STRING_OP #DST_REG ", [ip]\n");       \
1804   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r8, -65623)),             \
1805               "sub ip, r8, #87\n"                                    \
1806               "sub ip, #65536\n" STRING_OP #DST_REG ", [ip]\n");     \
1807                                                                      \
1808   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 0, PreIndex)),        \
1809               STRING_OP #DST_REG ", [r9]\n");                        \
1810   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 137, PreIndex)),      \
1811               "add r9, #137\n" STRING_OP #DST_REG ", [r9]\n");       \
1812   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 274, PreIndex)),      \
1813               "add r9, #18\n"                                        \
1814               "add r9, #256\n" STRING_OP #DST_REG ", [r9]\n");       \
1815   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, 65623, PreIndex)),    \
1816               "add r9, #87\n"                                        \
1817               "add r9, #65536\n" STRING_OP #DST_REG ", [r9]\n");     \
1818                                                                      \
1819   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -137, PreIndex)),     \
1820               "sub r9, #137\n" STRING_OP #DST_REG ", [r9]\n");       \
1821   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -274, PreIndex)),     \
1822               "sub r9, #18\n"                                        \
1823               "sub r9, #256\n" STRING_OP #DST_REG ", [r9]\n");       \
1824   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r9, -65623, PreIndex)),   \
1825               "sub r9, #87\n"                                        \
1826               "sub r9, #65536\n" STRING_OP #DST_REG ", [r9]\n");     \
1827                                                                      \
1828   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 0, PostIndex)),      \
1829               STRING_OP #DST_REG ", [r10]\n");                       \
1830   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 137, PostIndex)),    \
1831               STRING_OP #DST_REG                                     \
1832               ", [r10]\n"                                            \
1833               "add r10, #137\n");                                    \
1834   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 274, PostIndex)),    \
1835               STRING_OP #DST_REG                                     \
1836               ", [r10]\n"                                            \
1837               "add r10, #18\n"                                       \
1838               "add r10, #256\n");                                    \
1839   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, 65623, PostIndex)),  \
1840               STRING_OP #DST_REG                                     \
1841               ", [r10]\n"                                            \
1842               "add r10, #87\n"                                       \
1843               "add r10, #65536\n");                                  \
1844                                                                      \
1845   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -137, PostIndex)),   \
1846               STRING_OP #DST_REG                                     \
1847               ", [r10]\n"                                            \
1848               "sub r10, #137\n");                                    \
1849   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -274, PostIndex)),   \
1850               STRING_OP #DST_REG                                     \
1851               ", [r10]\n"                                            \
1852               "sub r10, #18\n"                                       \
1853               "sub r10, #256\n");                                    \
1854   COMPARE_A32(MACRO_OP(DST_REG, MemOperand(r10, -65623, PostIndex)), \
1855               STRING_OP #DST_REG                                     \
1856               ", [r10]\n"                                            \
1857               "sub r10, #87\n"                                       \
1858               "sub r10, #65536\n");                                  \
1859   CLEANUP();
1860 
1861 
TEST(macro_assembler_A32_Vldr_d)1862 TEST(macro_assembler_A32_Vldr_d) { TEST_VMEMOP(Vldr, "vldr ", d0); }
1863 
TEST(macro_assembler_A32_Vstr_d)1864 TEST(macro_assembler_A32_Vstr_d) { TEST_VMEMOP(Vstr, "vstr ", d1); }
1865 
TEST(macro_assembler_A32_Vldr_s)1866 TEST(macro_assembler_A32_Vldr_s) { TEST_VMEMOP(Vldr, "vldr ", s2); }
1867 
TEST(macro_assembler_A32_Vstr_s)1868 TEST(macro_assembler_A32_Vstr_s) { TEST_VMEMOP(Vstr, "vstr ", s3); }
1869 
1870 #undef TEST_VMEMOP
1871 
TEST(macro_assembler_Vldr_Vstr_negative)1872 TEST(macro_assembler_Vldr_Vstr_negative) {
1873   SETUP();
1874 
1875   MUST_FAIL_TEST_BOTH(Vldr(s0, MemOperand(pc, 1, PreIndex)),
1876                       "The MacroAssembler does not convert vldr or vstr"
1877                       " with a PC base register.\n");
1878 
1879   MUST_FAIL_TEST_BOTH(Vldr(s0, MemOperand(pc, r0, PreIndex)),
1880                       "Ill-formed 'vldr' instruction.\n");
1881 
1882   MUST_FAIL_TEST_BOTH(Vstr(s0, MemOperand(pc, 1, PreIndex)),
1883                       "The MacroAssembler does not convert vldr or vstr"
1884                       " with a PC base register.\n");
1885 
1886   MUST_FAIL_TEST_BOTH(Vstr(s0, MemOperand(pc, r0, PreIndex)),
1887                       "Ill-formed 'vstr' instruction.\n");
1888 
1889   MUST_FAIL_TEST_BOTH(Vldr(d0, MemOperand(pc, 1, PreIndex)),
1890                       "The MacroAssembler does not convert vldr or vstr"
1891                       " with a PC base register.\n");
1892 
1893   MUST_FAIL_TEST_BOTH(Vldr(d0, MemOperand(pc, r0, PreIndex)),
1894                       "Ill-formed 'vldr' instruction.\n");
1895 
1896   MUST_FAIL_TEST_BOTH(Vstr(d0, MemOperand(pc, 1, PreIndex)),
1897                       "The MacroAssembler does not convert vldr or vstr"
1898                       " with a PC base register.\n");
1899 
1900   MUST_FAIL_TEST_BOTH(Vstr(d0, MemOperand(pc, r0, PreIndex)),
1901                       "Ill-formed 'vstr' instruction.\n");
1902   CLEANUP();
1903 }
1904 
1905 #define TEST_SHIFT_T32(Inst, name, offset)          \
1906   COMPARE_T32(Inst(r0, Operand(r1, LSL, r2)),       \
1907               "lsl ip, r1, r2\n" name " r0, ip\n"); \
1908   COMPARE_T32(Inst(r0, Operand(r1, LSR, r2)),       \
1909               "lsr ip, r1, r2\n" name " r0, ip\n"); \
1910   COMPARE_T32(Inst(r0, Operand(r1, ASR, r2)),       \
1911               "asr ip, r1, r2\n" name " r0, ip\n"); \
1912   COMPARE_T32(Inst(r0, Operand(r1, ROR, r2)),       \
1913               "ror ip, r1, r2\n" name " r0, ip\n"); \
1914   COMPARE_T32(Inst(eq, r0, Operand(r1, LSL, r2)),   \
1915               "bne " #offset                        \
1916               "\n"                                  \
1917               "lsl ip, r1, r2\n" name " r0, ip\n"); \
1918   COMPARE_T32(Inst(le, r0, Operand(r1, LSL, r2)),   \
1919               "bgt " #offset                        \
1920               "\n"                                  \
1921               "lsl ip, r1, r2\n" name " r0, ip\n");
1922 
1923 #define TEST_MOV_SHIFT_T32(Inst, s, offset)                             \
1924   COMPARE_T32(Inst(r0, Operand(r1, LSL, r2)), "lsl" s " r0, r1, r2\n"); \
1925   COMPARE_T32(Inst(r0, Operand(r1, LSR, r2)), "lsr" s " r0, r1, r2\n"); \
1926   COMPARE_T32(Inst(r0, Operand(r1, ASR, r2)), "asr" s " r0, r1, r2\n"); \
1927   COMPARE_T32(Inst(r0, Operand(r1, ROR, r2)), "ror" s " r0, r1, r2\n"); \
1928   COMPARE_T32(Inst(eq, r0, Operand(r1, LSL, r2)),                       \
1929               "bne " #offset                                            \
1930               "\n"                                                      \
1931               "lsl" s " r0, r1, r2\n");                                 \
1932   COMPARE_T32(Inst(le, r0, Operand(r1, LSL, r2)),                       \
1933               "bgt " #offset                                            \
1934               "\n"                                                      \
1935               "lsl" s " r0, r1, r2\n");
1936 
1937 #define TEST_WIDE_IMMEDIATE(Inst, name, offset)         \
1938   COMPARE_BOTH(Inst(r0, 0xbadbeef),                     \
1939                "mov ip, #48879\n"                       \
1940                "movt ip, #2989\n" name " r0, ip\n");    \
1941   COMPARE_A32(Inst(eq, r0, 0xbadbeef),                  \
1942               "moveq ip, #48879\n"                      \
1943               "movteq ip, #2989\n" name "eq r0, ip\n"); \
1944   COMPARE_T32(Inst(eq, r0, 0xbadbeef),                  \
1945               "bne " #offset                            \
1946               "\n"                                      \
1947               "mov ip, #48879\n"                        \
1948               "movt ip, #2989\n" name " r0, ip\n");
1949 
1950 #define TEST_WIDE_IMMEDIATE_PC(Inst, name, offset)            \
1951   COMPARE_A32(Inst(pc, 0xbadbeef),                            \
1952               "mov ip, #48879\n"                              \
1953               "movt ip, #2989\n" name " pc, ip\n");           \
1954   COMPARE_A32(Inst(eq, pc, 0xbadbeef),                        \
1955               "moveq ip, #48879\n"                            \
1956               "movteq ip, #2989\n" name "eq pc, ip\n");       \
1957   MUST_FAIL_TEST_T32(Inst(pc, 0xbadbeef),                     \
1958                      "Ill-formed '" name "' instruction.\n"); \
1959   MUST_FAIL_TEST_T32(Inst(eq, pc, 0xbadbeef),                 \
1960                      "Ill-formed '" name "' instruction.\n");
1961 
TEST(macro_assembler_InstructionCondSizeROp)1962 TEST(macro_assembler_InstructionCondSizeROp) {
1963   SETUP();
1964 
1965   // T32 register shifted register.
1966   TEST_SHIFT_T32(Cmn, "cmn", 0x0000000a)
1967   TEST_SHIFT_T32(Cmp, "cmp", 0x00000008)
1968   TEST_SHIFT_T32(Mvn, "mvn", 0x0000000a)
1969   TEST_SHIFT_T32(Mvns, "mvns", 0x0000000a)
1970   TEST_SHIFT_T32(Sxtb, "sxtb", 0x0000000a)
1971   TEST_SHIFT_T32(Sxth, "sxth", 0x0000000a)
1972   TEST_SHIFT_T32(Tst, "tst", 0x0000000a)
1973   TEST_SHIFT_T32(Uxtb, "uxtb", 0x0000000a)
1974   TEST_SHIFT_T32(Uxth, "uxth", 0x0000000a)
1975 
1976   TEST_MOV_SHIFT_T32(Mov, "", 0x00000006)
1977   TEST_MOV_SHIFT_T32(Movs, "s", 0x00000006)
1978 
1979   MUST_FAIL_TEST_BOTH(Movs(pc, r0), "Unpredictable instruction.\n");
1980   MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, LSL, 0x4)),
1981                       "Unpredictable instruction.\n");
1982   MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, ASR, r2)),
1983                       "Unpredictable instruction.\n");
1984 
1985   // Wide immediates (Mov and Movs are tested in
1986   // "macro_assembler_wide_immediate").
1987   TEST_WIDE_IMMEDIATE(Cmp, "cmp", 0x0000000c);
1988   TEST_WIDE_IMMEDIATE(Cmn, "cmn", 0x0000000e);
1989   TEST_WIDE_IMMEDIATE(Tst, "tst", 0x0000000e);
1990   TEST_WIDE_IMMEDIATE_PC(Cmp, "cmp", 0x0000000c);
1991   TEST_WIDE_IMMEDIATE_PC(Cmn, "cmn", 0x0000000e);
1992   TEST_WIDE_IMMEDIATE_PC(Tst, "tst", 0x0000000e);
1993 
1994   // For Mvn and Mvns, we don't allow PC as a destination.
1995   TEST_WIDE_IMMEDIATE(Mvn, "mvn", 0x0000000e);
1996   TEST_WIDE_IMMEDIATE(Mvns, "mvns", 0x0000000e);
1997   MUST_FAIL_TEST_BOTH(Mvn(pc, 0xbadbeef), "Ill-formed 'mvn' instruction.\n");
1998   MUST_FAIL_TEST_BOTH(Mvn(eq, pc, 0xbadbeef),
1999                       "Ill-formed 'mvn' instruction.\n");
2000   MUST_FAIL_TEST_BOTH(Mvns(pc, 0xbadbeef), "Ill-formed 'mvns' instruction.\n");
2001   MUST_FAIL_TEST_BOTH(Mvns(eq, pc, 0xbadbeef),
2002                       "Ill-formed 'mvns' instruction.\n");
2003 
2004   MUST_FAIL_TEST_BOTH(Sxtb(r0, 0x1), "Ill-formed 'sxtb' instruction.\n");
2005   MUST_FAIL_TEST_BOTH(Sxth(r0, 0x1), "Ill-formed 'sxth' instruction.\n");
2006   MUST_FAIL_TEST_BOTH(Uxtb(r0, 0x1), "Ill-formed 'uxtb' instruction.\n");
2007   MUST_FAIL_TEST_BOTH(Uxth(r0, 0x1), "Ill-formed 'uxth' instruction.\n");
2008 
2009   CLEANUP();
2010 }
2011 
2012 #undef TEST_SHIFT_T32
2013 #undef TEST_MOV_SHIFT_T32
2014 #undef TEST_WIDE_IMMEDIATE
2015 #undef TEST_WIDE_IMMEDIATE_PC
2016 
TEST(macro_assembler_Msr)2017 TEST(macro_assembler_Msr) {
2018   SETUP();
2019 
2020   // Msr with immediate for T32.
2021   COMPARE_T32(Msr(APSR_nzcvq, 0x0),
2022               "mov ip, #0\n"
2023               "msr APSR_nzcvq, ip\n");
2024 
2025   // Wide immediate.
2026   COMPARE_BOTH(Msr(APSR_nzcvq, 0xbadbeef),
2027                "mov ip, #48879\n"
2028                "movt ip, #2989\n"
2029                "msr APSR_nzcvq, ip\n");
2030 
2031   // Other types of operands are not handled.
2032   MUST_FAIL_TEST_BOTH(Msr(APSR_nzcvq, Operand(r0, LSR, r1)),
2033                       "Ill-formed 'msr' instruction.\n");
2034   CLEANUP();
2035 }
2036 
2037 
TEST(macro_assembler_Vmov_imm)2038 TEST(macro_assembler_Vmov_imm) {
2039   SETUP();
2040 
2041   COMPARE_BOTH(Vmov(s0, 0.0f),
2042                "mov ip, #0\n"
2043                "vmov s0, ip\n");
2044   COMPARE_BOTH(Vmov(s1, 1.0f), "vmov.f32 s1, #1\n");
2045   COMPARE_BOTH(Vmov(s2, RawbitsToFloat(0x0000db6c)),
2046                "mov ip, #56172\n"
2047                "vmov s2, ip\n");
2048   COMPARE_BOTH(Vmov(s3, RawbitsToFloat(0x327b23c6)),
2049                "mov ip, #9158\n"
2050                "movt ip, #12923\n"
2051                "vmov s3, ip\n");
2052   COMPARE_BOTH(Vmov(s4, RawbitsToFloat(0xffcc7fff)),
2053                "mvn ip, #3375104\n"
2054                "vmov s4, ip\n");
2055   COMPARE_BOTH(Vmov(s5, RawbitsToFloat(0xb72df575)),
2056                "mov ip, #62837\n"
2057                "movt ip, #46893\n"
2058                "vmov s5, ip\n");
2059 
2060   COMPARE_BOTH(Vmov(d6, 0.0), "vmov.i64 d6, #0x0000000000000000\n");
2061   COMPARE_BOTH(Vmov(d7, 1.0), "vmov.f64 d7, #1\n");
2062   COMPARE_BOTH(Vmov(d8, RawbitsToDouble(0x000000000000af8e)),
2063                "mov ip, #44942\n"
2064                "vdup.32 d8, ip\n"
2065                "mov ip, #0\n"
2066                "vmov.32 d8[1], ip\n");
2067   COMPARE_BOTH(Vmov(d9, RawbitsToDouble(0x000070210000af8e)),
2068                "mov ip, #44942\n"
2069                "vdup.32 d9, ip\n"
2070                "mov ip, #28705\n"
2071                "vmov.32 d9[1], ip\n");
2072   COMPARE_BOTH(Vmov(d10, RawbitsToDouble(0x7021000000000000)),
2073                "mov ip, #0\n"
2074                "vdup.32 d10, ip\n"
2075                "mov ip, #0\n"
2076                "movt ip, #28705\n"
2077                "vmov.32 d10[1], ip\n");
2078   COMPARE_BOTH(Vmov(d11, RawbitsToDouble(0x7021da4b0000af8e)),
2079                "mov ip, #44942\n"
2080                "vdup.32 d11, ip\n"
2081                "mov ip, #55883\n"
2082                "movt ip, #28705\n"
2083                "vmov.32 d11[1], ip\n");
2084   COMPARE_BOTH(Vmov(d12, RawbitsToDouble(0x0cff553204ec4a3f)),
2085                "mov ip, #19007\n"
2086                "movt ip, #1260\n"
2087                "vdup.32 d12, ip\n"
2088                "mov ip, #21810\n"
2089                "movt ip, #3327\n"
2090                "vmov.32 d12[1], ip\n");
2091   COMPARE_BOTH(Vmov(d13, RawbitsToDouble(0xa2037ad20000f592)),
2092                "mov ip, #62866\n"
2093                "vdup.32 d13, ip\n"
2094                "mov ip, #31442\n"
2095                "movt ip, #41475\n"
2096                "vmov.32 d13[1], ip\n");
2097   COMPARE_BOTH(Vmov(d14, RawbitsToDouble(0xe62556c325a59470)),
2098                "mov ip, #38000\n"
2099                "movt ip, #9637\n"
2100                "vdup.32 d14, ip\n"
2101                "mov ip, #22211\n"
2102                "movt ip, #58917\n"
2103                "vmov.32 d14[1], ip\n");
2104   CLEANUP();
2105 }
2106 
TEST(macro_assembler_PushRegisterList)2107 TEST(macro_assembler_PushRegisterList) {
2108   SETUP();
2109 
2110   // Allow the test to use all registers.
2111   UseScratchRegisterScope temps(&masm);
2112   temps.ExcludeAll();
2113 
2114   COMPARE_BOTH(Push(RegisterList(0x1111)), "push {r0,r4,r8,ip}\n");
2115 
2116   COMPARE_BOTH(Push(RegisterList(0x1fff)),
2117                "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2118 
2119   COMPARE_BOTH(Push(RegisterList(0x5fff)),
2120                "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip,lr}\n");
2121 
2122   COMPARE_A32(Push(ne, RegisterList(0x1fff)),
2123               "pushne {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2124 
2125   COMPARE_T32(Push(ne, RegisterList(0x1fff)),
2126               "beq 0x00000006\n"
2127               "push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2128 
2129   COMPARE_A32(Push(RegisterList(sp)), "stmdb sp!, {sp}\n");
2130 
2131   // TODO: Clarify behaviour of MacroAssembler vs Assembler with respect to
2132   //       deprecated and unpredictable instructions. The tests reflect the
2133   //       current behaviour and will need to be updated.
2134 
2135   // Deprecated, but accepted:
2136   SHOULD_FAIL_TEST_A32(Push(RegisterList(pc)));
2137   // Whereas we don't accept the single-register version:
2138   MUST_FAIL_TEST_A32(Push(pc), "Unpredictable instruction.\n");
2139 
2140   // For T32, pushing the PC is allowed:
2141   COMPARE_T32(Push(pc), "push {pc}\n");
2142 
2143   // Accepted, but stores UNKNOWN value for the SP:
2144   SHOULD_FAIL_TEST_A32(Push(RegisterList(r0, sp)));
2145 
2146   // The following use the T1 and A1 encodings for T32 and A32 respectively, and
2147   // hence have different preferred disassembly.
2148   COMPARE_T32(Push(RegisterList(r0)), "push {r0}\n");
2149   COMPARE_A32(Push(RegisterList(r0)), "stmdb sp!, {r0}\n");
2150   COMPARE_T32(Push(RegisterList(r7)), "push {r7}\n");
2151   COMPARE_A32(Push(RegisterList(r7)), "stmdb sp!, {r7}\n");
2152   COMPARE_T32(Push(RegisterList(lr)), "push {lr}\n");
2153   COMPARE_A32(Push(RegisterList(lr)), "stmdb sp!, {lr}\n");
2154 
2155   // T2 and A1 encodings, with the same preferred disassembly:
2156   COMPARE_BOTH(Push(RegisterList(r8)), "stmdb sp!, {r8}\n");
2157 
2158   // Cannot push the sp and pc in T32 when using a register list.
2159   MUST_FAIL_TEST_T32(Push(RegisterList(sp)),
2160                      "Ill-formed 'push' instruction.\n");
2161   MUST_FAIL_TEST_T32(Push(RegisterList(pc)),
2162                      "Ill-formed 'push' instruction.\n");
2163 
2164   CLEANUP();
2165 }
2166 
TEST(macro_assembler_PopRegisterList)2167 TEST(macro_assembler_PopRegisterList) {
2168   SETUP();
2169 
2170   // Allow the test to use all registers.
2171   UseScratchRegisterScope temps(&masm);
2172   temps.ExcludeAll();
2173 
2174   COMPARE_BOTH(Pop(RegisterList(0x1111)), "pop {r0,r4,r8,ip}\n");
2175 
2176   COMPARE_BOTH(Pop(RegisterList(0x1fff)),
2177                "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2178 
2179   COMPARE_BOTH(Pop(RegisterList(0x5fff)),
2180                "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip,lr}\n");
2181 
2182   COMPARE_A32(Pop(ne, RegisterList(0x1fff)),
2183               "popne {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2184 
2185   COMPARE_T32(Pop(ne, RegisterList(0x1fff)),
2186               "beq 0x00000006\n"
2187               "pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,ip}\n");
2188 
2189   // TODO: Accepted, but value of SP after the instruction is UNKNOWN:
2190   SHOULD_FAIL_TEST_A32(Pop(RegisterList(sp)));
2191 
2192   // Cannot pop the sp in T32 when using a register list.
2193   MUST_FAIL_TEST_T32(Pop(RegisterList(sp)), "Ill-formed 'pop' instruction.\n");
2194 
2195   // The following use the T1 and A1 encodings for T32 and A32 respectively, and
2196   // hence have different preferred disassembly.
2197   COMPARE_T32(Pop(RegisterList(pc)), "pop {pc}\n");
2198   COMPARE_A32(Pop(RegisterList(pc)), "ldm sp!, {pc}\n");
2199   COMPARE_T32(Pop(RegisterList(r0)), "pop {r0}\n");
2200   COMPARE_A32(Pop(RegisterList(r0)), "ldm sp!, {r0}\n");
2201   COMPARE_T32(Pop(RegisterList(r7)), "pop {r7}\n");
2202   COMPARE_A32(Pop(RegisterList(r7)), "ldm sp!, {r7}\n");
2203 
2204   // T2 and A1 encodings, with the same preferred disassembly:
2205   COMPARE_BOTH(Pop(RegisterList(r8)), "ldm sp!, {r8}\n");
2206   COMPARE_BOTH(Pop(RegisterList(lr)), "ldm sp!, {lr}\n");
2207 
2208   // TODO: Pushing both the lr and pc should not be allowed by the
2209   //       MacroAssembler (deprecated for A32, for T32 they shouldn't both
2210   //       be in the list).
2211   SHOULD_FAIL_TEST_BOTH(Pop(RegisterList(lr, pc)));
2212 
2213   CLEANUP();
2214 }
2215 
2216 
TEST(macro_assembler_unpredictable)2217 TEST(macro_assembler_unpredictable) {
2218   SETUP();
2219 
2220   // ADC, ADCS (immediate).
2221   COMPARE_A32(Adc(pc, r0, 1), "adc pc, r0, #1\n");
2222   COMPARE_A32(Adc(r0, pc, 1), "adc r0, pc, #1\n");
2223   MUST_FAIL_TEST_T32(Adc(pc, r0, 1), "Unpredictable instruction.\n");
2224   MUST_FAIL_TEST_T32(Adc(r0, pc, 1), "Unpredictable instruction.\n");
2225   COMPARE_A32(Adcs(pc, r0, 1), "adcs pc, r0, #1\n");
2226   COMPARE_A32(Adcs(r0, pc, 1), "adcs r0, pc, #1\n");
2227   MUST_FAIL_TEST_T32(Adcs(pc, r0, 1), "Unpredictable instruction.\n");
2228   MUST_FAIL_TEST_T32(Adcs(r0, pc, 1), "Unpredictable instruction.\n");
2229 
2230   // ADC, ADCS (register).
2231   COMPARE_A32(Adc(pc, r0, r1), "adc pc, r0, r1\n");
2232   COMPARE_A32(Adc(r0, pc, r1), "adc r0, pc, r1\n");
2233   COMPARE_A32(Adc(r0, r1, pc), "adc r0, r1, pc\n");
2234   MUST_FAIL_TEST_T32(Adc(pc, r0, r1), "Unpredictable instruction.\n");
2235   MUST_FAIL_TEST_T32(Adc(r0, pc, r1), "Unpredictable instruction.\n");
2236   MUST_FAIL_TEST_T32(Adc(r0, r1, pc), "Unpredictable instruction.\n");
2237   COMPARE_A32(Adcs(pc, r0, r1), "adcs pc, r0, r1\n");
2238   COMPARE_A32(Adcs(r0, pc, r1), "adcs r0, pc, r1\n");
2239   COMPARE_A32(Adcs(r0, r1, pc), "adcs r0, r1, pc\n");
2240   MUST_FAIL_TEST_T32(Adcs(pc, r0, r1), "Unpredictable instruction.\n");
2241   MUST_FAIL_TEST_T32(Adcs(r0, pc, r1), "Unpredictable instruction.\n");
2242   MUST_FAIL_TEST_T32(Adcs(r0, r1, pc), "Unpredictable instruction.\n");
2243 
2244   // ADC, ADCS (register-shifted register).
2245   MUST_FAIL_TEST_A32(Adc(pc, r0, Operand(r1, LSL, r2)),
2246                      "Unpredictable instruction.\n");
2247   MUST_FAIL_TEST_A32(Adc(r0, pc, Operand(r1, LSL, r2)),
2248                      "Unpredictable instruction.\n");
2249   MUST_FAIL_TEST_A32(Adc(r0, r1, Operand(pc, LSL, r2)),
2250                      "Unpredictable instruction.\n");
2251   MUST_FAIL_TEST_A32(Adc(r0, r1, Operand(r2, LSL, pc)),
2252                      "Unpredictable instruction.\n");
2253   MUST_FAIL_TEST_A32(Adcs(pc, r0, Operand(r1, LSL, r2)),
2254                      "Unpredictable instruction.\n");
2255   MUST_FAIL_TEST_A32(Adcs(r0, pc, Operand(r1, LSL, r2)),
2256                      "Unpredictable instruction.\n");
2257   MUST_FAIL_TEST_A32(Adcs(r0, r1, Operand(pc, LSL, r2)),
2258                      "Unpredictable instruction.\n");
2259   MUST_FAIL_TEST_A32(Adcs(r0, r1, Operand(r2, LSL, pc)),
2260                      "Unpredictable instruction.\n");
2261 
2262   // ADD (immediate, to PC).
2263   COMPARE_A32(Add(r0, pc, 1), "adr r0, 0x00000009\n");
2264   COMPARE_T32(Add(r0, pc, 1), "adr r0, 0x00000005\n");
2265   COMPARE_A32(Add(pc, pc, 1), "adr pc, 0x00000009\n");
2266   MUST_FAIL_TEST_T32(Add(pc, pc, 1), "Unpredictable instruction.\n");
2267 
2268   // ADD, ADDS (immediate).
2269   COMPARE_A32(Add(pc, r0, 1), "add pc, r0, #1\n");
2270   MUST_FAIL_TEST_T32(Add(pc, r0, 1), "Unpredictable instruction.\n");
2271   MUST_FAIL_TEST_T32(Add(pc, r0, 0x123), "Unpredictable instruction.\n");
2272   COMPARE_A32(Adds(pc, r0, 1), "adds pc, r0, #1\n");
2273   COMPARE_A32(Adds(r0, pc, 1), "adds r0, pc, #1\n");
2274   // TODO: Try to make these error messages more consistent.
2275   MUST_FAIL_TEST_T32(Adds(r0, pc, 1), "Unpredictable instruction.\n");
2276   MUST_FAIL_TEST_T32(Adds(r0, pc, 0x123), "Ill-formed 'adds' instruction.\n");
2277 
2278   // ADD, ADDS (register).
2279   COMPARE_A32(Add(pc, r0, r1), "add pc, r0, r1\n");
2280   COMPARE_A32(Add(r0, pc, r1), "add r0, pc, r1\n");
2281   COMPARE_A32(Add(r0, r1, pc), "add r0, r1, pc\n");
2282   COMPARE_T32(Add(r0, r0, pc), "add r0, pc\n");
2283   COMPARE_T32(Add(pc, pc, r0), "add pc, r0\n");
2284   MUST_FAIL_TEST_T32(Add(pc, pc, pc), "Unpredictable instruction.\n");
2285   MUST_FAIL_TEST_T32(Add(pc, r0, r1), "Unpredictable instruction.\n");
2286   MUST_FAIL_TEST_T32(Add(r0, pc, r1), "Unpredictable instruction.\n");
2287   MUST_FAIL_TEST_T32(Add(r0, r1, pc), "Unpredictable instruction.\n");
2288   COMPARE_A32(Adds(pc, r0, r1), "adds pc, r0, r1\n");
2289   COMPARE_A32(Adds(r0, pc, r1), "adds r0, pc, r1\n");
2290   COMPARE_A32(Adds(r0, r1, pc), "adds r0, r1, pc\n");
2291   MUST_FAIL_TEST_T32(Adds(r0, pc, r1), "Unpredictable instruction.\n");
2292   MUST_FAIL_TEST_T32(Adds(r0, r1, pc), "Unpredictable instruction.\n");
2293 
2294   // ADD, ADDS (register-shifted register)
2295   MUST_FAIL_TEST_A32(Add(pc, r0, Operand(r1, LSL, r2)),
2296                      "Unpredictable instruction.\n");
2297   MUST_FAIL_TEST_A32(Add(r0, pc, Operand(r1, LSL, r2)),
2298                      "Unpredictable instruction.\n");
2299   MUST_FAIL_TEST_A32(Add(r0, r1, Operand(pc, LSL, r2)),
2300                      "Unpredictable instruction.\n");
2301   MUST_FAIL_TEST_A32(Add(r0, r1, Operand(r2, LSL, pc)),
2302                      "Unpredictable instruction.\n");
2303   COMPARE_A32(Add(pc, sp, 1), "add pc, sp, #1\n");
2304   MUST_FAIL_TEST_T32(Add(pc, sp, 1), "Unpredictable instruction.\n");
2305   MUST_FAIL_TEST_A32(Adds(pc, r0, Operand(r1, LSL, r2)),
2306                      "Unpredictable instruction.\n");
2307   MUST_FAIL_TEST_A32(Adds(r0, pc, Operand(r1, LSL, r2)),
2308                      "Unpredictable instruction.\n");
2309   MUST_FAIL_TEST_A32(Adds(r0, r1, Operand(pc, LSL, r2)),
2310                      "Unpredictable instruction.\n");
2311   MUST_FAIL_TEST_A32(Adds(r0, r1, Operand(r2, LSL, pc)),
2312                      "Unpredictable instruction.\n");
2313 
2314   // ADD, ADDS (SP plus immediate).
2315   COMPARE_A32(Add(pc, sp, 1), "add pc, sp, #1\n");
2316   MUST_FAIL_TEST_T32(Add(pc, sp, 1), "Unpredictable instruction.\n");
2317   COMPARE_A32(Adds(pc, sp, 1), "adds pc, sp, #1\n");
2318   MUST_FAIL_TEST_T32(Adds(pc, sp, 1), "Ill-formed 'adds' instruction.\n");
2319 
2320   // ADD, ADDS (SP plus register).
2321   COMPARE_A32(Add(pc, sp, r0), "add pc, sp, r0\n");
2322   MUST_FAIL_TEST_T32(Add(pc, sp, r0), "Unpredictable instruction.\n");
2323   COMPARE_A32(Add(r0, sp, pc), "add r0, sp, pc\n");
2324   MUST_FAIL_TEST_T32(Add(r0, sp, pc), "Unpredictable instruction.\n");
2325   COMPARE_BOTH(Add(pc, sp, pc), "add pc, sp, pc\n");
2326   COMPARE_BOTH(Add(sp, sp, pc), "add sp, pc\n");
2327   COMPARE_A32(Adds(pc, sp, r0), "adds pc, sp, r0\n");
2328   MUST_FAIL_TEST_T32(Adds(pc, sp, r0), "Ill-formed 'adds' instruction.\n");
2329   COMPARE_A32(Adds(r0, sp, pc), "adds r0, sp, pc\n");
2330   MUST_FAIL_TEST_T32(Adds(r0, sp, pc), "Unpredictable instruction.\n");
2331   COMPARE_A32(Adds(pc, sp, pc), "adds pc, sp, pc\n");
2332   MUST_FAIL_TEST_T32(Adds(pc, sp, pc), "Ill-formed 'adds' instruction.\n");
2333   COMPARE_A32(Adds(sp, sp, pc), "adds sp, pc\n");
2334   MUST_FAIL_TEST_T32(Adds(sp, sp, pc), "Unpredictable instruction.\n");
2335 
2336   // ADR.
2337   {
2338     Literal<uint32_t> literal(0x12345678);
2339     // The address is 0x4 and not 0x0 because of the branch over the literal.
2340     // TODO: Consider disallowing this instruction.
2341     COMPARE_A32(Adr(pc, &literal), "adr pc, 0x00000004\n");
2342     MUST_FAIL_TEST_T32(Adr(pc, &literal), "Unpredictable instruction.\n");
2343   }
2344 
2345   // CLZ.
2346   MUST_FAIL_TEST_BOTH(Clz(pc, r0), "Unpredictable instruction.\n");
2347   MUST_FAIL_TEST_BOTH(Clz(r0, pc), "Unpredictable instruction.\n");
2348 
2349   // MOV, MOVS (immediate).
2350   COMPARE_A32(Mov(pc, 1), "mov pc, #1\n");
2351   MUST_FAIL_TEST_T32(Mov(pc, 1), "Unpredictable instruction.\n");
2352   MUST_FAIL_TEST_T32(Mov(pc, 0xfff), "Unpredictable instruction.\n");
2353   COMPARE_A32(Mov(pc, 0xf000), "mov pc, #61440\n");
2354   MUST_FAIL_TEST_T32(Mov(pc, 0xf000), "Unpredictable instruction.\n");
2355   COMPARE_A32(Movs(pc, 1), "movs pc, #1\n");
2356   MUST_FAIL_TEST_T32(Movs(pc, 1), "Unpredictable instruction.\n");
2357   MUST_FAIL_TEST_BOTH(Movs(pc, 0xfff), "Ill-formed 'movs' instruction.\n");
2358   COMPARE_A32(Movs(pc, 0xf000), "movs pc, #61440\n");
2359   MUST_FAIL_TEST_T32(Movs(pc, 0xf000), "Unpredictable instruction.\n");
2360 
2361   // MOV, MOVS (register).
2362   COMPARE_BOTH(Mov(pc, r0), "mov pc, r0\n");
2363   COMPARE_BOTH(Mov(r0, pc), "mov r0, pc\n");
2364   MUST_FAIL_TEST_BOTH(Movs(pc, r0), "Unpredictable instruction.\n");
2365   COMPARE_A32(Movs(r0, pc), "movs r0, pc\n");
2366   MUST_FAIL_TEST_T32(Movs(r0, pc), "Unpredictable instruction.\n");
2367 
2368   // MOV, MOVS (register-shifted register).
2369   MUST_FAIL_TEST_BOTH(Mov(pc, Operand(r0, ASR, r1)),
2370                       "Unpredictable instruction.\n");
2371   MUST_FAIL_TEST_BOTH(Mov(r0, Operand(pc, ASR, r1)),
2372                       "Unpredictable instruction.\n");
2373   MUST_FAIL_TEST_BOTH(Mov(r0, Operand(r1, ASR, pc)),
2374                       "Unpredictable instruction.\n");
2375   MUST_FAIL_TEST_BOTH(Movs(pc, Operand(r0, ASR, r1)),
2376                       "Unpredictable instruction.\n");
2377   MUST_FAIL_TEST_BOTH(Movs(r0, Operand(pc, ASR, r1)),
2378                       "Unpredictable instruction.\n");
2379   MUST_FAIL_TEST_BOTH(Movs(r0, Operand(r1, ASR, pc)),
2380                       "Unpredictable instruction.\n");
2381 
2382   CLEANUP();
2383 }
2384 
2385 
TEST(macro_assembler_pc_rel_A32)2386 TEST(macro_assembler_pc_rel_A32) {
2387   SETUP();
2388   // Simple cases alias adr.
2389   COMPARE_A32(Add(r0, pc, -8), "adr r0, 0x00000000\n");
2390   COMPARE_A32(Add(r0, pc, 255), "adr r0, 0x00000107\n");
2391   COMPARE_A32(Add(r0, pc, 256), "adr r0, 0x00000108\n");
2392   COMPARE_A32(Add(r0, pc, 1024), "adr r0, 0x00000408\n");
2393   COMPARE_A32(Add(r0, pc, -9), "adr r0, 0xffffffff\n");
2394   COMPARE_A32(Add(r0, pc, -1024), "adr r0, 0xfffffc08\n");
2395   COMPARE_A32(Add(r0, pc, UINT32_C(0x80000000)), "adr r0, 0x80000008\n");
2396   COMPARE_A32(Add(r0, pc, -0x7fffffff), "adr r0, 0x80000009\n");
2397 
2398   COMPARE_A32(Sub(r0, pc, 8), "adr r0, 0x00000000\n");
2399   COMPARE_A32(Sub(r0, pc, -255), "adr r0, 0x00000107\n");
2400   COMPARE_A32(Sub(r0, pc, -256), "adr r0, 0x00000108\n");
2401   COMPARE_A32(Sub(r0, pc, -1024), "adr r0, 0x00000408\n");
2402   COMPARE_A32(Sub(r0, pc, 9), "adr r0, 0xffffffff\n");
2403   COMPARE_A32(Sub(r0, pc, 1024), "adr r0, 0xfffffc08\n");
2404   COMPARE_A32(Sub(r0, pc, UINT32_C(0x80000000)), "adr r0, 0x80000008\n");
2405   COMPARE_A32(Sub(r0, pc, -0x7fffffff), "adr r0, 0x80000007\n");
2406 
2407   // Cases out of range.
2408   // Only negative offsets are supported, because the proper behaviour for
2409   // positive offsets is not clear.
2410   MUST_FAIL_TEST_A32(Add(r0, pc, 1025), "Ill-formed 'add' instruction.\n");
2411   MUST_FAIL_TEST_A32(Add(r0, pc, 0xffff), "Ill-formed 'add' instruction.\n");
2412   MUST_FAIL_TEST_A32(Add(r0, pc, 0x10001), "Ill-formed 'add' instruction.\n");
2413   MUST_FAIL_TEST_A32(Add(r0, pc, 0x12345678),
2414                      "Ill-formed 'add' instruction.\n");
2415   MUST_FAIL_TEST_A32(Add(r0, pc, 0x7fffffff),
2416                      "Ill-formed 'add' instruction.\n");
2417   COMPARE_A32(Add(r0, pc, -1025),
2418               "adr r0, 0x00000007\n"
2419               "sub r0, #1024\n");
2420   COMPARE_A32(Add(r0, pc, -0xffff),
2421               "adr r0, 0xffffff09\n"
2422               "sub r0, #65280\n");
2423   COMPARE_A32(Add(r0, pc, -0x10001),
2424               "adr r0, 0x00000007\n"
2425               "sub r0, #65536\n");
2426   COMPARE_A32(Add(r0, pc, -0x2345678),
2427               "adr r0, 0xfffffd90\n"
2428               "sub r0, #21504\n"
2429               "sub r0, #36962304\n");
2430   COMPARE_A32(Add(r0, pc, -0x12345678),
2431               "adr r0, 0xfffffd90\n"
2432               "mov ip, #21504\n"
2433               "movt ip, #4660\n"
2434               "sub r0, ip\n");
2435 
2436   MUST_FAIL_TEST_A32(Sub(r0, pc, -1025), "Ill-formed 'add' instruction.\n");
2437   MUST_FAIL_TEST_A32(Sub(r0, pc, -0xffff), "Ill-formed 'add' instruction.\n");
2438   MUST_FAIL_TEST_A32(Sub(r0, pc, -0x10001), "Ill-formed 'add' instruction.\n");
2439   MUST_FAIL_TEST_A32(Sub(r0, pc, -0x12345678),
2440                      "Ill-formed 'add' instruction.\n");
2441   COMPARE_A32(Sub(r0, pc, 1025),
2442               "adr r0, 0x00000007\n"
2443               "sub r0, #1024\n");
2444   COMPARE_A32(Sub(r0, pc, 0xffff),
2445               "adr r0, 0xffffff09\n"
2446               "sub r0, #65280\n");
2447   COMPARE_A32(Sub(r0, pc, 0x10001),
2448               "adr r0, 0x00000007\n"
2449               "sub r0, #65536\n");
2450   COMPARE_A32(Sub(r0, pc, 0x2345678),
2451               "adr r0, 0xfffffd90\n"
2452               "sub r0, #21504\n"
2453               "sub r0, #36962304\n");
2454   COMPARE_A32(Sub(r0, pc, 0x12345678),
2455               "adr r0, 0xfffffd90\n"
2456               "mov ip, #21504\n"
2457               "movt ip, #4660\n"
2458               "sub r0, ip\n");
2459   COMPARE_A32(Sub(r0, pc, 0x7fffffff),
2460               "adr r0, 0xffffff09\n"
2461               "add r0, #256\n"
2462               "add r0, #2147483648\n");
2463 
2464   CLEANUP();
2465 }
2466 
2467 
TEST(macro_assembler_pc_rel_T32)2468 TEST(macro_assembler_pc_rel_T32) {
2469   SETUP();
2470   // Simple cases alias adr.
2471   COMPARE_T32(Add(r0, pc, -4), "adr r0, 0x00000000\n");     // T1
2472   COMPARE_T32(Add(r0, pc, 1020), "adr r0, 0x00000400\n");   // T1
2473   COMPARE_T32(Add(r0, pc, -5), "adr r0, 0xffffffff\n");     // T2
2474   COMPARE_T32(Add(r0, pc, -4095), "adr r0, 0xfffff005\n");  // T2
2475   COMPARE_T32(Add(r0, pc, -3), "adr r0, 0x00000001\n");     // T3
2476   COMPARE_T32(Add(r0, pc, 1021), "adr r0, 0x00000401\n");   // T3
2477   COMPARE_T32(Add(r0, pc, 1019), "adr r0, 0x000003ff\n");   // T3
2478   COMPARE_T32(Add(r0, pc, 4095), "adr r0, 0x00001003\n");   // T3
2479 
2480   COMPARE_T32(Sub(r0, pc, 4), "adr r0, 0x00000000\n");      // T1
2481   COMPARE_T32(Sub(r0, pc, -1020), "adr r0, 0x00000400\n");  // T1
2482   COMPARE_T32(Sub(r0, pc, 5), "adr r0, 0xffffffff\n");      // T2
2483   COMPARE_T32(Sub(r0, pc, 4095), "adr r0, 0xfffff005\n");   // T2
2484   COMPARE_T32(Sub(r0, pc, 3), "adr r0, 0x00000001\n");      // T3
2485   COMPARE_T32(Sub(r0, pc, -1021), "adr r0, 0x00000401\n");  // T3
2486   COMPARE_T32(Sub(r0, pc, -1019), "adr r0, 0x000003ff\n");  // T3
2487   COMPARE_T32(Sub(r0, pc, -4095), "adr r0, 0x00001003\n");  // T3
2488 
2489   // Cases out of range.
2490   // Only negative offsets are supported, because the proper behaviour for
2491   // positive offsets is not clear.
2492 
2493   MUST_FAIL_TEST_T32(Add(r0, pc, 4096), "Unpredictable instruction.\n");
2494 
2495   // TODO: This case is incorrect; the instruction is unpredictable. The test
2496   // must be updated once the bug is fixed.
2497   COMPARE_T32(Add(r0, pc, -4096), "sub r0, pc, #4096\n");
2498 
2499   MUST_FAIL_TEST_T32(Add(r0, pc, 0xffff), "Ill-formed 'add' instruction.\n");
2500   MUST_FAIL_TEST_T32(Add(r0, pc, 0x10002), "Ill-formed 'add' instruction.\n");
2501   MUST_FAIL_TEST_T32(Add(r0, pc, 0x12345678),
2502                      "Ill-formed 'add' instruction.\n");
2503   MUST_FAIL_TEST_T32(Add(r0, pc, 0x7fffffff),
2504                      "Ill-formed 'add' instruction.\n");
2505   COMPARE_T32(Add(r0, pc, -0x12345678),
2506               "mov r0, pc\n"
2507               "mov ip, #22136\n"
2508               "movt ip, #4660\n"
2509               "sub r0, ip\n");
2510   COMPARE_T32(Add(r0, pc, -0x7fffffff),
2511               "mov r0, pc\n"
2512               "add r0, #1\n"
2513               "add r0, #2147483648\n");
2514 
2515   // TODO: This test aborts in the Assembler (with unpredictable instruction
2516   // errors) before the MacroAssembler gets a chance to do something
2517   // predictable.
2518   // COMPARE_T32(Sub(r0, pc, -4096), "mov r0, pc\n"
2519   //                                 "add r0, #4096\n");
2520 
2521   // TODO: This case is incorrect; the instruction is unpredictable. The test
2522   // must be updated once the bug is fixed.
2523   COMPARE_T32(Sub(r0, pc, 4096), "sub r0, pc, #4096\n");
2524 
2525   MUST_FAIL_TEST_T32(Sub(r0, pc, -0xffff), "Ill-formed 'add' instruction.\n");
2526   MUST_FAIL_TEST_T32(Sub(r0, pc, -0x10002), "Ill-formed 'add' instruction.\n");
2527   MUST_FAIL_TEST_T32(Sub(r0, pc, -0x12345678),
2528                      "Ill-formed 'add' instruction.\n");
2529   MUST_FAIL_TEST_T32(Sub(r0, pc, -0x7fffffff),
2530                      "Ill-formed 'add' instruction.\n");
2531   COMPARE_T32(Sub(r0, pc, 0x12345678),
2532               "mov r0, pc\n"
2533               "mov ip, #22136\n"
2534               "movt ip, #4660\n"
2535               "sub r0, ip\n");
2536   COMPARE_T32(Sub(r0, pc, 0x7fffffff),
2537               "mov r0, pc\n"
2538               "add r0, #1\n"
2539               "add r0, #2147483648\n");
2540   CLEANUP();
2541 }
2542 
2543 
TEST(macro_assembler_unsupported)2544 TEST(macro_assembler_unsupported) {
2545   SETUP();
2546 
2547   MUST_FAIL_TEST_BOTH(Sxtab(r0, r1, Operand(r2, ROR, 1)),
2548                       "Ill-formed 'sxtab' instruction.\n");
2549   MUST_FAIL_TEST_BOTH(Sxtab16(r0, r1, Operand(r0, ASR, 2)),
2550                       "Ill-formed 'sxtab16' instruction.\n");
2551   MUST_FAIL_TEST_BOTH(Sxtah(r0, r1, Operand(r0, LSL, r1)),
2552                       "Ill-formed 'sxtah' instruction.\n");
2553   MUST_FAIL_TEST_BOTH(Uxtab(r0, r1, Operand(r0, LSR, r2)),
2554                       "Ill-formed 'uxtab' instruction.\n");
2555   MUST_FAIL_TEST_BOTH(Uxtab16(r0, r1, Operand(r0, ROR, 1)),
2556                       "Ill-formed 'uxtab16' instruction.\n");
2557   MUST_FAIL_TEST_BOTH(Uxtah(r0, r1, Operand(r0, ASR, 2)),
2558                       "Ill-formed 'uxtah' instruction.\n");
2559   MUST_FAIL_TEST_BOTH(Pkhbt(r0, r1, Operand(r0, LSL, r1)),
2560                       "Ill-formed 'pkhbt' instruction.\n");
2561   MUST_FAIL_TEST_BOTH(Pkhtb(r0, r1, Operand(r0, LSR, r2)),
2562                       "Ill-formed 'pkhtb' instruction.\n");
2563 
2564   MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, 1, PreIndex)),
2565                       "Ill-formed 'pld' instruction.\n");
2566   MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, 1, PostIndex)),
2567                       "Ill-formed 'pldw' instruction.\n");
2568   MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, 1, PreIndex)),
2569                       "Ill-formed 'pli' instruction.\n");
2570 
2571   MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, r0, PreIndex)),
2572                       "Ill-formed 'pld' instruction.\n");
2573   MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, r1, PostIndex)),
2574                       "Ill-formed 'pldw' instruction.\n");
2575   MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, r2, PreIndex)),
2576                       "Ill-formed 'pli' instruction.\n");
2577 
2578   MUST_FAIL_TEST_BOTH(Pld(MemOperand(r0, r0, LSL, 1, PreIndex)),
2579                       "Ill-formed 'pld' instruction.\n");
2580   MUST_FAIL_TEST_BOTH(Pldw(MemOperand(r0, r1, LSR, 2, PostIndex)),
2581                       "Ill-formed 'pldw' instruction.\n");
2582   MUST_FAIL_TEST_BOTH(Pli(MemOperand(r0, r2, ASR, 3, PreIndex)),
2583                       "Ill-formed 'pli' instruction.\n");
2584 
2585   MUST_FAIL_TEST_BOTH(Lda(r0, MemOperand(r0, 1)),
2586                       "Ill-formed 'lda' instruction.\n");
2587   MUST_FAIL_TEST_BOTH(Ldab(r0, MemOperand(r0, 1)),
2588                       "Ill-formed 'ldab' instruction.\n");
2589   MUST_FAIL_TEST_BOTH(Ldaex(r0, MemOperand(r0, 1)),
2590                       "Ill-formed 'ldaex' instruction.\n");
2591   MUST_FAIL_TEST_BOTH(Ldaexb(r0, MemOperand(r0, 1)),
2592                       "Ill-formed 'ldaexb' instruction.\n");
2593   MUST_FAIL_TEST_BOTH(Ldaexh(r0, MemOperand(r0, 1)),
2594                       "Ill-formed 'ldaexh' instruction.\n");
2595   MUST_FAIL_TEST_BOTH(Ldah(r0, MemOperand(r0, 1)),
2596                       "Ill-formed 'ldah' instruction.\n");
2597   MUST_FAIL_TEST_BOTH(Ldrex(r0, MemOperand(r0, 1)),
2598                       "Ill-formed 'ldrex' instruction.\n");
2599   MUST_FAIL_TEST_BOTH(Ldrexb(r0, MemOperand(r0, 1)),
2600                       "Ill-formed 'ldrexb' instruction.\n");
2601   MUST_FAIL_TEST_BOTH(Ldrexh(r0, MemOperand(r0, 1)),
2602                       "Ill-formed 'ldrexh' instruction.\n");
2603   MUST_FAIL_TEST_BOTH(Stl(r0, MemOperand(r0, 1)),
2604                       "Ill-formed 'stl' instruction.\n");
2605   MUST_FAIL_TEST_BOTH(Stlb(r0, MemOperand(r0, 1)),
2606                       "Ill-formed 'stlb' instruction.\n");
2607   MUST_FAIL_TEST_BOTH(Stlh(r0, MemOperand(r0, 1)),
2608                       "Ill-formed 'stlh' instruction.\n");
2609 
2610   MUST_FAIL_TEST_BOTH(Ldaexd(r0, r1, MemOperand(r0, 1)),
2611                       "Ill-formed 'ldaexd' instruction.\n");
2612   MUST_FAIL_TEST_BOTH(Ldrexd(r0, r1, MemOperand(r0, 1)),
2613                       "Ill-formed 'ldrexd' instruction.\n");
2614   MUST_FAIL_TEST_BOTH(Stlex(r0, r1, MemOperand(r0, 1)),
2615                       "Ill-formed 'stlex' instruction.\n");
2616   MUST_FAIL_TEST_BOTH(Stlexb(r0, r1, MemOperand(r0, 1)),
2617                       "Ill-formed 'stlexb' instruction.\n");
2618   MUST_FAIL_TEST_BOTH(Stlexh(r0, r1, MemOperand(r0, 1)),
2619                       "Ill-formed 'stlexh' instruction.\n");
2620   MUST_FAIL_TEST_BOTH(Strex(r0, r1, MemOperand(r0, 1)),
2621                       "Ill-formed 'strex' instruction.\n");
2622   MUST_FAIL_TEST_BOTH(Strexb(r0, r1, MemOperand(r0, 1)),
2623                       "Ill-formed 'strexb' instruction.\n");
2624   MUST_FAIL_TEST_BOTH(Strexh(r0, r1, MemOperand(r0, 1)),
2625                       "Ill-formed 'strexh' instruction.\n");
2626 
2627   MUST_FAIL_TEST_BOTH(Stlexd(r0, r1, r2, MemOperand(r0, 1)),
2628                       "Ill-formed 'stlexd' instruction.\n");
2629   MUST_FAIL_TEST_BOTH(Strexd(r0, r1, r2, MemOperand(r0, 1)),
2630                       "Ill-formed 'strexd' instruction.\n");
2631 
2632   CLEANUP();
2633 }
2634 
TEST(macro_assembler_Vmov_neon_immediate)2635 TEST(macro_assembler_Vmov_neon_immediate) {
2636   SETUP();
2637 
2638   // Move 8, 16 and 32-bit immediates into D registers, duplicated across the
2639   // destination.
2640   COMPARE_BOTH(Vmov(I8, d0, 0xac), "vmov.i8 d0, #172\n");
2641 
2642   COMPARE_BOTH(Vmov(I16, d0, 0xa4), "vmov.i16 d0, #164\n");
2643   COMPARE_BOTH(Vmov(I16, d0, 0x9797), "vmov.i8 d0, #151\n");
2644   COMPARE_BOTH(Vmov(I16, d0, 0x9ef6),
2645                "mov ip, #40694\n"
2646                "vdup.16 d0, ip\n");
2647 
2648   COMPARE_BOTH(Vmov(I32, d0, 0x6d0000), "vmov.i32 d0, #7143424\n");
2649   COMPARE_BOTH(Vmov(I32, d0, 0x15ffffff), "vmvn.i32 d0, #3925868544\n");
2650   COMPARE_BOTH(Vmov(I32, d0, 0x74747474), "vmov.i8 d0, #116\n");
2651   COMPARE_BOTH(Vmov(I32, d0, 0xff0000ff), "vmov.i64 d0, #0xff0000ffff0000ff\n");
2652   COMPARE_BOTH(Vmov(I32, d0, 0x1ecb9ef6),
2653                "mov ip, #40694\n"
2654                "movt ip, #7883\n"
2655                "vdup.32 d0, ip\n");
2656   COMPARE_BOTH(Vmov(I32, d0, 0x006d0000), "vmov.i32 d0, #7143424\n");
2657   COMPARE_BOTH(Vmov(I32, d0, 0x00004da6),
2658                "mov ip, #19878\n"
2659                "vdup.32 d0, ip\n");
2660   COMPARE_BOTH(Vmov(I32, d0, 0xffffff55), "vmvn.i32 d0, #170\n");
2661   COMPARE_BOTH(Vmov(I32, d0, 0xffff55ff), "vmvn.i32 d0, #43520\n");
2662   COMPARE_BOTH(Vmov(I32, d0, 0xff55ffff), "vmvn.i32 d0, #11141120\n");
2663 
2664   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0xa5a5a5a5a5a5a5a5)),
2665                "vmov.i8 d0, #165\n");
2666   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x0a01248315ffffff)),
2667                "mvn ip, #3925868544\n"
2668                "vdup.32 d0, ip\n"
2669                "mov ip, #9347\n"
2670                "movt ip, #2561\n"
2671                "vmov.32 d0[1], ip\n");
2672   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x6fe1a7a779e33af2)),
2673                "mov ip, #15090\n"
2674                "movt ip, #31203\n"
2675                "vdup.32 d0, ip\n"
2676                "mov ip, #42919\n"
2677                "movt ip, #28641\n"
2678                "vmov.32 d0[1], ip\n");
2679   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x2efa8b440000c1da)),
2680                "mov ip, #49626\n"
2681                "vdup.32 d0, ip\n"
2682                "mov ip, #35652\n"
2683                "movt ip, #12026\n"
2684                "vmov.32 d0[1], ip\n");
2685   COMPARE_BOTH(Vmov(I64, d0, UINT64_C(0x00008bb75c3036fd)),
2686                "mov ip, #14077\n"
2687                "movt ip, #23600\n"
2688                "vdup.32 d0, ip\n"
2689                "mov ip, #35767\n"
2690                "vmov.32 d0[1], ip\n");
2691 
2692   COMPARE_BOTH(Vmov(F32, d0, 0.5), "vmov.f32 d0, #0.5\n");
2693   COMPARE_BOTH(Vmov(F32, d0, 1.1),
2694                "mov ip, #52429\n"
2695                "movt ip, #16268\n"
2696                "vdup.32 d0, ip\n");
2697 
2698   COMPARE_T32(Vmov(I64, d0, UINT64_C(0x2fff2fff3e2869e7)),
2699               "mov ip, #27111\n"
2700               "movt ip, #15912\n"
2701               "vdup.32 d0, ip\n"
2702               "mvn ip, #3489714176\n"
2703               "vmov.32 d0[1], ip\n");
2704 
2705   COMPARE_A32(Vmov(I32, d0, 0x0ffffffa),
2706               "mvn ip, #4026531845\n"
2707               "vdup.32 d0, ip\n");
2708   COMPARE_A32(Vmov(I64, d0, UINT64_C(0x65ffffff16a0ef46)),
2709               "mov ip, #61254\n"
2710               "movt ip, #5792\n"
2711               "vdup.32 d0, ip\n"
2712               "mvn ip, #2583691264\n"
2713               "vmov.32 d0[1], ip\n");
2714 
2715   // Move 8, 16 and 32-bit immediates into Q registers, duplicated across the
2716   // destination.
2717   COMPARE_BOTH(Vmov(I8, q0, 0xac), "vmov.i8 q0, #172\n");
2718 
2719   COMPARE_BOTH(Vmov(I16, q0, 0xa4), "vmov.i16 q0, #164\n");
2720   COMPARE_BOTH(Vmov(I16, q0, 0x9797), "vmov.i8 q0, #151\n");
2721   COMPARE_BOTH(Vmov(I16, q0, 0x9ef6),
2722                "mov ip, #40694\n"
2723                "vdup.16 q0, ip\n");
2724 
2725   COMPARE_BOTH(Vmov(I32, q0, 0x6d0000), "vmov.i32 q0, #7143424\n");
2726   COMPARE_BOTH(Vmov(I32, q0, 0x15ffffff), "vmvn.i32 q0, #3925868544\n");
2727   COMPARE_BOTH(Vmov(I32, q0, 0x74747474), "vmov.i8 q0, #116\n");
2728   COMPARE_BOTH(Vmov(I32, q0, 0xff0000ff), "vmov.i64 q0, #0xff0000ffff0000ff\n");
2729   COMPARE_BOTH(Vmov(I32, q0, 0x1ecb9ef6),
2730                "mov ip, #40694\n"
2731                "movt ip, #7883\n"
2732                "vdup.32 q0, ip\n");
2733   COMPARE_BOTH(Vmov(I32, q0, 0x006d0000), "vmov.i32 q0, #7143424\n");
2734   COMPARE_BOTH(Vmov(I32, q0, 0x00004da6),
2735                "mov ip, #19878\n"
2736                "vdup.32 q0, ip\n");
2737 
2738   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0xa5a5a5a5a5a5a5a5)),
2739                "vmov.i8 q0, #165\n");
2740   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x0a01248315ffffff)),
2741                "mvn ip, #3925868544\n"
2742                "vdup.32 q0, ip\n"
2743                "mov ip, #9347\n"
2744                "movt ip, #2561\n"
2745                "vmov.32 d0[1], ip\n"
2746                "vmov.f64 d1, d0\n");
2747   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x6fe1a7a779e33af2)),
2748                "mov ip, #15090\n"
2749                "movt ip, #31203\n"
2750                "vdup.32 q0, ip\n"
2751                "mov ip, #42919\n"
2752                "movt ip, #28641\n"
2753                "vmov.32 d0[1], ip\n"
2754                "vmov.f64 d1, d0\n");
2755   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x2efa8b440000c1da)),
2756                "mov ip, #49626\n"
2757                "vdup.32 q0, ip\n"
2758                "mov ip, #35652\n"
2759                "movt ip, #12026\n"
2760                "vmov.32 d0[1], ip\n"
2761                "vmov.f64 d1, d0\n");
2762   COMPARE_BOTH(Vmov(I64, q0, UINT64_C(0x00008bb75c3036fd)),
2763                "mov ip, #14077\n"
2764                "movt ip, #23600\n"
2765                "vdup.32 q0, ip\n"
2766                "mov ip, #35767\n"
2767                "vmov.32 d0[1], ip\n"
2768                "vmov.f64 d1, d0\n");
2769 
2770   COMPARE_BOTH(Vmov(F32, q0, 0.5), "vmov.f32 q0, #0.5\n");
2771   COMPARE_BOTH(Vmov(F32, q0, 1.1),
2772                "mov ip, #52429\n"
2773                "movt ip, #16268\n"
2774                "vdup.32 q0, ip\n");
2775   COMPARE_BOTH(Vmov(F64, q0, 0.5),
2776                "vmov.f64 d0, #0.5\n"
2777                "vmov.f64 d1, d0\n");
2778   COMPARE_BOTH(Vmov(F64, q0, 1.1),
2779                "mov ip, #39322\n"
2780                "movt ip, #39321\n"
2781                "vdup.32 d0, ip\n"
2782                "mov ip, #39321\n"
2783                "movt ip, #16369\n"
2784                "vmov.32 d0[1], ip\n"
2785                "vmov.f64 d1, d0\n");
2786 
2787   COMPARE_T32(Vmov(I64, q0, UINT64_C(0x2fff2fff3e2869e7)),
2788               "mov ip, #27111\n"
2789               "movt ip, #15912\n"
2790               "vdup.32 q0, ip\n"
2791               "mvn ip, #3489714176\n"
2792               "vmov.32 d0[1], ip\n"
2793               "vmov.f64 d1, d0\n");
2794 
2795   COMPARE_A32(Vmov(I32, q0, 0x0ffffffa),
2796               "mvn ip, #4026531845\n"
2797               "vdup.32 q0, ip\n");
2798   COMPARE_A32(Vmov(I64, q0, UINT64_C(0x65ffffff16a0ef46)),
2799               "mov ip, #61254\n"
2800               "movt ip, #5792\n"
2801               "vdup.32 q0, ip\n"
2802               "mvn ip, #2583691264\n"
2803               "vmov.32 d0[1], ip\n"
2804               "vmov.f64 d1, d0\n");
2805   CLEANUP();
2806 }
2807 
TEST(macro_assembler_T32_IT)2808 TEST(macro_assembler_T32_IT) {
2809   SETUP();
2810 
2811   // ADC (register) T1
2812   COMPARE_T32(Adc(eq, r0, r0, r1),
2813               "it eq\n"
2814               "adceq r0, r1\n");
2815 
2816   COMPARE_T32(Adc(eq, r0, r1, r2),
2817               "bne 0x00000006\n"
2818               "adc r0, r1, r2\n");
2819 
2820   // ADD (immediate) T1
2821   COMPARE_T32(Add(eq, r0, r1, 0x1),
2822               "it eq\n"
2823               "addeq r0, r1, #1\n");
2824 
2825   COMPARE_T32(Add(eq, r0, r1, 0x8),
2826               "bne 0x00000006\n"
2827               "add r0, r1, #8\n");
2828 
2829   // ADD (immediate) T2
2830   COMPARE_T32(Add(eq, r0, r0, 0xff),
2831               "it eq\n"
2832               "addeq r0, #255\n");
2833 
2834   // ADD (register) T1
2835   COMPARE_T32(Add(eq, r0, r1, r7),
2836               "it eq\n"
2837               "addeq r0, r1, r7\n");
2838 
2839   // ADD (register) T2
2840   COMPARE_T32(Add(eq, r5, r5, r8),
2841               "it eq\n"
2842               "addeq r5, r8\n");
2843 
2844   // ADD (SP plus immediate) T1
2845   COMPARE_T32(Add(eq, r7, sp, 1020),
2846               "it eq\n"
2847               "addeq r7, sp, #1020\n");
2848 
2849   COMPARE_T32(Add(eq, r7, sp, 1),
2850               "bne 0x00000006\n"
2851               "add r7, sp, #1\n");
2852 
2853   COMPARE_T32(Add(eq, r7, sp, 1024),
2854               "bne 0x00000006\n"
2855               "add r7, sp, #1024\n");
2856 
2857   COMPARE_T32(Add(eq, sp, sp, 32),
2858               "bne 0x00000004\n"
2859               "add sp, #32\n");
2860 
2861   // ADD (SP plus register) T1
2862   COMPARE_T32(Add(eq, r7, sp, r7),
2863               "it eq\n"
2864               "addeq r7, sp, r7\n");
2865 
2866   // ADD (SP plus register) T2
2867   COMPARE_T32(Add(eq, sp, sp, r10),
2868               "it eq\n"
2869               "addeq sp, r10\n");
2870 
2871   COMPARE_T32(Add(eq, r5, r5, sp),
2872               "bne 0x00000006\n"
2873               "add.w r5, sp\n");
2874 
2875   // AND (register) T1
2876   COMPARE_T32(And(eq, r7, r7, r0),
2877               "it eq\n"
2878               "andeq r7, r0\n");
2879 
2880   COMPARE_T32(And(eq, r8, r8, r0),
2881               "bne 0x00000006\n"
2882               "and r8, r0\n");
2883 
2884   // ASR (immediate) T2
2885   COMPARE_T32(Asr(eq, r0, r1, 16),
2886               "it eq\n"
2887               "asreq r0, r1, #16\n");
2888 
2889   COMPARE_T32(Asr(eq, r0, r1, 32),
2890               "it eq\n"
2891               "asreq r0, r1, #32\n");
2892 
2893   COMPARE_T32(Asr(eq, r0, r1, 0),
2894               "bne 0x0000000a\n"
2895               "mov r0, #0\n"
2896               "asr r0, r1, r0\n");
2897 
2898   // ASR (register) T1
2899   COMPARE_T32(Asr(eq, r7, r7, r3),
2900               "it eq\n"
2901               "asreq r7, r3\n");
2902 
2903   COMPARE_T32(Asr(eq, r8, r8, r3),
2904               "bne 0x00000006\n"
2905               "asr r8, r3\n");
2906 
2907   // BIC (register) T1
2908   COMPARE_T32(Bic(eq, r7, r7, r6),
2909               "it eq\n"
2910               "biceq r7, r6\n");
2911 
2912   COMPARE_T32(Bic(eq, r8, r8, r6),
2913               "bne 0x00000006\n"
2914               "bic r8, r6\n");
2915 
2916   Label l;
2917   __ Bind(&l);
2918 
2919   // BLX (register) T1
2920   COMPARE_T32(Blx(eq, lr),
2921               "it eq\n"
2922               "blxeq lr\n");
2923   COMPARE_T32(Blx(eq, &l),
2924               "bne 0x00000006\n"
2925               "blx 0x00000000\n");
2926 
2927   // BX (register) T1
2928   COMPARE_T32(Bx(eq, lr),
2929               "it eq\n"
2930               "bxeq lr\n");
2931 
2932   // CMN (register) T1
2933   COMPARE_T32(Cmn(eq, r0, r1),
2934               "it eq\n"
2935               "cmneq r0, r1\n");
2936 
2937   COMPARE_T32(Cmn(eq, r0, r8),
2938               "bne 0x00000006\n"
2939               "cmn r0, r8\n");
2940 
2941   // CMP (immediate) T1
2942   COMPARE_T32(Cmp(eq, r7, 0xff),
2943               "it eq\n"
2944               "cmpeq r7, #255\n");
2945 
2946   // CMP (register) T1
2947   COMPARE_T32(Cmp(eq, r6, r7),
2948               "it eq\n"
2949               "cmpeq r6, r7\n");
2950 
2951   // CMP (register) T2
2952   COMPARE_T32(Cmp(eq, r9, r10),
2953               "it eq\n"
2954               "cmpeq r9, r10\n");
2955 
2956   COMPARE_T32(Cmp(eq, r0, 0x100),
2957               "bne 0x00000006\n"
2958               "cmp r0, #256\n");
2959 
2960   // EOR (register) T1
2961   COMPARE_T32(Eor(eq, r0, r0, r7),
2962               "it eq\n"
2963               "eoreq r0, r7\n");
2964 
2965   COMPARE_T32(Eor(eq, r0, r0, 0x1),
2966               "bne 0x00000006\n"
2967               "eor r0, #0x1\n");
2968 
2969   // LDR (immediate) T1
2970   COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 124)),
2971               "it eq\n"
2972               "ldreq r4, [r7, #124]\n");
2973 
2974   COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 1)),
2975               "bne 0x00000006\n"
2976               "ldr r4, [r7, #1]\n");
2977 
2978   COMPARE_T32(Ldr(eq, r4, MemOperand(r7, 128)),
2979               "bne 0x00000006\n"
2980               "ldr r4, [r7, #128]\n");
2981 
2982   // LDR (immediate) T2
2983   COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1020)),
2984               "it eq\n"
2985               "ldreq r4, [sp, #1020]\n");
2986 
2987   COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1)),
2988               "bne 0x00000006\n"
2989               "ldr r4, [sp, #1]\n");
2990 
2991   COMPARE_T32(Ldr(eq, r4, MemOperand(sp, 1024)),
2992               "bne 0x00000006\n"
2993               "ldr r4, [sp, #1024]\n");
2994 
2995   // LDR (register) T1
2996   COMPARE_T32(Ldr(eq, r5, MemOperand(r6, r7)),
2997               "it eq\n"
2998               "ldreq r5, [r6, r7]\n");
2999 
3000   COMPARE_T32(Ldr(eq, r5, MemOperand(r6, r8)),
3001               "bne 0x00000006\n"
3002               "ldr r5, [r6, r8]\n");
3003 
3004   // LDRB (immediate) T1
3005   COMPARE_T32(Ldrb(eq, r6, MemOperand(r7, 31)),
3006               "it eq\n"
3007               "ldrbeq r6, [r7, #31]\n");
3008 
3009   COMPARE_T32(Ldrb(eq, r6, MemOperand(r7, 32)),
3010               "bne 0x00000006\n"
3011               "ldrb r6, [r7, #32]\n");
3012 
3013   // LDRB (register) T1
3014   COMPARE_T32(Ldrb(eq, r5, MemOperand(r6, r7)),
3015               "it eq\n"
3016               "ldrbeq r5, [r6, r7]\n");
3017 
3018   COMPARE_T32(Ldrb(eq, r6, MemOperand(r9)),
3019               "bne 0x00000006\n"
3020               "ldrb r6, [r9]\n");
3021 
3022   // LDRH (immediate) T1
3023   COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 62)),
3024               "it eq\n"
3025               "ldrheq r6, [r7, #62]\n");
3026 
3027   COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 64)),
3028               "bne 0x00000006\n"
3029               "ldrh r6, [r7, #64]\n");
3030 
3031   COMPARE_T32(Ldrh(eq, r6, MemOperand(r7, 1)),
3032               "bne 0x00000006\n"
3033               "ldrh r6, [r7, #1]\n");
3034 
3035   // LDRH (register) T1
3036   COMPARE_T32(Ldrh(eq, r5, MemOperand(r6, r7)),
3037               "it eq\n"
3038               "ldrheq r5, [r6, r7]\n");
3039 
3040   COMPARE_T32(Ldrh(eq, r6, MemOperand(r9)),
3041               "bne 0x00000006\n"
3042               "ldrh r6, [r9]\n");
3043 
3044   // LDRSB (register) T1
3045   COMPARE_T32(Ldrsb(eq, r5, MemOperand(r6, r7)),
3046               "it eq\n"
3047               "ldrsbeq r5, [r6, r7]\n");
3048 
3049   COMPARE_T32(Ldrsb(eq, r6, MemOperand(r9)),
3050               "bne 0x00000006\n"
3051               "ldrsb r6, [r9]\n");
3052 
3053   // LDRSH (register) T1
3054   COMPARE_T32(Ldrsh(eq, r5, MemOperand(r6, r7)),
3055               "it eq\n"
3056               "ldrsheq r5, [r6, r7]\n");
3057 
3058   COMPARE_T32(Ldrsh(eq, r6, MemOperand(r9)),
3059               "bne 0x00000006\n"
3060               "ldrsh r6, [r9]\n");
3061 
3062   // LSL (immediate) T2
3063   COMPARE_T32(Lsl(eq, r0, r1, 16),
3064               "it eq\n"
3065               "lsleq r0, r1, #16\n");
3066 
3067   COMPARE_T32(Lsl(eq, r0, r1, 0),
3068               "bne 0x0000000a\n"
3069               "mov r0, #0\n"
3070               "lsl r0, r1, r0\n");
3071 
3072   COMPARE_T32(Lsl(eq, r0, r1, 32),
3073               "bne 0x0000000a\n"
3074               "mov r0, #32\n"
3075               "lsl r0, r1, r0\n");
3076 
3077   // LSL (register) T1
3078   COMPARE_T32(Lsl(eq, r7, r7, r3),
3079               "it eq\n"
3080               "lsleq r7, r3\n");
3081 
3082   COMPARE_T32(Lsl(eq, r8, r8, r3),
3083               "bne 0x00000006\n"
3084               "lsl r8, r3\n");
3085 
3086   // LSR (immediate) T2
3087   COMPARE_T32(Lsr(eq, r0, r1, 16),
3088               "it eq\n"
3089               "lsreq r0, r1, #16\n");
3090 
3091   COMPARE_T32(Lsr(eq, r0, r1, 32),
3092               "it eq\n"
3093               "lsreq r0, r1, #32\n");
3094 
3095   COMPARE_T32(Lsr(eq, r0, r1, 0),
3096               "bne 0x0000000a\n"
3097               "mov r0, #0\n"
3098               "lsr r0, r1, r0\n");
3099 
3100   // LSR (register) T1
3101   COMPARE_T32(Lsr(eq, r7, r7, r3),
3102               "it eq\n"
3103               "lsreq r7, r3\n");
3104 
3105   COMPARE_T32(Lsr(eq, r8, r8, r3),
3106               "bne 0x00000006\n"
3107               "lsr r8, r3\n");
3108 
3109   // MOV (immediate) T1
3110   COMPARE_T32(Mov(eq, r7, 0xff),
3111               "it eq\n"
3112               "moveq r7, #255\n");
3113 
3114   // MOV (register) T1
3115   COMPARE_T32(Mov(eq, r9, r8),
3116               "it eq\n"
3117               "moveq r9, r8\n");
3118 
3119   // MOV (register) T2
3120   COMPARE_T32(Mov(eq, r0, Operand(r1, LSR, 16)),
3121               "it eq\n"
3122               "lsreq r0, r1, #16\n");
3123 
3124   COMPARE_T32(Mov(eq, r0, Operand(r1, ROR, 16)),
3125               "bne 0x00000006\n"
3126               "ror r0, r1, #16\n");
3127 
3128   // MOV (register-shifted register) T1
3129   COMPARE_T32(Mov(eq, r0, Operand(r0, LSR, r1)),
3130               "it eq\n"
3131               "lsreq r0, r1\n");
3132 
3133   COMPARE_T32(Mov(eq, r0, Operand(r1, LSR, r2)),
3134               "bne 0x00000006\n"
3135               "lsr r0, r1, r2\n");
3136 
3137   // MUL (T1)
3138   COMPARE_T32(Mul(eq, r0, r1, r0),
3139               "it eq\n"
3140               "muleq r0, r1, r0\n");
3141 
3142   COMPARE_T32(Mul(eq, r0, r1, r2),
3143               "bne 0x00000006\n"
3144               "mul r0, r1, r2\n");
3145 
3146   // MVN (register) T1
3147   COMPARE_T32(Mvn(eq, r4, r6),
3148               "it eq\n"
3149               "mvneq r4, r6\n");
3150 
3151   COMPARE_T32(Mvn(eq, r8, r6),
3152               "bne 0x00000006\n"
3153               "mvn r8, r6\n");
3154 
3155   // ORR (register) T1
3156   COMPARE_T32(Orr(eq, r0, r0, r1),
3157               "it eq\n"
3158               "orreq r0, r1\n");
3159 
3160   COMPARE_T32(Orr(eq, r0, r1, r2),
3161               "bne 0x00000006\n"
3162               "orr r0, r1, r2\n");
3163 
3164   // ROR (register) T1
3165   COMPARE_T32(Ror(eq, r7, r7, r3),
3166               "it eq\n"
3167               "roreq r7, r3\n");
3168 
3169   COMPARE_T32(Ror(eq, r8, r8, r3),
3170               "bne 0x00000006\n"
3171               "ror r8, r3\n");
3172 
3173   COMPARE_T32(Ror(eq, r0, r1, 16),
3174               "bne 0x00000006\n"
3175               "ror r0, r1, #16\n");
3176 
3177   // RSB (immediate) T1
3178   COMPARE_T32(Rsb(eq, r0, r1, 0),
3179               "it eq\n"
3180               "rsbeq r0, r1, #0\n");
3181 
3182   COMPARE_T32(Rsb(eq, r0, r1, 1),
3183               "bne 0x00000006\n"
3184               "rsb r0, r1, #1\n");
3185 
3186   // SBC (register) T1
3187   COMPARE_T32(Sbc(eq, r0, r0, r1),
3188               "it eq\n"
3189               "sbceq r0, r1\n");
3190 
3191   COMPARE_T32(Sbc(eq, r0, r1, r2),
3192               "bne 0x00000006\n"
3193               "sbc r0, r1, r2\n");
3194 
3195   // STR (immediate) T1
3196   COMPARE_T32(Str(eq, r4, MemOperand(r7, 124)),
3197               "it eq\n"
3198               "streq r4, [r7, #124]\n");
3199 
3200   COMPARE_T32(Str(eq, r4, MemOperand(r7, 1)),
3201               "bne 0x00000006\n"
3202               "str r4, [r7, #1]\n");
3203 
3204   COMPARE_T32(Str(eq, r4, MemOperand(r7, 128)),
3205               "bne 0x00000006\n"
3206               "str r4, [r7, #128]\n");
3207 
3208   // STR (immediate) T2
3209   COMPARE_T32(Str(eq, r4, MemOperand(sp, 1020)),
3210               "it eq\n"
3211               "streq r4, [sp, #1020]\n");
3212 
3213   COMPARE_T32(Str(eq, r4, MemOperand(sp, 1)),
3214               "bne 0x00000006\n"
3215               "str r4, [sp, #1]\n");
3216 
3217   COMPARE_T32(Str(eq, r4, MemOperand(sp, 1024)),
3218               "bne 0x00000006\n"
3219               "str r4, [sp, #1024]\n");
3220 
3221   // STR (register) T1
3222   COMPARE_T32(Str(eq, r5, MemOperand(r6, r7)),
3223               "it eq\n"
3224               "streq r5, [r6, r7]\n");
3225 
3226   COMPARE_T32(Str(eq, r5, MemOperand(r6, r8)),
3227               "bne 0x00000006\n"
3228               "str r5, [r6, r8]\n");
3229 
3230   // STRB (immediate) T1
3231   COMPARE_T32(Strb(eq, r6, MemOperand(r7, 31)),
3232               "it eq\n"
3233               "strbeq r6, [r7, #31]\n");
3234 
3235   COMPARE_T32(Strb(eq, r6, MemOperand(r7, 32)),
3236               "bne 0x00000006\n"
3237               "strb r6, [r7, #32]\n");
3238 
3239   // STRB (register) T1
3240   COMPARE_T32(Strb(eq, r5, MemOperand(r6, r7)),
3241               "it eq\n"
3242               "strbeq r5, [r6, r7]\n");
3243 
3244   COMPARE_T32(Strb(eq, r6, MemOperand(r9)),
3245               "bne 0x00000006\n"
3246               "strb r6, [r9]\n");
3247 
3248   // STRH (immediate) T1
3249   COMPARE_T32(Strh(eq, r6, MemOperand(r7, 62)),
3250               "it eq\n"
3251               "strheq r6, [r7, #62]\n");
3252 
3253   COMPARE_T32(Strh(eq, r6, MemOperand(r7, 64)),
3254               "bne 0x00000006\n"
3255               "strh r6, [r7, #64]\n");
3256 
3257   COMPARE_T32(Strh(eq, r6, MemOperand(r7, 1)),
3258               "bne 0x00000006\n"
3259               "strh r6, [r7, #1]\n");
3260 
3261   // STRH (register) T1
3262   COMPARE_T32(Strh(eq, r5, MemOperand(r6, r7)),
3263               "it eq\n"
3264               "strheq r5, [r6, r7]\n");
3265 
3266   COMPARE_T32(Strh(eq, r6, MemOperand(r9)),
3267               "bne 0x00000006\n"
3268               "strh r6, [r9]\n");
3269 
3270   // SUB (immediate) T1
3271   COMPARE_T32(Sub(eq, r0, r1, 0x1),
3272               "it eq\n"
3273               "subeq r0, r1, #1\n");
3274 
3275   COMPARE_T32(Sub(eq, r0, r1, 0x8),
3276               "bne 0x00000006\n"
3277               "sub r0, r1, #8\n");
3278 
3279   // SUB (immediate) T2
3280   COMPARE_T32(Sub(eq, r0, r0, 0xff),
3281               "it eq\n"
3282               "subeq r0, #255\n");
3283 
3284   // SUB (register) T1
3285   COMPARE_T32(Sub(eq, r0, r1, r7),
3286               "it eq\n"
3287               "subeq r0, r1, r7\n");
3288 
3289   COMPARE_T32(Sub(eq, r5, r5, r8),
3290               "bne 0x00000006\n"
3291               "sub r5, r8\n");
3292 
3293   COMPARE_T32(Sub(eq, r7, sp, 1),
3294               "bne 0x00000006\n"
3295               "sub r7, sp, #1\n");
3296 
3297   COMPARE_T32(Sub(eq, pc, pc, 0),
3298               "bne 0x00000006\n"
3299               "sub pc, #0\n");
3300 
3301   // TST (register) T1
3302   COMPARE_T32(Tst(eq, r0, r1),
3303               "it eq\n"
3304               "tsteq r0, r1\n");
3305 
3306   COMPARE_T32(Tst(eq, r8, r9),
3307               "bne 0x00000006\n"
3308               "tst r8, r9\n");
3309 
3310   CLEANUP();
3311 }
3312 
3313 
TEST(unbound_label)3314 TEST(unbound_label) {
3315   SETUP();
3316 
3317 #ifdef VIXL_DEBUG
3318   MUST_FAIL_TEST_BOTH_BLOCK({
3319     Label label;
3320     masm.B(&label);
3321   }, "Label used but not bound.\n")
3322 
3323   MUST_FAIL_TEST_BOTH_BLOCK({
3324     Label label;
3325     masm.B(eq, &label);
3326   }, "Label used but not bound.\n")
3327 
3328   MUST_FAIL_TEST_T32_BLOCK({
3329     Label label;
3330     masm.Cbz(r0, &label);
3331   }, "Label used but not bound.\n")
3332 
3333   MUST_FAIL_TEST_T32_BLOCK({
3334     Label label;
3335     masm.Cbnz(r1, &label);
3336   }, "Label used but not bound.\n")
3337 #endif
3338 
3339   CLEANUP();
3340 }
3341 
3342 
TEST(macro_assembler_AddressComputationHelper)3343 TEST(macro_assembler_AddressComputationHelper) {
3344   SETUP();
3345 
3346   // Simple cases: the address fits in the mask.
3347   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0xfff, 0xfff)),
3348               "ldr r0, [r1, #4095]\n");
3349   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 1, 0xfff)),
3350               "ldr r0, [r1, #1]\n");
3351   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0, 0xfff)),
3352               "ldr r0, [r1]\n");
3353 
3354   // Similar, but the base register must be preserved. (This has no effect for
3355   // encodable cases.)
3356   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r2, r1, 0xfff, 0xfff)),
3357               "ldr r0, [r1, #4095]\n");
3358 
3359   // Cases where the extra offset has to be aligned.
3360   COMPARE_A32(Vldr(d0, masm.MemOperandComputationHelper(r1, r1, 0x3fc, 0x3fc)),
3361               "vldr d0, [r1, #1020]\n");
3362 
3363   // Out-of-range offsets.
3364   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r1, r1, 0x1000, 0xfff)),
3365               "add r1, #4096\n"
3366               "ldr r0, [r1]\n");
3367   COMPARE_A32(Ldr(r0, masm.MemOperandComputationHelper(r2, r1, 0x1000, 0xfff)),
3368               "add r2, r1, #4096\n"
3369               "ldr r0, [r2]\n");
3370   COMPARE_A32(Ldr(r0,
3371                   masm.MemOperandComputationHelper(r2, r1, 0xffffffff, 0xfff)),
3372               "sub r2, r1, #1\n"
3373               "ldr r0, [r2]\n");
3374 
3375   // TODO: Improve the code generation for these cases.
3376 
3377   COMPARE_A32(Ldr(r0,
3378                   masm.MemOperandComputationHelper(r2, r1, 0x12345678, 0xfff)),
3379               "mov r2, #20480\n"
3380               "movt r2, #4660\n"
3381               "add r2, r1, r2\n"
3382               "ldr r0, [r2, #1656]\n");
3383   COMPARE_A32(Ldr(r0,
3384                   masm.MemOperandComputationHelper(r2, r1, 0x7fffffff, 0xfff)),
3385               "sub r2, r1, #1\n"
3386               "sub r2, #2147483648\n"
3387               "ldr r0, [r2]\n");
3388   COMPARE_A32(Ldr(r0,
3389                   masm.MemOperandComputationHelper(r2, r1, 0xffcba000, 0xfff)),
3390               "sub r2, r1, #286720\n"
3391               "sub r2, #3145728\n"
3392               "ldr r0, [r2]\n");
3393 
3394   CLEANUP();
3395 }
3396 
3397 
TEST(barriers)3398 TEST(barriers) {
3399   SETUP();
3400 
3401   // DMB
3402   COMPARE_BOTH(Dmb(SY), "dmb sy\n");
3403   COMPARE_BOTH(Dmb(ST), "dmb st\n");
3404   COMPARE_BOTH(Dmb(ISH), "dmb ish\n");
3405   COMPARE_BOTH(Dmb(ISHST), "dmb ishst\n");
3406   COMPARE_BOTH(Dmb(NSH), "dmb nsh\n");
3407   COMPARE_BOTH(Dmb(NSHST), "dmb nshst\n");
3408   COMPARE_BOTH(Dmb(OSH), "dmb osh\n");
3409   COMPARE_BOTH(Dmb(OSHST), "dmb oshst\n");
3410 
3411   // DSB
3412   COMPARE_BOTH(Dsb(SY), "dsb sy\n");
3413   COMPARE_BOTH(Dsb(ST), "dsb st\n");
3414   COMPARE_BOTH(Dsb(ISH), "dsb ish\n");
3415   COMPARE_BOTH(Dsb(ISHST), "dsb ishst\n");
3416   COMPARE_BOTH(Dsb(NSH), "dsb nsh\n");
3417   COMPARE_BOTH(Dsb(NSHST), "dsb nshst\n");
3418   COMPARE_BOTH(Dsb(OSH), "dsb osh\n");
3419   COMPARE_BOTH(Dsb(OSHST), "dsb oshst\n");
3420 
3421   // ISB
3422   COMPARE_BOTH(Isb(SY), "isb sy\n");
3423 
3424   CLEANUP();
3425 }
3426 
3427 
TEST(preloads)3428 TEST(preloads) {
3429   // Smoke test for various pld/pli forms.
3430   SETUP();
3431 
3432   // PLD immediate
3433   COMPARE_BOTH(Pld(MemOperand(r0, 0)), "pld [r0]\n");
3434   COMPARE_BOTH(Pld(MemOperand(r1, 123)), "pld [r1, #123]\n");
3435   COMPARE_BOTH(Pld(MemOperand(r4, -123)), "pld [r4, #-123]\n");
3436 
3437   COMPARE_A32(Pld(MemOperand(r7, -4095)), "pld [r7, #-4095]\n");
3438 
3439   // PLDW immediate
3440   COMPARE_BOTH(Pldw(MemOperand(r0, 0)), "pldw [r0]\n");
3441   COMPARE_BOTH(Pldw(MemOperand(r1, 123)), "pldw [r1, #123]\n");
3442   COMPARE_BOTH(Pldw(MemOperand(r4, -123)), "pldw [r4, #-123]\n");
3443 
3444   COMPARE_A32(Pldw(MemOperand(r7, -4095)), "pldw [r7, #-4095]\n");
3445 
3446   // PLD register
3447   COMPARE_BOTH(Pld(MemOperand(r0, r1)), "pld [r0, r1]\n");
3448   COMPARE_BOTH(Pld(MemOperand(r0, r1, LSL, 1)), "pld [r0, r1, lsl #1]\n");
3449 
3450   COMPARE_A32(Pld(MemOperand(r0, r1, LSL, 20)), "pld [r0, r1, lsl #20]\n");
3451 
3452   // PLDW register
3453   COMPARE_BOTH(Pldw(MemOperand(r0, r1)), "pldw [r0, r1]\n");
3454   COMPARE_BOTH(Pldw(MemOperand(r0, r1, LSL, 1)), "pldw [r0, r1, lsl #1]\n");
3455 
3456   COMPARE_A32(Pldw(MemOperand(r0, r1, LSL, 20)), "pldw [r0, r1, lsl #20]\n");
3457 
3458   // PLD literal
3459   Label pld_label;
3460   COMPARE_A32(Pld(&pld_label);, "pld [pc, #-0]\n");
3461   COMPARE_T32(Pld(&pld_label);, "pld [pc, #-0]\n");
3462   __ Bind(&pld_label);
3463 
3464   // PLI immediate
3465   COMPARE_BOTH(Pli(MemOperand(r0, 0)), "pli [r0]\n");
3466   COMPARE_BOTH(Pli(MemOperand(r1, 123)), "pli [r1, #123]\n");
3467   COMPARE_BOTH(Pli(MemOperand(r4, -123)), "pli [r4, #-123]\n");
3468 
3469   COMPARE_A32(Pli(MemOperand(r7, -4095)), "pli [r7, #-4095]\n");
3470 
3471   // PLI register
3472   COMPARE_BOTH(Pli(MemOperand(r0, r1)), "pli [r0, r1]\n");
3473   COMPARE_BOTH(Pli(MemOperand(r0, r1, LSL, 1)), "pli [r0, r1, lsl #1]\n");
3474 
3475   COMPARE_A32(Pli(MemOperand(r0, r1, LSL, 20)), "pli [r0, r1, lsl #20]\n");
3476 
3477   // PLI literal
3478   Label pli_label;
3479   COMPARE_A32(Pli(&pli_label);, "pli [pc, #-0]\n");
3480   COMPARE_T32(Pli(&pli_label);, "pli [pc, #-0]\n");
3481   __ Bind(&pli_label);
3482 
3483   CLEANUP();
3484 }
3485 
3486 
TEST(vmrs_vmsr)3487 TEST(vmrs_vmsr) {
3488   SETUP();
3489 
3490   COMPARE_BOTH(Vmsr(FPSCR, r0), "vmsr FPSCR, r0\n");
3491 
3492   COMPARE_BOTH(Vmrs(RegisterOrAPSR_nzcv(r1.GetCode()), FPSCR),
3493                "vmrs r1, FPSCR\n");
3494 
3495   COMPARE_BOTH(Vmrs(RegisterOrAPSR_nzcv(pc.GetCode()), FPSCR),
3496                "vmrs APSR_nzcv, FPSCR\n");
3497 
3498   CLEANUP();
3499 }
3500 
3501 
TEST(ldm_stm)3502 TEST(ldm_stm) {
3503   SETUP();
3504 
3505   // ldm/stm
3506   COMPARE_BOTH(Ldm(r0, NO_WRITE_BACK, RegisterList(r1)), "ldm r0, {r1}\n");
3507 
3508   COMPARE_BOTH(Ldm(r1, NO_WRITE_BACK, RegisterList(r2, r5, r9, r10)),
3509                "ldm r1, {r2,r5,r9,r10}\n");
3510 
3511   COMPARE_BOTH(Ldm(r0, WRITE_BACK, RegisterList(r1, r2)), "ldm r0!, {r1,r2}\n");
3512 
3513   COMPARE_BOTH(Stm(r1, NO_WRITE_BACK, RegisterList(r2, r5, r9, r10)),
3514                "stm r1, {r2,r5,r9,r10}\n");
3515 
3516   COMPARE_BOTH(Stm(r0, WRITE_BACK, RegisterList(r1, r2)), "stm r0!, {r1,r2}\n");
3517 
3518   // ldmda/stmda
3519   COMPARE_A32(Ldmda(r11, WRITE_BACK, RegisterList(r0, r1)),
3520               "ldmda r11!, {r0,r1}\n");
3521 
3522   COMPARE_A32(Ldmda(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3523               "ldmda r11, {r2,r3}\n");
3524 
3525   COMPARE_A32(Stmda(r11, WRITE_BACK, RegisterList(r0, r1)),
3526               "stmda r11!, {r0,r1}\n");
3527 
3528   COMPARE_A32(Stmda(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3529               "stmda r11, {r2,r3}\n");
3530 
3531   // ldmib/stmib
3532   COMPARE_A32(Ldmib(r11, WRITE_BACK, RegisterList(r0, r1)),
3533               "ldmib r11!, {r0,r1}\n");
3534 
3535   COMPARE_A32(Ldmib(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3536               "ldmib r11, {r2,r3}\n");
3537 
3538   COMPARE_A32(Stmib(r11, WRITE_BACK, RegisterList(r0, r1)),
3539               "stmib r11!, {r0,r1}\n");
3540 
3541   COMPARE_A32(Stmib(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3542               "stmib r11, {r2,r3}\n");
3543 
3544   // ldmdb/stmdb
3545   COMPARE_BOTH(Ldmdb(r11, WRITE_BACK, RegisterList(r0, r1)),
3546                "ldmdb r11!, {r0,r1}\n");
3547 
3548   COMPARE_BOTH(Ldmdb(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3549                "ldmdb r11, {r2,r3}\n");
3550 
3551   COMPARE_BOTH(Stmdb(r11, WRITE_BACK, RegisterList(r0, r1)),
3552                "stmdb r11!, {r0,r1}\n");
3553 
3554   COMPARE_BOTH(Stmdb(r11, NO_WRITE_BACK, RegisterList(r2, r3)),
3555                "stmdb r11, {r2,r3}\n");
3556 
3557   CLEANUP();
3558 }
3559 
3560 
3561 #define CHECK_T32_16(ASM, EXP) COMPARE_T32_CHECK_SIZE(ASM, EXP, 2)
3562 // For instructions inside an IT block, we need to account for the IT
3563 // instruction as well (another 16 bits).
3564 #define CHECK_T32_16_IT_BLOCK(ASM, EXP) COMPARE_T32_CHECK_SIZE(ASM, EXP, 4)
3565 
TEST(macro_assembler_T32_16bit)3566 TEST(macro_assembler_T32_16bit) {
3567   SETUP();
3568 
3569   // Allow the test to use all registers.
3570   UseScratchRegisterScope temps(&masm);
3571   temps.ExcludeAll();
3572 
3573   CHECK_T32_16(Adc(DontCare, r7, r7, r6), "adcs r7, r6\n");
3574 
3575   CHECK_T32_16_IT_BLOCK(Adc(DontCare, eq, r7, r7, r6),
3576                         "it eq\n"
3577                         "adceq r7, r6\n");
3578 
3579   CHECK_T32_16(Add(DontCare, r6, r7, 7), "adds r6, r7, #7\n");
3580 
3581   CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r6, r7, 7),
3582                         "it lt\n"
3583                         "addlt r6, r7, #7\n");
3584 
3585   CHECK_T32_16(Add(DontCare, r5, r5, 255), "adds r5, #255\n");
3586 
3587   CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r5, r5, 255),
3588                         "it lt\n"
3589                         "addlt r5, #255\n");
3590 
3591   // Make sure we select the non flag-setting version here, since
3592   // this can have two potential encodings.
3593   CHECK_T32_16(Add(DontCare, r1, r1, r2), "add r1, r2\n");
3594 
3595   CHECK_T32_16(Add(DontCare, r1, r2, r7), "adds r1, r2, r7\n");
3596 
3597   CHECK_T32_16_IT_BLOCK(Add(DontCare, lt, r1, r2, r7),
3598                         "it lt\n"
3599                         "addlt r1, r2, r7\n");
3600 
3601   CHECK_T32_16(Add(DontCare, r4, r4, r12), "add r4, ip\n");
3602 
3603   CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, r4, r4, r12),
3604                         "it eq\n"
3605                         "addeq r4, ip\n");
3606 
3607   CHECK_T32_16(Add(DontCare, r0, sp, 1020), "add r0, sp, #1020\n");
3608 
3609   CHECK_T32_16_IT_BLOCK(Add(DontCare, ge, r0, sp, 1020),
3610                         "it ge\n"
3611                         "addge r0, sp, #1020\n");
3612 
3613   // The equivalent inside an IT block is deprecated.
3614   CHECK_T32_16(Add(DontCare, sp, sp, 508), "add sp, #508\n");
3615 
3616   CHECK_T32_16(Add(DontCare, r7, sp, r7), "add r7, sp, r7\n");
3617 
3618   CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, r7, sp, r7),
3619                         "it eq\n"
3620                         "addeq r7, sp, r7\n");
3621 
3622   CHECK_T32_16(Add(DontCare, sp, sp, r10), "add sp, r10\n");
3623 
3624   CHECK_T32_16_IT_BLOCK(Add(DontCare, eq, sp, sp, r10),
3625                         "it eq\n"
3626                         "addeq sp, r10\n");
3627 
3628   CHECK_T32_16(And(DontCare, r7, r7, r6), "ands r7, r6\n");
3629 
3630   CHECK_T32_16_IT_BLOCK(And(DontCare, eq, r7, r7, r6),
3631                         "it eq\n"
3632                         "andeq r7, r6\n");
3633 
3634   CHECK_T32_16(Asr(DontCare, r0, r1, 32), "asrs r0, r1, #32\n");
3635 
3636   CHECK_T32_16_IT_BLOCK(Asr(DontCare, eq, r0, r1, 32),
3637                         "it eq\n"
3638                         "asreq r0, r1, #32\n");
3639 
3640   CHECK_T32_16(Asr(DontCare, r0, r0, r1), "asrs r0, r1\n");
3641 
3642   CHECK_T32_16_IT_BLOCK(Asr(DontCare, eq, r0, r0, r1),
3643                         "it eq\n"
3644                         "asreq r0, r1\n");
3645 
3646   CHECK_T32_16(Bic(DontCare, r7, r7, r6), "bics r7, r6\n");
3647 
3648   CHECK_T32_16_IT_BLOCK(Bic(DontCare, eq, r7, r7, r6),
3649                         "it eq\n"
3650                         "biceq r7, r6\n");
3651 
3652   CHECK_T32_16(Eor(DontCare, r7, r7, r6), "eors r7, r6\n");
3653 
3654   CHECK_T32_16_IT_BLOCK(Eor(DontCare, eq, r7, r7, r6),
3655                         "it eq\n"
3656                         "eoreq r7, r6\n");
3657 
3658   CHECK_T32_16(Lsl(DontCare, r0, r1, 31), "lsls r0, r1, #31\n");
3659 
3660   CHECK_T32_16_IT_BLOCK(Lsl(DontCare, eq, r0, r1, 31),
3661                         "it eq\n"
3662                         "lsleq r0, r1, #31\n");
3663 
3664   CHECK_T32_16(Lsl(DontCare, r0, r0, r1), "lsls r0, r1\n");
3665 
3666   CHECK_T32_16_IT_BLOCK(Lsl(DontCare, eq, r0, r0, r1),
3667                         "it eq\n"
3668                         "lsleq r0, r1\n");
3669 
3670   CHECK_T32_16(Lsr(DontCare, r0, r1, 32), "lsrs r0, r1, #32\n");
3671 
3672   CHECK_T32_16_IT_BLOCK(Lsr(DontCare, eq, r0, r1, 32),
3673                         "it eq\n"
3674                         "lsreq r0, r1, #32\n");
3675 
3676   CHECK_T32_16(Lsr(DontCare, r0, r0, r1), "lsrs r0, r1\n");
3677 
3678   CHECK_T32_16_IT_BLOCK(Lsr(DontCare, eq, r0, r0, r1),
3679                         "it eq\n"
3680                         "lsreq r0, r1\n");
3681 
3682   CHECK_T32_16(Mov(DontCare, r7, 255), "movs r7, #255\n");
3683 
3684   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, 255),
3685                         "it eq\n"
3686                         "moveq r7, #255\n");
3687 
3688   CHECK_T32_16(Mov(DontCare, r9, r8), "mov r9, r8\n");
3689 
3690   // Check that we don't try to pick the MOVS register-shifted register variant.
3691   CHECK_T32_16(Mov(DontCare, r5, r6), "mov r5, r6\n");
3692 
3693   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r9, r8),
3694                         "it eq\n"
3695                         "moveq r9, r8\n");
3696 
3697   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, ASR, 1)), "asrs r5, r6, #1\n");
3698 
3699   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, ASR, 32)), "asrs r5, r6, #32\n");
3700 
3701   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSR, 1)), "lsrs r5, r6, #1\n");
3702 
3703   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSR, 32)), "lsrs r5, r6, #32\n");
3704 
3705   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSL, 1)), "lsls r5, r6, #1\n");
3706 
3707   CHECK_T32_16(Mov(DontCare, r5, Operand(r6, LSL, 31)), "lsls r5, r6, #31\n");
3708 
3709   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, ASR, 1)),
3710                         "it eq\n"
3711                         "asreq r5, r6, #1\n");
3712 
3713   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, ASR, 32)),
3714                         "it eq\n"
3715                         "asreq r5, r6, #32\n");
3716 
3717   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSR, 1)),
3718                         "it eq\n"
3719                         "lsreq r5, r6, #1\n");
3720 
3721   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSR, 32)),
3722                         "it eq\n"
3723                         "lsreq r5, r6, #32\n");
3724 
3725   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSL, 1)),
3726                         "it eq\n"
3727                         "lsleq r5, r6, #1\n");
3728 
3729   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r5, Operand(r6, LSL, 31)),
3730                         "it eq\n"
3731                         "lsleq r5, r6, #31\n");
3732 
3733   CHECK_T32_16(Mov(DontCare, r7, Operand(r7, ASR, r6)), "asrs r7, r6\n");
3734 
3735   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, ASR, r6)),
3736                         "it eq\n"
3737                         "asreq r7, r6\n");
3738 
3739   CHECK_T32_16(Mov(DontCare, r7, Operand(r7, LSR, r6)), "lsrs r7, r6\n");
3740 
3741   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, LSR, r6)),
3742                         "it eq\n"
3743                         "lsreq r7, r6\n");
3744 
3745   CHECK_T32_16(Mov(DontCare, r7, Operand(r7, LSL, r6)), "lsls r7, r6\n");
3746 
3747   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, LSL, r6)),
3748                         "it eq\n"
3749                         "lsleq r7, r6\n");
3750 
3751   CHECK_T32_16(Mov(DontCare, r7, Operand(r7, ROR, r6)), "rors r7, r6\n");
3752 
3753   CHECK_T32_16_IT_BLOCK(Mov(DontCare, eq, r7, Operand(r7, ROR, r6)),
3754                         "it eq\n"
3755                         "roreq r7, r6\n");
3756 
3757   CHECK_T32_16(Mul(DontCare, r0, r1, r0), "muls r0, r1, r0\n");
3758 
3759   CHECK_T32_16_IT_BLOCK(Mul(DontCare, eq, r0, r1, r0),
3760                         "it eq\n"
3761                         "muleq r0, r1, r0\n");
3762 
3763   CHECK_T32_16(Mvn(DontCare, r6, r7), "mvns r6, r7\n");
3764 
3765   CHECK_T32_16_IT_BLOCK(Mvn(DontCare, eq, r6, r7),
3766                         "it eq\n"
3767                         "mvneq r6, r7\n");
3768 
3769   CHECK_T32_16(Orr(DontCare, r7, r7, r6), "orrs r7, r6\n");
3770 
3771   CHECK_T32_16_IT_BLOCK(Orr(DontCare, eq, r7, r7, r6),
3772                         "it eq\n"
3773                         "orreq r7, r6\n");
3774 
3775   CHECK_T32_16(Ror(DontCare, r0, r0, r1), "rors r0, r1\n");
3776 
3777   CHECK_T32_16_IT_BLOCK(Ror(DontCare, eq, r0, r0, r1),
3778                         "it eq\n"
3779                         "roreq r0, r1\n");
3780 
3781   CHECK_T32_16(Rsb(DontCare, r7, r6, 0), "rsbs r7, r6, #0\n");
3782 
3783   CHECK_T32_16_IT_BLOCK(Rsb(DontCare, eq, r7, r6, 0),
3784                         "it eq\n"
3785                         "rsbeq r7, r6, #0\n");
3786 
3787   CHECK_T32_16(Sbc(DontCare, r7, r7, r6), "sbcs r7, r6\n");
3788 
3789   CHECK_T32_16_IT_BLOCK(Sbc(DontCare, eq, r7, r7, r6),
3790                         "it eq\n"
3791                         "sbceq r7, r6\n");
3792 
3793   CHECK_T32_16(Sub(DontCare, r6, r7, 7), "subs r6, r7, #7\n");
3794 
3795   CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r6, r7, 7),
3796                         "it lt\n"
3797                         "sublt r6, r7, #7\n");
3798 
3799   CHECK_T32_16(Sub(DontCare, r5, r5, 255), "subs r5, #255\n");
3800 
3801   CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r5, r5, 255),
3802                         "it lt\n"
3803                         "sublt r5, #255\n");
3804 
3805   CHECK_T32_16(Sub(DontCare, r1, r2, r7), "subs r1, r2, r7\n");
3806 
3807   CHECK_T32_16_IT_BLOCK(Sub(DontCare, lt, r1, r2, r7),
3808                         "it lt\n"
3809                         "sublt r1, r2, r7\n");
3810 
3811   // The equivalent inside an IT block is deprecated.
3812   CHECK_T32_16(Sub(DontCare, sp, sp, 508), "sub sp, #508\n");
3813 
3814   // Generate SUBS for ADD.
3815   CHECK_T32_16(Add(DontCare, r0, r1, -1), "subs r0, r1, #1\n");
3816 
3817   CHECK_T32_16(Add(DontCare, r0, r1, -7), "subs r0, r1, #7\n");
3818 
3819   CHECK_T32_16(Add(DontCare, r6, r6, -1), "subs r6, #1\n");
3820 
3821   CHECK_T32_16(Add(DontCare, r6, r6, -255), "subs r6, #255\n");
3822 
3823   // Generate ADDS for SUB.
3824   CHECK_T32_16(Sub(DontCare, r0, r1, -1), "adds r0, r1, #1\n");
3825 
3826   CHECK_T32_16(Sub(DontCare, r0, r1, -7), "adds r0, r1, #7\n");
3827 
3828   CHECK_T32_16(Sub(DontCare, r6, r6, -1), "adds r6, #1\n");
3829 
3830   CHECK_T32_16(Sub(DontCare, r6, r6, -255), "adds r6, #255\n");
3831 
3832   // Check that we don't change the opcode for INT_MIN.
3833   COMPARE_T32(Add(DontCare, r6, r6, 0x80000000), "add r6, #2147483648\n");
3834 
3835   COMPARE_T32(Sub(DontCare, r6, r6, 0x80000000), "sub r6, #2147483648\n");
3836 
3837   CLEANUP();
3838 }
3839 #undef CHECK_T32_16
3840 #undef CHECK_T32_16_IT_BLOCK
3841 
TEST(nop_code)3842 TEST(nop_code) {
3843   SETUP();
3844 
3845   COMPARE_BOTH(Nop(), "nop\n");
3846 
3847   COMPARE_BOTH(And(r0, r0, r0), "");
3848   COMPARE_BOTH(And(DontCare, r0, r0, r0), "");
3849 
3850   COMPARE_BOTH(Mov(r0, r0), "");
3851   COMPARE_BOTH(Mov(DontCare, r0, r0), "");
3852 
3853   COMPARE_BOTH(Orr(r0, r0, r0), "");
3854   COMPARE_BOTH(Orr(DontCare, r0, r0, r0), "");
3855 
3856   CLEANUP();
3857 }
3858 
3859 
TEST(big_add_sub)3860 TEST(big_add_sub) {
3861   SETUP();
3862 
3863   COMPARE_A32(Add(r0, r1, 0x4321),
3864               "add r0, r1, #33\n"
3865               "add r0, #17152\n");
3866   COMPARE_T32(Add(r0, r1, 0x4321),
3867               "add r0, r1, #801\n"
3868               "add r0, #16384\n");
3869   COMPARE_BOTH(Add(r0, r1, 0x432100),
3870                "add r0, r1, #8448\n"
3871                "add r0, #4390912\n");
3872   COMPARE_BOTH(Add(r0, r1, 0x43000210),
3873                "add r0, r1, #528\n"
3874                "add r0, #1124073472\n");
3875   COMPARE_BOTH(Add(r0, r1, 0x30c00210),
3876                "add r0, r1, #528\n"
3877                "add r0, #817889280\n");
3878   COMPARE_BOTH(Add(r0, r1, 0x43000021),
3879                "add r0, r1, #33\n"
3880                "add r0, #1124073472\n");
3881   COMPARE_T32(Add(r0, r1, 0x54321),
3882               "add r0, r1, #801\n"
3883               "add r0, #344064\n");
3884   COMPARE_T32(Add(r0, r1, 0x54000321),
3885               "add r0, r1, #801\n"
3886               "add r0, #1409286144\n");
3887 
3888   COMPARE_A32(Sub(r0, r1, 0x4321),
3889               "sub r0, r1, #33\n"
3890               "sub r0, #17152\n");
3891   COMPARE_T32(Sub(r0, r1, 0x4321),
3892               "sub r0, r1, #801\n"
3893               "sub r0, #16384\n");
3894   COMPARE_BOTH(Sub(r0, r1, 0x432100),
3895                "sub r0, r1, #8448\n"
3896                "sub r0, #4390912\n");
3897   COMPARE_BOTH(Sub(r0, r1, 0x43000210),
3898                "sub r0, r1, #528\n"
3899                "sub r0, #1124073472\n");
3900   COMPARE_BOTH(Sub(r0, r1, 0x30c00210),
3901                "sub r0, r1, #528\n"
3902                "sub r0, #817889280\n");
3903   COMPARE_BOTH(Sub(r0, r1, 0x43000021),
3904                "sub r0, r1, #33\n"
3905                "sub r0, #1124073472\n");
3906   COMPARE_T32(Sub(r0, r1, 0x54321),
3907               "sub r0, r1, #801\n"
3908               "sub r0, #344064\n");
3909   COMPARE_T32(Sub(r0, r1, 0x54000321),
3910               "sub r0, r1, #801\n"
3911               "sub r0, #1409286144\n");
3912 
3913   CLEANUP();
3914 }
3915 
3916 }  // namespace aarch32
3917 }  // namespace vixl
3918