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