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