• 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 #include <stdlib.h>
29 
30 #include "v8.h"
31 
32 #include "debug.h"
33 #include "disasm.h"
34 #include "disassembler.h"
35 #include "macro-assembler.h"
36 #include "serialize.h"
37 #include "cctest.h"
38 
39 using namespace v8::internal;
40 
41 static v8::Persistent<v8::Context> env;
42 
InitializeVM()43 static void InitializeVM() {
44   if (env.IsEmpty()) {
45     env = v8::Context::New();
46   }
47 }
48 
49 
50 #define __ assm.
51 
52 
DummyStaticFunction(Object * result)53 static void DummyStaticFunction(Object* result) {
54 }
55 
56 
TEST(DisasmIa320)57 TEST(DisasmIa320) {
58   InitializeVM();
59   v8::HandleScope scope;
60   v8::internal::byte buffer[2048];
61   Assembler assm(Isolate::Current(), buffer, sizeof buffer);
62   DummyStaticFunction(NULL);  // just bloody use it (DELETE; debugging)
63 
64   // Short immediate instructions
65   __ adc(eax, 12345678);
66   __ add(Operand(eax), Immediate(12345678));
67   __ or_(eax, 12345678);
68   __ sub(Operand(eax), Immediate(12345678));
69   __ xor_(eax, 12345678);
70   __ and_(eax, 12345678);
71   Handle<FixedArray> foo = FACTORY->NewFixedArray(10, TENURED);
72   __ cmp(eax, foo);
73 
74   // ---- This one caused crash
75   __ mov(ebx,  Operand(esp, ecx, times_2, 0));  // [esp+ecx*4]
76 
77   // ---- All instructions that I can think of
78   __ add(edx, Operand(ebx));
79   __ add(edx, Operand(12, RelocInfo::NONE));
80   __ add(edx, Operand(ebx, 0));
81   __ add(edx, Operand(ebx, 16));
82   __ add(edx, Operand(ebx, 1999));
83   __ add(edx, Operand(esp, 0));
84   __ add(edx, Operand(esp, 16));
85   __ add(edx, Operand(esp, 1999));
86   __ nop();
87   __ add(edi, Operand(ebp, ecx, times_4, 0));
88   __ add(edi, Operand(ebp, ecx, times_4, 12));
89   __ add(Operand(ebp, ecx, times_4, 12), Immediate(12));
90 
91   __ nop();
92   __ add(Operand(ebx), Immediate(12));
93   __ nop();
94   __ adc(ecx, 12);
95   __ adc(ecx, 1000);
96   __ nop();
97   __ and_(edx, 3);
98   __ and_(edx, Operand(esp, 4));
99   __ cmp(edx, 3);
100   __ cmp(edx, Operand(esp, 4));
101   __ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
102   Handle<FixedArray> foo2 = FACTORY->NewFixedArray(10, TENURED);
103   __ cmp(ebx, foo2);
104   __ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
105   __ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
106   __ or_(edx, 3);
107   __ xor_(edx, 3);
108   __ nop();
109   {
110     CHECK(CpuFeatures::IsSupported(CPUID));
111     CpuFeatures::Scope fscope(CPUID);
112     __ cpuid();
113   }
114   {
115     CHECK(CpuFeatures::IsSupported(RDTSC));
116     CpuFeatures::Scope fscope(RDTSC);
117     __ rdtsc();
118   }
119   __ movsx_b(edx, Operand(ecx));
120   __ movsx_w(edx, Operand(ecx));
121   __ movzx_b(edx, Operand(ecx));
122   __ movzx_w(edx, Operand(ecx));
123 
124   __ nop();
125   __ imul(edx, Operand(ecx));
126   __ shld(edx, Operand(ecx));
127   __ shrd(edx, Operand(ecx));
128   __ bts(Operand(edx), ecx);
129   __ bts(Operand(ebx, ecx, times_4, 0), ecx);
130   __ nop();
131   __ pushad();
132   __ popad();
133   __ pushfd();
134   __ popfd();
135   __ push(Immediate(12));
136   __ push(Immediate(23456));
137   __ push(ecx);
138   __ push(esi);
139   __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
140   __ push(Operand(ebx, ecx, times_4, 0));
141   __ push(Operand(ebx, ecx, times_4, 0));
142   __ push(Operand(ebx, ecx, times_4, 10000));
143   __ pop(edx);
144   __ pop(eax);
145   __ pop(Operand(ebx, ecx, times_4, 0));
146   __ nop();
147 
148   __ add(edx, Operand(esp, 16));
149   __ add(edx, Operand(ecx));
150   __ mov_b(edx, Operand(ecx));
151   __ mov_b(Operand(ecx), 6);
152   __ mov_b(Operand(ebx, ecx, times_4, 10000), 6);
153   __ mov_b(Operand(esp, 16), edx);
154   __ mov_w(edx, Operand(esp, 16));
155   __ mov_w(Operand(esp, 16), edx);
156   __ nop();
157   __ movsx_w(edx, Operand(esp, 12));
158   __ movsx_b(edx, Operand(esp, 12));
159   __ movzx_w(edx, Operand(esp, 12));
160   __ movzx_b(edx, Operand(esp, 12));
161   __ nop();
162   __ mov(edx, 1234567);
163   __ mov(edx, Operand(esp, 12));
164   __ mov(Operand(ebx, ecx, times_4, 10000), Immediate(12345));
165   __ mov(Operand(ebx, ecx, times_4, 10000), edx);
166   __ nop();
167   __ dec_b(edx);
168   __ dec_b(Operand(eax, 10));
169   __ dec_b(Operand(ebx, ecx, times_4, 10000));
170   __ dec(edx);
171   __ cdq();
172 
173   __ nop();
174   __ idiv(edx);
175   __ mul(edx);
176   __ neg(edx);
177   __ not_(edx);
178   __ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456));
179 
180   __ imul(edx, Operand(ebx, ecx, times_4, 10000));
181   __ imul(edx, ecx, 12);
182   __ imul(edx, ecx, 1000);
183 
184   __ inc(edx);
185   __ inc(Operand(ebx, ecx, times_4, 10000));
186   __ push(Operand(ebx, ecx, times_4, 10000));
187   __ pop(Operand(ebx, ecx, times_4, 10000));
188   __ call(Operand(ebx, ecx, times_4, 10000));
189   __ jmp(Operand(ebx, ecx, times_4, 10000));
190 
191   __ lea(edx, Operand(ebx, ecx, times_4, 10000));
192   __ or_(edx, 12345);
193   __ or_(edx, Operand(ebx, ecx, times_4, 10000));
194 
195   __ nop();
196 
197   __ rcl(edx, 1);
198   __ rcl(edx, 7);
199   __ rcr(edx, 1);
200   __ rcr(edx, 7);
201   __ sar(edx, 1);
202   __ sar(edx, 6);
203   __ sar_cl(edx);
204   __ sbb(edx, Operand(ebx, ecx, times_4, 10000));
205   __ shld(edx, Operand(ebx, ecx, times_4, 10000));
206   __ shl(edx, 1);
207   __ shl(edx, 6);
208   __ shl_cl(edx);
209   __ shrd(edx, Operand(ebx, ecx, times_4, 10000));
210   __ shr(edx, 1);
211   __ shr(edx, 7);
212   __ shr_cl(edx);
213 
214 
215   // Immediates
216 
217   __ adc(edx, 12345);
218 
219   __ add(Operand(ebx), Immediate(12));
220   __ add(Operand(edx, ecx, times_4, 10000), Immediate(12));
221 
222   __ and_(ebx, 12345);
223 
224   __ cmp(ebx, 12345);
225   __ cmp(Operand(ebx), Immediate(12));
226   __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
227 
228   __ or_(ebx, 12345);
229 
230   __ sub(Operand(ebx), Immediate(12));
231   __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
232   __ subb(Operand(edx, ecx, times_4, 10000), 100);
233   __ subb(Operand(eax), 100);
234   __ subb(eax, Operand(edx, ecx, times_4, 10000));
235 
236   __ xor_(ebx, 12345);
237 
238   __ imul(edx, ecx, 12);
239   __ imul(edx, ecx, 1000);
240 
241   __ cld();
242   __ rep_movs();
243   __ rep_stos();
244   __ stos();
245 
246   __ sub(edx, Operand(ebx, ecx, times_4, 10000));
247   __ sub(edx, Operand(ebx));
248 
249   __ test(edx, Immediate(12345));
250   __ test(edx, Operand(ebx, ecx, times_8, 10000));
251   __ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000));
252   __ test_b(edx, Operand(ecx, ebx, times_2, 1000));
253   __ test_b(Operand(eax, -20), 0x9A);
254   __ nop();
255 
256   __ xor_(edx, 12345);
257   __ xor_(edx, Operand(ebx, ecx, times_8, 10000));
258   __ bts(Operand(ebx, ecx, times_8, 10000), edx);
259   __ hlt();
260   __ int3();
261   __ ret(0);
262   __ ret(8);
263 
264   // Calls
265 
266   Label L1, L2;
267   __ bind(&L1);
268   __ nop();
269   __ call(&L1);
270   __ call(&L2);
271   __ nop();
272   __ bind(&L2);
273   __ call(Operand(ebx, ecx, times_4, 10000));
274   __ nop();
275   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
276       Builtins::kLoadIC_Initialize));
277   __ call(ic, RelocInfo::CODE_TARGET);
278   __ nop();
279   __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
280   __ nop();
281 
282   __ jmp(&L1);
283   __ jmp(Operand(ebx, ecx, times_4, 10000));
284 #ifdef ENABLE_DEBUGGER_SUPPORT
285   ExternalReference after_break_target =
286       ExternalReference(Debug_Address::AfterBreakTarget(),
287                         assm.isolate());
288   __ jmp(Operand::StaticVariable(after_break_target));
289 #endif  // ENABLE_DEBUGGER_SUPPORT
290   __ jmp(ic, RelocInfo::CODE_TARGET);
291   __ nop();
292 
293 
294   Label Ljcc;
295   __ nop();
296   // long jumps
297   __ j(overflow, &Ljcc);
298   __ j(no_overflow, &Ljcc);
299   __ j(below, &Ljcc);
300   __ j(above_equal, &Ljcc);
301   __ j(equal, &Ljcc);
302   __ j(not_equal, &Ljcc);
303   __ j(below_equal, &Ljcc);
304   __ j(above, &Ljcc);
305   __ j(sign, &Ljcc);
306   __ j(not_sign, &Ljcc);
307   __ j(parity_even, &Ljcc);
308   __ j(parity_odd, &Ljcc);
309   __ j(less, &Ljcc);
310   __ j(greater_equal, &Ljcc);
311   __ j(less_equal, &Ljcc);
312   __ j(greater, &Ljcc);
313   __ nop();
314   __ bind(&Ljcc);
315   // short jumps
316   __ j(overflow, &Ljcc);
317   __ j(no_overflow, &Ljcc);
318   __ j(below, &Ljcc);
319   __ j(above_equal, &Ljcc);
320   __ j(equal, &Ljcc);
321   __ j(not_equal, &Ljcc);
322   __ j(below_equal, &Ljcc);
323   __ j(above, &Ljcc);
324   __ j(sign, &Ljcc);
325   __ j(not_sign, &Ljcc);
326   __ j(parity_even, &Ljcc);
327   __ j(parity_odd, &Ljcc);
328   __ j(less, &Ljcc);
329   __ j(greater_equal, &Ljcc);
330   __ j(less_equal, &Ljcc);
331   __ j(greater, &Ljcc);
332 
333   // checking hints
334   __ j(zero, &Ljcc, taken);
335   __ j(zero, &Ljcc, not_taken);
336 
337   // __ mov(Operand::StaticVariable(Isolate::handler_address()), eax);
338   // 0xD9 instructions
339   __ nop();
340 
341   __ fld(1);
342   __ fld1();
343   __ fldz();
344   __ fldpi();
345   __ fabs();
346   __ fchs();
347   __ fprem();
348   __ fprem1();
349   __ fincstp();
350   __ ftst();
351   __ fxch(3);
352   __ fld_s(Operand(ebx, ecx, times_4, 10000));
353   __ fstp_s(Operand(ebx, ecx, times_4, 10000));
354   __ ffree(3);
355   __ fld_d(Operand(ebx, ecx, times_4, 10000));
356   __ fstp_d(Operand(ebx, ecx, times_4, 10000));
357   __ nop();
358 
359   __ fild_s(Operand(ebx, ecx, times_4, 10000));
360   __ fistp_s(Operand(ebx, ecx, times_4, 10000));
361   __ fild_d(Operand(ebx, ecx, times_4, 10000));
362   __ fistp_d(Operand(ebx, ecx, times_4, 10000));
363   __ fnstsw_ax();
364   __ nop();
365   __ fadd(3);
366   __ fsub(3);
367   __ fmul(3);
368   __ fdiv(3);
369 
370   __ faddp(3);
371   __ fsubp(3);
372   __ fmulp(3);
373   __ fdivp(3);
374   __ fcompp();
375   __ fwait();
376   __ nop();
377   {
378     if (CpuFeatures::IsSupported(SSE2)) {
379       CpuFeatures::Scope fscope(SSE2);
380       __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
381       __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
382       __ addsd(xmm1, xmm0);
383       __ mulsd(xmm1, xmm0);
384       __ subsd(xmm1, xmm0);
385       __ divsd(xmm1, xmm0);
386       __ movdbl(xmm1, Operand(ebx, ecx, times_4, 10000));
387       __ movdbl(Operand(ebx, ecx, times_4, 10000), xmm1);
388       __ ucomisd(xmm0, xmm1);
389 
390       // 128 bit move instructions.
391       __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
392       __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
393       __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
394       __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
395     }
396   }
397 
398   // cmov.
399   {
400     if (CpuFeatures::IsSupported(CMOV)) {
401       CpuFeatures::Scope use_cmov(CMOV);
402       __ cmov(overflow, eax, Operand(eax, 0));
403       __ cmov(no_overflow, eax, Operand(eax, 1));
404       __ cmov(below, eax, Operand(eax, 2));
405       __ cmov(above_equal, eax, Operand(eax, 3));
406       __ cmov(equal, eax, Operand(ebx, 0));
407       __ cmov(not_equal, eax, Operand(ebx, 1));
408       __ cmov(below_equal, eax, Operand(ebx, 2));
409       __ cmov(above, eax, Operand(ebx, 3));
410       __ cmov(sign, eax, Operand(ecx, 0));
411       __ cmov(not_sign, eax, Operand(ecx, 1));
412       __ cmov(parity_even, eax, Operand(ecx, 2));
413       __ cmov(parity_odd, eax, Operand(ecx, 3));
414       __ cmov(less, eax, Operand(edx, 0));
415       __ cmov(greater_equal, eax, Operand(edx, 1));
416       __ cmov(less_equal, eax, Operand(edx, 2));
417       __ cmov(greater, eax, Operand(edx, 3));
418     }
419   }
420 
421   // andpd, cmpltsd, movaps, psllq, psrlq, por.
422   {
423     if (CpuFeatures::IsSupported(SSE2)) {
424       CpuFeatures::Scope fscope(SSE2);
425       __ andpd(xmm0, xmm1);
426       __ andpd(xmm1, xmm2);
427 
428       __ cmpltsd(xmm0, xmm1);
429       __ cmpltsd(xmm1, xmm2);
430 
431       __ movaps(xmm0, xmm1);
432       __ movaps(xmm1, xmm2);
433 
434       __ psllq(xmm0, 17);
435       __ psllq(xmm1, 42);
436 
437       __ psllq(xmm0, xmm1);
438       __ psllq(xmm1, xmm2);
439 
440       __ psrlq(xmm0, 17);
441       __ psrlq(xmm1, 42);
442 
443       __ psrlq(xmm0, xmm1);
444       __ psrlq(xmm1, xmm2);
445 
446       __ por(xmm0, xmm1);
447       __ por(xmm1, xmm2);
448     }
449   }
450 
451   {
452     if (CpuFeatures::IsSupported(SSE4_1)) {
453       CpuFeatures::Scope scope(SSE4_1);
454       __ pextrd(Operand(eax), xmm0, 1);
455       __ pinsrd(xmm1, Operand(eax), 0);
456     }
457   }
458 
459   __ ret(0);
460 
461   CodeDesc desc;
462   assm.GetCode(&desc);
463   Object* code = HEAP->CreateCode(
464       desc,
465       Code::ComputeFlags(Code::STUB),
466       Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
467   CHECK(code->IsCode());
468 #ifdef OBJECT_PRINT
469   Code::cast(code)->Print();
470   byte* begin = Code::cast(code)->instruction_start();
471   byte* end = begin + Code::cast(code)->instruction_size();
472   disasm::Disassembler::Disassemble(stdout, begin, end);
473 #endif
474 }
475 
476 #undef __
477