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

Generated by: LCOV version 1.10