Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: test/cctest/test-assembler-x64.cc

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-assembler-ia32.cc ('k') | test/cctest/test-ast.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 17 matching lines...) Expand all
28 #include <stdlib.h> 28 #include <stdlib.h>
29 29
30 #include "v8.h" 30 #include "v8.h"
31 31
32 #include "macro-assembler.h" 32 #include "macro-assembler.h"
33 #include "factory.h" 33 #include "factory.h"
34 #include "platform.h" 34 #include "platform.h"
35 #include "serialize.h" 35 #include "serialize.h"
36 #include "cctest.h" 36 #include "cctest.h"
37 37
38 using v8::internal::Assembler; 38 using namespace v8::internal;
39 using v8::internal::Code;
40 using v8::internal::CodeDesc;
41 using v8::internal::FUNCTION_CAST;
42 using v8::internal::Immediate;
43 using v8::internal::Isolate;
44 using v8::internal::Label;
45 using v8::internal::OS;
46 using v8::internal::Operand;
47 using v8::internal::byte;
48 using v8::internal::greater;
49 using v8::internal::less_equal;
50 using v8::internal::equal;
51 using v8::internal::not_equal;
52 using v8::internal::r13;
53 using v8::internal::r15;
54 using v8::internal::r8;
55 using v8::internal::r9;
56 using v8::internal::rax;
57 using v8::internal::rbx;
58 using v8::internal::rbp;
59 using v8::internal::rcx;
60 using v8::internal::rdi;
61 using v8::internal::rdx;
62 using v8::internal::rsi;
63 using v8::internal::rsp;
64 using v8::internal::times_1;
65 using v8::internal::xmm0;
66 39
67 // Test the x64 assembler by compiling some simple functions into 40 // Test the x64 assembler by compiling some simple functions into
68 // a buffer and executing them. These tests do not initialize the 41 // a buffer and executing them. These tests do not initialize the
69 // V8 library, create a context, or use any V8 objects. 42 // V8 library, create a context, or use any V8 objects.
70 // The AMD64 calling convention is used, with the first six arguments 43 // The AMD64 calling convention is used, with the first six arguments
71 // in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in 44 // in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in
72 // the XMM registers. The return value is in RAX. 45 // the XMM registers. The return value is in RAX.
73 // This calling convention is used on Linux, with GCC, and on Mac OS, 46 // This calling convention is used on Linux, with GCC, and on Mac OS,
74 // with GCC. A different convention is used on 64-bit windows, 47 // with GCC. A different convention is used on 64-bit windows,
75 // where the first four integer arguments are passed in RCX, RDX, R8 and R9. 48 // where the first four integer arguments are passed in RCX, RDX, R8 and R9.
76 49
77 typedef int (*F0)(); 50 typedef int (*F0)();
78 typedef int (*F1)(int64_t x); 51 typedef int (*F1)(int64_t x);
79 typedef int (*F2)(int64_t x, int64_t y); 52 typedef int (*F2)(int64_t x, int64_t y);
53 typedef int (*F3)(double x);
54 typedef int64_t (*F4)(int64_t* x, int64_t* y);
55 typedef int64_t (*F5)(int64_t x);
80 56
81 #ifdef _WIN64 57 #ifdef _WIN64
82 static const v8::internal::Register arg1 = rcx; 58 static const Register arg1 = rcx;
83 static const v8::internal::Register arg2 = rdx; 59 static const Register arg2 = rdx;
84 #else 60 #else
85 static const v8::internal::Register arg1 = rdi; 61 static const Register arg1 = rdi;
86 static const v8::internal::Register arg2 = rsi; 62 static const Register arg2 = rsi;
87 #endif 63 #endif
88 64
89 #define __ assm. 65 #define __ assm.
90 66
91 67
92 TEST(AssemblerX64ReturnOperation) { 68 TEST(AssemblerX64ReturnOperation) {
93 // Allocate an executable page of memory. 69 // Allocate an executable page of memory.
94 size_t actual_size; 70 size_t actual_size;
95 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 71 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
96 &actual_size, 72 &actual_size,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 // Call the function from C++. 162 // Call the function from C++.
187 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 163 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
188 CHECK_EQ(0, result); 164 CHECK_EQ(0, result);
189 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l); 165 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l);
190 CHECK_EQ(1, result); 166 CHECK_EQ(1, result);
191 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l); 167 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l);
192 CHECK_EQ(-1, result); 168 CHECK_EQ(-1, result);
193 } 169 }
194 170
195 171
172 TEST(AssemblerX64XchglOperations) {
173 // Allocate an executable page of memory.
174 size_t actual_size;
175 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
176 &actual_size,
177 true));
178 CHECK(buffer);
179 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
180
181 __ movq(rax, Operand(arg1, 0));
182 __ movq(rbx, Operand(arg2, 0));
183 __ xchgl(rax, rbx);
184 __ movq(Operand(arg1, 0), rax);
185 __ movq(Operand(arg2, 0), rbx);
186 __ ret(0);
187
188 CodeDesc desc;
189 assm.GetCode(&desc);
190 // Call the function from C++.
191 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
192 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000);
193 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
194 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 40000000), left);
195 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 20000000), right);
196 USE(result);
197 }
198
199
200 TEST(AssemblerX64OrlOperations) {
201 // Allocate an executable page of memory.
202 size_t actual_size;
203 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
204 &actual_size,
205 true));
206 CHECK(buffer);
207 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
208
209 __ movq(rax, Operand(arg2, 0));
210 __ orl(Operand(arg1, 0), rax);
211 __ ret(0);
212
213 CodeDesc desc;
214 assm.GetCode(&desc);
215 // Call the function from C++.
216 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
217 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000);
218 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
219 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 60000000), left);
220 USE(result);
221 }
222
223
224 TEST(AssemblerX64RollOperations) {
225 // Allocate an executable page of memory.
226 size_t actual_size;
227 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
228 &actual_size,
229 true));
230 CHECK(buffer);
231 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
232
233 __ movq(rax, arg1);
234 __ roll(rax, Immediate(1));
235 __ ret(0);
236
237 CodeDesc desc;
238 assm.GetCode(&desc);
239 // Call the function from C++.
240 int64_t src = V8_2PART_UINT64_C(0x10000000, C0000000);
241 int64_t result = FUNCTION_CAST<F5>(buffer)(src);
242 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 80000001), result);
243 }
244
245
246 TEST(AssemblerX64SublOperations) {
247 // Allocate an executable page of memory.
248 size_t actual_size;
249 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
250 &actual_size,
251 true));
252 CHECK(buffer);
253 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
254
255 __ movq(rax, Operand(arg2, 0));
256 __ subl(Operand(arg1, 0), rax);
257 __ ret(0);
258
259 CodeDesc desc;
260 assm.GetCode(&desc);
261 // Call the function from C++.
262 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
263 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000);
264 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
265 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, e0000000), left);
266 USE(result);
267 }
268
269
270 TEST(AssemblerX64TestlOperations) {
271 // Allocate an executable page of memory.
272 size_t actual_size;
273 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
274 &actual_size,
275 true));
276 CHECK(buffer);
277 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
278
279 // Set rax with the ZF flag of the testl instruction.
280 Label done;
281 __ movq(rax, Immediate(1));
282 __ movq(rbx, Operand(arg2, 0));
283 __ testl(Operand(arg1, 0), rbx);
284 __ j(zero, &done, Label::kNear);
285 __ movq(rax, Immediate(0));
286 __ bind(&done);
287 __ ret(0);
288
289 CodeDesc desc;
290 assm.GetCode(&desc);
291 // Call the function from C++.
292 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
293 int64_t right = V8_2PART_UINT64_C(0x30000000, 00000000);
294 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
295 CHECK_EQ(static_cast<int64_t>(1), result);
296 }
297
298
299 TEST(AssemblerX64XorlOperations) {
300 // Allocate an executable page of memory.
301 size_t actual_size;
302 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
303 &actual_size,
304 true));
305 CHECK(buffer);
306 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
307
308 __ movq(rax, Operand(arg2, 0));
309 __ xorl(Operand(arg1, 0), rax);
310 __ ret(0);
311
312 CodeDesc desc;
313 assm.GetCode(&desc);
314 // Call the function from C++.
315 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000);
316 int64_t right = V8_2PART_UINT64_C(0x30000000, 60000000);
317 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right);
318 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 40000000), left);
319 USE(result);
320 }
321
322
196 TEST(AssemblerX64MemoryOperands) { 323 TEST(AssemblerX64MemoryOperands) {
197 // Allocate an executable page of memory. 324 // Allocate an executable page of memory.
198 size_t actual_size; 325 size_t actual_size;
199 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 326 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
200 &actual_size, 327 &actual_size,
201 true)); 328 true));
202 CHECK(buffer); 329 CHECK(buffer);
203 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); 330 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
204 331
205 // Assemble a simple function that copies argument 2 and returns it. 332 // Assemble a simple function that copies argument 2 and returns it.
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 __ j(equal, &target); 486 __ j(equal, &target);
360 __ j(not_equal, &target); 487 __ j(not_equal, &target);
361 __ bind(&target); 488 __ bind(&target);
362 __ nop(); 489 __ nop();
363 } 490 }
364 491
365 492
366 TEST(AssemblerMultiByteNop) { 493 TEST(AssemblerMultiByteNop) {
367 CcTest::InitializeVM(); 494 CcTest::InitializeVM();
368 v8::HandleScope scope(CcTest::isolate()); 495 v8::HandleScope scope(CcTest::isolate());
369 v8::internal::byte buffer[1024]; 496 byte buffer[1024];
370 Isolate* isolate = CcTest::i_isolate(); 497 Isolate* isolate = CcTest::i_isolate();
371 Assembler assm(isolate, buffer, sizeof(buffer)); 498 Assembler assm(isolate, buffer, sizeof(buffer));
372 __ push(rbx); 499 __ push(rbx);
373 __ push(rcx); 500 __ push(rcx);
374 __ push(rdx); 501 __ push(rdx);
375 __ push(rdi); 502 __ push(rdi);
376 __ push(rsi); 503 __ push(rsi);
377 __ movq(rax, Immediate(1)); 504 __ movq(rax, Immediate(1));
378 __ movq(rbx, Immediate(2)); 505 __ movq(rbx, Immediate(2));
379 __ movq(rcx, Immediate(3)); 506 __ movq(rcx, Immediate(3));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 __ pop(rdx); 540 __ pop(rdx);
414 __ pop(rcx); 541 __ pop(rcx);
415 __ pop(rbx); 542 __ pop(rbx);
416 __ ret(0); 543 __ ret(0);
417 544
418 CodeDesc desc; 545 CodeDesc desc;
419 assm.GetCode(&desc); 546 assm.GetCode(&desc);
420 Code* code = Code::cast(isolate->heap()->CreateCode( 547 Code* code = Code::cast(isolate->heap()->CreateCode(
421 desc, 548 desc,
422 Code::ComputeFlags(Code::STUB), 549 Code::ComputeFlags(Code::STUB),
423 v8::internal::Handle<Code>())->ToObjectChecked()); 550 Handle<Code>())->ToObjectChecked());
424 CHECK(code->IsCode()); 551 CHECK(code->IsCode());
425 552
426 F0 f = FUNCTION_CAST<F0>(code->entry()); 553 F0 f = FUNCTION_CAST<F0>(code->entry());
427 int res = f(); 554 int res = f();
428 CHECK_EQ(42, res); 555 CHECK_EQ(42, res);
429 } 556 }
430 557
431 558
432 #ifdef __GNUC__ 559 #ifdef __GNUC__
433 #define ELEMENT_COUNT 4 560 #define ELEMENT_COUNT 4
434 561
435 void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { 562 void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
436 v8::HandleScope scope(CcTest::isolate()); 563 v8::HandleScope scope(CcTest::isolate());
437 v8::internal::byte buffer[1024]; 564 byte buffer[1024];
438 565
439 CHECK(args[0]->IsArray()); 566 CHECK(args[0]->IsArray());
440 v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]); 567 v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]);
441 CHECK_EQ(ELEMENT_COUNT, vec->Length()); 568 CHECK_EQ(ELEMENT_COUNT, vec->Length());
442 569
443 Isolate* isolate = CcTest::i_isolate(); 570 Isolate* isolate = CcTest::i_isolate();
444 Assembler assm(isolate, buffer, sizeof(buffer)); 571 Assembler assm(isolate, buffer, sizeof(buffer));
445 572
446 // Remove return address from the stack for fix stack frame alignment. 573 // Remove return address from the stack for fix stack frame alignment.
447 __ pop(rcx); 574 __ pop(rcx);
(...skipping 17 matching lines...) Expand all
465 // Restore return address. 592 // Restore return address.
466 __ push(rcx); 593 __ push(rcx);
467 594
468 __ ret(0); 595 __ ret(0);
469 596
470 CodeDesc desc; 597 CodeDesc desc;
471 assm.GetCode(&desc); 598 assm.GetCode(&desc);
472 Code* code = Code::cast(isolate->heap()->CreateCode( 599 Code* code = Code::cast(isolate->heap()->CreateCode(
473 desc, 600 desc,
474 Code::ComputeFlags(Code::STUB), 601 Code::ComputeFlags(Code::STUB),
475 v8::internal::Handle<Code>())->ToObjectChecked()); 602 Handle<Code>())->ToObjectChecked());
476 CHECK(code->IsCode()); 603 CHECK(code->IsCode());
477 604
478 F0 f = FUNCTION_CAST<F0>(code->entry()); 605 F0 f = FUNCTION_CAST<F0>(code->entry());
479 int res = f(); 606 int res = f();
480 args.GetReturnValue().Set(v8::Integer::New(res)); 607 args.GetReturnValue().Set(v8::Integer::New(res));
481 } 608 }
482 609
483 610
484 TEST(StackAlignmentForSSE2) { 611 TEST(StackAlignmentForSSE2) {
485 CcTest::InitializeVM(); 612 CcTest::InitializeVM();
(...skipping 24 matching lines...) Expand all
510 v8::Local<v8::Value> result = foo->Call(global_object, 1, args); 637 v8::Local<v8::Value> result = foo->Call(global_object, 1, args);
511 638
512 // The mask should be 0b1000. 639 // The mask should be 0b1000.
513 CHECK_EQ(8, result->Int32Value()); 640 CHECK_EQ(8, result->Int32Value());
514 } 641 }
515 642
516 #undef ELEMENT_COUNT 643 #undef ELEMENT_COUNT
517 #endif // __GNUC__ 644 #endif // __GNUC__
518 645
519 646
647 TEST(AssemblerX64Extractps) {
648 CcTest::InitializeVM();
649 if (!CpuFeatures::IsSupported(SSE4_1)) return;
650
651 v8::HandleScope scope(CcTest::isolate());
652 byte buffer[256];
653 Isolate* isolate = CcTest::i_isolate();
654 Assembler assm(isolate, buffer, sizeof(buffer));
655 { CpuFeatureScope fscope2(&assm, SSE4_1);
656 __ extractps(rax, xmm0, 0x1);
657 __ ret(0);
658 }
659
660 CodeDesc desc;
661 assm.GetCode(&desc);
662 Code* code = Code::cast(isolate->heap()->CreateCode(
663 desc,
664 Code::ComputeFlags(Code::STUB),
665 Handle<Code>())->ToObjectChecked());
666 CHECK(code->IsCode());
667 #ifdef OBJECT_PRINT
668 Code::cast(code)->Print();
669 #endif
670
671 F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
672 uint64_t value1 = V8_2PART_UINT64_C(0x12345678, 87654321);
673 CHECK_EQ(0x12345678, f(uint64_to_double(value1)));
674 uint64_t value2 = V8_2PART_UINT64_C(0x87654321, 12345678);
675 CHECK_EQ(0x87654321, f(uint64_to_double(value2)));
676 }
677
678
520 #undef __ 679 #undef __
OLDNEW
« no previous file with comments | « test/cctest/test-assembler-ia32.cc ('k') | test/cctest/test-ast.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698