Home | History | Annotate | Download | only in cctest
      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 "src/v8.h"
     31 
     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 "src/serialize.h"
     38 #include "test/cctest/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(DisasmX64) {
     51   CcTest::InitializeVM();
     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   __ addq(rax, Immediate(12345678));
     60   __ orq(rax, Immediate(12345678));
     61   __ subq(rax, Immediate(12345678));
     62   __ xorq(rax, Immediate(12345678));
     63   __ andq(rax, Immediate(12345678));
     64 
     65   // ---- This one caused crash
     66   __ movq(rbx,  Operand(rsp, rcx, times_2, 0));  // [rsp+rcx*4]
     67 
     68   // ---- All instructions that I can think of
     69   __ addq(rdx, rbx);
     70   __ addq(rdx, Operand(rbx, 0));
     71   __ addq(rdx, Operand(rbx, 16));
     72   __ addq(rdx, Operand(rbx, 1999));
     73   __ addq(rdx, Operand(rbx, -4));
     74   __ addq(rdx, Operand(rbx, -1999));
     75   __ addq(rdx, Operand(rsp, 0));
     76   __ addq(rdx, Operand(rsp, 16));
     77   __ addq(rdx, Operand(rsp, 1999));
     78   __ addq(rdx, Operand(rsp, -4));
     79   __ addq(rdx, Operand(rsp, -1999));
     80   __ nop();
     81   __ addq(rsi, Operand(rcx, times_4, 0));
     82   __ addq(rsi, Operand(rcx, times_4, 24));
     83   __ addq(rsi, Operand(rcx, times_4, -4));
     84   __ addq(rsi, Operand(rcx, times_4, -1999));
     85   __ nop();
     86   __ addq(rdi, Operand(rbp, rcx, times_4, 0));
     87   __ addq(rdi, Operand(rbp, rcx, times_4, 12));
     88   __ addq(rdi, Operand(rbp, rcx, times_4, -8));
     89   __ addq(rdi, Operand(rbp, rcx, times_4, -3999));
     90   __ addq(Operand(rbp, rcx, times_4, 12), Immediate(12));
     91 
     92   __ nop();
     93   __ addq(rbx, Immediate(12));
     94   __ nop();
     95   __ nop();
     96   __ andq(rdx, Immediate(3));
     97   __ andq(rdx, Operand(rsp, 4));
     98   __ cmpq(rdx, Immediate(3));
     99   __ cmpq(rdx, Operand(rsp, 4));
    100   __ cmpq(Operand(rbp, rcx, times_4, 0), Immediate(1000));
    101   __ cmpb(rbx, Operand(rbp, rcx, times_2, 0));
    102   __ cmpb(Operand(rbp, rcx, times_2, 0), rbx);
    103   __ orq(rdx, Immediate(3));
    104   __ xorq(rdx, Immediate(3));
    105   __ nop();
    106   __ cpuid();
    107   __ movsxbl(rdx, Operand(rcx, 0));
    108   __ movsxbq(rdx, Operand(rcx, 0));
    109   __ movsxwl(rdx, Operand(rcx, 0));
    110   __ movsxwq(rdx, Operand(rcx, 0));
    111   __ movzxbl(rdx, Operand(rcx, 0));
    112   __ movzxwl(rdx, Operand(rcx, 0));
    113   __ movzxbq(rdx, Operand(rcx, 0));
    114   __ movzxwq(rdx, Operand(rcx, 0));
    115 
    116   __ nop();
    117   __ imulq(rdx, rcx);
    118   __ shld(rdx, rcx);
    119   __ shrd(rdx, rcx);
    120   __ bts(Operand(rdx, 0), rcx);
    121   __ bts(Operand(rbx, rcx, times_4, 0), rcx);
    122   __ nop();
    123   __ pushq(Immediate(12));
    124   __ pushq(Immediate(23456));
    125   __ pushq(rcx);
    126   __ pushq(rsi);
    127   __ pushq(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
    128   __ pushq(Operand(rbx, rcx, times_4, 0));
    129   __ pushq(Operand(rbx, rcx, times_4, 0));
    130   __ pushq(Operand(rbx, rcx, times_4, 10000));
    131   __ popq(rdx);
    132   __ popq(rax);
    133   __ popq(Operand(rbx, rcx, times_4, 0));
    134   __ nop();
    135 
    136   __ addq(rdx, Operand(rsp, 16));
    137   __ addq(rdx, rcx);
    138   __ movb(rdx, Operand(rcx, 0));
    139   __ movb(rcx, Immediate(6));
    140   __ movb(Operand(rsp, 16), rdx);
    141   __ movw(Operand(rsp, 16), rdx);
    142   __ nop();
    143   __ movsxwq(rdx, Operand(rsp, 12));
    144   __ movsxbq(rdx, Operand(rsp, 12));
    145   __ movsxlq(rdx, Operand(rsp, 12));
    146   __ movzxwq(rdx, Operand(rsp, 12));
    147   __ movzxbq(rdx, Operand(rsp, 12));
    148   __ nop();
    149   __ movq(rdx, Immediate(1234567));
    150   __ movq(rdx, Operand(rsp, 12));
    151   __ movq(Operand(rbx, rcx, times_4, 10000), Immediate(12345));
    152   __ movq(Operand(rbx, rcx, times_4, 10000), rdx);
    153   __ nop();
    154   __ decb(rdx);
    155   __ decb(Operand(rax, 10));
    156   __ decb(Operand(rbx, rcx, times_4, 10000));
    157   __ decq(rdx);
    158   __ cdq();
    159 
    160   __ nop();
    161   __ idivq(rdx);
    162   __ mul(rdx);
    163   __ negq(rdx);
    164   __ notq(rdx);
    165   __ testq(Operand(rbx, rcx, times_4, 10000), rdx);
    166 
    167   __ imulq(rdx, Operand(rbx, rcx, times_4, 10000));
    168   __ imulq(rdx, rcx, Immediate(12));
    169   __ imulq(rdx, rcx, Immediate(1000));
    170 
    171   __ incq(rdx);
    172   __ incq(Operand(rbx, rcx, times_4, 10000));
    173   __ pushq(Operand(rbx, rcx, times_4, 10000));
    174   __ popq(Operand(rbx, rcx, times_4, 10000));
    175   // TODO(mstarzinger): The following is protected.
    176   // __ jmp(Operand(rbx, rcx, times_4, 10000));
    177 
    178   __ leaq(rdx, Operand(rbx, rcx, times_4, 10000));
    179   __ orq(rdx, Immediate(12345));
    180   __ orq(rdx, Operand(rbx, rcx, times_4, 10000));
    181 
    182   __ nop();
    183 
    184   __ rclq(rdx, Immediate(1));
    185   __ rclq(rdx, Immediate(7));
    186   __ rcrq(rdx, Immediate(1));
    187   __ rcrq(rdx, Immediate(7));
    188   __ sarq(rdx, Immediate(1));
    189   __ sarq(rdx, Immediate(6));
    190   __ sarq_cl(rdx);
    191   __ sbbq(rdx, rbx);
    192   __ shld(rdx, rbx);
    193   __ shlq(rdx, Immediate(1));
    194   __ shlq(rdx, Immediate(6));
    195   __ shlq_cl(rdx);
    196   __ shrd(rdx, rbx);
    197   __ shrq(rdx, Immediate(1));
    198   __ shrq(rdx, Immediate(7));
    199   __ shrq_cl(rdx);
    200 
    201 
    202   // Immediates
    203 
    204   __ addq(rbx, Immediate(12));
    205   __ addq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
    206 
    207   __ andq(rbx, Immediate(12345));
    208 
    209   __ cmpq(rbx, Immediate(12345));
    210   __ cmpq(rbx, Immediate(12));
    211   __ cmpq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
    212   __ cmpb(rax, Immediate(100));
    213 
    214   __ orq(rbx, Immediate(12345));
    215 
    216   __ subq(rbx, Immediate(12));
    217   __ subq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
    218 
    219   __ xorq(rbx, Immediate(12345));
    220 
    221   __ imulq(rdx, rcx, Immediate(12));
    222   __ imulq(rdx, rcx, Immediate(1000));
    223 
    224   __ cld();
    225 
    226   __ subq(rdx, Operand(rbx, rcx, times_4, 10000));
    227   __ subq(rdx, rbx);
    228 
    229   __ testq(rdx, Immediate(12345));
    230   __ testq(Operand(rbx, rcx, times_8, 10000), rdx);
    231   __ testb(Operand(rcx, rbx, times_2, 1000), rdx);
    232   __ testb(Operand(rax, -20), Immediate(0x9A));
    233   __ nop();
    234 
    235   __ xorq(rdx, Immediate(12345));
    236   __ xorq(rdx, Operand(rbx, rcx, times_8, 10000));
    237   __ bts(Operand(rbx, rcx, times_8, 10000), rdx);
    238   __ hlt();
    239   __ int3();
    240   __ ret(0);
    241   __ ret(8);
    242 
    243   // Calls
    244 
    245   Label L1, L2;
    246   __ bind(&L1);
    247   __ nop();
    248   __ call(&L1);
    249   __ call(&L2);
    250   __ nop();
    251   __ bind(&L2);
    252   // TODO(mstarzinger): The following is protected.
    253   // __ call(Operand(rbx, rcx, times_4, 10000));
    254   __ nop();
    255   Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
    256   __ call(ic, RelocInfo::CODE_TARGET);
    257   __ nop();
    258   __ nop();
    259 
    260   __ jmp(&L1);
    261   // TODO(mstarzinger): The following is protected.
    262   // __ jmp(Operand(rbx, rcx, times_4, 10000));
    263   ExternalReference after_break_target =
    264       ExternalReference::debug_after_break_target_address(isolate);
    265   USE(after_break_target);
    266   __ jmp(ic, RelocInfo::CODE_TARGET);
    267   __ nop();
    268 
    269 
    270   Label Ljcc;
    271   __ nop();
    272   // long jumps
    273   __ j(overflow, &Ljcc);
    274   __ j(no_overflow, &Ljcc);
    275   __ j(below, &Ljcc);
    276   __ j(above_equal, &Ljcc);
    277   __ j(equal, &Ljcc);
    278   __ j(not_equal, &Ljcc);
    279   __ j(below_equal, &Ljcc);
    280   __ j(above, &Ljcc);
    281   __ j(sign, &Ljcc);
    282   __ j(not_sign, &Ljcc);
    283   __ j(parity_even, &Ljcc);
    284   __ j(parity_odd, &Ljcc);
    285   __ j(less, &Ljcc);
    286   __ j(greater_equal, &Ljcc);
    287   __ j(less_equal, &Ljcc);
    288   __ j(greater, &Ljcc);
    289   __ nop();
    290   __ bind(&Ljcc);
    291   // short jumps
    292   __ j(overflow, &Ljcc);
    293   __ j(no_overflow, &Ljcc);
    294   __ j(below, &Ljcc);
    295   __ j(above_equal, &Ljcc);
    296   __ j(equal, &Ljcc);
    297   __ j(not_equal, &Ljcc);
    298   __ j(below_equal, &Ljcc);
    299   __ j(above, &Ljcc);
    300   __ j(sign, &Ljcc);
    301   __ j(not_sign, &Ljcc);
    302   __ j(parity_even, &Ljcc);
    303   __ j(parity_odd, &Ljcc);
    304   __ j(less, &Ljcc);
    305   __ j(greater_equal, &Ljcc);
    306   __ j(less_equal, &Ljcc);
    307   __ j(greater, &Ljcc);
    308 
    309   // 0xD9 instructions
    310   __ nop();
    311 
    312   __ fld(1);
    313   __ fld1();
    314   __ fldz();
    315   __ fldpi();
    316   __ fabs();
    317   __ fchs();
    318   __ fprem();
    319   __ fprem1();
    320   __ fincstp();
    321   __ ftst();
    322   __ fxch(3);
    323   __ fld_s(Operand(rbx, rcx, times_4, 10000));
    324   __ fstp_s(Operand(rbx, rcx, times_4, 10000));
    325   __ ffree(3);
    326   __ fld_d(Operand(rbx, rcx, times_4, 10000));
    327   __ fstp_d(Operand(rbx, rcx, times_4, 10000));
    328   __ nop();
    329 
    330   __ fild_s(Operand(rbx, rcx, times_4, 10000));
    331   __ fistp_s(Operand(rbx, rcx, times_4, 10000));
    332   __ fild_d(Operand(rbx, rcx, times_4, 10000));
    333   __ fistp_d(Operand(rbx, rcx, times_4, 10000));
    334   __ fnstsw_ax();
    335   __ nop();
    336   __ fadd(3);
    337   __ fsub(3);
    338   __ fmul(3);
    339   __ fdiv(3);
    340 
    341   __ faddp(3);
    342   __ fsubp(3);
    343   __ fmulp(3);
    344   __ fdivp(3);
    345   __ fcompp();
    346   __ fwait();
    347   __ frndint();
    348   __ fninit();
    349   __ nop();
    350 
    351   // SSE instruction
    352   {
    353     // Move operation
    354     __ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000));
    355     __ cvttss2si(rdx, xmm1);
    356     __ movaps(xmm0, xmm1);
    357 
    358     // logic operation
    359     __ andps(xmm0, xmm1);
    360     __ andps(xmm0, Operand(rbx, rcx, times_4, 10000));
    361     __ orps(xmm0, xmm1);
    362     __ orps(xmm0, Operand(rbx, rcx, times_4, 10000));
    363     __ xorps(xmm0, xmm1);
    364     __ xorps(xmm0, Operand(rbx, rcx, times_4, 10000));
    365 
    366     // Arithmetic operation
    367     __ addps(xmm1, xmm0);
    368     __ addps(xmm1, Operand(rbx, rcx, times_4, 10000));
    369     __ subps(xmm1, xmm0);
    370     __ subps(xmm1, Operand(rbx, rcx, times_4, 10000));
    371     __ mulps(xmm1, xmm0);
    372     __ mulps(xmm1, Operand(rbx, rcx, times_4, 10000));
    373     __ divps(xmm1, xmm0);
    374     __ divps(xmm1, Operand(rbx, rcx, times_4, 10000));
    375   }
    376   // SSE 2 instructions
    377   {
    378     __ cvttsd2si(rdx, Operand(rbx, rcx, times_4, 10000));
    379     __ cvttsd2si(rdx, xmm1);
    380     __ cvttsd2siq(rdx, xmm1);
    381     __ cvttsd2siq(rdx, Operand(rbx, rcx, times_4, 10000));
    382     __ movsd(xmm1, Operand(rbx, rcx, times_4, 10000));
    383     __ movsd(Operand(rbx, rcx, times_4, 10000), xmm1);
    384     // 128 bit move instructions.
    385     __ movdqa(xmm0, Operand(rbx, rcx, times_4, 10000));
    386     __ movdqa(Operand(rbx, rcx, times_4, 10000), xmm0);
    387 
    388     __ addsd(xmm1, xmm0);
    389     __ mulsd(xmm1, xmm0);
    390     __ subsd(xmm1, xmm0);
    391     __ divsd(xmm1, xmm0);
    392     __ ucomisd(xmm0, xmm1);
    393 
    394     __ andpd(xmm0, xmm1);
    395   }
    396 
    397   // cmov.
    398   {
    399     __ cmovq(overflow, rax, Operand(rax, 0));
    400     __ cmovq(no_overflow, rax, Operand(rax, 1));
    401     __ cmovq(below, rax, Operand(rax, 2));
    402     __ cmovq(above_equal, rax, Operand(rax, 3));
    403     __ cmovq(equal, rax, Operand(rbx, 0));
    404     __ cmovq(not_equal, rax, Operand(rbx, 1));
    405     __ cmovq(below_equal, rax, Operand(rbx, 2));
    406     __ cmovq(above, rax, Operand(rbx, 3));
    407     __ cmovq(sign, rax, Operand(rcx, 0));
    408     __ cmovq(not_sign, rax, Operand(rcx, 1));
    409     __ cmovq(parity_even, rax, Operand(rcx, 2));
    410     __ cmovq(parity_odd, rax, Operand(rcx, 3));
    411     __ cmovq(less, rax, Operand(rdx, 0));
    412     __ cmovq(greater_equal, rax, Operand(rdx, 1));
    413     __ cmovq(less_equal, rax, Operand(rdx, 2));
    414     __ cmovq(greater, rax, Operand(rdx, 3));
    415   }
    416 
    417   {
    418     if (CpuFeatures::IsSupported(SSE4_1)) {
    419       CpuFeatureScope scope(&assm, SSE4_1);
    420       __ extractps(rax, xmm1, 0);
    421     }
    422   }
    423 
    424   // xchg.
    425   {
    426     __ xchgq(rax, rax);
    427     __ xchgq(rax, rbx);
    428     __ xchgq(rbx, rbx);
    429     __ xchgq(rbx, Operand(rsp, 12));
    430   }
    431 
    432   // Nop instructions
    433   for (int i = 0; i < 16; i++) {
    434     __ Nop(i);
    435   }
    436 
    437   __ ret(0);
    438 
    439   CodeDesc desc;
    440   assm.GetCode(&desc);
    441   Handle<Code> code = isolate->factory()->NewCode(
    442       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    443   USE(code);
    444 #ifdef OBJECT_PRINT
    445   OFStream os(stdout);
    446   code->Print(os);
    447   byte* begin = code->instruction_start();
    448   byte* end = begin + code->instruction_size();
    449   disasm::Disassembler::Disassemble(stdout, begin, end);
    450 #endif
    451 }
    452 
    453 #undef __
    454