OLD | NEW |
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 11 matching lines...) Expand all Loading... |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <stdlib.h> | 28 #include <stdlib.h> |
29 | 29 |
30 #include "src/v8.h" | 30 #include "src/v8.h" |
31 | 31 |
| 32 #include "src/base/platform/platform.h" |
32 #include "src/factory.h" | 33 #include "src/factory.h" |
33 #include "src/macro-assembler.h" | 34 #include "src/macro-assembler.h" |
34 #include "src/platform.h" | |
35 #include "src/serialize.h" | 35 #include "src/serialize.h" |
36 #include "test/cctest/cctest.h" | 36 #include "test/cctest/cctest.h" |
37 | 37 |
38 using namespace v8::internal; | 38 using namespace v8::internal; |
39 | 39 |
40 // Test the x64 assembler by compiling some simple functions into | 40 // Test the x64 assembler by compiling some simple functions into |
41 // a buffer and executing them. These tests do not initialize the | 41 // a buffer and executing them. These tests do not initialize the |
42 // V8 library, create a context, or use any V8 objects. | 42 // V8 library, create a context, or use any V8 objects. |
43 // The AMD64 calling convention is used, with the first six arguments | 43 // The AMD64 calling convention is used, with the first six arguments |
44 // 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 |
(...skipping 17 matching lines...) Expand all Loading... |
62 static const Register arg2 = rsi; | 62 static const Register arg2 = rsi; |
63 #endif | 63 #endif |
64 | 64 |
65 #define __ assm. | 65 #define __ assm. |
66 | 66 |
67 | 67 |
68 TEST(AssemblerX64ReturnOperation) { | 68 TEST(AssemblerX64ReturnOperation) { |
69 CcTest::InitializeVM(); | 69 CcTest::InitializeVM(); |
70 // Allocate an executable page of memory. | 70 // Allocate an executable page of memory. |
71 size_t actual_size; | 71 size_t actual_size; |
72 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 72 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
73 &actual_size, | 73 Assembler::kMinimalBufferSize, &actual_size, true)); |
74 true)); | |
75 CHECK(buffer); | 74 CHECK(buffer); |
76 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 75 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
77 | 76 |
78 // Assemble a simple function that copies argument 2 and returns it. | 77 // Assemble a simple function that copies argument 2 and returns it. |
79 __ movq(rax, arg2); | 78 __ movq(rax, arg2); |
80 __ nop(); | 79 __ nop(); |
81 __ ret(0); | 80 __ ret(0); |
82 | 81 |
83 CodeDesc desc; | 82 CodeDesc desc; |
84 assm.GetCode(&desc); | 83 assm.GetCode(&desc); |
85 // Call the function from C++. | 84 // Call the function from C++. |
86 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 85 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
87 CHECK_EQ(2, result); | 86 CHECK_EQ(2, result); |
88 } | 87 } |
89 | 88 |
90 | 89 |
91 TEST(AssemblerX64StackOperations) { | 90 TEST(AssemblerX64StackOperations) { |
92 CcTest::InitializeVM(); | 91 CcTest::InitializeVM(); |
93 // Allocate an executable page of memory. | 92 // Allocate an executable page of memory. |
94 size_t actual_size; | 93 size_t actual_size; |
95 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 94 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
96 &actual_size, | 95 Assembler::kMinimalBufferSize, &actual_size, true)); |
97 true)); | |
98 CHECK(buffer); | 96 CHECK(buffer); |
99 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 97 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
100 | 98 |
101 // Assemble a simple function that copies argument 2 and returns it. | 99 // Assemble a simple function that copies argument 2 and returns it. |
102 // We compile without stack frame pointers, so the gdb debugger shows | 100 // We compile without stack frame pointers, so the gdb debugger shows |
103 // incorrect stack frames when debugging this function (which has them). | 101 // incorrect stack frames when debugging this function (which has them). |
104 __ pushq(rbp); | 102 __ pushq(rbp); |
105 __ movq(rbp, rsp); | 103 __ movq(rbp, rsp); |
106 __ pushq(arg2); // Value at (rbp - 8) | 104 __ pushq(arg2); // Value at (rbp - 8) |
107 __ pushq(arg2); // Value at (rbp - 16) | 105 __ pushq(arg2); // Value at (rbp - 16) |
(...skipping 10 matching lines...) Expand all Loading... |
118 // Call the function from C++. | 116 // Call the function from C++. |
119 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 117 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
120 CHECK_EQ(2, result); | 118 CHECK_EQ(2, result); |
121 } | 119 } |
122 | 120 |
123 | 121 |
124 TEST(AssemblerX64ArithmeticOperations) { | 122 TEST(AssemblerX64ArithmeticOperations) { |
125 CcTest::InitializeVM(); | 123 CcTest::InitializeVM(); |
126 // Allocate an executable page of memory. | 124 // Allocate an executable page of memory. |
127 size_t actual_size; | 125 size_t actual_size; |
128 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 126 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
129 &actual_size, | 127 Assembler::kMinimalBufferSize, &actual_size, true)); |
130 true)); | |
131 CHECK(buffer); | 128 CHECK(buffer); |
132 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 129 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
133 | 130 |
134 // Assemble a simple function that adds arguments returning the sum. | 131 // Assemble a simple function that adds arguments returning the sum. |
135 __ movq(rax, arg2); | 132 __ movq(rax, arg2); |
136 __ addq(rax, arg1); | 133 __ addq(rax, arg1); |
137 __ ret(0); | 134 __ ret(0); |
138 | 135 |
139 CodeDesc desc; | 136 CodeDesc desc; |
140 assm.GetCode(&desc); | 137 assm.GetCode(&desc); |
141 // Call the function from C++. | 138 // Call the function from C++. |
142 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 139 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
143 CHECK_EQ(5, result); | 140 CHECK_EQ(5, result); |
144 } | 141 } |
145 | 142 |
146 | 143 |
147 TEST(AssemblerX64CmpbOperation) { | 144 TEST(AssemblerX64CmpbOperation) { |
148 CcTest::InitializeVM(); | 145 CcTest::InitializeVM(); |
149 // Allocate an executable page of memory. | 146 // Allocate an executable page of memory. |
150 size_t actual_size; | 147 size_t actual_size; |
151 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 148 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
152 &actual_size, | 149 Assembler::kMinimalBufferSize, &actual_size, true)); |
153 true)); | |
154 CHECK(buffer); | 150 CHECK(buffer); |
155 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 151 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
156 | 152 |
157 // Assemble a function that compare argument byte returing 1 if equal else 0. | 153 // Assemble a function that compare argument byte returing 1 if equal else 0. |
158 // On Windows, it compares rcx with rdx which does not require REX prefix; | 154 // On Windows, it compares rcx with rdx which does not require REX prefix; |
159 // on Linux, it compares rdi with rsi which requires REX prefix. | 155 // on Linux, it compares rdi with rsi which requires REX prefix. |
160 | 156 |
161 Label done; | 157 Label done; |
162 __ movq(rax, Immediate(1)); | 158 __ movq(rax, Immediate(1)); |
163 __ cmpb(arg1, arg2); | 159 __ cmpb(arg1, arg2); |
164 __ j(equal, &done); | 160 __ j(equal, &done); |
165 __ movq(rax, Immediate(0)); | 161 __ movq(rax, Immediate(0)); |
166 __ bind(&done); | 162 __ bind(&done); |
167 __ ret(0); | 163 __ ret(0); |
168 | 164 |
169 CodeDesc desc; | 165 CodeDesc desc; |
170 assm.GetCode(&desc); | 166 assm.GetCode(&desc); |
171 // Call the function from C++. | 167 // Call the function from C++. |
172 int result = FUNCTION_CAST<F2>(buffer)(0x1002, 0x2002); | 168 int result = FUNCTION_CAST<F2>(buffer)(0x1002, 0x2002); |
173 CHECK_EQ(1, result); | 169 CHECK_EQ(1, result); |
174 result = FUNCTION_CAST<F2>(buffer)(0x1002, 0x2003); | 170 result = FUNCTION_CAST<F2>(buffer)(0x1002, 0x2003); |
175 CHECK_EQ(0, result); | 171 CHECK_EQ(0, result); |
176 } | 172 } |
177 | 173 |
178 | 174 |
179 TEST(AssemblerX64ImulOperation) { | 175 TEST(AssemblerX64ImulOperation) { |
180 CcTest::InitializeVM(); | 176 CcTest::InitializeVM(); |
181 // Allocate an executable page of memory. | 177 // Allocate an executable page of memory. |
182 size_t actual_size; | 178 size_t actual_size; |
183 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 179 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
184 &actual_size, | 180 Assembler::kMinimalBufferSize, &actual_size, true)); |
185 true)); | |
186 CHECK(buffer); | 181 CHECK(buffer); |
187 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 182 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
188 | 183 |
189 // Assemble a simple function that multiplies arguments returning the high | 184 // Assemble a simple function that multiplies arguments returning the high |
190 // word. | 185 // word. |
191 __ movq(rax, arg2); | 186 __ movq(rax, arg2); |
192 __ imulq(arg1); | 187 __ imulq(arg1); |
193 __ movq(rax, rdx); | 188 __ movq(rax, rdx); |
194 __ ret(0); | 189 __ ret(0); |
195 | 190 |
196 CodeDesc desc; | 191 CodeDesc desc; |
197 assm.GetCode(&desc); | 192 assm.GetCode(&desc); |
198 // Call the function from C++. | 193 // Call the function from C++. |
199 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 194 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
200 CHECK_EQ(0, result); | 195 CHECK_EQ(0, result); |
201 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l); | 196 result = FUNCTION_CAST<F2>(buffer)(0x100000000l, 0x100000000l); |
202 CHECK_EQ(1, result); | 197 CHECK_EQ(1, result); |
203 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l); | 198 result = FUNCTION_CAST<F2>(buffer)(-0x100000000l, 0x100000000l); |
204 CHECK_EQ(-1, result); | 199 CHECK_EQ(-1, result); |
205 } | 200 } |
206 | 201 |
207 | 202 |
208 TEST(AssemblerX64XchglOperations) { | 203 TEST(AssemblerX64XchglOperations) { |
209 CcTest::InitializeVM(); | 204 CcTest::InitializeVM(); |
210 // Allocate an executable page of memory. | 205 // Allocate an executable page of memory. |
211 size_t actual_size; | 206 size_t actual_size; |
212 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 207 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
213 &actual_size, | 208 Assembler::kMinimalBufferSize, &actual_size, true)); |
214 true)); | |
215 CHECK(buffer); | 209 CHECK(buffer); |
216 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 210 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
217 | 211 |
218 __ movq(rax, Operand(arg1, 0)); | 212 __ movq(rax, Operand(arg1, 0)); |
219 __ movq(r11, Operand(arg2, 0)); | 213 __ movq(r11, Operand(arg2, 0)); |
220 __ xchgl(rax, r11); | 214 __ xchgl(rax, r11); |
221 __ movq(Operand(arg1, 0), rax); | 215 __ movq(Operand(arg1, 0), rax); |
222 __ movq(Operand(arg2, 0), r11); | 216 __ movq(Operand(arg2, 0), r11); |
223 __ ret(0); | 217 __ ret(0); |
224 | 218 |
225 CodeDesc desc; | 219 CodeDesc desc; |
226 assm.GetCode(&desc); | 220 assm.GetCode(&desc); |
227 // Call the function from C++. | 221 // Call the function from C++. |
228 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 222 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
229 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); | 223 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); |
230 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 224 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
231 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 40000000), left); | 225 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 40000000), left); |
232 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 20000000), right); | 226 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 20000000), right); |
233 USE(result); | 227 USE(result); |
234 } | 228 } |
235 | 229 |
236 | 230 |
237 TEST(AssemblerX64OrlOperations) { | 231 TEST(AssemblerX64OrlOperations) { |
238 CcTest::InitializeVM(); | 232 CcTest::InitializeVM(); |
239 // Allocate an executable page of memory. | 233 // Allocate an executable page of memory. |
240 size_t actual_size; | 234 size_t actual_size; |
241 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 235 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
242 &actual_size, | 236 Assembler::kMinimalBufferSize, &actual_size, true)); |
243 true)); | |
244 CHECK(buffer); | 237 CHECK(buffer); |
245 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 238 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
246 | 239 |
247 __ movq(rax, Operand(arg2, 0)); | 240 __ movq(rax, Operand(arg2, 0)); |
248 __ orl(Operand(arg1, 0), rax); | 241 __ orl(Operand(arg1, 0), rax); |
249 __ ret(0); | 242 __ ret(0); |
250 | 243 |
251 CodeDesc desc; | 244 CodeDesc desc; |
252 assm.GetCode(&desc); | 245 assm.GetCode(&desc); |
253 // Call the function from C++. | 246 // Call the function from C++. |
254 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 247 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
255 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); | 248 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); |
256 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 249 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
257 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 60000000), left); | 250 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 60000000), left); |
258 USE(result); | 251 USE(result); |
259 } | 252 } |
260 | 253 |
261 | 254 |
262 TEST(AssemblerX64RollOperations) { | 255 TEST(AssemblerX64RollOperations) { |
263 CcTest::InitializeVM(); | 256 CcTest::InitializeVM(); |
264 // Allocate an executable page of memory. | 257 // Allocate an executable page of memory. |
265 size_t actual_size; | 258 size_t actual_size; |
266 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 259 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
267 &actual_size, | 260 Assembler::kMinimalBufferSize, &actual_size, true)); |
268 true)); | |
269 CHECK(buffer); | 261 CHECK(buffer); |
270 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 262 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
271 | 263 |
272 __ movq(rax, arg1); | 264 __ movq(rax, arg1); |
273 __ roll(rax, Immediate(1)); | 265 __ roll(rax, Immediate(1)); |
274 __ ret(0); | 266 __ ret(0); |
275 | 267 |
276 CodeDesc desc; | 268 CodeDesc desc; |
277 assm.GetCode(&desc); | 269 assm.GetCode(&desc); |
278 // Call the function from C++. | 270 // Call the function from C++. |
279 int64_t src = V8_2PART_UINT64_C(0x10000000, C0000000); | 271 int64_t src = V8_2PART_UINT64_C(0x10000000, C0000000); |
280 int64_t result = FUNCTION_CAST<F5>(buffer)(src); | 272 int64_t result = FUNCTION_CAST<F5>(buffer)(src); |
281 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 80000001), result); | 273 CHECK_EQ(V8_2PART_UINT64_C(0x00000000, 80000001), result); |
282 } | 274 } |
283 | 275 |
284 | 276 |
285 TEST(AssemblerX64SublOperations) { | 277 TEST(AssemblerX64SublOperations) { |
286 CcTest::InitializeVM(); | 278 CcTest::InitializeVM(); |
287 // Allocate an executable page of memory. | 279 // Allocate an executable page of memory. |
288 size_t actual_size; | 280 size_t actual_size; |
289 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 281 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
290 &actual_size, | 282 Assembler::kMinimalBufferSize, &actual_size, true)); |
291 true)); | |
292 CHECK(buffer); | 283 CHECK(buffer); |
293 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 284 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
294 | 285 |
295 __ movq(rax, Operand(arg2, 0)); | 286 __ movq(rax, Operand(arg2, 0)); |
296 __ subl(Operand(arg1, 0), rax); | 287 __ subl(Operand(arg1, 0), rax); |
297 __ ret(0); | 288 __ ret(0); |
298 | 289 |
299 CodeDesc desc; | 290 CodeDesc desc; |
300 assm.GetCode(&desc); | 291 assm.GetCode(&desc); |
301 // Call the function from C++. | 292 // Call the function from C++. |
302 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 293 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
303 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); | 294 int64_t right = V8_2PART_UINT64_C(0x30000000, 40000000); |
304 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 295 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
305 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, e0000000), left); | 296 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, e0000000), left); |
306 USE(result); | 297 USE(result); |
307 } | 298 } |
308 | 299 |
309 | 300 |
310 TEST(AssemblerX64TestlOperations) { | 301 TEST(AssemblerX64TestlOperations) { |
311 CcTest::InitializeVM(); | 302 CcTest::InitializeVM(); |
312 // Allocate an executable page of memory. | 303 // Allocate an executable page of memory. |
313 size_t actual_size; | 304 size_t actual_size; |
314 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 305 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
315 &actual_size, | 306 Assembler::kMinimalBufferSize, &actual_size, true)); |
316 true)); | |
317 CHECK(buffer); | 307 CHECK(buffer); |
318 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 308 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
319 | 309 |
320 // Set rax with the ZF flag of the testl instruction. | 310 // Set rax with the ZF flag of the testl instruction. |
321 Label done; | 311 Label done; |
322 __ movq(rax, Immediate(1)); | 312 __ movq(rax, Immediate(1)); |
323 __ movq(r11, Operand(arg2, 0)); | 313 __ movq(r11, Operand(arg2, 0)); |
324 __ testl(Operand(arg1, 0), r11); | 314 __ testl(Operand(arg1, 0), r11); |
325 __ j(zero, &done, Label::kNear); | 315 __ j(zero, &done, Label::kNear); |
326 __ movq(rax, Immediate(0)); | 316 __ movq(rax, Immediate(0)); |
327 __ bind(&done); | 317 __ bind(&done); |
328 __ ret(0); | 318 __ ret(0); |
329 | 319 |
330 CodeDesc desc; | 320 CodeDesc desc; |
331 assm.GetCode(&desc); | 321 assm.GetCode(&desc); |
332 // Call the function from C++. | 322 // Call the function from C++. |
333 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 323 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
334 int64_t right = V8_2PART_UINT64_C(0x30000000, 00000000); | 324 int64_t right = V8_2PART_UINT64_C(0x30000000, 00000000); |
335 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 325 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
336 CHECK_EQ(static_cast<int64_t>(1), result); | 326 CHECK_EQ(static_cast<int64_t>(1), result); |
337 } | 327 } |
338 | 328 |
339 | 329 |
340 TEST(AssemblerX64XorlOperations) { | 330 TEST(AssemblerX64XorlOperations) { |
341 CcTest::InitializeVM(); | 331 CcTest::InitializeVM(); |
342 // Allocate an executable page of memory. | 332 // Allocate an executable page of memory. |
343 size_t actual_size; | 333 size_t actual_size; |
344 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 334 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
345 &actual_size, | 335 Assembler::kMinimalBufferSize, &actual_size, true)); |
346 true)); | |
347 CHECK(buffer); | 336 CHECK(buffer); |
348 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 337 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
349 | 338 |
350 __ movq(rax, Operand(arg2, 0)); | 339 __ movq(rax, Operand(arg2, 0)); |
351 __ xorl(Operand(arg1, 0), rax); | 340 __ xorl(Operand(arg1, 0), rax); |
352 __ ret(0); | 341 __ ret(0); |
353 | 342 |
354 CodeDesc desc; | 343 CodeDesc desc; |
355 assm.GetCode(&desc); | 344 assm.GetCode(&desc); |
356 // Call the function from C++. | 345 // Call the function from C++. |
357 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); | 346 int64_t left = V8_2PART_UINT64_C(0x10000000, 20000000); |
358 int64_t right = V8_2PART_UINT64_C(0x30000000, 60000000); | 347 int64_t right = V8_2PART_UINT64_C(0x30000000, 60000000); |
359 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); | 348 int64_t result = FUNCTION_CAST<F4>(buffer)(&left, &right); |
360 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 40000000), left); | 349 CHECK_EQ(V8_2PART_UINT64_C(0x10000000, 40000000), left); |
361 USE(result); | 350 USE(result); |
362 } | 351 } |
363 | 352 |
364 | 353 |
365 TEST(AssemblerX64MemoryOperands) { | 354 TEST(AssemblerX64MemoryOperands) { |
366 CcTest::InitializeVM(); | 355 CcTest::InitializeVM(); |
367 // Allocate an executable page of memory. | 356 // Allocate an executable page of memory. |
368 size_t actual_size; | 357 size_t actual_size; |
369 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 358 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
370 &actual_size, | 359 Assembler::kMinimalBufferSize, &actual_size, true)); |
371 true)); | |
372 CHECK(buffer); | 360 CHECK(buffer); |
373 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 361 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
374 | 362 |
375 // Assemble a simple function that copies argument 2 and returns it. | 363 // Assemble a simple function that copies argument 2 and returns it. |
376 __ pushq(rbp); | 364 __ pushq(rbp); |
377 __ movq(rbp, rsp); | 365 __ movq(rbp, rsp); |
378 | 366 |
379 __ pushq(arg2); // Value at (rbp - 8) | 367 __ pushq(arg2); // Value at (rbp - 8) |
380 __ pushq(arg2); // Value at (rbp - 16) | 368 __ pushq(arg2); // Value at (rbp - 16) |
381 __ pushq(arg1); // Value at (rbp - 24) | 369 __ pushq(arg1); // Value at (rbp - 24) |
(...skipping 12 matching lines...) Expand all Loading... |
394 // Call the function from C++. | 382 // Call the function from C++. |
395 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 383 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
396 CHECK_EQ(3, result); | 384 CHECK_EQ(3, result); |
397 } | 385 } |
398 | 386 |
399 | 387 |
400 TEST(AssemblerX64ControlFlow) { | 388 TEST(AssemblerX64ControlFlow) { |
401 CcTest::InitializeVM(); | 389 CcTest::InitializeVM(); |
402 // Allocate an executable page of memory. | 390 // Allocate an executable page of memory. |
403 size_t actual_size; | 391 size_t actual_size; |
404 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 392 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
405 &actual_size, | 393 Assembler::kMinimalBufferSize, &actual_size, true)); |
406 true)); | |
407 CHECK(buffer); | 394 CHECK(buffer); |
408 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 395 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
409 | 396 |
410 // Assemble a simple function that copies argument 1 and returns it. | 397 // Assemble a simple function that copies argument 1 and returns it. |
411 __ pushq(rbp); | 398 __ pushq(rbp); |
412 | 399 |
413 __ movq(rbp, rsp); | 400 __ movq(rbp, rsp); |
414 __ movq(rax, arg1); | 401 __ movq(rax, arg1); |
415 Label target; | 402 Label target; |
416 __ jmp(&target); | 403 __ jmp(&target); |
417 __ movq(rax, arg2); | 404 __ movq(rax, arg2); |
418 __ bind(&target); | 405 __ bind(&target); |
419 __ popq(rbp); | 406 __ popq(rbp); |
420 __ ret(0); | 407 __ ret(0); |
421 | 408 |
422 CodeDesc desc; | 409 CodeDesc desc; |
423 assm.GetCode(&desc); | 410 assm.GetCode(&desc); |
424 // Call the function from C++. | 411 // Call the function from C++. |
425 int result = FUNCTION_CAST<F2>(buffer)(3, 2); | 412 int result = FUNCTION_CAST<F2>(buffer)(3, 2); |
426 CHECK_EQ(3, result); | 413 CHECK_EQ(3, result); |
427 } | 414 } |
428 | 415 |
429 | 416 |
430 TEST(AssemblerX64LoopImmediates) { | 417 TEST(AssemblerX64LoopImmediates) { |
431 CcTest::InitializeVM(); | 418 CcTest::InitializeVM(); |
432 // Allocate an executable page of memory. | 419 // Allocate an executable page of memory. |
433 size_t actual_size; | 420 size_t actual_size; |
434 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 421 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
435 &actual_size, | 422 Assembler::kMinimalBufferSize, &actual_size, true)); |
436 true)); | |
437 CHECK(buffer); | 423 CHECK(buffer); |
438 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); | 424 Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size)); |
439 // Assemble two loops using rax as counter, and verify the ending counts. | 425 // Assemble two loops using rax as counter, and verify the ending counts. |
440 Label Fail; | 426 Label Fail; |
441 __ movq(rax, Immediate(-3)); | 427 __ movq(rax, Immediate(-3)); |
442 Label Loop1_test; | 428 Label Loop1_test; |
443 Label Loop1_body; | 429 Label Loop1_body; |
444 __ jmp(&Loop1_test); | 430 __ jmp(&Loop1_test); |
445 __ bind(&Loop1_body); | 431 __ bind(&Loop1_body); |
446 __ addq(rax, Immediate(7)); | 432 __ addq(rax, Immediate(7)); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 628 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
643 | 629 |
644 F0 f = FUNCTION_CAST<F0>(code->entry()); | 630 F0 f = FUNCTION_CAST<F0>(code->entry()); |
645 int res = f(); | 631 int res = f(); |
646 args.GetReturnValue().Set(v8::Integer::New(CcTest::isolate(), res)); | 632 args.GetReturnValue().Set(v8::Integer::New(CcTest::isolate(), res)); |
647 } | 633 } |
648 | 634 |
649 | 635 |
650 TEST(StackAlignmentForSSE2) { | 636 TEST(StackAlignmentForSSE2) { |
651 CcTest::InitializeVM(); | 637 CcTest::InitializeVM(); |
652 CHECK_EQ(0, OS::ActivationFrameAlignment() % 16); | 638 CHECK_EQ(0, v8::base::OS::ActivationFrameAlignment() % 16); |
653 | 639 |
654 v8::Isolate* isolate = CcTest::isolate(); | 640 v8::Isolate* isolate = CcTest::isolate(); |
655 v8::HandleScope handle_scope(isolate); | 641 v8::HandleScope handle_scope(isolate); |
656 v8::Handle<v8::ObjectTemplate> global_template = | 642 v8::Handle<v8::ObjectTemplate> global_template = |
657 v8::ObjectTemplate::New(isolate); | 643 v8::ObjectTemplate::New(isolate); |
658 global_template->Set(v8_str("do_sse2"), | 644 global_template->Set(v8_str("do_sse2"), |
659 v8::FunctionTemplate::New(isolate, DoSSE2)); | 645 v8::FunctionTemplate::New(isolate, DoSSE2)); |
660 | 646 |
661 LocalContext env(NULL, global_template); | 647 LocalContext env(NULL, global_template); |
662 CompileRun( | 648 CompileRun( |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 Code::ComputeFlags(Code::STUB), | 727 Code::ComputeFlags(Code::STUB), |
742 Handle<Code>()); | 728 Handle<Code>()); |
743 #ifdef OBJECT_PRINT | 729 #ifdef OBJECT_PRINT |
744 code->Print(); | 730 code->Print(); |
745 #endif | 731 #endif |
746 | 732 |
747 F6 f = FUNCTION_CAST<F6>(code->entry()); | 733 F6 f = FUNCTION_CAST<F6>(code->entry()); |
748 CHECK_EQ(2, f(1.0, 2.0)); | 734 CHECK_EQ(2, f(1.0, 2.0)); |
749 } | 735 } |
750 #undef __ | 736 #undef __ |
OLD | NEW |