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

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

Issue 148503002: A64: Synchronize with r15545. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months 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-compare-nil-ic-stub.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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 using v8::internal::r9; 55 using v8::internal::r9;
56 using v8::internal::rax; 56 using v8::internal::rax;
57 using v8::internal::rbx; 57 using v8::internal::rbx;
58 using v8::internal::rbp; 58 using v8::internal::rbp;
59 using v8::internal::rcx; 59 using v8::internal::rcx;
60 using v8::internal::rdi; 60 using v8::internal::rdi;
61 using v8::internal::rdx; 61 using v8::internal::rdx;
62 using v8::internal::rsi; 62 using v8::internal::rsi;
63 using v8::internal::rsp; 63 using v8::internal::rsp;
64 using v8::internal::times_1; 64 using v8::internal::times_1;
65 using v8::internal::xmm0;
65 66
66 // Test the x64 assembler by compiling some simple functions into 67 // Test the x64 assembler by compiling some simple functions into
67 // a buffer and executing them. These tests do not initialize the 68 // a buffer and executing them. These tests do not initialize the
68 // V8 library, create a context, or use any V8 objects. 69 // V8 library, create a context, or use any V8 objects.
69 // The AMD64 calling convention is used, with the first six arguments 70 // The AMD64 calling convention is used, with the first six arguments
70 // in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in 71 // in RDI, RSI, RDX, RCX, R8, and R9, and floating point arguments in
71 // the XMM registers. The return value is in RAX. 72 // the XMM registers. The return value is in RAX.
72 // This calling convention is used on Linux, with GCC, and on Mac OS, 73 // This calling convention is used on Linux, with GCC, and on Mac OS,
73 // with GCC. A different convention is used on 64-bit windows, 74 // with GCC. A different convention is used on 64-bit windows,
74 // where the first four integer arguments are passed in RCX, RDX, R8 and R9. 75 // where the first four integer arguments are passed in RCX, RDX, R8 and R9.
(...skipping 28 matching lines...) Expand all
103 __ nop(); 104 __ nop();
104 __ ret(0); 105 __ ret(0);
105 106
106 CodeDesc desc; 107 CodeDesc desc;
107 assm.GetCode(&desc); 108 assm.GetCode(&desc);
108 // Call the function from C++. 109 // Call the function from C++.
109 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 110 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
110 CHECK_EQ(2, result); 111 CHECK_EQ(2, result);
111 } 112 }
112 113
114
113 TEST(AssemblerX64StackOperations) { 115 TEST(AssemblerX64StackOperations) {
114 OS::SetUp(); 116 OS::SetUp();
115 // Allocate an executable page of memory. 117 // Allocate an executable page of memory.
116 size_t actual_size; 118 size_t actual_size;
117 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 119 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
118 &actual_size, 120 &actual_size,
119 true)); 121 true));
120 CHECK(buffer); 122 CHECK(buffer);
121 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); 123 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
122 124
(...skipping 12 matching lines...) Expand all
135 __ nop(); 137 __ nop();
136 __ ret(0); 138 __ ret(0);
137 139
138 CodeDesc desc; 140 CodeDesc desc;
139 assm.GetCode(&desc); 141 assm.GetCode(&desc);
140 // Call the function from C++. 142 // Call the function from C++.
141 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 143 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
142 CHECK_EQ(2, result); 144 CHECK_EQ(2, result);
143 } 145 }
144 146
147
145 TEST(AssemblerX64ArithmeticOperations) { 148 TEST(AssemblerX64ArithmeticOperations) {
146 OS::SetUp(); 149 OS::SetUp();
147 // Allocate an executable page of memory. 150 // Allocate an executable page of memory.
148 size_t actual_size; 151 size_t actual_size;
149 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 152 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
150 &actual_size, 153 &actual_size,
151 true)); 154 true));
152 CHECK(buffer); 155 CHECK(buffer);
153 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); 156 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
154 157
155 // Assemble a simple function that adds arguments returning the sum. 158 // Assemble a simple function that adds arguments returning the sum.
156 __ movq(rax, arg2); 159 __ movq(rax, arg2);
157 __ addq(rax, arg1); 160 __ addq(rax, arg1);
158 __ ret(0); 161 __ ret(0);
159 162
160 CodeDesc desc; 163 CodeDesc desc;
161 assm.GetCode(&desc); 164 assm.GetCode(&desc);
162 // Call the function from C++. 165 // Call the function from C++.
163 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 166 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
164 CHECK_EQ(5, result); 167 CHECK_EQ(5, result);
165 } 168 }
166 169
170
167 TEST(AssemblerX64ImulOperation) { 171 TEST(AssemblerX64ImulOperation) {
168 OS::SetUp(); 172 OS::SetUp();
169 // Allocate an executable page of memory. 173 // Allocate an executable page of memory.
170 size_t actual_size; 174 size_t actual_size;
171 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 175 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
172 &actual_size, 176 &actual_size,
173 true)); 177 true));
174 CHECK(buffer); 178 CHECK(buffer);
175 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); 179 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
176 180
177 // Assemble a simple function that multiplies arguments returning the high 181 // Assemble a simple function that multiplies arguments returning the high
178 // word. 182 // word.
179 __ movq(rax, arg2); 183 __ movq(rax, arg2);
180 __ imul(arg1); 184 __ imul(arg1);
181 __ movq(rax, rdx); 185 __ movq(rax, rdx);
182 __ ret(0); 186 __ ret(0);
183 187
184 CodeDesc desc; 188 CodeDesc desc;
185 assm.GetCode(&desc); 189 assm.GetCode(&desc);
186 // Call the function from C++. 190 // Call the function from C++.
187 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 191 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
188 CHECK_EQ(0, result); 192 CHECK_EQ(0, result);
189 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l); 193 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l);
190 CHECK_EQ(1, result); 194 CHECK_EQ(1, result);
191 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l); 195 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l);
192 CHECK_EQ(-1, result); 196 CHECK_EQ(-1, result);
193 } 197 }
194 198
199
195 TEST(AssemblerX64MemoryOperands) { 200 TEST(AssemblerX64MemoryOperands) {
196 OS::SetUp(); 201 OS::SetUp();
197 // Allocate an executable page of memory. 202 // Allocate an executable page of memory.
198 size_t actual_size; 203 size_t actual_size;
199 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 204 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
200 &actual_size, 205 &actual_size,
201 true)); 206 true));
202 CHECK(buffer); 207 CHECK(buffer);
203 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); 208 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
204 209
(...skipping 14 matching lines...) Expand all
219 __ nop(); 224 __ nop();
220 __ ret(0); 225 __ ret(0);
221 226
222 CodeDesc desc; 227 CodeDesc desc;
223 assm.GetCode(&desc); 228 assm.GetCode(&desc);
224 // Call the function from C++. 229 // Call the function from C++.
225 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 230 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
226 CHECK_EQ(3, result); 231 CHECK_EQ(3, result);
227 } 232 }
228 233
234
229 TEST(AssemblerX64ControlFlow) { 235 TEST(AssemblerX64ControlFlow) {
230 OS::SetUp(); 236 OS::SetUp();
231 // Allocate an executable page of memory. 237 // Allocate an executable page of memory.
232 size_t actual_size; 238 size_t actual_size;
233 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 239 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
234 &actual_size, 240 &actual_size,
235 true)); 241 true));
236 CHECK(buffer); 242 CHECK(buffer);
237 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); 243 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
238 244
239 // Assemble a simple function that copies argument 1 and returns it. 245 // Assemble a simple function that copies argument 1 and returns it.
240 __ push(rbp); 246 __ push(rbp);
241 247
242 __ movq(rbp, rsp); 248 __ movq(rbp, rsp);
243 __ movq(rax, arg1); 249 __ movq(rax, arg1);
244 Label target; 250 Label target;
245 __ jmp(&target); 251 __ jmp(&target);
246 __ movq(rax, arg2); 252 __ movq(rax, arg2);
247 __ bind(&target); 253 __ bind(&target);
248 __ pop(rbp); 254 __ pop(rbp);
249 __ ret(0); 255 __ ret(0);
250 256
251 CodeDesc desc; 257 CodeDesc desc;
252 assm.GetCode(&desc); 258 assm.GetCode(&desc);
253 // Call the function from C++. 259 // Call the function from C++.
254 int result = FUNCTION_CAST<F2>(buffer)(3, 2); 260 int result = FUNCTION_CAST<F2>(buffer)(3, 2);
255 CHECK_EQ(3, result); 261 CHECK_EQ(3, result);
256 } 262 }
257 263
264
258 TEST(AssemblerX64LoopImmediates) { 265 TEST(AssemblerX64LoopImmediates) {
259 OS::SetUp(); 266 OS::SetUp();
260 // Allocate an executable page of memory. 267 // Allocate an executable page of memory.
261 size_t actual_size; 268 size_t actual_size;
262 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, 269 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
263 &actual_size, 270 &actual_size,
264 true)); 271 true));
265 CHECK(buffer); 272 CHECK(buffer);
266 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size)); 273 Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
267 // Assemble two loops using rax as counter, and verify the ending counts. 274 // Assemble two loops using rax as counter, and verify the ending counts.
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 Code::ComputeFlags(Code::STUB), 429 Code::ComputeFlags(Code::STUB),
423 v8::internal::Handle<Code>())->ToObjectChecked()); 430 v8::internal::Handle<Code>())->ToObjectChecked());
424 CHECK(code->IsCode()); 431 CHECK(code->IsCode());
425 432
426 F0 f = FUNCTION_CAST<F0>(code->entry()); 433 F0 f = FUNCTION_CAST<F0>(code->entry());
427 int res = f(); 434 int res = f();
428 CHECK_EQ(42, res); 435 CHECK_EQ(42, res);
429 } 436 }
430 437
431 438
439 #ifdef __GNUC__
440 #define ELEMENT_COUNT 4
441
442 void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
443 CcTest::InitializeVM();
444 v8::HandleScope scope(CcTest::isolate());
445 v8::internal::byte buffer[1024];
446
447 CHECK(args[0]->IsArray());
448 v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]);
449 CHECK_EQ(ELEMENT_COUNT, vec->Length());
450
451 Isolate* isolate = Isolate::Current();
452 Assembler assm(isolate, buffer, sizeof(buffer));
453
454 // Remove return address from the stack for fix stack frame alignment.
455 __ pop(rcx);
456
457 // Store input vector on the stack.
458 for (int i = 0; i < ELEMENT_COUNT; i++) {
459 __ movl(rax, Immediate(vec->Get(i)->Int32Value()));
460 __ shl(rax, Immediate(0x20));
461 __ or_(rax, Immediate(vec->Get(++i)->Int32Value()));
462 __ push(rax);
463 }
464
465 // Read vector into a xmm register.
466 __ xorps(xmm0, xmm0);
467 __ movdqa(xmm0, Operand(rsp, 0));
468 // Create mask and store it in the return register.
469 __ movmskps(rax, xmm0);
470
471 // Remove unused data from the stack.
472 __ addq(rsp, Immediate(ELEMENT_COUNT * sizeof(int32_t)));
473 // Restore return address.
474 __ push(rcx);
475
476 __ ret(0);
477
478 CodeDesc desc;
479 assm.GetCode(&desc);
480 Code* code = Code::cast(isolate->heap()->CreateCode(
481 desc,
482 Code::ComputeFlags(Code::STUB),
483 v8::internal::Handle<Code>())->ToObjectChecked());
484 CHECK(code->IsCode());
485
486 F0 f = FUNCTION_CAST<F0>(code->entry());
487 int res = f();
488 args.GetReturnValue().Set(v8::Integer::New(res));
489 }
490
491
492 TEST(StackAlignmentForSSE2) {
493 CHECK_EQ(0, OS::ActivationFrameAlignment() % 16);
494
495 v8::Isolate* isolate = v8::Isolate::GetCurrent();
496 v8::HandleScope handle_scope(isolate);
497 v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
498 global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(DoSSE2));
499
500 LocalContext env(NULL, global_template);
501 CompileRun(
502 "function foo(vec) {"
503 " return do_sse2(vec);"
504 "}");
505
506 v8::Local<v8::Object> global_object = env->Global();
507 v8::Local<v8::Function> foo =
508 v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo")));
509
510 int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 };
511 v8::Local<v8::Array> v8_vec = v8::Array::New(ELEMENT_COUNT);
512 for (int i = 0; i < ELEMENT_COUNT; i++) {
513 v8_vec->Set(i, v8_num(vec[i]));
514 }
515
516 v8::Local<v8::Value> args[] = { v8_vec };
517 v8::Local<v8::Value> result = foo->Call(global_object, 1, args);
518
519 // The mask should be 0b1000.
520 CHECK_EQ(8, result->Int32Value());
521 }
522
523 #undef ELEMENT_COUNT
524 #endif // __GNUC__
432 525
433 526
434 #undef __ 527 #undef __
OLDNEW
« no previous file with comments | « test/cctest/test-assembler-ia32.cc ('k') | test/cctest/test-compare-nil-ic-stub.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698