blob: d40156841ec071d7aecd1b2001e328919851af49 [file] [log] [blame]
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001// Copyright 2011 the V8 project authors. All rights reserved.
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdlib.h>
29
30#include "v8.h"
31
32#include "disassembler.h"
33#include "factory.h"
34#include "macro-assembler.h"
35#include "platform.h"
36#include "serialize.h"
37#include "cctest.h"
38
39using namespace v8::internal;
40
41
42typedef int (*F0)();
43typedef int (*F1)(int x);
44typedef int (*F2)(int x, int y);
45
46
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000047#define __ assm.
48
49TEST(AssemblerIa320) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000050 CcTest::InitializeVM();
51 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +000052 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000053
54 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +000055 Assembler assm(isolate, buffer, sizeof buffer);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000056
57 __ mov(eax, Operand(esp, 4));
58 __ add(eax, Operand(esp, 8));
59 __ ret(0);
60
61 CodeDesc desc;
62 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +000063 Object* code = isolate->heap()->CreateCode(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000064 desc,
65 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +000066 Handle<Code>())->ToObjectChecked();
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000067 CHECK(code->IsCode());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +000068#ifdef OBJECT_PRINT
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000069 Code::cast(code)->Print();
70#endif
71 F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
72 int res = f(3, 4);
73 ::printf("f() = %d\n", res);
74 CHECK_EQ(7, res);
75}
76
77
78TEST(AssemblerIa321) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000079 CcTest::InitializeVM();
80 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +000081 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000082
83 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +000084 Assembler assm(isolate, buffer, sizeof buffer);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000085 Label L, C;
86
87 __ mov(edx, Operand(esp, 4));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000088 __ xor_(eax, eax); // clear eax
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000089 __ jmp(&C);
90
91 __ bind(&L);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000092 __ add(eax, edx);
93 __ sub(edx, Immediate(1));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000094
95 __ bind(&C);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000096 __ test(edx, edx);
vegorov@chromium.org7304bca2011-05-16 12:14:13 +000097 __ j(not_zero, &L);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000098 __ ret(0);
99
100 CodeDesc desc;
101 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000102 Object* code = isolate->heap()->CreateCode(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000103 desc,
104 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000105 Handle<Code>())->ToObjectChecked();
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000106 CHECK(code->IsCode());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000107#ifdef OBJECT_PRINT
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000108 Code::cast(code)->Print();
109#endif
110 F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
111 int res = f(100);
112 ::printf("f() = %d\n", res);
113 CHECK_EQ(5050, res);
114}
115
116
117TEST(AssemblerIa322) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000118 CcTest::InitializeVM();
119 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000120 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000121
122 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000123 Assembler assm(isolate, buffer, sizeof buffer);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000124 Label L, C;
125
126 __ mov(edx, Operand(esp, 4));
127 __ mov(eax, 1);
128 __ jmp(&C);
129
130 __ bind(&L);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000131 __ imul(eax, edx);
132 __ sub(edx, Immediate(1));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000133
134 __ bind(&C);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000135 __ test(edx, edx);
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000136 __ j(not_zero, &L);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000137 __ ret(0);
138
139 // some relocated stuff here, not executed
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000140 __ mov(eax, isolate->factory()->true_value());
ager@chromium.org236ad962008-09-25 09:45:57 +0000141 __ jmp(NULL, RelocInfo::RUNTIME_ENTRY);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000142
143 CodeDesc desc;
144 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000145 Object* code = isolate->heap()->CreateCode(
lrn@chromium.org303ada72010-10-27 09:33:13 +0000146 desc,
147 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000148 Handle<Code>())->ToObjectChecked();
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000149 CHECK(code->IsCode());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000150#ifdef OBJECT_PRINT
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000151 Code::cast(code)->Print();
152#endif
153 F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
154 int res = f(10);
155 ::printf("f() = %d\n", res);
156 CHECK_EQ(3628800, res);
157}
158
159
160typedef int (*F3)(float x);
161
162TEST(AssemblerIa323) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000163 CcTest::InitializeVM();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000164 if (!CpuFeatures::IsSupported(SSE2)) return;
165
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000166 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000167 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000168
169 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000170 Assembler assm(isolate, buffer, sizeof buffer);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000171
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000172 CHECK(CpuFeatures::IsSupported(SSE2));
ulan@chromium.org750145a2013-03-07 15:14:13 +0000173 { CpuFeatureScope fscope(&assm, SSE2);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000174 __ cvttss2si(eax, Operand(esp, 4));
175 __ ret(0);
176 }
177
178 CodeDesc desc;
179 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000180 Code* code = Code::cast(isolate->heap()->CreateCode(
lrn@chromium.org303ada72010-10-27 09:33:13 +0000181 desc,
182 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000183 Handle<Code>())->ToObjectChecked());
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000184 // don't print the code - our disassembler can't handle cvttss2si
185 // instead print bytes
186 Disassembler::Dump(stdout,
187 code->instruction_start(),
188 code->instruction_start() + code->instruction_size());
189 F3 f = FUNCTION_CAST<F3>(code->entry());
190 int res = f(static_cast<float>(-3.1415));
191 ::printf("f() = %d\n", res);
192 CHECK_EQ(-3, res);
193}
194
195
196typedef int (*F4)(double x);
197
198TEST(AssemblerIa324) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000199 CcTest::InitializeVM();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000200 if (!CpuFeatures::IsSupported(SSE2)) return;
201
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000202 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000203 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000204
205 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000206 Assembler assm(isolate, buffer, sizeof buffer);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000207
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000208 CHECK(CpuFeatures::IsSupported(SSE2));
ulan@chromium.org750145a2013-03-07 15:14:13 +0000209 CpuFeatureScope fscope(&assm, SSE2);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000210 __ cvttsd2si(eax, Operand(esp, 4));
211 __ ret(0);
212
213 CodeDesc desc;
214 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000215 Code* code = Code::cast(isolate->heap()->CreateCode(
lrn@chromium.org303ada72010-10-27 09:33:13 +0000216 desc,
217 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000218 Handle<Code>())->ToObjectChecked());
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000219 // don't print the code - our disassembler can't handle cvttsd2si
220 // instead print bytes
221 Disassembler::Dump(stdout,
222 code->instruction_start(),
223 code->instruction_start() + code->instruction_size());
224 F4 f = FUNCTION_CAST<F4>(code->entry());
225 int res = f(2.718281828);
226 ::printf("f() = %d\n", res);
227 CHECK_EQ(2, res);
228}
229
230
231static int baz = 42;
232TEST(AssemblerIa325) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000233 CcTest::InitializeVM();
234 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000235 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000236
237 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000238 Assembler assm(isolate, buffer, sizeof buffer);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000239
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000240 __ mov(eax, Operand(reinterpret_cast<intptr_t>(&baz), RelocInfo::NONE32));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000241 __ ret(0);
242
243 CodeDesc desc;
244 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000245 Code* code = Code::cast(isolate->heap()->CreateCode(
lrn@chromium.org303ada72010-10-27 09:33:13 +0000246 desc,
247 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000248 Handle<Code>())->ToObjectChecked());
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000249 F0 f = FUNCTION_CAST<F0>(code->entry());
250 int res = f();
251 CHECK_EQ(42, res);
252}
253
254
255typedef double (*F5)(double x, double y);
256
257TEST(AssemblerIa326) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000258 CcTest::InitializeVM();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000259 if (!CpuFeatures::IsSupported(SSE2)) return;
260
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000261 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000262 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000263 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000264 Assembler assm(isolate, buffer, sizeof buffer);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000265
ulan@chromium.org750145a2013-03-07 15:14:13 +0000266 CpuFeatureScope fscope(&assm, SSE2);
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +0000267 __ movsd(xmm0, Operand(esp, 1 * kPointerSize));
268 __ movsd(xmm1, Operand(esp, 3 * kPointerSize));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000269 __ addsd(xmm0, xmm1);
270 __ mulsd(xmm0, xmm1);
271 __ subsd(xmm0, xmm1);
272 __ divsd(xmm0, xmm1);
273 // Copy xmm0 to st(0) using eight bytes of stack.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000274 __ sub(esp, Immediate(8));
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +0000275 __ movsd(Operand(esp, 0), xmm0);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000276 __ fld_d(Operand(esp, 0));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000277 __ add(esp, Immediate(8));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000278 __ ret(0);
279
280 CodeDesc desc;
281 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000282 Code* code = Code::cast(isolate->heap()->CreateCode(
lrn@chromium.org303ada72010-10-27 09:33:13 +0000283 desc,
284 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000285 Handle<Code>())->ToObjectChecked());
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000286#ifdef DEBUG
287 ::printf("\n---\n");
288 // don't print the code - our disassembler can't handle SSE instructions
289 // instead print bytes
290 Disassembler::Dump(stdout,
291 code->instruction_start(),
292 code->instruction_start() + code->instruction_size());
293#endif
294 F5 f = FUNCTION_CAST<F5>(code->entry());
295 double res = f(2.2, 1.1);
296 ::printf("f() = %f\n", res);
297 CHECK(2.29 < res && res < 2.31);
298}
299
300
301typedef double (*F6)(int x);
302
303TEST(AssemblerIa328) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000304 CcTest::InitializeVM();
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000305 if (!CpuFeatures::IsSupported(SSE2)) return;
306
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000307 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000308 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000309 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000310 Assembler assm(isolate, buffer, sizeof buffer);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000311 CpuFeatureScope fscope(&assm, SSE2);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000312 __ mov(eax, Operand(esp, 4));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000313 __ cvtsi2sd(xmm0, eax);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000314 // Copy xmm0 to st(0) using eight bytes of stack.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000315 __ sub(esp, Immediate(8));
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +0000316 __ movsd(Operand(esp, 0), xmm0);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000317 __ fld_d(Operand(esp, 0));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000318 __ add(esp, Immediate(8));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000319 __ ret(0);
320 CodeDesc desc;
321 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000322 Code* code = Code::cast(isolate->heap()->CreateCode(
lrn@chromium.org303ada72010-10-27 09:33:13 +0000323 desc,
324 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000325 Handle<Code>())->ToObjectChecked());
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000326 CHECK(code->IsCode());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000327#ifdef OBJECT_PRINT
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000328 Code::cast(code)->Print();
329#endif
330 F6 f = FUNCTION_CAST<F6>(Code::cast(code)->entry());
331 double res = f(12);
332
333 ::printf("f() = %f\n", res);
334 CHECK(11.99 < res && res < 12.001);
335}
336
337
338typedef int (*F7)(double x, double y);
339
340TEST(AssemblerIa329) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000341 CcTest::InitializeVM();
342 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000343 HandleScope scope(isolate);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000344 v8::internal::byte buffer[256];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000345 MacroAssembler assm(isolate, buffer, sizeof buffer);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000346 enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 };
347 Label equal_l, less_l, greater_l, nan_l;
348 __ fld_d(Operand(esp, 3 * kPointerSize));
349 __ fld_d(Operand(esp, 1 * kPointerSize));
350 __ FCmp();
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000351 __ j(parity_even, &nan_l);
352 __ j(equal, &equal_l);
353 __ j(below, &less_l);
354 __ j(above, &greater_l);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000355
356 __ mov(eax, kUndefined);
357 __ ret(0);
358
359 __ bind(&equal_l);
360 __ mov(eax, kEqual);
361 __ ret(0);
362
363 __ bind(&greater_l);
364 __ mov(eax, kGreater);
365 __ ret(0);
366
367 __ bind(&less_l);
368 __ mov(eax, kLess);
369 __ ret(0);
370
371 __ bind(&nan_l);
372 __ mov(eax, kNaN);
373 __ ret(0);
374
375
376 CodeDesc desc;
377 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000378 Code* code = Code::cast(isolate->heap()->CreateCode(
lrn@chromium.org303ada72010-10-27 09:33:13 +0000379 desc,
380 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000381 Handle<Code>())->ToObjectChecked());
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000382 CHECK(code->IsCode());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000383#ifdef OBJECT_PRINT
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000384 Code::cast(code)->Print();
385#endif
386
387 F7 f = FUNCTION_CAST<F7>(Code::cast(code)->entry());
388 CHECK_EQ(kLess, f(1.1, 2.2));
389 CHECK_EQ(kEqual, f(2.2, 2.2));
390 CHECK_EQ(kGreater, f(3.3, 2.2));
391 CHECK_EQ(kNaN, f(OS::nan_value(), 1.1));
392}
393
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000394
395TEST(AssemblerIa3210) {
396 // Test chaining of label usages within instructions (issue 1644).
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000397 CcTest::InitializeVM();
398 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000399 HandleScope scope(isolate);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000400 Assembler assm(isolate, NULL, 0);
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000401
402 Label target;
403 __ j(equal, &target);
404 __ j(not_equal, &target);
405 __ bind(&target);
406 __ nop();
407}
408
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000409
410TEST(AssemblerMultiByteNop) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000411 CcTest::InitializeVM();
412 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000413 HandleScope scope(isolate);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000414 v8::internal::byte buffer[1024];
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000415 Assembler assm(isolate, buffer, sizeof(buffer));
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000416 __ push(ebx);
417 __ push(ecx);
418 __ push(edx);
419 __ push(edi);
420 __ push(esi);
421 __ mov(eax, 1);
422 __ mov(ebx, 2);
423 __ mov(ecx, 3);
424 __ mov(edx, 4);
425 __ mov(edi, 5);
426 __ mov(esi, 6);
427 for (int i = 0; i < 16; i++) {
428 int before = assm.pc_offset();
429 __ Nop(i);
430 CHECK_EQ(assm.pc_offset() - before, i);
431 }
432
433 Label fail;
434 __ cmp(eax, 1);
435 __ j(not_equal, &fail);
436 __ cmp(ebx, 2);
437 __ j(not_equal, &fail);
438 __ cmp(ecx, 3);
439 __ j(not_equal, &fail);
440 __ cmp(edx, 4);
441 __ j(not_equal, &fail);
442 __ cmp(edi, 5);
443 __ j(not_equal, &fail);
444 __ cmp(esi, 6);
445 __ j(not_equal, &fail);
446 __ mov(eax, 42);
447 __ pop(esi);
448 __ pop(edi);
449 __ pop(edx);
450 __ pop(ecx);
451 __ pop(ebx);
452 __ ret(0);
453 __ bind(&fail);
454 __ mov(eax, 13);
455 __ pop(esi);
456 __ pop(edi);
457 __ pop(edx);
458 __ pop(ecx);
459 __ pop(ebx);
460 __ ret(0);
461
462 CodeDesc desc;
463 assm.GetCode(&desc);
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000464 Code* code = Code::cast(isolate->heap()->CreateCode(
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000465 desc,
466 Code::ComputeFlags(Code::STUB),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000467 Handle<Code>())->ToObjectChecked());
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000468 CHECK(code->IsCode());
469
470 F0 f = FUNCTION_CAST<F0>(code->entry());
471 int res = f();
472 CHECK_EQ(42, res);
473}
474
475
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000476#ifdef __GNUC__
477#define ELEMENT_COUNT 4
478
479void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
480 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
481 HandleScope scope(isolate);
482
483 CHECK(args[0]->IsArray());
484 v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]);
485 CHECK_EQ(ELEMENT_COUNT, vec->Length());
486
487 v8::internal::byte buffer[256];
488 Assembler assm(isolate, buffer, sizeof buffer);
489
490 ASSERT(CpuFeatures::IsSupported(SSE2));
491 CpuFeatureScope fscope(&assm, SSE2);
492
493 // Remove return address from the stack for fix stack frame alignment.
494 __ pop(ecx);
495
496 // Store input vector on the stack.
497 for (int i = 0; i < ELEMENT_COUNT; ++i) {
498 __ push(Immediate(vec->Get(i)->Int32Value()));
499 }
500
501 // Read vector into a xmm register.
502 __ pxor(xmm0, xmm0);
503 __ movdqa(xmm0, Operand(esp, 0));
504 // Create mask and store it in the return register.
505 __ movmskps(eax, xmm0);
506
507 // Remove unused data from the stack.
508 __ add(esp, Immediate(ELEMENT_COUNT * sizeof(int32_t)));
509 // Restore return address.
510 __ push(ecx);
511
512 __ ret(0);
513
514 CodeDesc desc;
515 assm.GetCode(&desc);
516
517 Object* code = isolate->heap()->CreateCode(
518 desc,
519 Code::ComputeFlags(Code::STUB),
520 Handle<Code>())->ToObjectChecked();
521 CHECK(code->IsCode());
522
523 F0 f = FUNCTION_CAST<F0>(Code::cast(code)->entry());
524 int res = f();
525 args.GetReturnValue().Set(v8::Integer::New(res));
526}
527
528
529TEST(StackAlignmentForSSE2) {
530 CcTest::InitializeVM();
531 if (!CpuFeatures::IsSupported(SSE2)) return;
532
533 CHECK_EQ(0, OS::ActivationFrameAlignment() % 16);
534
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000535 v8::Isolate* isolate = CcTest::isolate();
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000536 v8::HandleScope handle_scope(isolate);
537 v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
538 global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(DoSSE2));
539
540 LocalContext env(NULL, global_template);
541 CompileRun(
542 "function foo(vec) {"
543 " return do_sse2(vec);"
544 "}");
545
546 v8::Local<v8::Object> global_object = env->Global();
547 v8::Local<v8::Function> foo =
548 v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo")));
549
550 int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 };
551 v8::Local<v8::Array> v8_vec = v8::Array::New(ELEMENT_COUNT);
552 for (int i = 0; i < ELEMENT_COUNT; i++) {
553 v8_vec->Set(i, v8_num(vec[i]));
554 }
555
556 v8::Local<v8::Value> args[] = { v8_vec };
557 v8::Local<v8::Value> result = foo->Call(global_object, 1, args);
558
559 // The mask should be 0b1000.
560 CHECK_EQ(8, result->Int32Value());
561}
562
563#undef ELEMENT_COUNT
564#endif // __GNUC__
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000565
566
mstarzinger@chromium.orgb4968be2013-10-16 09:00:56 +0000567TEST(AssemblerIa32Extractps) {
568 CcTest::InitializeVM();
569 if (!CpuFeatures::IsSupported(SSE2) ||
570 !CpuFeatures::IsSupported(SSE4_1)) return;
571
572 Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
573 HandleScope scope(isolate);
574 v8::internal::byte buffer[256];
575 MacroAssembler assm(isolate, buffer, sizeof buffer);
576 { CpuFeatureScope fscope2(&assm, SSE2);
577 CpuFeatureScope fscope41(&assm, SSE4_1);
bmeurer@chromium.org0fdb2a62013-10-21 07:19:36 +0000578 __ movsd(xmm1, Operand(esp, 4));
mstarzinger@chromium.orgb4968be2013-10-16 09:00:56 +0000579 __ extractps(eax, xmm1, 0x1);
580 __ ret(0);
581 }
582
583 CodeDesc desc;
584 assm.GetCode(&desc);
585 Code* code = Code::cast(isolate->heap()->CreateCode(
586 desc,
587 Code::ComputeFlags(Code::STUB),
588 Handle<Code>())->ToObjectChecked());
589 CHECK(code->IsCode());
590#ifdef OBJECT_PRINT
591 Code::cast(code)->Print();
592#endif
593
594 F4 f = FUNCTION_CAST<F4>(Code::cast(code)->entry());
595 uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321);
596 CHECK_EQ(0x12345678, f(uint64_to_double(value1)));
597 uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678);
598 CHECK_EQ(0x87654321, f(uint64_to_double(value2)));
599}
600
601
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000602#undef __