Revision f230a1cf deps/v8/test/cctest/test-assembler-x64.cc

View differences:

deps/v8/test/cctest/test-assembler-x64.cc
35 35
#include "serialize.h"
36 36
#include "cctest.h"
37 37

  
38
using v8::internal::Assembler;
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;
38
using namespace v8::internal;
66 39

  
67 40
// Test the x64 assembler by compiling some simple functions into
68 41
// a buffer and executing them.  These tests do not initialize the
......
77 50
typedef int (*F0)();
78 51
typedef int (*F1)(int64_t x);
79 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 57
#ifdef _WIN64
82
static const v8::internal::Register arg1 = rcx;
83
static const v8::internal::Register arg2 = rdx;
58
static const Register arg1 = rcx;
59
static const Register arg2 = rdx;
84 60
#else
85
static const v8::internal::Register arg1 = rdi;
86
static const v8::internal::Register arg2 = rsi;
61
static const Register arg1 = rdi;
62
static const Register arg2 = rsi;
87 63
#endif
88 64

  
89 65
#define __ assm.
......
96 72
                                                 &actual_size,
97 73
                                                 true));
98 74
  CHECK(buffer);
99
  Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
75
  Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
100 76

  
101 77
  // Assemble a simple function that copies argument 2 and returns it.
102 78
  __ movq(rax, arg2);
......
118 94
                                                 &actual_size,
119 95
                                                 true));
120 96
  CHECK(buffer);
121
  Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
97
  Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
122 98

  
123 99
  // Assemble a simple function that copies argument 2 and returns it.
124 100
  // We compile without stack frame pointers, so the gdb debugger shows
......
150 126
                                                 &actual_size,
151 127
                                                 true));
152 128
  CHECK(buffer);
153
  Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
129
  Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
154 130

  
155 131
  // Assemble a simple function that adds arguments returning the sum.
156 132
  __ movq(rax, arg2);
......
172 148
                                                 &actual_size,
173 149
                                                 true));
174 150
  CHECK(buffer);
175
  Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
151
  Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
176 152

  
177 153
  // Assemble a simple function that multiplies arguments returning the high
178 154
  // word.
......
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 323
TEST(AssemblerX64MemoryOperands) {
197 324
  // Allocate an executable page of memory.
198 325
  size_t actual_size;
......
200 327
                                                 &actual_size,
201 328
                                                 true));
202 329
  CHECK(buffer);
203
  Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
330
  Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
204 331

  
205 332
  // Assemble a simple function that copies argument 2 and returns it.
206 333
  __ push(rbp);
......
234 361
                                                 &actual_size,
235 362
                                                 true));
236 363
  CHECK(buffer);
237
  Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
364
  Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
238 365

  
239 366
  // Assemble a simple function that copies argument 1 and returns it.
240 367
  __ push(rbp);
......
263 390
                                                 &actual_size,
264 391
                                                 true));
265 392
  CHECK(buffer);
266
  Assembler assm(Isolate::Current(), buffer, static_cast<int>(actual_size));
393
  Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
267 394
  // Assemble two loops using rax as counter, and verify the ending counts.
268 395
  Label Fail;
269 396
  __ movq(rax, Immediate(-3));
......
353 480
  // Test chaining of label usages within instructions (issue 1644).
354 481
  CcTest::InitializeVM();
355 482
  v8::HandleScope scope(CcTest::isolate());
356
  Assembler assm(Isolate::Current(), NULL, 0);
483
  Assembler assm(CcTest::i_isolate(), NULL, 0);
357 484

  
358 485
  Label target;
359 486
  __ j(equal, &target);
......
366 493
TEST(AssemblerMultiByteNop) {
367 494
  CcTest::InitializeVM();
368 495
  v8::HandleScope scope(CcTest::isolate());
369
  v8::internal::byte buffer[1024];
370
  Isolate* isolate = Isolate::Current();
496
  byte buffer[1024];
497
  Isolate* isolate = CcTest::i_isolate();
371 498
  Assembler assm(isolate, buffer, sizeof(buffer));
372 499
  __ push(rbx);
373 500
  __ push(rcx);
......
420 547
  Code* code = Code::cast(isolate->heap()->CreateCode(
421 548
      desc,
422 549
      Code::ComputeFlags(Code::STUB),
423
      v8::internal::Handle<Code>())->ToObjectChecked());
550
      Handle<Code>())->ToObjectChecked());
424 551
  CHECK(code->IsCode());
425 552

  
426 553
  F0 f = FUNCTION_CAST<F0>(code->entry());
......
433 560
#define ELEMENT_COUNT 4
434 561

  
435 562
void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
436
  CcTest::InitializeVM();
437 563
  v8::HandleScope scope(CcTest::isolate());
438
  v8::internal::byte buffer[1024];
564
  byte buffer[1024];
439 565

  
440 566
  CHECK(args[0]->IsArray());
441 567
  v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]);
442 568
  CHECK_EQ(ELEMENT_COUNT, vec->Length());
443 569

  
444
  Isolate* isolate = Isolate::Current();
570
  Isolate* isolate = CcTest::i_isolate();
445 571
  Assembler assm(isolate, buffer, sizeof(buffer));
446 572

  
447 573
  // Remove return address from the stack for fix stack frame alignment.
......
473 599
  Code* code = Code::cast(isolate->heap()->CreateCode(
474 600
      desc,
475 601
      Code::ComputeFlags(Code::STUB),
476
      v8::internal::Handle<Code>())->ToObjectChecked());
602
      Handle<Code>())->ToObjectChecked());
477 603
  CHECK(code->IsCode());
478 604

  
479 605
  F0 f = FUNCTION_CAST<F0>(code->entry());
......
483 609

  
484 610

  
485 611
TEST(StackAlignmentForSSE2) {
612
  CcTest::InitializeVM();
486 613
  CHECK_EQ(0, OS::ActivationFrameAlignment() % 16);
487 614

  
488
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
615
  v8::Isolate* isolate = CcTest::isolate();
489 616
  v8::HandleScope handle_scope(isolate);
490 617
  v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
491 618
  global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(DoSSE2));
......
517 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 679
#undef __

Also available in: Unified diff