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(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   __ idiv(Operand(edx, ecx, times_1, 1));
    172   __ idiv(Operand(esp, 12));
    173   __ div(edx);
    174   __ div(Operand(edx, ecx, times_1, 1));
    175   __ div(Operand(esp, 12));
    176   __ mul(edx);
    177   __ neg(edx);
    178   __ not_(edx);
    179   __ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456));
    180 
    181   __ imul(edx, Operand(ebx, ecx, times_4, 10000));
    182   __ imul(edx, ecx, 12);
    183   __ imul(edx, Operand(edx, eax, times_2, 42), 8);
    184   __ imul(edx, ecx, 1000);
    185   __ imul(edx, Operand(ebx, ecx, times_4, 1), 9000);
    186 
    187   __ inc(edx);
    188   __ inc(Operand(ebx, ecx, times_4, 10000));
    189   __ push(Operand(ebx, ecx, times_4, 10000));
    190   __ pop(Operand(ebx, ecx, times_4, 10000));
    191   __ call(Operand(ebx, ecx, times_4, 10000));
    192   __ jmp(Operand(ebx, ecx, times_4, 10000));
    193 
    194   __ lea(edx, Operand(ebx, ecx, times_4, 10000));
    195   __ or_(edx, 12345);
    196   __ or_(edx, Operand(ebx, ecx, times_4, 10000));
    197 
    198   __ nop();
    199 
    200   __ rcl(edx, 1);
    201   __ rcl(edx, 7);
    202   __ rcr(edx, 1);
    203   __ rcr(edx, 7);
    204   __ sar(edx, 1);
    205   __ sar(edx, 6);
    206   __ sar_cl(edx);
    207   __ sar(Operand(ebx, ecx, times_4, 10000), 1);
    208   __ sar(Operand(ebx, ecx, times_4, 10000), 6);
    209   __ sar_cl(Operand(ebx, ecx, times_4, 10000));
    210   __ sbb(edx, Operand(ebx, ecx, times_4, 10000));
    211   __ shld(edx, Operand(ebx, ecx, times_4, 10000));
    212   __ shl(edx, 1);
    213   __ shl(edx, 6);
    214   __ shl_cl(edx);
    215   __ shl(Operand(ebx, ecx, times_4, 10000), 1);
    216   __ shl(Operand(ebx, ecx, times_4, 10000), 6);
    217   __ shl_cl(Operand(ebx, ecx, times_4, 10000));
    218   __ shrd(edx, Operand(ebx, ecx, times_4, 10000));
    219   __ shr(edx, 1);
    220   __ shr(edx, 7);
    221   __ shr_cl(edx);
    222   __ shr(Operand(ebx, ecx, times_4, 10000), 1);
    223   __ shr(Operand(ebx, ecx, times_4, 10000), 6);
    224   __ shr_cl(Operand(ebx, ecx, times_4, 10000));
    225 
    226 
    227   // Immediates
    228 
    229   __ adc(edx, 12345);
    230 
    231   __ add(ebx, Immediate(12));
    232   __ add(Operand(edx, ecx, times_4, 10000), Immediate(12));
    233 
    234   __ and_(ebx, 12345);
    235 
    236   __ cmp(ebx, 12345);
    237   __ cmp(ebx, Immediate(12));
    238   __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
    239   __ cmpb(eax, 100);
    240 
    241   __ or_(ebx, 12345);
    242 
    243   __ sub(ebx, Immediate(12));
    244   __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
    245 
    246   __ xor_(ebx, 12345);
    247 
    248   __ imul(edx, ecx, 12);
    249   __ imul(edx, ecx, 1000);
    250 
    251   __ cld();
    252   __ rep_movs();
    253   __ rep_stos();
    254   __ stos();
    255 
    256   __ sub(edx, Operand(ebx, ecx, times_4, 10000));
    257   __ sub(edx, ebx);
    258 
    259   __ test(edx, Immediate(12345));
    260   __ test(edx, Operand(ebx, ecx, times_8, 10000));
    261   __ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000));
    262   __ test_b(edx, Operand(ecx, ebx, times_2, 1000));
    263   __ test_b(Operand(eax, -20), 0x9A);
    264   __ nop();
    265 
    266   __ xor_(edx, 12345);
    267   __ xor_(edx, Operand(ebx, ecx, times_8, 10000));
    268   __ bts(Operand(ebx, ecx, times_8, 10000), edx);
    269   __ hlt();
    270   __ int3();
    271   __ ret(0);
    272   __ ret(8);
    273 
    274   // Calls
    275 
    276   Label L1, L2;
    277   __ bind(&L1);
    278   __ nop();
    279   __ call(&L1);
    280   __ call(&L2);
    281   __ nop();
    282   __ bind(&L2);
    283   __ call(Operand(ebx, ecx, times_4, 10000));
    284   __ nop();
    285   Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
    286   __ call(ic, RelocInfo::CODE_TARGET);
    287   __ nop();
    288   __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
    289   __ nop();
    290 
    291   __ jmp(&L1);
    292   __ jmp(Operand(ebx, ecx, times_4, 10000));
    293   ExternalReference after_break_target =
    294       ExternalReference::debug_after_break_target_address(isolate);
    295   __ jmp(Operand::StaticVariable(after_break_target));
    296   __ jmp(ic, RelocInfo::CODE_TARGET);
    297   __ nop();
    298 
    299 
    300   Label Ljcc;
    301   __ nop();
    302   // long jumps
    303   __ j(overflow, &Ljcc);
    304   __ j(no_overflow, &Ljcc);
    305   __ j(below, &Ljcc);
    306   __ j(above_equal, &Ljcc);
    307   __ j(equal, &Ljcc);
    308   __ j(not_equal, &Ljcc);
    309   __ j(below_equal, &Ljcc);
    310   __ j(above, &Ljcc);
    311   __ j(sign, &Ljcc);
    312   __ j(not_sign, &Ljcc);
    313   __ j(parity_even, &Ljcc);
    314   __ j(parity_odd, &Ljcc);
    315   __ j(less, &Ljcc);
    316   __ j(greater_equal, &Ljcc);
    317   __ j(less_equal, &Ljcc);
    318   __ j(greater, &Ljcc);
    319   __ nop();
    320   __ bind(&Ljcc);
    321   // short jumps
    322   __ j(overflow, &Ljcc);
    323   __ j(no_overflow, &Ljcc);
    324   __ j(below, &Ljcc);
    325   __ j(above_equal, &Ljcc);
    326   __ j(equal, &Ljcc);
    327   __ j(not_equal, &Ljcc);
    328   __ j(below_equal, &Ljcc);
    329   __ j(above, &Ljcc);
    330   __ j(sign, &Ljcc);
    331   __ j(not_sign, &Ljcc);
    332   __ j(parity_even, &Ljcc);
    333   __ j(parity_odd, &Ljcc);
    334   __ j(less, &Ljcc);
    335   __ j(greater_equal, &Ljcc);
    336   __ j(less_equal, &Ljcc);
    337   __ j(greater, &Ljcc);
    338 
    339   // 0xD9 instructions
    340   __ nop();
    341 
    342   __ fld(1);
    343   __ fld1();
    344   __ fldz();
    345   __ fldpi();
    346   __ fabs();
    347   __ fchs();
    348   __ fprem();
    349   __ fprem1();
    350   __ fincstp();
    351   __ ftst();
    352   __ fxch(3);
    353   __ fld_s(Operand(ebx, ecx, times_4, 10000));
    354   __ fstp_s(Operand(ebx, ecx, times_4, 10000));
    355   __ ffree(3);
    356   __ fld_d(Operand(ebx, ecx, times_4, 10000));
    357   __ fstp_d(Operand(ebx, ecx, times_4, 10000));
    358   __ nop();
    359 
    360   __ fild_s(Operand(ebx, ecx, times_4, 10000));
    361   __ fistp_s(Operand(ebx, ecx, times_4, 10000));
    362   __ fild_d(Operand(ebx, ecx, times_4, 10000));
    363   __ fistp_d(Operand(ebx, ecx, times_4, 10000));
    364   __ fnstsw_ax();
    365   __ nop();
    366   __ fadd(3);
    367   __ fsub(3);
    368   __ fmul(3);
    369   __ fdiv(3);
    370 
    371   __ faddp(3);
    372   __ fsubp(3);
    373   __ fmulp(3);
    374   __ fdivp(3);
    375   __ fcompp();
    376   __ fwait();
    377   __ frndint();
    378   __ fninit();
    379   __ nop();
    380 
    381   // SSE instruction
    382   {
    383     // Move operation
    384     __ movaps(xmm0, xmm1);
    385     __ shufps(xmm0, xmm0, 0x0);
    386 
    387     // logic operation
    388     __ andps(xmm0, xmm1);
    389     __ andps(xmm0, Operand(ebx, ecx, times_4, 10000));
    390     __ orps(xmm0, xmm1);
    391     __ orps(xmm0, Operand(ebx, ecx, times_4, 10000));
    392     __ xorps(xmm0, xmm1);
    393     __ xorps(xmm0, Operand(ebx, ecx, times_4, 10000));
    394 
    395     // Arithmetic operation
    396     __ addps(xmm1, xmm0);
    397     __ addps(xmm1, Operand(ebx, ecx, times_4, 10000));
    398     __ subps(xmm1, xmm0);
    399     __ subps(xmm1, Operand(ebx, ecx, times_4, 10000));
    400     __ mulps(xmm1, xmm0);
    401     __ mulps(xmm1, Operand(ebx, ecx, times_4, 10000));
    402     __ divps(xmm1, xmm0);
    403     __ divps(xmm1, Operand(ebx, ecx, times_4, 10000));
    404   }
    405   {
    406     __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
    407     __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
    408     __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000));
    409     __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1);
    410     // 128 bit move instructions.
    411     __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
    412     __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
    413     __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
    414     __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
    415 
    416     __ addsd(xmm1, xmm0);
    417     __ mulsd(xmm1, xmm0);
    418     __ subsd(xmm1, xmm0);
    419     __ subsd(xmm1, Operand(ebx, ecx, times_4, 10000));
    420     __ divsd(xmm1, xmm0);
    421     __ ucomisd(xmm0, xmm1);
    422     __ cmpltsd(xmm0, xmm1);
    423 
    424     __ andpd(xmm0, xmm1);
    425     __ psllq(xmm0, 17);
    426     __ psllq(xmm0, xmm1);
    427     __ psrlq(xmm0, 17);
    428     __ psrlq(xmm0, xmm1);
    429     __ por(xmm0, xmm1);
    430   }
    431 
    432   // cmov.
    433   {
    434     __ cmov(overflow, eax, Operand(eax, 0));
    435     __ cmov(no_overflow, eax, Operand(eax, 1));
    436     __ cmov(below, eax, Operand(eax, 2));
    437     __ cmov(above_equal, eax, Operand(eax, 3));
    438     __ cmov(equal, eax, Operand(ebx, 0));
    439     __ cmov(not_equal, eax, Operand(ebx, 1));
    440     __ cmov(below_equal, eax, Operand(ebx, 2));
    441     __ cmov(above, eax, Operand(ebx, 3));
    442     __ cmov(sign, eax, Operand(ecx, 0));
    443     __ cmov(not_sign, eax, Operand(ecx, 1));
    444     __ cmov(parity_even, eax, Operand(ecx, 2));
    445     __ cmov(parity_odd, eax, Operand(ecx, 3));
    446     __ cmov(less, eax, Operand(edx, 0));
    447     __ cmov(greater_equal, eax, Operand(edx, 1));
    448     __ cmov(less_equal, eax, Operand(edx, 2));
    449     __ cmov(greater, eax, Operand(edx, 3));
    450   }
    451 
    452   {
    453     if (CpuFeatures::IsSupported(SSE4_1)) {
    454       CpuFeatureScope scope(&assm, SSE4_1);
    455       __ pextrd(eax, xmm0, 1);
    456       __ pinsrd(xmm1, eax, 0);
    457       __ extractps(eax, xmm1, 0);
    458     }
    459   }
    460 
    461   // xchg.
    462   {
    463     __ xchg(eax, eax);
    464     __ xchg(eax, ebx);
    465     __ xchg(ebx, ebx);
    466     __ xchg(ebx, Operand(esp, 12));
    467   }
    468 
    469   // Nop instructions
    470   for (int i = 0; i < 16; i++) {
    471     __ Nop(i);
    472   }
    473 
    474   __ ret(0);
    475 
    476   CodeDesc desc;
    477   assm.GetCode(&desc);
    478   Handle<Code> code = isolate->factory()->NewCode(
    479       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    480   USE(code);
    481 #ifdef OBJECT_PRINT
    482   OFStream os(stdout);
    483   code->Print(os);
    484   byte* begin = code->instruction_start();
    485   byte* end = begin + code->instruction_size();
    486   disasm::Disassembler::Disassemble(stdout, begin, end);
    487 #endif
    488 }
    489 
    490 #undef __
    491