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