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/macro-assembler.h"
     36 #include "src/serialize.h"
     37 #include "src/stub-cache.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(DisasmIa320) {
     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   __ 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);
     65   Handle<FixedArray> foo = isolate->factory()->NewFixedArray(10, TENURED);
     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);
    135   __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
    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();
    269   Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
    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   ExternalReference after_break_target =
    278       ExternalReference::debug_after_break_target_address(isolate);
    279   __ jmp(Operand::StaticVariable(after_break_target));
    280   __ jmp(ic, RelocInfo::CODE_TARGET);
    281   __ nop();
    282 
    283 
    284   Label Ljcc;
    285   __ nop();
    286   // long 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   __ nop();
    304   __ bind(&Ljcc);
    305   // short jumps
    306   __ j(overflow, &Ljcc);
    307   __ j(no_overflow, &Ljcc);
    308   __ j(below, &Ljcc);
    309   __ j(above_equal, &Ljcc);
    310   __ j(equal, &Ljcc);
    311   __ j(not_equal, &Ljcc);
    312   __ j(below_equal, &Ljcc);
    313   __ j(above, &Ljcc);
    314   __ j(sign, &Ljcc);
    315   __ j(not_sign, &Ljcc);
    316   __ j(parity_even, &Ljcc);
    317   __ j(parity_odd, &Ljcc);
    318   __ j(less, &Ljcc);
    319   __ j(greater_equal, &Ljcc);
    320   __ j(less_equal, &Ljcc);
    321   __ j(greater, &Ljcc);
    322 
    323   // 0xD9 instructions
    324   __ nop();
    325 
    326   __ fld(1);
    327   __ fld1();
    328   __ fldz();
    329   __ fldpi();
    330   __ fabs();
    331   __ fchs();
    332   __ fprem();
    333   __ fprem1();
    334   __ fincstp();
    335   __ ftst();
    336   __ fxch(3);
    337   __ fld_s(Operand(ebx, ecx, times_4, 10000));
    338   __ fstp_s(Operand(ebx, ecx, times_4, 10000));
    339   __ ffree(3);
    340   __ fld_d(Operand(ebx, ecx, times_4, 10000));
    341   __ fstp_d(Operand(ebx, ecx, times_4, 10000));
    342   __ nop();
    343 
    344   __ fild_s(Operand(ebx, ecx, times_4, 10000));
    345   __ fistp_s(Operand(ebx, ecx, times_4, 10000));
    346   __ fild_d(Operand(ebx, ecx, times_4, 10000));
    347   __ fistp_d(Operand(ebx, ecx, times_4, 10000));
    348   __ fnstsw_ax();
    349   __ nop();
    350   __ fadd(3);
    351   __ fsub(3);
    352   __ fmul(3);
    353   __ fdiv(3);
    354 
    355   __ faddp(3);
    356   __ fsubp(3);
    357   __ fmulp(3);
    358   __ fdivp(3);
    359   __ fcompp();
    360   __ fwait();
    361   __ frndint();
    362   __ fninit();
    363   __ nop();
    364 
    365   // SSE instruction
    366   {
    367     // Move operation
    368     __ movaps(xmm0, xmm1);
    369     __ shufps(xmm0, xmm0, 0x0);
    370 
    371     // logic operation
    372     __ andps(xmm0, xmm1);
    373     __ andps(xmm0, Operand(ebx, ecx, times_4, 10000));
    374     __ orps(xmm0, xmm1);
    375     __ orps(xmm0, Operand(ebx, ecx, times_4, 10000));
    376     __ xorps(xmm0, xmm1);
    377     __ xorps(xmm0, Operand(ebx, ecx, times_4, 10000));
    378 
    379     // Arithmetic operation
    380     __ addps(xmm1, xmm0);
    381     __ addps(xmm1, Operand(ebx, ecx, times_4, 10000));
    382     __ subps(xmm1, xmm0);
    383     __ subps(xmm1, Operand(ebx, ecx, times_4, 10000));
    384     __ mulps(xmm1, xmm0);
    385     __ mulps(xmm1, Operand(ebx, ecx, times_4, 10000));
    386     __ divps(xmm1, xmm0);
    387     __ divps(xmm1, Operand(ebx, ecx, times_4, 10000));
    388   }
    389   {
    390     __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
    391     __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
    392     __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000));
    393     __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1);
    394     // 128 bit move instructions.
    395     __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
    396     __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
    397     __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
    398     __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
    399 
    400     __ addsd(xmm1, xmm0);
    401     __ mulsd(xmm1, xmm0);
    402     __ subsd(xmm1, xmm0);
    403     __ divsd(xmm1, xmm0);
    404     __ ucomisd(xmm0, xmm1);
    405     __ cmpltsd(xmm0, xmm1);
    406 
    407     __ andpd(xmm0, xmm1);
    408     __ psllq(xmm0, 17);
    409     __ psllq(xmm0, xmm1);
    410     __ psrlq(xmm0, 17);
    411     __ psrlq(xmm0, xmm1);
    412     __ por(xmm0, xmm1);
    413   }
    414 
    415   // cmov.
    416   {
    417     __ cmov(overflow, eax, Operand(eax, 0));
    418     __ cmov(no_overflow, eax, Operand(eax, 1));
    419     __ cmov(below, eax, Operand(eax, 2));
    420     __ cmov(above_equal, eax, Operand(eax, 3));
    421     __ cmov(equal, eax, Operand(ebx, 0));
    422     __ cmov(not_equal, eax, Operand(ebx, 1));
    423     __ cmov(below_equal, eax, Operand(ebx, 2));
    424     __ cmov(above, eax, Operand(ebx, 3));
    425     __ cmov(sign, eax, Operand(ecx, 0));
    426     __ cmov(not_sign, eax, Operand(ecx, 1));
    427     __ cmov(parity_even, eax, Operand(ecx, 2));
    428     __ cmov(parity_odd, eax, Operand(ecx, 3));
    429     __ cmov(less, eax, Operand(edx, 0));
    430     __ cmov(greater_equal, eax, Operand(edx, 1));
    431     __ cmov(less_equal, eax, Operand(edx, 2));
    432     __ cmov(greater, eax, Operand(edx, 3));
    433   }
    434 
    435   {
    436     if (CpuFeatures::IsSupported(SSE4_1)) {
    437       CpuFeatureScope scope(&assm, SSE4_1);
    438       __ pextrd(eax, xmm0, 1);
    439       __ pinsrd(xmm1, eax, 0);
    440       __ extractps(eax, xmm1, 0);
    441     }
    442   }
    443 
    444   // Nop instructions
    445   for (int i = 0; i < 16; i++) {
    446     __ Nop(i);
    447   }
    448 
    449   __ ret(0);
    450 
    451   CodeDesc desc;
    452   assm.GetCode(&desc);
    453   Handle<Code> code = isolate->factory()->NewCode(
    454       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    455   USE(code);
    456 #ifdef OBJECT_PRINT
    457   code->Print();
    458   byte* begin = code->instruction_start();
    459   byte* end = begin + code->instruction_size();
    460   disasm::Disassembler::Disassemble(stdout, begin, end);
    461 #endif
    462 }
    463 
    464 #undef __
    465