1ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 2ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// Rrdistribution and use in source and binary forms, with or without 3ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// modification, are permitted provided that the following conditions are 4ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// met: 5ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// 6ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// * Rrdistributions of source code must retain the above copyright 7ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// notice, this list of conditions and the following disclaimer. 8ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// * Rrdistributions in binary form must reproduce the above 9ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// copyright notice, this list of conditions and the following 10ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// disclaimer in the documentation and/or other materials provided 11ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// with the distribution. 12ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// * Neither the name of Google Inc. nor the names of its 13ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// contributors may be used to endorse or promote products derived 14ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// from this software without specific prior written permission. 15ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// 16ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 28ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#include <stdlib.h> 29ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 31ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 325de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h" 33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h" 34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/factory.h" 35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h" 36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h" 37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/test-code-stubs.h" 38ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 39ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgusing namespace v8::internal; 40ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 41ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 42ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#define __ assm. 43ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 44ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, 45ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Register source_reg, 46ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Register destination_reg) { 47ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Allocate an executable page of memory. 48ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org size_t actual_size; 495de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( 505de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org Assembler::kMinimalBufferSize, &actual_size, true)); 51ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(buffer); 52ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope handles(isolate); 53ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size)); 54ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org int offset = 55ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org source_reg.is(rsp) ? 0 : (HeapNumber::kValueOffset - kSmiTagSize); 56f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org DoubleToIStub stub(isolate, source_reg, destination_reg, offset, true); 57f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org byte* start = stub.GetCode()->instruction_start(); 58ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 59763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbx); 60763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rcx); 61763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdx); 62763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rsi); 63763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdi); 64ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 65ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (!source_reg.is(rsp)) { 66935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // The argument we pass to the stub is not a heap number, but instead 67935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // stack-allocated and offset-wise made to look like a heap number for 68935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // the stub. We create that "heap number" after pushing all allocatable 69935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // registers. 70935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org int double_argument_slot = 71935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org (Register::NumAllocatableRegisters() - 1) * kPointerSize + kDoubleSize; 72895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leaq(source_reg, MemOperand(rsp, -double_argument_slot - offset)); 73ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 74ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 75ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Save registers make sure they don't get clobbered. 76ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org int reg_num = 0; 77ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) { 78935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org Register reg = Register::FromAllocationIndex(reg_num); 79ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (!reg.is(rsp) && !reg.is(rbp) && !reg.is(destination_reg)) { 80763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(reg); 81ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 82ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 83ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 84935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // Put the double argument into the designated double argument slot. 85ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ subq(rsp, Immediate(kDoubleSize)); 86ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ movsd(MemOperand(rsp, 0), xmm0); 87ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 88ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Call through to the actual stub 89ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ Call(start, RelocInfo::EXTERNAL_REFERENCE); 90ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 91ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ addq(rsp, Immediate(kDoubleSize)); 92ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 93ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Make sure no registers have been unexpectedly clobbered 94ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org for (--reg_num; reg_num >= 0; --reg_num) { 95935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org Register reg = Register::FromAllocationIndex(reg_num); 96ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (!reg.is(rsp) && !reg.is(rbp) && !reg.is(destination_reg)) { 97ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ cmpq(reg, MemOperand(rsp, 0)); 98594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(equal, kRegisterWasClobbered); 99ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ addq(rsp, Immediate(kPointerSize)); 100ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 101ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 102ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 103ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ movq(rax, destination_reg); 104ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 105763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdi); 106763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rsi); 107763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdx); 108763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rcx); 109763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbx); 110ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 111ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org __ ret(0); 112ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 113ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CodeDesc desc; 114ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org assm.GetCode(&desc); 115ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org return reinterpret_cast<ConvertDToIFunc>( 116ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org reinterpret_cast<intptr_t>(buffer)); 117ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 118ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 119ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#undef __ 120ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 121ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 122ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic Isolate* GetIsolateFrom(LocalContext* context) { 123ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org return reinterpret_cast<Isolate*>((*context)->GetIsolate()); 124ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 125ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 126ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 127ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgTEST(ConvertDToI) { 128ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CcTest::InitializeVM(); 129ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org LocalContext context; 130ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Isolate* isolate = GetIsolateFrom(&context); 131ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 132ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 133ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#if DEBUG 134ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Verify that the tests actually work with the C version. In the release 135ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // code, the compiler optimizes it away because it's all constant, but does it 136ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // wrong, triggering an assert on gcc. 137ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org RunAllTruncationTests(&ConvertDToICVersion); 138ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#endif 139ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 140ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Register source_registers[] = {rsp, rax, rbx, rcx, rdx, rsi, rdi, r8, r9}; 141ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Register dest_registers[] = {rax, rbx, rcx, rdx, rsi, rdi, r8, r9}; 142ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 143ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) { 144ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) { 145ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org RunAllTruncationTests( 146ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org MakeConvertDToIFuncTrampoline(isolate, 147ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org source_registers[s], 148ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org dest_registers[d])); 149ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 150ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 151ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 152