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
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.
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.
32 #include "src/debug.h"
33 #include "src/disasm.h"
34 #include "src/disassembler.h"
35 #include "src/ic/ic.h"
36 #include "src/macro-assembler.h"
37 #include "test/cctest/cctest.h"
39 using namespace v8::internal;
45 static void DummyStaticFunction(Object* result) {
50 CcTest::InitializeVM();
51 Isolate* isolate = CcTest::i_isolate();
52 HandleScope scope(isolate);
53 v8::internal::byte buffer[4096];
54 Assembler assm(isolate, buffer, sizeof buffer);
55 DummyStaticFunction(NULL); // just bloody use it (DELETE; debugging)
57 // Short immediate instructions
58 __ adc(eax, 12345678);
59 __ add(eax, Immediate(12345678));
60 __ or_(eax, 12345678);
61 __ sub(eax, Immediate(12345678));
62 __ xor_(eax, 12345678);
63 __ and_(eax, 12345678);
64 Handle<FixedArray> foo = isolate->factory()->NewFixedArray(10, TENURED);
67 // ---- This one caused crash
68 __ mov(ebx, Operand(esp, ecx, times_2, 0)); // [esp+ecx*4]
70 // ---- All instructions that I can think of
72 __ add(edx, Operand(12, RelocInfo::NONE32));
73 __ add(edx, Operand(ebx, 0));
74 __ add(edx, Operand(ebx, 16));
75 __ add(edx, Operand(ebx, 1999));
76 __ add(edx, Operand(ebx, -4));
77 __ add(edx, Operand(ebx, -1999));
78 __ add(edx, Operand(esp, 0));
79 __ add(edx, Operand(esp, 16));
80 __ add(edx, Operand(esp, 1999));
81 __ add(edx, Operand(esp, -4));
82 __ add(edx, Operand(esp, -1999));
84 __ add(esi, Operand(ecx, times_4, 0));
85 __ add(esi, Operand(ecx, times_4, 24));
86 __ add(esi, Operand(ecx, times_4, -4));
87 __ add(esi, Operand(ecx, times_4, -1999));
89 __ add(edi, Operand(ebp, ecx, times_4, 0));
90 __ add(edi, Operand(ebp, ecx, times_4, 12));
91 __ add(edi, Operand(ebp, ecx, times_4, -8));
92 __ add(edi, Operand(ebp, ecx, times_4, -3999));
93 __ add(Operand(ebp, ecx, times_4, 12), Immediate(12));
96 __ add(ebx, Immediate(12));
102 __ and_(edx, Operand(esp, 4));
104 __ cmp(edx, Operand(esp, 4));
105 __ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
106 Handle<FixedArray> foo2 = isolate->factory()->NewFixedArray(10, TENURED);
108 __ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
109 __ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
114 __ movsx_b(edx, ecx);
115 __ movsx_w(edx, ecx);
116 __ movzx_b(edx, ecx);
117 __ movzx_w(edx, ecx);
124 __ bts(Operand(ebx, ecx, times_4, 0), ecx);
130 __ push(Immediate(12));
131 __ push(Immediate(23456));
134 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
135 __ push(Operand(ebx, ecx, times_4, 0));
136 __ push(Operand(ebx, ecx, times_4, 0));
137 __ push(Operand(ebx, ecx, times_4, 10000));
140 __ pop(Operand(ebx, ecx, times_4, 0));
143 __ add(edx, Operand(esp, 16));
147 __ mov_b(Operand(ebx, ecx, times_4, 10000), 6);
148 __ mov_b(Operand(esp, 16), edx);
149 __ mov_w(edx, Operand(esp, 16));
150 __ mov_w(Operand(esp, 16), edx);
152 __ movsx_w(edx, Operand(esp, 12));
153 __ movsx_b(edx, Operand(esp, 12));
154 __ movzx_w(edx, Operand(esp, 12));
155 __ movzx_b(edx, Operand(esp, 12));
157 __ mov(edx, 1234567);
158 __ mov(edx, Operand(esp, 12));
159 __ mov(Operand(ebx, ecx, times_4, 10000), Immediate(12345));
160 __ mov(Operand(ebx, ecx, times_4, 10000), edx);
163 __ dec_b(Operand(eax, 10));
164 __ dec_b(Operand(ebx, ecx, times_4, 10000));
170 __ idiv(Operand(edx, ecx, times_1, 1));
171 __ idiv(Operand(esp, 12));
173 __ div(Operand(edx, ecx, times_1, 1));
174 __ div(Operand(esp, 12));
178 __ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456));
180 __ imul(edx, Operand(ebx, ecx, times_4, 10000));
181 __ imul(edx, ecx, 12);
182 __ imul(edx, Operand(edx, eax, times_2, 42), 8);
183 __ imul(edx, ecx, 1000);
184 __ imul(edx, Operand(ebx, ecx, times_4, 1), 9000);
187 __ inc(Operand(ebx, ecx, times_4, 10000));
188 __ push(Operand(ebx, ecx, times_4, 10000));
189 __ pop(Operand(ebx, ecx, times_4, 10000));
190 __ call(Operand(ebx, ecx, times_4, 10000));
191 __ jmp(Operand(ebx, ecx, times_4, 10000));
193 __ lea(edx, Operand(ebx, ecx, times_4, 10000));
195 __ or_(edx, Operand(ebx, ecx, times_4, 10000));
206 __ ror(Operand(ebx, ecx, times_4, 10000), 1);
207 __ ror(Operand(ebx, ecx, times_4, 10000), 6);
208 __ ror_cl(Operand(ebx, ecx, times_4, 10000));
212 __ sar(Operand(ebx, ecx, times_4, 10000), 1);
213 __ sar(Operand(ebx, ecx, times_4, 10000), 6);
214 __ sar_cl(Operand(ebx, ecx, times_4, 10000));
215 __ sbb(edx, Operand(ebx, ecx, times_4, 10000));
216 __ shld(edx, Operand(ebx, ecx, times_4, 10000));
220 __ shl(Operand(ebx, ecx, times_4, 10000), 1);
221 __ shl(Operand(ebx, ecx, times_4, 10000), 6);
222 __ shl_cl(Operand(ebx, ecx, times_4, 10000));
223 __ shrd(edx, Operand(ebx, ecx, times_4, 10000));
227 __ shr(Operand(ebx, ecx, times_4, 10000), 1);
228 __ shr(Operand(ebx, ecx, times_4, 10000), 6);
229 __ shr_cl(Operand(ebx, ecx, times_4, 10000));
236 __ add(ebx, Immediate(12));
237 __ add(Operand(edx, ecx, times_4, 10000), Immediate(12));
242 __ cmp(ebx, Immediate(12));
243 __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
248 __ sub(ebx, Immediate(12));
249 __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
253 __ imul(edx, ecx, 12);
254 __ imul(edx, ecx, 1000);
261 __ sub(edx, Operand(ebx, ecx, times_4, 10000));
264 __ test(edx, Immediate(12345));
265 __ test(edx, Operand(ebx, ecx, times_8, 10000));
266 __ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000));
267 __ test_b(edx, Operand(ecx, ebx, times_2, 1000));
268 __ test_b(Operand(eax, -20), 0x9A);
272 __ xor_(edx, Operand(ebx, ecx, times_8, 10000));
273 __ bts(Operand(ebx, ecx, times_8, 10000), edx);
288 __ call(Operand(ebx, ecx, times_4, 10000));
290 Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
291 __ call(ic, RelocInfo::CODE_TARGET);
293 __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
297 __ jmp(Operand(ebx, ecx, times_4, 10000));
298 ExternalReference after_break_target =
299 ExternalReference::debug_after_break_target_address(isolate);
300 __ jmp(Operand::StaticVariable(after_break_target));
301 __ jmp(ic, RelocInfo::CODE_TARGET);
308 __ j(overflow, &Ljcc);
309 __ j(no_overflow, &Ljcc);
311 __ j(above_equal, &Ljcc);
313 __ j(not_equal, &Ljcc);
314 __ j(below_equal, &Ljcc);
317 __ j(not_sign, &Ljcc);
318 __ j(parity_even, &Ljcc);
319 __ j(parity_odd, &Ljcc);
321 __ j(greater_equal, &Ljcc);
322 __ j(less_equal, &Ljcc);
323 __ j(greater, &Ljcc);
327 __ j(overflow, &Ljcc);
328 __ j(no_overflow, &Ljcc);
330 __ j(above_equal, &Ljcc);
332 __ j(not_equal, &Ljcc);
333 __ j(below_equal, &Ljcc);
336 __ j(not_sign, &Ljcc);
337 __ j(parity_even, &Ljcc);
338 __ j(parity_odd, &Ljcc);
340 __ j(greater_equal, &Ljcc);
341 __ j(less_equal, &Ljcc);
342 __ j(greater, &Ljcc);
358 __ fld_s(Operand(ebx, ecx, times_4, 10000));
359 __ fstp_s(Operand(ebx, ecx, times_4, 10000));
361 __ fld_d(Operand(ebx, ecx, times_4, 10000));
362 __ fstp_d(Operand(ebx, ecx, times_4, 10000));
365 __ fild_s(Operand(ebx, ecx, times_4, 10000));
366 __ fistp_s(Operand(ebx, ecx, times_4, 10000));
367 __ fild_d(Operand(ebx, ecx, times_4, 10000));
368 __ fistp_d(Operand(ebx, ecx, times_4, 10000));
389 __ movaps(xmm0, xmm1);
390 __ shufps(xmm0, xmm0, 0x0);
391 __ cvtsd2ss(xmm0, xmm1);
392 __ cvtsd2ss(xmm0, Operand(ebx, ecx, times_4, 10000));
395 __ andps(xmm0, xmm1);
396 __ andps(xmm0, Operand(ebx, ecx, times_4, 10000));
398 __ orps(xmm0, Operand(ebx, ecx, times_4, 10000));
399 __ xorps(xmm0, xmm1);
400 __ xorps(xmm0, Operand(ebx, ecx, times_4, 10000));
402 // Arithmetic operation
403 __ addss(xmm1, xmm0);
404 __ addss(xmm1, Operand(ebx, ecx, times_4, 10000));
405 __ mulss(xmm1, xmm0);
406 __ mulss(xmm1, Operand(ebx, ecx, times_4, 10000));
407 __ subss(xmm1, xmm0);
408 __ subss(xmm1, Operand(ebx, ecx, times_4, 10000));
409 __ divss(xmm1, xmm0);
410 __ divss(xmm1, Operand(ebx, ecx, times_4, 10000));
411 __ addps(xmm1, xmm0);
412 __ addps(xmm1, Operand(ebx, ecx, times_4, 10000));
413 __ subps(xmm1, xmm0);
414 __ subps(xmm1, Operand(ebx, ecx, times_4, 10000));
415 __ mulps(xmm1, xmm0);
416 __ mulps(xmm1, Operand(ebx, ecx, times_4, 10000));
417 __ divps(xmm1, xmm0);
418 __ divps(xmm1, Operand(ebx, ecx, times_4, 10000));
420 __ ucomiss(xmm0, xmm1);
421 __ ucomiss(xmm0, Operand(ebx, ecx, times_4, 10000));
424 __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
425 __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
426 __ cvtss2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
427 __ cvtss2sd(xmm1, xmm0);
428 __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000));
429 __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1);
430 // 128 bit move instructions.
431 __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
432 __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
433 __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
434 __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
436 __ addsd(xmm1, xmm0);
437 __ addsd(xmm1, Operand(ebx, ecx, times_4, 10000));
438 __ mulsd(xmm1, xmm0);
439 __ mulsd(xmm1, Operand(ebx, ecx, times_4, 10000));
440 __ subsd(xmm1, xmm0);
441 __ subsd(xmm1, Operand(ebx, ecx, times_4, 10000));
442 __ divsd(xmm1, xmm0);
443 __ divsd(xmm1, Operand(ebx, ecx, times_4, 10000));
444 __ minsd(xmm1, xmm0);
445 __ minsd(xmm1, Operand(ebx, ecx, times_4, 10000));
446 __ maxsd(xmm1, xmm0);
447 __ maxsd(xmm1, Operand(ebx, ecx, times_4, 10000));
448 __ ucomisd(xmm0, xmm1);
449 __ cmpltsd(xmm0, xmm1);
451 __ andpd(xmm0, xmm1);
453 __ psllq(xmm0, xmm1);
455 __ psrlq(xmm0, xmm1);
458 __ pcmpeqd(xmm1, xmm0);
460 __ punpckldq(xmm1, xmm6);
461 __ punpckhdq(xmm7, xmm5);
466 __ cmov(overflow, eax, Operand(eax, 0));
467 __ cmov(no_overflow, eax, Operand(eax, 1));
468 __ cmov(below, eax, Operand(eax, 2));
469 __ cmov(above_equal, eax, Operand(eax, 3));
470 __ cmov(equal, eax, Operand(ebx, 0));
471 __ cmov(not_equal, eax, Operand(ebx, 1));
472 __ cmov(below_equal, eax, Operand(ebx, 2));
473 __ cmov(above, eax, Operand(ebx, 3));
474 __ cmov(sign, eax, Operand(ecx, 0));
475 __ cmov(not_sign, eax, Operand(ecx, 1));
476 __ cmov(parity_even, eax, Operand(ecx, 2));
477 __ cmov(parity_odd, eax, Operand(ecx, 3));
478 __ cmov(less, eax, Operand(edx, 0));
479 __ cmov(greater_equal, eax, Operand(edx, 1));
480 __ cmov(less_equal, eax, Operand(edx, 2));
481 __ cmov(greater, eax, Operand(edx, 3));
485 if (CpuFeatures::IsSupported(SSE4_1)) {
486 CpuFeatureScope scope(&assm, SSE4_1);
487 __ pextrd(eax, xmm0, 1);
488 __ pinsrd(xmm1, eax, 0);
489 __ extractps(eax, xmm1, 0);
495 if (CpuFeatures::IsSupported(AVX)) {
496 CpuFeatureScope scope(&assm, AVX);
497 __ vaddsd(xmm0, xmm1, xmm2);
498 __ vaddsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
499 __ vmulsd(xmm0, xmm1, xmm2);
500 __ vmulsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
501 __ vsubsd(xmm0, xmm1, xmm2);
502 __ vsubsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
503 __ vdivsd(xmm0, xmm1, xmm2);
504 __ vdivsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
505 __ vminsd(xmm0, xmm1, xmm2);
506 __ vminsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
507 __ vmaxsd(xmm0, xmm1, xmm2);
508 __ vmaxsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
514 if (CpuFeatures::IsSupported(FMA3)) {
515 CpuFeatureScope scope(&assm, FMA3);
516 __ vfmadd132sd(xmm0, xmm1, xmm2);
517 __ vfmadd132sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
518 __ vfmadd213sd(xmm0, xmm1, xmm2);
519 __ vfmadd213sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
520 __ vfmadd231sd(xmm0, xmm1, xmm2);
521 __ vfmadd231sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
523 __ vfmsub132sd(xmm0, xmm1, xmm2);
524 __ vfmsub132sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
525 __ vfmsub213sd(xmm0, xmm1, xmm2);
526 __ vfmsub213sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
527 __ vfmsub231sd(xmm0, xmm1, xmm2);
528 __ vfmsub231sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
530 __ vfnmadd132sd(xmm0, xmm1, xmm2);
531 __ vfnmadd132sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
532 __ vfnmadd213sd(xmm0, xmm1, xmm2);
533 __ vfnmadd213sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
534 __ vfnmadd231sd(xmm0, xmm1, xmm2);
535 __ vfnmadd231sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
537 __ vfnmsub132sd(xmm0, xmm1, xmm2);
538 __ vfnmsub132sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
539 __ vfnmsub213sd(xmm0, xmm1, xmm2);
540 __ vfnmsub213sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
541 __ vfnmsub231sd(xmm0, xmm1, xmm2);
542 __ vfnmsub231sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
544 __ vfmadd132ss(xmm0, xmm1, xmm2);
545 __ vfmadd132ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
546 __ vfmadd213ss(xmm0, xmm1, xmm2);
547 __ vfmadd213ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
548 __ vfmadd231ss(xmm0, xmm1, xmm2);
549 __ vfmadd231ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
551 __ vfmsub132ss(xmm0, xmm1, xmm2);
552 __ vfmsub132ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
553 __ vfmsub213ss(xmm0, xmm1, xmm2);
554 __ vfmsub213ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
555 __ vfmsub231ss(xmm0, xmm1, xmm2);
556 __ vfmsub231ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
558 __ vfnmadd132ss(xmm0, xmm1, xmm2);
559 __ vfnmadd132ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
560 __ vfnmadd213ss(xmm0, xmm1, xmm2);
561 __ vfnmadd213ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
562 __ vfnmadd231ss(xmm0, xmm1, xmm2);
563 __ vfnmadd231ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
565 __ vfnmsub132ss(xmm0, xmm1, xmm2);
566 __ vfnmsub132ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
567 __ vfnmsub213ss(xmm0, xmm1, xmm2);
568 __ vfnmsub213ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
569 __ vfnmsub231ss(xmm0, xmm1, xmm2);
570 __ vfnmsub231ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
579 __ xchg(ebx, Operand(esp, 12));
583 for (int i = 0; i < 16; i++) {
591 Handle<Code> code = isolate->factory()->NewCode(
592 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
597 byte* begin = code->instruction_start();
598 byte* end = begin + code->instruction_size();
599 disasm::Disassembler::Disassemble(stdout, begin, end);