1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
29 #include <cinttypes>
30 #include <cstdlib>
31 
32 // The C++ style guide recommends using <re2> instead of <regex>. However, the
33 // former isn't available in V8.
34 #include <regex>  // NOLINT(build/c++11)
35 
36 #include "src/base/numbers/double.h"
37 #include "src/codegen/assembler-inl.h"
38 #include "src/codegen/macro-assembler.h"
39 #include "src/debug/debug.h"
40 #include "src/diagnostics/disasm.h"
41 #include "src/diagnostics/disassembler.h"
42 #include "src/execution/frames-inl.h"
43 #include "src/init/v8.h"
44 #include "src/objects/objects-inl.h"
45 #include "src/utils/boxed-float.h"
46 #include "test/cctest/cctest.h"
47 
48 namespace v8 {
49 namespace internal {
50 
51 enum UseRegex { kRawString, kRegexString };
52 
53 template <typename... S>
DisassembleAndCompare(byte * begin,UseRegex use_regex,S...expected_strings)54 bool DisassembleAndCompare(byte* begin, UseRegex use_regex,
55                            S... expected_strings) {
56   disasm::NameConverter converter;
57   disasm::Disassembler disasm(converter);
58   base::EmbeddedVector<char, 128> buffer;
59 
60   std::vector<std::string> expected_disassembly = {expected_strings...};
61   size_t n_expected = expected_disassembly.size();
62   byte* end = begin + (n_expected * kInstrSize);
63 
64   std::vector<std::string> disassembly;
65   for (byte* pc = begin; pc < end;) {
66     pc += disasm.InstructionDecode(buffer, pc);
67     disassembly.emplace_back(buffer.begin());
68   }
69 
70   bool test_passed = true;
71 
72   for (size_t i = 0; i < disassembly.size(); i++) {
73     if (use_regex == kRawString) {
74       if (expected_disassembly[i] != disassembly[i]) {
75         fprintf(stderr,
76                 "expected: \n"
77                 "%s\n"
78                 "disassembled: \n"
79                 "%s\n\n",
80                 expected_disassembly[i].c_str(), disassembly[i].c_str());
81         test_passed = false;
82       }
83     } else {
84       DCHECK_EQ(use_regex, kRegexString);
85       if (!std::regex_match(disassembly[i],
86                             std::regex(expected_disassembly[i]))) {
87         fprintf(stderr,
88                 "expected (regex): \n"
89                 "%s\n"
90                 "disassembled: \n"
91                 "%s\n\n",
92                 expected_disassembly[i].c_str(), disassembly[i].c_str());
93         test_passed = false;
94       }
95     }
96   }
97 
98   // Fail after printing expected disassembly if we expected a different number
99   // of instructions.
100   if (disassembly.size() != expected_disassembly.size()) {
101     return false;
102   }
103 
104   return test_passed;
105 }
106 
107 // Set up V8 to a state where we can at least run the assembler and
108 // disassembler. Declare the variables and allocate the data structures used
109 // in the rest of the macros.
110 #define SET_UP()                                             \
111   CcTest::InitializeVM();                                    \
112   Isolate* isolate = CcTest::i_isolate();                    \
113   HandleScope scope(isolate);                                \
114   byte* buffer = reinterpret_cast<byte*>(malloc(4 * 1024));  \
115   Assembler assm(AssemblerOptions{},                         \
116                  ExternalAssemblerBuffer(buffer, 4 * 1024)); \
117   bool failure = false;
118 
119 // This macro assembles one instruction using the preallocated assembler and
120 // disassembles the generated instruction, comparing the output to the expected
121 // value. If the comparison fails an error message is printed, but the test
122 // continues to run until the end.
123 #define BASE_COMPARE(asm_, use_regex, ...)                             \
124   {                                                                    \
125     int pc_offset = assm.pc_offset();                                  \
126     byte* progcounter = &buffer[pc_offset];                            \
127     assm.asm_;                                                         \
128     if (!DisassembleAndCompare(progcounter, use_regex, __VA_ARGS__)) { \
129       failure = true;                                                  \
130     }                                                                  \
131   }
132 
133 #define COMPARE(asm_, ...) BASE_COMPARE(asm_, kRawString, __VA_ARGS__)
134 
135 #define COMPARE_REGEX(asm_, ...) BASE_COMPARE(asm_, kRegexString, __VA_ARGS__)
136 
137 // Force emission of any pending literals into a pool.
138 #define EMIT_PENDING_LITERALS() \
139   assm.CheckConstPool(true, false)
140 
141 
142 // Verify that all invocations of the COMPARE macro passed successfully.
143 // Exit with a failure if at least one of the tests failed.
144 #define VERIFY_RUN()                           \
145   if (failure) {                               \
146     FATAL("ARM Disassembler tests failed.\n"); \
147   }
148 
149 // clang-format off
150 
151 
TEST(Type0)152 TEST(Type0) {
153   SET_UP();
154 
155   COMPARE(and_(r0, r1, Operand(r2)),
156           "e0010002       and r0, r1, r2");
157   COMPARE(and_(r1, r2, Operand(r3), LeaveCC),
158           "e0021003       and r1, r2, r3");
159   COMPARE(and_(r2, r3, Operand(r4), SetCC),
160           "e0132004       ands r2, r3, r4");
161   COMPARE(and_(r3, r4, Operand(r5), LeaveCC, eq),
162           "00043005       andeq r3, r4, r5");
163 
164   COMPARE(eor(r4, r5, Operand(r6, LSL, 0)),
165           "e0254006       eor r4, r5, r6");
166   COMPARE(eor(r4, r5, Operand(r7, LSL, 1), SetCC),
167           "e0354087       eors r4, r5, r7, lsl #1");
168   COMPARE(eor(r4, r5, Operand(r8, LSL, 2), LeaveCC, ne),
169           "10254108       eorne r4, r5, r8, lsl #2");
170   COMPARE(eor(r4, r5, Operand(r9, LSL, 3), SetCC, cs),
171           "20354189       eorcss r4, r5, r9, lsl #3");
172 
173   COMPARE(sub(r5, r6, Operand(r10, LSL, 31), LeaveCC, hs),
174           "20465f8a       subcs r5, r6, r10, lsl #31");
175   COMPARE(sub(r5, r6, Operand(r10, LSL, 30), SetCC, cc),
176           "30565f0a       subccs r5, r6, r10, lsl #30");
177   COMPARE(sub(r5, r6, Operand(r10, LSL, 24), LeaveCC, lo),
178           "30465c0a       subcc r5, r6, r10, lsl #24");
179   COMPARE(sub(r5, r6, Operand(r10, LSL, 16), SetCC, mi),
180           "4056580a       submis r5, r6, r10, lsl #16");
181 
182   COMPARE(rsb(r6, r7, Operand(fp)),
183           "e067600b       rsb r6, r7, fp");
184   COMPARE(rsb(r6, r7, Operand(fp, LSR, 1)),
185           "e06760ab       rsb r6, r7, fp, lsr #1");
186   COMPARE(rsb(r6, r7, Operand(fp, LSR, 0), SetCC),
187           "e077602b       rsbs r6, r7, fp, lsr #32");
188   COMPARE(rsb(r6, r7, Operand(fp, LSR, 31), LeaveCC, pl),
189           "50676fab       rsbpl r6, r7, fp, lsr #31");
190 
191   COMPARE(add(r7, r8, Operand(ip, ASR, 1)),
192           "e08870cc       add r7, r8, ip, asr #1");
193   COMPARE(add(r7, r8, Operand(ip, ASR, 0)),
194           "e088704c       add r7, r8, ip, asr #32");
195   COMPARE(add(r7, r8, Operand(ip), SetCC),
196           "e098700c       adds r7, r8, ip");
197   COMPARE(add(r7, r8, Operand(ip, ASR, 31), SetCC, vs),
198           "60987fcc       addvss r7, r8, ip, asr #31");
199 
200   COMPARE(adc(r7, fp, Operand(ip, ASR, 5)),
201           "e0ab72cc       adc r7, fp, ip, asr #5");
202   COMPARE(adc(r4, ip, Operand(ip, ASR, 1), LeaveCC, vc),
203           "70ac40cc       adcvc r4, ip, ip, asr #1");
204   COMPARE(adc(r5, sp, Operand(ip), SetCC),
205           "e0bd500c       adcs r5, sp, ip");
206   COMPARE(adc(r8, lr, Operand(ip, ASR, 31), SetCC, vc),
207           "70be8fcc       adcvcs r8, lr, ip, asr #31");
208 
209   COMPARE(sbc(r7, r1, Operand(ip, ROR, 1), LeaveCC, hi),
210           "80c170ec       sbchi r7, r1, ip, ror #1");
211   COMPARE(sbc(r7, r9, Operand(ip, ROR, 4)),
212           "e0c9726c       sbc r7, r9, ip, ror #4");
213   COMPARE(sbc(r7, r10, Operand(ip), SetCC),
214           "e0da700c       sbcs r7, r10, ip");
215   COMPARE(sbc(r7, ip, Operand(ip, ROR, 31), SetCC, hi),
216           "80dc7fec       sbchis r7, ip, ip, ror #31");
217 
218   COMPARE(rsc(r7, r8, Operand(ip, LSL, r0)),
219           "e0e8701c       rsc r7, r8, ip, lsl r0");
220   COMPARE(rsc(r7, r8, Operand(ip, LSL, r1)),
221           "e0e8711c       rsc r7, r8, ip, lsl r1");
222   COMPARE(rsc(r7, r8, Operand(ip), SetCC),
223           "e0f8700c       rscs r7, r8, ip");
224   COMPARE(rsc(r7, r8, Operand(ip, LSL, r3), SetCC, ls),
225           "90f8731c       rsclss r7, r8, ip, lsl r3");
226 
227   COMPARE(tst(r7, Operand(r5, ASR, ip), ge),
228           "a1170c55       tstge r7, r5, asr ip");
229   COMPARE(tst(r7, Operand(r6, ASR, sp)),
230           "e1170d56       tst r7, r6, asr sp");
231   COMPARE(tst(r7, Operand(r7), ge),
232           "a1170007       tstge r7, r7");
233   COMPARE(tst(r7, Operand(r8, ASR, fp), ge),
234           "a1170b58       tstge r7, r8, asr fp");
235 
236   COMPARE(teq(r7, Operand(r5, ROR, r0), lt),
237           "b1370075       teqlt r7, r5, ror r0");
238   COMPARE(teq(r7, Operand(r6, ROR, lr)),
239           "e1370e76       teq r7, r6, ror lr");
240   COMPARE(teq(r7, Operand(r7), lt),
241           "b1370007       teqlt r7, r7");
242   COMPARE(teq(r7, Operand(r8, ROR, r1)),
243           "e1370178       teq r7, r8, ror r1");
244 
245   COMPARE(cmp(r7, Operand(r4)),
246           "e1570004       cmp r7, r4");
247   COMPARE(cmp(r7, Operand(r6, LSL, 1), gt),
248           "c1570086       cmpgt r7, r6, lsl #1");
249   COMPARE(cmp(r7, Operand(r8, LSR, 3), gt),
250           "c15701a8       cmpgt r7, r8, lsr #3");
251   COMPARE(cmp(r7, Operand(r8, ASR, 19)),
252           "e15709c8       cmp r7, r8, asr #19");
253 
254   COMPARE(cmn(r0, Operand(r4)),
255           "e1700004       cmn r0, r4");
256   COMPARE(cmn(r1, Operand(r6, ROR, 1)),
257           "e17100e6       cmn r1, r6, ror #1");
258   COMPARE(cmn(r2, Operand(r8)),
259           "e1720008       cmn r2, r8");
260   COMPARE(cmn(r3, Operand(fp), le),
261           "d173000b       cmnle r3, fp");
262 
263   COMPARE(orr(r7, r8, Operand(lr), LeaveCC, al),
264           "e188700e       orr r7, r8, lr");
265   COMPARE(orr(r7, r8, Operand(fp)),
266           "e188700b       orr r7, r8, fp");
267   COMPARE(orr(r7, r8, Operand(sp), SetCC),
268           "e198700d       orrs r7, r8, sp");
269   COMPARE(orr(r7, r8, Operand(ip), SetCC, al),
270           "e198700c       orrs r7, r8, ip");
271 
272   COMPARE(mov(r0, Operand(r1), LeaveCC, eq),
273           "01a00001       moveq r0, r1");
274   COMPARE(mov(r0, Operand(r2)),
275           "e1a00002       mov r0, r2");
276   COMPARE(mov(r0, Operand(r3), SetCC),
277           "e1b00003       movs r0, r3");
278   COMPARE(mov(r0, Operand(r4), SetCC, pl),
279           "51b00004       movpls r0, r4");
280 
281   COMPARE(bic(r0, lr, Operand(r1), LeaveCC, vs),
282           "61ce0001       bicvs r0, lr, r1");
283   COMPARE(bic(r0, r9, Operand(r2), LeaveCC, vc),
284           "71c90002       bicvc r0, r9, r2");
285   COMPARE(bic(r0, r5, Operand(r3), SetCC),
286           "e1d50003       bics r0, r5, r3");
287   COMPARE(bic(r0, r1, Operand(r4), SetCC, pl),
288           "51d10004       bicpls r0, r1, r4");
289 
290   COMPARE(mvn(r10, Operand(r1)),
291           "e1e0a001       mvn r10, r1");
292   COMPARE(mvn(r9, Operand(r2)),
293           "e1e09002       mvn r9, r2");
294   COMPARE(mvn(r0, Operand(r3), SetCC),
295           "e1f00003       mvns r0, r3");
296   COMPARE(mvn(r5, Operand(r4), SetCC, cc),
297           "31f05004       mvnccs r5, r4");
298 
299   // Instructions autotransformed by the assembler.
300   // mov -> mvn.
301   COMPARE(mov(r3, Operand(-1), LeaveCC, al),
302           "e3e03000       mvn r3, #0");
303   COMPARE(mov(r4, Operand(-2), SetCC, al),
304           "e3f04001       mvns r4, #1");
305   COMPARE(mov(r5, Operand(0x0FFFFFF0), SetCC, ne),
306           "13f052ff       mvnnes r5, #-268435441");
307   COMPARE(mov(r6, Operand(-1), LeaveCC, ne),
308           "13e06000       mvnne r6, #0");
309 
310   // mvn -> mov.
311   COMPARE(mvn(r3, Operand(-1), LeaveCC, al),
312           "e3a03000       mov r3, #0");
313   COMPARE(mvn(r4, Operand(-2), SetCC, al),
314           "e3b04001       movs r4, #1");
315   COMPARE(mvn(r5, Operand(0x0FFFFFF0), SetCC, ne),
316           "13b052ff       movnes r5, #-268435441");
317   COMPARE(mvn(r6, Operand(-1), LeaveCC, ne),
318           "13a06000       movne r6, #0");
319 
320   // mov -> movw.
321   if (CpuFeatures::IsSupported(ARMv7)) {
322     COMPARE(mov(r5, Operand(0x01234), LeaveCC, ne),
323             "13015234       movwne r5, #4660");
324     COMPARE(eor(r5, r4, Operand(0x1234), LeaveCC, ne),
325             "13015234       movwne r5, #4660",
326             "10245005       eorne r5, r4, r5");
327     // Movw can't do setcc, so first move to r5, then the following instruction
328     // sets the flags. Mov immediate with setcc is pretty strange anyway.
329     COMPARE(mov(r5, Operand(0x01234), SetCC, ne),
330             "13015234       movwne r5, #4660",
331             "11b05005       movnes r5, r5");
332     // Emit a literal pool now, otherwise this could be dumped later, in the
333     // middle of a different test.
334     EMIT_PENDING_LITERALS();
335 
336     // The eor does the setcc so we get a movw here.
337     COMPARE(eor(r5, r4, Operand(0x1234), SetCC, ne),
338             "13015234       movwne r5, #4660",
339             "10345005       eornes r5, r4, r5");
340 
341     COMPARE(movt(r5, 0x4321, ne),
342             "13445321       movtne r5, #17185");
343     COMPARE(movw(r5, 0xABCD, eq),
344             "030a5bcd       movweq r5, #43981");
345   }
346 
347   // Eor doesn't have an eor-negative variant, but we can do an mvn followed by
348   // an eor to get the same effect.
349   COMPARE(eor(r5, r4, Operand(0xFFFFFF34), SetCC, ne),
350           "13e050cb       mvnne r5, #203",
351           "10345005       eornes r5, r4, r5");
352 
353   // and <-> bic.
354   COMPARE(and_(r3, r5, Operand(0xFC03FFFF)),
355           "e3c537ff       bic r3, r5, #66846720");
356   COMPARE(bic(r3, r5, Operand(0xFC03FFFF)),
357           "e20537ff       and r3, r5, #66846720");
358 
359   // sub <-> add.
360   COMPARE(add(r3, r5, Operand(-1024)),
361           "e2453b01       sub r3, r5, #1024");
362   COMPARE(sub(r3, r5, Operand(-1024)),
363           "e2853b01       add r3, r5, #1024");
364 
365   // cmp <-> cmn.
366   COMPARE(cmp(r3, Operand(-1024)),
367           "e3730b01       cmn r3, #1024");
368   COMPARE(cmn(r3, Operand(-1024)),
369           "e3530b01       cmp r3, #1024");
370 
371   // Miscellaneous instructions encoded as type 0.
372   COMPARE(blx(ip),
373           "e12fff3c       blx ip");
374   COMPARE(bkpt(0),
375           "e1200070       bkpt 0");
376   COMPARE(bkpt(0xFFFF),
377           "e12fff7f       bkpt 65535");
378   COMPARE(clz(r6, r7),
379           "e16f6f17       clz r6, r7");
380 
381   VERIFY_RUN();
382 }
383 
384 
TEST(Type1)385 TEST(Type1) {
386   SET_UP();
387 
388   COMPARE(and_(r0, r1, Operand(0x00000000)),
389           "e2010000       and r0, r1, #0");
390   COMPARE(and_(r1, r2, Operand(0x00000001), LeaveCC),
391           "e2021001       and r1, r2, #1");
392   COMPARE(and_(r2, r3, Operand(0x00000010), SetCC),
393           "e2132010       ands r2, r3, #16");
394   COMPARE(and_(r3, r4, Operand(0x00000100), LeaveCC, eq),
395           "02043c01       andeq r3, r4, #256");
396   COMPARE(and_(r4, r5, Operand(0x00001000), SetCC, ne),
397           "12154a01       andnes r4, r5, #4096");
398 
399   COMPARE(eor(r4, r5, Operand(0x00001000)),
400           "e2254a01       eor r4, r5, #4096");
401   COMPARE(eor(r4, r4, Operand(0x00010000), LeaveCC),
402           "e2244801       eor r4, r4, #65536");
403   COMPARE(eor(r4, r3, Operand(0x00100000), SetCC),
404           "e2334601       eors r4, r3, #1048576");
405   COMPARE(eor(r4, r2, Operand(0x01000000), LeaveCC, cs),
406           "22224401       eorcs r4, r2, #16777216");
407   COMPARE(eor(r4, r1, Operand(0x10000000), SetCC, cc),
408           "32314201       eorccs r4, r1, #268435456");
409 
410   VERIFY_RUN();
411 }
412 
413 
TEST(Type3)414 TEST(Type3) {
415   SET_UP();
416 
417   if (CpuFeatures::IsSupported(ARMv7)) {
418     CpuFeatureScope scope(&assm, ARMv7);
419     COMPARE(ubfx(r0, r1, 5, 10),
420             "e7e902d1       ubfx r0, r1, #5, #10");
421     COMPARE(ubfx(r1, r0, 5, 10),
422             "e7e912d0       ubfx r1, r0, #5, #10");
423     COMPARE(ubfx(r0, r1, 31, 1),
424             "e7e00fd1       ubfx r0, r1, #31, #1");
425     COMPARE(ubfx(r1, r0, 31, 1),
426             "e7e01fd0       ubfx r1, r0, #31, #1");
427 
428     COMPARE(sbfx(r0, r1, 5, 10),
429             "e7a902d1       sbfx r0, r1, #5, #10");
430     COMPARE(sbfx(r1, r0, 5, 10),
431             "e7a912d0       sbfx r1, r0, #5, #10");
432     COMPARE(sbfx(r0, r1, 31, 1),
433             "e7a00fd1       sbfx r0, r1, #31, #1");
434     COMPARE(sbfx(r1, r0, 31, 1),
435             "e7a01fd0       sbfx r1, r0, #31, #1");
436 
437     COMPARE(bfc(r0, 5, 10),
438             "e7ce029f       bfc r0, #5, #10");
439     COMPARE(bfc(r1, 5, 10),
440             "e7ce129f       bfc r1, #5, #10");
441     COMPARE(bfc(r0, 31, 1),
442             "e7df0f9f       bfc r0, #31, #1");
443     COMPARE(bfc(r1, 31, 1),
444             "e7df1f9f       bfc r1, #31, #1");
445 
446     COMPARE(bfi(r0, r1, 5, 10),
447             "e7ce0291       bfi r0, r1, #5, #10");
448     COMPARE(bfi(r1, r0, 5, 10),
449             "e7ce1290       bfi r1, r0, #5, #10");
450     COMPARE(bfi(r0, r1, 31, 1),
451             "e7df0f91       bfi r0, r1, #31, #1");
452     COMPARE(bfi(r1, r0, 31, 1),
453             "e7df1f90       bfi r1, r0, #31, #1");
454 
455     COMPARE(pkhbt(r3, r4, Operand(r5, LSL, 17)),
456             "e6843895       pkhbt r3, r4, r5, lsl #17");
457     COMPARE(pkhtb(r3, r4, Operand(r5, ASR, 17)),
458             "e68438d5       pkhtb r3, r4, r5, asr #17");
459 
460     COMPARE(sxtb(r1, r7, 0, eq), "06af1077       sxtbeq r1, r7");
461     COMPARE(sxtb(r0, r0, 8, ne), "16af0470       sxtbne r0, r0, ror #8");
462     COMPARE(sxtb(r9, r10, 16), "e6af987a       sxtb r9, r10, ror #16");
463     COMPARE(sxtb(r4, r3, 24), "e6af4c73       sxtb r4, r3, ror #24");
464 
465     COMPARE(sxtab(r3, r4, r5), "e6a43075       sxtab r3, r4, r5");
466 
467     COMPARE(sxth(r5, r0), "e6bf5070       sxth r5, r0");
468     COMPARE(sxth(r5, r9, 8), "e6bf5479       sxth r5, r9, ror #8");
469     COMPARE(sxth(r5, r9, 16, hi), "86bf5879       sxthhi r5, r9, ror #16");
470     COMPARE(sxth(r8, r9, 24, cc), "36bf8c79       sxthcc r8, r9, ror #24");
471 
472     COMPARE(sxtah(r3, r4, r5, 16), "e6b43875       sxtah r3, r4, r5, ror #16");
473 
474     COMPARE(uxtb(r9, r10), "e6ef907a       uxtb r9, r10");
475     COMPARE(uxtb(r3, r4, 8), "e6ef3474       uxtb r3, r4, ror #8");
476 
477     COMPARE(uxtab(r3, r4, r5, 8), "e6e43475       uxtab r3, r4, r5, ror #8");
478 
479     COMPARE(uxtb16(r3, r4, 8), "e6cf3474       uxtb16 r3, r4, ror #8");
480 
481     COMPARE(uxth(r9, r10), "e6ff907a       uxth r9, r10");
482     COMPARE(uxth(r3, r4, 8), "e6ff3474       uxth r3, r4, ror #8");
483 
484     COMPARE(uxtah(r3, r4, r5, 24), "e6f43c75       uxtah r3, r4, r5, ror #24");
485 
486     COMPARE(rbit(r1, r2), "e6ff1f32       rbit r1, r2");
487     COMPARE(rbit(r10, ip), "e6ffaf3c       rbit r10, ip");
488 
489     COMPARE(rev(r1, r2), "e6bf1f32       rev r1, r2");
490     COMPARE(rev(r10, ip), "e6bfaf3c       rev r10, ip");
491   }
492 
493   COMPARE(usat(r0, 1, Operand(r1)),
494           "e6e10011       usat r0, #1, r1");
495   COMPARE(usat(r2, 7, Operand(lr)),
496           "e6e7201e       usat r2, #7, lr");
497   COMPARE(usat(r3, 31, Operand(r4, LSL, 31)),
498           "e6ff3f94       usat r3, #31, r4, lsl #31");
499   COMPARE(usat(r8, 0, Operand(r5, ASR, 17)),
500           "e6e088d5       usat r8, #0, r5, asr #17");
501 
502   COMPARE(smmla(r0, r1, r2, r3), "e7503211       smmla r0, r1, r2, r3");
503   COMPARE(smmla(r10, r9, r8, r7), "e75a7819       smmla r10, r9, r8, r7");
504 
505   COMPARE(smmul(r0, r1, r2), "e750f211       smmul r0, r1, r2");
506   COMPARE(smmul(r8, r9, r10), "e758fa19       smmul r8, r9, r10");
507 
508   VERIFY_RUN();
509 }
510 
511 
TEST(msr_mrs_disasm)512 TEST(msr_mrs_disasm) {
513   SET_UP();
514 
515   SRegisterFieldMask CPSR_all = CPSR_f | CPSR_s | CPSR_x | CPSR_c;
516   SRegisterFieldMask SPSR_all = SPSR_f | SPSR_s | SPSR_x | SPSR_c;
517 
518   COMPARE(msr(CPSR_f, Operand(r0)),       "e128f000       msr CPSR_f, r0");
519   COMPARE(msr(CPSR_s, Operand(r1)),       "e124f001       msr CPSR_s, r1");
520   COMPARE(msr(CPSR_x, Operand(r2)),       "e122f002       msr CPSR_x, r2");
521   COMPARE(msr(CPSR_c, Operand(r3)),       "e121f003       msr CPSR_c, r3");
522   COMPARE(msr(CPSR_all, Operand(ip)),     "e12ff00c       msr CPSR_fsxc, ip");
523   COMPARE(msr(SPSR_f, Operand(r0)),       "e168f000       msr SPSR_f, r0");
524   COMPARE(msr(SPSR_s, Operand(r1)),       "e164f001       msr SPSR_s, r1");
525   COMPARE(msr(SPSR_x, Operand(r2)),       "e162f002       msr SPSR_x, r2");
526   COMPARE(msr(SPSR_c, Operand(r3)),       "e161f003       msr SPSR_c, r3");
527   COMPARE(msr(SPSR_all, Operand(ip)),     "e16ff00c       msr SPSR_fsxc, ip");
528   COMPARE(msr(CPSR_f, Operand(r0), eq),   "0128f000       msreq CPSR_f, r0");
529   COMPARE(msr(CPSR_s, Operand(r1), ne),   "1124f001       msrne CPSR_s, r1");
530   COMPARE(msr(CPSR_x, Operand(r2), cs),   "2122f002       msrcs CPSR_x, r2");
531   COMPARE(msr(CPSR_c, Operand(r3), cc),   "3121f003       msrcc CPSR_c, r3");
532   COMPARE(msr(CPSR_all, Operand(ip), mi), "412ff00c       msrmi CPSR_fsxc, ip");
533   COMPARE(msr(SPSR_f, Operand(r0), pl),   "5168f000       msrpl SPSR_f, r0");
534   COMPARE(msr(SPSR_s, Operand(r1), vs),   "6164f001       msrvs SPSR_s, r1");
535   COMPARE(msr(SPSR_x, Operand(r2), vc),   "7162f002       msrvc SPSR_x, r2");
536   COMPARE(msr(SPSR_c, Operand(r3), hi),   "8161f003       msrhi SPSR_c, r3");
537   COMPARE(msr(SPSR_all, Operand(ip), ls), "916ff00c       msrls SPSR_fsxc, ip");
538 
539   // Other combinations of mask bits.
540   COMPARE(msr(CPSR_s | CPSR_x, Operand(r4)),
541           "e126f004       msr CPSR_sx, r4");
542   COMPARE(msr(SPSR_s | SPSR_x | SPSR_c, Operand(r5)),
543           "e167f005       msr SPSR_sxc, r5");
544   COMPARE(msr(SPSR_s | SPSR_c, Operand(r6)),
545           "e165f006       msr SPSR_sc, r6");
546   COMPARE(msr(SPSR_f | SPSR_c, Operand(r7)),
547           "e169f007       msr SPSR_fc, r7");
548   // MSR with no mask is UNPREDICTABLE, and checked by the assembler, but check
549   // that the disassembler does something sensible.
550   COMPARE(dd(0xE120F008), "e120f008       msr CPSR_(none), r8");
551 
552   COMPARE(mrs(r0, CPSR),     "e10f0000       mrs r0, CPSR");
553   COMPARE(mrs(r1, SPSR),     "e14f1000       mrs r1, SPSR");
554   COMPARE(mrs(r2, CPSR, ge), "a10f2000       mrsge r2, CPSR");
555   COMPARE(mrs(r3, SPSR, lt), "b14f3000       mrslt r3, SPSR");
556 
557   VERIFY_RUN();
558 }
559 
560 
TEST(Vfp)561 TEST(Vfp) {
562   SET_UP();
563 
564   if (CpuFeatures::IsSupported(VFPv3)) {
565     CpuFeatureScope scope(&assm, VFPv3);
566     COMPARE(vmov(d0, r2, r3),
567             "ec432b10       vmov d0, r2, r3");
568     COMPARE(vmov(r2, r3, d0),
569             "ec532b10       vmov r2, r3, d0");
570     COMPARE(vmov(r4, ip, d1),
571             "ec5c4b11       vmov r4, ip, d1");
572     COMPARE(vmov(d0, d1),
573             "eeb00b41       vmov.f64 d0, d1");
574     COMPARE(vmov(d3, d3, eq),
575             "0eb03b43       vmoveq.f64 d3, d3");
576 
577     COMPARE(vmov(s0, s31),
578             "eeb00a6f       vmov.f32 s0, s31");
579     COMPARE(vmov(s31, s0),
580             "eef0fa40       vmov.f32 s31, s0");
581     COMPARE(vmov(r0, s0),
582             "ee100a10       vmov r0, s0");
583     COMPARE(vmov(r10, s31),
584             "ee1faa90       vmov r10, s31");
585     COMPARE(vmov(s0, r0),
586             "ee000a10       vmov s0, r0");
587     COMPARE(vmov(s31, r10),
588             "ee0faa90       vmov s31, r10");
589 
590     COMPARE(vabs(d0, d1),
591             "eeb00bc1       vabs.f64 d0, d1");
592     COMPARE(vabs(d3, d4, mi),
593             "4eb03bc4       vabsmi.f64 d3, d4");
594 
595     COMPARE(vabs(s0, s1),
596             "eeb00ae0       vabs.f32 s0, s1");
597     COMPARE(vabs(s3, s4, mi),
598             "4ef01ac2       vabsmi.f32 s3, s4");
599 
600     COMPARE(vneg(d0, d1),
601             "eeb10b41       vneg.f64 d0, d1");
602     COMPARE(vneg(d3, d4, mi),
603             "4eb13b44       vnegmi.f64 d3, d4");
604 
605     COMPARE(vneg(s0, s1),
606             "eeb10a60       vneg.f32 s0, s1");
607     COMPARE(vneg(s3, s4, mi),
608             "4ef11a42       vnegmi.f32 s3, s4");
609 
610     COMPARE(vadd(d0, d1, d2),
611             "ee310b02       vadd.f64 d0, d1, d2");
612     COMPARE(vadd(d3, d4, d5, mi),
613             "4e343b05       vaddmi.f64 d3, d4, d5");
614 
615     COMPARE(vadd(s0, s1, s2),
616             "ee300a81       vadd.f32 s0, s1, s2");
617     COMPARE(vadd(s3, s4, s5, mi),
618             "4e721a22       vaddmi.f32 s3, s4, s5");
619 
620     COMPARE(vsub(d0, d1, d2),
621             "ee310b42       vsub.f64 d0, d1, d2");
622     COMPARE(vsub(d3, d4, d5, ne),
623             "1e343b45       vsubne.f64 d3, d4, d5");
624 
625     COMPARE(vsub(s0, s1, s2),
626             "ee300ac1       vsub.f32 s0, s1, s2");
627     COMPARE(vsub(s3, s4, s5, ne),
628             "1e721a62       vsubne.f32 s3, s4, s5");
629 
630     COMPARE(vmul(d2, d1, d0),
631             "ee212b00       vmul.f64 d2, d1, d0");
632     COMPARE(vmul(d6, d4, d5, cc),
633             "3e246b05       vmulcc.f64 d6, d4, d5");
634 
635     COMPARE(vmul(s2, s1, s0),
636             "ee201a80       vmul.f32 s2, s1, s0");
637     COMPARE(vmul(s6, s4, s5, cc),
638             "3e223a22       vmulcc.f32 s6, s4, s5");
639 
640     COMPARE(vdiv(d2, d2, d2),
641             "ee822b02       vdiv.f64 d2, d2, d2");
642     COMPARE(vdiv(d6, d7, d7, hi),
643             "8e876b07       vdivhi.f64 d6, d7, d7");
644 
645     COMPARE(vdiv(s2, s2, s2),
646             "ee811a01       vdiv.f32 s2, s2, s2");
647     COMPARE(vdiv(s6, s7, s7, hi),
648             "8e833aa3       vdivhi.f32 s6, s7, s7");
649 
650     COMPARE(vcmp(d0, d1),
651             "eeb40b41       vcmp.f64 d0, d1");
652     COMPARE(vcmp(d0, 0.0),
653             "eeb50b40       vcmp.f64 d0, #0.0");
654 
655     COMPARE(vcmp(s0, s1),
656             "eeb40a60       vcmp.f32 s0, s1");
657     COMPARE(vcmp(s0, 0.0f),
658             "eeb50a40       vcmp.f32 s0, #0.0");
659 
660     COMPARE(vsqrt(d0, d0),
661             "eeb10bc0       vsqrt.f64 d0, d0");
662     COMPARE(vsqrt(d2, d3, ne),
663             "1eb12bc3       vsqrtne.f64 d2, d3");
664 
665     COMPARE(vsqrt(s0, s0),
666             "eeb10ac0       vsqrt.f32 s0, s0");
667     COMPARE(vsqrt(s2, s3, ne),
668             "1eb11ae1       vsqrtne.f32 s2, s3");
669 
670     COMPARE(vmov(d0, base::Double(1.0)),
671             "eeb70b00       vmov.f64 d0, #1");
672     COMPARE(vmov(d2, base::Double(-13.0)),
673             "eeba2b0a       vmov.f64 d2, #-13");
674 
675     COMPARE(vmov(s1, Float32(-1.0f)),
676             "eeff0a00       vmov.f32 s1, #-1");
677     COMPARE(vmov(s3, Float32(13.0f)),
678             "eef21a0a       vmov.f32 s3, #13");
679 
680     COMPARE(vmov(NeonS32, d0, 0, r0),
681             "ee000b10       vmov.32 d0[0], r0");
682     COMPARE(vmov(NeonS32, d0, 1, r0),
683             "ee200b10       vmov.32 d0[1], r0");
684 
685     COMPARE(vmov(NeonS32, r2, d15, 0),
686             "ee1f2b10       vmov.32 r2, d15[0]");
687     COMPARE(vmov(NeonS32, r3, d14, 1),
688             "ee3e3b10       vmov.32 r3, d14[1]");
689 
690     COMPARE(vldr(s0, r0, 0),
691             "ed900a00       vldr s0, [r0 + 4*0]");
692     COMPARE(vldr(s1, r1, 4),
693             "edd10a01       vldr s1, [r1 + 4*1]");
694     COMPARE(vldr(s15, r4, 16),
695             "edd47a04       vldr s15, [r4 + 4*4]");
696     COMPARE(vldr(s16, r5, 20),
697             "ed958a05       vldr s16, [r5 + 4*5]");
698     COMPARE(vldr(s31, r10, 1020),
699             "eddafaff       vldr s31, [r10 + 4*255]");
700     COMPARE(vldr(s31, ip, 1020),
701             "eddcfaff       vldr s31, [ip + 4*255]");
702 
703     COMPARE(vstr(s0, r0, 0),
704             "ed800a00       vstr s0, [r0 + 4*0]");
705     COMPARE(vstr(s1, r1, 4),
706             "edc10a01       vstr s1, [r1 + 4*1]");
707     COMPARE(vstr(s15, r8, 8),
708             "edc87a02       vstr s15, [r8 + 4*2]");
709     COMPARE(vstr(s16, r9, 12),
710             "ed898a03       vstr s16, [r9 + 4*3]");
711     COMPARE(vstr(s31, r10, 1020),
712             "edcafaff       vstr s31, [r10 + 4*255]");
713 
714     COMPARE(vldr(d0, r0, 0),
715             "ed900b00       vldr d0, [r0 + 4*0]");
716     COMPARE(vldr(d1, r1, 4),
717             "ed911b01       vldr d1, [r1 + 4*1]");
718     COMPARE(vldr(d15, r10, 1020),
719             "ed9afbff       vldr d15, [r10 + 4*255]");
720     COMPARE(vstr(d0, r0, 0),
721             "ed800b00       vstr d0, [r0 + 4*0]");
722     COMPARE(vstr(d1, r1, 4),
723             "ed811b01       vstr d1, [r1 + 4*1]");
724     COMPARE(vstr(d15, r10, 1020),
725             "ed8afbff       vstr d15, [r10 + 4*255]");
726 
727     COMPARE(vmsr(r5),
728             "eee15a10       vmsr FPSCR, r5");
729     COMPARE(vmsr(r10, pl),
730             "5ee1aa10       vmsrpl FPSCR, r10");
731     COMPARE(vmsr(pc),
732             "eee1fa10       vmsr FPSCR, APSR");
733     COMPARE(vmrs(r5),
734             "eef15a10       vmrs r5, FPSCR");
735     COMPARE(vmrs(r10, ge),
736             "aef1aa10       vmrsge r10, FPSCR");
737     COMPARE(vmrs(pc),
738             "eef1fa10       vmrs APSR, FPSCR");
739 
740     COMPARE(vstm(ia, r0, d1, d3),
741             "ec801b06       vstmia r0, {d1-d3}");
742     COMPARE(vldm(ia, r1, d2, d5),
743             "ec912b08       vldmia r1, {d2-d5}");
744     COMPARE(vstm(ia, r2, d0, d15),
745             "ec820b20       vstmia r2, {d0-d15}");
746     COMPARE(vldm(ia, r3, d0, d15),
747             "ec930b20       vldmia r3, {d0-d15}");
748     COMPARE(vstm(ia, r4, s1, s3),
749             "ecc40a03       vstmia r4, {s1-s3}");
750     COMPARE(vldm(ia, r5, s2, s5),
751             "ec951a04       vldmia r5, {s2-s5}");
752     COMPARE(vstm(ia, r6, s0, s31),
753             "ec860a20       vstmia r6, {s0-s31}");
754     COMPARE(vldm(ia, r7, s0, s31),
755             "ec970a20       vldmia r7, {s0-s31}");
756 
757     COMPARE(vmla(d2, d1, d0),
758             "ee012b00       vmla.f64 d2, d1, d0");
759     COMPARE(vmla(d6, d4, d5, cc),
760             "3e046b05       vmlacc.f64 d6, d4, d5");
761 
762     COMPARE(vmla(s2, s1, s0),
763             "ee001a80       vmla.f32 s2, s1, s0");
764     COMPARE(vmla(s6, s4, s5, cc),
765             "3e023a22       vmlacc.f32 s6, s4, s5");
766 
767     COMPARE(vmls(d2, d1, d0),
768             "ee012b40       vmls.f64 d2, d1, d0");
769     COMPARE(vmls(d6, d4, d5, cc),
770             "3e046b45       vmlscc.f64 d6, d4, d5");
771 
772     COMPARE(vmls(s2, s1, s0),
773             "ee001ac0       vmls.f32 s2, s1, s0");
774     COMPARE(vmls(s6, s4, s5, cc),
775             "3e023a62       vmlscc.f32 s6, s4, s5");
776 
777     COMPARE(vcvt_f32_f64(s31, d15),
778             "eef7fbcf       vcvt.f32.f64 s31, d15");
779     COMPARE(vcvt_f32_s32(s30, s29),
780             "eeb8faee       vcvt.f32.s32 s30, s29");
781     COMPARE(vcvt_f64_f32(d14, s28),
782             "eeb7eace       vcvt.f64.f32 d14, s28");
783     COMPARE(vcvt_f64_s32(d13, s27),
784             "eeb8dbed       vcvt.f64.s32 d13, s27");
785     COMPARE(vcvt_f64_u32(d12, s26),
786             "eeb8cb4d       vcvt.f64.u32 d12, s26");
787     COMPARE(vcvt_s32_f32(s25, s24),
788             "eefdcacc       vcvt.s32.f32 s25, s24");
789     COMPARE(vcvt_s32_f64(s23, d11),
790             "eefdbbcb       vcvt.s32.f64 s23, d11");
791     COMPARE(vcvt_u32_f32(s22, s21),
792             "eebcbaea       vcvt.u32.f32 s22, s21");
793     COMPARE(vcvt_u32_f64(s20, d10),
794             "eebcabca       vcvt.u32.f64 s20, d10");
795 
796     COMPARE(vcvt_f64_s32(d9, 2),
797             "eeba9bcf       vcvt.f64.s32 d9, d9, #2");
798 
799     if (CpuFeatures::IsSupported(VFP32DREGS)) {
800       CpuFeatureScope scope(&assm, VFP32DREGS);
801       COMPARE(vmov(d3, d27),
802               "eeb03b6b       vmov.f64 d3, d27");
803       COMPARE(vmov(d18, d7),
804               "eef02b47       vmov.f64 d18, d7");
805       COMPARE(vmov(d18, r2, r3),
806               "ec432b32       vmov d18, r2, r3");
807       COMPARE(vmov(r2, r3, d18),
808               "ec532b32       vmov r2, r3, d18");
809       COMPARE(vmov(d20, d31),
810               "eef04b6f       vmov.f64 d20, d31");
811 
812       COMPARE(vabs(d16, d31),
813               "eef00bef       vabs.f64 d16, d31");
814 
815       COMPARE(vneg(d16, d31),
816               "eef10b6f       vneg.f64 d16, d31");
817 
818       COMPARE(vadd(d16, d17, d18),
819               "ee710ba2       vadd.f64 d16, d17, d18");
820 
821       COMPARE(vsub(d16, d17, d18),
822               "ee710be2       vsub.f64 d16, d17, d18");
823 
824       COMPARE(vmul(d16, d17, d18),
825               "ee610ba2       vmul.f64 d16, d17, d18");
826 
827       COMPARE(vdiv(d16, d17, d18),
828               "eec10ba2       vdiv.f64 d16, d17, d18");
829 
830       COMPARE(vcmp(d16, d17),
831               "eef40b61       vcmp.f64 d16, d17");
832       COMPARE(vcmp(d16, 0.0),
833               "eef50b40       vcmp.f64 d16, #0.0");
834 
835       COMPARE(vsqrt(d16, d17),
836               "eef10be1       vsqrt.f64 d16, d17");
837 
838       COMPARE(vmov(d30, base::Double(16.0)),
839               "eef3eb00       vmov.f64 d30, #16");
840 
841       COMPARE(vmov(NeonS32, d31, 0, r7),
842               "ee0f7b90       vmov.32 d31[0], r7");
843       COMPARE(vmov(NeonS32, d31, 1, r7),
844               "ee2f7b90       vmov.32 d31[1], r7");
845 
846       COMPARE(vldr(d25, r0, 0),
847               "edd09b00       vldr d25, [r0 + 4*0]");
848       COMPARE(vldr(d26, r1, 4),
849               "edd1ab01       vldr d26, [r1 + 4*1]");
850       COMPARE(vldr(d31, r10, 1020),
851               "eddafbff       vldr d31, [r10 + 4*255]");
852 
853       COMPARE(vstr(d16, r0, 0),
854               "edc00b00       vstr d16, [r0 + 4*0]");
855       COMPARE(vstr(d17, r1, 4),
856               "edc11b01       vstr d17, [r1 + 4*1]");
857       COMPARE(vstr(d31, r10, 1020),
858               "edcafbff       vstr d31, [r10 + 4*255]");
859 
860       COMPARE(vstm(ia, r0, d16, d31),
861               "ecc00b20       vstmia r0, {d16-d31}");
862       COMPARE(vldm(ia, r3, d16, d31),
863               "ecd30b20       vldmia r3, {d16-d31}");
864       COMPARE(vstm(ia, r0, d23, d27),
865               "ecc07b0a       vstmia r0, {d23-d27}");
866       COMPARE(vldm(ia, r3, d23, d27),
867               "ecd37b0a       vldmia r3, {d23-d27}");
868 
869       COMPARE(vmla(d16, d17, d18),
870               "ee410ba2       vmla.f64 d16, d17, d18");
871 
872       COMPARE(vcvt_f32_f64(s0, d31),
873               "eeb70bef       vcvt.f32.f64 s0, d31");
874       COMPARE(vcvt_f32_s32(s1, s2),
875               "eef80ac1       vcvt.f32.s32 s1, s2");
876       COMPARE(vcvt_f64_f32(d30, s3),
877               "eef7eae1       vcvt.f64.f32 d30, s3");
878       COMPARE(vcvt_f64_s32(d29, s4),
879               "eef8dbc2       vcvt.f64.s32 d29, s4");
880       COMPARE(vcvt_f64_u32(d28, s5),
881               "eef8cb62       vcvt.f64.u32 d28, s5");
882       COMPARE(vcvt_s32_f32(s6, s7),
883               "eebd3ae3       vcvt.s32.f32 s6, s7");
884       COMPARE(vcvt_s32_f64(s8, d27),
885               "eebd4beb       vcvt.s32.f64 s8, d27");
886       COMPARE(vcvt_u32_f32(s9, s10),
887               "eefc4ac5       vcvt.u32.f32 s9, s10");
888       COMPARE(vcvt_u32_f64(s11, d26),
889               "eefc5bea       vcvt.u32.f64 s11, d26");
890 
891       COMPARE(vcvt_f64_s32(d25, 2),
892               "eefa9bcf       vcvt.f64.s32 d25, d25, #2");
893     }
894   }
895 
896   VERIFY_RUN();
897 }
898 
899 
TEST(ARMv8_vrintX_disasm)900 TEST(ARMv8_vrintX_disasm) {
901   SET_UP();
902 
903   if (CpuFeatures::IsSupported(ARMv8)) {
904     CpuFeatureScope scope(&assm, ARMv8);
905     COMPARE(vrinta(d0, d0), "feb80b40       vrinta.f64.f64 d0, d0");
906     COMPARE(vrinta(d2, d3), "feb82b43       vrinta.f64.f64 d2, d3");
907 
908     COMPARE(vrintp(d0, d0), "feba0b40       vrintp.f64.f64 d0, d0");
909     COMPARE(vrintp(d2, d3), "feba2b43       vrintp.f64.f64 d2, d3");
910 
911     COMPARE(vrintn(d0, d0), "feb90b40       vrintn.f64.f64 d0, d0");
912     COMPARE(vrintn(d2, d3), "feb92b43       vrintn.f64.f64 d2, d3");
913 
914     COMPARE(vrintm(d0, d0), "febb0b40       vrintm.f64.f64 d0, d0");
915     COMPARE(vrintm(d2, d3), "febb2b43       vrintm.f64.f64 d2, d3");
916 
917     COMPARE(vrintz(d0, d0), "eeb60bc0       vrintz.f64.f64 d0, d0");
918     COMPARE(vrintz(d2, d3, ne), "1eb62bc3       vrintzne.f64.f64 d2, d3");
919 
920     // Advanced SIMD
921     COMPARE(vrintm(NeonS32, q0, q3), "f3ba06c6       vrintm.f32 q0, q3");
922     COMPARE(vrintn(NeonS32, q0, q3), "f3ba0446       vrintn.f32 q0, q3");
923     COMPARE(vrintp(NeonS32, q0, q3), "f3ba07c6       vrintp.f32 q0, q3");
924     COMPARE(vrintz(NeonS32, q0, q3), "f3ba05c6       vrintz.f32 q0, q3");
925   }
926 
927   VERIFY_RUN();
928 }
929 
930 
TEST(ARMv8_vminmax_disasm)931 TEST(ARMv8_vminmax_disasm) {
932   SET_UP();
933 
934   if (CpuFeatures::IsSupported(ARMv8)) {
935     CpuFeatureScope scope(&assm, ARMv8);
936     COMPARE(vmaxnm(d0, d1, d2), "fe810b02       vmaxnm.f64 d0, d1, d2");
937     COMPARE(vminnm(d3, d4, d5), "fe843b45       vminnm.f64 d3, d4, d5");
938     COMPARE(vmaxnm(s6, s7, s8), "fe833a84       vmaxnm.f32 s6, s7, s8");
939     COMPARE(vminnm(s9, s10, s11), "fec54a65       vminnm.f32 s9, s10, s11");
940   }
941 
942   VERIFY_RUN();
943 }
944 
945 
TEST(ARMv8_vselX_disasm)946 TEST(ARMv8_vselX_disasm) {
947   SET_UP();
948 
949   if (CpuFeatures::IsSupported(ARMv8)) {
950     CpuFeatureScope scope(&assm, ARMv8);
951     // Native instructions.
952     COMPARE(vsel(eq, d0, d1, d2),
953             "fe010b02       vseleq.f64 d0, d1, d2");
954     COMPARE(vsel(eq, s0, s1, s2),
955             "fe000a81       vseleq.f32 s0, s1, s2");
956     COMPARE(vsel(ge, d0, d1, d2),
957             "fe210b02       vselge.f64 d0, d1, d2");
958     COMPARE(vsel(ge, s0, s1, s2),
959             "fe200a81       vselge.f32 s0, s1, s2");
960     COMPARE(vsel(gt, d0, d1, d2),
961             "fe310b02       vselgt.f64 d0, d1, d2");
962     COMPARE(vsel(gt, s0, s1, s2),
963             "fe300a81       vselgt.f32 s0, s1, s2");
964     COMPARE(vsel(vs, d0, d1, d2),
965             "fe110b02       vselvs.f64 d0, d1, d2");
966     COMPARE(vsel(vs, s0, s1, s2),
967             "fe100a81       vselvs.f32 s0, s1, s2");
968 
969     // Inverted conditions (and swapped inputs).
970     COMPARE(vsel(ne, d0, d1, d2),
971             "fe020b01       vseleq.f64 d0, d2, d1");
972     COMPARE(vsel(ne, s0, s1, s2),
973             "fe010a20       vseleq.f32 s0, s2, s1");
974     COMPARE(vsel(lt, d0, d1, d2),
975             "fe220b01       vselge.f64 d0, d2, d1");
976     COMPARE(vsel(lt, s0, s1, s2),
977             "fe210a20       vselge.f32 s0, s2, s1");
978     COMPARE(vsel(le, d0, d1, d2),
979             "fe320b01       vselgt.f64 d0, d2, d1");
980     COMPARE(vsel(le, s0, s1, s2),
981             "fe310a20       vselgt.f32 s0, s2, s1");
982     COMPARE(vsel(vc, d0, d1, d2),
983             "fe120b01       vselvs.f64 d0, d2, d1");
984     COMPARE(vsel(vc, s0, s1, s2),
985             "fe110a20       vselvs.f32 s0, s2, s1");
986   }
987 
988   VERIFY_RUN();
989 }
990 
991 
TEST(Neon)992 TEST(Neon) {
993   SET_UP();
994 
995   if (CpuFeatures::IsSupported(NEON)) {
996     CpuFeatureScope scope(&assm, NEON);
997       COMPARE(vld1(Neon8, NeonListOperand(d4, 1), NeonMemOperand(r1)),
998               "f421470f       vld1.8 {d4}, [r1]");
999       COMPARE(vld1(Neon8, NeonListOperand(d4, 2), NeonMemOperand(r1)),
1000               "f4214a0f       vld1.8 {d4, d5}, [r1]");
1001       COMPARE(vld1(Neon8, NeonListOperand(d4, 3), NeonMemOperand(r1)),
1002               "f421460f       vld1.8 {d4, d5, d6}, [r1]");
1003       COMPARE(vld1(Neon8, NeonListOperand(d4, 4), NeonMemOperand(r1)),
1004               "f421420f       vld1.8 {d4, d5, d6, d7}, [r1]");
1005       COMPARE(vld1s(Neon32, NeonListOperand(d4, 1), 0, NeonMemOperand(r1)),
1006               "f4a1480f       vld1.32 {d4[0]}, [r1]");
1007       COMPARE(vld1s(Neon16, NeonListOperand(d4, 1), 3, NeonMemOperand(r1)),
1008               "f4a144cf       vld1.16 {d4[3]}, [r1]");
1009       COMPARE(vld1r(Neon8, NeonListOperand(d4, 1), NeonMemOperand(r1)),
1010               "f4a14c0f       vld1.8 {d4}, [r1]");
1011       COMPARE(vld1r(Neon16, NeonListOperand(d4, 2), NeonMemOperand(r1)),
1012               "f4a14c6f       vld1.16 {d4, d5}, [r1]");
1013       COMPARE(vst1(Neon8, NeonListOperand(d4, 1), NeonMemOperand(r6)),
1014               "f406470f       vst1.8 {d4}, [r6]")
1015       COMPARE(vst1(Neon8, NeonListOperand(q4), NeonMemOperand(r6)),
1016               "f4068a0f       vst1.8 {d8, d9}, [r6]")
1017       COMPARE(vst1(Neon8, NeonListOperand(d4, 3), NeonMemOperand(r6)),
1018               "f406460f       vst1.8 {d4, d5, d6}, [r6]")
1019       COMPARE(vst1(Neon16, NeonListOperand(d17, 4), NeonMemOperand(r9)),
1020               "f449124f       vst1.16 {d17, d18, d19, d20}, [r9]");
1021       COMPARE(vst1s(Neon8, NeonListOperand(d4), 1, NeonMemOperand(r1)),
1022               "f481402f       vst1.8 {d4[1]}, [r1]");
1023       COMPARE(vst1s(Neon16, NeonListOperand(d4), 2, NeonMemOperand(r1)),
1024               "f481448f       vst1.16 {d4[2]}, [r1]");
1025       COMPARE(vst1s(Neon32, NeonListOperand(d4), 0, NeonMemOperand(r1)),
1026               "f481480f       vst1.32 {d4[0]}, [r1]");
1027       COMPARE(vmovl(NeonU8, q3, d1), "f3886a11       vmovl.u8 q3, d1");
1028       COMPARE(vmovl(NeonU8, q4, d2), "f3888a12       vmovl.u8 q4, d2");
1029       COMPARE(vmovl(NeonS16, q4, d2), "f2908a12       vmovl.s16 q4, d2");
1030       COMPARE(vmovl(NeonU32, q4, d2), "f3a08a12       vmovl.u32 q4, d2");
1031 
1032       COMPARE(vqmovn(NeonU8, NeonU8, d16, q8),
1033               "f3f202e0       vqmovn.u16 d16, q8");
1034       COMPARE(vqmovn(NeonS16, NeonS16, d16, q8),
1035               "f3f602a0       vqmovn.s32 d16, q8");
1036       COMPARE(vqmovn(NeonU32, NeonU32, d2, q4),
1037               "f3ba22c8       vqmovn.u64 d2, q4");
1038       COMPARE(vqmovn(NeonU32, NeonS32, d2, q4),
1039               "f3ba2248       vqmovun.s64 d2, q4");
1040 
1041       COMPARE(vmov(NeonS8, d0, 0, r0), "ee400b10       vmov.8 d0[0], r0");
1042       COMPARE(vmov(NeonU8, d1, 1, r1), "ee411b30       vmov.8 d1[1], r1");
1043       COMPARE(vmov(NeonS8, d2, 2, r2), "ee422b50       vmov.8 d2[2], r2");
1044       COMPARE(vmov(NeonU8, d3, 3, r8), "ee438b70       vmov.8 d3[3], r8");
1045       COMPARE(vmov(NeonU8, d3, 3, ip), "ee43cb70       vmov.8 d3[3], ip");
1046       COMPARE(vmov(NeonS8, d4, 4, r0), "ee640b10       vmov.8 d4[4], r0");
1047       COMPARE(vmov(NeonU8, d5, 5, r1), "ee651b30       vmov.8 d5[5], r1");
1048       COMPARE(vmov(NeonS8, d6, 6, r2), "ee662b50       vmov.8 d6[6], r2");
1049       COMPARE(vmov(NeonU8, d7, 7, r8), "ee678b70       vmov.8 d7[7], r8");
1050       COMPARE(vmov(NeonS16, d0, 0, r0), "ee000b30       vmov.16 d0[0], r0");
1051       COMPARE(vmov(NeonS16, d1, 1, r1), "ee011b70       vmov.16 d1[1], r1");
1052       COMPARE(vmov(NeonS16, d2, 2, r2), "ee222b30       vmov.16 d2[2], r2");
1053       COMPARE(vmov(NeonS16, d3, 3, r7), "ee237b70       vmov.16 d3[3], r7");
1054       COMPARE(vmov(NeonS16, d3, 3, ip), "ee23cb70       vmov.16 d3[3], ip");
1055       COMPARE(vmov(NeonS32, d0, 0, r0), "ee000b10       vmov.32 d0[0], r0");
1056       COMPARE(vmov(NeonU32, d0, 1, r0), "ee200b10       vmov.32 d0[1], r0");
1057 
1058       COMPARE(vmov(NeonS8, r0, d0, 0), "ee500b10       vmov.s8 r0, d0[0]");
1059       COMPARE(vmov(NeonU8, r1, d1, 1), "eed11b30       vmov.u8 r1, d1[1]");
1060       COMPARE(vmov(NeonS8, r2, d2, 2), "ee522b50       vmov.s8 r2, d2[2]");
1061       COMPARE(vmov(NeonU8, r8, d3, 3), "eed38b70       vmov.u8 r8, d3[3]");
1062       COMPARE(vmov(NeonS8, r0, d4, 4), "ee740b10       vmov.s8 r0, d4[4]");
1063       COMPARE(vmov(NeonU8, r1, d5, 5), "eef51b30       vmov.u8 r1, d5[5]");
1064       COMPARE(vmov(NeonS8, r2, d6, 6), "ee762b50       vmov.s8 r2, d6[6]");
1065       COMPARE(vmov(NeonU8, r8, d7, 7), "eef78b70       vmov.u8 r8, d7[7]");
1066       COMPARE(vmov(NeonU8, ip, d7, 7), "eef7cb70       vmov.u8 ip, d7[7]");
1067       COMPARE(vmov(NeonS16, r0, d0, 0), "ee100b30       vmov.s16 r0, d0[0]");
1068       COMPARE(vmov(NeonU16, r1, d1, 1), "ee911b70       vmov.u16 r1, d1[1]");
1069       COMPARE(vmov(NeonS16, r2, d2, 2), "ee322b30       vmov.s16 r2, d2[2]");
1070       COMPARE(vmov(NeonU16, r7, d3, 3), "eeb37b70       vmov.u16 r7, d3[3]");
1071       COMPARE(vmov(NeonS32, r2, d15, 0), "ee1f2b10       vmov.32 r2, d15[0]");
1072       COMPARE(vmov(NeonS32, r3, d14, 1), "ee3e3b10       vmov.32 r3, d14[1]");
1073 
1074       COMPARE(vmov(q0, q15),
1075               "f22e01fe       vmov q0, q15");
1076       COMPARE(vmov(q8, q9),
1077               "f26201f2       vmov q8, q9");
1078       COMPARE(vmov(q1, 0),
1079               "f2802050       vmov.i32 q1, 0");
1080       COMPARE(vmov(q1, 0x0000001200000012),
1081               "f2812052       vmov.i32 q1, 18");
1082       COMPARE(vmov(q0, 0xffffffffffffffff),
1083               "f3870e5f       vmov.i8 q0, 255");
1084       COMPARE(vmov(d0, 0xffffffffffffffff),
1085               "f3870e1f       vmov.i8 q0, 255");
1086       COMPARE(vmvn(q0, q15),
1087               "f3b005ee       vmvn q0, q15");
1088       COMPARE(vmvn(q8, q9),
1089               "f3f005e2       vmvn q8, q9");
1090       COMPARE(vswp(d0, d31),
1091               "f3b2002f       vswp d0, d31");
1092       COMPARE(vswp(d16, d14),
1093               "f3f2000e       vswp d16, d14");
1094       COMPARE(vswp(q0, q15),
1095               "f3b2006e       vswp q0, q15");
1096       COMPARE(vswp(q8, q9),
1097               "f3f20062       vswp q8, q9");
1098       COMPARE(vdup(Neon8, q0, r0),
1099               "eee00b10       vdup.8 q0, r0");
1100       COMPARE(vdup(Neon16, q1, r4),
1101               "eea24b30       vdup.16 q1, r4");
1102       COMPARE(vdup(Neon32, q15, r1),
1103               "eeae1b90       vdup.32 q15, r1");
1104       COMPARE(vdup(Neon32, q0, d1, 1),
1105               "f3bc0c41       vdup.32 q0, d1[1]");
1106       COMPARE(vdup(Neon32, q15, d1, 0),
1107               "f3f4ec41       vdup.32 q15, d1[0]");
1108       COMPARE(vdup(Neon16, q7, d8, 3),
1109               "f3beec48       vdup.16 q7, d8[3]");
1110       COMPARE(vdup(Neon32, d0, d30, 0),
1111               "f3b40c2e       vdup.32 d0, d30[0]");
1112       COMPARE(vcvt_f32_s32(q15, q1),
1113               "f3fbe642       vcvt.f32.s32 q15, q1");
1114       COMPARE(vcvt_f32_u32(q8, q9),
1115               "f3fb06e2       vcvt.f32.u32 q8, q9");
1116       COMPARE(vcvt_s32_f32(q15, q1),
1117               "f3fbe742       vcvt.s32.f32 q15, q1");
1118       COMPARE(vcvt_u32_f32(q8, q9),
1119               "f3fb07e2       vcvt.u32.f32 q8, q9");
1120       COMPARE(vclt(Neon8, q1, q3, 0),
1121               "f3b12246       vclt.s8 q1, q3, #0");
1122       COMPARE(vclt(Neon16, q1, q3, 0),
1123               "f3b52246       vclt.s16 q1, q3, #0");
1124       COMPARE(vclt(Neon32, q1, q3, 0),
1125               "f3b92246       vclt.s32 q1, q3, #0");
1126       COMPARE(vabs(q0, q1),
1127               "f3b90742       vabs.f32 q0, q1");
1128       COMPARE(vabs(Neon8, q6, q7),
1129               "f3b1c34e       vabs.s8 q6, q7");
1130       COMPARE(vabs(Neon16, q0, q1),
1131               "f3b50342       vabs.s16 q0, q1");
1132       COMPARE(vabs(Neon32, q0, q1),
1133               "f3b90342       vabs.s32 q0, q1");
1134       COMPARE(vneg(q0, q1),
1135               "f3b907c2       vneg.f32 q0, q1");
1136       COMPARE(vneg(Neon8, q6, q7),
1137               "f3b1c3ce       vneg.s8 q6, q7");
1138       COMPARE(vneg(Neon16, q0, q1),
1139               "f3b503c2       vneg.s16 q0, q1");
1140       COMPARE(vneg(Neon32, q0, q1),
1141               "f3b903c2       vneg.s32 q0, q1");
1142       COMPARE(veor(d0, d1, d2),
1143               "f3010112       veor d0, d1, d2");
1144       COMPARE(veor(d0, d30, d31),
1145               "f30e01bf       veor d0, d30, d31");
1146       COMPARE(veor(q0, q1, q2),
1147               "f3020154       veor q0, q1, q2");
1148       COMPARE(veor(q15, q0, q8),
1149               "f340e170       veor q15, q0, q8");
1150       COMPARE(vand(q15, q0, q8),
1151               "f240e170       vand q15, q0, q8");
1152       COMPARE(vbic(q15, q0, q8),
1153               "f250e170       vbic q15, q0, q8");
1154       COMPARE(vorr(q15, q0, q8),
1155               "f260e170       vorr q15, q0, q8");
1156       COMPARE(vmin(q15, q0, q8),
1157               "f260ef60       vmin.f32 q15, q0, q8");
1158       COMPARE(vmax(q15, q0, q8),
1159               "f240ef60       vmax.f32 q15, q0, q8");
1160       COMPARE(vmax(NeonS8, q0, q1, q2),
1161               "f2020644       vmax.s8 q0, q1, q2");
1162       COMPARE(vmin(NeonU16, q1, q2, q8),
1163               "f3142670       vmin.u16 q1, q2, q8");
1164       COMPARE(vmax(NeonS32, q15, q0, q8),
1165               "f260e660       vmax.s32 q15, q0, q8");
1166       COMPARE(vpadd(d0, d1, d2),
1167               "f3010d02       vpadd.f32 d0, d1, d2");
1168       COMPARE(vpadd(Neon8, d0, d1, d2),
1169               "f2010b12       vpadd.i8 d0, d1, d2");
1170       COMPARE(vpadd(Neon16, d0, d1, d2),
1171               "f2110b12       vpadd.i16 d0, d1, d2");
1172       COMPARE(vpadd(Neon32, d0, d1, d2),
1173               "f2210b12       vpadd.i32 d0, d1, d2");
1174       COMPARE(vpadal(NeonS8, q0, q1),
1175               "f3b00642       vpadal.s8 q0, q1");
1176       COMPARE(vpadal(NeonS16, q0, q1),
1177               "f3b40642       vpadal.s16 q0, q1");
1178       COMPARE(vpadal(NeonS32, q0, q1),
1179               "f3b80642       vpadal.s32 q0, q1");
1180       COMPARE(vpadal(NeonU8, q14, q15),
1181               "f3f0c6ee       vpadal.u8 q14, q15");
1182       COMPARE(vpadal(NeonU16, q14, q15),
1183               "f3f4c6ee       vpadal.u16 q14, q15");
1184       COMPARE(vpadal(NeonU32, q14, q15),
1185               "f3f8c6ee       vpadal.u32 q14, q15");
1186       COMPARE(vpaddl(NeonS8, q0, q1),
1187               "f3b00242       vpaddl.s8 q0, q1");
1188       COMPARE(vpaddl(NeonS16, q0, q1),
1189               "f3b40242       vpaddl.s16 q0, q1");
1190       COMPARE(vpaddl(NeonS32, q0, q1),
1191               "f3b80242       vpaddl.s32 q0, q1");
1192       COMPARE(vpaddl(NeonU8, q14, q15),
1193               "f3f0c2ee       vpaddl.u8 q14, q15");
1194       COMPARE(vpaddl(NeonU16, q14, q15),
1195               "f3f4c2ee       vpaddl.u16 q14, q15");
1196       COMPARE(vpaddl(NeonU32, q14, q15),
1197               "f3f8c2ee       vpaddl.u32 q14, q15");
1198       COMPARE(vpmax(NeonS8, d0, d1, d2),
1199               "f2010a02       vpmax.s8 d0, d1, d2");
1200       COMPARE(vpmin(NeonU16, d1, d2, d8),
1201               "f3121a18       vpmin.u16 d1, d2, d8");
1202       COMPARE(vpmax(NeonS32, d15, d0, d8),
1203               "f220fa08       vpmax.s32 d15, d0, d8");
1204       COMPARE(vadd(q15, q0, q8),
1205               "f240ed60       vadd.f32 q15, q0, q8");
1206       COMPARE(vadd(Neon8, q0, q1, q2),
1207               "f2020844       vadd.i8 q0, q1, q2");
1208       COMPARE(vadd(Neon16, q1, q2, q8),
1209               "f2142860       vadd.i16 q1, q2, q8");
1210       COMPARE(vadd(Neon32, q15, q0, q8),
1211               "f260e860       vadd.i32 q15, q0, q8");
1212       COMPARE(vqadd(NeonU8, q0, q1, q2),
1213               "f3020054       vqadd.u8 q0, q1, q2");
1214       COMPARE(vqadd(NeonS16, q1, q2, q8),
1215               "f2142070       vqadd.s16 q1, q2, q8");
1216       COMPARE(vqadd(NeonU32, q15, q0, q8),
1217               "f360e070       vqadd.u32 q15, q0, q8");
1218       COMPARE(vsub(q15, q0, q8),
1219               "f260ed60       vsub.f32 q15, q0, q8");
1220       COMPARE(vsub(Neon8, q0, q1, q2),
1221               "f3020844       vsub.i8 q0, q1, q2");
1222       COMPARE(vsub(Neon16, q1, q2, q8),
1223               "f3142860       vsub.i16 q1, q2, q8");
1224       COMPARE(vsub(Neon32, q15, q0, q8),
1225               "f360e860       vsub.i32 q15, q0, q8");
1226       COMPARE(vqsub(NeonU8, q0, q1, q2),
1227               "f3020254       vqsub.u8 q0, q1, q2");
1228       COMPARE(vqsub(NeonS16, q1, q2, q8),
1229               "f2142270       vqsub.s16 q1, q2, q8");
1230       COMPARE(vqsub(NeonU32, q15, q0, q8),
1231               "f360e270       vqsub.u32 q15, q0, q8");
1232       COMPARE(vmul(q0, q1, q2),
1233               "f3020d54       vmul.f32 q0, q1, q2");
1234       COMPARE(vmul(Neon8, q0, q1, q2),
1235               "f2020954       vmul.i8 q0, q1, q2");
1236       COMPARE(vmul(Neon16, q1, q2, q8),
1237               "f2142970       vmul.i16 q1, q2, q8");
1238       COMPARE(vmul(Neon32, q15, q0, q8),
1239               "f260e970       vmul.i32 q15, q0, q8");
1240 
1241       COMPARE(vqrdmulh(NeonS16, q0, q1, q8),
1242               "f3120b60       vqrdmulh.s16 q0, q1, q8");
1243       COMPARE(vqrdmulh(NeonS32, q15, q0, q8),
1244               "f360eb60       vqrdmulh.s32 q15, q0, q8");
1245 
1246       COMPARE(vmull(NeonU8, q15, d0, d8),
1247               "f3c0ec08       vmull.u8 q15, d0, d8");
1248       COMPARE(vmull(NeonS16, q15, d0, d8),
1249               "f2d0ec08       vmull.s16 q15, d0, d8");
1250       COMPARE(vmull(NeonU32, q15, d0, d8),
1251               "f3e0ec08       vmull.u32 q15, d0, d8");
1252       COMPARE(vmlal(NeonU32, q15, d0, d8),
1253               "f3e0e808       vmlal.u32 q15, d0, d8");
1254 
1255       COMPARE(vshl(NeonS8, q15, q0, 6),
1256               "f2cee550       vshl.i8 q15, q0, #6");
1257       COMPARE(vshl(NeonU16, q15, q0, 10),
1258               "f2dae550       vshl.i16 q15, q0, #10");
1259       COMPARE(vshl(NeonS32, q15, q0, 17),
1260               "f2f1e550       vshl.i32 q15, q0, #17");
1261       COMPARE(vshl(NeonS64, q15, q0, 40),
1262               "f2e8e5d0       vshl.i64 q15, q0, #40");
1263       COMPARE(vshl(NeonS8, q15, q0, q1),
1264               "f242e440       vshl.s8 q15, q0, q1");
1265       COMPARE(vshl(NeonU16, q15, q2, q3),
1266               "f356e444       vshl.u16 q15, q2, q3");
1267       COMPARE(vshl(NeonS32, q15, q4, q5),
1268               "f26ae448       vshl.s32 q15, q4, q5");
1269       COMPARE(vshr(NeonS8, q15, q0, 6),
1270               "f2cae050       vshr.s8 q15, q0, #6");
1271       COMPARE(vshr(NeonU16, q15, q0, 10),
1272               "f3d6e050       vshr.u16 q15, q0, #10");
1273       COMPARE(vshr(NeonS32, q15, q0, 17),
1274               "f2efe050       vshr.s32 q15, q0, #17");
1275       COMPARE(vshr(NeonS64, q15, q0, 40),
1276               "f2d8e0d0       vshr.s64 q15, q0, #40");
1277       COMPARE(vshr(NeonU64, q15, q0, 40),
1278               "f3d8e0d0       vshr.u64 q15, q0, #40");
1279       COMPARE(vsli(Neon64, d2, d0, 32),
1280               "f3a02590       vsli.64 d2, d0, #32");
1281       COMPARE(vsli(Neon32, d7, d8, 17),
1282               "f3b17518       vsli.32 d7, d8, #17");
1283       COMPARE(vsri(Neon64, d2, d0, 32),
1284               "f3a02490       vsri.64 d2, d0, #32");
1285       COMPARE(vsri(Neon16, d7, d8, 8),
1286               "f3987418       vsri.16 d7, d8, #8");
1287       COMPARE(vrecpe(q15, q0),
1288               "f3fbe540       vrecpe.f32 q15, q0");
1289       COMPARE(vrecps(q15, q0, q8),
1290               "f240ef70       vrecps.f32 q15, q0, q8");
1291       COMPARE(vrsqrte(q15, q0),
1292               "f3fbe5c0       vrsqrte.f32 q15, q0");
1293       COMPARE(vrsqrts(q15, q0, q8),
1294               "f260ef70       vrsqrts.f32 q15, q0, q8");
1295       COMPARE(vtst(Neon8, q0, q1, q2),
1296               "f2020854       vtst.i8 q0, q1, q2");
1297       COMPARE(vtst(Neon16, q1, q2, q8),
1298               "f2142870       vtst.i16 q1, q2, q8");
1299       COMPARE(vtst(Neon32, q15, q0, q8),
1300               "f260e870       vtst.i32 q15, q0, q8");
1301       COMPARE(vceq(q0, q1, q2),
1302               "f2020e44       vceq.f32 q0, q1, q2");
1303       COMPARE(vcge(q0, q1, q2),
1304               "f3020e44       vcge.f32 q0, q1, q2");
1305       COMPARE(vcgt(q0, q1, q2),
1306               "f3220e44       vcgt.f32 q0, q1, q2");
1307       COMPARE(vceq(Neon8, q0, q1, q2),
1308               "f3020854       vceq.i8 q0, q1, q2");
1309       COMPARE(vceq(Neon16, q1, q2, q8),
1310               "f3142870       vceq.i16 q1, q2, q8");
1311       COMPARE(vceq(Neon32, q15, q0, q8),
1312               "f360e870       vceq.i32 q15, q0, q8");
1313       COMPARE(vcge(NeonS8, q0, q1, q2),
1314               "f2020354       vcge.s8 q0, q1, q2");
1315       COMPARE(vcge(NeonU16, q1, q2, q8),
1316               "f3142370       vcge.u16 q1, q2, q8");
1317       COMPARE(vcge(NeonS32, q15, q0, q8),
1318               "f260e370       vcge.s32 q15, q0, q8");
1319       COMPARE(vcgt(NeonS8, q0, q1, q2),
1320               "f2020344       vcgt.s8 q0, q1, q2");
1321       COMPARE(vcgt(NeonU16, q1, q2, q8),
1322               "f3142360       vcgt.u16 q1, q2, q8");
1323       COMPARE(vcgt(NeonS32, q15, q0, q8),
1324               "f260e360       vcgt.s32 q15, q0, q8");
1325       COMPARE(vrhadd(NeonU8, q0, q1, q2),
1326               "f3020144       vrhadd.u8 q0, q1, q2");
1327       COMPARE(vrhadd(NeonU16, q1, q2, q8),
1328               "f3142160       vrhadd.u16 q1, q2, q8");
1329       COMPARE(vrhadd(NeonU32, q15, q0, q8),
1330               "f360e160       vrhadd.u32 q15, q0, q8");
1331       COMPARE(vbsl(q0, q1, q2),
1332               "f3120154       vbsl q0, q1, q2");
1333       COMPARE(vbsl(q15, q0, q8),
1334               "f350e170       vbsl q15, q0, q8");
1335       COMPARE(vext(q15, q0, q8, 3),
1336               "f2f0e360       vext.8 q15, q0, q8, #3");
1337       COMPARE(vzip(Neon16, d15, d0),
1338               "f3b6f180       vzip.16 d15, d0");
1339       COMPARE(vzip(Neon16, q15, q0),
1340               "f3f6e1c0       vzip.16 q15, q0");
1341       COMPARE(vuzp(Neon16, d15, d0),
1342               "f3b6f100       vuzp.16 d15, d0");
1343       COMPARE(vuzp(Neon16, q15, q0),
1344               "f3f6e140       vuzp.16 q15, q0");
1345       COMPARE(vrev16(Neon8, q15, q0),
1346               "f3f0e140       vrev16.8 q15, q0");
1347       COMPARE(vrev32(Neon8, q15, q0),
1348               "f3f0e0c0       vrev32.8 q15, q0");
1349       COMPARE(vrev64(Neon8, q15, q0),
1350               "f3f0e040       vrev64.8 q15, q0");
1351       COMPARE(vtrn(Neon16, d15, d0),
1352               "f3b6f080       vtrn.16 d15, d0");
1353       COMPARE(vtrn(Neon16, q15, q0),
1354               "f3f6e0c0       vtrn.16 q15, q0");
1355       COMPARE(vtbl(d0, NeonListOperand(d1, 1), d2),
1356               "f3b10802       vtbl.8 d0, {d1}, d2");
1357       COMPARE(vtbl(d31, NeonListOperand(d0, 2), d4),
1358               "f3f0f904       vtbl.8 d31, {d0, d1}, d4");
1359       COMPARE(vtbl(d15, NeonListOperand(d1, 3), d5),
1360               "f3b1fa05       vtbl.8 d15, {d1, d2, d3}, d5");
1361       COMPARE(vtbl(d15, NeonListOperand(d1, 4), d5),
1362               "f3b1fb05       vtbl.8 d15, {d1, d2, d3, d4}, d5");
1363       COMPARE(vtbx(d0, NeonListOperand(d1, 1), d2),
1364               "f3b10842       vtbx.8 d0, {d1}, d2");
1365       COMPARE(vtbx(d31, NeonListOperand(d0, 2), d4),
1366               "f3f0f944       vtbx.8 d31, {d0, d1}, d4");
1367       COMPARE(vtbx(d15, NeonListOperand(d1, 3), d5),
1368               "f3b1fa45       vtbx.8 d15, {d1, d2, d3}, d5");
1369       COMPARE(vtbx(d15, NeonListOperand(d1, 4), d5),
1370               "f3b1fb45       vtbx.8 d15, {d1, d2, d3, d4}, d5");
1371       COMPARE(vcnt(q1, q2),
1372               "f3b02544       vcnt.8 q1, q2");
1373   }
1374 
1375   VERIFY_RUN();
1376 }
1377 
1378 
TEST(LoadStore)1379 TEST(LoadStore) {
1380   SET_UP();
1381 
1382   COMPARE(ldrb(r0, MemOperand(r1)),
1383           "e5d10000       ldrb r0, [r1, #+0]");
1384   COMPARE(ldrb(r2, MemOperand(r3, 42)),
1385           "e5d3202a       ldrb r2, [r3, #+42]");
1386   COMPARE(ldrb(r4, MemOperand(r5, -42)),
1387           "e555402a       ldrb r4, [r5, #-42]");
1388   COMPARE(ldrb(r6, MemOperand(r7, 42, PostIndex)),
1389           "e4d7602a       ldrb r6, [r7], #+42");
1390   COMPARE(ldrb(r8, MemOperand(r9, -42, PostIndex)),
1391           "e459802a       ldrb r8, [r9], #-42");
1392   COMPARE(ldrb(r10, MemOperand(fp, 42, PreIndex)),
1393           "e5fba02a       ldrb r10, [fp, #+42]!");
1394   COMPARE(ldrb(ip, MemOperand(sp, -42, PreIndex)),
1395           "e57dc02a       ldrb ip, [sp, #-42]!");
1396   COMPARE(ldrb(r0, MemOperand(r1, r2)),
1397           "e7d10002       ldrb r0, [r1, +r2]");
1398   COMPARE(ldrb(r0, MemOperand(r1, r2, NegOffset)),
1399           "e7510002       ldrb r0, [r1, -r2]");
1400   COMPARE(ldrb(r0, MemOperand(r1, r2, PostIndex)),
1401           "e6d10002       ldrb r0, [r1], +r2");
1402   COMPARE(ldrb(r0, MemOperand(r1, r2, NegPostIndex)),
1403           "e6510002       ldrb r0, [r1], -r2");
1404   COMPARE(ldrb(r0, MemOperand(r1, r2, PreIndex)),
1405           "e7f10002       ldrb r0, [r1, +r2]!");
1406   COMPARE(ldrb(r0, MemOperand(r1, r2, NegPreIndex)),
1407           "e7710002       ldrb r0, [r1, -r2]!");
1408 
1409   COMPARE(strb(r0, MemOperand(r1)),
1410           "e5c10000       strb r0, [r1, #+0]");
1411   COMPARE(strb(r2, MemOperand(r3, 42)),
1412           "e5c3202a       strb r2, [r3, #+42]");
1413   COMPARE(strb(r4, MemOperand(r5, -42)),
1414           "e545402a       strb r4, [r5, #-42]");
1415   COMPARE(strb(r6, MemOperand(r7, 42, PostIndex)),
1416           "e4c7602a       strb r6, [r7], #+42");
1417   COMPARE(strb(r8, MemOperand(r9, -42, PostIndex)),
1418           "e449802a       strb r8, [r9], #-42");
1419   COMPARE(strb(r10, MemOperand(fp, 42, PreIndex)),
1420           "e5eba02a       strb r10, [fp, #+42]!");
1421   COMPARE(strb(ip, MemOperand(sp, -42, PreIndex)),
1422           "e56dc02a       strb ip, [sp, #-42]!");
1423   COMPARE(strb(r0, MemOperand(r1, r2)),
1424           "e7c10002       strb r0, [r1, +r2]");
1425   COMPARE(strb(r0, MemOperand(r1, r2, NegOffset)),
1426           "e7410002       strb r0, [r1, -r2]");
1427   COMPARE(strb(r0, MemOperand(r1, r2, PostIndex)),
1428           "e6c10002       strb r0, [r1], +r2");
1429   COMPARE(strb(r0, MemOperand(r1, r2, NegPostIndex)),
1430           "e6410002       strb r0, [r1], -r2");
1431   COMPARE(strb(r0, MemOperand(r1, r2, PreIndex)),
1432           "e7e10002       strb r0, [r1, +r2]!");
1433   COMPARE(strb(r0, MemOperand(r1, r2, NegPreIndex)),
1434           "e7610002       strb r0, [r1, -r2]!");
1435 
1436   COMPARE(ldrh(r0, MemOperand(r1)),
1437           "e1d100b0       ldrh r0, [r1, #+0]");
1438   COMPARE(ldrh(r2, MemOperand(r3, 42)),
1439           "e1d322ba       ldrh r2, [r3, #+42]");
1440   COMPARE(ldrh(r4, MemOperand(r5, -42)),
1441           "e15542ba       ldrh r4, [r5, #-42]");
1442   COMPARE(ldrh(r6, MemOperand(r7, 42, PostIndex)),
1443           "e0d762ba       ldrh r6, [r7], #+42");
1444   COMPARE(ldrh(r8, MemOperand(r9, -42, PostIndex)),
1445           "e05982ba       ldrh r8, [r9], #-42");
1446   COMPARE(ldrh(r10, MemOperand(fp, 42, PreIndex)),
1447           "e1fba2ba       ldrh r10, [fp, #+42]!");
1448   COMPARE(ldrh(ip, MemOperand(sp, -42, PreIndex)),
1449           "e17dc2ba       ldrh ip, [sp, #-42]!");
1450   COMPARE(ldrh(r0, MemOperand(r1, r2)),
1451           "e19100b2       ldrh r0, [r1, +r2]");
1452   COMPARE(ldrh(r0, MemOperand(r1, r2, NegOffset)),
1453           "e11100b2       ldrh r0, [r1, -r2]");
1454   COMPARE(ldrh(r0, MemOperand(r1, r2, PostIndex)),
1455           "e09100b2       ldrh r0, [r1], +r2");
1456   COMPARE(ldrh(r0, MemOperand(r1, r2, NegPostIndex)),
1457           "e01100b2       ldrh r0, [r1], -r2");
1458   COMPARE(ldrh(r0, MemOperand(r1, r2, PreIndex)),
1459           "e1b100b2       ldrh r0, [r1, +r2]!");
1460   COMPARE(ldrh(r0, MemOperand(r1, r2, NegPreIndex)),
1461           "e13100b2       ldrh r0, [r1, -r2]!");
1462 
1463   COMPARE(strh(r0, MemOperand(r1)),
1464           "e1c100b0       strh r0, [r1, #+0]");
1465   COMPARE(strh(r2, MemOperand(r3, 42)),
1466           "e1c322ba       strh r2, [r3, #+42]");
1467   COMPARE(strh(r4, MemOperand(r5, -42)),
1468           "e14542ba       strh r4, [r5, #-42]");
1469   COMPARE(strh(r6, MemOperand(r7, 42, PostIndex)),
1470           "e0c762ba       strh r6, [r7], #+42");
1471   COMPARE(strh(r8, MemOperand(r9, -42, PostIndex)),
1472           "e04982ba       strh r8, [r9], #-42");
1473   COMPARE(strh(r10, MemOperand(fp, 42, PreIndex)),
1474           "e1eba2ba       strh r10, [fp, #+42]!");
1475   COMPARE(strh(ip, MemOperand(sp, -42, PreIndex)),
1476           "e16dc2ba       strh ip, [sp, #-42]!");
1477   COMPARE(strh(r0, MemOperand(r1, r2)),
1478           "e18100b2       strh r0, [r1, +r2]");
1479   COMPARE(strh(r0, MemOperand(r1, r2, NegOffset)),
1480           "e10100b2       strh r0, [r1, -r2]");
1481   COMPARE(strh(r0, MemOperand(r1, r2, PostIndex)),
1482           "e08100b2       strh r0, [r1], +r2");
1483   COMPARE(strh(r0, MemOperand(r1, r2, NegPostIndex)),
1484           "e00100b2       strh r0, [r1], -r2");
1485   COMPARE(strh(r0, MemOperand(r1, r2, PreIndex)),
1486           "e1a100b2       strh r0, [r1, +r2]!");
1487   COMPARE(strh(r0, MemOperand(r1, r2, NegPreIndex)),
1488           "e12100b2       strh r0, [r1, -r2]!");
1489 
1490   COMPARE(ldr(r0, MemOperand(r1)),
1491           "e5910000       ldr r0, [r1, #+0]");
1492   COMPARE(ldr(r2, MemOperand(r3, 42)),
1493           "e593202a       ldr r2, [r3, #+42]");
1494   COMPARE(ldr(r4, MemOperand(r5, -42)),
1495           "e515402a       ldr r4, [r5, #-42]");
1496   COMPARE(ldr(r6, MemOperand(r7, 42, PostIndex)),
1497           "e497602a       ldr r6, [r7], #+42");
1498   COMPARE(ldr(r8, MemOperand(r9, -42, PostIndex)),
1499           "e419802a       ldr r8, [r9], #-42");
1500   COMPARE(ldr(r10, MemOperand(fp, 42, PreIndex)),
1501           "e5bba02a       ldr r10, [fp, #+42]!");
1502   COMPARE(ldr(ip, MemOperand(sp, -42, PreIndex)),
1503           "e53dc02a       ldr ip, [sp, #-42]!");
1504   COMPARE(ldr(r0, MemOperand(r1, r2)),
1505           "e7910002       ldr r0, [r1, +r2]");
1506   COMPARE(ldr(r0, MemOperand(r1, r2, NegOffset)),
1507           "e7110002       ldr r0, [r1, -r2]");
1508   COMPARE(ldr(r0, MemOperand(r1, r2, PostIndex)),
1509           "e6910002       ldr r0, [r1], +r2");
1510   COMPARE(ldr(r0, MemOperand(r1, r2, NegPostIndex)),
1511           "e6110002       ldr r0, [r1], -r2");
1512   COMPARE(ldr(r0, MemOperand(r1, r2, PreIndex)),
1513           "e7b10002       ldr r0, [r1, +r2]!");
1514   COMPARE(ldr(r0, MemOperand(r1, r2, NegPreIndex)),
1515           "e7310002       ldr r0, [r1, -r2]!");
1516 
1517   COMPARE(str(r0, MemOperand(r1)),
1518           "e5810000       str r0, [r1, #+0]");
1519   COMPARE(str(r2, MemOperand(r3, 42)),
1520           "e583202a       str r2, [r3, #+42]");
1521   COMPARE(str(r4, MemOperand(r5, -42)),
1522           "e505402a       str r4, [r5, #-42]");
1523   COMPARE(str(r6, MemOperand(r7, 42, PostIndex)),
1524           "e487602a       str r6, [r7], #+42");
1525   COMPARE(str(r8, MemOperand(r9, -42, PostIndex)),
1526           "e409802a       str r8, [r9], #-42");
1527   COMPARE(str(r10, MemOperand(fp, 42, PreIndex)),
1528           "e5aba02a       str r10, [fp, #+42]!");
1529   COMPARE(str(ip, MemOperand(sp, -42, PreIndex)),
1530           "e52dc02a       str ip, [sp, #-42]!");
1531   COMPARE(str(r0, MemOperand(r1, r2)),
1532           "e7810002       str r0, [r1, +r2]");
1533   COMPARE(str(r0, MemOperand(r1, r2, NegOffset)),
1534           "e7010002       str r0, [r1, -r2]");
1535   COMPARE(str(r0, MemOperand(r1, r2, PostIndex)),
1536           "e6810002       str r0, [r1], +r2");
1537   COMPARE(str(r0, MemOperand(r1, r2, NegPostIndex)),
1538           "e6010002       str r0, [r1], -r2");
1539   COMPARE(str(r0, MemOperand(r1, r2, PreIndex)),
1540           "e7a10002       str r0, [r1, +r2]!");
1541   COMPARE(str(r0, MemOperand(r1, r2, NegPreIndex)),
1542           "e7210002       str r0, [r1, -r2]!");
1543 
1544   if (CpuFeatures::IsSupported(ARMv7)) {
1545     CpuFeatureScope scope(&assm, ARMv7);
1546     COMPARE(ldrd(r0, r1, MemOperand(r1)),
1547             "e1c100d0       ldrd r0, [r1, #+0]");
1548     COMPARE(ldrd(r2, r3, MemOperand(r3, 127)),
1549             "e1c327df       ldrd r2, [r3, #+127]");
1550     COMPARE(ldrd(r4, r5, MemOperand(r5, -127)),
1551             "e14547df       ldrd r4, [r5, #-127]");
1552     COMPARE(ldrd(r6, r7, MemOperand(r7, 127, PostIndex)),
1553             "e0c767df       ldrd r6, [r7], #+127");
1554     COMPARE(ldrd(r8, r9, MemOperand(r9, -127, PostIndex)),
1555             "e04987df       ldrd r8, [r9], #-127");
1556     COMPARE(ldrd(r10, fp, MemOperand(fp, 127, PreIndex)),
1557             "e1eba7df       ldrd r10, [fp, #+127]!");
1558     COMPARE(ldrd(ip, sp, MemOperand(sp, -127, PreIndex)),
1559             "e16dc7df       ldrd ip, [sp, #-127]!");
1560 
1561     COMPARE(strd(r0, r1, MemOperand(r1)),
1562             "e1c100f0       strd r0, [r1, #+0]");
1563     COMPARE(strd(r2, r3, MemOperand(r3, 127)),
1564             "e1c327ff       strd r2, [r3, #+127]");
1565     COMPARE(strd(r4, r5, MemOperand(r5, -127)),
1566             "e14547ff       strd r4, [r5, #-127]");
1567     COMPARE(strd(r6, r7, MemOperand(r7, 127, PostIndex)),
1568             "e0c767ff       strd r6, [r7], #+127");
1569     COMPARE(strd(r8, r9, MemOperand(r9, -127, PostIndex)),
1570             "e04987ff       strd r8, [r9], #-127");
1571     COMPARE(strd(r10, fp, MemOperand(fp, 127, PreIndex)),
1572             "e1eba7ff       strd r10, [fp, #+127]!");
1573     COMPARE(strd(ip, sp, MemOperand(sp, -127, PreIndex)),
1574             "e16dc7ff       strd ip, [sp, #-127]!");
1575 
1576     COMPARE(pld(MemOperand(r1, 0)),
1577             "f5d1f000       pld [r1]");
1578     COMPARE(pld(MemOperand(ip, 64)),
1579             "f5dcf040       pld [ip, #+64]");
1580     COMPARE(pld(MemOperand(r2, 128)),
1581             "f5d2f080       pld [r2, #+128]");
1582   }
1583 
1584   // Test out-of-bound immediates.
1585   COMPARE(ldrb(r6, MemOperand(r7, 42 << 12)),
1586           "e3a06a2a       mov r6, #172032",
1587           "e7d76006       ldrb r6, [r7, +r6]");
1588   COMPARE(ldrh(r6, MemOperand(r7, 42 << 8, PostIndex)),
1589           "e3a06c2a       mov r6, #10752",
1590           "e09760b6       ldrh r6, [r7], +r6");
1591   // Make sure ip is used if the destination is the same as the base.
1592   COMPARE(ldr(r8, MemOperand(r8, 42 << 12, PreIndex)),
1593           "e3a0ca2a       mov ip, #172032",
1594           "e7b8800c       ldr r8, [r8, +ip]!");
1595   COMPARE(strb(r6, MemOperand(r7, 42 << 12)),
1596           "e3a0ca2a       mov ip, #172032",
1597           "e7c7600c       strb r6, [r7, +ip]");
1598   COMPARE(strh(r6, MemOperand(r7, 42 << 8, PostIndex)),
1599           "e3a0cc2a       mov ip, #10752",
1600           "e08760bc       strh r6, [r7], +ip");
1601   COMPARE(str(r6, MemOperand(r7, 42 << 12, PreIndex)),
1602           "e3a0ca2a       mov ip, #172032",
1603           "e7a7600c       str r6, [r7, +ip]!");
1604 
1605   // Test scaled operands for instructions that do not support it natively.
1606   COMPARE(ldrh(r0, MemOperand(r1, r2, LSL, 2)),
1607           "e1a00102       mov r0, r2, lsl #2",
1608           "e19100b0       ldrh r0, [r1, +r0]");
1609   COMPARE(strh(r3, MemOperand(r4, r5, LSR, 3)),
1610           "e1a0c1a5       mov ip, r5, lsr #3",
1611           "e18430bc       strh r3, [r4, +ip]");
1612   // Make sure ip is used if the destination is the same as the base.
1613   COMPARE(ldrsb(r6, MemOperand(r6, r8, ASR, 4)),
1614           "e1a0c248       mov ip, r8, asr #4",
1615           "e19660dc       ldrsb r6, [r6, +ip]");
1616   COMPARE(ldrsh(r9, MemOperand(sp, r10, ROR, 5)),
1617           "e1a092ea       mov r9, r10, ror #5",
1618           "e19d90f9       ldrsh r9, [sp, +r9]");
1619 
1620   VERIFY_RUN();
1621 }
1622 
1623 
TestLoadLiteral(byte * buffer,Assembler * assm,bool * failure,int offset)1624 static void TestLoadLiteral(byte* buffer, Assembler* assm, bool* failure,
1625                             int offset) {
1626   int pc_offset = assm->pc_offset();
1627   byte *progcounter = &buffer[pc_offset];
1628   assm->ldr_pcrel(r0, offset);
1629 
1630   const char *expected_string_template =
1631     (offset >= 0) ?
1632     "e59f0%03x       ldr r0, [pc, #+%d] (addr 0x%08" PRIxPTR ")" :
1633     "e51f0%03x       ldr r0, [pc, #%d] (addr 0x%08" PRIxPTR ")";
1634   char expected_string[80];
1635   snprintf(expected_string, sizeof(expected_string), expected_string_template,
1636     abs(offset), offset,
1637     reinterpret_cast<uintptr_t>(
1638       progcounter + Instruction::kPcLoadDelta + offset));
1639   if (!DisassembleAndCompare(progcounter, kRawString, expected_string)) {
1640     *failure = true;
1641   }
1642 }
1643 
1644 
TEST(LoadLiteral)1645 TEST(LoadLiteral) {
1646   SET_UP();
1647 
1648   TestLoadLiteral(buffer, &assm, &failure, 0);
1649   TestLoadLiteral(buffer, &assm, &failure, 1);
1650   TestLoadLiteral(buffer, &assm, &failure, 4);
1651   TestLoadLiteral(buffer, &assm, &failure, 4095);
1652   TestLoadLiteral(buffer, &assm, &failure, -1);
1653   TestLoadLiteral(buffer, &assm, &failure, -4);
1654   TestLoadLiteral(buffer, &assm, &failure, -4095);
1655 
1656   VERIFY_RUN();
1657 }
1658 
1659 
TEST(Barrier)1660 TEST(Barrier) {
1661   SET_UP();
1662 
1663   if (CpuFeatures::IsSupported(ARMv7)) {
1664     CpuFeatureScope scope(&assm, ARMv7);
1665 
1666     COMPARE(dmb(OSHLD),
1667             "f57ff051       dmb oshld");
1668     COMPARE(dmb(OSHST),
1669             "f57ff052       dmb oshst");
1670     COMPARE(dmb(OSH),
1671             "f57ff053       dmb osh");
1672     COMPARE(dmb(NSHLD),
1673             "f57ff055       dmb nshld");
1674     COMPARE(dmb(NSHST),
1675             "f57ff056       dmb nshst");
1676     COMPARE(dmb(NSH),
1677             "f57ff057       dmb nsh");
1678     COMPARE(dmb(ISHLD),
1679             "f57ff059       dmb ishld");
1680     COMPARE(dmb(ISHST),
1681             "f57ff05a       dmb ishst");
1682     COMPARE(dmb(ISH),
1683             "f57ff05b       dmb ish");
1684     COMPARE(dmb(LD),
1685             "f57ff05d       dmb ld");
1686     COMPARE(dmb(ST),
1687             "f57ff05e       dmb st");
1688     COMPARE(dmb(SY),
1689             "f57ff05f       dmb sy");
1690 
1691     COMPARE(dsb(ISH),
1692             "f57ff04b       dsb ish");
1693 
1694     COMPARE(isb(SY),
1695             "f57ff06f       isb sy");
1696   } else {
1697     // ARMv6 uses CP15 to implement barriers. The BarrierOption argument is
1698     // ignored.
1699     COMPARE(dmb(ISH),
1700             "ee070fba       mcr (CP15DMB)");
1701     COMPARE(dsb(OSH),
1702             "ee070f9a       mcr (CP15DSB)");
1703     COMPARE(isb(SY),
1704             "ee070f95       mcr (CP15ISB)");
1705   }
1706 
1707   // ARMv6 barriers.
1708   // Details available in ARM DDI 0406C.b, B3-1750.
1709   COMPARE(mcr(p15, 0, r0, cr7, cr10, 5), "ee070fba       mcr (CP15DMB)");
1710   COMPARE(mcr(p15, 0, r0, cr7, cr10, 4), "ee070f9a       mcr (CP15DSB)");
1711   COMPARE(mcr(p15, 0, r0, cr7, cr5, 4), "ee070f95       mcr (CP15ISB)");
1712   // Rt is ignored.
1713   COMPARE(mcr(p15, 0, lr, cr7, cr10, 5), "ee07efba       mcr (CP15DMB)");
1714   COMPARE(mcr(p15, 0, lr, cr7, cr10, 4), "ee07ef9a       mcr (CP15DSB)");
1715   COMPARE(mcr(p15, 0, lr, cr7, cr5, 4), "ee07ef95       mcr (CP15ISB)");
1716   // The mcr instruction can be conditional.
1717   COMPARE(mcr(p15, 0, r0, cr7, cr10, 5, eq), "0e070fba       mcreq (CP15DMB)");
1718   COMPARE(mcr(p15, 0, r0, cr7, cr10, 4, ne), "1e070f9a       mcrne (CP15DSB)");
1719   COMPARE(mcr(p15, 0, r0, cr7, cr5, 4, mi), "4e070f95       mcrmi (CP15ISB)");
1720 
1721   // Conditional speculation barrier.
1722   COMPARE(csdb(), "e320f014       csdb");
1723 
1724   VERIFY_RUN();
1725 }
1726 
1727 
TEST(LoadStoreExclusive)1728 TEST(LoadStoreExclusive) {
1729   SET_UP();
1730 
1731   COMPARE(ldrexb(r0, r1), "e1d10f9f       ldrexb r0, [r1]");
1732   COMPARE(strexb(r0, r1, r2), "e1c20f91       strexb r0, r1, [r2]");
1733   COMPARE(ldrexh(r0, r1), "e1f10f9f       ldrexh r0, [r1]");
1734   COMPARE(strexh(r0, r1, r2), "e1e20f91       strexh r0, r1, [r2]");
1735   COMPARE(ldrex(r0, r1), "e1910f9f       ldrex r0, [r1]");
1736   COMPARE(strex(r0, r1, r2), "e1820f91       strex r0, r1, [r2]");
1737   COMPARE(ldrexd(r0, r1, r2), "e1b20f9f       ldrexd r0, [r2]");
1738   COMPARE(strexd(r0, r2, r3, r4),
1739           "e1a40f92       strexd r0, r2, [r4]");
1740 
1741   VERIFY_RUN();
1742 }
1743 
TEST(SplitAddImmediate)1744 TEST(SplitAddImmediate) {
1745   SET_UP();
1746 
1747   if (CpuFeatures::IsSupported(ARMv7)) {
1748     // Re-use the destination as a scratch.
1749     COMPARE(add(r0, r1, Operand(0x12345678)),
1750             "e3050678       movw r0, #22136",
1751             "e3410234       movt r0, #4660",
1752             "e0810000       add r0, r1, r0");
1753 
1754     // Use ip as a scratch.
1755     COMPARE(add(r0, r0, Operand(0x12345678)),
1756             "e305c678       movw ip, #22136",
1757             "e341c234       movt ip, #4660",
1758             "e080000c       add r0, r0, ip");
1759   } else {
1760     // Re-use the destination as a scratch.
1761     COMPARE_REGEX(add(r0, r1, Operand(0x12345678)),
1762                   "e59f0[0-9a-f]{3}       "
1763                       "ldr r0, \\[pc, #\\+[0-9]+\\] \\(addr 0x[0-9a-f]{8}\\)",
1764                   "e0810000       add r0, r1, r0");
1765 
1766     // Use ip as a scratch.
1767     COMPARE_REGEX(add(r0, r0, Operand(0x12345678)),
1768                   "e59fc[0-9a-f]{3}       "
1769                       "ldr ip, \\[pc, #\\+[0-9]+\\] \\(addr 0x[0-9a-f]{8}\\)",
1770                   "e080000c       add r0, r0, ip");
1771   }
1772 
1773   // If ip is not available, split the operation into multiple additions.
1774   {
1775     UseScratchRegisterScope temps(&assm);
1776     Register reserved = temps.Acquire();
1777     USE(reserved);
1778     COMPARE(add(r2, r2, Operand(0x12345678)),
1779             "e2822f9e       add r2, r2, #632",
1780             "e2822b15       add r2, r2, #21504",
1781             "e282278d       add r2, r2, #36962304",
1782             "e2822201       add r2, r2, #268435456");
1783   }
1784 
1785   VERIFY_RUN();
1786 }
1787 
1788 }  // namespace internal
1789 }  // namespace v8
1790