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