The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / test / cctest / test-assembler-ia32.cc @ 40c0f755

History | View | Annotate | Download (10.8 KB)

1
// Copyright 2006-2008 the V8 project authors. All rights reserved.
2
// 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

    
39
using namespace v8::internal;
40

    
41

    
42
typedef int (*F0)();
43
typedef int (*F1)(int x);
44
typedef int (*F2)(int x, int y);
45

    
46

    
47
static v8::Persistent<v8::Context> env;
48

    
49

    
50
static void InitializeVM() {
51
  if (env.IsEmpty()) {
52
    env = v8::Context::New();
53
  }
54
}
55

    
56

    
57
#define __ assm.
58

    
59
TEST(AssemblerIa320) {
60
  InitializeVM();
61
  v8::HandleScope scope;
62

    
63
  v8::internal::byte buffer[256];
64
  Assembler assm(buffer, sizeof buffer);
65

    
66
  __ mov(eax, Operand(esp, 4));
67
  __ add(eax, Operand(esp, 8));
68
  __ ret(0);
69

    
70
  CodeDesc desc;
71
  assm.GetCode(&desc);
72
  Object* code = Heap::CreateCode(desc,
73
                                  NULL,
74
                                  Code::ComputeFlags(Code::STUB),
75
                                  Handle<Object>(Heap::undefined_value()));
76
  CHECK(code->IsCode());
77
#ifdef DEBUG
78
  Code::cast(code)->Print();
79
#endif
80
  F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
81
  int res = f(3, 4);
82
  ::printf("f() = %d\n", res);
83
  CHECK_EQ(7, res);
84
}
85

    
86

    
87
TEST(AssemblerIa321) {
88
  InitializeVM();
89
  v8::HandleScope scope;
90

    
91
  v8::internal::byte buffer[256];
92
  Assembler assm(buffer, sizeof buffer);
93
  Label L, C;
94

    
95
  __ mov(edx, Operand(esp, 4));
96
  __ xor_(eax, Operand(eax));  // clear eax
97
  __ jmp(&C);
98

    
99
  __ bind(&L);
100
  __ add(eax, Operand(edx));
101
  __ sub(Operand(edx), Immediate(1));
102

    
103
  __ bind(&C);
104
  __ test(edx, Operand(edx));
105
  __ j(not_zero, &L, taken);
106
  __ ret(0);
107

    
108
  CodeDesc desc;
109
  assm.GetCode(&desc);
110
  Object* code = Heap::CreateCode(desc,
111
                                  NULL,
112
                                  Code::ComputeFlags(Code::STUB),
113
                                  Handle<Object>(Heap::undefined_value()));
114
  CHECK(code->IsCode());
115
#ifdef DEBUG
116
  Code::cast(code)->Print();
117
#endif
118
  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
119
  int res = f(100);
120
  ::printf("f() = %d\n", res);
121
  CHECK_EQ(5050, res);
122
}
123

    
124

    
125
TEST(AssemblerIa322) {
126
  InitializeVM();
127
  v8::HandleScope scope;
128

    
129
  v8::internal::byte buffer[256];
130
  Assembler assm(buffer, sizeof buffer);
131
  Label L, C;
132

    
133
  __ mov(edx, Operand(esp, 4));
134
  __ mov(eax, 1);
135
  __ jmp(&C);
136

    
137
  __ bind(&L);
138
  __ imul(eax, Operand(edx));
139
  __ sub(Operand(edx), Immediate(1));
140

    
141
  __ bind(&C);
142
  __ test(edx, Operand(edx));
143
  __ j(not_zero, &L, taken);
144
  __ ret(0);
145

    
146
  // some relocated stuff here, not executed
147
  __ mov(eax, Factory::true_value());
148
  __ jmp(NULL, RelocInfo::RUNTIME_ENTRY);
149

    
150
  CodeDesc desc;
151
  assm.GetCode(&desc);
152
  Object* code = Heap::CreateCode(desc,
153
                                  NULL,
154
                                  Code::ComputeFlags(Code::STUB),
155
                                  Handle<Object>(Heap::undefined_value()));
156
  CHECK(code->IsCode());
157
#ifdef DEBUG
158
  Code::cast(code)->Print();
159
#endif
160
  F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
161
  int res = f(10);
162
  ::printf("f() = %d\n", res);
163
  CHECK_EQ(3628800, res);
164
}
165

    
166

    
167
typedef int (*F3)(float x);
168

    
169
TEST(AssemblerIa323) {
170
  InitializeVM();
171
  v8::HandleScope scope;
172

    
173
  v8::internal::byte buffer[256];
174
  Assembler assm(buffer, sizeof buffer);
175

    
176
  CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2));
177
  { CpuFeatures::Scope fscope(CpuFeatures::SSE2);
178
    __ cvttss2si(eax, Operand(esp, 4));
179
    __ ret(0);
180
  }
181

    
182
  CodeDesc desc;
183
  assm.GetCode(&desc);
184
  Code* code =
185
      Code::cast(Heap::CreateCode(desc,
186
                                  NULL,
187
                                  Code::ComputeFlags(Code::STUB),
188
                                  Handle<Object>(Heap::undefined_value())));
189
  // don't print the code - our disassembler can't handle cvttss2si
190
  // instead print bytes
191
  Disassembler::Dump(stdout,
192
                     code->instruction_start(),
193
                     code->instruction_start() + code->instruction_size());
194
  F3 f = FUNCTION_CAST<F3>(code->entry());
195
  int res = f(static_cast<float>(-3.1415));
196
  ::printf("f() = %d\n", res);
197
  CHECK_EQ(-3, res);
198
}
199

    
200

    
201
typedef int (*F4)(double x);
202

    
203
TEST(AssemblerIa324) {
204
  InitializeVM();
205
  v8::HandleScope scope;
206

    
207
  v8::internal::byte buffer[256];
208
  Assembler assm(buffer, sizeof buffer);
209

    
210
  CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2));
211
  CpuFeatures::Scope fscope(CpuFeatures::SSE2);
212
  __ cvttsd2si(eax, Operand(esp, 4));
213
  __ ret(0);
214

    
215
  CodeDesc desc;
216
  assm.GetCode(&desc);
217
  Code* code =
218
      Code::cast(Heap::CreateCode(desc,
219
                                  NULL,
220
                                  Code::ComputeFlags(Code::STUB),
221
                                  Handle<Object>(Heap::undefined_value())));
222
  // don't print the code - our disassembler can't handle cvttsd2si
223
  // instead print bytes
224
  Disassembler::Dump(stdout,
225
                     code->instruction_start(),
226
                     code->instruction_start() + code->instruction_size());
227
  F4 f = FUNCTION_CAST<F4>(code->entry());
228
  int res = f(2.718281828);
229
  ::printf("f() = %d\n", res);
230
  CHECK_EQ(2, res);
231
}
232

    
233

    
234
static int baz = 42;
235
TEST(AssemblerIa325) {
236
  InitializeVM();
237
  v8::HandleScope scope;
238

    
239
  v8::internal::byte buffer[256];
240
  Assembler assm(buffer, sizeof buffer);
241

    
242
  __ mov(eax, Operand(reinterpret_cast<intptr_t>(&baz), RelocInfo::NONE));
243
  __ ret(0);
244

    
245
  CodeDesc desc;
246
  assm.GetCode(&desc);
247
  Code* code =
248
      Code::cast(Heap::CreateCode(desc,
249
                                  NULL,
250
                                  Code::ComputeFlags(Code::STUB),
251
                                  Handle<Object>(Heap::undefined_value())));
252
  F0 f = FUNCTION_CAST<F0>(code->entry());
253
  int res = f();
254
  CHECK_EQ(42, res);
255
}
256

    
257

    
258
typedef double (*F5)(double x, double y);
259

    
260
TEST(AssemblerIa326) {
261
  InitializeVM();
262
  v8::HandleScope scope;
263
  CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2));
264
  CpuFeatures::Scope fscope(CpuFeatures::SSE2);
265
  v8::internal::byte buffer[256];
266
  Assembler assm(buffer, sizeof buffer);
267

    
268
  __ movdbl(xmm0, Operand(esp, 1 * kPointerSize));
269
  __ movdbl(xmm1, Operand(esp, 3 * kPointerSize));
270
  __ addsd(xmm0, xmm1);
271
  __ mulsd(xmm0, xmm1);
272
  __ subsd(xmm0, xmm1);
273
  __ divsd(xmm0, xmm1);
274
  // Copy xmm0 to st(0) using eight bytes of stack.
275
  __ sub(Operand(esp), Immediate(8));
276
  __ movdbl(Operand(esp, 0), xmm0);
277
  __ fld_d(Operand(esp, 0));
278
  __ add(Operand(esp), Immediate(8));
279
  __ ret(0);
280

    
281
  CodeDesc desc;
282
  assm.GetCode(&desc);
283
  Code* code =
284
      Code::cast(Heap::CreateCode(desc,
285
                                  NULL,
286
                                  Code::ComputeFlags(Code::STUB),
287
                                  Handle<Object>(Heap::undefined_value())));
288
#ifdef DEBUG
289
  ::printf("\n---\n");
290
  // don't print the code - our disassembler can't handle SSE instructions
291
  // instead print bytes
292
  Disassembler::Dump(stdout,
293
                     code->instruction_start(),
294
                     code->instruction_start() + code->instruction_size());
295
#endif
296
  F5 f = FUNCTION_CAST<F5>(code->entry());
297
  double res = f(2.2, 1.1);
298
  ::printf("f() = %f\n", res);
299
  CHECK(2.29 < res && res < 2.31);
300
}
301

    
302

    
303
typedef double (*F6)(int x);
304

    
305
TEST(AssemblerIa328) {
306
  InitializeVM();
307
  v8::HandleScope scope;
308
  CHECK(CpuFeatures::IsSupported(CpuFeatures::SSE2));
309
  CpuFeatures::Scope fscope(CpuFeatures::SSE2);
310
  v8::internal::byte buffer[256];
311
  Assembler assm(buffer, sizeof buffer);
312
  __ mov(eax, Operand(esp, 4));
313
  __ cvtsi2sd(xmm0, Operand(eax));
314
  // Copy xmm0 to st(0) using eight bytes of stack.
315
  __ sub(Operand(esp), Immediate(8));
316
  __ movdbl(Operand(esp, 0), xmm0);
317
  __ fld_d(Operand(esp, 0));
318
  __ add(Operand(esp), Immediate(8));
319
  __ ret(0);
320
  CodeDesc desc;
321
  assm.GetCode(&desc);
322
  Code* code =
323
      Code::cast(Heap::CreateCode(desc,
324
                                  NULL,
325
                                  Code::ComputeFlags(Code::STUB),
326
                                  Handle<Object>(Heap::undefined_value())));
327
  CHECK(code->IsCode());
328
#ifdef DEBUG
329
  Code::cast(code)->Print();
330
#endif
331
  F6 f = FUNCTION_CAST<F6>(Code::cast(code)->entry());
332
  double res = f(12);
333

    
334
  ::printf("f() = %f\n", res);
335
  CHECK(11.99 < res && res < 12.001);
336
}
337

    
338

    
339
typedef int (*F7)(double x, double y);
340

    
341
TEST(AssemblerIa329) {
342
  InitializeVM();
343
  v8::HandleScope scope;
344
  v8::internal::byte buffer[256];
345
  MacroAssembler assm(buffer, sizeof buffer);
346
  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();
351
  __ j(parity_even, &nan_l, taken);
352
  __ j(equal, &equal_l, taken);
353
  __ j(below, &less_l, taken);
354
  __ j(above, &greater_l, taken);
355

    
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);
378
  Code* code =
379
      Code::cast(Heap::CreateCode(desc,
380
                                  NULL,
381
                                  Code::ComputeFlags(Code::STUB),
382
                                  Handle<Object>(Heap::undefined_value())));
383
  CHECK(code->IsCode());
384
#ifdef DEBUG
385
  Code::cast(code)->Print();
386
#endif
387

    
388
  F7 f = FUNCTION_CAST<F7>(Code::cast(code)->entry());
389
  CHECK_EQ(kLess, f(1.1, 2.2));
390
  CHECK_EQ(kEqual, f(2.2, 2.2));
391
  CHECK_EQ(kGreater, f(3.3, 2.2));
392
  CHECK_EQ(kNaN, f(OS::nan_value(), 1.1));
393
}
394

    
395
#undef __