1755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// Copyright 2009 the V8 project authors. All rights reserved. 2755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// Redistribution and use in source and binary forms, with or without 3755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// modification, are permitted provided that the following conditions are 4755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// met: 5755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// 6755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// * Redistributions of source code must retain the above copyright 7755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// notice, this list of conditions and the following disclaimer. 8755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// * Redistributions in binary form must reproduce the above 9755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// copyright notice, this list of conditions and the following 10755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// disclaimer in the documentation and/or other materials provided 11755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// with the distribution. 12755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// * Neither the name of Google Inc. nor the names of its 13755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// contributors may be used to endorse or promote products derived 14755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// from this software without specific prior written permission. 15755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// 16755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 28755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org#include <stdlib.h> 29755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 31755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 325de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h" 33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/factory.h" 344b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/macro-assembler.h" 357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/ostreams.h" 36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h" 37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h" 38755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 39b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgusing namespace v8::internal; 400ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 41755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// Test the x64 assembler by compiling some simple functions into 42755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// a buffer and executing them. These tests do not initialize the 43755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// V8 library, create a context, or use any V8 objects. 449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com// The AMD64 calling convention is used, with the first six arguments 459d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com// in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in 46755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// the XMM registers. The return value is in RAX. 47755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org// This calling convention is used on Linux, with GCC, and on Mac OS, 489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com// with GCC. A different convention is used on 64-bit windows, 499d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com// where the first four integer arguments are passed in RCX, RDX, R8 and R9. 50755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 51755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgtypedef int (*F0)(); 522abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgtypedef int (*F1)(int64_t x); 532abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgtypedef int (*F2)(int64_t x, int64_t y); 54b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgtypedef int (*F3)(double x); 55c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgtypedef int64_t (*F4)(int64_t* x, int64_t* y); 56c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgtypedef int64_t (*F5)(int64_t x); 57755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com#ifdef _WIN64 59b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgstatic const Register arg1 = rcx; 60b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgstatic const Register arg2 = rdx; 619d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com#else 62b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgstatic const Register arg1 = rdi; 63b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgstatic const Register arg2 = rsi; 649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com#endif 659d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 66755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org#define __ assm. 67755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 68755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 69755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgTEST(AssemblerX64ReturnOperation) { 70874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 71755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Allocate an executable page of memory. 72755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org size_t actual_size; 735de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 745de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 75755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK(buffer); 76528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 77755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 78755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Assemble a simple function that copies argument 2 and returns it. 799d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com __ movq(rax, arg2); 80755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ nop(); 81755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ ret(0); 82755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 83755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CodeDesc desc; 84755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org assm.GetCode(&desc); 85755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Call the function from C++. 86755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int result = FUNCTION_CAST<F2>(buffer)(3, 2); 87755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK_EQ(2, result); 88755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 89755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 90e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 91755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgTEST(AssemblerX64StackOperations) { 92874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 93755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Allocate an executable page of memory. 94755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org size_t actual_size; 955de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 965de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 97755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK(buffer); 98528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 99755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 100755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Assemble a simple function that copies argument 2 and returns it. 101755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // We compile without stack frame pointers, so the gdb debugger shows 102755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // incorrect stack frames when debugging this function (which has them). 103763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); 104755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ movq(rbp, rsp); 105763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(arg2); // Value at (rbp - 8) 106763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(arg2); // Value at (rbp - 16) 107763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(arg1); // Value at (rbp - 24) 108763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rax); 109763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rax); 110763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rax); 111763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 112755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ nop(); 113755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ ret(0); 114755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 115755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CodeDesc desc; 116755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org assm.GetCode(&desc); 117755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Call the function from C++. 118755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int result = FUNCTION_CAST<F2>(buffer)(3, 2); 119755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK_EQ(2, result); 120755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 121755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 122e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 123755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgTEST(AssemblerX64ArithmeticOperations) { 124874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 125755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Allocate an executable page of memory. 126755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org size_t actual_size; 1275de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 1285de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 129755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK(buffer); 130528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 131755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 1322abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org // Assemble a simple function that adds arguments returning the sum. 1339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com __ movq(rax, arg2); 1349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com __ addq(rax, arg1); 135755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ ret(0); 136755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 137755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CodeDesc desc; 138755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org assm.GetCode(&desc); 139755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Call the function from C++. 140755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int result = FUNCTION_CAST<F2>(buffer)(3, 2); 141755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK_EQ(5, result); 142755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 143755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 144e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1452f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.orgTEST(AssemblerX64CmpbOperation) { 146874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 1472f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // Allocate an executable page of memory. 1482f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org size_t actual_size; 1495de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 1505de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 1512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CHECK(buffer); 1522f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 1532f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 1542f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // Assemble a function that compare argument byte returing 1 if equal else 0. 1552f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // On Windows, it compares rcx with rdx which does not require REX prefix; 1562f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // on Linux, it compares rdi with rsi which requires REX prefix. 1572f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 1582f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org Label done; 1592f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ movq(rax, Immediate(1)); 1602f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ cmpb(arg1, arg2); 1612f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ j(equal, &done); 1622f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ movq(rax, Immediate(0)); 1632f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ bind(&done); 1642f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ ret(0); 1652f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 1662f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CodeDesc desc; 1672f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org assm.GetCode(&desc); 1682f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org // Call the function from C++. 1692f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org int result = FUNCTION_CAST<F2>(buffer)(0x1002, 0x2002); 1702f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CHECK_EQ(1, result); 1712f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org result = FUNCTION_CAST<F2>(buffer)(0x1002, 0x2003); 1722f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org CHECK_EQ(0, result); 1732f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org} 1742f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 1752f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org 1762abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.orgTEST(AssemblerX64ImulOperation) { 177874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 1782abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org // Allocate an executable page of memory. 1792abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org size_t actual_size; 1805de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 1815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 1822abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org CHECK(buffer); 183528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 1842abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 1852abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org // Assemble a simple function that multiplies arguments returning the high 1862abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org // word. 1879d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com __ movq(rax, arg2); 188fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ imulq(arg1); 1892abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org __ movq(rax, rdx); 1902abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org __ ret(0); 1912abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 1922abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org CodeDesc desc; 1932abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org assm.GetCode(&desc); 1942abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org // Call the function from C++. 1952abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org int result = FUNCTION_CAST<F2>(buffer)(3, 2); 1962abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org CHECK_EQ(0, result); 1972abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l); 1982abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org CHECK_EQ(1, result); 1992abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l); 2002abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org CHECK_EQ(-1, result); 2012abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org} 2022abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 203e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 204c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgTEST(AssemblerX64XchglOperations) { 205874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 206c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Allocate an executable page of memory. 207c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org size_t actual_size; 2085de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 2095de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 210c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK(buffer); 211c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 212c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 213c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ movq(rax, Operand(arg1, 0)); 21425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org __ movq(r11, Operand(arg2, 0)); 21525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org __ xchgl(rax, r11); 216c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ movq(Operand(arg1, 0), rax); 21725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org __ movq(Operand(arg2, 0), r11); 218c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ ret(0); 219c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 220c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CodeDesc desc; 221c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org assm.GetCode(&desc); 222c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Call the function from C++. 223c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); 224c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); 225c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); 226c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 40000000), left); 227c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 20000000), right); 228c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org USE(result); 229c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 230c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 231c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 232c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgTEST(AssemblerX64OrlOperations) { 233874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 234c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Allocate an executable page of memory. 235c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org size_t actual_size; 2365de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 2375de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 238c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK(buffer); 239c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 240c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 241c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ movq(rax, Operand(arg2, 0)); 242c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ orl(Operand(arg1, 0), rax); 243c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ ret(0); 244c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 245c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CodeDesc desc; 246c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org assm.GetCode(&desc); 247c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Call the function from C++. 248c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); 249c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); 250c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); 251c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 60000000), left); 252c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org USE(result); 253c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 254c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 255c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 256c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgTEST(AssemblerX64RollOperations) { 257874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 258c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Allocate an executable page of memory. 259c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org size_t actual_size; 2605de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 2615de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 262c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK(buffer); 263c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 264c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 265c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ movq(rax, arg1); 266c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ roll(rax, Immediate(1)); 267c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ ret(0); 268c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 269c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CodeDesc desc; 270c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org assm.GetCode(&desc); 271c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Call the function from C++. 272c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t src = V8_2PART_UINT64_C(0x10000000, C0000000); 273c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t result = FUNCTION_CAST<F5>(buffer)(src); 274c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 80000001), result); 275c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 276c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 277c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 278c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgTEST(AssemblerX64SublOperations) { 279874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 280c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Allocate an executable page of memory. 281c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org size_t actual_size; 2825de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 2835de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 284c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK(buffer); 285c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 286c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 287c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ movq(rax, Operand(arg2, 0)); 288c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ subl(Operand(arg1, 0), rax); 289c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ ret(0); 290c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 291c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CodeDesc desc; 292c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org assm.GetCode(&desc); 293c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Call the function from C++. 294c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); 295c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); 296c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); 297c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK_EQ(V8_2PART_UINT64_C(0x10000000, e0000000), left); 298c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org USE(result); 299c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 300c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 301c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 302c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgTEST(AssemblerX64TestlOperations) { 303874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 304c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Allocate an executable page of memory. 305c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org size_t actual_size; 3065de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 3075de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 308c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK(buffer); 309c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 310c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 311c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Set rax with the ZF flag of the testl instruction. 312c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Label done; 313c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ movq(rax, Immediate(1)); 31425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org __ movq(r11, Operand(arg2, 0)); 31525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org __ testl(Operand(arg1, 0), r11); 316c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ j(zero, &done, Label::kNear); 317c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ movq(rax, Immediate(0)); 318c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ bind(&done); 319c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ ret(0); 320c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 321c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CodeDesc desc; 322c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org assm.GetCode(&desc); 323c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Call the function from C++. 324c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); 325c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t right = V8_2PART_UINT64_C(0x30000000, 00000000); 326c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); 327c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK_EQ(static_cast<int64_t>(1), result); 328c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 329c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 330c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 331c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgTEST(AssemblerX64XorlOperations) { 332874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 333c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Allocate an executable page of memory. 334c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org size_t actual_size; 3355de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 3365de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 337c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK(buffer); 338c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 339c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 340c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ movq(rax, Operand(arg2, 0)); 341c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ xorl(Operand(arg1, 0), rax); 342c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ ret(0); 343c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 344c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CodeDesc desc; 345c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org assm.GetCode(&desc); 346c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Call the function from C++. 347c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); 348c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t right = V8_2PART_UINT64_C(0x30000000, 60000000); 349c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); 350c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 40000000), left); 351c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org USE(result); 352c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 353c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 354c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 355755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgTEST(AssemblerX64MemoryOperands) { 356874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 357755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Allocate an executable page of memory. 358755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org size_t actual_size; 3595de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 3605de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 361755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK(buffer); 362528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 363755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 364755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Assemble a simple function that copies argument 2 and returns it. 365763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); 366755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ movq(rbp, rsp); 3679d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 368763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(arg2); // Value at (rbp - 8) 369763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(arg2); // Value at (rbp - 16) 370763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(arg1); // Value at (rbp - 24) 3719d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 372755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org const int kStackElementSize = 8; 373755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ movq(rax, Operand(rbp, -3 * kStackElementSize)); 374763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(arg2); 375763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(arg2); 376763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(arg2); 377763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 378755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ nop(); 379755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ ret(0); 380755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 381755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CodeDesc desc; 382755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org assm.GetCode(&desc); 383755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Call the function from C++. 384755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int result = FUNCTION_CAST<F2>(buffer)(3, 2); 385755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK_EQ(3, result); 386755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 387755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 388e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 389755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgTEST(AssemblerX64ControlFlow) { 390874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 391755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Allocate an executable page of memory. 392755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org size_t actual_size; 3935de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 3945de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 395755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK(buffer); 396528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 397755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 3989d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Assemble a simple function that copies argument 1 and returns it. 399763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); 4009d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 401755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ movq(rbp, rsp); 4029d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com __ movq(rax, arg1); 403755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Label target; 404755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ jmp(&target); 4059d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com __ movq(rax, arg2); 406755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ bind(&target); 407763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 408755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ ret(0); 409755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 410755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CodeDesc desc; 411755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org assm.GetCode(&desc); 412755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Call the function from C++. 413755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int result = FUNCTION_CAST<F2>(buffer)(3, 2); 414755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK_EQ(3, result); 415755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 416755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 417e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 418755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.orgTEST(AssemblerX64LoopImmediates) { 419874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org CcTest::InitializeVM(); 420755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Allocate an executable page of memory. 421755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org size_t actual_size; 4225de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 4235de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 424755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK(buffer); 425528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 426755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Assemble two loops using rax as counter, and verify the ending counts. 427755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Label Fail; 428755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ movq(rax, Immediate(-3)); 429755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Label Loop1_test; 430755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Label Loop1_body; 431755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ jmp(&Loop1_test); 432755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ bind(&Loop1_body); 433eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org __ addq(rax, Immediate(7)); 434755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ bind(&Loop1_test); 435eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org __ cmpq(rax, Immediate(20)); 436755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ j(less_equal, &Loop1_body); 437755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Did the loop terminate with the expected value? 438eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org __ cmpq(rax, Immediate(25)); 439755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ j(not_equal, &Fail); 440755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 441755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Label Loop2_test; 442755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org Label Loop2_body; 443755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ movq(rax, Immediate(0x11FEED00)); 444755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ jmp(&Loop2_test); 445755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ bind(&Loop2_body); 446eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org __ addq(rax, Immediate(-0x1100)); 447755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ bind(&Loop2_test); 448eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org __ cmpq(rax, Immediate(0x11FE8000)); 449755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ j(greater, &Loop2_body); 450755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Did the loop terminate with the expected value? 451eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org __ cmpq(rax, Immediate(0x11FE7600)); 452755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ j(not_equal, &Fail); 453755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 454755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ movq(rax, Immediate(1)); 455755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ ret(0); 456755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ bind(&Fail); 457755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ movq(rax, Immediate(0)); 458755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org __ ret(0); 459755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org 460755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CodeDesc desc; 461755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org assm.GetCode(&desc); 462755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org // Call the function from C++. 463755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org int result = FUNCTION_CAST<F0>(buffer)(); 464755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org CHECK_EQ(1, result); 465755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org} 466eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4670ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4680ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgTEST(OperandRegisterDependency) { 4690ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int offsets[4] = {0, 1, 0xfed, 0xbeefcad}; 4700ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org for (int i = 0; i < 4; i++) { 4710ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int offset = offsets[i]; 4720ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rax, offset).AddressUsesRegister(rax)); 4730ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rax, offset).AddressUsesRegister(r8)); 4740ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rax, offset).AddressUsesRegister(rcx)); 4750ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4760ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rax, rax, times_1, offset).AddressUsesRegister(rax)); 4770ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rax, rax, times_1, offset).AddressUsesRegister(r8)); 4780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rax, rax, times_1, offset).AddressUsesRegister(rcx)); 4790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rax, rcx, times_1, offset).AddressUsesRegister(rax)); 4810ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rax, rcx, times_1, offset).AddressUsesRegister(rcx)); 4820ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rax, rcx, times_1, offset).AddressUsesRegister(r8)); 4830ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rax, rcx, times_1, offset).AddressUsesRegister(r9)); 4840ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rax, rcx, times_1, offset).AddressUsesRegister(rdx)); 4850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rax, rcx, times_1, offset).AddressUsesRegister(rsp)); 4860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4870ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rsp, offset).AddressUsesRegister(rsp)); 4880ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rsp, offset).AddressUsesRegister(rax)); 489b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org CHECK(!Operand(rsp, offset).AddressUsesRegister(r15)); 4900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4910ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rbp, offset).AddressUsesRegister(rbp)); 4920ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rbp, offset).AddressUsesRegister(rax)); 4930ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rbp, offset).AddressUsesRegister(r13)); 4940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rbp, rax, times_1, offset).AddressUsesRegister(rbp)); 4960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rbp, rax, times_1, offset).AddressUsesRegister(rax)); 4970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rbp, rax, times_1, offset).AddressUsesRegister(rcx)); 4980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rbp, rax, times_1, offset).AddressUsesRegister(r13)); 4990ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rbp, rax, times_1, offset).AddressUsesRegister(r8)); 5000ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rbp, rax, times_1, offset).AddressUsesRegister(rsp)); 5010ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 5020ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rsp)); 5030ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rbp)); 5040ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(rax)); 505b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r15)); 5060ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org CHECK(!Operand(rsp, rbp, times_1, offset).AddressUsesRegister(r13)); 5070ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 5080ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 5090ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 51080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 51180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.orgTEST(AssemblerX64LabelChaining) { 51280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org // Test chaining of label usages within instructions (issue 1644). 513e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 514e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 515528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Assembler assm(CcTest::i_isolate(), NULL, 0); 51680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 51780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org Label target; 51880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ j(equal, &target); 51980c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ j(not_equal, &target); 52080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ bind(&target); 52180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org __ nop(); 52280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org} 52380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org 52464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 52564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgTEST(AssemblerMultiByteNop) { 526e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org CcTest::InitializeVM(); 527e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 528b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org byte buffer[1024]; 529528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); 53009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Assembler assm(isolate, buffer, sizeof(buffer)); 531763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbx); 532763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rcx); 533763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdx); 534763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdi); 535763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rsi); 53664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(rax, Immediate(1)); 53764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(rbx, Immediate(2)); 53864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(rcx, Immediate(3)); 53964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(rdx, Immediate(4)); 54064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(rdi, Immediate(5)); 54164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(rsi, Immediate(6)); 54264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org for (int i = 0; i < 16; i++) { 54364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org int before = assm.pc_offset(); 54464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Nop(i); 54564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org CHECK_EQ(assm.pc_offset() - before, i); 54664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 54764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 54864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label fail; 54964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmpq(rax, Immediate(1)); 55064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &fail); 55164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmpq(rbx, Immediate(2)); 55264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &fail); 55364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmpq(rcx, Immediate(3)); 55464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &fail); 55564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmpq(rdx, Immediate(4)); 55664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &fail); 55764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmpq(rdi, Immediate(5)); 55864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &fail); 55964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ cmpq(rsi, Immediate(6)); 56064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ j(not_equal, &fail); 56164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(rax, Immediate(42)); 562763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rsi); 563763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdi); 564763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdx); 565763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rcx); 566763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbx); 56764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ ret(0); 56864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&fail); 56964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ movq(rax, Immediate(13)); 570763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rsi); 571763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdi); 572763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdx); 573763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rcx); 574763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbx); 57564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ ret(0); 57664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 57764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org CodeDesc desc; 57864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org assm.GetCode(&desc); 5799fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Code> code = isolate->factory()->NewCode( 5809fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 58164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 58264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org F0 f = FUNCTION_CAST<F0>(code->entry()); 58364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org int res = f(); 58464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org CHECK_EQ(42, res); 58564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 58664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 58764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 588e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org#ifdef __GNUC__ 589e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org#define ELEMENT_COUNT 4 590e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 591e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgvoid DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { 592e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 593b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org byte buffer[1024]; 594e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 595e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org CHECK(args[0]->IsArray()); 596e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]); 597e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org CHECK_EQ(ELEMENT_COUNT, vec->Length()); 598e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 599528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Isolate* isolate = CcTest::i_isolate(); 600e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Assembler assm(isolate, buffer, sizeof(buffer)); 601e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 602e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // Remove return address from the stack for fix stack frame alignment. 603763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rcx); 604e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 605e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // Store input vector on the stack. 606e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org for (int i = 0; i < ELEMENT_COUNT; i++) { 607e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ movl(rax, Immediate(vec->Get(i)->Int32Value())); 6082f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shlq(rax, Immediate(0x20)); 609895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orq(rax, Immediate(vec->Get(++i)->Int32Value())); 610763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rax); 611e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 612e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 613e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // Read vector into a xmm register. 614e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ xorps(xmm0, xmm0); 615e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ movdqa(xmm0, Operand(rsp, 0)); 616e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // Create mask and store it in the return register. 617e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ movmskps(rax, xmm0); 618e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 619e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // Remove unused data from the stack. 620e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ addq(rsp, Immediate(ELEMENT_COUNT * sizeof(int32_t))); 621e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // Restore return address. 622763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rcx); 623e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 624e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org __ ret(0); 625e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 626e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org CodeDesc desc; 627e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org assm.GetCode(&desc); 6289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Code> code = isolate->factory()->NewCode( 6299fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 630e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 631e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org F0 f = FUNCTION_CAST<F0>(code->entry()); 632e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org int res = f(); 6330f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org args.GetReturnValue().Set(v8::Integer::New(CcTest::isolate(), res)); 634e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org} 635e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 636e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 637e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgTEST(StackAlignmentForSSE2) { 638528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CcTest::InitializeVM(); 6395de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CHECK_EQ(0, v8::base::OS::ActivationFrameAlignment() % 16); 640e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 641528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org v8::Isolate* isolate = CcTest::isolate(); 642e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8::HandleScope handle_scope(isolate); 6439cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org v8::Handle<v8::ObjectTemplate> global_template = 6449cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org v8::ObjectTemplate::New(isolate); 6454f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org global_template->Set(v8_str("do_sse2"), 6464f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org v8::FunctionTemplate::New(isolate, DoSSE2)); 647e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 648e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org LocalContext env(NULL, global_template); 649e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org CompileRun( 650e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org "function foo(vec) {" 651e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org " return do_sse2(vec);" 652e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org "}"); 653e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 654e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8::Local<v8::Object> global_object = env->Global(); 655e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8::Local<v8::Function> foo = 656e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo"))); 657e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 658e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 }; 6599f18d9111f676f2899d9aa2444130c985eb75395machenbach@chromium.org v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT); 660e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org for (int i = 0; i < ELEMENT_COUNT; i++) { 661e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8_vec->Set(i, v8_num(vec[i])); 662e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 663e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 664e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8::Local<v8::Value> args[] = { v8_vec }; 665e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org v8::Local<v8::Value> result = foo->Call(global_object, 1, args); 666e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 667e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // The mask should be 0b1000. 668e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org CHECK_EQ(8, result->Int32Value()); 669e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org} 670e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 671e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org#undef ELEMENT_COUNT 672e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org#endif // __GNUC__ 67364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 67464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 675b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.orgTEST(AssemblerX64Extractps) { 676b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org CcTest::InitializeVM(); 677b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org if (!CpuFeatures::IsSupported(SSE4_1)) return; 678b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org 679b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org v8::HandleScope scope(CcTest::isolate()); 680b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org byte buffer[256]; 681b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Isolate* isolate = CcTest::i_isolate(); 682b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Assembler assm(isolate, buffer, sizeof(buffer)); 683b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org { CpuFeatureScope fscope2(&assm, SSE4_1); 684b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ extractps(rax, xmm0, 0x1); 685b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ ret(0); 686b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org } 687b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org 688b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org CodeDesc desc; 689b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org assm.GetCode(&desc); 6909fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Code> code = isolate->factory()->NewCode( 6919fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 692b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org#ifdef OBJECT_PRINT 693f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org OFStream os(stdout); 694f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org code->Print(os); 695b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org#endif 696b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org 6979fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org F3 f = FUNCTION_CAST<F3>(code->entry()); 698b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321); 699b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org CHECK_EQ(0x12345678, f(uint64_to_double(value1))); 700b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678); 701b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org CHECK_EQ(0x87654321, f(uint64_to_double(value2))); 702b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org} 703b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org 704b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org 705af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgtypedef int (*F6)(float x, float y); 706af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgTEST(AssemblerX64SSE) { 707af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org CcTest::InitializeVM(); 708af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 709af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 710af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org HandleScope scope(isolate); 711af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org v8::internal::byte buffer[256]; 712af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org MacroAssembler assm(isolate, buffer, sizeof buffer); 713af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org { 714af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ shufps(xmm0, xmm0, 0x0); // brocast first argument 715af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ shufps(xmm1, xmm1, 0x0); // brocast second argument 716af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ movaps(xmm2, xmm1); 717af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ addps(xmm2, xmm0); 718af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ mulps(xmm2, xmm1); 719af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ subps(xmm2, xmm0); 720af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ divps(xmm2, xmm1); 721af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ cvttss2si(rax, xmm2); 722af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ ret(0); 723af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org } 724af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 725af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org CodeDesc desc; 726af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org assm.GetCode(&desc); 7279fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Code> code = isolate->factory()->NewCode( 728af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org desc, 729af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Code::ComputeFlags(Code::STUB), 7309fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Code>()); 731af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org#ifdef OBJECT_PRINT 732f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org OFStream os(stdout); 733f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org code->Print(os); 734af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org#endif 735af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 7369fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org F6 f = FUNCTION_CAST<F6>(code->entry()); 737af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org CHECK_EQ(2, f(1.0, 2.0)); 738af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org} 739755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org#undef __ 740