LCOV - code coverage report
Current view: top level - test/cctest - test-macro-assembler-x64.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 585 585 100.0 %
Date: 2017-10-20 Functions: 18 18 100.0 %

          Line data    Source code
       1             : // Copyright 2009 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/factory.h"
      34             : #include "src/macro-assembler.h"
      35             : #include "src/objects-inl.h"
      36             : #include "test/cctest/cctest.h"
      37             : 
      38             : namespace v8 {
      39             : namespace internal {
      40             : namespace test_macro_assembler_x64 {
      41             : 
      42             : // Test the x64 assembler by compiling some simple functions into
      43             : // a buffer and executing them.  These tests do not initialize the
      44             : // V8 library, create a context, or use any V8 objects.
      45             : // The AMD64 calling convention is used, with the first five arguments
      46             : // in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in
      47             : // the XMM registers.  The return value is in RAX.
      48             : // This calling convention is used on Linux, with GCC, and on Mac OS,
      49             : // with GCC.  A different convention is used on 64-bit windows.
      50             : 
      51             : typedef int (*F0)();
      52             : 
      53             : #define __ masm->
      54             : 
      55             : 
      56             : static void EntryCode(MacroAssembler* masm) {
      57             :   // Smi constant register is callee save.
      58          48 :   __ pushq(kRootRegister);
      59          48 :   __ InitializeRootRegister();
      60             : }
      61             : 
      62          48 : static void ExitCode(MacroAssembler* masm) { __ popq(kRootRegister); }
      63             : 
      64       23724 : TEST(Smi) {
      65             :   // Check that C++ Smi operations work as expected.
      66             :   int64_t test_numbers[] = {
      67             :       0, 1, -1, 127, 128, -128, -129, 255, 256, -256, -257,
      68             :       Smi::kMaxValue, static_cast<int64_t>(Smi::kMaxValue) + 1,
      69             :       Smi::kMinValue, static_cast<int64_t>(Smi::kMinValue) - 1
      70           6 :   };
      71             :   int test_number_count = 15;
      72          96 :   for (int i = 0; i < test_number_count; i++) {
      73          90 :     int64_t number = test_numbers[i];
      74             :     bool is_valid = Smi::IsValid(number);
      75          90 :     bool is_in_range = number >= Smi::kMinValue && number <= Smi::kMaxValue;
      76          90 :     CHECK_EQ(is_in_range, is_valid);
      77          90 :     if (is_valid) {
      78             :       Smi* smi_from_intptr = Smi::FromIntptr(number);
      79          78 :       if (static_cast<int>(number) == number) {  // Is a 32-bit int.
      80             :         Smi* smi_from_int = Smi::FromInt(static_cast<int32_t>(number));
      81          78 :         CHECK_EQ(smi_from_int, smi_from_intptr);
      82             :       }
      83          78 :       int64_t smi_value = smi_from_intptr->value();
      84          78 :       CHECK_EQ(number, smi_value);
      85             :     }
      86             :   }
      87           6 : }
      88             : 
      89             : 
      90          72 : static void TestMoveSmi(MacroAssembler* masm, Label* exit, int id, Smi* value) {
      91          72 :   __ movl(rax, Immediate(id));
      92          72 :   __ Move(rcx, value);
      93          72 :   __ Set(rdx, reinterpret_cast<intptr_t>(value));
      94          72 :   __ cmpq(rcx, rdx);
      95          72 :   __ j(not_equal, exit);
      96          72 : }
      97             : 
      98             : 
      99             : // Test that we can move a Smi value literally into a register.
     100       23724 : TEST(SmiMove) {
     101             :   // Allocate an executable page of memory.
     102             :   size_t actual_size;
     103             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     104           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     105           6 :   CHECK(buffer);
     106             :   Isolate* isolate = CcTest::i_isolate();
     107             :   HandleScope handles(isolate);
     108             :   MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
     109           6 :                            v8::internal::CodeObjectRequired::kYes);
     110             :   MacroAssembler* masm = &assembler;  // Create a pointer for the __ macro.
     111             :   EntryCode(masm);
     112             :   Label exit;
     113             : 
     114           6 :   TestMoveSmi(masm, &exit, 1, Smi::kZero);
     115           6 :   TestMoveSmi(masm, &exit, 2, Smi::FromInt(127));
     116           6 :   TestMoveSmi(masm, &exit, 3, Smi::FromInt(128));
     117           6 :   TestMoveSmi(masm, &exit, 4, Smi::FromInt(255));
     118           6 :   TestMoveSmi(masm, &exit, 5, Smi::FromInt(256));
     119           6 :   TestMoveSmi(masm, &exit, 6, Smi::FromInt(Smi::kMaxValue));
     120           6 :   TestMoveSmi(masm, &exit, 7, Smi::FromInt(-1));
     121           6 :   TestMoveSmi(masm, &exit, 8, Smi::FromInt(-128));
     122           6 :   TestMoveSmi(masm, &exit, 9, Smi::FromInt(-129));
     123           6 :   TestMoveSmi(masm, &exit, 10, Smi::FromInt(-256));
     124           6 :   TestMoveSmi(masm, &exit, 11, Smi::FromInt(-257));
     125           6 :   TestMoveSmi(masm, &exit, 12, Smi::FromInt(Smi::kMinValue));
     126             : 
     127             :   __ xorq(rax, rax);  // Success.
     128           6 :   __ bind(&exit);
     129             :   ExitCode(masm);
     130           6 :   __ ret(0);
     131             : 
     132             :   CodeDesc desc;
     133           6 :   masm->GetCode(isolate, &desc);
     134             :   // Call the function from C++.
     135           6 :   int result = FUNCTION_CAST<F0>(buffer)();
     136           6 :   CHECK_EQ(0, result);
     137           6 : }
     138             : 
     139             : 
     140         114 : void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) {
     141         114 :   __ Move(rcx, Smi::FromInt(x));
     142         114 :   __ movq(r8, rcx);
     143         114 :   __ Move(rdx, Smi::FromInt(y));
     144             :   __ movq(r9, rdx);
     145         114 :   __ SmiCompare(rcx, rdx);
     146         114 :   if (x < y) {
     147          42 :     __ movl(rax, Immediate(id + 1));
     148          42 :     __ j(greater_equal, exit);
     149          72 :   } else if (x > y) {
     150          42 :     __ movl(rax, Immediate(id + 2));
     151          42 :     __ j(less_equal, exit);
     152             :   } else {
     153          30 :     CHECK_EQ(x, y);
     154          30 :     __ movl(rax, Immediate(id + 3));
     155          30 :     __ j(not_equal, exit);
     156             :   }
     157         114 :   __ movl(rax, Immediate(id + 4));
     158         114 :   __ cmpq(rcx, r8);
     159         114 :   __ j(not_equal, exit);
     160             :   __ incq(rax);
     161         114 :   __ cmpq(rdx, r9);
     162         114 :   __ j(not_equal, exit);
     163             : 
     164         114 :   if (x != y) {
     165          84 :     __ SmiCompare(rdx, rcx);
     166          84 :     if (y < x) {
     167          42 :       __ movl(rax, Immediate(id + 9));
     168          42 :       __ j(greater_equal, exit);
     169             :     } else {
     170          42 :       CHECK(y > x);
     171          42 :       __ movl(rax, Immediate(id + 10));
     172          42 :       __ j(less_equal, exit);
     173             :     }
     174             :   } else {
     175          30 :     __ cmpq(rcx, rcx);
     176          30 :     __ movl(rax, Immediate(id + 11));
     177          30 :     __ j(not_equal, exit);
     178             :     __ incq(rax);
     179          30 :     __ cmpq(rcx, r8);
     180          30 :     __ j(not_equal, exit);
     181             :   }
     182         114 : }
     183             : 
     184             : 
     185             : // Test that we can compare smis for equality (and more).
     186       23724 : TEST(SmiCompare) {
     187             :   // Allocate an executable page of memory.
     188             :   size_t actual_size;
     189             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     190           6 :       Assembler::kMinimalBufferSize * 2, &actual_size, true));
     191           6 :   CHECK(buffer);
     192             :   Isolate* isolate = CcTest::i_isolate();
     193             :   HandleScope handles(isolate);
     194             :   MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
     195           6 :                            v8::internal::CodeObjectRequired::kYes);
     196             : 
     197             :   MacroAssembler* masm = &assembler;
     198             :   EntryCode(masm);
     199             :   Label exit;
     200             : 
     201           6 :   TestSmiCompare(masm, &exit, 0x10, 0, 0);
     202           6 :   TestSmiCompare(masm, &exit, 0x20, 0, 1);
     203           6 :   TestSmiCompare(masm, &exit, 0x30, 1, 0);
     204           6 :   TestSmiCompare(masm, &exit, 0x40, 1, 1);
     205           6 :   TestSmiCompare(masm, &exit, 0x50, 0, -1);
     206           6 :   TestSmiCompare(masm, &exit, 0x60, -1, 0);
     207           6 :   TestSmiCompare(masm, &exit, 0x70, -1, -1);
     208           6 :   TestSmiCompare(masm, &exit, 0x80, 0, Smi::kMinValue);
     209           6 :   TestSmiCompare(masm, &exit, 0x90, Smi::kMinValue, 0);
     210           6 :   TestSmiCompare(masm, &exit, 0xA0, 0, Smi::kMaxValue);
     211           6 :   TestSmiCompare(masm, &exit, 0xB0, Smi::kMaxValue, 0);
     212           6 :   TestSmiCompare(masm, &exit, 0xC0, -1, Smi::kMinValue);
     213           6 :   TestSmiCompare(masm, &exit, 0xD0, Smi::kMinValue, -1);
     214           6 :   TestSmiCompare(masm, &exit, 0xE0, -1, Smi::kMaxValue);
     215           6 :   TestSmiCompare(masm, &exit, 0xF0, Smi::kMaxValue, -1);
     216           6 :   TestSmiCompare(masm, &exit, 0x100, Smi::kMinValue, Smi::kMinValue);
     217           6 :   TestSmiCompare(masm, &exit, 0x110, Smi::kMinValue, Smi::kMaxValue);
     218           6 :   TestSmiCompare(masm, &exit, 0x120, Smi::kMaxValue, Smi::kMinValue);
     219           6 :   TestSmiCompare(masm, &exit, 0x130, Smi::kMaxValue, Smi::kMaxValue);
     220             : 
     221             :   __ xorq(rax, rax);  // Success.
     222           6 :   __ bind(&exit);
     223             :   ExitCode(masm);
     224           6 :   __ ret(0);
     225             : 
     226             :   CodeDesc desc;
     227           6 :   masm->GetCode(isolate, &desc);
     228             :   // Call the function from C++.
     229           6 :   int result = FUNCTION_CAST<F0>(buffer)();
     230           6 :   CHECK_EQ(0, result);
     231           6 : }
     232             : 
     233             : 
     234             : 
     235       23724 : TEST(Integer32ToSmi) {
     236             :   // Allocate an executable page of memory.
     237             :   size_t actual_size;
     238             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     239           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     240           6 :   CHECK(buffer);
     241             :   Isolate* isolate = CcTest::i_isolate();
     242             :   HandleScope handles(isolate);
     243             :   MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
     244           6 :                            v8::internal::CodeObjectRequired::kYes);
     245             : 
     246             :   MacroAssembler* masm = &assembler;
     247             :   EntryCode(masm);
     248             :   Label exit;
     249             : 
     250             :   __ movq(rax, Immediate(1));  // Test number.
     251             :   __ movl(rcx, Immediate(0));
     252           6 :   __ Integer32ToSmi(rcx, rcx);
     253           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::kZero));
     254           6 :   __ cmpq(rcx, rdx);
     255           6 :   __ j(not_equal, &exit);
     256             : 
     257             :   __ movq(rax, Immediate(2));  // Test number.
     258             :   __ movl(rcx, Immediate(1024));
     259           6 :   __ Integer32ToSmi(rcx, rcx);
     260           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(1024)));
     261           6 :   __ cmpq(rcx, rdx);
     262           6 :   __ j(not_equal, &exit);
     263             : 
     264             :   __ movq(rax, Immediate(3));  // Test number.
     265             :   __ movl(rcx, Immediate(-1));
     266           6 :   __ Integer32ToSmi(rcx, rcx);
     267           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(-1)));
     268           6 :   __ cmpq(rcx, rdx);
     269           6 :   __ j(not_equal, &exit);
     270             : 
     271             :   __ movq(rax, Immediate(4));  // Test number.
     272             :   __ movl(rcx, Immediate(Smi::kMaxValue));
     273           6 :   __ Integer32ToSmi(rcx, rcx);
     274           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMaxValue)));
     275           6 :   __ cmpq(rcx, rdx);
     276           6 :   __ j(not_equal, &exit);
     277             : 
     278             :   __ movq(rax, Immediate(5));  // Test number.
     279             :   __ movl(rcx, Immediate(Smi::kMinValue));
     280           6 :   __ Integer32ToSmi(rcx, rcx);
     281           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMinValue)));
     282           6 :   __ cmpq(rcx, rdx);
     283           6 :   __ j(not_equal, &exit);
     284             : 
     285             :   // Different target register.
     286             : 
     287             :   __ movq(rax, Immediate(6));  // Test number.
     288             :   __ movl(rcx, Immediate(0));
     289           6 :   __ Integer32ToSmi(r8, rcx);
     290           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::kZero));
     291           6 :   __ cmpq(r8, rdx);
     292           6 :   __ j(not_equal, &exit);
     293             : 
     294             :   __ movq(rax, Immediate(7));  // Test number.
     295             :   __ movl(rcx, Immediate(1024));
     296           6 :   __ Integer32ToSmi(r8, rcx);
     297           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(1024)));
     298           6 :   __ cmpq(r8, rdx);
     299           6 :   __ j(not_equal, &exit);
     300             : 
     301             :   __ movq(rax, Immediate(8));  // Test number.
     302             :   __ movl(rcx, Immediate(-1));
     303           6 :   __ Integer32ToSmi(r8, rcx);
     304           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(-1)));
     305           6 :   __ cmpq(r8, rdx);
     306           6 :   __ j(not_equal, &exit);
     307             : 
     308             :   __ movq(rax, Immediate(9));  // Test number.
     309             :   __ movl(rcx, Immediate(Smi::kMaxValue));
     310           6 :   __ Integer32ToSmi(r8, rcx);
     311           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMaxValue)));
     312           6 :   __ cmpq(r8, rdx);
     313           6 :   __ j(not_equal, &exit);
     314             : 
     315             :   __ movq(rax, Immediate(10));  // Test number.
     316             :   __ movl(rcx, Immediate(Smi::kMinValue));
     317           6 :   __ Integer32ToSmi(r8, rcx);
     318           6 :   __ Set(rdx, reinterpret_cast<intptr_t>(Smi::FromInt(Smi::kMinValue)));
     319           6 :   __ cmpq(r8, rdx);
     320           6 :   __ j(not_equal, &exit);
     321             : 
     322             : 
     323             :   __ xorq(rax, rax);  // Success.
     324           6 :   __ bind(&exit);
     325             :   ExitCode(masm);
     326           6 :   __ ret(0);
     327             : 
     328             :   CodeDesc desc;
     329           6 :   masm->GetCode(isolate, &desc);
     330             :   // Call the function from C++.
     331           6 :   int result = FUNCTION_CAST<F0>(buffer)();
     332           6 :   CHECK_EQ(0, result);
     333           6 : }
     334             : 
     335       23724 : TEST(SmiCheck) {
     336             :   // Allocate an executable page of memory.
     337             :   size_t actual_size;
     338             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     339           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     340           6 :   CHECK(buffer);
     341             :   Isolate* isolate = CcTest::i_isolate();
     342             :   HandleScope handles(isolate);
     343             :   MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
     344           6 :                            v8::internal::CodeObjectRequired::kYes);
     345             : 
     346             :   MacroAssembler* masm = &assembler;
     347             :   EntryCode(masm);
     348             :   Label exit;
     349             :   Condition cond;
     350             : 
     351             :   __ movl(rax, Immediate(1));  // Test number.
     352             : 
     353             :   // CheckSmi
     354             : 
     355             :   __ movl(rcx, Immediate(0));
     356           6 :   __ Integer32ToSmi(rcx, rcx);
     357           6 :   cond = masm->CheckSmi(rcx);
     358           6 :   __ j(NegateCondition(cond), &exit);
     359             : 
     360             :   __ incq(rax);
     361           6 :   __ xorq(rcx, Immediate(kSmiTagMask));
     362           6 :   cond = masm->CheckSmi(rcx);
     363           6 :   __ j(cond, &exit);
     364             : 
     365             :   __ incq(rax);
     366             :   __ movl(rcx, Immediate(-1));
     367           6 :   __ Integer32ToSmi(rcx, rcx);
     368           6 :   cond = masm->CheckSmi(rcx);
     369           6 :   __ j(NegateCondition(cond), &exit);
     370             : 
     371             :   __ incq(rax);
     372           6 :   __ xorq(rcx, Immediate(kSmiTagMask));
     373           6 :   cond = masm->CheckSmi(rcx);
     374           6 :   __ j(cond, &exit);
     375             : 
     376             :   __ incq(rax);
     377             :   __ movl(rcx, Immediate(Smi::kMaxValue));
     378           6 :   __ Integer32ToSmi(rcx, rcx);
     379           6 :   cond = masm->CheckSmi(rcx);
     380           6 :   __ j(NegateCondition(cond), &exit);
     381             : 
     382             :   __ incq(rax);
     383           6 :   __ xorq(rcx, Immediate(kSmiTagMask));
     384           6 :   cond = masm->CheckSmi(rcx);
     385           6 :   __ j(cond, &exit);
     386             : 
     387             :   __ incq(rax);
     388             :   __ movl(rcx, Immediate(Smi::kMinValue));
     389           6 :   __ Integer32ToSmi(rcx, rcx);
     390           6 :   cond = masm->CheckSmi(rcx);
     391           6 :   __ j(NegateCondition(cond), &exit);
     392             : 
     393             :   __ incq(rax);
     394           6 :   __ xorq(rcx, Immediate(kSmiTagMask));
     395           6 :   cond = masm->CheckSmi(rcx);
     396           6 :   __ j(cond, &exit);
     397             : 
     398             :   // Success
     399             :   __ xorq(rax, rax);
     400             : 
     401           6 :   __ bind(&exit);
     402             :   ExitCode(masm);
     403           6 :   __ ret(0);
     404             : 
     405             :   CodeDesc desc;
     406           6 :   masm->GetCode(isolate, &desc);
     407             :   // Call the function from C++.
     408           6 :   int result = FUNCTION_CAST<F0>(buffer)();
     409           6 :   CHECK_EQ(0, result);
     410           6 : }
     411             : 
     412          30 : void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) {
     413          30 :   __ movl(rax, Immediate(id));
     414             : 
     415         270 :   for (int i = 0; i < 8; i++) {
     416         240 :     __ Move(rcx, Smi::FromInt(x));
     417         240 :     SmiIndex index = masm->SmiToIndex(rdx, rcx, i);
     418         240 :     CHECK(index.reg == rcx || index.reg == rdx);
     419         240 :     __ shlq(index.reg, Immediate(index.scale));
     420         240 :     __ Set(r8, static_cast<intptr_t>(x) << i);
     421         240 :     __ cmpq(index.reg, r8);
     422         240 :     __ j(not_equal, exit);
     423             :     __ incq(rax);
     424         240 :     __ Move(rcx, Smi::FromInt(x));
     425         240 :     index = masm->SmiToIndex(rcx, rcx, i);
     426         240 :     CHECK(index.reg == rcx);
     427         240 :     __ shlq(rcx, Immediate(index.scale));
     428         240 :     __ Set(r8, static_cast<intptr_t>(x) << i);
     429         240 :     __ cmpq(rcx, r8);
     430         240 :     __ j(not_equal, exit);
     431             :     __ incq(rax);
     432             :   }
     433          30 : }
     434             : 
     435       23724 : TEST(SmiIndex) {
     436             :   // Allocate an executable page of memory.
     437             :   size_t actual_size;
     438             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     439           6 :       Assembler::kMinimalBufferSize * 5, &actual_size, true));
     440           6 :   CHECK(buffer);
     441             :   Isolate* isolate = CcTest::i_isolate();
     442             :   HandleScope handles(isolate);
     443             :   MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
     444           6 :                            v8::internal::CodeObjectRequired::kYes);
     445             : 
     446             :   MacroAssembler* masm = &assembler;
     447             :   EntryCode(masm);
     448             :   Label exit;
     449             : 
     450           6 :   TestSmiIndex(masm, &exit, 0x10, 0);
     451           6 :   TestSmiIndex(masm, &exit, 0x20, 1);
     452           6 :   TestSmiIndex(masm, &exit, 0x30, 100);
     453           6 :   TestSmiIndex(masm, &exit, 0x40, 1000);
     454           6 :   TestSmiIndex(masm, &exit, 0x50, Smi::kMaxValue);
     455             : 
     456             :   __ xorq(rax, rax);  // Success.
     457           6 :   __ bind(&exit);
     458             :   ExitCode(masm);
     459           6 :   __ ret(0);
     460             : 
     461             :   CodeDesc desc;
     462           6 :   masm->GetCode(isolate, &desc);
     463             :   // Call the function from C++.
     464           6 :   int result = FUNCTION_CAST<F0>(buffer)();
     465           6 :   CHECK_EQ(0, result);
     466           6 : }
     467             : 
     468       23724 : TEST(OperandOffset) {
     469             :   uint32_t data[256];
     470           6 :   for (uint32_t i = 0; i < 256; i++) { data[i] = i * 0x01010101; }
     471             : 
     472             :   // Allocate an executable page of memory.
     473             :   size_t actual_size;
     474             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     475           6 :       Assembler::kMinimalBufferSize * 2, &actual_size, true));
     476           6 :   CHECK(buffer);
     477             :   Isolate* isolate = CcTest::i_isolate();
     478             :   HandleScope handles(isolate);
     479             :   MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
     480           6 :                            v8::internal::CodeObjectRequired::kYes);
     481             : 
     482             :   MacroAssembler* masm = &assembler;
     483             :   Label exit;
     484             : 
     485             :   EntryCode(masm);
     486           6 :   __ pushq(r13);
     487           6 :   __ pushq(r14);
     488           6 :   __ pushq(rbx);
     489           6 :   __ pushq(rbp);
     490           6 :   __ pushq(Immediate(0x100));  // <-- rbp
     491             :   __ movq(rbp, rsp);
     492           6 :   __ pushq(Immediate(0x101));
     493           6 :   __ pushq(Immediate(0x102));
     494           6 :   __ pushq(Immediate(0x103));
     495           6 :   __ pushq(Immediate(0x104));
     496           6 :   __ pushq(Immediate(0x105));  // <-- rbx
     497           6 :   __ pushq(Immediate(0x106));
     498           6 :   __ pushq(Immediate(0x107));
     499           6 :   __ pushq(Immediate(0x108));
     500           6 :   __ pushq(Immediate(0x109));  // <-- rsp
     501             :   // rbp = rsp[9]
     502             :   // r15 = rsp[3]
     503             :   // rbx = rsp[5]
     504             :   // r13 = rsp[7]
     505          12 :   __ leaq(r14, Operand(rsp, 3 * kPointerSize));
     506          12 :   __ leaq(r13, Operand(rbp, -3 * kPointerSize));
     507          12 :   __ leaq(rbx, Operand(rbp, -5 * kPointerSize));
     508             :   __ movl(rcx, Immediate(2));
     509             :   __ Move(r8, reinterpret_cast<Address>(&data[128]), RelocInfo::NONE64);
     510             :   __ movl(rax, Immediate(1));
     511             : 
     512           6 :   Operand sp0 = Operand(rsp, 0);
     513             : 
     514             :   // Test 1.
     515             :   __ movl(rdx, sp0);  // Sanity check.
     516           6 :   __ cmpl(rdx, Immediate(0x109));
     517           6 :   __ j(not_equal, &exit);
     518             :   __ incq(rax);
     519             : 
     520             :   // Test 2.
     521             :   // Zero to non-zero displacement.
     522          12 :   __ movl(rdx, Operand(sp0, 2 * kPointerSize));
     523           6 :   __ cmpl(rdx, Immediate(0x107));
     524           6 :   __ j(not_equal, &exit);
     525             :   __ incq(rax);
     526             : 
     527           6 :   Operand sp2 = Operand(rsp, 2 * kPointerSize);
     528             : 
     529             :   // Test 3.
     530             :   __ movl(rdx, sp2);  // Sanity check.
     531           6 :   __ cmpl(rdx, Immediate(0x107));
     532           6 :   __ j(not_equal, &exit);
     533             :   __ incq(rax);
     534             : 
     535          12 :   __ movl(rdx, Operand(sp2, 2 * kPointerSize));
     536           6 :   __ cmpl(rdx, Immediate(0x105));
     537           6 :   __ j(not_equal, &exit);
     538             :   __ incq(rax);
     539             : 
     540             :   // Non-zero to zero displacement.
     541          12 :   __ movl(rdx, Operand(sp2, -2 * kPointerSize));
     542           6 :   __ cmpl(rdx, Immediate(0x109));
     543           6 :   __ j(not_equal, &exit);
     544             :   __ incq(rax);
     545             : 
     546           6 :   Operand sp2c2 = Operand(rsp, rcx, times_pointer_size, 2 * kPointerSize);
     547             : 
     548             :   // Test 6.
     549             :   __ movl(rdx, sp2c2);  // Sanity check.
     550           6 :   __ cmpl(rdx, Immediate(0x105));
     551           6 :   __ j(not_equal, &exit);
     552             :   __ incq(rax);
     553             : 
     554          12 :   __ movl(rdx, Operand(sp2c2, 2 * kPointerSize));
     555           6 :   __ cmpl(rdx, Immediate(0x103));
     556           6 :   __ j(not_equal, &exit);
     557             :   __ incq(rax);
     558             : 
     559             :   // Non-zero to zero displacement.
     560          12 :   __ movl(rdx, Operand(sp2c2, -2 * kPointerSize));
     561           6 :   __ cmpl(rdx, Immediate(0x107));
     562           6 :   __ j(not_equal, &exit);
     563             :   __ incq(rax);
     564             : 
     565             : 
     566           6 :   Operand bp0 = Operand(rbp, 0);
     567             : 
     568             :   // Test 9.
     569             :   __ movl(rdx, bp0);  // Sanity check.
     570           6 :   __ cmpl(rdx, Immediate(0x100));
     571           6 :   __ j(not_equal, &exit);
     572             :   __ incq(rax);
     573             : 
     574             :   // Zero to non-zero displacement.
     575          12 :   __ movl(rdx, Operand(bp0, -2 * kPointerSize));
     576           6 :   __ cmpl(rdx, Immediate(0x102));
     577           6 :   __ j(not_equal, &exit);
     578             :   __ incq(rax);
     579             : 
     580           6 :   Operand bp2 = Operand(rbp, -2 * kPointerSize);
     581             : 
     582             :   // Test 11.
     583             :   __ movl(rdx, bp2);  // Sanity check.
     584           6 :   __ cmpl(rdx, Immediate(0x102));
     585           6 :   __ j(not_equal, &exit);
     586             :   __ incq(rax);
     587             : 
     588             :   // Non-zero to zero displacement.
     589          12 :   __ movl(rdx, Operand(bp2, 2 * kPointerSize));
     590           6 :   __ cmpl(rdx, Immediate(0x100));
     591           6 :   __ j(not_equal, &exit);
     592             :   __ incq(rax);
     593             : 
     594          12 :   __ movl(rdx, Operand(bp2, -2 * kPointerSize));
     595           6 :   __ cmpl(rdx, Immediate(0x104));
     596           6 :   __ j(not_equal, &exit);
     597             :   __ incq(rax);
     598             : 
     599           6 :   Operand bp2c4 = Operand(rbp, rcx, times_pointer_size, -4 * kPointerSize);
     600             : 
     601             :   // Test 14:
     602             :   __ movl(rdx, bp2c4);  // Sanity check.
     603           6 :   __ cmpl(rdx, Immediate(0x102));
     604           6 :   __ j(not_equal, &exit);
     605             :   __ incq(rax);
     606             : 
     607          12 :   __ movl(rdx, Operand(bp2c4, 2 * kPointerSize));
     608           6 :   __ cmpl(rdx, Immediate(0x100));
     609           6 :   __ j(not_equal, &exit);
     610             :   __ incq(rax);
     611             : 
     612          12 :   __ movl(rdx, Operand(bp2c4, -2 * kPointerSize));
     613           6 :   __ cmpl(rdx, Immediate(0x104));
     614           6 :   __ j(not_equal, &exit);
     615             :   __ incq(rax);
     616             : 
     617           6 :   Operand bx0 = Operand(rbx, 0);
     618             : 
     619             :   // Test 17.
     620             :   __ movl(rdx, bx0);  // Sanity check.
     621           6 :   __ cmpl(rdx, Immediate(0x105));
     622           6 :   __ j(not_equal, &exit);
     623             :   __ incq(rax);
     624             : 
     625          12 :   __ movl(rdx, Operand(bx0, 5 * kPointerSize));
     626           6 :   __ cmpl(rdx, Immediate(0x100));
     627           6 :   __ j(not_equal, &exit);
     628             :   __ incq(rax);
     629             : 
     630          12 :   __ movl(rdx, Operand(bx0, -4 * kPointerSize));
     631           6 :   __ cmpl(rdx, Immediate(0x109));
     632           6 :   __ j(not_equal, &exit);
     633             :   __ incq(rax);
     634             : 
     635           6 :   Operand bx2 = Operand(rbx, 2 * kPointerSize);
     636             : 
     637             :   // Test 20.
     638             :   __ movl(rdx, bx2);  // Sanity check.
     639           6 :   __ cmpl(rdx, Immediate(0x103));
     640           6 :   __ j(not_equal, &exit);
     641             :   __ incq(rax);
     642             : 
     643          12 :   __ movl(rdx, Operand(bx2, 2 * kPointerSize));
     644           6 :   __ cmpl(rdx, Immediate(0x101));
     645           6 :   __ j(not_equal, &exit);
     646             :   __ incq(rax);
     647             : 
     648             :   // Non-zero to zero displacement.
     649          12 :   __ movl(rdx, Operand(bx2, -2 * kPointerSize));
     650           6 :   __ cmpl(rdx, Immediate(0x105));
     651           6 :   __ j(not_equal, &exit);
     652             :   __ incq(rax);
     653             : 
     654           6 :   Operand bx2c2 = Operand(rbx, rcx, times_pointer_size, -2 * kPointerSize);
     655             : 
     656             :   // Test 23.
     657             :   __ movl(rdx, bx2c2);  // Sanity check.
     658           6 :   __ cmpl(rdx, Immediate(0x105));
     659           6 :   __ j(not_equal, &exit);
     660             :   __ incq(rax);
     661             : 
     662          12 :   __ movl(rdx, Operand(bx2c2, 2 * kPointerSize));
     663           6 :   __ cmpl(rdx, Immediate(0x103));
     664           6 :   __ j(not_equal, &exit);
     665             :   __ incq(rax);
     666             : 
     667          12 :   __ movl(rdx, Operand(bx2c2, -2 * kPointerSize));
     668           6 :   __ cmpl(rdx, Immediate(0x107));
     669           6 :   __ j(not_equal, &exit);
     670             :   __ incq(rax);
     671             : 
     672           6 :   Operand r80 = Operand(r8, 0);
     673             : 
     674             :   // Test 26.
     675             :   __ movl(rdx, r80);  // Sanity check.
     676           6 :   __ cmpl(rdx, Immediate(0x80808080));
     677           6 :   __ j(not_equal, &exit);
     678             :   __ incq(rax);
     679             : 
     680          12 :   __ movl(rdx, Operand(r80, -8 * kIntSize));
     681           6 :   __ cmpl(rdx, Immediate(0x78787878));
     682           6 :   __ j(not_equal, &exit);
     683             :   __ incq(rax);
     684             : 
     685          12 :   __ movl(rdx, Operand(r80, 8 * kIntSize));
     686           6 :   __ cmpl(rdx, Immediate(0x88888888));
     687           6 :   __ j(not_equal, &exit);
     688             :   __ incq(rax);
     689             : 
     690          12 :   __ movl(rdx, Operand(r80, -64 * kIntSize));
     691           6 :   __ cmpl(rdx, Immediate(0x40404040));
     692           6 :   __ j(not_equal, &exit);
     693             :   __ incq(rax);
     694             : 
     695          12 :   __ movl(rdx, Operand(r80, 64 * kIntSize));
     696           6 :   __ cmpl(rdx, Immediate(0xC0C0C0C0));
     697           6 :   __ j(not_equal, &exit);
     698             :   __ incq(rax);
     699             : 
     700           6 :   Operand r88 = Operand(r8, 8 * kIntSize);
     701             : 
     702             :   // Test 31.
     703             :   __ movl(rdx, r88);  // Sanity check.
     704           6 :   __ cmpl(rdx, Immediate(0x88888888));
     705           6 :   __ j(not_equal, &exit);
     706             :   __ incq(rax);
     707             : 
     708          12 :   __ movl(rdx, Operand(r88, -8 * kIntSize));
     709           6 :   __ cmpl(rdx, Immediate(0x80808080));
     710           6 :   __ j(not_equal, &exit);
     711             :   __ incq(rax);
     712             : 
     713          12 :   __ movl(rdx, Operand(r88, 8 * kIntSize));
     714           6 :   __ cmpl(rdx, Immediate(0x90909090));
     715           6 :   __ j(not_equal, &exit);
     716             :   __ incq(rax);
     717             : 
     718          12 :   __ movl(rdx, Operand(r88, -64 * kIntSize));
     719           6 :   __ cmpl(rdx, Immediate(0x48484848));
     720           6 :   __ j(not_equal, &exit);
     721             :   __ incq(rax);
     722             : 
     723          12 :   __ movl(rdx, Operand(r88, 64 * kIntSize));
     724           6 :   __ cmpl(rdx, Immediate(0xC8C8C8C8));
     725           6 :   __ j(not_equal, &exit);
     726             :   __ incq(rax);
     727             : 
     728             : 
     729           6 :   Operand r864 = Operand(r8, 64 * kIntSize);
     730             : 
     731             :   // Test 36.
     732             :   __ movl(rdx, r864);  // Sanity check.
     733           6 :   __ cmpl(rdx, Immediate(0xC0C0C0C0));
     734           6 :   __ j(not_equal, &exit);
     735             :   __ incq(rax);
     736             : 
     737          12 :   __ movl(rdx, Operand(r864, -8 * kIntSize));
     738           6 :   __ cmpl(rdx, Immediate(0xB8B8B8B8));
     739           6 :   __ j(not_equal, &exit);
     740             :   __ incq(rax);
     741             : 
     742          12 :   __ movl(rdx, Operand(r864, 8 * kIntSize));
     743           6 :   __ cmpl(rdx, Immediate(0xC8C8C8C8));
     744           6 :   __ j(not_equal, &exit);
     745             :   __ incq(rax);
     746             : 
     747          12 :   __ movl(rdx, Operand(r864, -64 * kIntSize));
     748           6 :   __ cmpl(rdx, Immediate(0x80808080));
     749           6 :   __ j(not_equal, &exit);
     750             :   __ incq(rax);
     751             : 
     752          12 :   __ movl(rdx, Operand(r864, 32 * kIntSize));
     753           6 :   __ cmpl(rdx, Immediate(0xE0E0E0E0));
     754           6 :   __ j(not_equal, &exit);
     755             :   __ incq(rax);
     756             : 
     757             :   // 32-bit offset to 8-bit offset.
     758          12 :   __ movl(rdx, Operand(r864, -60 * kIntSize));
     759           6 :   __ cmpl(rdx, Immediate(0x84848484));
     760           6 :   __ j(not_equal, &exit);
     761             :   __ incq(rax);
     762             : 
     763          12 :   __ movl(rdx, Operand(r864, 60 * kIntSize));
     764           6 :   __ cmpl(rdx, Immediate(0xFCFCFCFC));
     765           6 :   __ j(not_equal, &exit);
     766             :   __ incq(rax);
     767             : 
     768             :   // Test unaligned offsets.
     769             : 
     770             :   // Test 43.
     771          12 :   __ movl(rdx, Operand(r80, 2));
     772           6 :   __ cmpl(rdx, Immediate(0x81818080));
     773           6 :   __ j(not_equal, &exit);
     774             :   __ incq(rax);
     775             : 
     776          12 :   __ movl(rdx, Operand(r80, -2));
     777           6 :   __ cmpl(rdx, Immediate(0x80807F7F));
     778           6 :   __ j(not_equal, &exit);
     779             :   __ incq(rax);
     780             : 
     781          12 :   __ movl(rdx, Operand(r80, 126));
     782           6 :   __ cmpl(rdx, Immediate(0xA0A09F9F));
     783           6 :   __ j(not_equal, &exit);
     784             :   __ incq(rax);
     785             : 
     786          12 :   __ movl(rdx, Operand(r80, -126));
     787           6 :   __ cmpl(rdx, Immediate(0x61616060));
     788           6 :   __ j(not_equal, &exit);
     789             :   __ incq(rax);
     790             : 
     791          12 :   __ movl(rdx, Operand(r80, 254));
     792           6 :   __ cmpl(rdx, Immediate(0xC0C0BFBF));
     793           6 :   __ j(not_equal, &exit);
     794             :   __ incq(rax);
     795             : 
     796          12 :   __ movl(rdx, Operand(r80, -254));
     797           6 :   __ cmpl(rdx, Immediate(0x41414040));
     798           6 :   __ j(not_equal, &exit);
     799             :   __ incq(rax);
     800             : 
     801             :   // Success.
     802             : 
     803             :   __ movl(rax, Immediate(0));
     804           6 :   __ bind(&exit);
     805          12 :   __ leaq(rsp, Operand(rbp, kPointerSize));
     806           6 :   __ popq(rbp);
     807           6 :   __ popq(rbx);
     808           6 :   __ popq(r14);
     809           6 :   __ popq(r13);
     810             :   ExitCode(masm);
     811           6 :   __ ret(0);
     812             : 
     813             : 
     814             :   CodeDesc desc;
     815           6 :   masm->GetCode(isolate, &desc);
     816             :   // Call the function from C++.
     817           6 :   int result = FUNCTION_CAST<F0>(buffer)();
     818           6 :   CHECK_EQ(0, result);
     819           6 : }
     820             : 
     821             : 
     822       23724 : TEST(LoadAndStoreWithRepresentation) {
     823             :   // Allocate an executable page of memory.
     824             :   size_t actual_size;
     825             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     826           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     827           6 :   CHECK(buffer);
     828             :   Isolate* isolate = CcTest::i_isolate();
     829             :   HandleScope handles(isolate);
     830             :   MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
     831           6 :                            v8::internal::CodeObjectRequired::kYes);
     832             :   MacroAssembler* masm = &assembler;  // Create a pointer for the __ macro.
     833             :   EntryCode(masm);
     834           6 :   __ subq(rsp, Immediate(1 * kPointerSize));
     835             :   Label exit;
     836             : 
     837             :   // Test 1.
     838             :   __ movq(rax, Immediate(1));  // Test number.
     839          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     840             :   __ movq(rcx, Immediate(-1));
     841           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::UInteger8());
     842          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     843             :   __ movl(rdx, Immediate(255));
     844           6 :   __ cmpq(rcx, rdx);
     845           6 :   __ j(not_equal, &exit);
     846           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::UInteger8());
     847           6 :   __ cmpq(rcx, rdx);
     848           6 :   __ j(not_equal, &exit);
     849             : 
     850             :   // Test 2.
     851             :   __ movq(rax, Immediate(2));  // Test number.
     852          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     853           6 :   __ Set(rcx, V8_2PART_UINT64_C(0xdeadbeaf, 12345678));
     854           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Smi());
     855          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     856           6 :   __ Set(rdx, V8_2PART_UINT64_C(0xdeadbeaf, 12345678));
     857           6 :   __ cmpq(rcx, rdx);
     858           6 :   __ j(not_equal, &exit);
     859           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Smi());
     860           6 :   __ cmpq(rcx, rdx);
     861           6 :   __ j(not_equal, &exit);
     862             : 
     863             :   // Test 3.
     864             :   __ movq(rax, Immediate(3));  // Test number.
     865          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     866             :   __ movq(rcx, Immediate(-1));
     867           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer32());
     868          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     869             :   __ movl(rdx, Immediate(-1));
     870           6 :   __ cmpq(rcx, rdx);
     871           6 :   __ j(not_equal, &exit);
     872           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer32());
     873           6 :   __ cmpq(rcx, rdx);
     874           6 :   __ j(not_equal, &exit);
     875             : 
     876             :   // Test 4.
     877             :   __ movq(rax, Immediate(4));  // Test number.
     878          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     879             :   __ movl(rcx, Immediate(0x44332211));
     880           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::HeapObject());
     881          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     882             :   __ movl(rdx, Immediate(0x44332211));
     883           6 :   __ cmpq(rcx, rdx);
     884           6 :   __ j(not_equal, &exit);
     885           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::HeapObject());
     886           6 :   __ cmpq(rcx, rdx);
     887           6 :   __ j(not_equal, &exit);
     888             : 
     889             :   // Test 5.
     890             :   __ movq(rax, Immediate(5));  // Test number.
     891          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     892           6 :   __ Set(rcx, V8_2PART_UINT64_C(0x12345678, deadbeaf));
     893           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Tagged());
     894          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     895           6 :   __ Set(rdx, V8_2PART_UINT64_C(0x12345678, deadbeaf));
     896           6 :   __ cmpq(rcx, rdx);
     897           6 :   __ j(not_equal, &exit);
     898           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Tagged());
     899           6 :   __ cmpq(rcx, rdx);
     900           6 :   __ j(not_equal, &exit);
     901             : 
     902             :   // Test 6.
     903             :   __ movq(rax, Immediate(6));  // Test number.
     904          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     905           6 :   __ Set(rcx, V8_2PART_UINT64_C(0x11223344, 55667788));
     906           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::External());
     907          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     908           6 :   __ Set(rdx, V8_2PART_UINT64_C(0x11223344, 55667788));
     909           6 :   __ cmpq(rcx, rdx);
     910           6 :   __ j(not_equal, &exit);
     911           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::External());
     912           6 :   __ cmpq(rcx, rdx);
     913           6 :   __ j(not_equal, &exit);
     914             : 
     915             :   // Test 7.
     916             :   __ movq(rax, Immediate(7));  // Test number.
     917          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     918             :   __ movq(rcx, Immediate(-1));
     919           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer8());
     920          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     921             :   __ movl(rdx, Immediate(255));
     922           6 :   __ cmpq(rcx, rdx);
     923           6 :   __ j(not_equal, &exit);
     924           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer8());
     925             :   __ movq(rcx, Immediate(-1));
     926           6 :   __ cmpq(rcx, rdx);
     927           6 :   __ j(not_equal, &exit);
     928             : 
     929             :   // Test 8.
     930             :   __ movq(rax, Immediate(8));  // Test number.
     931          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     932             :   __ movq(rcx, Immediate(-1));
     933           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer16());
     934          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     935             :   __ movl(rdx, Immediate(65535));
     936           6 :   __ cmpq(rcx, rdx);
     937           6 :   __ j(not_equal, &exit);
     938           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer16());
     939             :   __ movq(rcx, Immediate(-1));
     940           6 :   __ cmpq(rcx, rdx);
     941           6 :   __ j(not_equal, &exit);
     942             : 
     943             :   // Test 9.
     944             :   __ movq(rax, Immediate(9));  // Test number.
     945          12 :   __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
     946             :   __ movq(rcx, Immediate(-1));
     947           6 :   __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::UInteger16());
     948          12 :   __ movq(rcx, Operand(rsp, 0 * kPointerSize));
     949             :   __ movl(rdx, Immediate(65535));
     950           6 :   __ cmpq(rcx, rdx);
     951           6 :   __ j(not_equal, &exit);
     952           6 :   __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::UInteger16());
     953           6 :   __ cmpq(rcx, rdx);
     954           6 :   __ j(not_equal, &exit);
     955             : 
     956             :   __ xorq(rax, rax);  // Success.
     957           6 :   __ bind(&exit);
     958           6 :   __ addq(rsp, Immediate(1 * kPointerSize));
     959             :   ExitCode(masm);
     960           6 :   __ ret(0);
     961             : 
     962             :   CodeDesc desc;
     963           6 :   masm->GetCode(isolate, &desc);
     964             :   // Call the function from C++.
     965           6 :   int result = FUNCTION_CAST<F0>(buffer)();
     966           6 :   CHECK_EQ(0, result);
     967           6 : }
     968             : 
     969           6 : void TestFloat32x4Abs(MacroAssembler* masm, Label* exit, float x, float y,
     970             :                       float z, float w) {
     971           6 :   __ subq(rsp, Immediate(kSimd128Size));
     972             : 
     973           6 :   __ Move(xmm1, x);
     974           6 :   __ Movss(Operand(rsp, 0 * kFloatSize), xmm1);
     975             :   __ Move(xmm2, y);
     976           6 :   __ Movss(Operand(rsp, 1 * kFloatSize), xmm2);
     977             :   __ Move(xmm3, z);
     978           6 :   __ Movss(Operand(rsp, 2 * kFloatSize), xmm3);
     979             :   __ Move(xmm4, w);
     980           6 :   __ Movss(Operand(rsp, 3 * kFloatSize), xmm4);
     981           6 :   __ Movups(xmm0, Operand(rsp, 0));
     982             : 
     983           6 :   __ Absps(xmm0);
     984           6 :   __ Movups(Operand(rsp, 0), xmm0);
     985             : 
     986             :   __ incq(rax);
     987           6 :   __ Move(xmm1, fabsf(x));
     988           6 :   __ Ucomiss(xmm1, Operand(rsp, 0 * kFloatSize));
     989           6 :   __ j(not_equal, exit);
     990             :   __ incq(rax);
     991           6 :   __ Move(xmm2, fabsf(y));
     992           6 :   __ Ucomiss(xmm2, Operand(rsp, 1 * kFloatSize));
     993           6 :   __ j(not_equal, exit);
     994             :   __ incq(rax);
     995           6 :   __ Move(xmm3, fabsf(z));
     996           6 :   __ Ucomiss(xmm3, Operand(rsp, 2 * kFloatSize));
     997           6 :   __ j(not_equal, exit);
     998             :   __ incq(rax);
     999           6 :   __ Move(xmm4, fabsf(w));
    1000           6 :   __ Ucomiss(xmm4, Operand(rsp, 3 * kFloatSize));
    1001           6 :   __ j(not_equal, exit);
    1002             : 
    1003           6 :   __ addq(rsp, Immediate(kSimd128Size));
    1004           6 : }
    1005             : 
    1006           6 : void TestFloat32x4Neg(MacroAssembler* masm, Label* exit, float x, float y,
    1007             :                       float z, float w) {
    1008           6 :   __ subq(rsp, Immediate(kSimd128Size));
    1009             : 
    1010           6 :   __ Move(xmm1, x);
    1011           6 :   __ Movss(Operand(rsp, 0 * kFloatSize), xmm1);
    1012             :   __ Move(xmm2, y);
    1013           6 :   __ Movss(Operand(rsp, 1 * kFloatSize), xmm2);
    1014             :   __ Move(xmm3, z);
    1015           6 :   __ Movss(Operand(rsp, 2 * kFloatSize), xmm3);
    1016             :   __ Move(xmm4, w);
    1017           6 :   __ Movss(Operand(rsp, 3 * kFloatSize), xmm4);
    1018           6 :   __ Movups(xmm0, Operand(rsp, 0));
    1019             : 
    1020           6 :   __ Negps(xmm0);
    1021           6 :   __ Movups(Operand(rsp, 0), xmm0);
    1022             : 
    1023             :   __ incq(rax);
    1024           6 :   __ Move(xmm1, -x);
    1025           6 :   __ Ucomiss(xmm1, Operand(rsp, 0 * kFloatSize));
    1026           6 :   __ j(not_equal, exit);
    1027             :   __ incq(rax);
    1028           6 :   __ Move(xmm2, -y);
    1029           6 :   __ Ucomiss(xmm2, Operand(rsp, 1 * kFloatSize));
    1030           6 :   __ j(not_equal, exit);
    1031             :   __ incq(rax);
    1032           6 :   __ Move(xmm3, -z);
    1033           6 :   __ Ucomiss(xmm3, Operand(rsp, 2 * kFloatSize));
    1034           6 :   __ j(not_equal, exit);
    1035             :   __ incq(rax);
    1036           6 :   __ Move(xmm4, -w);
    1037           6 :   __ Ucomiss(xmm4, Operand(rsp, 3 * kFloatSize));
    1038           6 :   __ j(not_equal, exit);
    1039             : 
    1040           6 :   __ addq(rsp, Immediate(kSimd128Size));
    1041           6 : }
    1042             : 
    1043           6 : void TestFloat64x2Abs(MacroAssembler* masm, Label* exit, double x, double y) {
    1044           6 :   __ subq(rsp, Immediate(kSimd128Size));
    1045             : 
    1046           6 :   __ Move(xmm1, x);
    1047           6 :   __ Movsd(Operand(rsp, 0 * kDoubleSize), xmm1);
    1048             :   __ Move(xmm2, y);
    1049           6 :   __ Movsd(Operand(rsp, 1 * kDoubleSize), xmm2);
    1050           6 :   __ movupd(xmm0, Operand(rsp, 0));
    1051             : 
    1052           6 :   __ Abspd(xmm0);
    1053           6 :   __ movupd(Operand(rsp, 0), xmm0);
    1054             : 
    1055             :   __ incq(rax);
    1056           6 :   __ Move(xmm1, fabs(x));
    1057           6 :   __ Ucomisd(xmm1, Operand(rsp, 0 * kDoubleSize));
    1058           6 :   __ j(not_equal, exit);
    1059             :   __ incq(rax);
    1060           6 :   __ Move(xmm2, fabs(y));
    1061           6 :   __ Ucomisd(xmm2, Operand(rsp, 1 * kDoubleSize));
    1062           6 :   __ j(not_equal, exit);
    1063             : 
    1064           6 :   __ addq(rsp, Immediate(kSimd128Size));
    1065           6 : }
    1066             : 
    1067           6 : void TestFloat64x2Neg(MacroAssembler* masm, Label* exit, double x, double y) {
    1068           6 :   __ subq(rsp, Immediate(kSimd128Size));
    1069             : 
    1070           6 :   __ Move(xmm1, x);
    1071           6 :   __ Movsd(Operand(rsp, 0 * kDoubleSize), xmm1);
    1072             :   __ Move(xmm2, y);
    1073           6 :   __ Movsd(Operand(rsp, 1 * kDoubleSize), xmm2);
    1074           6 :   __ movupd(xmm0, Operand(rsp, 0));
    1075             : 
    1076           6 :   __ Negpd(xmm0);
    1077           6 :   __ movupd(Operand(rsp, 0), xmm0);
    1078             : 
    1079             :   __ incq(rax);
    1080           6 :   __ Move(xmm1, -x);
    1081           6 :   __ Ucomisd(xmm1, Operand(rsp, 0 * kDoubleSize));
    1082           6 :   __ j(not_equal, exit);
    1083             :   __ incq(rax);
    1084           6 :   __ Move(xmm2, -y);
    1085           6 :   __ Ucomisd(xmm2, Operand(rsp, 1 * kDoubleSize));
    1086           6 :   __ j(not_equal, exit);
    1087             : 
    1088           6 :   __ addq(rsp, Immediate(kSimd128Size));
    1089           6 : }
    1090             : 
    1091       23724 : TEST(SIMDMacros) {
    1092             :   // Allocate an executable page of memory.
    1093             :   size_t actual_size;
    1094             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
    1095           6 :       Assembler::kMinimalBufferSize * 2, &actual_size, true));
    1096           6 :   CHECK(buffer);
    1097             :   Isolate* isolate = CcTest::i_isolate();
    1098             :   HandleScope handles(isolate);
    1099             :   MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
    1100           6 :                            v8::internal::CodeObjectRequired::kYes);
    1101             : 
    1102             :   MacroAssembler* masm = &assembler;
    1103             :   EntryCode(masm);
    1104             :   Label exit;
    1105             : 
    1106             :   __ xorq(rax, rax);
    1107           6 :   TestFloat32x4Abs(masm, &exit, 1.5, -1.5, 0.5, -0.5);
    1108           6 :   TestFloat32x4Neg(masm, &exit, 1.5, -1.5, 0.5, -0.5);
    1109           6 :   TestFloat64x2Abs(masm, &exit, 1.75, -1.75);
    1110           6 :   TestFloat64x2Neg(masm, &exit, 1.75, -1.75);
    1111             : 
    1112             :   __ xorq(rax, rax);  // Success.
    1113           6 :   __ bind(&exit);
    1114             :   ExitCode(masm);
    1115           6 :   __ ret(0);
    1116             : 
    1117             :   CodeDesc desc;
    1118           6 :   masm->GetCode(isolate, &desc);
    1119             :   // Call the function from C++.
    1120           6 :   int result = FUNCTION_CAST<F0>(buffer)();
    1121           6 :   CHECK_EQ(0, result);
    1122           6 : }
    1123             : 
    1124             : #undef __
    1125             : 
    1126             : }  // namespace test_macro_assembler_x64
    1127             : }  // namespace internal
    1128       71154 : }  // namespace v8

Generated by: LCOV version 1.10