LCOV - code coverage report
Current view: top level - test/cctest - test-assembler-x64.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1375 1375 100.0 %
Date: 2017-10-20 Functions: 39 39 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 <cstdlib>
      29             : #include <iostream>
      30             : 
      31             : #include "src/v8.h"
      32             : 
      33             : #include "src/base/platform/platform.h"
      34             : #include "src/base/utils/random-number-generator.h"
      35             : #include "src/double.h"
      36             : #include "src/factory.h"
      37             : #include "src/macro-assembler.h"
      38             : #include "src/objects-inl.h"
      39             : #include "src/ostreams.h"
      40             : #include "test/cctest/cctest.h"
      41             : 
      42             : namespace v8 {
      43             : namespace internal {
      44             : 
      45             : // Test the x64 assembler by compiling some simple functions into
      46             : // a buffer and executing them.  These tests do not initialize the
      47             : // V8 library, create a context, or use any V8 objects.
      48             : // The AMD64 calling convention is used, with the first six arguments
      49             : // in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in
      50             : // the XMM registers.  The return value is in RAX.
      51             : // This calling convention is used on Linux, with GCC, and on Mac OS,
      52             : // with GCC.  A different convention is used on 64-bit windows,
      53             : // where the first four integer arguments are passed in RCX, RDX, R8 and R9.
      54             : 
      55             : typedef int (*F0)();
      56             : typedef int (*F1)(int64_t x);
      57             : typedef int (*F2)(int64_t x, int64_t y);
      58             : typedef unsigned (*F3)(double x);
      59             : typedef uint64_t (*F4)(uint64_t* x, uint64_t* y);
      60             : typedef uint64_t (*F5)(uint64_t x);
      61             : 
      62             : #ifdef _WIN64
      63             : static const Register arg1 = rcx;
      64             : static const Register arg2 = rdx;
      65             : #else
      66             : static const Register arg1 = rdi;
      67             : static const Register arg2 = rsi;
      68             : #endif
      69             : 
      70             : #define __ assm.
      71             : 
      72             : 
      73       23724 : TEST(AssemblerX64ReturnOperation) {
      74           6 :   CcTest::InitializeVM();
      75             :   // Allocate an executable page of memory.
      76             :   size_t actual_size;
      77             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
      78           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
      79           6 :   CHECK(buffer);
      80          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
      81             : 
      82             :   // Assemble a simple function that copies argument 2 and returns it.
      83             :   __ movq(rax, arg2);
      84           6 :   __ nop();
      85           6 :   __ ret(0);
      86             : 
      87             :   CodeDesc desc;
      88           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
      89             :   // Call the function from C++.
      90           6 :   int result =  FUNCTION_CAST<F2>(buffer)(3, 2);
      91           6 :   CHECK_EQ(2, result);
      92           6 : }
      93             : 
      94             : 
      95       23724 : TEST(AssemblerX64StackOperations) {
      96           6 :   CcTest::InitializeVM();
      97             :   // Allocate an executable page of memory.
      98             :   size_t actual_size;
      99             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     100           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     101           6 :   CHECK(buffer);
     102          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     103             : 
     104             :   // Assemble a simple function that copies argument 2 and returns it.
     105             :   // We compile without stack frame pointers, so the gdb debugger shows
     106             :   // incorrect stack frames when debugging this function (which has them).
     107           6 :   __ pushq(rbp);
     108             :   __ movq(rbp, rsp);
     109           6 :   __ pushq(arg2);  // Value at (rbp - 8)
     110           6 :   __ pushq(arg2);  // Value at (rbp - 16)
     111           6 :   __ pushq(arg1);  // Value at (rbp - 24)
     112           6 :   __ popq(rax);
     113           6 :   __ popq(rax);
     114           6 :   __ popq(rax);
     115           6 :   __ popq(rbp);
     116           6 :   __ nop();
     117           6 :   __ ret(0);
     118             : 
     119             :   CodeDesc desc;
     120           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     121             :   // Call the function from C++.
     122           6 :   int result =  FUNCTION_CAST<F2>(buffer)(3, 2);
     123           6 :   CHECK_EQ(2, result);
     124           6 : }
     125             : 
     126             : 
     127       23724 : TEST(AssemblerX64ArithmeticOperations) {
     128           6 :   CcTest::InitializeVM();
     129             :   // Allocate an executable page of memory.
     130             :   size_t actual_size;
     131             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     132           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     133           6 :   CHECK(buffer);
     134          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     135             : 
     136             :   // Assemble a simple function that adds arguments returning the sum.
     137             :   __ movq(rax, arg2);
     138           6 :   __ addq(rax, arg1);
     139           6 :   __ ret(0);
     140             : 
     141             :   CodeDesc desc;
     142           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     143             :   // Call the function from C++.
     144           6 :   int result =  FUNCTION_CAST<F2>(buffer)(3, 2);
     145           6 :   CHECK_EQ(5, result);
     146           6 : }
     147             : 
     148             : 
     149       23724 : TEST(AssemblerX64CmpbOperation) {
     150           6 :   CcTest::InitializeVM();
     151             :   // Allocate an executable page of memory.
     152             :   size_t actual_size;
     153             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     154           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     155           6 :   CHECK(buffer);
     156          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     157             : 
     158             :   // Assemble a function that compare argument byte returing 1 if equal else 0.
     159             :   // On Windows, it compares rcx with rdx which does not require REX prefix;
     160             :   // on Linux, it compares rdi with rsi which requires REX prefix.
     161             : 
     162             :   Label done;
     163             :   __ movq(rax, Immediate(1));
     164             :   __ cmpb(arg1, arg2);
     165           6 :   __ j(equal, &done);
     166             :   __ movq(rax, Immediate(0));
     167           6 :   __ bind(&done);
     168           6 :   __ ret(0);
     169             : 
     170             :   CodeDesc desc;
     171           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     172             :   // Call the function from C++.
     173           6 :   int result =  FUNCTION_CAST<F2>(buffer)(0x1002, 0x2002);
     174           6 :   CHECK_EQ(1, result);
     175           6 :   result =  FUNCTION_CAST<F2>(buffer)(0x1002, 0x2003);
     176           6 :   CHECK_EQ(0, result);
     177           6 : }
     178             : 
     179       23724 : TEST(Regression684407) {
     180           6 :   CcTest::InitializeVM();
     181             :   // Allocate an executable page of memory.
     182             :   size_t actual_size;
     183             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     184           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     185           6 :   CHECK(buffer);
     186          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     187           6 :   Address before = assm.pc();
     188             :   __ cmpl(Operand(arg1, 0),
     189          12 :           Immediate(0, RelocInfo::WASM_FUNCTION_TABLE_SIZE_REFERENCE));
     190           6 :   Address after = assm.pc();
     191           6 :   size_t instruction_size = static_cast<size_t>(after - before);
     192             :   // Check that the immediate is not encoded as uint8.
     193           6 :   CHECK_LT(sizeof(uint32_t), instruction_size);
     194           6 : }
     195             : 
     196       23724 : TEST(AssemblerX64ImulOperation) {
     197           6 :   CcTest::InitializeVM();
     198             :   // Allocate an executable page of memory.
     199             :   size_t actual_size;
     200             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     201           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     202           6 :   CHECK(buffer);
     203          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     204             : 
     205             :   // Assemble a simple function that multiplies arguments returning the high
     206             :   // word.
     207             :   __ movq(rax, arg2);
     208             :   __ imulq(arg1);
     209             :   __ movq(rax, rdx);
     210           6 :   __ ret(0);
     211             : 
     212             :   CodeDesc desc;
     213           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     214             :   // Call the function from C++.
     215           6 :   int result =  FUNCTION_CAST<F2>(buffer)(3, 2);
     216           6 :   CHECK_EQ(0, result);
     217           6 :   result =  FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l);
     218           6 :   CHECK_EQ(1, result);
     219           6 :   result =  FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l);
     220           6 :   CHECK_EQ(-1, result);
     221           6 : }
     222             : 
     223       23724 : TEST(AssemblerX64testbwqOperation) {
     224           6 :   CcTest::InitializeVM();
     225           6 :   v8::HandleScope scope(CcTest::isolate());
     226             :   // Allocate an executable page of memory.
     227             :   size_t actual_size;
     228             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     229           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     230           6 :   CHECK(buffer);
     231          18 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     232             : 
     233           6 :   __ pushq(rbx);
     234           6 :   __ pushq(rdi);
     235           6 :   __ pushq(rsi);
     236           6 :   __ pushq(r12);
     237           6 :   __ pushq(r13);
     238           6 :   __ pushq(r14);
     239           6 :   __ pushq(r15);
     240             : 
     241             :   // Assemble a simple function that tests testb and testw
     242             :   Label bad;
     243             :   Label done;
     244             : 
     245             :   // Test immediate testb and testw
     246             :   __ movq(rax, Immediate(2));
     247             :   __ movq(rbx, Immediate(4));
     248             :   __ movq(rcx, Immediate(8));
     249             :   __ movq(rdx, Immediate(16));
     250             :   __ movq(rsi, Immediate(32));
     251             :   __ movq(rdi, Immediate(64));
     252             :   __ movq(r10, Immediate(128));
     253             :   __ movq(r11, Immediate(0));
     254             :   __ movq(r12, Immediate(0));
     255             :   __ movq(r13, Immediate(0));
     256           6 :   __ testb(rax, Immediate(2));
     257           6 :   __ j(zero, &bad);
     258           6 :   __ testb(rbx, Immediate(4));
     259           6 :   __ j(zero, &bad);
     260           6 :   __ testb(rcx, Immediate(8));
     261           6 :   __ j(zero, &bad);
     262           6 :   __ testb(rdx, Immediate(16));
     263           6 :   __ j(zero, &bad);
     264           6 :   __ testb(rsi, Immediate(32));
     265           6 :   __ j(zero, &bad);
     266           6 :   __ testb(rdi, Immediate(64));
     267           6 :   __ j(zero, &bad);
     268           6 :   __ testb(r10, Immediate(128));
     269           6 :   __ j(zero, &bad);
     270           6 :   __ testw(rax, Immediate(2));
     271           6 :   __ j(zero, &bad);
     272           6 :   __ testw(rbx, Immediate(4));
     273           6 :   __ j(zero, &bad);
     274           6 :   __ testw(rcx, Immediate(8));
     275           6 :   __ j(zero, &bad);
     276           6 :   __ testw(rdx, Immediate(16));
     277           6 :   __ j(zero, &bad);
     278           6 :   __ testw(rsi, Immediate(32));
     279           6 :   __ j(zero, &bad);
     280           6 :   __ testw(rdi, Immediate(64));
     281           6 :   __ j(zero, &bad);
     282           6 :   __ testw(r10, Immediate(128));
     283           6 :   __ j(zero, &bad);
     284             : 
     285             :   // Test reg, reg testb and testw
     286             :   __ movq(rax, Immediate(2));
     287             :   __ movq(rbx, Immediate(2));
     288           6 :   __ testb(rax, rbx);
     289           6 :   __ j(zero, &bad);
     290             :   __ movq(rbx, Immediate(4));
     291             :   __ movq(rax, Immediate(4));
     292           6 :   __ testb(rbx, rax);
     293           6 :   __ j(zero, &bad);
     294             :   __ movq(rax, Immediate(8));
     295           6 :   __ testb(rcx, rax);
     296           6 :   __ j(zero, &bad);
     297             :   __ movq(rax, Immediate(16));
     298           6 :   __ testb(rdx, rax);
     299           6 :   __ j(zero, &bad);
     300             :   __ movq(rax, Immediate(32));
     301           6 :   __ testb(rsi, rax);
     302           6 :   __ j(zero, &bad);
     303             :   __ movq(rax, Immediate(64));
     304           6 :   __ testb(rdi, rax);
     305           6 :   __ j(zero, &bad);
     306             :   __ movq(rax, Immediate(128));
     307           6 :   __ testb(r10, rax);
     308           6 :   __ j(zero, &bad);
     309             :   __ movq(rax, Immediate(2));
     310             :   __ movq(rbx, Immediate(2));
     311           6 :   __ testw(rax, rbx);
     312           6 :   __ j(zero, &bad);
     313             :   __ movq(rbx, Immediate(4));
     314             :   __ movq(rax, Immediate(4));
     315           6 :   __ testw(rbx, rax);
     316           6 :   __ j(zero, &bad);
     317             :   __ movq(rax, Immediate(8));
     318           6 :   __ testw(rcx, rax);
     319           6 :   __ j(zero, &bad);
     320             :   __ movq(rax, Immediate(16));
     321           6 :   __ testw(rdx, rax);
     322           6 :   __ j(zero, &bad);
     323             :   __ movq(rax, Immediate(32));
     324           6 :   __ testw(rsi, rax);
     325           6 :   __ j(zero, &bad);
     326             :   __ movq(rax, Immediate(64));
     327           6 :   __ testw(rdi, rax);
     328           6 :   __ j(zero, &bad);
     329             :   __ movq(rax, Immediate(128));
     330           6 :   __ testw(r10, rax);
     331           6 :   __ j(zero, &bad);
     332             : 
     333             :   // Test diffrrent extended register coding combinations.
     334             :   __ movq(rax, Immediate(5));
     335             :   __ movq(r11, Immediate(5));
     336           6 :   __ testb(r11, rax);
     337           6 :   __ j(zero, &bad);
     338           6 :   __ testb(rax, r11);
     339           6 :   __ j(zero, &bad);
     340           6 :   __ testw(r11, rax);
     341           6 :   __ j(zero, &bad);
     342           6 :   __ testw(rax, r11);
     343           6 :   __ j(zero, &bad);
     344             :   __ movq(r11, Immediate(3));
     345             :   __ movq(r12, Immediate(3));
     346             :   __ movq(rdi, Immediate(3));
     347           6 :   __ testb(r12, rdi);
     348           6 :   __ j(zero, &bad);
     349           6 :   __ testb(rdi, r12);
     350           6 :   __ j(zero, &bad);
     351           6 :   __ testb(r12, r11);
     352           6 :   __ j(zero, &bad);
     353           6 :   __ testb(r11, r12);
     354           6 :   __ j(zero, &bad);
     355           6 :   __ testw(r12, r11);
     356           6 :   __ j(zero, &bad);
     357           6 :   __ testw(r11, r12);
     358           6 :   __ j(zero, &bad);
     359             : 
     360             :   // Test sign-extended imediate tests
     361             :   __ movq(r11, Immediate(2));
     362             :   __ shlq(r11, Immediate(32));
     363             :   __ testq(r11, Immediate(-1));
     364           6 :   __ j(zero, &bad);
     365             : 
     366             :   // All tests passed
     367             :   __ movq(rax, Immediate(1));
     368           6 :   __ jmp(&done);
     369             : 
     370           6 :   __ bind(&bad);
     371             :   __ movq(rax, Immediate(0));
     372           6 :   __ bind(&done);
     373             : 
     374           6 :   __ popq(r15);
     375           6 :   __ popq(r14);
     376           6 :   __ popq(r13);
     377           6 :   __ popq(r12);
     378           6 :   __ popq(rsi);
     379           6 :   __ popq(rdi);
     380           6 :   __ popq(rbx);
     381             : 
     382           6 :   __ ret(0);
     383             : 
     384             :   CodeDesc desc;
     385           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     386             :   // Call the function from C++.
     387           6 :   int result = FUNCTION_CAST<F2>(buffer)(0, 0);
     388          12 :   CHECK_EQ(1, result);
     389           6 : }
     390             : 
     391       23724 : TEST(AssemblerX64XchglOperations) {
     392           6 :   CcTest::InitializeVM();
     393             :   // Allocate an executable page of memory.
     394             :   size_t actual_size;
     395             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     396           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     397           6 :   CHECK(buffer);
     398          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     399             : 
     400          12 :   __ movq(rax, Operand(arg1, 0));
     401          12 :   __ movq(r11, Operand(arg2, 0));
     402             :   __ xchgl(rax, r11);
     403          12 :   __ movq(Operand(arg1, 0), rax);
     404          12 :   __ movq(Operand(arg2, 0), r11);
     405           6 :   __ ret(0);
     406             : 
     407             :   CodeDesc desc;
     408           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     409             :   // Call the function from C++.
     410           6 :   uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
     411           6 :   uint64_t right = V8_2PART_UINT64_C(0x30000000, 40000000);
     412           6 :   uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
     413           6 :   CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 40000000), left);
     414           6 :   CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 20000000), right);
     415           6 :   USE(result);
     416           6 : }
     417             : 
     418             : 
     419       23724 : TEST(AssemblerX64OrlOperations) {
     420           6 :   CcTest::InitializeVM();
     421             :   // Allocate an executable page of memory.
     422             :   size_t actual_size;
     423             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     424           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     425           6 :   CHECK(buffer);
     426          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     427             : 
     428          12 :   __ movq(rax, Operand(arg2, 0));
     429          12 :   __ orl(Operand(arg1, 0), rax);
     430           6 :   __ ret(0);
     431             : 
     432             :   CodeDesc desc;
     433           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     434             :   // Call the function from C++.
     435           6 :   uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
     436           6 :   uint64_t right = V8_2PART_UINT64_C(0x30000000, 40000000);
     437           6 :   uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
     438           6 :   CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 60000000), left);
     439           6 :   USE(result);
     440           6 : }
     441             : 
     442             : 
     443       23724 : TEST(AssemblerX64RollOperations) {
     444           6 :   CcTest::InitializeVM();
     445             :   // Allocate an executable page of memory.
     446             :   size_t actual_size;
     447             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     448           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     449           6 :   CHECK(buffer);
     450          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     451             : 
     452             :   __ movq(rax, arg1);
     453             :   __ roll(rax, Immediate(1));
     454           6 :   __ ret(0);
     455             : 
     456             :   CodeDesc desc;
     457           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     458             :   // Call the function from C++.
     459             :   uint64_t src = V8_2PART_UINT64_C(0x10000000, C0000000);
     460           6 :   uint64_t result = FUNCTION_CAST<F5>(buffer)(src);
     461           6 :   CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 80000001), result);
     462           6 : }
     463             : 
     464             : 
     465       23724 : TEST(AssemblerX64SublOperations) {
     466           6 :   CcTest::InitializeVM();
     467             :   // Allocate an executable page of memory.
     468             :   size_t actual_size;
     469             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     470           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     471           6 :   CHECK(buffer);
     472          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     473             : 
     474          12 :   __ movq(rax, Operand(arg2, 0));
     475          12 :   __ subl(Operand(arg1, 0), rax);
     476           6 :   __ ret(0);
     477             : 
     478             :   CodeDesc desc;
     479           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     480             :   // Call the function from C++.
     481           6 :   uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
     482           6 :   uint64_t right = V8_2PART_UINT64_C(0x30000000, 40000000);
     483           6 :   uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
     484           6 :   CHECK_EQ(V8_2PART_UINT64_C(0x10000000, e0000000), left);
     485           6 :   USE(result);
     486           6 : }
     487             : 
     488             : 
     489       23724 : TEST(AssemblerX64TestlOperations) {
     490           6 :   CcTest::InitializeVM();
     491             :   // Allocate an executable page of memory.
     492             :   size_t actual_size;
     493             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     494           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     495           6 :   CHECK(buffer);
     496          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     497             : 
     498             :   // Set rax with the ZF flag of the testl instruction.
     499             :   Label done;
     500             :   __ movq(rax, Immediate(1));
     501          12 :   __ movq(r11, Operand(arg2, 0));
     502          12 :   __ testl(Operand(arg1, 0), r11);
     503           6 :   __ j(zero, &done, Label::kNear);
     504             :   __ movq(rax, Immediate(0));
     505           6 :   __ bind(&done);
     506           6 :   __ ret(0);
     507             : 
     508             :   CodeDesc desc;
     509           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     510             :   // Call the function from C++.
     511           6 :   uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
     512           6 :   uint64_t right = V8_2PART_UINT64_C(0x30000000, 00000000);
     513           6 :   uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
     514           6 :   CHECK_EQ(1u, result);
     515           6 : }
     516             : 
     517       23724 : TEST(AssemblerX64TestwOperations) {
     518             :   typedef uint16_t (*F)(uint16_t * x);
     519           6 :   CcTest::InitializeVM();
     520             :   // Allocate an executable page of memory.
     521             :   size_t actual_size;
     522             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     523           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     524           6 :   CHECK(buffer);
     525          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     526             : 
     527             :   // Set rax with the ZF flag of the testl instruction.
     528             :   Label done;
     529             :   __ movq(rax, Immediate(1));
     530           6 :   __ testw(Operand(arg1, 0), Immediate(0xf0f0));
     531           6 :   __ j(not_zero, &done, Label::kNear);
     532             :   __ movq(rax, Immediate(0));
     533           6 :   __ bind(&done);
     534           6 :   __ ret(0);
     535             : 
     536             :   CodeDesc desc;
     537           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     538             :   // Call the function from C++.
     539           6 :   uint16_t operand = 0x8000;
     540           6 :   uint16_t result = FUNCTION_CAST<F>(buffer)(&operand);
     541           6 :   CHECK_EQ(1u, result);
     542           6 : }
     543             : 
     544       23724 : TEST(AssemblerX64XorlOperations) {
     545           6 :   CcTest::InitializeVM();
     546             :   // Allocate an executable page of memory.
     547             :   size_t actual_size;
     548             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     549           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     550           6 :   CHECK(buffer);
     551          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     552             : 
     553          12 :   __ movq(rax, Operand(arg2, 0));
     554          12 :   __ xorl(Operand(arg1, 0), rax);
     555           6 :   __ ret(0);
     556             : 
     557             :   CodeDesc desc;
     558           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     559             :   // Call the function from C++.
     560           6 :   uint64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
     561           6 :   uint64_t right = V8_2PART_UINT64_C(0x30000000, 60000000);
     562           6 :   uint64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
     563           6 :   CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 40000000), left);
     564           6 :   USE(result);
     565           6 : }
     566             : 
     567             : 
     568       23724 : TEST(AssemblerX64MemoryOperands) {
     569           6 :   CcTest::InitializeVM();
     570             :   // Allocate an executable page of memory.
     571             :   size_t actual_size;
     572             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     573           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     574           6 :   CHECK(buffer);
     575          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     576             : 
     577             :   // Assemble a simple function that copies argument 2 and returns it.
     578           6 :   __ pushq(rbp);
     579             :   __ movq(rbp, rsp);
     580             : 
     581           6 :   __ pushq(arg2);  // Value at (rbp - 8)
     582           6 :   __ pushq(arg2);  // Value at (rbp - 16)
     583           6 :   __ pushq(arg1);  // Value at (rbp - 24)
     584             : 
     585             :   const int kStackElementSize = 8;
     586          12 :   __ movq(rax, Operand(rbp, -3 * kStackElementSize));
     587           6 :   __ popq(arg2);
     588           6 :   __ popq(arg2);
     589           6 :   __ popq(arg2);
     590           6 :   __ popq(rbp);
     591           6 :   __ nop();
     592           6 :   __ ret(0);
     593             : 
     594             :   CodeDesc desc;
     595           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     596             :   // Call the function from C++.
     597           6 :   int result =  FUNCTION_CAST<F2>(buffer)(3, 2);
     598           6 :   CHECK_EQ(3, result);
     599           6 : }
     600             : 
     601             : 
     602       23724 : TEST(AssemblerX64ControlFlow) {
     603           6 :   CcTest::InitializeVM();
     604             :   // Allocate an executable page of memory.
     605             :   size_t actual_size;
     606             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     607           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     608           6 :   CHECK(buffer);
     609          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     610             : 
     611             :   // Assemble a simple function that copies argument 1 and returns it.
     612           6 :   __ pushq(rbp);
     613             : 
     614             :   __ movq(rbp, rsp);
     615             :   __ movq(rax, arg1);
     616             :   Label target;
     617           6 :   __ jmp(&target);
     618             :   __ movq(rax, arg2);
     619           6 :   __ bind(&target);
     620           6 :   __ popq(rbp);
     621           6 :   __ ret(0);
     622             : 
     623             :   CodeDesc desc;
     624           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     625             :   // Call the function from C++.
     626           6 :   int result =  FUNCTION_CAST<F2>(buffer)(3, 2);
     627           6 :   CHECK_EQ(3, result);
     628           6 : }
     629             : 
     630             : 
     631       23724 : TEST(AssemblerX64LoopImmediates) {
     632           6 :   CcTest::InitializeVM();
     633             :   // Allocate an executable page of memory.
     634             :   size_t actual_size;
     635             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
     636           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
     637           6 :   CHECK(buffer);
     638          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
     639             :   // Assemble two loops using rax as counter, and verify the ending counts.
     640             :   Label Fail;
     641             :   __ movq(rax, Immediate(-3));
     642             :   Label Loop1_test;
     643             :   Label Loop1_body;
     644           6 :   __ jmp(&Loop1_test);
     645           6 :   __ bind(&Loop1_body);
     646           6 :   __ addq(rax, Immediate(7));
     647           6 :   __ bind(&Loop1_test);
     648           6 :   __ cmpq(rax, Immediate(20));
     649           6 :   __ j(less_equal, &Loop1_body);
     650             :   // Did the loop terminate with the expected value?
     651           6 :   __ cmpq(rax, Immediate(25));
     652           6 :   __ j(not_equal, &Fail);
     653             : 
     654             :   Label Loop2_test;
     655             :   Label Loop2_body;
     656             :   __ movq(rax, Immediate(0x11FEED00));
     657           6 :   __ jmp(&Loop2_test);
     658           6 :   __ bind(&Loop2_body);
     659           6 :   __ addq(rax, Immediate(-0x1100));
     660           6 :   __ bind(&Loop2_test);
     661           6 :   __ cmpq(rax, Immediate(0x11FE8000));
     662           6 :   __ j(greater, &Loop2_body);
     663             :   // Did the loop terminate with the expected value?
     664           6 :   __ cmpq(rax, Immediate(0x11FE7600));
     665           6 :   __ j(not_equal, &Fail);
     666             : 
     667             :   __ movq(rax, Immediate(1));
     668           6 :   __ ret(0);
     669           6 :   __ bind(&Fail);
     670             :   __ movq(rax, Immediate(0));
     671           6 :   __ ret(0);
     672             : 
     673             :   CodeDesc desc;
     674           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
     675             :   // Call the function from C++.
     676           6 :   int result =  FUNCTION_CAST<F0>(buffer)();
     677           6 :   CHECK_EQ(1, result);
     678           6 : }
     679             : 
     680             : 
     681       23724 : TEST(OperandRegisterDependency) {
     682           6 :   int offsets[4] = {0, 1, 0xfed, 0xbeefcad};
     683          30 :   for (int i = 0; i < 4; i++) {
     684          24 :     int offset = offsets[i];
     685          24 :     CHECK(Operand(rax, offset).AddressUsesRegister(rax));
     686          24 :     CHECK(!Operand(rax, offset).AddressUsesRegister(r8));
     687          24 :     CHECK(!Operand(rax, offset).AddressUsesRegister(rcx));
     688             : 
     689          24 :     CHECK(Operand(rax, rax, times_1, offset).AddressUsesRegister(rax));
     690          24 :     CHECK(!Operand(rax, rax, times_1, offset).AddressUsesRegister(r8));
     691          24 :     CHECK(!Operand(rax, rax, times_1, offset).AddressUsesRegister(rcx));
     692             : 
     693          24 :     CHECK(Operand(rax, rcx, times_1, offset).AddressUsesRegister(rax));
     694          24 :     CHECK(Operand(rax, rcx, times_1, offset).AddressUsesRegister(rcx));
     695          24 :     CHECK(!Operand(rax, rcx, times_1, offset).AddressUsesRegister(r8));
     696          24 :     CHECK(!Operand(rax, rcx, times_1, offset).AddressUsesRegister(r9));
     697          24 :     CHECK(!Operand(rax, rcx, times_1, offset).AddressUsesRegister(rdx));
     698          24 :     CHECK(!Operand(rax, rcx, times_1, offset).AddressUsesRegister(rsp));
     699             : 
     700          24 :     CHECK(Operand(rsp, offset).AddressUsesRegister(rsp));
     701          24 :     CHECK(!Operand(rsp, offset).AddressUsesRegister(rax));
     702          24 :     CHECK(!Operand(rsp, offset).AddressUsesRegister(r15));
     703             : 
     704          24 :     CHECK(Operand(rbp, offset).AddressUsesRegister(rbp));
     705          24 :     CHECK(!Operand(rbp, offset).AddressUsesRegister(rax));
     706          24 :     CHECK(!Operand(rbp, offset).AddressUsesRegister(r13));
     707             : 
     708          24 :     CHECK(Operand(rbp, rax, times_1, offset).AddressUsesRegister(rbp));
     709          24 :     CHECK(Operand(rbp, rax, times_1, offset).AddressUsesRegister(rax));
     710          24 :     CHECK(!Operand(rbp, rax, times_1, offset).AddressUsesRegister(rcx));
     711          24 :     CHECK(!Operand(rbp, rax, times_1, offset).AddressUsesRegister(r13));
     712          24 :     CHECK(!Operand(rbp, rax, times_1, offset).AddressUsesRegister(r8));
     713          24 :     CHECK(!Operand(rbp, rax, times_1, offset).AddressUsesRegister(rsp));
     714             : 
     715          24 :     CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rsp));
     716          24 :     CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rbp));
     717          24 :     CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rax));
     718          24 :     CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r15));
     719          24 :     CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r13));
     720             :   }
     721           6 : }
     722             : 
     723             : 
     724       23724 : TEST(AssemblerX64LabelChaining) {
     725             :   // Test chaining of label usages within instructions (issue 1644).
     726           6 :   CcTest::InitializeVM();
     727           6 :   v8::HandleScope scope(CcTest::isolate());
     728          12 :   Assembler assm(CcTest::i_isolate(), nullptr, 0);
     729             : 
     730             :   Label target;
     731           6 :   __ j(equal, &target);
     732           6 :   __ j(not_equal, &target);
     733           6 :   __ bind(&target);
     734          12 :   __ nop();
     735           6 : }
     736             : 
     737             : 
     738       23724 : TEST(AssemblerMultiByteNop) {
     739           6 :   CcTest::InitializeVM();
     740           6 :   v8::HandleScope scope(CcTest::isolate());
     741             :   byte buffer[1024];
     742             :   Isolate* isolate = CcTest::i_isolate();
     743          12 :   Assembler assm(isolate, buffer, sizeof(buffer));
     744           6 :   __ pushq(rbx);
     745           6 :   __ pushq(rcx);
     746           6 :   __ pushq(rdx);
     747           6 :   __ pushq(rdi);
     748           6 :   __ pushq(rsi);
     749             :   __ movq(rax, Immediate(1));
     750             :   __ movq(rbx, Immediate(2));
     751             :   __ movq(rcx, Immediate(3));
     752             :   __ movq(rdx, Immediate(4));
     753             :   __ movq(rdi, Immediate(5));
     754             :   __ movq(rsi, Immediate(6));
     755         102 :   for (int i = 0; i < 16; i++) {
     756          96 :     int before = assm.pc_offset();
     757          96 :     __ Nop(i);
     758         192 :     CHECK_EQ(assm.pc_offset() - before, i);
     759             :   }
     760             : 
     761             :   Label fail;
     762           6 :   __ cmpq(rax, Immediate(1));
     763           6 :   __ j(not_equal, &fail);
     764           6 :   __ cmpq(rbx, Immediate(2));
     765           6 :   __ j(not_equal, &fail);
     766           6 :   __ cmpq(rcx, Immediate(3));
     767           6 :   __ j(not_equal, &fail);
     768           6 :   __ cmpq(rdx, Immediate(4));
     769           6 :   __ j(not_equal, &fail);
     770           6 :   __ cmpq(rdi, Immediate(5));
     771           6 :   __ j(not_equal, &fail);
     772           6 :   __ cmpq(rsi, Immediate(6));
     773           6 :   __ j(not_equal, &fail);
     774             :   __ movq(rax, Immediate(42));
     775           6 :   __ popq(rsi);
     776           6 :   __ popq(rdi);
     777           6 :   __ popq(rdx);
     778           6 :   __ popq(rcx);
     779           6 :   __ popq(rbx);
     780           6 :   __ ret(0);
     781           6 :   __ bind(&fail);
     782             :   __ movq(rax, Immediate(13));
     783           6 :   __ popq(rsi);
     784           6 :   __ popq(rdi);
     785           6 :   __ popq(rdx);
     786           6 :   __ popq(rcx);
     787           6 :   __ popq(rbx);
     788           6 :   __ ret(0);
     789             : 
     790             :   CodeDesc desc;
     791           6 :   assm.GetCode(isolate, &desc);
     792             :   Handle<Code> code =
     793           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
     794             : 
     795           6 :   F0 f = FUNCTION_CAST<F0>(code->entry());
     796           6 :   int res = f();
     797          12 :   CHECK_EQ(42, res);
     798           6 : }
     799             : 
     800             : 
     801             : #ifdef __GNUC__
     802             : #define ELEMENT_COUNT 4u
     803             : 
     804          12 : void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
     805           6 :   v8::HandleScope scope(CcTest::isolate());
     806           6 :   v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
     807             :   byte buffer[1024];
     808             : 
     809           6 :   CHECK(args[0]->IsArray());
     810             :   v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]);
     811           6 :   CHECK_EQ(ELEMENT_COUNT, vec->Length());
     812             : 
     813             :   Isolate* isolate = CcTest::i_isolate();
     814          12 :   Assembler assm(isolate, buffer, sizeof(buffer));
     815             : 
     816             :   // Remove return address from the stack for fix stack frame alignment.
     817           6 :   __ popq(rcx);
     818             : 
     819             :   // Store input vector on the stack.
     820          18 :   for (unsigned i = 0; i < ELEMENT_COUNT; i++) {
     821             :     __ movl(rax, Immediate(vec->Get(context, i)
     822          12 :                                .ToLocalChecked()
     823             :                                ->Int32Value(context)
     824          24 :                                .FromJust()));
     825             :     __ shlq(rax, Immediate(0x20));
     826             :     __ orq(rax, Immediate(vec->Get(context, ++i)
     827          12 :                               .ToLocalChecked()
     828             :                               ->Int32Value(context)
     829          24 :                               .FromJust()));
     830          12 :     __ pushq(rax);
     831             :   }
     832             : 
     833             :   // Read vector into a xmm register.
     834           6 :   __ xorps(xmm0, xmm0);
     835           6 :   __ movdqa(xmm0, Operand(rsp, 0));
     836             :   // Create mask and store it in the return register.
     837           6 :   __ movmskps(rax, xmm0);
     838             : 
     839             :   // Remove unused data from the stack.
     840           6 :   __ addq(rsp, Immediate(ELEMENT_COUNT * sizeof(int32_t)));
     841             :   // Restore return address.
     842           6 :   __ pushq(rcx);
     843             : 
     844           6 :   __ ret(0);
     845             : 
     846             :   CodeDesc desc;
     847           6 :   assm.GetCode(isolate, &desc);
     848             :   Handle<Code> code =
     849           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
     850             : 
     851           6 :   F0 f = FUNCTION_CAST<F0>(code->entry());
     852           6 :   int res = f();
     853          12 :   args.GetReturnValue().Set(v8::Integer::New(CcTest::isolate(), res));
     854           6 : }
     855             : 
     856             : 
     857       23724 : TEST(StackAlignmentForSSE2) {
     858           6 :   CcTest::InitializeVM();
     859           6 :   CHECK_EQ(0, v8::base::OS::ActivationFrameAlignment() % 16);
     860             : 
     861           6 :   v8::Isolate* isolate = CcTest::isolate();
     862           6 :   v8::HandleScope handle_scope(isolate);
     863             :   v8::Local<v8::ObjectTemplate> global_template =
     864           6 :       v8::ObjectTemplate::New(isolate);
     865             :   global_template->Set(v8_str("do_sse2"),
     866          18 :                        v8::FunctionTemplate::New(isolate, DoSSE2));
     867             : 
     868          12 :   LocalContext env(nullptr, global_template);
     869             :   CompileRun(
     870             :       "function foo(vec) {"
     871             :       "  return do_sse2(vec);"
     872             :       "}");
     873             : 
     874           6 :   v8::Local<v8::Object> global_object = env->Global();
     875             :   v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
     876          24 :       global_object->Get(env.local(), v8_str("foo")).ToLocalChecked());
     877             : 
     878           6 :   int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 };
     879           6 :   v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT);
     880          30 :   for (unsigned i = 0; i < ELEMENT_COUNT; i++) {
     881          72 :     v8_vec->Set(env.local(), i, v8_num(vec[i])).FromJust();
     882             :   }
     883             : 
     884             :   v8::Local<v8::Value> args[] = { v8_vec };
     885             :   v8::Local<v8::Value> result =
     886          12 :       foo->Call(env.local(), global_object, 1, args).ToLocalChecked();
     887             : 
     888             :   // The mask should be 0b1000.
     889          18 :   CHECK_EQ(8, result->Int32Value(env.local()).FromJust());
     890           6 : }
     891             : 
     892             : #undef ELEMENT_COUNT
     893             : #endif  // __GNUC__
     894             : 
     895             : 
     896       23724 : TEST(AssemblerX64Extractps) {
     897           6 :   CcTest::InitializeVM();
     898           6 :   if (!CpuFeatures::IsSupported(SSE4_1)) return;
     899             : 
     900           6 :   v8::HandleScope scope(CcTest::isolate());
     901             :   byte buffer[256];
     902             :   Isolate* isolate = CcTest::i_isolate();
     903          12 :   Assembler assm(isolate, buffer, sizeof(buffer));
     904             :   { CpuFeatureScope fscope2(&assm, SSE4_1);
     905           6 :     __ extractps(rax, xmm0, 0x1);
     906           6 :     __ ret(0);
     907             :   }
     908             : 
     909             :   CodeDesc desc;
     910           6 :   assm.GetCode(isolate, &desc);
     911             :   Handle<Code> code =
     912           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
     913             : #ifdef OBJECT_PRINT
     914             :   OFStream os(stdout);
     915             :   code->Print(os);
     916             : #endif
     917             : 
     918           6 :   F3 f = FUNCTION_CAST<F3>(code->entry());
     919             :   uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321);
     920           6 :   CHECK_EQ(0x12345678u, f(uint64_to_double(value1)));
     921             :   uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678);
     922          12 :   CHECK_EQ(0x87654321u, f(uint64_to_double(value2)));
     923             : }
     924             : 
     925             : 
     926             : typedef int (*F6)(float x, float y);
     927       23724 : TEST(AssemblerX64SSE) {
     928           6 :   CcTest::InitializeVM();
     929             : 
     930           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
     931             :   HandleScope scope(isolate);
     932             :   v8::internal::byte buffer[256];
     933             :   MacroAssembler assm(isolate, buffer, sizeof(buffer),
     934           6 :                       v8::internal::CodeObjectRequired::kYes);
     935             :   {
     936           6 :     __ shufps(xmm0, xmm0, 0x0);  // brocast first argument
     937           6 :     __ shufps(xmm1, xmm1, 0x0);  // brocast second argument
     938           6 :     __ movaps(xmm2, xmm1);
     939           6 :     __ addps(xmm2, xmm0);
     940           6 :     __ mulps(xmm2, xmm1);
     941           6 :     __ subps(xmm2, xmm0);
     942           6 :     __ divps(xmm2, xmm1);
     943           6 :     __ cvttss2si(rax, xmm2);
     944           6 :     __ ret(0);
     945             :   }
     946             : 
     947             :   CodeDesc desc;
     948           6 :   assm.GetCode(isolate, &desc);
     949             :   Handle<Code> code =
     950           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
     951             : #ifdef OBJECT_PRINT
     952             :   OFStream os(stdout);
     953             :   code->Print(os);
     954             : #endif
     955             : 
     956           6 :   F6 f = FUNCTION_CAST<F6>(code->entry());
     957           6 :   CHECK_EQ(2, f(1.0, 2.0));
     958           6 : }
     959             : 
     960             : 
     961             : typedef int (*F7)(double x, double y, double z);
     962       23724 : TEST(AssemblerX64FMA_sd) {
     963           6 :   CcTest::InitializeVM();
     964           6 :   if (!CpuFeatures::IsSupported(FMA3)) return;
     965             : 
     966           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
     967             :   HandleScope scope(isolate);
     968             :   v8::internal::byte buffer[1024];
     969             :   MacroAssembler assm(isolate, buffer, sizeof(buffer),
     970           6 :                       v8::internal::CodeObjectRequired::kYes);
     971             :   {
     972             :     CpuFeatureScope fscope(&assm, FMA3);
     973             :     Label exit;
     974             :     // argument in xmm0, xmm1 and xmm2
     975             :     // xmm0 * xmm1 + xmm2
     976           6 :     __ movaps(xmm3, xmm0);
     977           6 :     __ mulsd(xmm3, xmm1);
     978           6 :     __ addsd(xmm3, xmm2);  // Expected result in xmm3
     979             : 
     980           6 :     __ subq(rsp, Immediate(kDoubleSize));  // For memory operand
     981             :     // vfmadd132sd
     982             :     __ movl(rax, Immediate(1));  // Test number
     983           6 :     __ movaps(xmm8, xmm0);
     984             :     __ vfmadd132sd(xmm8, xmm2, xmm1);
     985           6 :     __ ucomisd(xmm8, xmm3);
     986           6 :     __ j(not_equal, &exit);
     987             :     // vfmadd213sd
     988             :     __ incq(rax);
     989           6 :     __ movaps(xmm8, xmm1);
     990             :     __ vfmadd213sd(xmm8, xmm0, xmm2);
     991           6 :     __ ucomisd(xmm8, xmm3);
     992           6 :     __ j(not_equal, &exit);
     993             :     // vfmadd231sd
     994             :     __ incq(rax);
     995           6 :     __ movaps(xmm8, xmm2);
     996             :     __ vfmadd231sd(xmm8, xmm0, xmm1);
     997           6 :     __ ucomisd(xmm8, xmm3);
     998           6 :     __ j(not_equal, &exit);
     999             : 
    1000             :     // vfmadd132sd
    1001             :     __ incq(rax);
    1002           6 :     __ movaps(xmm8, xmm0);
    1003           6 :     __ movsd(Operand(rsp, 0), xmm1);
    1004          12 :     __ vfmadd132sd(xmm8, xmm2, Operand(rsp, 0));
    1005           6 :     __ ucomisd(xmm8, xmm3);
    1006           6 :     __ j(not_equal, &exit);
    1007             :     // vfmadd213sd
    1008             :     __ incq(rax);
    1009           6 :     __ movaps(xmm8, xmm1);
    1010           6 :     __ movsd(Operand(rsp, 0), xmm2);
    1011          12 :     __ vfmadd213sd(xmm8, xmm0, Operand(rsp, 0));
    1012           6 :     __ ucomisd(xmm8, xmm3);
    1013           6 :     __ j(not_equal, &exit);
    1014             :     // vfmadd231sd
    1015             :     __ incq(rax);
    1016           6 :     __ movaps(xmm8, xmm2);
    1017           6 :     __ movsd(Operand(rsp, 0), xmm1);
    1018          12 :     __ vfmadd231sd(xmm8, xmm0, Operand(rsp, 0));
    1019           6 :     __ ucomisd(xmm8, xmm3);
    1020           6 :     __ j(not_equal, &exit);
    1021             : 
    1022             :     // xmm0 * xmm1 - xmm2
    1023           6 :     __ movaps(xmm3, xmm0);
    1024           6 :     __ mulsd(xmm3, xmm1);
    1025           6 :     __ subsd(xmm3, xmm2);  // Expected result in xmm3
    1026             : 
    1027             :     // vfmsub132sd
    1028             :     __ incq(rax);
    1029           6 :     __ movaps(xmm8, xmm0);
    1030             :     __ vfmsub132sd(xmm8, xmm2, xmm1);
    1031           6 :     __ ucomisd(xmm8, xmm3);
    1032           6 :     __ j(not_equal, &exit);
    1033             :     // vfmadd213sd
    1034             :     __ incq(rax);
    1035           6 :     __ movaps(xmm8, xmm1);
    1036             :     __ vfmsub213sd(xmm8, xmm0, xmm2);
    1037           6 :     __ ucomisd(xmm8, xmm3);
    1038           6 :     __ j(not_equal, &exit);
    1039             :     // vfmsub231sd
    1040             :     __ incq(rax);
    1041           6 :     __ movaps(xmm8, xmm2);
    1042             :     __ vfmsub231sd(xmm8, xmm0, xmm1);
    1043           6 :     __ ucomisd(xmm8, xmm3);
    1044           6 :     __ j(not_equal, &exit);
    1045             : 
    1046             :     // vfmsub132sd
    1047             :     __ incq(rax);
    1048           6 :     __ movaps(xmm8, xmm0);
    1049           6 :     __ movsd(Operand(rsp, 0), xmm1);
    1050          12 :     __ vfmsub132sd(xmm8, xmm2, Operand(rsp, 0));
    1051           6 :     __ ucomisd(xmm8, xmm3);
    1052           6 :     __ j(not_equal, &exit);
    1053             :     // vfmsub213sd
    1054             :     __ incq(rax);
    1055           6 :     __ movaps(xmm8, xmm1);
    1056           6 :     __ movsd(Operand(rsp, 0), xmm2);
    1057          12 :     __ vfmsub213sd(xmm8, xmm0, Operand(rsp, 0));
    1058           6 :     __ ucomisd(xmm8, xmm3);
    1059           6 :     __ j(not_equal, &exit);
    1060             :     // vfmsub231sd
    1061             :     __ incq(rax);
    1062           6 :     __ movaps(xmm8, xmm2);
    1063           6 :     __ movsd(Operand(rsp, 0), xmm1);
    1064          12 :     __ vfmsub231sd(xmm8, xmm0, Operand(rsp, 0));
    1065           6 :     __ ucomisd(xmm8, xmm3);
    1066           6 :     __ j(not_equal, &exit);
    1067             : 
    1068             : 
    1069             :     // - xmm0 * xmm1 + xmm2
    1070           6 :     __ movaps(xmm3, xmm0);
    1071           6 :     __ mulsd(xmm3, xmm1);
    1072           6 :     __ Move(xmm4, (uint64_t)1 << 63);
    1073           6 :     __ xorpd(xmm3, xmm4);
    1074           6 :     __ addsd(xmm3, xmm2);  // Expected result in xmm3
    1075             : 
    1076             :     // vfnmadd132sd
    1077             :     __ incq(rax);
    1078           6 :     __ movaps(xmm8, xmm0);
    1079             :     __ vfnmadd132sd(xmm8, xmm2, xmm1);
    1080           6 :     __ ucomisd(xmm8, xmm3);
    1081           6 :     __ j(not_equal, &exit);
    1082             :     // vfmadd213sd
    1083             :     __ incq(rax);
    1084           6 :     __ movaps(xmm8, xmm1);
    1085             :     __ vfnmadd213sd(xmm8, xmm0, xmm2);
    1086           6 :     __ ucomisd(xmm8, xmm3);
    1087           6 :     __ j(not_equal, &exit);
    1088             :     // vfnmadd231sd
    1089             :     __ incq(rax);
    1090           6 :     __ movaps(xmm8, xmm2);
    1091             :     __ vfnmadd231sd(xmm8, xmm0, xmm1);
    1092           6 :     __ ucomisd(xmm8, xmm3);
    1093           6 :     __ j(not_equal, &exit);
    1094             : 
    1095             :     // vfnmadd132sd
    1096             :     __ incq(rax);
    1097           6 :     __ movaps(xmm8, xmm0);
    1098           6 :     __ movsd(Operand(rsp, 0), xmm1);
    1099          12 :     __ vfnmadd132sd(xmm8, xmm2, Operand(rsp, 0));
    1100           6 :     __ ucomisd(xmm8, xmm3);
    1101           6 :     __ j(not_equal, &exit);
    1102             :     // vfnmadd213sd
    1103             :     __ incq(rax);
    1104           6 :     __ movaps(xmm8, xmm1);
    1105           6 :     __ movsd(Operand(rsp, 0), xmm2);
    1106          12 :     __ vfnmadd213sd(xmm8, xmm0, Operand(rsp, 0));
    1107           6 :     __ ucomisd(xmm8, xmm3);
    1108           6 :     __ j(not_equal, &exit);
    1109             :     // vfnmadd231sd
    1110             :     __ incq(rax);
    1111           6 :     __ movaps(xmm8, xmm2);
    1112           6 :     __ movsd(Operand(rsp, 0), xmm1);
    1113          12 :     __ vfnmadd231sd(xmm8, xmm0, Operand(rsp, 0));
    1114           6 :     __ ucomisd(xmm8, xmm3);
    1115           6 :     __ j(not_equal, &exit);
    1116             : 
    1117             : 
    1118             :     // - xmm0 * xmm1 - xmm2
    1119           6 :     __ movaps(xmm3, xmm0);
    1120           6 :     __ mulsd(xmm3, xmm1);
    1121           6 :     __ Move(xmm4, (uint64_t)1 << 63);
    1122           6 :     __ xorpd(xmm3, xmm4);
    1123           6 :     __ subsd(xmm3, xmm2);  // Expected result in xmm3
    1124             : 
    1125             :     // vfnmsub132sd
    1126             :     __ incq(rax);
    1127           6 :     __ movaps(xmm8, xmm0);
    1128             :     __ vfnmsub132sd(xmm8, xmm2, xmm1);
    1129           6 :     __ ucomisd(xmm8, xmm3);
    1130           6 :     __ j(not_equal, &exit);
    1131             :     // vfmsub213sd
    1132             :     __ incq(rax);
    1133           6 :     __ movaps(xmm8, xmm1);
    1134             :     __ vfnmsub213sd(xmm8, xmm0, xmm2);
    1135           6 :     __ ucomisd(xmm8, xmm3);
    1136           6 :     __ j(not_equal, &exit);
    1137             :     // vfnmsub231sd
    1138             :     __ incq(rax);
    1139           6 :     __ movaps(xmm8, xmm2);
    1140             :     __ vfnmsub231sd(xmm8, xmm0, xmm1);
    1141           6 :     __ ucomisd(xmm8, xmm3);
    1142           6 :     __ j(not_equal, &exit);
    1143             : 
    1144             :     // vfnmsub132sd
    1145             :     __ incq(rax);
    1146           6 :     __ movaps(xmm8, xmm0);
    1147           6 :     __ movsd(Operand(rsp, 0), xmm1);
    1148          12 :     __ vfnmsub132sd(xmm8, xmm2, Operand(rsp, 0));
    1149           6 :     __ ucomisd(xmm8, xmm3);
    1150           6 :     __ j(not_equal, &exit);
    1151             :     // vfnmsub213sd
    1152             :     __ incq(rax);
    1153           6 :     __ movaps(xmm8, xmm1);
    1154           6 :     __ movsd(Operand(rsp, 0), xmm2);
    1155          12 :     __ vfnmsub213sd(xmm8, xmm0, Operand(rsp, 0));
    1156           6 :     __ ucomisd(xmm8, xmm3);
    1157           6 :     __ j(not_equal, &exit);
    1158             :     // vfnmsub231sd
    1159             :     __ incq(rax);
    1160           6 :     __ movaps(xmm8, xmm2);
    1161           6 :     __ movsd(Operand(rsp, 0), xmm1);
    1162          12 :     __ vfnmsub231sd(xmm8, xmm0, Operand(rsp, 0));
    1163           6 :     __ ucomisd(xmm8, xmm3);
    1164           6 :     __ j(not_equal, &exit);
    1165             : 
    1166             : 
    1167             :     __ xorl(rax, rax);
    1168           6 :     __ bind(&exit);
    1169           6 :     __ addq(rsp, Immediate(kDoubleSize));
    1170           6 :     __ ret(0);
    1171             :   }
    1172             : 
    1173             :   CodeDesc desc;
    1174           6 :   assm.GetCode(isolate, &desc);
    1175             :   Handle<Code> code =
    1176           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    1177             : #ifdef OBJECT_PRINT
    1178             :   OFStream os(stdout);
    1179             :   code->Print(os);
    1180             : #endif
    1181             : 
    1182           6 :   F7 f = FUNCTION_CAST<F7>(code->entry());
    1183           6 :   CHECK_EQ(0, f(0.000092662107262076, -2.460774966188315, -1.0958787393627414));
    1184             : }
    1185             : 
    1186             : 
    1187             : typedef int (*F8)(float x, float y, float z);
    1188       23724 : TEST(AssemblerX64FMA_ss) {
    1189           6 :   CcTest::InitializeVM();
    1190           6 :   if (!CpuFeatures::IsSupported(FMA3)) return;
    1191             : 
    1192           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    1193             :   HandleScope scope(isolate);
    1194             :   v8::internal::byte buffer[1024];
    1195             :   MacroAssembler assm(isolate, buffer, sizeof(buffer),
    1196           6 :                       v8::internal::CodeObjectRequired::kYes);
    1197             :   {
    1198             :     CpuFeatureScope fscope(&assm, FMA3);
    1199             :     Label exit;
    1200             :     // arguments in xmm0, xmm1 and xmm2
    1201             :     // xmm0 * xmm1 + xmm2
    1202           6 :     __ movaps(xmm3, xmm0);
    1203           6 :     __ mulss(xmm3, xmm1);
    1204           6 :     __ addss(xmm3, xmm2);  // Expected result in xmm3
    1205             : 
    1206           6 :     __ subq(rsp, Immediate(kDoubleSize));  // For memory operand
    1207             :     // vfmadd132ss
    1208             :     __ movl(rax, Immediate(1));  // Test number
    1209           6 :     __ movaps(xmm8, xmm0);
    1210             :     __ vfmadd132ss(xmm8, xmm2, xmm1);
    1211           6 :     __ ucomiss(xmm8, xmm3);
    1212           6 :     __ j(not_equal, &exit);
    1213             :     // vfmadd213ss
    1214             :     __ incq(rax);
    1215           6 :     __ movaps(xmm8, xmm1);
    1216             :     __ vfmadd213ss(xmm8, xmm0, xmm2);
    1217           6 :     __ ucomiss(xmm8, xmm3);
    1218           6 :     __ j(not_equal, &exit);
    1219             :     // vfmadd231ss
    1220             :     __ incq(rax);
    1221           6 :     __ movaps(xmm8, xmm2);
    1222             :     __ vfmadd231ss(xmm8, xmm0, xmm1);
    1223           6 :     __ ucomiss(xmm8, xmm3);
    1224           6 :     __ j(not_equal, &exit);
    1225             : 
    1226             :     // vfmadd132ss
    1227             :     __ incq(rax);
    1228           6 :     __ movaps(xmm8, xmm0);
    1229           6 :     __ movss(Operand(rsp, 0), xmm1);
    1230          12 :     __ vfmadd132ss(xmm8, xmm2, Operand(rsp, 0));
    1231           6 :     __ ucomiss(xmm8, xmm3);
    1232           6 :     __ j(not_equal, &exit);
    1233             :     // vfmadd213ss
    1234             :     __ incq(rax);
    1235           6 :     __ movaps(xmm8, xmm1);
    1236           6 :     __ movss(Operand(rsp, 0), xmm2);
    1237          12 :     __ vfmadd213ss(xmm8, xmm0, Operand(rsp, 0));
    1238           6 :     __ ucomiss(xmm8, xmm3);
    1239           6 :     __ j(not_equal, &exit);
    1240             :     // vfmadd231ss
    1241             :     __ incq(rax);
    1242           6 :     __ movaps(xmm8, xmm2);
    1243           6 :     __ movss(Operand(rsp, 0), xmm1);
    1244          12 :     __ vfmadd231ss(xmm8, xmm0, Operand(rsp, 0));
    1245           6 :     __ ucomiss(xmm8, xmm3);
    1246           6 :     __ j(not_equal, &exit);
    1247             : 
    1248             :     // xmm0 * xmm1 - xmm2
    1249           6 :     __ movaps(xmm3, xmm0);
    1250           6 :     __ mulss(xmm3, xmm1);
    1251           6 :     __ subss(xmm3, xmm2);  // Expected result in xmm3
    1252             : 
    1253             :     // vfmsub132ss
    1254             :     __ incq(rax);
    1255           6 :     __ movaps(xmm8, xmm0);
    1256             :     __ vfmsub132ss(xmm8, xmm2, xmm1);
    1257           6 :     __ ucomiss(xmm8, xmm3);
    1258           6 :     __ j(not_equal, &exit);
    1259             :     // vfmadd213ss
    1260             :     __ incq(rax);
    1261           6 :     __ movaps(xmm8, xmm1);
    1262             :     __ vfmsub213ss(xmm8, xmm0, xmm2);
    1263           6 :     __ ucomiss(xmm8, xmm3);
    1264           6 :     __ j(not_equal, &exit);
    1265             :     // vfmsub231ss
    1266             :     __ incq(rax);
    1267           6 :     __ movaps(xmm8, xmm2);
    1268             :     __ vfmsub231ss(xmm8, xmm0, xmm1);
    1269           6 :     __ ucomiss(xmm8, xmm3);
    1270           6 :     __ j(not_equal, &exit);
    1271             : 
    1272             :     // vfmsub132ss
    1273             :     __ incq(rax);
    1274           6 :     __ movaps(xmm8, xmm0);
    1275           6 :     __ movss(Operand(rsp, 0), xmm1);
    1276          12 :     __ vfmsub132ss(xmm8, xmm2, Operand(rsp, 0));
    1277           6 :     __ ucomiss(xmm8, xmm3);
    1278           6 :     __ j(not_equal, &exit);
    1279             :     // vfmsub213ss
    1280             :     __ incq(rax);
    1281           6 :     __ movaps(xmm8, xmm1);
    1282           6 :     __ movss(Operand(rsp, 0), xmm2);
    1283          12 :     __ vfmsub213ss(xmm8, xmm0, Operand(rsp, 0));
    1284           6 :     __ ucomiss(xmm8, xmm3);
    1285           6 :     __ j(not_equal, &exit);
    1286             :     // vfmsub231ss
    1287             :     __ incq(rax);
    1288           6 :     __ movaps(xmm8, xmm2);
    1289           6 :     __ movss(Operand(rsp, 0), xmm1);
    1290          12 :     __ vfmsub231ss(xmm8, xmm0, Operand(rsp, 0));
    1291           6 :     __ ucomiss(xmm8, xmm3);
    1292           6 :     __ j(not_equal, &exit);
    1293             : 
    1294             : 
    1295             :     // - xmm0 * xmm1 + xmm2
    1296           6 :     __ movaps(xmm3, xmm0);
    1297           6 :     __ mulss(xmm3, xmm1);
    1298           6 :     __ Move(xmm4, (uint32_t)1 << 31);
    1299           6 :     __ xorps(xmm3, xmm4);
    1300           6 :     __ addss(xmm3, xmm2);  // Expected result in xmm3
    1301             : 
    1302             :     // vfnmadd132ss
    1303             :     __ incq(rax);
    1304           6 :     __ movaps(xmm8, xmm0);
    1305             :     __ vfnmadd132ss(xmm8, xmm2, xmm1);
    1306           6 :     __ ucomiss(xmm8, xmm3);
    1307           6 :     __ j(not_equal, &exit);
    1308             :     // vfmadd213ss
    1309             :     __ incq(rax);
    1310           6 :     __ movaps(xmm8, xmm1);
    1311             :     __ vfnmadd213ss(xmm8, xmm0, xmm2);
    1312           6 :     __ ucomiss(xmm8, xmm3);
    1313           6 :     __ j(not_equal, &exit);
    1314             :     // vfnmadd231ss
    1315             :     __ incq(rax);
    1316           6 :     __ movaps(xmm8, xmm2);
    1317             :     __ vfnmadd231ss(xmm8, xmm0, xmm1);
    1318           6 :     __ ucomiss(xmm8, xmm3);
    1319           6 :     __ j(not_equal, &exit);
    1320             : 
    1321             :     // vfnmadd132ss
    1322             :     __ incq(rax);
    1323           6 :     __ movaps(xmm8, xmm0);
    1324           6 :     __ movss(Operand(rsp, 0), xmm1);
    1325          12 :     __ vfnmadd132ss(xmm8, xmm2, Operand(rsp, 0));
    1326           6 :     __ ucomiss(xmm8, xmm3);
    1327           6 :     __ j(not_equal, &exit);
    1328             :     // vfnmadd213ss
    1329             :     __ incq(rax);
    1330           6 :     __ movaps(xmm8, xmm1);
    1331           6 :     __ movss(Operand(rsp, 0), xmm2);
    1332          12 :     __ vfnmadd213ss(xmm8, xmm0, Operand(rsp, 0));
    1333           6 :     __ ucomiss(xmm8, xmm3);
    1334           6 :     __ j(not_equal, &exit);
    1335             :     // vfnmadd231ss
    1336             :     __ incq(rax);
    1337           6 :     __ movaps(xmm8, xmm2);
    1338           6 :     __ movss(Operand(rsp, 0), xmm1);
    1339          12 :     __ vfnmadd231ss(xmm8, xmm0, Operand(rsp, 0));
    1340           6 :     __ ucomiss(xmm8, xmm3);
    1341           6 :     __ j(not_equal, &exit);
    1342             : 
    1343             : 
    1344             :     // - xmm0 * xmm1 - xmm2
    1345           6 :     __ movaps(xmm3, xmm0);
    1346           6 :     __ mulss(xmm3, xmm1);
    1347           6 :     __ Move(xmm4, (uint32_t)1 << 31);
    1348           6 :     __ xorps(xmm3, xmm4);
    1349           6 :     __ subss(xmm3, xmm2);  // Expected result in xmm3
    1350             : 
    1351             :     // vfnmsub132ss
    1352             :     __ incq(rax);
    1353           6 :     __ movaps(xmm8, xmm0);
    1354             :     __ vfnmsub132ss(xmm8, xmm2, xmm1);
    1355           6 :     __ ucomiss(xmm8, xmm3);
    1356           6 :     __ j(not_equal, &exit);
    1357             :     // vfmsub213ss
    1358             :     __ incq(rax);
    1359           6 :     __ movaps(xmm8, xmm1);
    1360             :     __ vfnmsub213ss(xmm8, xmm0, xmm2);
    1361           6 :     __ ucomiss(xmm8, xmm3);
    1362           6 :     __ j(not_equal, &exit);
    1363             :     // vfnmsub231ss
    1364             :     __ incq(rax);
    1365           6 :     __ movaps(xmm8, xmm2);
    1366             :     __ vfnmsub231ss(xmm8, xmm0, xmm1);
    1367           6 :     __ ucomiss(xmm8, xmm3);
    1368           6 :     __ j(not_equal, &exit);
    1369             : 
    1370             :     // vfnmsub132ss
    1371             :     __ incq(rax);
    1372           6 :     __ movaps(xmm8, xmm0);
    1373           6 :     __ movss(Operand(rsp, 0), xmm1);
    1374          12 :     __ vfnmsub132ss(xmm8, xmm2, Operand(rsp, 0));
    1375           6 :     __ ucomiss(xmm8, xmm3);
    1376           6 :     __ j(not_equal, &exit);
    1377             :     // vfnmsub213ss
    1378             :     __ incq(rax);
    1379           6 :     __ movaps(xmm8, xmm1);
    1380           6 :     __ movss(Operand(rsp, 0), xmm2);
    1381          12 :     __ vfnmsub213ss(xmm8, xmm0, Operand(rsp, 0));
    1382           6 :     __ ucomiss(xmm8, xmm3);
    1383           6 :     __ j(not_equal, &exit);
    1384             :     // vfnmsub231ss
    1385             :     __ incq(rax);
    1386           6 :     __ movaps(xmm8, xmm2);
    1387           6 :     __ movss(Operand(rsp, 0), xmm1);
    1388          12 :     __ vfnmsub231ss(xmm8, xmm0, Operand(rsp, 0));
    1389           6 :     __ ucomiss(xmm8, xmm3);
    1390           6 :     __ j(not_equal, &exit);
    1391             : 
    1392             : 
    1393             :     __ xorl(rax, rax);
    1394           6 :     __ bind(&exit);
    1395           6 :     __ addq(rsp, Immediate(kDoubleSize));
    1396           6 :     __ ret(0);
    1397             :   }
    1398             : 
    1399             :   CodeDesc desc;
    1400           6 :   assm.GetCode(isolate, &desc);
    1401             :   Handle<Code> code =
    1402           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    1403             : #ifdef OBJECT_PRINT
    1404             :   OFStream os(stdout);
    1405             :   code->Print(os);
    1406             : #endif
    1407             : 
    1408           6 :   F8 f = FUNCTION_CAST<F8>(code->entry());
    1409           6 :   CHECK_EQ(0, f(9.26621069e-05f, -2.4607749f, -1.09587872f));
    1410             : }
    1411             : 
    1412             : 
    1413       23724 : TEST(AssemblerX64SSE_ss) {
    1414           6 :   CcTest::InitializeVM();
    1415             : 
    1416           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    1417             :   HandleScope scope(isolate);
    1418             :   v8::internal::byte buffer[1024];
    1419          12 :   Assembler assm(isolate, buffer, sizeof(buffer));
    1420             :   {
    1421             :     Label exit;
    1422             :     // arguments in xmm0, xmm1 and xmm2
    1423             :     __ movl(rax, Immediate(0));
    1424             : 
    1425           6 :     __ movaps(xmm3, xmm0);
    1426           6 :     __ maxss(xmm3, xmm1);
    1427           6 :     __ ucomiss(xmm3, xmm1);
    1428           6 :     __ j(parity_even, &exit);
    1429           6 :     __ j(not_equal, &exit);
    1430             :     __ movl(rax, Immediate(1));
    1431             : 
    1432           6 :     __ movaps(xmm3, xmm1);
    1433           6 :     __ minss(xmm3, xmm2);
    1434           6 :     __ ucomiss(xmm3, xmm1);
    1435           6 :     __ j(parity_even, &exit);
    1436           6 :     __ j(not_equal, &exit);
    1437             :     __ movl(rax, Immediate(2));
    1438             : 
    1439           6 :     __ movaps(xmm3, xmm2);
    1440           6 :     __ subss(xmm3, xmm1);
    1441           6 :     __ ucomiss(xmm3, xmm0);
    1442           6 :     __ j(parity_even, &exit);
    1443           6 :     __ j(not_equal, &exit);
    1444             :     __ movl(rax, Immediate(3));
    1445             : 
    1446           6 :     __ movaps(xmm3, xmm0);
    1447           6 :     __ addss(xmm3, xmm1);
    1448           6 :     __ ucomiss(xmm3, xmm2);
    1449           6 :     __ j(parity_even, &exit);
    1450           6 :     __ j(not_equal, &exit);
    1451             :     __ movl(rax, Immediate(4));
    1452             : 
    1453           6 :     __ movaps(xmm3, xmm0);
    1454           6 :     __ mulss(xmm3, xmm1);
    1455           6 :     __ ucomiss(xmm3, xmm1);
    1456           6 :     __ j(parity_even, &exit);
    1457           6 :     __ j(not_equal, &exit);
    1458             :     __ movl(rax, Immediate(5));
    1459             : 
    1460           6 :     __ movaps(xmm3, xmm0);
    1461           6 :     __ divss(xmm3, xmm1);
    1462           6 :     __ mulss(xmm3, xmm2);
    1463           6 :     __ mulss(xmm3, xmm1);
    1464           6 :     __ ucomiss(xmm3, xmm2);
    1465           6 :     __ j(parity_even, &exit);
    1466           6 :     __ j(not_equal, &exit);
    1467             :     __ movl(rax, Immediate(6));
    1468             : 
    1469             :     // result in eax
    1470           6 :     __ bind(&exit);
    1471           6 :     __ ret(0);
    1472             :   }
    1473             : 
    1474             :   CodeDesc desc;
    1475           6 :   assm.GetCode(isolate, &desc);
    1476             :   Handle<Code> code =
    1477           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    1478             : #ifdef OBJECT_PRINT
    1479             :   OFStream os(stdout);
    1480             :   code->Print(os);
    1481             : #endif
    1482             : 
    1483           6 :   F8 f = FUNCTION_CAST<F8>(code->entry());
    1484           6 :   int res = f(1.0f, 2.0f, 3.0f);
    1485           6 :   PrintF("f(1,2,3) = %d\n", res);
    1486           6 :   CHECK_EQ(6, res);
    1487           6 : }
    1488             : 
    1489             : 
    1490       23724 : TEST(AssemblerX64AVX_ss) {
    1491           6 :   CcTest::InitializeVM();
    1492           6 :   if (!CpuFeatures::IsSupported(AVX)) return;
    1493             : 
    1494           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    1495             :   HandleScope scope(isolate);
    1496             :   v8::internal::byte buffer[1024];
    1497          12 :   Assembler assm(isolate, buffer, sizeof(buffer));
    1498             :   {
    1499             :     CpuFeatureScope avx_scope(&assm, AVX);
    1500             :     Label exit;
    1501             :     // arguments in xmm0, xmm1 and xmm2
    1502           6 :     __ subq(rsp, Immediate(kDoubleSize * 2));  // For memory operand
    1503             : 
    1504             :     __ movl(rdx, Immediate(0xc2f64000));  // -123.125
    1505           6 :     __ vmovd(xmm4, rdx);
    1506          12 :     __ vmovss(Operand(rsp, 0), xmm4);
    1507          12 :     __ vmovss(xmm5, Operand(rsp, 0));
    1508             :     __ vmovaps(xmm6, xmm5);
    1509           6 :     __ vmovd(rcx, xmm6);
    1510           6 :     __ cmpl(rcx, rdx);
    1511             :     __ movl(rax, Immediate(9));
    1512           6 :     __ j(not_equal, &exit);
    1513             : 
    1514             :     __ movl(rax, Immediate(0));
    1515             :     __ vmaxss(xmm3, xmm0, xmm1);
    1516           6 :     __ vucomiss(xmm3, xmm1);
    1517           6 :     __ j(parity_even, &exit);
    1518           6 :     __ j(not_equal, &exit);
    1519             :     __ movl(rax, Immediate(1));
    1520             : 
    1521             :     __ vminss(xmm3, xmm1, xmm2);
    1522           6 :     __ vucomiss(xmm3, xmm1);
    1523           6 :     __ j(parity_even, &exit);
    1524           6 :     __ j(not_equal, &exit);
    1525             :     __ movl(rax, Immediate(2));
    1526             : 
    1527             :     __ vsubss(xmm3, xmm2, xmm1);
    1528           6 :     __ vucomiss(xmm3, xmm0);
    1529           6 :     __ j(parity_even, &exit);
    1530           6 :     __ j(not_equal, &exit);
    1531             :     __ movl(rax, Immediate(3));
    1532             : 
    1533             :     __ vaddss(xmm3, xmm0, xmm1);
    1534           6 :     __ vucomiss(xmm3, xmm2);
    1535           6 :     __ j(parity_even, &exit);
    1536           6 :     __ j(not_equal, &exit);
    1537             :     __ movl(rax, Immediate(4));
    1538             : 
    1539             :     __ vmulss(xmm3, xmm0, xmm1);
    1540           6 :     __ vucomiss(xmm3, xmm1);
    1541           6 :     __ j(parity_even, &exit);
    1542           6 :     __ j(not_equal, &exit);
    1543             :     __ movl(rax, Immediate(5));
    1544             : 
    1545             :     __ vdivss(xmm3, xmm0, xmm1);
    1546             :     __ vmulss(xmm3, xmm3, xmm2);
    1547             :     __ vmulss(xmm3, xmm3, xmm1);
    1548           6 :     __ vucomiss(xmm3, xmm2);
    1549           6 :     __ j(parity_even, &exit);
    1550           6 :     __ j(not_equal, &exit);
    1551             :     __ movl(rax, Immediate(6));
    1552             : 
    1553             :     // result in eax
    1554           6 :     __ bind(&exit);
    1555           6 :     __ addq(rsp, Immediate(kDoubleSize * 2));
    1556           6 :     __ ret(0);
    1557             :   }
    1558             : 
    1559             :   CodeDesc desc;
    1560           6 :   assm.GetCode(isolate, &desc);
    1561             :   Handle<Code> code =
    1562           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    1563             : #ifdef OBJECT_PRINT
    1564             :   OFStream os(stdout);
    1565             :   code->Print(os);
    1566             : #endif
    1567             : 
    1568           6 :   F8 f = FUNCTION_CAST<F8>(code->entry());
    1569           6 :   int res = f(1.0f, 2.0f, 3.0f);
    1570           6 :   PrintF("f(1,2,3) = %d\n", res);
    1571           6 :   CHECK_EQ(6, res);
    1572             : }
    1573             : 
    1574             : 
    1575       23724 : TEST(AssemblerX64AVX_sd) {
    1576           6 :   CcTest::InitializeVM();
    1577           6 :   if (!CpuFeatures::IsSupported(AVX)) return;
    1578             : 
    1579           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    1580             :   HandleScope scope(isolate);
    1581             :   v8::internal::byte buffer[1024];
    1582          12 :   Assembler assm(isolate, buffer, sizeof(buffer));
    1583             :   {
    1584             :     CpuFeatureScope avx_scope(&assm, AVX);
    1585             :     Label exit;
    1586             :     // arguments in xmm0, xmm1 and xmm2
    1587           6 :     __ subq(rsp, Immediate(kDoubleSize * 2));  // For memory operand
    1588             :     __ movl(rax, Immediate(0));
    1589             : 
    1590           6 :     __ vmaxsd(xmm4, xmm0, xmm1);
    1591           6 :     __ vmovsd(Operand(rsp, kDoubleSize), xmm4);
    1592           6 :     __ vmovsd(xmm5, Operand(rsp, kDoubleSize));
    1593           6 :     __ vmovsd(xmm6, xmm6, xmm5);
    1594             :     __ vmovapd(xmm3, xmm6);
    1595             : 
    1596             :     // Test vcvtss2sd & vcvtsd2ss
    1597             :     __ movl(rax, Immediate(9));
    1598           6 :     __ movq(rdx, V8_INT64_C(0x426D1A0000000000));
    1599          12 :     __ movq(Operand(rsp, 0), rdx);
    1600           6 :     __ vcvtsd2ss(xmm6, xmm6, Operand(rsp, 0));
    1601             :     __ vcvtss2sd(xmm7, xmm6, xmm6);
    1602           6 :     __ vcvtsd2ss(xmm8, xmm7, xmm7);
    1603          12 :     __ vmovss(Operand(rsp, 0), xmm8);
    1604          12 :     __ vcvtss2sd(xmm9, xmm8, Operand(rsp, 0));
    1605           6 :     __ vmovq(rcx, xmm9);
    1606           6 :     __ cmpq(rcx, rdx);
    1607           6 :     __ j(not_equal, &exit);
    1608             : 
    1609             :     // Test vcvttsd2si
    1610             :     __ movl(rax, Immediate(10));
    1611             :     __ movl(rdx, Immediate(123));
    1612             :     __ vcvtlsi2sd(xmm6, xmm6, rdx);
    1613           6 :     __ vcvttsd2si(rcx, xmm6);
    1614           6 :     __ cmpl(rcx, rdx);
    1615           6 :     __ j(not_equal, &exit);
    1616             :     __ xorl(rcx, rcx);
    1617           6 :     __ vmovsd(Operand(rsp, 0), xmm6);
    1618           6 :     __ vcvttsd2si(rcx, Operand(rsp, 0));
    1619           6 :     __ cmpl(rcx, rdx);
    1620           6 :     __ j(not_equal, &exit);
    1621             : 
    1622             :     // Test vcvttsd2siq
    1623             :     __ movl(rax, Immediate(11));
    1624           6 :     __ movq(rdx, V8_INT64_C(0x426D1A94A2000000));  // 1.0e12
    1625           6 :     __ vmovq(xmm6, rdx);
    1626           6 :     __ vcvttsd2siq(rcx, xmm6);
    1627           6 :     __ movq(rdx, V8_INT64_C(1000000000000));
    1628           6 :     __ cmpq(rcx, rdx);
    1629           6 :     __ j(not_equal, &exit);
    1630             :     __ xorq(rcx, rcx);
    1631           6 :     __ vmovsd(Operand(rsp, 0), xmm6);
    1632           6 :     __ vcvttsd2siq(rcx, Operand(rsp, 0));
    1633           6 :     __ cmpq(rcx, rdx);
    1634           6 :     __ j(not_equal, &exit);
    1635             : 
    1636             :     // Test vmovmskpd
    1637             :     __ movl(rax, Immediate(12));
    1638           6 :     __ movq(rdx, V8_INT64_C(0x426D1A94A2000000));  // 1.0e12
    1639           6 :     __ vmovq(xmm6, rdx);
    1640           6 :     __ movq(rdx, V8_INT64_C(0xC26D1A94A2000000));  // -1.0e12
    1641           6 :     __ vmovq(xmm7, rdx);
    1642           6 :     __ shufps(xmm6, xmm7, 0x44);
    1643             :     __ vmovmskpd(rdx, xmm6);
    1644           6 :     __ cmpl(rdx, Immediate(2));
    1645           6 :     __ j(not_equal, &exit);
    1646             : 
    1647             :     // Test vpcmpeqd
    1648           6 :     __ movq(rdx, V8_UINT64_C(0x0123456789abcdef));
    1649           6 :     __ movq(rcx, V8_UINT64_C(0x0123456788888888));
    1650           6 :     __ vmovq(xmm6, rdx);
    1651           6 :     __ vmovq(xmm7, rcx);
    1652             :     __ vpcmpeqd(xmm8, xmm6, xmm7);
    1653           6 :     __ vmovq(rdx, xmm8);
    1654           6 :     __ movq(rcx, V8_UINT64_C(0xffffffff00000000));
    1655           6 :     __ cmpq(rcx, rdx);
    1656             :     __ movl(rax, Immediate(13));
    1657           6 :     __ j(not_equal, &exit);
    1658             : 
    1659             :     // Test vpsllq, vpsrlq
    1660             :     __ movl(rax, Immediate(13));
    1661           6 :     __ movq(rdx, V8_UINT64_C(0x0123456789abcdef));
    1662           6 :     __ vmovq(xmm6, rdx);
    1663             :     __ vpsrlq(xmm7, xmm6, 4);
    1664           6 :     __ vmovq(rdx, xmm7);
    1665           6 :     __ movq(rcx, V8_UINT64_C(0x00123456789abcde));
    1666           6 :     __ cmpq(rdx, rcx);
    1667           6 :     __ j(not_equal, &exit);
    1668             :     __ vpsllq(xmm7, xmm6, 12);
    1669           6 :     __ vmovq(rdx, xmm7);
    1670           6 :     __ movq(rcx, V8_UINT64_C(0x3456789abcdef000));
    1671           6 :     __ cmpq(rdx, rcx);
    1672           6 :     __ j(not_equal, &exit);
    1673             : 
    1674             :     // Test vandpd, vorpd, vxorpd
    1675             :     __ movl(rax, Immediate(14));
    1676             :     __ movl(rdx, Immediate(0x00ff00ff));
    1677             :     __ movl(rcx, Immediate(0x0f0f0f0f));
    1678           6 :     __ vmovd(xmm4, rdx);
    1679           6 :     __ vmovd(xmm5, rcx);
    1680             :     __ vandpd(xmm6, xmm4, xmm5);
    1681           6 :     __ vmovd(rdx, xmm6);
    1682           6 :     __ cmpl(rdx, Immediate(0x000f000f));
    1683           6 :     __ j(not_equal, &exit);
    1684             :     __ vorpd(xmm6, xmm4, xmm5);
    1685           6 :     __ vmovd(rdx, xmm6);
    1686           6 :     __ cmpl(rdx, Immediate(0x0fff0fff));
    1687           6 :     __ j(not_equal, &exit);
    1688             :     __ vxorpd(xmm6, xmm4, xmm5);
    1689           6 :     __ vmovd(rdx, xmm6);
    1690           6 :     __ cmpl(rdx, Immediate(0x0ff00ff0));
    1691           6 :     __ j(not_equal, &exit);
    1692             : 
    1693             :     // Test vsqrtsd
    1694             :     __ movl(rax, Immediate(15));
    1695           6 :     __ movq(rdx, V8_UINT64_C(0x4004000000000000));  // 2.5
    1696           6 :     __ vmovq(xmm4, rdx);
    1697           6 :     __ vmulsd(xmm5, xmm4, xmm4);
    1698           6 :     __ vmovsd(Operand(rsp, 0), xmm5);
    1699           6 :     __ vsqrtsd(xmm6, xmm5, xmm5);
    1700           6 :     __ vmovq(rcx, xmm6);
    1701           6 :     __ cmpq(rcx, rdx);
    1702           6 :     __ j(not_equal, &exit);
    1703           6 :     __ vsqrtsd(xmm7, xmm7, Operand(rsp, 0));
    1704           6 :     __ vmovq(rcx, xmm7);
    1705           6 :     __ cmpq(rcx, rdx);
    1706           6 :     __ j(not_equal, &exit);
    1707             : 
    1708             :     // Test vroundsd
    1709             :     __ movl(rax, Immediate(16));
    1710           6 :     __ movq(rdx, V8_UINT64_C(0x4002000000000000));  // 2.25
    1711           6 :     __ vmovq(xmm4, rdx);
    1712           6 :     __ vroundsd(xmm5, xmm4, xmm4, kRoundUp);
    1713           6 :     __ movq(rcx, V8_UINT64_C(0x4008000000000000));  // 3.0
    1714           6 :     __ vmovq(xmm6, rcx);
    1715             :     __ vucomisd(xmm5, xmm6);
    1716           6 :     __ j(not_equal, &exit);
    1717             : 
    1718             :     // Test vcvtlsi2sd
    1719             :     __ movl(rax, Immediate(17));
    1720             :     __ movl(rdx, Immediate(6));
    1721           6 :     __ movq(rcx, V8_UINT64_C(0x4018000000000000));  // 6.0
    1722           6 :     __ vmovq(xmm5, rcx);
    1723             :     __ vcvtlsi2sd(xmm6, xmm6, rdx);
    1724             :     __ vucomisd(xmm5, xmm6);
    1725           6 :     __ j(not_equal, &exit);
    1726          12 :     __ movl(Operand(rsp, 0), rdx);
    1727          12 :     __ vcvtlsi2sd(xmm7, xmm7, Operand(rsp, 0));
    1728             :     __ vucomisd(xmm5, xmm6);
    1729           6 :     __ j(not_equal, &exit);
    1730             : 
    1731             :     // Test vcvtqsi2sd
    1732             :     __ movl(rax, Immediate(18));
    1733           6 :     __ movq(rdx, V8_UINT64_C(0x2000000000000000));  // 2 << 0x3c
    1734           6 :     __ movq(rcx, V8_UINT64_C(0x43c0000000000000));
    1735           6 :     __ vmovq(xmm5, rcx);
    1736             :     __ vcvtqsi2sd(xmm6, xmm6, rdx);
    1737             :     __ vucomisd(xmm5, xmm6);
    1738           6 :     __ j(not_equal, &exit);
    1739             : 
    1740             :     // Test vcvtsd2si
    1741             :     __ movl(rax, Immediate(19));
    1742           6 :     __ movq(rdx, V8_UINT64_C(0x4018000000000000));  // 6.0
    1743           6 :     __ vmovq(xmm5, rdx);
    1744           6 :     __ vcvtsd2si(rcx, xmm5);
    1745           6 :     __ cmpl(rcx, Immediate(6));
    1746           6 :     __ j(not_equal, &exit);
    1747             : 
    1748           6 :     __ movq(rdx, V8_INT64_C(0x3ff0000000000000));  // 1.0
    1749           6 :     __ vmovq(xmm7, rdx);
    1750           6 :     __ vmulsd(xmm1, xmm1, xmm7);
    1751          12 :     __ movq(Operand(rsp, 0), rdx);
    1752           6 :     __ vmovq(xmm6, Operand(rsp, 0));
    1753           6 :     __ vmulsd(xmm1, xmm1, xmm6);
    1754             : 
    1755             :     __ vucomisd(xmm3, xmm1);
    1756           6 :     __ j(parity_even, &exit);
    1757           6 :     __ j(not_equal, &exit);
    1758             :     __ movl(rax, Immediate(1));
    1759             : 
    1760           6 :     __ vminsd(xmm3, xmm1, xmm2);
    1761             :     __ vucomisd(xmm3, xmm1);
    1762           6 :     __ j(parity_even, &exit);
    1763           6 :     __ j(not_equal, &exit);
    1764             :     __ movl(rax, Immediate(2));
    1765             : 
    1766           6 :     __ vsubsd(xmm3, xmm2, xmm1);
    1767             :     __ vucomisd(xmm3, xmm0);
    1768           6 :     __ j(parity_even, &exit);
    1769           6 :     __ j(not_equal, &exit);
    1770             :     __ movl(rax, Immediate(3));
    1771             : 
    1772           6 :     __ vaddsd(xmm3, xmm0, xmm1);
    1773             :     __ vucomisd(xmm3, xmm2);
    1774           6 :     __ j(parity_even, &exit);
    1775           6 :     __ j(not_equal, &exit);
    1776             :     __ movl(rax, Immediate(4));
    1777             : 
    1778           6 :     __ vmulsd(xmm3, xmm0, xmm1);
    1779             :     __ vucomisd(xmm3, xmm1);
    1780           6 :     __ j(parity_even, &exit);
    1781           6 :     __ j(not_equal, &exit);
    1782             :     __ movl(rax, Immediate(5));
    1783             : 
    1784           6 :     __ vdivsd(xmm3, xmm0, xmm1);
    1785           6 :     __ vmulsd(xmm3, xmm3, xmm2);
    1786           6 :     __ vmulsd(xmm3, xmm3, xmm1);
    1787             :     __ vucomisd(xmm3, xmm2);
    1788           6 :     __ j(parity_even, &exit);
    1789           6 :     __ j(not_equal, &exit);
    1790             :     __ movl(rax, Immediate(6));
    1791             : 
    1792             :     // result in eax
    1793           6 :     __ bind(&exit);
    1794           6 :     __ addq(rsp, Immediate(kDoubleSize * 2));
    1795           6 :     __ ret(0);
    1796             :   }
    1797             : 
    1798             :   CodeDesc desc;
    1799           6 :   assm.GetCode(isolate, &desc);
    1800             :   Handle<Code> code =
    1801           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    1802             : #ifdef OBJECT_PRINT
    1803             :   OFStream os(stdout);
    1804             :   code->Print(os);
    1805             : #endif
    1806             : 
    1807           6 :   F7 f = FUNCTION_CAST<F7>(code->entry());
    1808           6 :   int res = f(1.0, 2.0, 3.0);
    1809           6 :   PrintF("f(1,2,3) = %d\n", res);
    1810           6 :   CHECK_EQ(6, res);
    1811             : }
    1812             : 
    1813             : 
    1814       23724 : TEST(AssemblerX64BMI1) {
    1815           6 :   CcTest::InitializeVM();
    1816           6 :   if (!CpuFeatures::IsSupported(BMI1)) return;
    1817             : 
    1818           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    1819             :   HandleScope scope(isolate);
    1820             :   v8::internal::byte buffer[1024];
    1821             :   MacroAssembler assm(isolate, buffer, sizeof(buffer),
    1822           6 :                       v8::internal::CodeObjectRequired::kYes);
    1823             :   {
    1824             :     CpuFeatureScope fscope(&assm, BMI1);
    1825             :     Label exit;
    1826             : 
    1827           6 :     __ movq(rcx, V8_UINT64_C(0x1122334455667788));  // source operand
    1828           6 :     __ pushq(rcx);                                  // For memory operand
    1829             : 
    1830             :     // andn
    1831           6 :     __ movq(rdx, V8_UINT64_C(0x1000000020000000));
    1832             : 
    1833             :     __ movl(rax, Immediate(1));  // Test number
    1834             :     __ andnq(r8, rdx, rcx);
    1835           6 :     __ movq(r9, V8_UINT64_C(0x0122334455667788));  // expected result
    1836           6 :     __ cmpq(r8, r9);
    1837           6 :     __ j(not_equal, &exit);
    1838             : 
    1839             :     __ incq(rax);
    1840          12 :     __ andnq(r8, rdx, Operand(rsp, 0));
    1841           6 :     __ movq(r9, V8_UINT64_C(0x0122334455667788));  // expected result
    1842           6 :     __ cmpq(r8, r9);
    1843           6 :     __ j(not_equal, &exit);
    1844             : 
    1845             :     __ incq(rax);
    1846             :     __ andnl(r8, rdx, rcx);
    1847           6 :     __ movq(r9, V8_UINT64_C(0x0000000055667788));  // expected result
    1848           6 :     __ cmpq(r8, r9);
    1849           6 :     __ j(not_equal, &exit);
    1850             : 
    1851             :     __ incq(rax);
    1852          12 :     __ andnl(r8, rdx, Operand(rsp, 0));
    1853           6 :     __ movq(r9, V8_UINT64_C(0x0000000055667788));  // expected result
    1854           6 :     __ cmpq(r8, r9);
    1855           6 :     __ j(not_equal, &exit);
    1856             : 
    1857             :     // bextr
    1858           6 :     __ movq(rdx, V8_UINT64_C(0x0000000000002808));
    1859             : 
    1860             :     __ incq(rax);
    1861             :     __ bextrq(r8, rcx, rdx);
    1862           6 :     __ movq(r9, V8_UINT64_C(0x0000003344556677));  // expected result
    1863           6 :     __ cmpq(r8, r9);
    1864           6 :     __ j(not_equal, &exit);
    1865             : 
    1866             :     __ incq(rax);
    1867          12 :     __ bextrq(r8, Operand(rsp, 0), rdx);
    1868           6 :     __ movq(r9, V8_UINT64_C(0x0000003344556677));  // expected result
    1869           6 :     __ cmpq(r8, r9);
    1870           6 :     __ j(not_equal, &exit);
    1871             : 
    1872             :     __ incq(rax);
    1873             :     __ bextrl(r8, rcx, rdx);
    1874           6 :     __ movq(r9, V8_UINT64_C(0x0000000000556677));  // expected result
    1875           6 :     __ cmpq(r8, r9);
    1876           6 :     __ j(not_equal, &exit);
    1877             : 
    1878             :     __ incq(rax);
    1879          12 :     __ bextrl(r8, Operand(rsp, 0), rdx);
    1880           6 :     __ movq(r9, V8_UINT64_C(0x0000000000556677));  // expected result
    1881           6 :     __ cmpq(r8, r9);
    1882           6 :     __ j(not_equal, &exit);
    1883             : 
    1884             :     // blsi
    1885             :     __ incq(rax);
    1886             :     __ blsiq(r8, rcx);
    1887           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000008));  // expected result
    1888           6 :     __ cmpq(r8, r9);
    1889           6 :     __ j(not_equal, &exit);
    1890             : 
    1891             :     __ incq(rax);
    1892          12 :     __ blsiq(r8, Operand(rsp, 0));
    1893           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000008));  // expected result
    1894           6 :     __ cmpq(r8, r9);
    1895           6 :     __ j(not_equal, &exit);
    1896             : 
    1897             :     __ incq(rax);
    1898             :     __ blsil(r8, rcx);
    1899           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000008));  // expected result
    1900           6 :     __ cmpq(r8, r9);
    1901           6 :     __ j(not_equal, &exit);
    1902             : 
    1903             :     __ incq(rax);
    1904          12 :     __ blsil(r8, Operand(rsp, 0));
    1905           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000008));  // expected result
    1906           6 :     __ cmpq(r8, r9);
    1907           6 :     __ j(not_equal, &exit);
    1908             : 
    1909             :     // blsmsk
    1910             :     __ incq(rax);
    1911             :     __ blsmskq(r8, rcx);
    1912           6 :     __ movq(r9, V8_UINT64_C(0x000000000000000f));  // expected result
    1913           6 :     __ cmpq(r8, r9);
    1914           6 :     __ j(not_equal, &exit);
    1915             : 
    1916             :     __ incq(rax);
    1917          12 :     __ blsmskq(r8, Operand(rsp, 0));
    1918           6 :     __ movq(r9, V8_UINT64_C(0x000000000000000f));  // expected result
    1919           6 :     __ cmpq(r8, r9);
    1920           6 :     __ j(not_equal, &exit);
    1921             : 
    1922             :     __ incq(rax);
    1923             :     __ blsmskl(r8, rcx);
    1924           6 :     __ movq(r9, V8_UINT64_C(0x000000000000000f));  // expected result
    1925           6 :     __ cmpq(r8, r9);
    1926           6 :     __ j(not_equal, &exit);
    1927             : 
    1928             :     __ incq(rax);
    1929          12 :     __ blsmskl(r8, Operand(rsp, 0));
    1930           6 :     __ movq(r9, V8_UINT64_C(0x000000000000000f));  // expected result
    1931           6 :     __ cmpq(r8, r9);
    1932           6 :     __ j(not_equal, &exit);
    1933             : 
    1934             :     // blsr
    1935             :     __ incq(rax);
    1936             :     __ blsrq(r8, rcx);
    1937           6 :     __ movq(r9, V8_UINT64_C(0x1122334455667780));  // expected result
    1938           6 :     __ cmpq(r8, r9);
    1939           6 :     __ j(not_equal, &exit);
    1940             : 
    1941             :     __ incq(rax);
    1942          12 :     __ blsrq(r8, Operand(rsp, 0));
    1943           6 :     __ movq(r9, V8_UINT64_C(0x1122334455667780));  // expected result
    1944           6 :     __ cmpq(r8, r9);
    1945           6 :     __ j(not_equal, &exit);
    1946             : 
    1947             :     __ incq(rax);
    1948             :     __ blsrl(r8, rcx);
    1949           6 :     __ movq(r9, V8_UINT64_C(0x0000000055667780));  // expected result
    1950           6 :     __ cmpq(r8, r9);
    1951           6 :     __ j(not_equal, &exit);
    1952             : 
    1953             :     __ incq(rax);
    1954          12 :     __ blsrl(r8, Operand(rsp, 0));
    1955           6 :     __ movq(r9, V8_UINT64_C(0x0000000055667780));  // expected result
    1956           6 :     __ cmpq(r8, r9);
    1957           6 :     __ j(not_equal, &exit);
    1958             : 
    1959             :     // tzcnt
    1960             :     __ incq(rax);
    1961           6 :     __ tzcntq(r8, rcx);
    1962           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000003));  // expected result
    1963           6 :     __ cmpq(r8, r9);
    1964           6 :     __ j(not_equal, &exit);
    1965             : 
    1966             :     __ incq(rax);
    1967           6 :     __ tzcntq(r8, Operand(rsp, 0));
    1968           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000003));  // expected result
    1969           6 :     __ cmpq(r8, r9);
    1970           6 :     __ j(not_equal, &exit);
    1971             : 
    1972             :     __ incq(rax);
    1973           6 :     __ tzcntl(r8, rcx);
    1974           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000003));  // expected result
    1975           6 :     __ cmpq(r8, r9);
    1976           6 :     __ j(not_equal, &exit);
    1977             : 
    1978             :     __ incq(rax);
    1979           6 :     __ tzcntl(r8, Operand(rsp, 0));
    1980           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000003));  // expected result
    1981           6 :     __ cmpq(r8, r9);
    1982           6 :     __ j(not_equal, &exit);
    1983             : 
    1984             :     __ xorl(rax, rax);
    1985           6 :     __ bind(&exit);
    1986           6 :     __ popq(rcx);
    1987           6 :     __ ret(0);
    1988             :   }
    1989             : 
    1990             :   CodeDesc desc;
    1991           6 :   assm.GetCode(isolate, &desc);
    1992             :   Handle<Code> code =
    1993           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    1994             : #ifdef OBJECT_PRINT
    1995             :   OFStream os(stdout);
    1996             :   code->Print(os);
    1997             : #endif
    1998             : 
    1999           6 :   F0 f = FUNCTION_CAST<F0>(code->entry());
    2000           6 :   CHECK_EQ(0, f());
    2001             : }
    2002             : 
    2003             : 
    2004       23724 : TEST(AssemblerX64LZCNT) {
    2005           6 :   CcTest::InitializeVM();
    2006           6 :   if (!CpuFeatures::IsSupported(LZCNT)) return;
    2007             : 
    2008           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    2009             :   HandleScope scope(isolate);
    2010             :   v8::internal::byte buffer[256];
    2011             :   MacroAssembler assm(isolate, buffer, sizeof(buffer),
    2012           6 :                       v8::internal::CodeObjectRequired::kYes);
    2013             :   {
    2014             :     CpuFeatureScope fscope(&assm, LZCNT);
    2015             :     Label exit;
    2016             : 
    2017           6 :     __ movq(rcx, V8_UINT64_C(0x1122334455667788));  // source operand
    2018           6 :     __ pushq(rcx);                                  // For memory operand
    2019             : 
    2020             :     __ movl(rax, Immediate(1));  // Test number
    2021           6 :     __ lzcntq(r8, rcx);
    2022           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000003));  // expected result
    2023           6 :     __ cmpq(r8, r9);
    2024           6 :     __ j(not_equal, &exit);
    2025             : 
    2026             :     __ incq(rax);
    2027           6 :     __ lzcntq(r8, Operand(rsp, 0));
    2028           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000003));  // expected result
    2029           6 :     __ cmpq(r8, r9);
    2030           6 :     __ j(not_equal, &exit);
    2031             : 
    2032             :     __ incq(rax);
    2033           6 :     __ lzcntl(r8, rcx);
    2034           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000001));  // expected result
    2035           6 :     __ cmpq(r8, r9);
    2036           6 :     __ j(not_equal, &exit);
    2037             : 
    2038             :     __ incq(rax);
    2039           6 :     __ lzcntl(r8, Operand(rsp, 0));
    2040           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000001));  // expected result
    2041           6 :     __ cmpq(r8, r9);
    2042           6 :     __ j(not_equal, &exit);
    2043             : 
    2044             :     __ xorl(rax, rax);
    2045           6 :     __ bind(&exit);
    2046           6 :     __ popq(rcx);
    2047           6 :     __ ret(0);
    2048             :   }
    2049             : 
    2050             :   CodeDesc desc;
    2051           6 :   assm.GetCode(isolate, &desc);
    2052             :   Handle<Code> code =
    2053           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    2054             : #ifdef OBJECT_PRINT
    2055             :   OFStream os(stdout);
    2056             :   code->Print(os);
    2057             : #endif
    2058             : 
    2059           6 :   F0 f = FUNCTION_CAST<F0>(code->entry());
    2060           6 :   CHECK_EQ(0, f());
    2061             : }
    2062             : 
    2063             : 
    2064       23724 : TEST(AssemblerX64POPCNT) {
    2065           6 :   CcTest::InitializeVM();
    2066           6 :   if (!CpuFeatures::IsSupported(POPCNT)) return;
    2067             : 
    2068           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    2069             :   HandleScope scope(isolate);
    2070             :   v8::internal::byte buffer[256];
    2071             :   MacroAssembler assm(isolate, buffer, sizeof(buffer),
    2072           6 :                       v8::internal::CodeObjectRequired::kYes);
    2073             :   {
    2074             :     CpuFeatureScope fscope(&assm, POPCNT);
    2075             :     Label exit;
    2076             : 
    2077           6 :     __ movq(rcx, V8_UINT64_C(0x1111111111111100));  // source operand
    2078           6 :     __ pushq(rcx);                                  // For memory operand
    2079             : 
    2080             :     __ movl(rax, Immediate(1));  // Test number
    2081           6 :     __ popcntq(r8, rcx);
    2082           6 :     __ movq(r9, V8_UINT64_C(0x000000000000000e));  // expected result
    2083           6 :     __ cmpq(r8, r9);
    2084           6 :     __ j(not_equal, &exit);
    2085             : 
    2086             :     __ incq(rax);
    2087           6 :     __ popcntq(r8, Operand(rsp, 0));
    2088           6 :     __ movq(r9, V8_UINT64_C(0x000000000000000e));  // expected result
    2089           6 :     __ cmpq(r8, r9);
    2090           6 :     __ j(not_equal, &exit);
    2091             : 
    2092             :     __ incq(rax);
    2093           6 :     __ popcntl(r8, rcx);
    2094           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000006));  // expected result
    2095           6 :     __ cmpq(r8, r9);
    2096           6 :     __ j(not_equal, &exit);
    2097             : 
    2098             :     __ incq(rax);
    2099           6 :     __ popcntl(r8, Operand(rsp, 0));
    2100           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000006));  // expected result
    2101           6 :     __ cmpq(r8, r9);
    2102           6 :     __ j(not_equal, &exit);
    2103             : 
    2104             :     __ xorl(rax, rax);
    2105           6 :     __ bind(&exit);
    2106           6 :     __ popq(rcx);
    2107           6 :     __ ret(0);
    2108             :   }
    2109             : 
    2110             :   CodeDesc desc;
    2111           6 :   assm.GetCode(isolate, &desc);
    2112             :   Handle<Code> code =
    2113           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    2114             : #ifdef OBJECT_PRINT
    2115             :   OFStream os(stdout);
    2116             :   code->Print(os);
    2117             : #endif
    2118             : 
    2119           6 :   F0 f = FUNCTION_CAST<F0>(code->entry());
    2120           6 :   CHECK_EQ(0, f());
    2121             : }
    2122             : 
    2123             : 
    2124       23724 : TEST(AssemblerX64BMI2) {
    2125           6 :   CcTest::InitializeVM();
    2126           6 :   if (!CpuFeatures::IsSupported(BMI2)) return;
    2127             : 
    2128           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    2129             :   HandleScope scope(isolate);
    2130             :   v8::internal::byte buffer[2048];
    2131             :   MacroAssembler assm(isolate, buffer, sizeof(buffer),
    2132           6 :                       v8::internal::CodeObjectRequired::kYes);
    2133             :   {
    2134             :     CpuFeatureScope fscope(&assm, BMI2);
    2135             :     Label exit;
    2136           6 :     __ pushq(rbx);                                  // save rbx
    2137           6 :     __ movq(rcx, V8_UINT64_C(0x1122334455667788));  // source operand
    2138           6 :     __ pushq(rcx);                                  // For memory operand
    2139             : 
    2140             :     // bzhi
    2141           6 :     __ movq(rdx, V8_UINT64_C(0x0000000000000009));
    2142             : 
    2143             :     __ movl(rax, Immediate(1));  // Test number
    2144             :     __ bzhiq(r8, rcx, rdx);
    2145           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000188));  // expected result
    2146           6 :     __ cmpq(r8, r9);
    2147           6 :     __ j(not_equal, &exit);
    2148             : 
    2149             :     __ incq(rax);
    2150          12 :     __ bzhiq(r8, Operand(rsp, 0), rdx);
    2151           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000188));  // expected result
    2152           6 :     __ cmpq(r8, r9);
    2153           6 :     __ j(not_equal, &exit);
    2154             : 
    2155             :     __ incq(rax);
    2156             :     __ bzhil(r8, rcx, rdx);
    2157           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000188));  // expected result
    2158           6 :     __ cmpq(r8, r9);
    2159           6 :     __ j(not_equal, &exit);
    2160             : 
    2161             :     __ incq(rax);
    2162          12 :     __ bzhil(r8, Operand(rsp, 0), rdx);
    2163           6 :     __ movq(r9, V8_UINT64_C(0x0000000000000188));  // expected result
    2164           6 :     __ cmpq(r8, r9);
    2165           6 :     __ j(not_equal, &exit);
    2166             : 
    2167             :     // mulx
    2168           6 :     __ movq(rdx, V8_UINT64_C(0x0000000000001000));
    2169             : 
    2170             :     __ incq(rax);
    2171             :     __ mulxq(r8, r9, rcx);
    2172           6 :     __ movq(rbx, V8_UINT64_C(0x0000000000000112));  // expected result
    2173           6 :     __ cmpq(r8, rbx);
    2174           6 :     __ j(not_equal, &exit);
    2175           6 :     __ movq(rbx, V8_UINT64_C(0x2334455667788000));  // expected result
    2176           6 :     __ cmpq(r9, rbx);
    2177           6 :     __ j(not_equal, &exit);
    2178             : 
    2179             :     __ incq(rax);
    2180          12 :     __ mulxq(r8, r9, Operand(rsp, 0));
    2181           6 :     __ movq(rbx, V8_UINT64_C(0x0000000000000112));  // expected result
    2182           6 :     __ cmpq(r8, rbx);
    2183           6 :     __ j(not_equal, &exit);
    2184           6 :     __ movq(rbx, V8_UINT64_C(0x2334455667788000));  // expected result
    2185           6 :     __ cmpq(r9, rbx);
    2186           6 :     __ j(not_equal, &exit);
    2187             : 
    2188             :     __ incq(rax);
    2189             :     __ mulxl(r8, r9, rcx);
    2190           6 :     __ movq(rbx, V8_UINT64_C(0x0000000000000556));  // expected result
    2191           6 :     __ cmpq(r8, rbx);
    2192           6 :     __ j(not_equal, &exit);
    2193           6 :     __ movq(rbx, V8_UINT64_C(0x0000000067788000));  // expected result
    2194           6 :     __ cmpq(r9, rbx);
    2195           6 :     __ j(not_equal, &exit);
    2196             : 
    2197             :     __ incq(rax);
    2198          12 :     __ mulxl(r8, r9, Operand(rsp, 0));
    2199           6 :     __ movq(rbx, V8_UINT64_C(0x0000000000000556));  // expected result
    2200           6 :     __ cmpq(r8, rbx);
    2201           6 :     __ j(not_equal, &exit);
    2202           6 :     __ movq(rbx, V8_UINT64_C(0x0000000067788000));  // expected result
    2203           6 :     __ cmpq(r9, rbx);
    2204           6 :     __ j(not_equal, &exit);
    2205             : 
    2206             :     // pdep
    2207           6 :     __ movq(rdx, V8_UINT64_C(0xfffffffffffffff0));
    2208             : 
    2209             :     __ incq(rax);
    2210             :     __ pdepq(r8, rdx, rcx);
    2211           6 :     __ movq(r9, V8_UINT64_C(0x1122334455667400));  // expected result
    2212           6 :     __ cmpq(r8, r9);
    2213           6 :     __ j(not_equal, &exit);
    2214             : 
    2215             :     __ incq(rax);
    2216          12 :     __ pdepq(r8, rdx, Operand(rsp, 0));
    2217           6 :     __ movq(r9, V8_UINT64_C(0x1122334455667400));  // expected result
    2218           6 :     __ cmpq(r8, r9);
    2219           6 :     __ j(not_equal, &exit);
    2220             : 
    2221             :     __ incq(rax);
    2222             :     __ pdepl(r8, rdx, rcx);
    2223           6 :     __ movq(r9, V8_UINT64_C(0x0000000055667400));  // expected result
    2224           6 :     __ cmpq(r8, r9);
    2225           6 :     __ j(not_equal, &exit);
    2226             : 
    2227             :     __ incq(rax);
    2228          12 :     __ pdepl(r8, rdx, Operand(rsp, 0));
    2229           6 :     __ movq(r9, V8_UINT64_C(0x0000000055667400));  // expected result
    2230           6 :     __ cmpq(r8, r9);
    2231           6 :     __ j(not_equal, &exit);
    2232             : 
    2233             :     // pext
    2234           6 :     __ movq(rdx, V8_UINT64_C(0xfffffffffffffff0));
    2235             : 
    2236             :     __ incq(rax);
    2237             :     __ pextq(r8, rdx, rcx);
    2238           6 :     __ movq(r9, V8_UINT64_C(0x0000000003fffffe));  // expected result
    2239           6 :     __ cmpq(r8, r9);
    2240           6 :     __ j(not_equal, &exit);
    2241             : 
    2242             :     __ incq(rax);
    2243          12 :     __ pextq(r8, rdx, Operand(rsp, 0));
    2244           6 :     __ movq(r9, V8_UINT64_C(0x0000000003fffffe));  // expected result
    2245           6 :     __ cmpq(r8, r9);
    2246           6 :     __ j(not_equal, &exit);
    2247             : 
    2248             :     __ incq(rax);
    2249             :     __ pextl(r8, rdx, rcx);
    2250           6 :     __ movq(r9, V8_UINT64_C(0x000000000000fffe));  // expected result
    2251           6 :     __ cmpq(r8, r9);
    2252           6 :     __ j(not_equal, &exit);
    2253             : 
    2254             :     __ incq(rax);
    2255          12 :     __ pextl(r8, rdx, Operand(rsp, 0));
    2256           6 :     __ movq(r9, V8_UINT64_C(0x000000000000fffe));  // expected result
    2257           6 :     __ cmpq(r8, r9);
    2258           6 :     __ j(not_equal, &exit);
    2259             : 
    2260             :     // sarx
    2261           6 :     __ movq(rdx, V8_UINT64_C(0x0000000000000004));
    2262             : 
    2263             :     __ incq(rax);
    2264             :     __ sarxq(r8, rcx, rdx);
    2265           6 :     __ movq(r9, V8_UINT64_C(0x0112233445566778));  // expected result
    2266           6 :     __ cmpq(r8, r9);
    2267           6 :     __ j(not_equal, &exit);
    2268             : 
    2269             :     __ incq(rax);
    2270          12 :     __ sarxq(r8, Operand(rsp, 0), rdx);
    2271           6 :     __ movq(r9, V8_UINT64_C(0x0112233445566778));  // expected result
    2272           6 :     __ cmpq(r8, r9);
    2273           6 :     __ j(not_equal, &exit);
    2274             : 
    2275             :     __ incq(rax);
    2276             :     __ sarxl(r8, rcx, rdx);
    2277           6 :     __ movq(r9, V8_UINT64_C(0x0000000005566778));  // expected result
    2278           6 :     __ cmpq(r8, r9);
    2279           6 :     __ j(not_equal, &exit);
    2280             : 
    2281             :     __ incq(rax);
    2282          12 :     __ sarxl(r8, Operand(rsp, 0), rdx);
    2283           6 :     __ movq(r9, V8_UINT64_C(0x0000000005566778));  // expected result
    2284           6 :     __ cmpq(r8, r9);
    2285           6 :     __ j(not_equal, &exit);
    2286             : 
    2287             :     // shlx
    2288           6 :     __ movq(rdx, V8_UINT64_C(0x0000000000000004));
    2289             : 
    2290             :     __ incq(rax);
    2291             :     __ shlxq(r8, rcx, rdx);
    2292           6 :     __ movq(r9, V8_UINT64_C(0x1223344556677880));  // expected result
    2293           6 :     __ cmpq(r8, r9);
    2294           6 :     __ j(not_equal, &exit);
    2295             : 
    2296             :     __ incq(rax);
    2297          12 :     __ shlxq(r8, Operand(rsp, 0), rdx);
    2298           6 :     __ movq(r9, V8_UINT64_C(0x1223344556677880));  // expected result
    2299           6 :     __ cmpq(r8, r9);
    2300           6 :     __ j(not_equal, &exit);
    2301             : 
    2302             :     __ incq(rax);
    2303             :     __ shlxl(r8, rcx, rdx);
    2304           6 :     __ movq(r9, V8_UINT64_C(0x0000000056677880));  // expected result
    2305           6 :     __ cmpq(r8, r9);
    2306           6 :     __ j(not_equal, &exit);
    2307             : 
    2308             :     __ incq(rax);
    2309          12 :     __ shlxl(r8, Operand(rsp, 0), rdx);
    2310           6 :     __ movq(r9, V8_UINT64_C(0x0000000056677880));  // expected result
    2311           6 :     __ cmpq(r8, r9);
    2312           6 :     __ j(not_equal, &exit);
    2313             : 
    2314             :     // shrx
    2315           6 :     __ movq(rdx, V8_UINT64_C(0x0000000000000004));
    2316             : 
    2317             :     __ incq(rax);
    2318             :     __ shrxq(r8, rcx, rdx);
    2319           6 :     __ movq(r9, V8_UINT64_C(0x0112233445566778));  // expected result
    2320           6 :     __ cmpq(r8, r9);
    2321           6 :     __ j(not_equal, &exit);
    2322             : 
    2323             :     __ incq(rax);
    2324          12 :     __ shrxq(r8, Operand(rsp, 0), rdx);
    2325           6 :     __ movq(r9, V8_UINT64_C(0x0112233445566778));  // expected result
    2326           6 :     __ cmpq(r8, r9);
    2327           6 :     __ j(not_equal, &exit);
    2328             : 
    2329             :     __ incq(rax);
    2330             :     __ shrxl(r8, rcx, rdx);
    2331           6 :     __ movq(r9, V8_UINT64_C(0x0000000005566778));  // expected result
    2332           6 :     __ cmpq(r8, r9);
    2333           6 :     __ j(not_equal, &exit);
    2334             : 
    2335             :     __ incq(rax);
    2336          12 :     __ shrxl(r8, Operand(rsp, 0), rdx);
    2337           6 :     __ movq(r9, V8_UINT64_C(0x0000000005566778));  // expected result
    2338           6 :     __ cmpq(r8, r9);
    2339           6 :     __ j(not_equal, &exit);
    2340             : 
    2341             :     // rorx
    2342             :     __ incq(rax);
    2343           6 :     __ rorxq(r8, rcx, 0x4);
    2344           6 :     __ movq(r9, V8_UINT64_C(0x8112233445566778));  // expected result
    2345           6 :     __ cmpq(r8, r9);
    2346           6 :     __ j(not_equal, &exit);
    2347             : 
    2348             :     __ incq(rax);
    2349           6 :     __ rorxq(r8, Operand(rsp, 0), 0x4);
    2350           6 :     __ movq(r9, V8_UINT64_C(0x8112233445566778));  // expected result
    2351           6 :     __ cmpq(r8, r9);
    2352           6 :     __ j(not_equal, &exit);
    2353             : 
    2354             :     __ incq(rax);
    2355           6 :     __ rorxl(r8, rcx, 0x4);
    2356           6 :     __ movq(r9, V8_UINT64_C(0x0000000085566778));  // expected result
    2357           6 :     __ cmpq(r8, r9);
    2358           6 :     __ j(not_equal, &exit);
    2359             : 
    2360             :     __ incq(rax);
    2361           6 :     __ rorxl(r8, Operand(rsp, 0), 0x4);
    2362           6 :     __ movq(r9, V8_UINT64_C(0x0000000085566778));  // expected result
    2363           6 :     __ cmpq(r8, r9);
    2364           6 :     __ j(not_equal, &exit);
    2365             : 
    2366             :     __ xorl(rax, rax);
    2367           6 :     __ bind(&exit);
    2368           6 :     __ popq(rcx);
    2369           6 :     __ popq(rbx);
    2370           6 :     __ ret(0);
    2371             :   }
    2372             : 
    2373             :   CodeDesc desc;
    2374           6 :   assm.GetCode(isolate, &desc);
    2375             :   Handle<Code> code =
    2376           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    2377             : #ifdef OBJECT_PRINT
    2378             :   OFStream os(stdout);
    2379             :   code->Print(os);
    2380             : #endif
    2381             : 
    2382           6 :   F0 f = FUNCTION_CAST<F0>(code->entry());
    2383           6 :   CHECK_EQ(0, f());
    2384             : }
    2385             : 
    2386             : 
    2387       23724 : TEST(AssemblerX64JumpTables1) {
    2388             :   // Test jump tables with forward jumps.
    2389           6 :   CcTest::InitializeVM();
    2390           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    2391             :   HandleScope scope(isolate);
    2392             :   MacroAssembler assm(isolate, nullptr, 0,
    2393           6 :                       v8::internal::CodeObjectRequired::kYes);
    2394             : 
    2395             :   const int kNumCases = 512;
    2396             :   int values[kNumCases];
    2397           6 :   isolate->random_number_generator()->NextBytes(values, sizeof(values));
    2398        3078 :   Label labels[kNumCases];
    2399             : 
    2400             :   Label done, table;
    2401          12 :   __ leaq(arg2, Operand(&table));
    2402           6 :   __ jmp(Operand(arg2, arg1, times_8, 0));
    2403           6 :   __ ud2();
    2404           6 :   __ bind(&table);
    2405        3078 :   for (int i = 0; i < kNumCases; ++i) {
    2406        3072 :     __ dq(&labels[i]);
    2407             :   }
    2408             : 
    2409        3072 :   for (int i = 0; i < kNumCases; ++i) {
    2410        3072 :     __ bind(&labels[i]);
    2411        3072 :     __ movq(rax, Immediate(values[i]));
    2412        3072 :     __ jmp(&done);
    2413             :   }
    2414             : 
    2415           6 :   __ bind(&done);
    2416           6 :   __ ret(0);
    2417             : 
    2418             :   CodeDesc desc;
    2419           6 :   assm.GetCode(isolate, &desc);
    2420             :   Handle<Code> code =
    2421           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    2422             : #ifdef OBJECT_PRINT
    2423             :   code->Print(std::cout);
    2424             : #endif
    2425             : 
    2426           6 :   F1 f = FUNCTION_CAST<F1>(code->entry());
    2427        3078 :   for (int i = 0; i < kNumCases; ++i) {
    2428        3072 :     int res = f(i);
    2429        3072 :     PrintF("f(%d) = %d\n", i, res);
    2430        3072 :     CHECK_EQ(values[i], res);
    2431             :   }
    2432           6 : }
    2433             : 
    2434             : 
    2435       23724 : TEST(AssemblerX64JumpTables2) {
    2436             :   // Test jump tables with backwards jumps.
    2437           6 :   CcTest::InitializeVM();
    2438           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    2439             :   HandleScope scope(isolate);
    2440             :   MacroAssembler assm(isolate, nullptr, 0,
    2441           6 :                       v8::internal::CodeObjectRequired::kYes);
    2442             : 
    2443             :   const int kNumCases = 512;
    2444             :   int values[kNumCases];
    2445           6 :   isolate->random_number_generator()->NextBytes(values, sizeof(values));
    2446        3078 :   Label labels[kNumCases];
    2447             : 
    2448             :   Label done, table;
    2449          12 :   __ leaq(arg2, Operand(&table));
    2450           6 :   __ jmp(Operand(arg2, arg1, times_8, 0));
    2451           6 :   __ ud2();
    2452             : 
    2453        3078 :   for (int i = 0; i < kNumCases; ++i) {
    2454        3072 :     __ bind(&labels[i]);
    2455        3072 :     __ movq(rax, Immediate(values[i]));
    2456        3072 :     __ jmp(&done);
    2457             :   }
    2458             : 
    2459           6 :   __ bind(&done);
    2460           6 :   __ ret(0);
    2461             : 
    2462           6 :   __ bind(&table);
    2463        3078 :   for (int i = 0; i < kNumCases; ++i) {
    2464        3072 :     __ dq(&labels[i]);
    2465             :   }
    2466             : 
    2467             :   CodeDesc desc;
    2468           6 :   assm.GetCode(isolate, &desc);
    2469             :   Handle<Code> code =
    2470           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    2471             : #ifdef OBJECT_PRINT
    2472             :   code->Print(std::cout);
    2473             : #endif
    2474             : 
    2475           6 :   F1 f = FUNCTION_CAST<F1>(code->entry());
    2476        3078 :   for (int i = 0; i < kNumCases; ++i) {
    2477        3072 :     int res = f(i);
    2478        3072 :     PrintF("f(%d) = %d\n", i, res);
    2479        3072 :     CHECK_EQ(values[i], res);
    2480             :   }
    2481           6 : }
    2482             : 
    2483       23724 : TEST(AssemblerX64PslldWithXmm15) {
    2484           6 :   CcTest::InitializeVM();
    2485             :   // Allocate an executable page of memory.
    2486             :   size_t actual_size;
    2487             :   byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
    2488           6 :       Assembler::kMinimalBufferSize, &actual_size, true));
    2489           6 :   CHECK(buffer);
    2490          12 :   Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
    2491             : 
    2492           6 :   __ movq(xmm15, arg1);
    2493           6 :   __ pslld(xmm15, 1);
    2494           6 :   __ movq(rax, xmm15);
    2495           6 :   __ ret(0);
    2496             : 
    2497             :   CodeDesc desc;
    2498           6 :   assm.GetCode(CcTest::i_isolate(), &desc);
    2499           6 :   uint64_t result = FUNCTION_CAST<F5>(buffer)(V8_UINT64_C(0x1122334455667788));
    2500           6 :   CHECK_EQ(V8_UINT64_C(0x22446688aaccef10), result);
    2501           6 : }
    2502             : 
    2503             : typedef float (*F9)(float x, float y);
    2504       23724 : TEST(AssemblerX64vmovups) {
    2505           6 :   CcTest::InitializeVM();
    2506           6 :   if (!CpuFeatures::IsSupported(AVX)) return;
    2507             : 
    2508           6 :   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
    2509             :   HandleScope scope(isolate);
    2510             :   v8::internal::byte buffer[256];
    2511             :   MacroAssembler assm(isolate, buffer, sizeof(buffer),
    2512           6 :                       v8::internal::CodeObjectRequired::kYes);
    2513             :   {
    2514             :     CpuFeatureScope avx_scope(&assm, AVX);
    2515           6 :     __ shufps(xmm0, xmm0, 0x0);  // brocast first argument
    2516           6 :     __ shufps(xmm1, xmm1, 0x0);  // brocast second argument
    2517             :     // copy xmm1 to xmm0 through the stack to test the "vmovups reg, mem".
    2518           6 :     __ subq(rsp, Immediate(kSimd128Size));
    2519          12 :     __ vmovups(Operand(rsp, 0), xmm1);
    2520          12 :     __ vmovups(xmm0, Operand(rsp, 0));
    2521           6 :     __ addq(rsp, Immediate(kSimd128Size));
    2522             : 
    2523           6 :     __ ret(0);
    2524             :   }
    2525             : 
    2526             :   CodeDesc desc;
    2527           6 :   assm.GetCode(isolate, &desc);
    2528             :   Handle<Code> code =
    2529           6 :       isolate->factory()->NewCode(desc, Code::STUB, Handle<Code>());
    2530             : #ifdef OBJECT_PRINT
    2531             :   OFStream os(stdout);
    2532             :   code->Print(os);
    2533             : #endif
    2534             : 
    2535           6 :   F9 f = FUNCTION_CAST<F9>(code->entry());
    2536           6 :   CHECK_EQ(-1.5, f(1.5, -1.5));
    2537             : }
    2538             : 
    2539             : #undef __
    2540             : 
    2541             : }  // namespace internal
    2542       71154 : }  // namespace v8

Generated by: LCOV version 1.10