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