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