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