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

Generated by: LCOV version 1.10