v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-disasm-ia32.cc
Go to the documentation of this file.
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 #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 "stub-cache.h"
38 #include "cctest.h"
39 
40 using namespace v8::internal;
41 
42 
43 #define __ assm.
44 
45 
46 static void DummyStaticFunction(Object* result) {
47 }
48 
49 
50 TEST(DisasmIa320) {
52  Isolate* isolate = CcTest::i_isolate();
53  HandleScope scope(isolate);
54  v8::internal::byte buffer[2048];
55  Assembler assm(isolate, buffer, sizeof buffer);
56  DummyStaticFunction(NULL); // just bloody use it (DELETE; debugging)
57 
58  // Short immediate instructions
59  __ adc(eax, 12345678);
60  __ add(eax, Immediate(12345678));
61  __ or_(eax, 12345678);
62  __ sub(eax, Immediate(12345678));
63  __ xor_(eax, 12345678);
64  __ and_(eax, 12345678);
66  __ cmp(eax, foo);
67 
68  // ---- This one caused crash
69  __ mov(ebx, Operand(esp, ecx, times_2, 0)); // [esp+ecx*4]
70 
71  // ---- All instructions that I can think of
72  __ add(edx, ebx);
73  __ add(edx, Operand(12, RelocInfo::NONE32));
74  __ add(edx, Operand(ebx, 0));
75  __ add(edx, Operand(ebx, 16));
76  __ add(edx, Operand(ebx, 1999));
77  __ add(edx, Operand(ebx, -4));
78  __ add(edx, Operand(ebx, -1999));
79  __ add(edx, Operand(esp, 0));
80  __ add(edx, Operand(esp, 16));
81  __ add(edx, Operand(esp, 1999));
82  __ add(edx, Operand(esp, -4));
83  __ add(edx, Operand(esp, -1999));
84  __ nop();
85  __ add(esi, Operand(ecx, times_4, 0));
86  __ add(esi, Operand(ecx, times_4, 24));
87  __ add(esi, Operand(ecx, times_4, -4));
88  __ add(esi, Operand(ecx, times_4, -1999));
89  __ nop();
90  __ add(edi, Operand(ebp, ecx, times_4, 0));
91  __ add(edi, Operand(ebp, ecx, times_4, 12));
92  __ add(edi, Operand(ebp, ecx, times_4, -8));
93  __ add(edi, Operand(ebp, ecx, times_4, -3999));
94  __ add(Operand(ebp, ecx, times_4, 12), Immediate(12));
95 
96  __ nop();
97  __ add(ebx, Immediate(12));
98  __ nop();
99  __ adc(ecx, 12);
100  __ adc(ecx, 1000);
101  __ nop();
102  __ and_(edx, 3);
103  __ and_(edx, Operand(esp, 4));
104  __ cmp(edx, 3);
105  __ cmp(edx, Operand(esp, 4));
106  __ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
107  Handle<FixedArray> foo2 = isolate->factory()->NewFixedArray(10, TENURED);
108  __ cmp(ebx, foo2);
109  __ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
110  __ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
111  __ or_(edx, 3);
112  __ xor_(edx, 3);
113  __ nop();
114  __ cpuid();
115  __ movsx_b(edx, ecx);
116  __ movsx_w(edx, ecx);
117  __ movzx_b(edx, ecx);
118  __ movzx_w(edx, ecx);
119 
120  __ nop();
121  __ imul(edx, ecx);
122  __ shld(edx, ecx);
123  __ shrd(edx, ecx);
124  __ bts(edx, ecx);
125  __ bts(Operand(ebx, ecx, times_4, 0), ecx);
126  __ nop();
127  __ pushad();
128  __ popad();
129  __ pushfd();
130  __ popfd();
131  __ push(Immediate(12));
132  __ push(Immediate(23456));
133  __ push(ecx);
134  __ push(esi);
136  __ push(Operand(ebx, ecx, times_4, 0));
137  __ push(Operand(ebx, ecx, times_4, 0));
138  __ push(Operand(ebx, ecx, times_4, 10000));
139  __ pop(edx);
140  __ pop(eax);
141  __ pop(Operand(ebx, ecx, times_4, 0));
142  __ nop();
143 
144  __ add(edx, Operand(esp, 16));
145  __ add(edx, ecx);
146  __ mov_b(edx, ecx);
147  __ mov_b(ecx, 6);
148  __ mov_b(Operand(ebx, ecx, times_4, 10000), 6);
149  __ mov_b(Operand(esp, 16), edx);
150  __ mov_w(edx, Operand(esp, 16));
151  __ mov_w(Operand(esp, 16), edx);
152  __ nop();
153  __ movsx_w(edx, Operand(esp, 12));
154  __ movsx_b(edx, Operand(esp, 12));
155  __ movzx_w(edx, Operand(esp, 12));
156  __ movzx_b(edx, Operand(esp, 12));
157  __ nop();
158  __ mov(edx, 1234567);
159  __ mov(edx, Operand(esp, 12));
160  __ mov(Operand(ebx, ecx, times_4, 10000), Immediate(12345));
161  __ mov(Operand(ebx, ecx, times_4, 10000), edx);
162  __ nop();
163  __ dec_b(edx);
164  __ dec_b(Operand(eax, 10));
165  __ dec_b(Operand(ebx, ecx, times_4, 10000));
166  __ dec(edx);
167  __ cdq();
168 
169  __ nop();
170  __ idiv(edx);
171  __ mul(edx);
172  __ neg(edx);
173  __ not_(edx);
174  __ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456));
175 
176  __ imul(edx, Operand(ebx, ecx, times_4, 10000));
177  __ imul(edx, ecx, 12);
178  __ imul(edx, ecx, 1000);
179 
180  __ inc(edx);
181  __ inc(Operand(ebx, ecx, times_4, 10000));
182  __ push(Operand(ebx, ecx, times_4, 10000));
183  __ pop(Operand(ebx, ecx, times_4, 10000));
184  __ call(Operand(ebx, ecx, times_4, 10000));
185  __ jmp(Operand(ebx, ecx, times_4, 10000));
186 
187  __ lea(edx, Operand(ebx, ecx, times_4, 10000));
188  __ or_(edx, 12345);
189  __ or_(edx, Operand(ebx, ecx, times_4, 10000));
190 
191  __ nop();
192 
193  __ rcl(edx, 1);
194  __ rcl(edx, 7);
195  __ rcr(edx, 1);
196  __ rcr(edx, 7);
197  __ sar(edx, 1);
198  __ sar(edx, 6);
199  __ sar_cl(edx);
200  __ sbb(edx, Operand(ebx, ecx, times_4, 10000));
201  __ shld(edx, Operand(ebx, ecx, times_4, 10000));
202  __ shl(edx, 1);
203  __ shl(edx, 6);
204  __ shl_cl(edx);
205  __ shrd(edx, Operand(ebx, ecx, times_4, 10000));
206  __ shr(edx, 1);
207  __ shr(edx, 7);
208  __ shr_cl(edx);
209 
210 
211  // Immediates
212 
213  __ adc(edx, 12345);
214 
215  __ add(ebx, Immediate(12));
216  __ add(Operand(edx, ecx, times_4, 10000), Immediate(12));
217 
218  __ and_(ebx, 12345);
219 
220  __ cmp(ebx, 12345);
221  __ cmp(ebx, Immediate(12));
222  __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
223  __ cmpb(eax, 100);
224 
225  __ or_(ebx, 12345);
226 
227  __ sub(ebx, Immediate(12));
228  __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
229 
230  __ xor_(ebx, 12345);
231 
232  __ imul(edx, ecx, 12);
233  __ imul(edx, ecx, 1000);
234 
235  __ cld();
236  __ rep_movs();
237  __ rep_stos();
238  __ stos();
239 
240  __ sub(edx, Operand(ebx, ecx, times_4, 10000));
241  __ sub(edx, ebx);
242 
243  __ test(edx, Immediate(12345));
244  __ test(edx, Operand(ebx, ecx, times_8, 10000));
245  __ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000));
246  __ test_b(edx, Operand(ecx, ebx, times_2, 1000));
247  __ test_b(Operand(eax, -20), 0x9A);
248  __ nop();
249 
250  __ xor_(edx, 12345);
251  __ xor_(edx, Operand(ebx, ecx, times_8, 10000));
252  __ bts(Operand(ebx, ecx, times_8, 10000), edx);
253  __ hlt();
254  __ int3();
255  __ ret(0);
256  __ ret(8);
257 
258  // Calls
259 
260  Label L1, L2;
261  __ bind(&L1);
262  __ nop();
263  __ call(&L1);
264  __ call(&L2);
265  __ nop();
266  __ bind(&L2);
267  __ call(Operand(ebx, ecx, times_4, 10000));
268  __ nop();
270  __ call(ic, RelocInfo::CODE_TARGET);
271  __ nop();
272  __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
273  __ nop();
274 
275  __ jmp(&L1);
276  __ jmp(Operand(ebx, ecx, times_4, 10000));
277 #ifdef ENABLE_DEBUGGER_SUPPORT
278  ExternalReference after_break_target =
279  ExternalReference(Debug_Address::AfterBreakTarget(), isolate);
280  __ jmp(Operand::StaticVariable(after_break_target));
281 #endif // ENABLE_DEBUGGER_SUPPORT
282  __ jmp(ic, RelocInfo::CODE_TARGET);
283  __ nop();
284 
285 
286  Label Ljcc;
287  __ nop();
288  // long jumps
289  __ j(overflow, &Ljcc);
290  __ j(no_overflow, &Ljcc);
291  __ j(below, &Ljcc);
292  __ j(above_equal, &Ljcc);
293  __ j(equal, &Ljcc);
294  __ j(not_equal, &Ljcc);
295  __ j(below_equal, &Ljcc);
296  __ j(above, &Ljcc);
297  __ j(sign, &Ljcc);
298  __ j(not_sign, &Ljcc);
299  __ j(parity_even, &Ljcc);
300  __ j(parity_odd, &Ljcc);
301  __ j(less, &Ljcc);
302  __ j(greater_equal, &Ljcc);
303  __ j(less_equal, &Ljcc);
304  __ j(greater, &Ljcc);
305  __ nop();
306  __ bind(&Ljcc);
307  // short jumps
308  __ j(overflow, &Ljcc);
309  __ j(no_overflow, &Ljcc);
310  __ j(below, &Ljcc);
311  __ j(above_equal, &Ljcc);
312  __ j(equal, &Ljcc);
313  __ j(not_equal, &Ljcc);
314  __ j(below_equal, &Ljcc);
315  __ j(above, &Ljcc);
316  __ j(sign, &Ljcc);
317  __ j(not_sign, &Ljcc);
318  __ j(parity_even, &Ljcc);
319  __ j(parity_odd, &Ljcc);
320  __ j(less, &Ljcc);
321  __ j(greater_equal, &Ljcc);
322  __ j(less_equal, &Ljcc);
323  __ j(greater, &Ljcc);
324 
325  // 0xD9 instructions
326  __ nop();
327 
328  __ fld(1);
329  __ fld1();
330  __ fldz();
331  __ fldpi();
332  __ fabs();
333  __ fchs();
334  __ fprem();
335  __ fprem1();
336  __ fincstp();
337  __ ftst();
338  __ fxch(3);
339  __ fld_s(Operand(ebx, ecx, times_4, 10000));
340  __ fstp_s(Operand(ebx, ecx, times_4, 10000));
341  __ ffree(3);
342  __ fld_d(Operand(ebx, ecx, times_4, 10000));
343  __ fstp_d(Operand(ebx, ecx, times_4, 10000));
344  __ nop();
345 
346  __ fild_s(Operand(ebx, ecx, times_4, 10000));
347  __ fistp_s(Operand(ebx, ecx, times_4, 10000));
348  __ fild_d(Operand(ebx, ecx, times_4, 10000));
349  __ fistp_d(Operand(ebx, ecx, times_4, 10000));
350  __ fnstsw_ax();
351  __ nop();
352  __ fadd(3);
353  __ fsub(3);
354  __ fmul(3);
355  __ fdiv(3);
356 
357  __ faddp(3);
358  __ fsubp(3);
359  __ fmulp(3);
360  __ fdivp(3);
361  __ fcompp();
362  __ fwait();
363  __ frndint();
364  __ fninit();
365  __ nop();
366 
367  // SSE instruction
368  {
370  CpuFeatureScope fscope(&assm, SSE2);
371  // Move operation
372  __ movaps(xmm0, xmm1);
373  __ shufps(xmm0, xmm0, 0x0);
374 
375  // logic operation
376  __ andps(xmm0, xmm1);
377  __ andps(xmm0, Operand(ebx, ecx, times_4, 10000));
378  __ orps(xmm0, xmm1);
379  __ orps(xmm0, Operand(ebx, ecx, times_4, 10000));
380  __ xorps(xmm0, xmm1);
381  __ xorps(xmm0, Operand(ebx, ecx, times_4, 10000));
382 
383  // Arithmetic operation
384  __ addps(xmm1, xmm0);
385  __ addps(xmm1, Operand(ebx, ecx, times_4, 10000));
386  __ subps(xmm1, xmm0);
387  __ subps(xmm1, Operand(ebx, ecx, times_4, 10000));
388  __ mulps(xmm1, xmm0);
389  __ mulps(xmm1, Operand(ebx, ecx, times_4, 10000));
390  __ divps(xmm1, xmm0);
391  __ divps(xmm1, Operand(ebx, ecx, times_4, 10000));
392  }
393  }
394  {
396  CpuFeatureScope fscope(&assm, SSE2);
397  __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
398  __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
399  __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000));
400  __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1);
401  // 128 bit move instructions.
402  __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
403  __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
404  __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
405  __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
406 
407  __ addsd(xmm1, xmm0);
408  __ mulsd(xmm1, xmm0);
409  __ subsd(xmm1, xmm0);
410  __ divsd(xmm1, xmm0);
411  __ ucomisd(xmm0, xmm1);
412  __ cmpltsd(xmm0, xmm1);
413 
414  __ andpd(xmm0, xmm1);
415  __ psllq(xmm0, 17);
416  __ psllq(xmm0, xmm1);
417  __ psrlq(xmm0, 17);
418  __ psrlq(xmm0, xmm1);
419  __ por(xmm0, xmm1);
420  }
421  }
422 
423  // cmov.
424  {
426  CpuFeatureScope use_cmov(&assm, CMOV);
427  __ cmov(overflow, eax, Operand(eax, 0));
428  __ cmov(no_overflow, eax, Operand(eax, 1));
429  __ cmov(below, eax, Operand(eax, 2));
430  __ cmov(above_equal, eax, Operand(eax, 3));
431  __ cmov(equal, eax, Operand(ebx, 0));
432  __ cmov(not_equal, eax, Operand(ebx, 1));
433  __ cmov(below_equal, eax, Operand(ebx, 2));
434  __ cmov(above, eax, Operand(ebx, 3));
435  __ cmov(sign, eax, Operand(ecx, 0));
436  __ cmov(not_sign, eax, Operand(ecx, 1));
437  __ cmov(parity_even, eax, Operand(ecx, 2));
438  __ cmov(parity_odd, eax, Operand(ecx, 3));
439  __ cmov(less, eax, Operand(edx, 0));
440  __ cmov(greater_equal, eax, Operand(edx, 1));
441  __ cmov(less_equal, eax, Operand(edx, 2));
442  __ cmov(greater, eax, Operand(edx, 3));
443  }
444  }
445 
446  {
449  CpuFeatureScope scope(&assm, SSE4_1);
450  __ pextrd(eax, xmm0, 1);
451  __ pinsrd(xmm1, eax, 0);
452  __ extractps(eax, xmm1, 0);
453  }
454  }
455 
456  // Nop instructions
457  for (int i = 0; i < 16; i++) {
458  __ Nop(i);
459  }
460 
461  __ ret(0);
462 
463  CodeDesc desc;
464  assm.GetCode(&desc);
465  Object* code = isolate->heap()->CreateCode(
466  desc,
468  Handle<Code>())->ToObjectChecked();
469  CHECK(code->IsCode());
470 #ifdef OBJECT_PRINT
471  Code::cast(code)->Print();
472  byte* begin = Code::cast(code)->instruction_start();
473  byte* end = begin + Code::cast(code)->instruction_size();
474  disasm::Disassembler::Disassemble(stdout, begin, end);
475 #endif
476 }
477 
478 #undef __
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
static void Disassemble(FILE *f, byte *begin, byte *end)
const Register esp
static bool IsSupported(CpuFeature f)
Definition: assembler-arm.h:68
#define CHECK(condition)
Definition: checks.h:75
static Handle< Code > initialize_stub(Isolate *isolate, ExtraICState extra_state)
Definition: ic.cc:782
Factory * factory()
Definition: isolate.h:995
static Code * cast(Object *obj)
const Register edi
int foo
uint8_t byte
Definition: globals.h:185
const Register ebp
const Register eax
const XMMRegister xmm1
byte * instruction_start()
Definition: objects-inl.h:5857
void GetCode(CodeDesc *desc)
const Register ecx
#define __
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:53
static i::Isolate * i_isolate()
Definition: cctest.h:102
MUST_USE_RESULT MaybeObject * CreateCode(const CodeDesc &desc, Code::Flags flags, Handle< Object > self_reference, bool immovable=false, bool crankshafted=false, int prologue_offset=Code::kPrologueOffsetNotSet)
Definition: heap.cc:4119
static void InitializeVM()
Definition: cctest.h:116
const Register ebx
static Flags ComputeFlags(Kind kind, InlineCacheState ic_state=UNINITIALIZED, ExtraICState extra_ic_state=kNoExtraICState, StubType type=NORMAL, InlineCacheHolderFlag holder=OWN_MAP)
Definition: objects-inl.h:4601
const Register esi
#define RUNTIME_ENTRY(name, nargs, ressize)
const Register edx
#define FUNCTION_ADDR(f)
Definition: globals.h:345
const XMMRegister xmm0