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 "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 
     42 #define __ assm.
     43 
     44 
     45 static void DummyStaticFunction(Object* result) {
     46 }
     47 
     48 
     49 TEST(DisasmX64) {
     50   CcTest::InitializeVM();
     51   v8::HandleScope scope;
     52   v8::internal::byte buffer[2048];
     53   Assembler assm(Isolate::Current(), buffer, sizeof buffer);
     54   DummyStaticFunction(NULL);  // just bloody use it (DELETE; debugging)
     55 
     56   // Short immediate instructions
     57   __ addq(rax, Immediate(12345678));
     58   __ or_(rax, Immediate(12345678));
     59   __ subq(rax, Immediate(12345678));
     60   __ xor_(rax, Immediate(12345678));
     61   __ and_(rax, Immediate(12345678));
     62 
     63   // ---- This one caused crash
     64   __ movq(rbx,  Operand(rsp, rcx, times_2, 0));  // [rsp+rcx*4]
     65 
     66   // ---- All instructions that I can think of
     67   __ addq(rdx, rbx);
     68   __ addq(rdx, Operand(rbx, 0));
     69   __ addq(rdx, Operand(rbx, 16));
     70   __ addq(rdx, Operand(rbx, 1999));
     71   __ addq(rdx, Operand(rsp, 0));
     72   __ addq(rdx, Operand(rsp, 16));
     73   __ addq(rdx, Operand(rsp, 1999));
     74   __ nop();
     75   __ addq(rdi, Operand(rbp, rcx, times_4, 0));
     76   __ addq(rdi, Operand(rbp, rcx, times_4, 12));
     77   __ addq(Operand(rbp, rcx, times_4, 12), Immediate(12));
     78 
     79   __ nop();
     80   __ addq(rbx, Immediate(12));
     81   __ nop();
     82   __ nop();
     83   __ and_(rdx, Immediate(3));
     84   __ and_(rdx, Operand(rsp, 4));
     85   __ cmpq(rdx, Immediate(3));
     86   __ cmpq(rdx, Operand(rsp, 4));
     87   __ cmpq(Operand(rbp, rcx, times_4, 0), Immediate(1000));
     88   __ cmpb(rbx, Operand(rbp, rcx, times_2, 0));
     89   __ cmpb(Operand(rbp, rcx, times_2, 0), rbx);
     90   __ or_(rdx, Immediate(3));
     91   __ xor_(rdx, Immediate(3));
     92   __ nop();
     93   {
     94     CHECK(CpuFeatures::IsSupported(CPUID));
     95     CpuFeatures::Scope fscope(CPUID);
     96     __ cpuid();
     97   }
     98   {
     99     CHECK(CpuFeatures::IsSupported(RDTSC));
    100     CpuFeatures::Scope fscope(RDTSC);
    101     __ rdtsc();
    102   }
    103   __ movsxbq(rdx, Operand(rcx, 0));
    104   __ movsxwq(rdx, Operand(rcx, 0));
    105   __ movzxbl(rdx, Operand(rcx, 0));
    106   __ movzxwl(rdx, Operand(rcx, 0));
    107   __ movzxbq(rdx, Operand(rcx, 0));
    108   __ movzxwq(rdx, Operand(rcx, 0));
    109 
    110   __ nop();
    111   __ imul(rdx, rcx);
    112   __ shld(rdx, rcx);
    113   __ shrd(rdx, rcx);
    114   __ bts(Operand(rdx, 0), rcx);
    115   __ bts(Operand(rbx, rcx, times_4, 0), rcx);
    116   __ nop();
    117   __ push(Immediate(12));
    118   __ push(Immediate(23456));
    119   __ push(rcx);
    120   __ push(rsi);
    121   __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
    122   __ push(Operand(rbx, rcx, times_4, 0));
    123   __ push(Operand(rbx, rcx, times_4, 0));
    124   __ push(Operand(rbx, rcx, times_4, 10000));
    125   __ pop(rdx);
    126   __ pop(rax);
    127   __ pop(Operand(rbx, rcx, times_4, 0));
    128   __ nop();
    129 
    130   __ addq(rdx, Operand(rsp, 16));
    131   __ addq(rdx, rcx);
    132   __ movb(rdx, Operand(rcx, 0));
    133   __ movb(rcx, Immediate(6));
    134   __ movb(Operand(rsp, 16), rdx);
    135   __ movw(Operand(rsp, 16), rdx);
    136   __ nop();
    137   __ movsxwq(rdx, Operand(rsp, 12));
    138   __ movsxbq(rdx, Operand(rsp, 12));
    139   __ movsxlq(rdx, Operand(rsp, 12));
    140   __ movzxwq(rdx, Operand(rsp, 12));
    141   __ movzxbq(rdx, Operand(rsp, 12));
    142   __ nop();
    143   __ movq(rdx, Immediate(1234567));
    144   __ movq(rdx, Operand(rsp, 12));
    145   __ movq(Operand(rbx, rcx, times_4, 10000), Immediate(12345));
    146   __ movq(Operand(rbx, rcx, times_4, 10000), rdx);
    147   __ nop();
    148   __ decb(rdx);
    149   __ decb(Operand(rax, 10));
    150   __ decb(Operand(rbx, rcx, times_4, 10000));
    151   __ decq(rdx);
    152   __ cdq();
    153 
    154   __ nop();
    155   __ idivq(rdx);
    156   __ mul(rdx);
    157   __ neg(rdx);
    158   __ not_(rdx);
    159   __ testq(Operand(rbx, rcx, times_4, 10000), rdx);
    160 
    161   __ imul(rdx, Operand(rbx, rcx, times_4, 10000));
    162   __ imul(rdx, rcx, Immediate(12));
    163   __ imul(rdx, rcx, Immediate(1000));
    164 
    165   __ incq(rdx);
    166   __ incq(Operand(rbx, rcx, times_4, 10000));
    167   __ push(Operand(rbx, rcx, times_4, 10000));
    168   __ pop(Operand(rbx, rcx, times_4, 10000));
    169   __ jmp(Operand(rbx, rcx, times_4, 10000));
    170 
    171   __ lea(rdx, Operand(rbx, rcx, times_4, 10000));
    172   __ or_(rdx, Immediate(12345));
    173   __ or_(rdx, Operand(rbx, rcx, times_4, 10000));
    174 
    175   __ nop();
    176 
    177   __ rcl(rdx, Immediate(1));
    178   __ rcl(rdx, Immediate(7));
    179   __ rcr(rdx, Immediate(1));
    180   __ rcr(rdx, Immediate(7));
    181   __ sar(rdx, Immediate(1));
    182   __ sar(rdx, Immediate(6));
    183   __ sar_cl(rdx);
    184   __ sbbq(rdx, rbx);
    185   __ shld(rdx, rbx);
    186   __ shl(rdx, Immediate(1));
    187   __ shl(rdx, Immediate(6));
    188   __ shl_cl(rdx);
    189   __ shrd(rdx, rbx);
    190   __ shr(rdx, Immediate(1));
    191   __ shr(rdx, Immediate(7));
    192   __ shr_cl(rdx);
    193 
    194 
    195   // Immediates
    196 
    197   __ addq(rbx, Immediate(12));
    198   __ addq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
    199 
    200   __ and_(rbx, Immediate(12345));
    201 
    202   __ cmpq(rbx, Immediate(12345));
    203   __ cmpq(rbx, Immediate(12));
    204   __ cmpq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
    205   __ cmpb(rax, Immediate(100));
    206 
    207   __ or_(rbx, Immediate(12345));
    208 
    209   __ subq(rbx, Immediate(12));
    210   __ subq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
    211 
    212   __ xor_(rbx, Immediate(12345));
    213 
    214   __ imul(rdx, rcx, Immediate(12));
    215   __ imul(rdx, rcx, Immediate(1000));
    216 
    217   __ cld();
    218 
    219   __ subq(rdx, Operand(rbx, rcx, times_4, 10000));
    220   __ subq(rdx, rbx);
    221 
    222   __ testq(rdx, Immediate(12345));
    223   __ testq(Operand(rbx, rcx, times_8, 10000), rdx);
    224   __ testb(Operand(rcx, rbx, times_2, 1000), rdx);
    225   __ testb(Operand(rax, -20), Immediate(0x9A));
    226   __ nop();
    227 
    228   __ xor_(rdx, Immediate(12345));
    229   __ xor_(rdx, Operand(rbx, rcx, times_8, 10000));
    230   __ bts(Operand(rbx, rcx, times_8, 10000), rdx);
    231   __ hlt();
    232   __ int3();
    233   __ ret(0);
    234   __ ret(8);
    235 
    236   // Calls
    237 
    238   Label L1, L2;
    239   __ bind(&L1);
    240   __ nop();
    241   __ call(&L1);
    242   __ call(&L2);
    243   __ nop();
    244   __ bind(&L2);
    245   __ call(Operand(rbx, rcx, times_4, 10000));
    246   __ nop();
    247   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
    248       Builtins::kLoadIC_Initialize));
    249   __ call(ic, RelocInfo::CODE_TARGET);
    250   __ nop();
    251   __ nop();
    252 
    253   __ jmp(&L1);
    254   __ jmp(Operand(rbx, rcx, times_4, 10000));
    255 #ifdef ENABLE_DEBUGGER_SUPPORT
    256   ExternalReference after_break_target =
    257       ExternalReference(Debug_Address::AfterBreakTarget(),
    258                         assm.isolate());
    259   USE(after_break_target);
    260 #endif  // ENABLE_DEBUGGER_SUPPORT
    261   __ jmp(ic, RelocInfo::CODE_TARGET);
    262   __ nop();
    263 
    264 
    265   Label Ljcc;
    266   __ nop();
    267   // long jumps
    268   __ j(overflow, &Ljcc);
    269   __ j(no_overflow, &Ljcc);
    270   __ j(below, &Ljcc);
    271   __ j(above_equal, &Ljcc);
    272   __ j(equal, &Ljcc);
    273   __ j(not_equal, &Ljcc);
    274   __ j(below_equal, &Ljcc);
    275   __ j(above, &Ljcc);
    276   __ j(sign, &Ljcc);
    277   __ j(not_sign, &Ljcc);
    278   __ j(parity_even, &Ljcc);
    279   __ j(parity_odd, &Ljcc);
    280   __ j(less, &Ljcc);
    281   __ j(greater_equal, &Ljcc);
    282   __ j(less_equal, &Ljcc);
    283   __ j(greater, &Ljcc);
    284   __ nop();
    285   __ bind(&Ljcc);
    286   // short jumps
    287   __ j(overflow, &Ljcc);
    288   __ j(no_overflow, &Ljcc);
    289   __ j(below, &Ljcc);
    290   __ j(above_equal, &Ljcc);
    291   __ j(equal, &Ljcc);
    292   __ j(not_equal, &Ljcc);
    293   __ j(below_equal, &Ljcc);
    294   __ j(above, &Ljcc);
    295   __ j(sign, &Ljcc);
    296   __ j(not_sign, &Ljcc);
    297   __ j(parity_even, &Ljcc);
    298   __ j(parity_odd, &Ljcc);
    299   __ j(less, &Ljcc);
    300   __ j(greater_equal, &Ljcc);
    301   __ j(less_equal, &Ljcc);
    302   __ j(greater, &Ljcc);
    303 
    304   // 0xD9 instructions
    305   __ nop();
    306 
    307   __ fld(1);
    308   __ fld1();
    309   __ fldz();
    310   __ fldpi();
    311   __ fabs();
    312   __ fchs();
    313   __ fprem();
    314   __ fprem1();
    315   __ fincstp();
    316   __ ftst();
    317   __ fxch(3);
    318   __ fld_s(Operand(rbx, rcx, times_4, 10000));
    319   __ fstp_s(Operand(rbx, rcx, times_4, 10000));
    320   __ ffree(3);
    321   __ fld_d(Operand(rbx, rcx, times_4, 10000));
    322   __ fstp_d(Operand(rbx, rcx, times_4, 10000));
    323   __ nop();
    324 
    325   __ fild_s(Operand(rbx, rcx, times_4, 10000));
    326   __ fistp_s(Operand(rbx, rcx, times_4, 10000));
    327   __ fild_d(Operand(rbx, rcx, times_4, 10000));
    328   __ fistp_d(Operand(rbx, rcx, times_4, 10000));
    329   __ fnstsw_ax();
    330   __ nop();
    331   __ fadd(3);
    332   __ fsub(3);
    333   __ fmul(3);
    334   __ fdiv(3);
    335 
    336   __ faddp(3);
    337   __ fsubp(3);
    338   __ fmulp(3);
    339   __ fdivp(3);
    340   __ fcompp();
    341   __ fwait();
    342   __ nop();
    343   {
    344     if (CpuFeatures::IsSupported(SSE2)) {
    345       CpuFeatures::Scope fscope(SSE2);
    346       __ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000));
    347       __ cvttss2si(rdx, xmm1);
    348       __ cvttsd2si(rdx, Operand(rbx, rcx, times_4, 10000));
    349       __ cvttsd2si(rdx, xmm1);
    350       __ cvttsd2siq(rdx, xmm1);
    351       __ addsd(xmm1, xmm0);
    352       __ mulsd(xmm1, xmm0);
    353       __ subsd(xmm1, xmm0);
    354       __ divsd(xmm1, xmm0);
    355       __ movsd(xmm1, Operand(rbx, rcx, times_4, 10000));
    356       __ movsd(Operand(rbx, rcx, times_4, 10000), xmm1);
    357       __ ucomisd(xmm0, xmm1);
    358 
    359       // 128 bit move instructions.
    360       __ movdqa(xmm0, Operand(rbx, rcx, times_4, 10000));
    361       __ movdqa(Operand(rbx, rcx, times_4, 10000), xmm0);
    362     }
    363   }
    364 
    365   // cmov.
    366   {
    367     if (CpuFeatures::IsSupported(CMOV)) {
    368       CpuFeatures::Scope use_cmov(CMOV);
    369       __ cmovq(overflow, rax, Operand(rax, 0));
    370       __ cmovq(no_overflow, rax, Operand(rax, 1));
    371       __ cmovq(below, rax, Operand(rax, 2));
    372       __ cmovq(above_equal, rax, Operand(rax, 3));
    373       __ cmovq(equal, rax, Operand(rbx, 0));
    374       __ cmovq(not_equal, rax, Operand(rbx, 1));
    375       __ cmovq(below_equal, rax, Operand(rbx, 2));
    376       __ cmovq(above, rax, Operand(rbx, 3));
    377       __ cmovq(sign, rax, Operand(rcx, 0));
    378       __ cmovq(not_sign, rax, Operand(rcx, 1));
    379       __ cmovq(parity_even, rax, Operand(rcx, 2));
    380       __ cmovq(parity_odd, rax, Operand(rcx, 3));
    381       __ cmovq(less, rax, Operand(rdx, 0));
    382       __ cmovq(greater_equal, rax, Operand(rdx, 1));
    383       __ cmovq(less_equal, rax, Operand(rdx, 2));
    384       __ cmovq(greater, rax, Operand(rdx, 3));
    385     }
    386   }
    387 
    388   // andpd, etc.
    389   {
    390     if (CpuFeatures::IsSupported(SSE2)) {
    391       CpuFeatures::Scope fscope(SSE2);
    392       __ andpd(xmm0, xmm1);
    393       __ andpd(xmm1, xmm2);
    394 
    395       __ movaps(xmm0, xmm1);
    396       __ movaps(xmm1, xmm2);
    397     }
    398   }
    399 
    400   // Nop instructions
    401   for (int i = 0; i < 16; i++) {
    402     __ Nop(i);
    403   }
    404 
    405   __ ret(0);
    406 
    407   CodeDesc desc;
    408   assm.GetCode(&desc);
    409   Object* code = HEAP->CreateCode(
    410       desc,
    411       Code::ComputeFlags(Code::STUB),
    412       Handle<Code>())->ToObjectChecked();
    413   CHECK(code->IsCode());
    414 #ifdef OBJECT_PRINT
    415   Code::cast(code)->Print();
    416   byte* begin = Code::cast(code)->instruction_start();
    417   byte* end = begin + Code::cast(code)->instruction_size();
    418   disasm::Disassembler::Disassemble(stdout, begin, end);
    419 #endif
    420 }
    421 
    422 #undef __
    423