8341f9b49ee7f9b77b1ffe92f4c5fca1763fda96
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / test-assembler-x87.cc
1 // Copyright 2011 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 "src/v8.h"
31
32 #include "src/base/platform/platform.h"
33 #include "src/disassembler.h"
34 #include "src/factory.h"
35 #include "src/macro-assembler.h"
36 #include "src/ostreams.h"
37 #include "src/serialize.h"
38 #include "test/cctest/cctest.h"
39
40 using namespace v8::internal;
41
42
43 typedef int (*F0)();
44 typedef int (*F1)(int x);
45 typedef int (*F2)(int x, int y);
46
47
48 #define __ assm.
49
50 TEST(AssemblerIa320) {
51   CcTest::InitializeVM();
52   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
53   HandleScope scope(isolate);
54
55   v8::internal::byte buffer[256];
56   Assembler assm(isolate, buffer, sizeof buffer);
57
58   __ mov(eax, Operand(esp, 4));
59   __ add(eax, Operand(esp, 8));
60   __ ret(0);
61
62   CodeDesc desc;
63   assm.GetCode(&desc);
64   Handle<Code> code = isolate->factory()->NewCode(
65       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
66 #ifdef OBJECT_PRINT
67   OFStream os(stdout);
68   code->Print(os);
69 #endif
70   F2 f = FUNCTION_CAST<F2>(code->entry());
71   int res = f(3, 4);
72   ::printf("f() = %d\n", res);
73   CHECK_EQ(7, res);
74 }
75
76
77 TEST(AssemblerIa321) {
78   CcTest::InitializeVM();
79   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
80   HandleScope scope(isolate);
81
82   v8::internal::byte buffer[256];
83   Assembler assm(isolate, buffer, sizeof buffer);
84   Label L, C;
85
86   __ mov(edx, Operand(esp, 4));
87   __ xor_(eax, eax);  // clear eax
88   __ jmp(&C);
89
90   __ bind(&L);
91   __ add(eax, edx);
92   __ sub(edx, Immediate(1));
93
94   __ bind(&C);
95   __ test(edx, edx);
96   __ j(not_zero, &L);
97   __ ret(0);
98
99   CodeDesc desc;
100   assm.GetCode(&desc);
101   Handle<Code> code = isolate->factory()->NewCode(
102       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
103 #ifdef OBJECT_PRINT
104   OFStream os(stdout);
105   code->Print(os);
106 #endif
107   F1 f = FUNCTION_CAST<F1>(code->entry());
108   int res = f(100);
109   ::printf("f() = %d\n", res);
110   CHECK_EQ(5050, res);
111 }
112
113
114 TEST(AssemblerIa322) {
115   CcTest::InitializeVM();
116   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
117   HandleScope scope(isolate);
118
119   v8::internal::byte buffer[256];
120   Assembler assm(isolate, buffer, sizeof buffer);
121   Label L, C;
122
123   __ mov(edx, Operand(esp, 4));
124   __ mov(eax, 1);
125   __ jmp(&C);
126
127   __ bind(&L);
128   __ imul(eax, edx);
129   __ sub(edx, Immediate(1));
130
131   __ bind(&C);
132   __ test(edx, edx);
133   __ j(not_zero, &L);
134   __ ret(0);
135
136   // some relocated stuff here, not executed
137   __ mov(eax, isolate->factory()->true_value());
138   __ jmp(NULL, RelocInfo::RUNTIME_ENTRY);
139
140   CodeDesc desc;
141   assm.GetCode(&desc);
142   Handle<Code> code = isolate->factory()->NewCode(
143       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
144 #ifdef OBJECT_PRINT
145   OFStream os(stdout);
146   code->Print(os);
147 #endif
148   F1 f = FUNCTION_CAST<F1>(code->entry());
149   int res = f(10);
150   ::printf("f() = %d\n", res);
151   CHECK_EQ(3628800, res);
152 }
153
154
155 typedef int (*F3)(float x);
156
157 typedef int (*F4)(double x);
158
159 static int baz = 42;
160 TEST(AssemblerIa325) {
161   CcTest::InitializeVM();
162   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
163   HandleScope scope(isolate);
164
165   v8::internal::byte buffer[256];
166   Assembler assm(isolate, buffer, sizeof buffer);
167
168   __ mov(eax, Operand(reinterpret_cast<intptr_t>(&baz), RelocInfo::NONE32));
169   __ ret(0);
170
171   CodeDesc desc;
172   assm.GetCode(&desc);
173   Handle<Code> code = isolate->factory()->NewCode(
174       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
175   F0 f = FUNCTION_CAST<F0>(code->entry());
176   int res = f();
177   CHECK_EQ(42, res);
178 }
179
180
181 typedef int (*F7)(double x, double y);
182
183 TEST(AssemblerIa329) {
184   CcTest::InitializeVM();
185   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
186   HandleScope scope(isolate);
187   v8::internal::byte buffer[256];
188   MacroAssembler assm(isolate, buffer, sizeof buffer);
189   enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 };
190   Label equal_l, less_l, greater_l, nan_l;
191   __ fld_d(Operand(esp, 3 * kPointerSize));
192   __ fld_d(Operand(esp, 1 * kPointerSize));
193   __ FCmp();
194   __ j(parity_even, &nan_l);
195   __ j(equal, &equal_l);
196   __ j(below, &less_l);
197   __ j(above, &greater_l);
198
199   __ mov(eax, kUndefined);
200   __ ret(0);
201
202   __ bind(&equal_l);
203   __ mov(eax, kEqual);
204   __ ret(0);
205
206   __ bind(&greater_l);
207   __ mov(eax, kGreater);
208   __ ret(0);
209
210   __ bind(&less_l);
211   __ mov(eax, kLess);
212   __ ret(0);
213
214   __ bind(&nan_l);
215   __ mov(eax, kNaN);
216   __ ret(0);
217
218
219   CodeDesc desc;
220   assm.GetCode(&desc);
221   Handle<Code> code = isolate->factory()->NewCode(
222       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
223 #ifdef OBJECT_PRINT
224   OFStream os(stdout);
225   code->Print(os);
226 #endif
227
228   F7 f = FUNCTION_CAST<F7>(code->entry());
229   CHECK_EQ(kLess, f(1.1, 2.2));
230   CHECK_EQ(kEqual, f(2.2, 2.2));
231   CHECK_EQ(kGreater, f(3.3, 2.2));
232   CHECK_EQ(kNaN, f(v8::base::OS::nan_value(), 1.1));
233 }
234
235
236 TEST(AssemblerIa3210) {
237   // Test chaining of label usages within instructions (issue 1644).
238   CcTest::InitializeVM();
239   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
240   HandleScope scope(isolate);
241   Assembler assm(isolate, NULL, 0);
242
243   Label target;
244   __ j(equal, &target);
245   __ j(not_equal, &target);
246   __ bind(&target);
247   __ nop();
248 }
249
250
251 TEST(AssemblerMultiByteNop) {
252   CcTest::InitializeVM();
253   Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
254   HandleScope scope(isolate);
255   v8::internal::byte buffer[1024];
256   Assembler assm(isolate, buffer, sizeof(buffer));
257   __ push(ebx);
258   __ push(ecx);
259   __ push(edx);
260   __ push(edi);
261   __ push(esi);
262   __ mov(eax, 1);
263   __ mov(ebx, 2);
264   __ mov(ecx, 3);
265   __ mov(edx, 4);
266   __ mov(edi, 5);
267   __ mov(esi, 6);
268   for (int i = 0; i < 16; i++) {
269     int before = assm.pc_offset();
270     __ Nop(i);
271     CHECK_EQ(assm.pc_offset() - before, i);
272   }
273
274   Label fail;
275   __ cmp(eax, 1);
276   __ j(not_equal, &fail);
277   __ cmp(ebx, 2);
278   __ j(not_equal, &fail);
279   __ cmp(ecx, 3);
280   __ j(not_equal, &fail);
281   __ cmp(edx, 4);
282   __ j(not_equal, &fail);
283   __ cmp(edi, 5);
284   __ j(not_equal, &fail);
285   __ cmp(esi, 6);
286   __ j(not_equal, &fail);
287   __ mov(eax, 42);
288   __ pop(esi);
289   __ pop(edi);
290   __ pop(edx);
291   __ pop(ecx);
292   __ pop(ebx);
293   __ ret(0);
294   __ bind(&fail);
295   __ mov(eax, 13);
296   __ pop(esi);
297   __ pop(edi);
298   __ pop(edx);
299   __ pop(ecx);
300   __ pop(ebx);
301   __ ret(0);
302
303   CodeDesc desc;
304   assm.GetCode(&desc);
305   Handle<Code> code = isolate->factory()->NewCode(
306       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
307   CHECK(code->IsCode());
308
309   F0 f = FUNCTION_CAST<F0>(code->entry());
310   int res = f();
311   CHECK_EQ(42, res);
312 }
313
314
315 #undef __