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/disassembler.h"
     33 #include "src/factory.h"
     34 #include "src/macro-assembler.h"
     35 #include "src/platform.h"
     36 #include "src/serialize.h"
     37 #include "test/cctest/cctest.h"
     38 
     39 using namespace v8::internal;
     40 
     41 
     42 typedef int (*F0)();
     43 typedef int (*F1)(int x);
     44 typedef int (*F2)(int x, int y);
     45 
     46 
     47 #define __ assm.
     48 
     49 TEST(AssemblerIa320) {
     50   CcTest::InitializeVM();
     51   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
     52   HandleScope scope(isolate);
     53 
     54   v8::internal::byte buffer[256];
     55   Assembler assm(isolate, buffer, sizeof buffer);
     56 
     57   __ mov(eax, Operand(esp, 4));
     58   __ add(eax, Operand(esp, 8));
     59   __ ret(0);
     60 
     61   CodeDesc desc;
     62   assm.GetCode(&desc);
     63   Handle<Code> code = isolate->factory()->NewCode(
     64       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
     65 #ifdef OBJECT_PRINT
     66   code->Print();
     67 #endif
     68   F2 f = FUNCTION_CAST<F2>(code->entry());
     69   int res = f(3, 4);
     70   ::printf("f() = %d\n", res);
     71   CHECK_EQ(7, res);
     72 }
     73 
     74 
     75 TEST(AssemblerIa321) {
     76   CcTest::InitializeVM();
     77   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
     78   HandleScope scope(isolate);
     79 
     80   v8::internal::byte buffer[256];
     81   Assembler assm(isolate, buffer, sizeof buffer);
     82   Label L, C;
     83 
     84   __ mov(edx, Operand(esp, 4));
     85   __ xor_(eax, eax);  // clear eax
     86   __ jmp(&C);
     87 
     88   __ bind(&L);
     89   __ add(eax, edx);
     90   __ sub(edx, Immediate(1));
     91 
     92   __ bind(&C);
     93   __ test(edx, edx);
     94   __ j(not_zero, &L);
     95   __ ret(0);
     96 
     97   CodeDesc desc;
     98   assm.GetCode(&desc);
     99   Handle<Code> code = isolate->factory()->NewCode(
    100       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    101 #ifdef OBJECT_PRINT
    102   code->Print();
    103 #endif
    104   F1 f = FUNCTION_CAST<F1>(code->entry());
    105   int res = f(100);
    106   ::printf("f() = %d\n", res);
    107   CHECK_EQ(5050, res);
    108 }
    109 
    110 
    111 TEST(AssemblerIa322) {
    112   CcTest::InitializeVM();
    113   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    114   HandleScope scope(isolate);
    115 
    116   v8::internal::byte buffer[256];
    117   Assembler assm(isolate, buffer, sizeof buffer);
    118   Label L, C;
    119 
    120   __ mov(edx, Operand(esp, 4));
    121   __ mov(eax, 1);
    122   __ jmp(&C);
    123 
    124   __ bind(&L);
    125   __ imul(eax, edx);
    126   __ sub(edx, Immediate(1));
    127 
    128   __ bind(&C);
    129   __ test(edx, edx);
    130   __ j(not_zero, &L);
    131   __ ret(0);
    132 
    133   // some relocated stuff here, not executed
    134   __ mov(eax, isolate->factory()->true_value());
    135   __ jmp(NULL, RelocInfo::RUNTIME_ENTRY);
    136 
    137   CodeDesc desc;
    138   assm.GetCode(&desc);
    139   Handle<Code> code = isolate->factory()->NewCode(
    140       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    141 #ifdef OBJECT_PRINT
    142   code->Print();
    143 #endif
    144   F1 f = FUNCTION_CAST<F1>(code->entry());
    145   int res = f(10);
    146   ::printf("f() = %d\n", res);
    147   CHECK_EQ(3628800, res);
    148 }
    149 
    150 
    151 typedef int (*F3)(float x);
    152 
    153 typedef int (*F4)(double x);
    154 
    155 static int baz = 42;
    156 TEST(AssemblerIa325) {
    157   CcTest::InitializeVM();
    158   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    159   HandleScope scope(isolate);
    160 
    161   v8::internal::byte buffer[256];
    162   Assembler assm(isolate, buffer, sizeof buffer);
    163 
    164   __ mov(eax, Operand(reinterpret_cast<intptr_t>(&baz), RelocInfo::NONE32));
    165   __ ret(0);
    166 
    167   CodeDesc desc;
    168   assm.GetCode(&desc);
    169   Handle<Code> code = isolate->factory()->NewCode(
    170       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    171   F0 f = FUNCTION_CAST<F0>(code->entry());
    172   int res = f();
    173   CHECK_EQ(42, res);
    174 }
    175 
    176 
    177 typedef int (*F7)(double x, double y);
    178 
    179 TEST(AssemblerIa329) {
    180   CcTest::InitializeVM();
    181   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    182   HandleScope scope(isolate);
    183   v8::internal::byte buffer[256];
    184   MacroAssembler assm(isolate, buffer, sizeof buffer);
    185   enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 };
    186   Label equal_l, less_l, greater_l, nan_l;
    187   __ fld_d(Operand(esp, 3 * kPointerSize));
    188   __ fld_d(Operand(esp, 1 * kPointerSize));
    189   __ FCmp();
    190   __ j(parity_even, &nan_l);
    191   __ j(equal, &equal_l);
    192   __ j(below, &less_l);
    193   __ j(above, &greater_l);
    194 
    195   __ mov(eax, kUndefined);
    196   __ ret(0);
    197 
    198   __ bind(&equal_l);
    199   __ mov(eax, kEqual);
    200   __ ret(0);
    201 
    202   __ bind(&greater_l);
    203   __ mov(eax, kGreater);
    204   __ ret(0);
    205 
    206   __ bind(&less_l);
    207   __ mov(eax, kLess);
    208   __ ret(0);
    209 
    210   __ bind(&nan_l);
    211   __ mov(eax, kNaN);
    212   __ ret(0);
    213 
    214 
    215   CodeDesc desc;
    216   assm.GetCode(&desc);
    217   Handle<Code> code = isolate->factory()->NewCode(
    218       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    219 #ifdef OBJECT_PRINT
    220   code->Print();
    221 #endif
    222 
    223   F7 f = FUNCTION_CAST<F7>(code->entry());
    224   CHECK_EQ(kLess, f(1.1, 2.2));
    225   CHECK_EQ(kEqual, f(2.2, 2.2));
    226   CHECK_EQ(kGreater, f(3.3, 2.2));
    227   CHECK_EQ(kNaN, f(OS::nan_value(), 1.1));
    228 }
    229 
    230 
    231 TEST(AssemblerIa3210) {
    232   // Test chaining of label usages within instructions (issue 1644).
    233   CcTest::InitializeVM();
    234   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    235   HandleScope scope(isolate);
    236   Assembler assm(isolate, NULL, 0);
    237 
    238   Label target;
    239   __ j(equal, &target);
    240   __ j(not_equal, &target);
    241   __ bind(&target);
    242   __ nop();
    243 }
    244 
    245 
    246 TEST(AssemblerMultiByteNop) {
    247   CcTest::InitializeVM();
    248   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    249   HandleScope scope(isolate);
    250   v8::internal::byte buffer[1024];
    251   Assembler assm(isolate, buffer, sizeof(buffer));
    252   __ push(ebx);
    253   __ push(ecx);
    254   __ push(edx);
    255   __ push(edi);
    256   __ push(esi);
    257   __ mov(eax, 1);
    258   __ mov(ebx, 2);
    259   __ mov(ecx, 3);
    260   __ mov(edx, 4);
    261   __ mov(edi, 5);
    262   __ mov(esi, 6);
    263   for (int i = 0; i < 16; i++) {
    264     int before = assm.pc_offset();
    265     __ Nop(i);
    266     CHECK_EQ(assm.pc_offset() - before, i);
    267   }
    268 
    269   Label fail;
    270   __ cmp(eax, 1);
    271   __ j(not_equal, &fail);
    272   __ cmp(ebx, 2);
    273   __ j(not_equal, &fail);
    274   __ cmp(ecx, 3);
    275   __ j(not_equal, &fail);
    276   __ cmp(edx, 4);
    277   __ j(not_equal, &fail);
    278   __ cmp(edi, 5);
    279   __ j(not_equal, &fail);
    280   __ cmp(esi, 6);
    281   __ j(not_equal, &fail);
    282   __ mov(eax, 42);
    283   __ pop(esi);
    284   __ pop(edi);
    285   __ pop(edx);
    286   __ pop(ecx);
    287   __ pop(ebx);
    288   __ ret(0);
    289   __ bind(&fail);
    290   __ mov(eax, 13);
    291   __ pop(esi);
    292   __ pop(edi);
    293   __ pop(edx);
    294   __ pop(ecx);
    295   __ pop(ebx);
    296   __ ret(0);
    297 
    298   CodeDesc desc;
    299   assm.GetCode(&desc);
    300   Handle<Code> code = isolate->factory()->NewCode(
    301       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
    302   CHECK(code->IsCode());
    303 
    304   F0 f = FUNCTION_CAST<F0>(code->entry());
    305   int res = f();
    306   CHECK_EQ(42, res);
    307 }
    308 
    309 
    310 #undef __
    311