Home | History | Annotate | Download | only in cctest
      1 // Copyright 2007-2008 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 static v8::Persistent<v8::Context> env;
     42 
     43 static void InitializeVM() {
     44   if (env.IsEmpty()) {
     45     env = v8::Context::New();
     46   }
     47 }
     48 
     49 
     50 #define __ assm.
     51 
     52 
     53 static void DummyStaticFunction(Object* result) {
     54 }
     55 
     56 
     57 TEST(DisasmIa320) {
     58   InitializeVM();
     59   v8::HandleScope scope;
     60   v8::internal::byte buffer[2048];
     61   Assembler assm(buffer, sizeof buffer);
     62   DummyStaticFunction(NULL);  // just bloody use it (DELETE; debugging)
     63 
     64   // Short immediate instructions
     65   __ adc(eax, 12345678);
     66   __ add(Operand(eax), Immediate(12345678));
     67   __ or_(eax, 12345678);
     68   __ sub(Operand(eax), Immediate(12345678));
     69   __ xor_(eax, 12345678);
     70   __ and_(eax, 12345678);
     71   Handle<FixedArray> foo = Factory::NewFixedArray(10, TENURED);
     72   __ cmp(eax, foo);
     73 
     74   // ---- This one caused crash
     75   __ mov(ebx,  Operand(esp, ecx, times_2, 0));  // [esp+ecx*4]
     76 
     77   // ---- All instructions that I can think of
     78   __ add(edx, Operand(ebx));
     79   __ add(edx, Operand(12, RelocInfo::NONE));
     80   __ add(edx, Operand(ebx, 0));
     81   __ add(edx, Operand(ebx, 16));
     82   __ add(edx, Operand(ebx, 1999));
     83   __ add(edx, Operand(esp, 0));
     84   __ add(edx, Operand(esp, 16));
     85   __ add(edx, Operand(esp, 1999));
     86   __ nop();
     87   __ add(edi, Operand(ebp, ecx, times_4, 0));
     88   __ add(edi, Operand(ebp, ecx, times_4, 12));
     89   __ add(Operand(ebp, ecx, times_4, 12), Immediate(12));
     90 
     91   __ nop();
     92   __ add(Operand(ebx), Immediate(12));
     93   __ nop();
     94   __ adc(ecx, 12);
     95   __ adc(ecx, 1000);
     96   __ nop();
     97   __ and_(edx, 3);
     98   __ and_(edx, Operand(esp, 4));
     99   __ cmp(edx, 3);
    100   __ cmp(edx, Operand(esp, 4));
    101   __ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
    102   Handle<FixedArray> foo2 = Factory::NewFixedArray(10, TENURED);
    103   __ cmp(ebx, foo2);
    104   __ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
    105   __ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
    106   __ or_(edx, 3);
    107   __ xor_(edx, 3);
    108   __ nop();
    109   {
    110     CHECK(CpuFeatures::IsSupported(CPUID));
    111     CpuFeatures::Scope fscope(CPUID);
    112     __ cpuid();
    113   }
    114   {
    115     CHECK(CpuFeatures::IsSupported(RDTSC));
    116     CpuFeatures::Scope fscope(RDTSC);
    117     __ rdtsc();
    118   }
    119   __ movsx_b(edx, Operand(ecx));
    120   __ movsx_w(edx, Operand(ecx));
    121   __ movzx_b(edx, Operand(ecx));
    122   __ movzx_w(edx, Operand(ecx));
    123 
    124   __ nop();
    125   __ imul(edx, Operand(ecx));
    126   __ shld(edx, Operand(ecx));
    127   __ shrd(edx, Operand(ecx));
    128   __ bts(Operand(edx), ecx);
    129   __ bts(Operand(ebx, ecx, times_4, 0), ecx);
    130   __ nop();
    131   __ pushad();
    132   __ popad();
    133   __ pushfd();
    134   __ popfd();
    135   __ push(Immediate(12));
    136   __ push(Immediate(23456));
    137   __ push(ecx);
    138   __ push(esi);
    139   __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
    140   __ push(Operand(ebx, ecx, times_4, 0));
    141   __ push(Operand(ebx, ecx, times_4, 0));
    142   __ push(Operand(ebx, ecx, times_4, 10000));
    143   __ pop(edx);
    144   __ pop(eax);
    145   __ pop(Operand(ebx, ecx, times_4, 0));
    146   __ nop();
    147 
    148   __ add(edx, Operand(esp, 16));
    149   __ add(edx, Operand(ecx));
    150   __ mov_b(edx, Operand(ecx));
    151   __ mov_b(Operand(ecx), 6);
    152   __ mov_b(Operand(ebx, ecx, times_4, 10000), 6);
    153   __ mov_b(Operand(esp, 16), edx);
    154   __ mov_w(edx, Operand(esp, 16));
    155   __ mov_w(Operand(esp, 16), edx);
    156   __ nop();
    157   __ movsx_w(edx, Operand(esp, 12));
    158   __ movsx_b(edx, Operand(esp, 12));
    159   __ movzx_w(edx, Operand(esp, 12));
    160   __ movzx_b(edx, Operand(esp, 12));
    161   __ nop();
    162   __ mov(edx, 1234567);
    163   __ mov(edx, Operand(esp, 12));
    164   __ mov(Operand(ebx, ecx, times_4, 10000), Immediate(12345));
    165   __ mov(Operand(ebx, ecx, times_4, 10000), edx);
    166   __ nop();
    167   __ dec_b(edx);
    168   __ dec(edx);
    169   __ cdq();
    170 
    171   __ nop();
    172   __ idiv(edx);
    173   __ mul(edx);
    174   __ neg(edx);
    175   __ not_(edx);
    176   __ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456));
    177 
    178   __ imul(edx, Operand(ebx, ecx, times_4, 10000));
    179   __ imul(edx, ecx, 12);
    180   __ imul(edx, ecx, 1000);
    181 
    182   __ inc(edx);
    183   __ inc(Operand(ebx, ecx, times_4, 10000));
    184   __ push(Operand(ebx, ecx, times_4, 10000));
    185   __ pop(Operand(ebx, ecx, times_4, 10000));
    186   __ call(Operand(ebx, ecx, times_4, 10000));
    187   __ jmp(Operand(ebx, ecx, times_4, 10000));
    188 
    189   __ lea(edx, Operand(ebx, ecx, times_4, 10000));
    190   __ or_(edx, 12345);
    191   __ or_(edx, Operand(ebx, ecx, times_4, 10000));
    192 
    193   __ nop();
    194 
    195   __ rcl(edx, 1);
    196   __ rcl(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(Operand(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(Operand(ebx), Immediate(12));
    222   __ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
    223 
    224   __ or_(ebx, 12345);
    225 
    226   __ sub(Operand(ebx), Immediate(12));
    227   __ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
    228   __ subb(Operand(edx, ecx, times_4, 10000), 100);
    229   __ subb(Operand(eax), 100);
    230   __ subb(eax, Operand(edx, ecx, times_4, 10000));
    231 
    232   __ xor_(ebx, 12345);
    233 
    234   __ imul(edx, ecx, 12);
    235   __ imul(edx, ecx, 1000);
    236 
    237   __ rep_movs();
    238 
    239   __ sub(edx, Operand(ebx, ecx, times_4, 10000));
    240   __ sub(edx, Operand(ebx));
    241 
    242   __ test(edx, Immediate(12345));
    243   __ test(edx, Operand(ebx, ecx, times_8, 10000));
    244   __ nop();
    245 
    246   __ xor_(edx, 12345);
    247   __ xor_(edx, Operand(ebx, ecx, times_8, 10000));
    248   __ bts(Operand(ebx, ecx, times_8, 10000), edx);
    249   __ hlt();
    250   __ int3();
    251   __ ret(0);
    252   __ ret(8);
    253 
    254   // Calls
    255 
    256   Label L1, L2;
    257   __ bind(&L1);
    258   __ nop();
    259   __ call(&L1);
    260   __ call(&L2);
    261   __ nop();
    262   __ bind(&L2);
    263   __ call(Operand(ebx, ecx, times_4, 10000));
    264   __ nop();
    265   Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
    266   __ call(ic, RelocInfo::CODE_TARGET);
    267   __ nop();
    268   __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
    269   __ nop();
    270 
    271   __ jmp(&L1);
    272   __ jmp(Operand(ebx, ecx, times_4, 10000));
    273   ExternalReference after_break_target =
    274       ExternalReference(Debug_Address::AfterBreakTarget());
    275   __ jmp(Operand::StaticVariable(after_break_target));
    276   __ jmp(ic, RelocInfo::CODE_TARGET);
    277   __ nop();
    278 
    279 
    280   Label Ljcc;
    281   __ nop();
    282   // long jumps
    283   __ j(overflow, &Ljcc);
    284   __ j(no_overflow, &Ljcc);
    285   __ j(below, &Ljcc);
    286   __ j(above_equal, &Ljcc);
    287   __ j(equal, &Ljcc);
    288   __ j(not_equal, &Ljcc);
    289   __ j(below_equal, &Ljcc);
    290   __ j(above, &Ljcc);
    291   __ j(sign, &Ljcc);
    292   __ j(not_sign, &Ljcc);
    293   __ j(parity_even, &Ljcc);
    294   __ j(parity_odd, &Ljcc);
    295   __ j(less, &Ljcc);
    296   __ j(greater_equal, &Ljcc);
    297   __ j(less_equal, &Ljcc);
    298   __ j(greater, &Ljcc);
    299   __ nop();
    300   __ bind(&Ljcc);
    301   // short jumps
    302   __ j(overflow, &Ljcc);
    303   __ j(no_overflow, &Ljcc);
    304   __ j(below, &Ljcc);
    305   __ j(above_equal, &Ljcc);
    306   __ j(equal, &Ljcc);
    307   __ j(not_equal, &Ljcc);
    308   __ j(below_equal, &Ljcc);
    309   __ j(above, &Ljcc);
    310   __ j(sign, &Ljcc);
    311   __ j(not_sign, &Ljcc);
    312   __ j(parity_even, &Ljcc);
    313   __ j(parity_odd, &Ljcc);
    314   __ j(less, &Ljcc);
    315   __ j(greater_equal, &Ljcc);
    316   __ j(less_equal, &Ljcc);
    317   __ j(greater, &Ljcc);
    318 
    319   // checking hints
    320   __ j(zero, &Ljcc, taken);
    321   __ j(zero, &Ljcc, not_taken);
    322 
    323   // __ mov(Operand::StaticVariable(Top::handler_address()), eax);
    324   // 0xD9 instructions
    325   __ nop();
    326 
    327   __ fld1();
    328   __ fldz();
    329   __ fabs();
    330   __ fchs();
    331   __ fprem();
    332   __ fprem1();
    333   __ fincstp();
    334   __ ftst();
    335   __ fxch(3);
    336   __ fld_s(Operand(ebx, ecx, times_4, 10000));
    337   __ fstp_s(Operand(ebx, ecx, times_4, 10000));
    338   __ ffree(3);
    339   __ fld_d(Operand(ebx, ecx, times_4, 10000));
    340   __ fstp_d(Operand(ebx, ecx, times_4, 10000));
    341   __ nop();
    342 
    343   __ fild_s(Operand(ebx, ecx, times_4, 10000));
    344   __ fistp_s(Operand(ebx, ecx, times_4, 10000));
    345   __ fild_d(Operand(ebx, ecx, times_4, 10000));
    346   __ fistp_d(Operand(ebx, ecx, times_4, 10000));
    347   __ fnstsw_ax();
    348   __ nop();
    349   __ fadd(3);
    350   __ fsub(3);
    351   __ fmul(3);
    352   __ fdiv(3);
    353 
    354   __ faddp(3);
    355   __ fsubp(3);
    356   __ fmulp(3);
    357   __ fdivp(3);
    358   __ fcompp();
    359   __ fwait();
    360   __ nop();
    361   {
    362     CHECK(CpuFeatures::IsSupported(SSE2));
    363     CpuFeatures::Scope fscope(SSE2);
    364     __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
    365     __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
    366     __ addsd(xmm1, xmm0);
    367     __ mulsd(xmm1, xmm0);
    368     __ subsd(xmm1, xmm0);
    369     __ divsd(xmm1, xmm0);
    370     __ movdbl(xmm1, Operand(ebx, ecx, times_4, 10000));
    371     __ movdbl(Operand(ebx, ecx, times_4, 10000), xmm1);
    372     __ comisd(xmm0, xmm1);
    373 
    374     // 128 bit move instructions.
    375     __ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
    376     __ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
    377     __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
    378     __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
    379   }
    380 
    381   // cmov.
    382   {
    383     CHECK(CpuFeatures::IsSupported(CMOV));
    384     CpuFeatures::Scope use_cmov(CMOV);
    385     __ cmov(overflow, eax, Operand(eax, 0));
    386     __ cmov(no_overflow, eax, Operand(eax, 1));
    387     __ cmov(below, eax, Operand(eax, 2));
    388     __ cmov(above_equal, eax, Operand(eax, 3));
    389     __ cmov(equal, eax, Operand(ebx, 0));
    390     __ cmov(not_equal, eax, Operand(ebx, 1));
    391     __ cmov(below_equal, eax, Operand(ebx, 2));
    392     __ cmov(above, eax, Operand(ebx, 3));
    393     __ cmov(sign, eax, Operand(ecx, 0));
    394     __ cmov(not_sign, eax, Operand(ecx, 1));
    395     __ cmov(parity_even, eax, Operand(ecx, 2));
    396     __ cmov(parity_odd, eax, Operand(ecx, 3));
    397     __ cmov(less, eax, Operand(edx, 0));
    398     __ cmov(greater_equal, eax, Operand(edx, 1));
    399     __ cmov(less_equal, eax, Operand(edx, 2));
    400     __ cmov(greater, eax, Operand(edx, 3));
    401   }
    402 
    403   __ ret(0);
    404 
    405   CodeDesc desc;
    406   assm.GetCode(&desc);
    407   Object* code = Heap::CreateCode(desc,
    408                                   NULL,
    409                                   Code::ComputeFlags(Code::STUB),
    410                                   Handle<Object>(Heap::undefined_value()));
    411   CHECK(code->IsCode());
    412 #ifdef DEBUG
    413   Code::cast(code)->Print();
    414   byte* begin = Code::cast(code)->instruction_start();
    415   byte* end = begin + Code::cast(code)->instruction_size();
    416   disasm::Disassembler::Disassemble(stdout, begin, end);
    417 #endif
    418 }
    419 
    420 #undef __
    421