• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdlib.h>
30 
31 #include "v8.h"
32 
33 #include "debug.h"
34 #include "disasm.h"
35 #include "disassembler.h"
36 #include "macro-assembler.h"
37 #include "serialize.h"
38 #include "cctest.h"
39 
40 using namespace v8::internal;
41 
42 
43 static v8::Persistent<v8::Context> env;
44 
InitializeVM()45 static void InitializeVM() {
46   if (env.IsEmpty()) {
47     env = v8::Context::New();
48   }
49 }
50 
51 
DisassembleAndCompare(byte * pc,const char * compare_string)52 bool DisassembleAndCompare(byte* pc, const char* compare_string) {
53   disasm::NameConverter converter;
54   disasm::Disassembler disasm(converter);
55   EmbeddedVector<char, 128> disasm_buffer;
56 
57   disasm.InstructionDecode(disasm_buffer, pc);
58 
59   if (strcmp(compare_string, disasm_buffer.start()) != 0) {
60     fprintf(stderr,
61             "expected: \n"
62             "%s\n"
63             "disassembled: \n"
64             "%s\n\n",
65             compare_string, disasm_buffer.start());
66     return false;
67   }
68   return true;
69 }
70 
71 
72 // Set up V8 to a state where we can at least run the assembler and
73 // disassembler. Declare the variables and allocate the data structures used
74 // in the rest of the macros.
75 #define SET_UP()                                           \
76   InitializeVM();                                         \
77   v8::HandleScope scope;                                  \
78   byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
79   Assembler assm(Isolate::Current(), buffer, 4*1024);     \
80   bool failure = false;
81 
82 
83 // This macro assembles one instruction using the preallocated assembler and
84 // disassembles the generated instruction, comparing the output to the expected
85 // value. If the comparison fails an error message is printed, but the test
86 // continues to run until the end.
87 #define COMPARE(asm_, compare_string) \
88   { \
89     int pc_offset = assm.pc_offset(); \
90     byte *progcounter = &buffer[pc_offset]; \
91     assm.asm_; \
92     if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \
93   }
94 
95 
96 // Verify that all invocations of the COMPARE macro passed successfully.
97 // Exit with a failure if at least one of the tests failed.
98 #define VERIFY_RUN() \
99 if (failure) { \
100     V8_Fatal(__FILE__, __LINE__, "ARM Disassembler tests failed.\n"); \
101   }
102 
103 
TEST(Type0)104 TEST(Type0) {
105   SET_UP();
106 
107   COMPARE(and_(r0, r1, Operand(r2)),
108           "e0010002       and r0, r1, r2");
109   COMPARE(and_(r1, r2, Operand(r3), LeaveCC),
110           "e0021003       and r1, r2, r3");
111   COMPARE(and_(r2, r3, Operand(r4), SetCC),
112           "e0132004       ands r2, r3, r4");
113   COMPARE(and_(r3, r4, Operand(r5), LeaveCC, eq),
114           "00043005       andeq r3, r4, r5");
115 
116   COMPARE(eor(r4, r5, Operand(r6, LSL, 0)),
117           "e0254006       eor r4, r5, r6");
118   COMPARE(eor(r4, r5, Operand(r7, LSL, 1), SetCC),
119           "e0354087       eors r4, r5, r7, lsl #1");
120   COMPARE(eor(r4, r5, Operand(r8, LSL, 2), LeaveCC, ne),
121           "10254108       eorne r4, r5, r8, lsl #2");
122   COMPARE(eor(r4, r5, Operand(r9, LSL, 3), SetCC, cs),
123           "20354189       eorcss r4, r5, r9, lsl #3");
124 
125   COMPARE(sub(r5, r6, Operand(r10, LSL, 31), LeaveCC, hs),
126           "20465f8a       subcs r5, r6, r10, lsl #31");
127   COMPARE(sub(r5, r6, Operand(r10, LSL, 30), SetCC, cc),
128           "30565f0a       subccs r5, r6, r10, lsl #30");
129   COMPARE(sub(r5, r6, Operand(r10, LSL, 24), LeaveCC, lo),
130           "30465c0a       subcc r5, r6, r10, lsl #24");
131   COMPARE(sub(r5, r6, Operand(r10, LSL, 16), SetCC, mi),
132           "4056580a       submis r5, r6, r10, lsl #16");
133 
134   COMPARE(rsb(r6, r7, Operand(fp)),
135           "e067600b       rsb r6, r7, fp");
136   COMPARE(rsb(r6, r7, Operand(fp, LSR, 1)),
137           "e06760ab       rsb r6, r7, fp, lsr #1");
138   COMPARE(rsb(r6, r7, Operand(fp, LSR, 0), SetCC),
139           "e077602b       rsbs r6, r7, fp, lsr #32");
140   COMPARE(rsb(r6, r7, Operand(fp, LSR, 31), LeaveCC, pl),
141           "50676fab       rsbpl r6, r7, fp, lsr #31");
142 
143   COMPARE(add(r7, r8, Operand(ip, ASR, 1)),
144           "e08870cc       add r7, r8, ip, asr #1");
145   COMPARE(add(r7, r8, Operand(ip, ASR, 0)),
146           "e088704c       add r7, r8, ip, asr #32");
147   COMPARE(add(r7, r8, Operand(ip), SetCC),
148           "e098700c       adds r7, r8, ip");
149   COMPARE(add(r7, r8, Operand(ip, ASR, 31), SetCC, vs),
150           "60987fcc       addvss r7, r8, ip, asr #31");
151 
152   COMPARE(adc(r7, fp, Operand(ip, ASR, 5)),
153           "e0ab72cc       adc r7, fp, ip, asr #5");
154   COMPARE(adc(r4, ip, Operand(ip, ASR, 1), LeaveCC, vc),
155           "70ac40cc       adcvc r4, ip, ip, asr #1");
156   COMPARE(adc(r5, sp, Operand(ip), SetCC),
157           "e0bd500c       adcs r5, sp, ip");
158   COMPARE(adc(r8, lr, Operand(ip, ASR, 31), SetCC, vc),
159           "70be8fcc       adcvcs r8, lr, ip, asr #31");
160 
161   COMPARE(sbc(r7, r1, Operand(ip, ROR, 1), LeaveCC, hi),
162           "80c170ec       sbchi r7, r1, ip, ror #1");
163   COMPARE(sbc(r7, r9, Operand(ip, ROR, 4)),
164           "e0c9726c       sbc r7, r9, ip, ror #4");
165   COMPARE(sbc(r7, r10, Operand(ip), SetCC),
166           "e0da700c       sbcs r7, r10, ip");
167   COMPARE(sbc(r7, ip, Operand(ip, ROR, 31), SetCC, hi),
168           "80dc7fec       sbchis r7, ip, ip, ror #31");
169 
170   COMPARE(rsc(r7, r8, Operand(ip, LSL, r0)),
171           "e0e8701c       rsc r7, r8, ip, lsl r0");
172   COMPARE(rsc(r7, r8, Operand(ip, LSL, r1)),
173           "e0e8711c       rsc r7, r8, ip, lsl r1");
174   COMPARE(rsc(r7, r8, Operand(ip), SetCC),
175           "e0f8700c       rscs r7, r8, ip");
176   COMPARE(rsc(r7, r8, Operand(ip, LSL, r3), SetCC, ls),
177           "90f8731c       rsclss r7, r8, ip, lsl r3");
178 
179   COMPARE(tst(r7, Operand(r5, ASR, ip), ge),
180           "a1170c55       tstge r7, r5, asr ip");
181   COMPARE(tst(r7, Operand(r6, ASR, sp)),
182           "e1170d56       tst r7, r6, asr sp");
183   COMPARE(tst(r7, Operand(r7), ge),
184           "a1170007       tstge r7, r7");
185   COMPARE(tst(r7, Operand(r8, ASR, fp), ge),
186           "a1170b58       tstge r7, r8, asr fp");
187 
188   COMPARE(teq(r7, Operand(r5, ROR, r0), lt),
189           "b1370075       teqlt r7, r5, ror r0");
190   COMPARE(teq(r7, Operand(r6, ROR, lr)),
191           "e1370e76       teq r7, r6, ror lr");
192   COMPARE(teq(r7, Operand(r7), lt),
193           "b1370007       teqlt r7, r7");
194   COMPARE(teq(r7, Operand(r8, ROR, r1)),
195           "e1370178       teq r7, r8, ror r1");
196 
197   COMPARE(cmp(r7, Operand(r4)),
198           "e1570004       cmp r7, r4");
199   COMPARE(cmp(r7, Operand(r6, LSL, 1), gt),
200           "c1570086       cmpgt r7, r6, lsl #1");
201   COMPARE(cmp(r7, Operand(r8, LSR, 3), gt),
202           "c15701a8       cmpgt r7, r8, lsr #3");
203   COMPARE(cmp(r7, Operand(r8, ASR, 19)),
204           "e15709c8       cmp r7, r8, asr #19");
205 
206   COMPARE(cmn(r0, Operand(r4)),
207           "e1700004       cmn r0, r4");
208   COMPARE(cmn(r1, Operand(r6, ROR, 1)),
209           "e17100e6       cmn r1, r6, ror #1");
210   COMPARE(cmn(r2, Operand(r8)),
211           "e1720008       cmn r2, r8");
212   COMPARE(cmn(r3, Operand(fp), le),
213           "d173000b       cmnle r3, fp");
214 
215   COMPARE(orr(r7, r8, Operand(lr), LeaveCC, al),
216           "e188700e       orr r7, r8, lr");
217   COMPARE(orr(r7, r8, Operand(fp)),
218           "e188700b       orr r7, r8, fp");
219   COMPARE(orr(r7, r8, Operand(sp), SetCC),
220           "e198700d       orrs r7, r8, sp");
221   COMPARE(orr(r7, r8, Operand(ip), SetCC, al),
222           "e198700c       orrs r7, r8, ip");
223 
224   COMPARE(mov(r0, Operand(r1), LeaveCC, eq),
225           "01a00001       moveq r0, r1");
226   COMPARE(mov(r0, Operand(r2)),
227           "e1a00002       mov r0, r2");
228   COMPARE(mov(r0, Operand(r3), SetCC),
229           "e1b00003       movs r0, r3");
230   COMPARE(mov(r0, Operand(r4), SetCC, pl),
231           "51b00004       movpls r0, r4");
232 
233   COMPARE(bic(r0, lr, Operand(r1), LeaveCC, vs),
234           "61ce0001       bicvs r0, lr, r1");
235   COMPARE(bic(r0, r9, Operand(r2), LeaveCC, vc),
236           "71c90002       bicvc r0, r9, r2");
237   COMPARE(bic(r0, r5, Operand(r3), SetCC),
238           "e1d50003       bics r0, r5, r3");
239   COMPARE(bic(r0, r1, Operand(r4), SetCC, pl),
240           "51d10004       bicpls r0, r1, r4");
241 
242   COMPARE(mvn(r10, Operand(r1)),
243           "e1e0a001       mvn r10, r1");
244   COMPARE(mvn(r9, Operand(r2)),
245           "e1e09002       mvn r9, r2");
246   COMPARE(mvn(r0, Operand(r3), SetCC),
247           "e1f00003       mvns r0, r3");
248   COMPARE(mvn(r5, Operand(r4), SetCC, cc),
249           "31f05004       mvnccs r5, r4");
250 
251   // Instructions autotransformed by the assembler.
252   // mov -> mvn.
253   COMPARE(mov(r3, Operand(-1), LeaveCC, al),
254           "e3e03000       mvn r3, #0");
255   COMPARE(mov(r4, Operand(-2), SetCC, al),
256           "e3f04001       mvns r4, #1");
257   COMPARE(mov(r5, Operand(0x0ffffff0), SetCC, ne),
258           "13f052ff       mvnnes r5, #-268435441");
259   COMPARE(mov(r6, Operand(-1), LeaveCC, ne),
260           "13e06000       mvnne r6, #0");
261 
262   // mvn -> mov.
263   COMPARE(mvn(r3, Operand(-1), LeaveCC, al),
264           "e3a03000       mov r3, #0");
265   COMPARE(mvn(r4, Operand(-2), SetCC, al),
266           "e3b04001       movs r4, #1");
267   COMPARE(mvn(r5, Operand(0x0ffffff0), SetCC, ne),
268           "13b052ff       movnes r5, #-268435441");
269   COMPARE(mvn(r6, Operand(-1), LeaveCC, ne),
270           "13a06000       movne r6, #0");
271 
272   // mov -> movw.
273   if (CpuFeatures::IsSupported(ARMv7)) {
274     COMPARE(mov(r5, Operand(0x01234), LeaveCC, ne),
275             "13015234       movwne r5, #4660");
276     // We only disassemble one instruction so the eor instruction is not here.
277     COMPARE(eor(r5, r4, Operand(0x1234), LeaveCC, ne),
278             "1301c234       movwne ip, #4660");
279     // Movw can't do setcc so we don't get that here.  Mov immediate with setcc
280     // is pretty strange anyway.
281     COMPARE(mov(r5, Operand(0x01234), SetCC, ne),
282             "159fc000       ldrne ip, [pc, #+0]");
283     // We only disassemble one instruction so the eor instruction is not here.
284     // The eor does the setcc so we get a movw here.
285     COMPARE(eor(r5, r4, Operand(0x1234), SetCC, ne),
286             "1301c234       movwne ip, #4660");
287 
288     COMPARE(movt(r5, 0x4321, ne),
289             "13445321       movtne r5, #17185");
290     COMPARE(movw(r5, 0xabcd, eq),
291             "030a5bcd       movweq r5, #43981");
292   }
293 
294   // Eor doesn't have an eor-negative variant, but we can do an mvn followed by
295   // an eor to get the same effect.
296   COMPARE(eor(r5, r4, Operand(0xffffff34), SetCC, ne),
297           "13e0c0cb       mvnne ip, #203");
298 
299   // and <-> bic.
300   COMPARE(and_(r3, r5, Operand(0xfc03ffff)),
301           "e3c537ff       bic r3, r5, #66846720");
302   COMPARE(bic(r3, r5, Operand(0xfc03ffff)),
303           "e20537ff       and r3, r5, #66846720");
304 
305   // sub <-> add.
306   COMPARE(add(r3, r5, Operand(-1024)),
307           "e2453b01       sub r3, r5, #1024");
308   COMPARE(sub(r3, r5, Operand(-1024)),
309           "e2853b01       add r3, r5, #1024");
310 
311   // cmp <-> cmn.
312   COMPARE(cmp(r3, Operand(-1024)),
313           "e3730b01       cmn r3, #1024");
314   COMPARE(cmn(r3, Operand(-1024)),
315           "e3530b01       cmp r3, #1024");
316 
317   // Miscellaneous instructions encoded as type 0.
318   COMPARE(blx(ip),
319           "e12fff3c       blx ip");
320   COMPARE(bkpt(0),
321           "e1200070       bkpt 0");
322   COMPARE(bkpt(0xffff),
323           "e12fff7f       bkpt 65535");
324   COMPARE(clz(r6, r7),
325           "e16f6f17       clz r6, r7");
326 
327   VERIFY_RUN();
328 }
329 
330 
TEST(Type1)331 TEST(Type1) {
332   SET_UP();
333 
334   COMPARE(and_(r0, r1, Operand(0x00000000)),
335           "e2010000       and r0, r1, #0");
336   COMPARE(and_(r1, r2, Operand(0x00000001), LeaveCC),
337           "e2021001       and r1, r2, #1");
338   COMPARE(and_(r2, r3, Operand(0x00000010), SetCC),
339           "e2132010       ands r2, r3, #16");
340   COMPARE(and_(r3, r4, Operand(0x00000100), LeaveCC, eq),
341           "02043c01       andeq r3, r4, #256");
342   COMPARE(and_(r4, r5, Operand(0x00001000), SetCC, ne),
343           "12154a01       andnes r4, r5, #4096");
344 
345   COMPARE(eor(r4, r5, Operand(0x00001000)),
346           "e2254a01       eor r4, r5, #4096");
347   COMPARE(eor(r4, r4, Operand(0x00010000), LeaveCC),
348           "e2244801       eor r4, r4, #65536");
349   COMPARE(eor(r4, r3, Operand(0x00100000), SetCC),
350           "e2334601       eors r4, r3, #1048576");
351   COMPARE(eor(r4, r2, Operand(0x01000000), LeaveCC, cs),
352           "22224401       eorcs r4, r2, #16777216");
353   COMPARE(eor(r4, r1, Operand(0x10000000), SetCC, cc),
354           "32314201       eorccs r4, r1, #268435456");
355 
356   VERIFY_RUN();
357 }
358 
359 
TEST(Type3)360 TEST(Type3) {
361   SET_UP();
362 
363   if (CpuFeatures::IsSupported(ARMv7)) {
364     COMPARE(ubfx(r0, r1, 5, 10),
365             "e7e902d1       ubfx r0, r1, #5, #10");
366     COMPARE(ubfx(r1, r0, 5, 10),
367             "e7e912d0       ubfx r1, r0, #5, #10");
368     COMPARE(ubfx(r0, r1, 31, 1),
369             "e7e00fd1       ubfx r0, r1, #31, #1");
370     COMPARE(ubfx(r1, r0, 31, 1),
371             "e7e01fd0       ubfx r1, r0, #31, #1");
372 
373     COMPARE(sbfx(r0, r1, 5, 10),
374             "e7a902d1       sbfx r0, r1, #5, #10");
375     COMPARE(sbfx(r1, r0, 5, 10),
376             "e7a912d0       sbfx r1, r0, #5, #10");
377     COMPARE(sbfx(r0, r1, 31, 1),
378             "e7a00fd1       sbfx r0, r1, #31, #1");
379     COMPARE(sbfx(r1, r0, 31, 1),
380             "e7a01fd0       sbfx r1, r0, #31, #1");
381 
382     COMPARE(bfc(r0, 5, 10),
383             "e7ce029f       bfc r0, #5, #10");
384     COMPARE(bfc(r1, 5, 10),
385             "e7ce129f       bfc r1, #5, #10");
386     COMPARE(bfc(r0, 31, 1),
387             "e7df0f9f       bfc r0, #31, #1");
388     COMPARE(bfc(r1, 31, 1),
389             "e7df1f9f       bfc r1, #31, #1");
390 
391     COMPARE(bfi(r0, r1, 5, 10),
392             "e7ce0291       bfi r0, r1, #5, #10");
393     COMPARE(bfi(r1, r0, 5, 10),
394             "e7ce1290       bfi r1, r0, #5, #10");
395     COMPARE(bfi(r0, r1, 31, 1),
396             "e7df0f91       bfi r0, r1, #31, #1");
397     COMPARE(bfi(r1, r0, 31, 1),
398             "e7df1f90       bfi r1, r0, #31, #1");
399 
400     COMPARE(usat(r0, 1, Operand(r1)),
401             "e6e10011       usat r0, #1, r1");
402     COMPARE(usat(r2, 7, Operand(lr)),
403             "e6e7201e       usat r2, #7, lr");
404     COMPARE(usat(r3, 31, Operand(r4, LSL, 31)),
405             "e6ff3f94       usat r3, #31, r4, lsl #31");
406     COMPARE(usat(r8, 0, Operand(r5, ASR, 17)),
407             "e6e088d5       usat r8, #0, r5, asr #17");
408   }
409 
410   VERIFY_RUN();
411 }
412 
413 
414 
TEST(Vfp)415 TEST(Vfp) {
416   SET_UP();
417 
418   if (CpuFeatures::IsSupported(VFP3)) {
419     CpuFeatures::Scope scope(VFP3);
420     COMPARE(vmov(d0, d1),
421             "eeb00b41       vmov.f64 d0, d1");
422     COMPARE(vmov(d3, d3, eq),
423             "0eb03b43       vmov.f64eq d3, d3");
424 
425     COMPARE(vmov(s0, s31),
426             "eeb00a6f       vmov.f32 s0, s31");
427     COMPARE(vmov(s31, s0),
428             "eef0fa40       vmov.f32 s31, s0");
429     COMPARE(vmov(r0, s0),
430             "ee100a10       vmov r0, s0");
431     COMPARE(vmov(r10, s31),
432             "ee1faa90       vmov r10, s31");
433     COMPARE(vmov(s0, r0),
434             "ee000a10       vmov s0, r0");
435     COMPARE(vmov(s31, r10),
436             "ee0faa90       vmov s31, r10");
437 
438     COMPARE(vabs(d0, d1),
439             "eeb00bc1       vabs.f64 d0, d1");
440     COMPARE(vabs(d3, d4, mi),
441             "4eb03bc4       vabs.f64mi d3, d4");
442 
443     COMPARE(vneg(d0, d1),
444             "eeb10b41       vneg.f64 d0, d1");
445     COMPARE(vneg(d3, d4, mi),
446             "4eb13b44       vneg.f64mi d3, d4");
447 
448     COMPARE(vadd(d0, d1, d2),
449             "ee310b02       vadd.f64 d0, d1, d2");
450     COMPARE(vadd(d3, d4, d5, mi),
451             "4e343b05       vadd.f64mi d3, d4, d5");
452 
453     COMPARE(vsub(d0, d1, d2),
454             "ee310b42       vsub.f64 d0, d1, d2");
455     COMPARE(vsub(d3, d4, d5, ne),
456             "1e343b45       vsub.f64ne d3, d4, d5");
457 
458     COMPARE(vmul(d2, d1, d0),
459             "ee212b00       vmul.f64 d2, d1, d0");
460     COMPARE(vmul(d6, d4, d5, cc),
461             "3e246b05       vmul.f64cc d6, d4, d5");
462 
463     COMPARE(vdiv(d2, d2, d2),
464             "ee822b02       vdiv.f64 d2, d2, d2");
465     COMPARE(vdiv(d6, d7, d7, hi),
466             "8e876b07       vdiv.f64hi d6, d7, d7");
467 
468     COMPARE(vsqrt(d0, d0),
469             "eeb10bc0       vsqrt.f64 d0, d0");
470     COMPARE(vsqrt(d2, d3, ne),
471             "1eb12bc3       vsqrt.f64ne d2, d3");
472 
473     COMPARE(vmov(d0, 1.0),
474             "eeb70b00       vmov.f64 d0, #1");
475     COMPARE(vmov(d2, -13.0),
476             "eeba2b0a       vmov.f64 d2, #-13");
477 
478     COMPARE(vldr(s0, r0, 0),
479             "ed900a00       vldr s0, [r0 + 4*0]");
480     COMPARE(vldr(s1, r1, 4),
481             "edd10a01       vldr s1, [r1 + 4*1]");
482     COMPARE(vldr(s15, r4, 16),
483             "edd47a04       vldr s15, [r4 + 4*4]");
484     COMPARE(vldr(s16, r5, 20),
485             "ed958a05       vldr s16, [r5 + 4*5]");
486     COMPARE(vldr(s31, r10, 1020),
487             "eddafaff       vldr s31, [r10 + 4*255]");
488 
489     COMPARE(vstr(s0, r0, 0),
490             "ed800a00       vstr s0, [r0 + 4*0]");
491     COMPARE(vstr(s1, r1, 4),
492             "edc10a01       vstr s1, [r1 + 4*1]");
493     COMPARE(vstr(s15, r8, 8),
494             "edc87a02       vstr s15, [r8 + 4*2]");
495     COMPARE(vstr(s16, r9, 12),
496             "ed898a03       vstr s16, [r9 + 4*3]");
497     COMPARE(vstr(s31, r10, 1020),
498             "edcafaff       vstr s31, [r10 + 4*255]");
499 
500     COMPARE(vldr(d0, r0, 0),
501             "ed900b00       vldr d0, [r0 + 4*0]");
502     COMPARE(vldr(d1, r1, 4),
503             "ed911b01       vldr d1, [r1 + 4*1]");
504     COMPARE(vldr(d15, r10, 1020),
505             "ed9afbff       vldr d15, [r10 + 4*255]");
506     COMPARE(vstr(d0, r0, 0),
507             "ed800b00       vstr d0, [r0 + 4*0]");
508     COMPARE(vstr(d1, r1, 4),
509             "ed811b01       vstr d1, [r1 + 4*1]");
510     COMPARE(vstr(d15, r10, 1020),
511             "ed8afbff       vstr d15, [r10 + 4*255]");
512 
513     COMPARE(vmsr(r5),
514             "eee15a10       vmsr FPSCR, r5");
515     COMPARE(vmsr(r10, pl),
516             "5ee1aa10       vmsrpl FPSCR, r10");
517     COMPARE(vmsr(pc),
518             "eee1fa10       vmsr FPSCR, APSR");
519     COMPARE(vmrs(r5),
520             "eef15a10       vmrs r5, FPSCR");
521     COMPARE(vmrs(r10, ge),
522             "aef1aa10       vmrsge r10, FPSCR");
523     COMPARE(vmrs(pc),
524             "eef1fa10       vmrs APSR, FPSCR");
525 
526     COMPARE(vstm(ia, r0, d1, d3),
527             "ec801b06       vstmia r0, {d1-d3}");
528     COMPARE(vldm(ia, r1, d2, d5),
529             "ec912b08       vldmia r1, {d2-d5}");
530     COMPARE(vstm(ia, r2, d0, d15),
531             "ec820b20       vstmia r2, {d0-d15}");
532     COMPARE(vldm(ia, r3, d0, d15),
533             "ec930b20       vldmia r3, {d0-d15}");
534     COMPARE(vstm(ia, r4, s1, s3),
535             "ecc40a03       vstmia r4, {s1-s3}");
536     COMPARE(vldm(ia, r5, s2, s5),
537             "ec951a04       vldmia r5, {s2-s5}");
538     COMPARE(vstm(ia, r6, s0, s31),
539             "ec860a20       vstmia r6, {s0-s31}");
540     COMPARE(vldm(ia, r7, s0, s31),
541             "ec970a20       vldmia r7, {s0-s31}");
542   }
543 
544   VERIFY_RUN();
545 }
546 
547 
TEST(LoadStore)548 TEST(LoadStore) {
549   SET_UP();
550 
551   COMPARE(ldrb(r0, MemOperand(r1)),
552           "e5d10000       ldrb r0, [r1, #+0]");
553   COMPARE(ldrb(r2, MemOperand(r3, 42)),
554           "e5d3202a       ldrb r2, [r3, #+42]");
555   COMPARE(ldrb(r4, MemOperand(r5, -42)),
556           "e555402a       ldrb r4, [r5, #-42]");
557   COMPARE(ldrb(r6, MemOperand(r7, 42, PostIndex)),
558           "e4d7602a       ldrb r6, [r7], #+42");
559   COMPARE(ldrb(r8, MemOperand(r9, -42, PostIndex)),
560           "e459802a       ldrb r8, [r9], #-42");
561   COMPARE(ldrb(r10, MemOperand(fp, 42, PreIndex)),
562           "e5fba02a       ldrb r10, [fp, #+42]!");
563   COMPARE(ldrb(ip, MemOperand(sp, -42, PreIndex)),
564           "e57dc02a       ldrb ip, [sp, #-42]!");
565   COMPARE(ldrb(r0, MemOperand(r1, r2)),
566           "e7d10002       ldrb r0, [r1, +r2]");
567   COMPARE(ldrb(r0, MemOperand(r1, r2, NegOffset)),
568           "e7510002       ldrb r0, [r1, -r2]");
569   COMPARE(ldrb(r0, MemOperand(r1, r2, PostIndex)),
570           "e6d10002       ldrb r0, [r1], +r2");
571   COMPARE(ldrb(r0, MemOperand(r1, r2, NegPostIndex)),
572           "e6510002       ldrb r0, [r1], -r2");
573   COMPARE(ldrb(r0, MemOperand(r1, r2, PreIndex)),
574           "e7f10002       ldrb r0, [r1, +r2]!");
575   COMPARE(ldrb(r0, MemOperand(r1, r2, NegPreIndex)),
576           "e7710002       ldrb r0, [r1, -r2]!");
577 
578   COMPARE(strb(r0, MemOperand(r1)),
579           "e5c10000       strb r0, [r1, #+0]");
580   COMPARE(strb(r2, MemOperand(r3, 42)),
581           "e5c3202a       strb r2, [r3, #+42]");
582   COMPARE(strb(r4, MemOperand(r5, -42)),
583           "e545402a       strb r4, [r5, #-42]");
584   COMPARE(strb(r6, MemOperand(r7, 42, PostIndex)),
585           "e4c7602a       strb r6, [r7], #+42");
586   COMPARE(strb(r8, MemOperand(r9, -42, PostIndex)),
587           "e449802a       strb r8, [r9], #-42");
588   COMPARE(strb(r10, MemOperand(fp, 42, PreIndex)),
589           "e5eba02a       strb r10, [fp, #+42]!");
590   COMPARE(strb(ip, MemOperand(sp, -42, PreIndex)),
591           "e56dc02a       strb ip, [sp, #-42]!");
592   COMPARE(strb(r0, MemOperand(r1, r2)),
593           "e7c10002       strb r0, [r1, +r2]");
594   COMPARE(strb(r0, MemOperand(r1, r2, NegOffset)),
595           "e7410002       strb r0, [r1, -r2]");
596   COMPARE(strb(r0, MemOperand(r1, r2, PostIndex)),
597           "e6c10002       strb r0, [r1], +r2");
598   COMPARE(strb(r0, MemOperand(r1, r2, NegPostIndex)),
599           "e6410002       strb r0, [r1], -r2");
600   COMPARE(strb(r0, MemOperand(r1, r2, PreIndex)),
601           "e7e10002       strb r0, [r1, +r2]!");
602   COMPARE(strb(r0, MemOperand(r1, r2, NegPreIndex)),
603           "e7610002       strb r0, [r1, -r2]!");
604 
605   COMPARE(ldrh(r0, MemOperand(r1)),
606           "e1d100b0       ldrh r0, [r1, #+0]");
607   COMPARE(ldrh(r2, MemOperand(r3, 42)),
608           "e1d322ba       ldrh r2, [r3, #+42]");
609   COMPARE(ldrh(r4, MemOperand(r5, -42)),
610           "e15542ba       ldrh r4, [r5, #-42]");
611   COMPARE(ldrh(r6, MemOperand(r7, 42, PostIndex)),
612           "e0d762ba       ldrh r6, [r7], #+42");
613   COMPARE(ldrh(r8, MemOperand(r9, -42, PostIndex)),
614           "e05982ba       ldrh r8, [r9], #-42");
615   COMPARE(ldrh(r10, MemOperand(fp, 42, PreIndex)),
616           "e1fba2ba       ldrh r10, [fp, #+42]!");
617   COMPARE(ldrh(ip, MemOperand(sp, -42, PreIndex)),
618           "e17dc2ba       ldrh ip, [sp, #-42]!");
619   COMPARE(ldrh(r0, MemOperand(r1, r2)),
620           "e19100b2       ldrh r0, [r1, +r2]");
621   COMPARE(ldrh(r0, MemOperand(r1, r2, NegOffset)),
622           "e11100b2       ldrh r0, [r1, -r2]");
623   COMPARE(ldrh(r0, MemOperand(r1, r2, PostIndex)),
624           "e09100b2       ldrh r0, [r1], +r2");
625   COMPARE(ldrh(r0, MemOperand(r1, r2, NegPostIndex)),
626           "e01100b2       ldrh r0, [r1], -r2");
627   COMPARE(ldrh(r0, MemOperand(r1, r2, PreIndex)),
628           "e1b100b2       ldrh r0, [r1, +r2]!");
629   COMPARE(ldrh(r0, MemOperand(r1, r2, NegPreIndex)),
630           "e13100b2       ldrh r0, [r1, -r2]!");
631 
632   COMPARE(strh(r0, MemOperand(r1)),
633           "e1c100b0       strh r0, [r1, #+0]");
634   COMPARE(strh(r2, MemOperand(r3, 42)),
635           "e1c322ba       strh r2, [r3, #+42]");
636   COMPARE(strh(r4, MemOperand(r5, -42)),
637           "e14542ba       strh r4, [r5, #-42]");
638   COMPARE(strh(r6, MemOperand(r7, 42, PostIndex)),
639           "e0c762ba       strh r6, [r7], #+42");
640   COMPARE(strh(r8, MemOperand(r9, -42, PostIndex)),
641           "e04982ba       strh r8, [r9], #-42");
642   COMPARE(strh(r10, MemOperand(fp, 42, PreIndex)),
643           "e1eba2ba       strh r10, [fp, #+42]!");
644   COMPARE(strh(ip, MemOperand(sp, -42, PreIndex)),
645           "e16dc2ba       strh ip, [sp, #-42]!");
646   COMPARE(strh(r0, MemOperand(r1, r2)),
647           "e18100b2       strh r0, [r1, +r2]");
648   COMPARE(strh(r0, MemOperand(r1, r2, NegOffset)),
649           "e10100b2       strh r0, [r1, -r2]");
650   COMPARE(strh(r0, MemOperand(r1, r2, PostIndex)),
651           "e08100b2       strh r0, [r1], +r2");
652   COMPARE(strh(r0, MemOperand(r1, r2, NegPostIndex)),
653           "e00100b2       strh r0, [r1], -r2");
654   COMPARE(strh(r0, MemOperand(r1, r2, PreIndex)),
655           "e1a100b2       strh r0, [r1, +r2]!");
656   COMPARE(strh(r0, MemOperand(r1, r2, NegPreIndex)),
657           "e12100b2       strh r0, [r1, -r2]!");
658 
659   COMPARE(ldr(r0, MemOperand(r1)),
660           "e5910000       ldr r0, [r1, #+0]");
661   COMPARE(ldr(r2, MemOperand(r3, 42)),
662           "e593202a       ldr r2, [r3, #+42]");
663   COMPARE(ldr(r4, MemOperand(r5, -42)),
664           "e515402a       ldr r4, [r5, #-42]");
665   COMPARE(ldr(r6, MemOperand(r7, 42, PostIndex)),
666           "e497602a       ldr r6, [r7], #+42");
667   COMPARE(ldr(r8, MemOperand(r9, -42, PostIndex)),
668           "e419802a       ldr r8, [r9], #-42");
669   COMPARE(ldr(r10, MemOperand(fp, 42, PreIndex)),
670           "e5bba02a       ldr r10, [fp, #+42]!");
671   COMPARE(ldr(ip, MemOperand(sp, -42, PreIndex)),
672           "e53dc02a       ldr ip, [sp, #-42]!");
673   COMPARE(ldr(r0, MemOperand(r1, r2)),
674           "e7910002       ldr r0, [r1, +r2]");
675   COMPARE(ldr(r0, MemOperand(r1, r2, NegOffset)),
676           "e7110002       ldr r0, [r1, -r2]");
677   COMPARE(ldr(r0, MemOperand(r1, r2, PostIndex)),
678           "e6910002       ldr r0, [r1], +r2");
679   COMPARE(ldr(r0, MemOperand(r1, r2, NegPostIndex)),
680           "e6110002       ldr r0, [r1], -r2");
681   COMPARE(ldr(r0, MemOperand(r1, r2, PreIndex)),
682           "e7b10002       ldr r0, [r1, +r2]!");
683   COMPARE(ldr(r0, MemOperand(r1, r2, NegPreIndex)),
684           "e7310002       ldr r0, [r1, -r2]!");
685 
686   COMPARE(str(r0, MemOperand(r1)),
687           "e5810000       str r0, [r1, #+0]");
688   COMPARE(str(r2, MemOperand(r3, 42)),
689           "e583202a       str r2, [r3, #+42]");
690   COMPARE(str(r4, MemOperand(r5, -42)),
691           "e505402a       str r4, [r5, #-42]");
692   COMPARE(str(r6, MemOperand(r7, 42, PostIndex)),
693           "e487602a       str r6, [r7], #+42");
694   COMPARE(str(r8, MemOperand(r9, -42, PostIndex)),
695           "e409802a       str r8, [r9], #-42");
696   COMPARE(str(r10, MemOperand(fp, 42, PreIndex)),
697           "e5aba02a       str r10, [fp, #+42]!");
698   COMPARE(str(ip, MemOperand(sp, -42, PreIndex)),
699           "e52dc02a       str ip, [sp, #-42]!");
700   COMPARE(str(r0, MemOperand(r1, r2)),
701           "e7810002       str r0, [r1, +r2]");
702   COMPARE(str(r0, MemOperand(r1, r2, NegOffset)),
703           "e7010002       str r0, [r1, -r2]");
704   COMPARE(str(r0, MemOperand(r1, r2, PostIndex)),
705           "e6810002       str r0, [r1], +r2");
706   COMPARE(str(r0, MemOperand(r1, r2, NegPostIndex)),
707           "e6010002       str r0, [r1], -r2");
708   COMPARE(str(r0, MemOperand(r1, r2, PreIndex)),
709           "e7a10002       str r0, [r1, +r2]!");
710   COMPARE(str(r0, MemOperand(r1, r2, NegPreIndex)),
711           "e7210002       str r0, [r1, -r2]!");
712 
713   if (CpuFeatures::IsSupported(ARMv7)) {
714     CpuFeatures::Scope scope(ARMv7);
715     COMPARE(ldrd(r0, r1, MemOperand(r1)),
716             "e1c100d0       ldrd r0, [r1, #+0]");
717     COMPARE(ldrd(r2, r3, MemOperand(r3, 127)),
718             "e1c327df       ldrd r2, [r3, #+127]");
719     COMPARE(ldrd(r4, r5, MemOperand(r5, -127)),
720             "e14547df       ldrd r4, [r5, #-127]");
721     COMPARE(ldrd(r6, r7, MemOperand(r7, 127, PostIndex)),
722             "e0c767df       ldrd r6, [r7], #+127");
723     COMPARE(ldrd(r8, r9, MemOperand(r9, -127, PostIndex)),
724             "e04987df       ldrd r8, [r9], #-127");
725     COMPARE(ldrd(r10, fp, MemOperand(fp, 127, PreIndex)),
726             "e1eba7df       ldrd r10, [fp, #+127]!");
727     COMPARE(ldrd(ip, sp, MemOperand(sp, -127, PreIndex)),
728             "e16dc7df       ldrd ip, [sp, #-127]!");
729 
730     COMPARE(strd(r0, r1, MemOperand(r1)),
731             "e1c100f0       strd r0, [r1, #+0]");
732     COMPARE(strd(r2, r3, MemOperand(r3, 127)),
733             "e1c327ff       strd r2, [r3, #+127]");
734     COMPARE(strd(r4, r5, MemOperand(r5, -127)),
735             "e14547ff       strd r4, [r5, #-127]");
736     COMPARE(strd(r6, r7, MemOperand(r7, 127, PostIndex)),
737             "e0c767ff       strd r6, [r7], #+127");
738     COMPARE(strd(r8, r9, MemOperand(r9, -127, PostIndex)),
739             "e04987ff       strd r8, [r9], #-127");
740     COMPARE(strd(r10, fp, MemOperand(fp, 127, PreIndex)),
741             "e1eba7ff       strd r10, [fp, #+127]!");
742     COMPARE(strd(ip, sp, MemOperand(sp, -127, PreIndex)),
743             "e16dc7ff       strd ip, [sp, #-127]!");
744   }
745 
746   VERIFY_RUN();
747 }
748 
749