• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2007-2008 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 // Setup 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 SETUP() \
76   InitializeVM(); \
77   v8::HandleScope scope; \
78   byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
79   Assembler assm(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 *pc = &buffer[pc_offset]; \
91     assm.asm_; \
92     if (!DisassembleAndCompare(pc, 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   SETUP();
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   VERIFY_RUN();
252 }
253 
254 
TEST(Type1)255 TEST(Type1) {
256   SETUP();
257 
258   COMPARE(and_(r0, r1, Operand(0x00000000)),
259           "e2010000       and r0, r1, #0");
260   COMPARE(and_(r1, r2, Operand(0x00000001), LeaveCC),
261           "e2021001       and r1, r2, #1");
262   COMPARE(and_(r2, r3, Operand(0x00000010), SetCC),
263           "e2132010       ands r2, r3, #16");
264   COMPARE(and_(r3, r4, Operand(0x00000100), LeaveCC, eq),
265           "02043c01       andeq r3, r4, #256");
266   COMPARE(and_(r4, r5, Operand(0x00001000), SetCC, ne),
267           "12154a01       andnes r4, r5, #4096");
268 
269   COMPARE(eor(r4, r5, Operand(0x00001000)),
270           "e2254a01       eor r4, r5, #4096");
271   COMPARE(eor(r4, r4, Operand(0x00010000), LeaveCC),
272           "e2244801       eor r4, r4, #65536");
273   COMPARE(eor(r4, r3, Operand(0x00100000), SetCC),
274           "e2334601       eors r4, r3, #1048576");
275   COMPARE(eor(r4, r2, Operand(0x01000000), LeaveCC, cs),
276           "22224401       eorcs r4, r2, #16777216");
277   COMPARE(eor(r4, r1, Operand(0x10000000), SetCC, cc),
278           "32314201       eorccs r4, r1, #268435456");
279 
280   VERIFY_RUN();
281 }
282