13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdlib.h> 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/disassembler.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/factory.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h" 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ostreams.h" 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/serialize.h" 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8::internal; 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef int (*F0)(); 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef int (*F1)(int x); 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef int (*F2)(int x, int y); 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ assm. 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa320) { 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, Operand(esp, 4)); 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ add(eax, Operand(esp, 8)); 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 669fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block#ifdef OBJECT_PRINT 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F2 f = FUNCTION_CAST<F2>(code->entry()); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = f(3, 4); 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, res); 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa321) { 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label L, C; 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(edx, Operand(esp, 4)); 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ xor_(eax, eax); // clear eax 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ jmp(&C); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&L); 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add(eax, edx); 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub(edx, Immediate(1)); 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&C); 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ test(edx, edx); 96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ j(not_zero, &L); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 1039fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block#ifdef OBJECT_PRINT 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F1 f = FUNCTION_CAST<F1>(code->entry()); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = f(100); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5050, res); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa322) { 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label L, C; 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(edx, Operand(esp, 4)); 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, 1); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ jmp(&C); 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&L); 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ imul(eax, edx); 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub(edx, Immediate(1)); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&C); 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ test(edx, edx); 133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ j(not_zero, &L); 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // some relocated stuff here, not executed 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(eax, isolate->factory()->true_value()); 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ jmp(NULL, RelocInfo::RUNTIME_ENTRY); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 1449fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block#ifdef OBJECT_PRINT 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F1 f = FUNCTION_CAST<F1>(code->entry()); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = f(10); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3628800, res); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef int (*F3)(float x); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa323) { 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ cvttss2si(eax, Operand(esp, 4)); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ret(0); 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // don't print the code - our disassembler can't handle cvttss2si 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instead print bytes 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Disassembler::Dump(stdout, 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code->instruction_start(), 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code->instruction_start() + code->instruction_size()); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F3 f = FUNCTION_CAST<F3>(code->entry()); 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = f(static_cast<float>(-3.1415)); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-3, res); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef int (*F4)(double x); 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa324) { 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 1898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ cvttsd2si(eax, Operand(esp, 4)); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // don't print the code - our disassembler can't handle cvttsd2si 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instead print bytes 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Disassembler::Dump(stdout, 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code->instruction_start(), 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code->instruction_start() + code->instruction_size()); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F4 f = FUNCTION_CAST<F4>(code->entry()); 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = f(2.718281828); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %d\n", res); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, res); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int baz = 42; 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa325) { 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(eax, Operand(reinterpret_cast<intptr_t>(&baz), RelocInfo::NONE32)); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F0 f = FUNCTION_CAST<F0>(code->entry()); 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int res = f(); 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(42, res); 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef double (*F5)(double x, double y); 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa326) { 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 2418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(xmm0, Operand(esp, 1 * kPointerSize)); 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(xmm1, Operand(esp, 3 * kPointerSize)); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ addsd(xmm0, xmm1); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mulsd(xmm0, xmm1); 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ subsd(xmm0, xmm1); 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ divsd(xmm0, xmm1); 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Copy xmm0 to st(0) using eight bytes of stack. 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub(esp, Immediate(8)); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(Operand(esp, 0), xmm0); 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ fld_d(Operand(esp, 0)); 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add(esp, Immediate(8)); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("\n---\n"); 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // don't print the code - our disassembler can't handle SSE instructions 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instead print bytes 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Disassembler::Dump(stdout, 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code->instruction_start(), 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code->instruction_start() + code->instruction_size()); 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block F5 f = FUNCTION_CAST<F5>(code->entry()); 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block double res = f(2.2, 1.1); 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %f\n", res); 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(2.29 < res && res < 2.31); 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef double (*F6)(int x); 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa328) { 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 2838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, Operand(esp, 4)); 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cvtsi2sd(xmm0, eax); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Copy xmm0 to st(0) using eight bytes of stack. 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub(esp, Immediate(8)); 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(Operand(esp, 0), xmm0); 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ fld_d(Operand(esp, 0)); 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add(esp, Immediate(8)); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 3009fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block#ifdef OBJECT_PRINT 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F6 f = FUNCTION_CAST<F6>(code->entry()); 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block double res = f(12); 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::printf("f() = %f\n", res); 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(11.99 < res && res < 12.001); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef int (*F7)(double x, double y); 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AssemblerIa329) { 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::byte buffer[256]; 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler assm(isolate, buffer, sizeof buffer); 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 }; 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label equal_l, less_l, greater_l, nan_l; 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ fld_d(Operand(esp, 3 * kPointerSize)); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ fld_d(Operand(esp, 1 * kPointerSize)); 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ FCmp(); 325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ j(parity_even, &nan_l); 326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ j(equal, &equal_l); 327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ j(below, &less_l); 328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch __ j(above, &greater_l); 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, kUndefined); 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&equal_l); 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, kEqual); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&greater_l); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, kGreater); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&less_l); 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, kLess); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ bind(&nan_l); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ mov(eax, kNaN); 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ret(0); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assm.GetCode(&desc); 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 3549fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block#ifdef OBJECT_PRINT 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F7 f = FUNCTION_CAST<F7>(code->entry()); 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(kLess, f(1.1, 2.2)); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(kEqual, f(2.2, 2.2)); 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(kGreater, f(3.3, 2.2)); 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(kNaN, f(v8::base::OS::nan_value(), 1.1)); 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 36769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(AssemblerIa3210) { 36869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Test chaining of label usages within instructions (issue 1644). 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, NULL, 0); 37369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 37469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Label target; 37569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ j(equal, &target); 37669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ j(not_equal, &target); 37769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(&target); 37869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ nop(); 37969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 38069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(AssemblerMultiByteNop) { 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::internal::byte buffer[1024]; 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof(buffer)); 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(ebx); 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(ecx); 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(edx); 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(edi); 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(esi); 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(eax, 1); 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(ebx, 2); 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(ecx, 3); 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(edx, 4); 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(edi, 5); 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(esi, 6); 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < 16; i++) { 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int before = assm.pc_offset(); 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Nop(i); 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(assm.pc_offset() - before, i); 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label fail; 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cmp(eax, 1); 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ j(not_equal, &fail); 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cmp(ebx, 2); 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ j(not_equal, &fail); 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cmp(ecx, 3); 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ j(not_equal, &fail); 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cmp(edx, 4); 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ j(not_equal, &fail); 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cmp(edi, 5); 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ j(not_equal, &fail); 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cmp(esi, 6); 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ j(not_equal, &fail); 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(eax, 42); 4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(esi); 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(edi); 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(edx); 4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(ecx); 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(ebx); 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ret(0); 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&fail); 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(eax, 13); 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(esi); 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(edi); 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(edx); 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(ecx); 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(ebx); 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ret(0); 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeDesc desc; 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch assm.GetCode(&desc); 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(code->IsCode()); 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch F0 f = FUNCTION_CAST<F0>(code->entry()); 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int res = f(); 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(42, res); 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef __GNUC__ 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ELEMENT_COUNT 4 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(args[0]->IsArray()); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]); 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(ELEMENT_COUNT, vec->Length()); 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::byte buffer[256]; 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler assm(isolate, buffer, sizeof buffer); 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove return address from the stack for fix stack frame alignment. 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ pop(ecx); 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store input vector on the stack. 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < ELEMENT_COUNT; ++i) { 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(Immediate(vec->Get(i)->Int32Value())); 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Read vector into a xmm register. 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ pxor(xmm0, xmm0); 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movdqa(xmm0, Operand(esp, 0)); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create mask and store it in the return register. 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movmskps(eax, xmm0); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Remove unused data from the stack. 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(esp, Immediate(ELEMENT_COUNT * sizeof(int32_t))); 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore return address. 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(ecx); 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ret(0); 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F0 f = FUNCTION_CAST<F0>(code->entry()); 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int res = f(); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch args.GetReturnValue().Set(v8::Integer::New(CcTest::isolate(), res)); 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(StackAlignmentForSSE2) { 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, v8::base::OS::ActivationFrameAlignment() % 16); 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope handle_scope(isolate); 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> global_template = 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ObjectTemplate::New(isolate); 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template->Set(v8_str("do_sse2"), 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(isolate, DoSSE2)); 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env(NULL, global_template); 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun( 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(vec) {" 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return do_sse2(vec);" 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}"); 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Object> global_object = env->Global(); 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo"))); 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 }; 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT); 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < ELEMENT_COUNT; i++) { 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8_vec->Set(i, v8_num(vec[i])); 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Value> args[] = { v8_vec }; 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Value> result = foo->Call(global_object, 1, args); 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The mask should be 0b1000. 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(8, result->Int32Value()); 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ELEMENT_COUNT 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // __GNUC__ 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(AssemblerIa32Extractps) { 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CpuFeatures::IsSupported(SSE4_1)) return; 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::byte buffer[256]; 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler assm(isolate, buffer, sizeof buffer); 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { CpuFeatureScope fscope41(&assm, SSE4_1); 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movsd(xmm1, Operand(esp, 4)); 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ extractps(eax, xmm1, 0x1); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ret(0); 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef OBJECT_PRINT 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F4 f = FUNCTION_CAST<F4>(code->entry()); 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321); 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x12345678, f(uint64_to_double(value1))); 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678); 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0x87654321, f(uint64_to_double(value2))); 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef int (*F8)(float x, float y); 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(AssemblerIa32SSE) { 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::byte buffer[256]; 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler assm(isolate, buffer, sizeof buffer); 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movss(xmm0, Operand(esp, kPointerSize)); 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movss(xmm1, Operand(esp, 2 * kPointerSize)); 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ shufps(xmm0, xmm0, 0x0); 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ shufps(xmm1, xmm1, 0x0); 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movaps(xmm2, xmm1); 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ addps(xmm2, xmm0); 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mulps(xmm2, xmm1); 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ subps(xmm2, xmm0); 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ divps(xmm2, xmm1); 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ cvttss2si(eax, xmm2); 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ret(0); 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm.GetCode(&desc); 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = isolate->factory()->NewCode( 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef OBJECT_PRINT 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->Print(os); 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch F8 f = FUNCTION_CAST<F8>(code->entry()); 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, f(1.0, 2.0)); 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef __ 599