11e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 21e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// Rrdistribution and use in source and binary forms, with or without 31e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// modification, are permitted provided that the following conditions are 41e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// met: 51e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// 61e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// * Rrdistributions of source code must retain the above copyright 71e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// notice, this list of conditions and the following disclaimer. 81e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// * Rrdistributions in binary form must reproduce the above 91e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// copyright notice, this list of conditions and the following 101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// disclaimer in the documentation and/or other materials provided 111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// with the distribution. 121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// * Neither the name of Google Inc. nor the names of its 131e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// contributors may be used to endorse or promote products derived 141e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// from this software without specific prior written permission. 151e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// 161e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 281e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include <stdlib.h> 291e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 301e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include "v8.h" 311e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 321e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include "cctest.h" 331e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include "code-stubs.h" 341e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include "test-code-stubs.h" 351e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include "factory.h" 361e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include "macro-assembler.h" 371e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include "platform.h" 381e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#include "simulator.h" 391e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgusing namespace v8::internal; 411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 421e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#define __ masm. 431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, 451e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Register source_reg, 461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Register destination_reg, 471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org bool inline_fastpath) { 481e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Allocate an executable page of memory. 491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org size_t actual_size; 501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org &actual_size, 521e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org true)); 531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org CHECK(buffer); 541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HandleScope handles(isolate); 551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); 561e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org DoubleToIStub stub(source_reg, destination_reg, 0, true, inline_fastpath); 571e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 581e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org byte* start = stub.GetCode(isolate)->instruction_start(); 591e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Label done; 601e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Save callee save registers. 621e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ Push(r7, r6, r5, r4); 631e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ Push(lr); 641e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 652c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org // For softfp, move the input value into d0. 662c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org if (!masm.use_eabi_hardfloat()) { 672c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org __ vmov(d0, r0, r1); 682c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org } 691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Push the double argument. 701e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ sub(sp, sp, Operand(kDoubleSize)); 711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ vstr(d0, sp, 0); 721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (!source_reg.is(sp)) { 731e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ mov(source_reg, sp); 741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 751e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 761e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Save registers make sure they don't get clobbered. 771e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int source_reg_offset = kDoubleSize; 781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int reg_num = 0; 791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org for (;reg_num < Register::NumAllocatableRegisters(); ++reg_num) { 801e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Register reg = Register::from_code(reg_num); 811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (!reg.is(destination_reg)) { 821e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ push(reg); 831e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org source_reg_offset += kPointerSize; 841e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 851e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 861e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 871e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Re-push the double argument. 881e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ sub(sp, sp, Operand(kDoubleSize)); 891e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ vstr(d0, sp, 0); 901e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 911e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Call through to the actual stub 921e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (inline_fastpath) { 931e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ vldr(d0, MemOperand(source_reg)); 941e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ TryInlineTruncateDoubleToI(destination_reg, d0, &done); 951e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (destination_reg.is(source_reg) && !source_reg.is(sp)) { 961e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Restore clobbered source_reg. 971e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ add(source_reg, sp, Operand(source_reg_offset)); 981e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 991e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 1001e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ Call(start, RelocInfo::EXTERNAL_REFERENCE); 1011e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ bind(&done); 1021e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1031e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ add(sp, sp, Operand(kDoubleSize)); 1041e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1051e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Make sure no registers have been unexpectedly clobbered 1061e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org for (--reg_num; reg_num >= 0; --reg_num) { 1071e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Register reg = Register::from_code(reg_num); 1081e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (!reg.is(destination_reg)) { 1091e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ ldr(ip, MemOperand(sp, 0)); 1101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ cmp(reg, ip); 1111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ Assert(eq, kRegisterWasClobbered); 1121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ add(sp, sp, Operand(kPointerSize)); 1131e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 1141e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 1151e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1161e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ add(sp, sp, Operand(kDoubleSize)); 1171e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1181e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (!destination_reg.is(r0)) 1191e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ mov(r0, destination_reg); 1201e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1211e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Restore callee save registers. 1221e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ Pop(lr); 1231e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ Pop(r7, r6, r5, r4); 1241e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1251e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ Ret(0); 1261e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1271e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org CodeDesc desc; 1281e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org masm.GetCode(&desc); 1292c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org CPU::FlushICache(buffer, actual_size); 1301e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return (reinterpret_cast<ConvertDToIFunc>( 1311e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org reinterpret_cast<intptr_t>(buffer))); 1321e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org} 1331e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1341e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#undef __ 1351e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1361e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1371e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgstatic Isolate* GetIsolateFrom(LocalContext* context) { 1381e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return reinterpret_cast<Isolate*>((*context)->GetIsolate()); 1391e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org} 1401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1421e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgint32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, 1431e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org double from) { 1441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#ifdef USE_SIMULATOR 145528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return CALL_GENERATED_FP_INT(func, from, 0); 1461e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#else 1471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return (*func)(from); 1481e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif 1491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org} 1501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1521e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgTEST(ConvertDToI) { 1531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org CcTest::InitializeVM(); 1541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org LocalContext context; 1551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Isolate* isolate = GetIsolateFrom(&context); 1561e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org HandleScope scope(isolate); 1571e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1581e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if DEBUG 1591e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Verify that the tests actually work with the C version. In the release 1601e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // code, the compiler optimizes it away because it's all constant, but does it 1611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // wrong, triggering an assert on gcc. 1621e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org RunAllTruncationTests(&ConvertDToICVersion); 1631e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#endif 1641e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1651e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Register source_registers[] = {sp, r0, r1, r2, r3, r4, r5, r6, r7}; 1661e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Register dest_registers[] = {r0, r1, r2, r3, r4, r5, r6, r7}; 1671e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 1681e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org for (size_t s = 0; s < sizeof(source_registers) / sizeof(Register); s++) { 1691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org for (size_t d = 0; d < sizeof(dest_registers) / sizeof(Register); d++) { 1701e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org RunAllTruncationTests( 1711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org RunGeneratedCodeCallWrapper, 1721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org MakeConvertDToIFuncTrampoline(isolate, 1731e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org source_registers[s], 1741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org dest_registers[d], 1751e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org false)); 1761e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org RunAllTruncationTests( 1771e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org RunGeneratedCodeCallWrapper, 1781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org MakeConvertDToIFuncTrampoline(isolate, 1791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org source_registers[s], 1801e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org dest_registers[d], 1811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org true)); 1821e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 1831e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 1841e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org} 185