OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/os.h" | 9 #include "vm/os.h" |
10 #include "vm/unit_test.h" | 10 #include "vm/unit_test.h" |
11 #include "vm/virtual_memory.h" | 11 #include "vm/virtual_memory.h" |
12 | 12 |
13 namespace dart { | 13 namespace dart { |
14 | 14 |
15 #define __ assembler-> | 15 #define __ assembler-> |
16 | 16 |
17 | |
18 ASSEMBLER_TEST_GENERATE(ReadArgument, assembler) { | 17 ASSEMBLER_TEST_GENERATE(ReadArgument, assembler) { |
19 __ pushq(CallingConventions::kArg1Reg); | 18 __ pushq(CallingConventions::kArg1Reg); |
20 __ movq(RAX, Address(RSP, 0)); | 19 __ movq(RAX, Address(RSP, 0)); |
21 __ popq(RDX); | 20 __ popq(RDX); |
22 __ ret(); | 21 __ ret(); |
23 } | 22 } |
24 | 23 |
25 | |
26 ASSEMBLER_TEST_RUN(ReadArgument, test) { | 24 ASSEMBLER_TEST_RUN(ReadArgument, test) { |
27 typedef int64_t (*ReadArgumentCode)(int64_t n); | 25 typedef int64_t (*ReadArgumentCode)(int64_t n); |
28 ReadArgumentCode id = reinterpret_cast<ReadArgumentCode>(test->entry()); | 26 ReadArgumentCode id = reinterpret_cast<ReadArgumentCode>(test->entry()); |
29 EXPECT_EQ(42, id(42)); | 27 EXPECT_EQ(42, id(42)); |
30 EXPECT_EQ(87, id(87)); | 28 EXPECT_EQ(87, id(87)); |
31 static const int64_t kLargeConstant = 0x1234567812345678LL; | 29 static const int64_t kLargeConstant = 0x1234567812345678LL; |
32 EXPECT_EQ(kLargeConstant, id(kLargeConstant)); | 30 EXPECT_EQ(kLargeConstant, id(kLargeConstant)); |
33 } | 31 } |
34 | 32 |
35 | |
36 ASSEMBLER_TEST_GENERATE(AddressingModes, assembler) { | 33 ASSEMBLER_TEST_GENERATE(AddressingModes, assembler) { |
37 __ movq(RAX, Address(RSP, 0)); | 34 __ movq(RAX, Address(RSP, 0)); |
38 __ movq(RAX, Address(RBP, 0)); | 35 __ movq(RAX, Address(RBP, 0)); |
39 __ movq(RAX, Address(RAX, 0)); | 36 __ movq(RAX, Address(RAX, 0)); |
40 __ movq(RAX, Address(R10, 0)); | 37 __ movq(RAX, Address(R10, 0)); |
41 __ movq(RAX, Address(R12, 0)); | 38 __ movq(RAX, Address(R12, 0)); |
42 __ movq(RAX, Address(R13, 0)); | 39 __ movq(RAX, Address(R13, 0)); |
43 __ movq(R10, Address(RAX, 0)); | 40 __ movq(R10, Address(RAX, 0)); |
44 | 41 |
45 __ movq(RAX, Address(RSP, kWordSize)); | 42 __ movq(RAX, Address(RSP, kWordSize)); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 __ movq(RAX, Address::AddressBaseImm32(R13, kWordSize)); | 214 __ movq(RAX, Address::AddressBaseImm32(R13, kWordSize)); |
218 | 215 |
219 __ movq(RAX, Address::AddressBaseImm32(RSP, -kWordSize)); | 216 __ movq(RAX, Address::AddressBaseImm32(RSP, -kWordSize)); |
220 __ movq(RAX, Address::AddressBaseImm32(RBP, -kWordSize)); | 217 __ movq(RAX, Address::AddressBaseImm32(RBP, -kWordSize)); |
221 __ movq(RAX, Address::AddressBaseImm32(RAX, -kWordSize)); | 218 __ movq(RAX, Address::AddressBaseImm32(RAX, -kWordSize)); |
222 __ movq(RAX, Address::AddressBaseImm32(R10, -kWordSize)); | 219 __ movq(RAX, Address::AddressBaseImm32(R10, -kWordSize)); |
223 __ movq(RAX, Address::AddressBaseImm32(R12, -kWordSize)); | 220 __ movq(RAX, Address::AddressBaseImm32(R12, -kWordSize)); |
224 __ movq(RAX, Address::AddressBaseImm32(R13, -kWordSize)); | 221 __ movq(RAX, Address::AddressBaseImm32(R13, -kWordSize)); |
225 } | 222 } |
226 | 223 |
227 | |
228 ASSEMBLER_TEST_RUN(AddressingModes, test) { | 224 ASSEMBLER_TEST_RUN(AddressingModes, test) { |
229 // Avoid running the code since it is constructed to lead to crashes. | 225 // Avoid running the code since it is constructed to lead to crashes. |
230 } | 226 } |
231 | 227 |
232 | |
233 ASSEMBLER_TEST_GENERATE(JumpAroundCrash, assembler) { | 228 ASSEMBLER_TEST_GENERATE(JumpAroundCrash, assembler) { |
234 Label done; | 229 Label done; |
235 // Make sure all the condition jumps work. | 230 // Make sure all the condition jumps work. |
236 for (Condition condition = OVERFLOW; condition <= GREATER; | 231 for (Condition condition = OVERFLOW; condition <= GREATER; |
237 condition = static_cast<Condition>(condition + 1)) { | 232 condition = static_cast<Condition>(condition + 1)) { |
238 __ j(condition, &done); | 233 __ j(condition, &done); |
239 } | 234 } |
240 // This isn't strictly necessary, but we do an unconditional | 235 // This isn't strictly necessary, but we do an unconditional |
241 // jump around the crashing code anyway. | 236 // jump around the crashing code anyway. |
242 __ jmp(&done); | 237 __ jmp(&done); |
243 | 238 |
244 // Be sure to skip this crashing code. | 239 // Be sure to skip this crashing code. |
245 __ movq(RAX, Immediate(0)); | 240 __ movq(RAX, Immediate(0)); |
246 __ movq(Address(RAX, 0), RAX); | 241 __ movq(Address(RAX, 0), RAX); |
247 | 242 |
248 __ Bind(&done); | 243 __ Bind(&done); |
249 __ ret(); | 244 __ ret(); |
250 } | 245 } |
251 | 246 |
252 | |
253 ASSEMBLER_TEST_RUN(JumpAroundCrash, test) { | 247 ASSEMBLER_TEST_RUN(JumpAroundCrash, test) { |
254 Instr* instr = Instr::At(test->entry()); | 248 Instr* instr = Instr::At(test->entry()); |
255 EXPECT(!instr->IsBreakPoint()); | 249 EXPECT(!instr->IsBreakPoint()); |
256 typedef void (*JumpAroundCrashCode)(); | 250 typedef void (*JumpAroundCrashCode)(); |
257 reinterpret_cast<JumpAroundCrashCode>(test->entry())(); | 251 reinterpret_cast<JumpAroundCrashCode>(test->entry())(); |
258 } | 252 } |
259 | 253 |
260 | |
261 ASSEMBLER_TEST_GENERATE(SimpleLoop, assembler) { | 254 ASSEMBLER_TEST_GENERATE(SimpleLoop, assembler) { |
262 __ movq(RAX, Immediate(0)); | 255 __ movq(RAX, Immediate(0)); |
263 __ movq(RCX, Immediate(0)); | 256 __ movq(RCX, Immediate(0)); |
264 Label loop; | 257 Label loop; |
265 __ Bind(&loop); | 258 __ Bind(&loop); |
266 __ addq(RAX, Immediate(2)); | 259 __ addq(RAX, Immediate(2)); |
267 __ incq(RCX); | 260 __ incq(RCX); |
268 __ cmpq(RCX, Immediate(87)); | 261 __ cmpq(RCX, Immediate(87)); |
269 __ j(LESS, &loop); | 262 __ j(LESS, &loop); |
270 __ ret(); | 263 __ ret(); |
271 } | 264 } |
272 | 265 |
273 | |
274 ASSEMBLER_TEST_RUN(SimpleLoop, test) { | 266 ASSEMBLER_TEST_RUN(SimpleLoop, test) { |
275 typedef int (*SimpleLoopCode)(); | 267 typedef int (*SimpleLoopCode)(); |
276 EXPECT_EQ(2 * 87, reinterpret_cast<SimpleLoopCode>(test->entry())()); | 268 EXPECT_EQ(2 * 87, reinterpret_cast<SimpleLoopCode>(test->entry())()); |
277 } | 269 } |
278 | 270 |
279 | |
280 ASSEMBLER_TEST_GENERATE(Cmpb, assembler) { | 271 ASSEMBLER_TEST_GENERATE(Cmpb, assembler) { |
281 Label done; | 272 Label done; |
282 __ movq(RAX, Immediate(1)); | 273 __ movq(RAX, Immediate(1)); |
283 __ pushq(Immediate(0xffffff11)); | 274 __ pushq(Immediate(0xffffff11)); |
284 __ cmpb(Address(RSP, 0), Immediate(0x11)); | 275 __ cmpb(Address(RSP, 0), Immediate(0x11)); |
285 __ j(EQUAL, &done, Assembler::kNearJump); | 276 __ j(EQUAL, &done, Assembler::kNearJump); |
286 __ movq(RAX, Immediate(0)); | 277 __ movq(RAX, Immediate(0)); |
287 __ Bind(&done); | 278 __ Bind(&done); |
288 __ popq(RCX); | 279 __ popq(RCX); |
289 __ ret(); | 280 __ ret(); |
290 } | 281 } |
291 | 282 |
292 | |
293 ASSEMBLER_TEST_RUN(Cmpb, test) { | 283 ASSEMBLER_TEST_RUN(Cmpb, test) { |
294 typedef int (*CmpbCode)(); | 284 typedef int (*CmpbCode)(); |
295 EXPECT_EQ(1, reinterpret_cast<CmpbCode>(test->entry())()); | 285 EXPECT_EQ(1, reinterpret_cast<CmpbCode>(test->entry())()); |
296 } | 286 } |
297 | 287 |
298 | |
299 ASSEMBLER_TEST_GENERATE(Testb, assembler) { | 288 ASSEMBLER_TEST_GENERATE(Testb, assembler) { |
300 Label done; | 289 Label done; |
301 __ movq(RAX, Immediate(1)); | 290 __ movq(RAX, Immediate(1)); |
302 __ movq(RCX, Immediate(0)); | 291 __ movq(RCX, Immediate(0)); |
303 __ pushq(Immediate(0xffffff11)); | 292 __ pushq(Immediate(0xffffff11)); |
304 __ testb(Address(RSP, 0), Immediate(0x10)); | 293 __ testb(Address(RSP, 0), Immediate(0x10)); |
305 // Fail if zero flag set. | 294 // Fail if zero flag set. |
306 __ cmoveq(RAX, RCX); | 295 __ cmoveq(RAX, RCX); |
307 __ testb(Address(RSP, 0), Immediate(0x20)); | 296 __ testb(Address(RSP, 0), Immediate(0x20)); |
308 // Fail if zero flag not set. | 297 // Fail if zero flag not set. |
309 __ j(ZERO, &done); | 298 __ j(ZERO, &done); |
310 __ movq(RAX, Immediate(0)); | 299 __ movq(RAX, Immediate(0)); |
311 __ Bind(&done); | 300 __ Bind(&done); |
312 __ popq(RCX); | 301 __ popq(RCX); |
313 __ ret(); | 302 __ ret(); |
314 } | 303 } |
315 | 304 |
316 | |
317 ASSEMBLER_TEST_RUN(Testb, test) { | 305 ASSEMBLER_TEST_RUN(Testb, test) { |
318 typedef int (*TestbCode)(); | 306 typedef int (*TestbCode)(); |
319 EXPECT_EQ(1, reinterpret_cast<TestbCode>(test->entry())()); | 307 EXPECT_EQ(1, reinterpret_cast<TestbCode>(test->entry())()); |
320 } | 308 } |
321 | 309 |
322 | |
323 ASSEMBLER_TEST_GENERATE(Increment, assembler) { | 310 ASSEMBLER_TEST_GENERATE(Increment, assembler) { |
324 __ movq(RAX, Immediate(0)); | 311 __ movq(RAX, Immediate(0)); |
325 __ pushq(RAX); | 312 __ pushq(RAX); |
326 __ incl(Address(RSP, 0)); | 313 __ incl(Address(RSP, 0)); |
327 __ incq(Address(RSP, 0)); | 314 __ incq(Address(RSP, 0)); |
328 __ movq(RCX, Address(RSP, 0)); | 315 __ movq(RCX, Address(RSP, 0)); |
329 __ incq(RCX); | 316 __ incq(RCX); |
330 __ popq(RAX); | 317 __ popq(RAX); |
331 __ movq(RAX, RCX); | 318 __ movq(RAX, RCX); |
332 __ ret(); | 319 __ ret(); |
333 } | 320 } |
334 | 321 |
335 | |
336 ASSEMBLER_TEST_RUN(Increment, test) { | 322 ASSEMBLER_TEST_RUN(Increment, test) { |
337 typedef int (*IncrementCode)(); | 323 typedef int (*IncrementCode)(); |
338 EXPECT_EQ(3, reinterpret_cast<IncrementCode>(test->entry())()); | 324 EXPECT_EQ(3, reinterpret_cast<IncrementCode>(test->entry())()); |
339 } | 325 } |
340 | 326 |
341 | |
342 ASSEMBLER_TEST_GENERATE(IncrementLong, assembler) { | 327 ASSEMBLER_TEST_GENERATE(IncrementLong, assembler) { |
343 __ movq(RAX, Immediate(0xffffffff)); | 328 __ movq(RAX, Immediate(0xffffffff)); |
344 __ pushq(RAX); | 329 __ pushq(RAX); |
345 __ incq(Address(RSP, 0)); | 330 __ incq(Address(RSP, 0)); |
346 __ movq(RCX, Address(RSP, 0)); | 331 __ movq(RCX, Address(RSP, 0)); |
347 __ incq(RCX); | 332 __ incq(RCX); |
348 __ popq(RAX); | 333 __ popq(RAX); |
349 __ movq(RAX, RCX); | 334 __ movq(RAX, RCX); |
350 __ ret(); | 335 __ ret(); |
351 } | 336 } |
352 | 337 |
353 | |
354 ASSEMBLER_TEST_RUN(IncrementLong, test) { | 338 ASSEMBLER_TEST_RUN(IncrementLong, test) { |
355 typedef int64_t (*IncrementCodeLong)(); | 339 typedef int64_t (*IncrementCodeLong)(); |
356 EXPECT_EQ(0x100000001, reinterpret_cast<IncrementCodeLong>(test->entry())()); | 340 EXPECT_EQ(0x100000001, reinterpret_cast<IncrementCodeLong>(test->entry())()); |
357 } | 341 } |
358 | 342 |
359 | |
360 ASSEMBLER_TEST_GENERATE(Decrement, assembler) { | 343 ASSEMBLER_TEST_GENERATE(Decrement, assembler) { |
361 __ movq(RAX, Immediate(3)); | 344 __ movq(RAX, Immediate(3)); |
362 __ pushq(RAX); | 345 __ pushq(RAX); |
363 __ decl(Address(RSP, 0)); | 346 __ decl(Address(RSP, 0)); |
364 __ decq(Address(RSP, 0)); | 347 __ decq(Address(RSP, 0)); |
365 __ movq(RCX, Address(RSP, 0)); | 348 __ movq(RCX, Address(RSP, 0)); |
366 __ decq(RCX); | 349 __ decq(RCX); |
367 __ popq(RAX); | 350 __ popq(RAX); |
368 __ movq(RAX, RCX); | 351 __ movq(RAX, RCX); |
369 __ ret(); | 352 __ ret(); |
370 } | 353 } |
371 | 354 |
372 | |
373 ASSEMBLER_TEST_RUN(Decrement, test) { | 355 ASSEMBLER_TEST_RUN(Decrement, test) { |
374 typedef int (*DecrementCode)(); | 356 typedef int (*DecrementCode)(); |
375 EXPECT_EQ(0, reinterpret_cast<DecrementCode>(test->entry())()); | 357 EXPECT_EQ(0, reinterpret_cast<DecrementCode>(test->entry())()); |
376 } | 358 } |
377 | 359 |
378 | |
379 ASSEMBLER_TEST_GENERATE(DecrementLong, assembler) { | 360 ASSEMBLER_TEST_GENERATE(DecrementLong, assembler) { |
380 __ movq(RAX, Immediate(0x100000001)); | 361 __ movq(RAX, Immediate(0x100000001)); |
381 __ pushq(RAX); | 362 __ pushq(RAX); |
382 __ decq(Address(RSP, 0)); | 363 __ decq(Address(RSP, 0)); |
383 __ movq(RCX, Address(RSP, 0)); | 364 __ movq(RCX, Address(RSP, 0)); |
384 __ decq(RCX); | 365 __ decq(RCX); |
385 __ popq(RAX); | 366 __ popq(RAX); |
386 __ movq(RAX, RCX); | 367 __ movq(RAX, RCX); |
387 __ ret(); | 368 __ ret(); |
388 } | 369 } |
389 | 370 |
390 | |
391 ASSEMBLER_TEST_RUN(DecrementLong, test) { | 371 ASSEMBLER_TEST_RUN(DecrementLong, test) { |
392 typedef int64_t (*DecrementCodeLong)(); | 372 typedef int64_t (*DecrementCodeLong)(); |
393 EXPECT_EQ(0xffffffff, reinterpret_cast<DecrementCodeLong>(test->entry())()); | 373 EXPECT_EQ(0xffffffff, reinterpret_cast<DecrementCodeLong>(test->entry())()); |
394 } | 374 } |
395 | 375 |
396 | |
397 ASSEMBLER_TEST_GENERATE(SignedMultiply, assembler) { | 376 ASSEMBLER_TEST_GENERATE(SignedMultiply, assembler) { |
398 __ movl(RAX, Immediate(2)); | 377 __ movl(RAX, Immediate(2)); |
399 __ movl(RCX, Immediate(4)); | 378 __ movl(RCX, Immediate(4)); |
400 __ imull(RAX, RCX); | 379 __ imull(RAX, RCX); |
401 __ imull(RAX, Immediate(1000)); | 380 __ imull(RAX, Immediate(1000)); |
402 __ ret(); | 381 __ ret(); |
403 } | 382 } |
404 | 383 |
405 | |
406 ASSEMBLER_TEST_RUN(SignedMultiply, test) { | 384 ASSEMBLER_TEST_RUN(SignedMultiply, test) { |
407 typedef int (*SignedMultiply)(); | 385 typedef int (*SignedMultiply)(); |
408 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply>(test->entry())()); | 386 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply>(test->entry())()); |
409 } | 387 } |
410 | 388 |
411 | |
412 ASSEMBLER_TEST_GENERATE(UnsignedMultiply, assembler) { | 389 ASSEMBLER_TEST_GENERATE(UnsignedMultiply, assembler) { |
413 __ movl(RAX, Immediate(-1)); // RAX = 0xFFFFFFFF | 390 __ movl(RAX, Immediate(-1)); // RAX = 0xFFFFFFFF |
414 __ movl(RCX, Immediate(16)); // RCX = 0x10 | 391 __ movl(RCX, Immediate(16)); // RCX = 0x10 |
415 __ mull(RCX); // RDX:RAX = RAX * RCX = 0x0FFFFFFFF0 | 392 __ mull(RCX); // RDX:RAX = RAX * RCX = 0x0FFFFFFFF0 |
416 __ movq(RAX, RDX); // Return high32(0x0FFFFFFFF0) == 0x0F | 393 __ movq(RAX, RDX); // Return high32(0x0FFFFFFFF0) == 0x0F |
417 __ ret(); | 394 __ ret(); |
418 } | 395 } |
419 | 396 |
420 | |
421 ASSEMBLER_TEST_RUN(UnsignedMultiply, test) { | 397 ASSEMBLER_TEST_RUN(UnsignedMultiply, test) { |
422 typedef int (*UnsignedMultiply)(); | 398 typedef int (*UnsignedMultiply)(); |
423 EXPECT_EQ(15, reinterpret_cast<UnsignedMultiply>(test->entry())()); | 399 EXPECT_EQ(15, reinterpret_cast<UnsignedMultiply>(test->entry())()); |
424 } | 400 } |
425 | 401 |
426 | |
427 ASSEMBLER_TEST_GENERATE(SignedMultiply64, assembler) { | 402 ASSEMBLER_TEST_GENERATE(SignedMultiply64, assembler) { |
428 __ pushq(R15); // Callee saved. | 403 __ pushq(R15); // Callee saved. |
429 __ movq(RAX, Immediate(2)); | 404 __ movq(RAX, Immediate(2)); |
430 __ movq(RCX, Immediate(4)); | 405 __ movq(RCX, Immediate(4)); |
431 __ imulq(RAX, RCX); | 406 __ imulq(RAX, RCX); |
432 | 407 |
433 __ movq(R8, Immediate(2)); | 408 __ movq(R8, Immediate(2)); |
434 __ movq(R9, Immediate(4)); | 409 __ movq(R9, Immediate(4)); |
435 __ pushq(R9); | 410 __ pushq(R9); |
436 __ imulq(R8, Address(RSP, 0)); | 411 __ imulq(R8, Address(RSP, 0)); |
437 __ popq(R9); | 412 __ popq(R9); |
438 __ addq(RAX, R8); | 413 __ addq(RAX, R8); |
439 | 414 |
440 __ movq(R10, Immediate(2)); | 415 __ movq(R10, Immediate(2)); |
441 __ movq(R11, Immediate(4)); | 416 __ movq(R11, Immediate(4)); |
442 __ imulq(R10, R11); | 417 __ imulq(R10, R11); |
443 __ addq(RAX, R10); | 418 __ addq(RAX, R10); |
444 | 419 |
445 __ movq(R15, Immediate(2)); | 420 __ movq(R15, Immediate(2)); |
446 __ imulq(R15, Immediate(4)); | 421 __ imulq(R15, Immediate(4)); |
447 __ addq(RAX, R15); | 422 __ addq(RAX, R15); |
448 __ popq(R15); | 423 __ popq(R15); |
449 __ ret(); | 424 __ ret(); |
450 } | 425 } |
451 | 426 |
452 | |
453 ASSEMBLER_TEST_RUN(SignedMultiply64, test) { | 427 ASSEMBLER_TEST_RUN(SignedMultiply64, test) { |
454 typedef int64_t (*SignedMultiply64)(); | 428 typedef int64_t (*SignedMultiply64)(); |
455 EXPECT_EQ(32, reinterpret_cast<SignedMultiply64>(test->entry())()); | 429 EXPECT_EQ(32, reinterpret_cast<SignedMultiply64>(test->entry())()); |
456 } | 430 } |
457 | 431 |
458 | |
459 static const int64_t kLargeConstant = 0x1234567887654321; | 432 static const int64_t kLargeConstant = 0x1234567887654321; |
460 static const int64_t kAnotherLargeConstant = 987654321987654321LL; | 433 static const int64_t kAnotherLargeConstant = 987654321987654321LL; |
461 static const int64_t kProductLargeConstants = 0x5bbb29a7f52fbbd1; | 434 static const int64_t kProductLargeConstants = 0x5bbb29a7f52fbbd1; |
462 | 435 |
463 | |
464 ASSEMBLER_TEST_GENERATE(SignedMultiplyLong, assembler) { | 436 ASSEMBLER_TEST_GENERATE(SignedMultiplyLong, assembler) { |
465 Label done; | 437 Label done; |
466 __ movq(RAX, Immediate(kLargeConstant)); | 438 __ movq(RAX, Immediate(kLargeConstant)); |
467 __ movq(RCX, Immediate(kAnotherLargeConstant)); | 439 __ movq(RCX, Immediate(kAnotherLargeConstant)); |
468 __ imulq(RAX, RCX); | 440 __ imulq(RAX, RCX); |
469 __ imulq(RCX, Immediate(kLargeConstant)); | 441 __ imulq(RCX, Immediate(kLargeConstant)); |
470 __ cmpq(RAX, RCX); | 442 __ cmpq(RAX, RCX); |
471 __ j(EQUAL, &done); | 443 __ j(EQUAL, &done); |
472 __ int3(); | 444 __ int3(); |
473 __ Bind(&done); | 445 __ Bind(&done); |
474 __ ret(); | 446 __ ret(); |
475 } | 447 } |
476 | 448 |
477 | |
478 ASSEMBLER_TEST_RUN(SignedMultiplyLong, test) { | 449 ASSEMBLER_TEST_RUN(SignedMultiplyLong, test) { |
479 typedef int64_t (*SignedMultiplyLong)(); | 450 typedef int64_t (*SignedMultiplyLong)(); |
480 EXPECT_EQ(kProductLargeConstants, | 451 EXPECT_EQ(kProductLargeConstants, |
481 reinterpret_cast<SignedMultiplyLong>(test->entry())()); | 452 reinterpret_cast<SignedMultiplyLong>(test->entry())()); |
482 } | 453 } |
483 | 454 |
484 | |
485 ASSEMBLER_TEST_GENERATE(OverflowSignedMultiply, assembler) { | 455 ASSEMBLER_TEST_GENERATE(OverflowSignedMultiply, assembler) { |
486 __ movl(RDX, Immediate(0)); | 456 __ movl(RDX, Immediate(0)); |
487 __ movl(RAX, Immediate(0x0fffffff)); | 457 __ movl(RAX, Immediate(0x0fffffff)); |
488 __ movl(RCX, Immediate(0x0fffffff)); | 458 __ movl(RCX, Immediate(0x0fffffff)); |
489 __ imull(RAX, RCX); | 459 __ imull(RAX, RCX); |
490 __ imull(RAX, RDX); | 460 __ imull(RAX, RDX); |
491 __ ret(); | 461 __ ret(); |
492 } | 462 } |
493 | 463 |
494 | |
495 ASSEMBLER_TEST_RUN(OverflowSignedMultiply, test) { | 464 ASSEMBLER_TEST_RUN(OverflowSignedMultiply, test) { |
496 typedef int (*OverflowSignedMultiply)(); | 465 typedef int (*OverflowSignedMultiply)(); |
497 EXPECT_EQ(0, reinterpret_cast<OverflowSignedMultiply>(test->entry())()); | 466 EXPECT_EQ(0, reinterpret_cast<OverflowSignedMultiply>(test->entry())()); |
498 } | 467 } |
499 | 468 |
500 | |
501 ASSEMBLER_TEST_GENERATE(SignedMultiply1, assembler) { | 469 ASSEMBLER_TEST_GENERATE(SignedMultiply1, assembler) { |
502 __ movl(RDX, Immediate(2)); | 470 __ movl(RDX, Immediate(2)); |
503 __ movl(RCX, Immediate(4)); | 471 __ movl(RCX, Immediate(4)); |
504 __ imull(RDX, RCX); | 472 __ imull(RDX, RCX); |
505 __ imull(RDX, Immediate(1000)); | 473 __ imull(RDX, Immediate(1000)); |
506 __ movl(RAX, RDX); | 474 __ movl(RAX, RDX); |
507 __ ret(); | 475 __ ret(); |
508 } | 476 } |
509 | 477 |
510 | |
511 ASSEMBLER_TEST_RUN(SignedMultiply1, test) { | 478 ASSEMBLER_TEST_RUN(SignedMultiply1, test) { |
512 typedef int (*SignedMultiply1)(); | 479 typedef int (*SignedMultiply1)(); |
513 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply1>(test->entry())()); | 480 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply1>(test->entry())()); |
514 } | 481 } |
515 | 482 |
516 | |
517 ASSEMBLER_TEST_GENERATE(SignedMultiply2, assembler) { | 483 ASSEMBLER_TEST_GENERATE(SignedMultiply2, assembler) { |
518 __ pushq(R15); // Callee saved. | 484 __ pushq(R15); // Callee saved. |
519 __ movl(R15, Immediate(2)); | 485 __ movl(R15, Immediate(2)); |
520 __ imull(R15, Immediate(1000)); | 486 __ imull(R15, Immediate(1000)); |
521 __ movl(RAX, R15); | 487 __ movl(RAX, R15); |
522 __ popq(R15); | 488 __ popq(R15); |
523 __ ret(); | 489 __ ret(); |
524 } | 490 } |
525 | 491 |
526 | |
527 ASSEMBLER_TEST_RUN(SignedMultiply2, test) { | 492 ASSEMBLER_TEST_RUN(SignedMultiply2, test) { |
528 typedef int (*SignedMultiply2)(); | 493 typedef int (*SignedMultiply2)(); |
529 EXPECT_EQ(2000, reinterpret_cast<SignedMultiply2>(test->entry())()); | 494 EXPECT_EQ(2000, reinterpret_cast<SignedMultiply2>(test->entry())()); |
530 } | 495 } |
531 | 496 |
532 | |
533 ASSEMBLER_TEST_GENERATE(UnsignedMultiplyLong, assembler) { | 497 ASSEMBLER_TEST_GENERATE(UnsignedMultiplyLong, assembler) { |
534 __ movq(RAX, Immediate(-1)); // RAX = 0xFFFFFFFFFFFFFFFF | 498 __ movq(RAX, Immediate(-1)); // RAX = 0xFFFFFFFFFFFFFFFF |
535 __ movq(RCX, Immediate(16)); // RCX = 0x10 | 499 __ movq(RCX, Immediate(16)); // RCX = 0x10 |
536 __ mulq(RCX); // RDX:RAX = RAX * RCX = 0x0FFFFFFFFFFFFFFFF0 | 500 __ mulq(RCX); // RDX:RAX = RAX * RCX = 0x0FFFFFFFFFFFFFFFF0 |
537 __ movq(RAX, RDX); // Return high64(0x0FFFFFFFFFFFFFFFF0) == 0x0F | 501 __ movq(RAX, RDX); // Return high64(0x0FFFFFFFFFFFFFFFF0) == 0x0F |
538 __ ret(); | 502 __ ret(); |
539 } | 503 } |
540 | 504 |
541 | |
542 ASSEMBLER_TEST_RUN(UnsignedMultiplyLong, test) { | 505 ASSEMBLER_TEST_RUN(UnsignedMultiplyLong, test) { |
543 typedef int64_t (*UnsignedMultiplyLong)(); | 506 typedef int64_t (*UnsignedMultiplyLong)(); |
544 EXPECT_EQ(15, reinterpret_cast<UnsignedMultiplyLong>(test->entry())()); | 507 EXPECT_EQ(15, reinterpret_cast<UnsignedMultiplyLong>(test->entry())()); |
545 } | 508 } |
546 | 509 |
547 | |
548 ASSEMBLER_TEST_GENERATE(SignedDivide, assembler) { | 510 ASSEMBLER_TEST_GENERATE(SignedDivide, assembler) { |
549 __ movl(RAX, Immediate(-87)); | 511 __ movl(RAX, Immediate(-87)); |
550 __ movl(RDX, Immediate(123)); | 512 __ movl(RDX, Immediate(123)); |
551 __ cdq(); | 513 __ cdq(); |
552 __ movl(RCX, Immediate(42)); | 514 __ movl(RCX, Immediate(42)); |
553 __ idivl(RCX); | 515 __ idivl(RCX); |
554 __ ret(); | 516 __ ret(); |
555 } | 517 } |
556 | 518 |
557 | |
558 ASSEMBLER_TEST_RUN(SignedDivide, test) { | 519 ASSEMBLER_TEST_RUN(SignedDivide, test) { |
559 typedef int32_t (*SignedDivide)(); | 520 typedef int32_t (*SignedDivide)(); |
560 EXPECT_EQ(-87 / 42, reinterpret_cast<SignedDivide>(test->entry())()); | 521 EXPECT_EQ(-87 / 42, reinterpret_cast<SignedDivide>(test->entry())()); |
561 } | 522 } |
562 | 523 |
563 | |
564 ASSEMBLER_TEST_GENERATE(UnsignedDivide, assembler) { | 524 ASSEMBLER_TEST_GENERATE(UnsignedDivide, assembler) { |
565 const int32_t low = 0; | 525 const int32_t low = 0; |
566 const int32_t high = 0xf0000000; | 526 const int32_t high = 0xf0000000; |
567 const int32_t divisor = 0xffffffff; | 527 const int32_t divisor = 0xffffffff; |
568 __ movl(RAX, Immediate(low)); | 528 __ movl(RAX, Immediate(low)); |
569 __ movl(RDX, Immediate(high)); | 529 __ movl(RDX, Immediate(high)); |
570 __ movl(RCX, Immediate(divisor)); | 530 __ movl(RCX, Immediate(divisor)); |
571 __ divl(RCX); // RAX = RDX:RAX / RCX = | 531 __ divl(RCX); // RAX = RDX:RAX / RCX = |
572 // = 0xf000000000000000 / 0xffffffff = 0xf0000000 | 532 // = 0xf000000000000000 / 0xffffffff = 0xf0000000 |
573 __ ret(); | 533 __ ret(); |
574 } | 534 } |
575 | 535 |
576 | |
577 ASSEMBLER_TEST_RUN(UnsignedDivide, test) { | 536 ASSEMBLER_TEST_RUN(UnsignedDivide, test) { |
578 typedef uint32_t (*UnsignedDivide)(); | 537 typedef uint32_t (*UnsignedDivide)(); |
579 EXPECT_EQ(0xf0000000, reinterpret_cast<UnsignedDivide>(test->entry())()); | 538 EXPECT_EQ(0xf0000000, reinterpret_cast<UnsignedDivide>(test->entry())()); |
580 } | 539 } |
581 | 540 |
582 | |
583 ASSEMBLER_TEST_GENERATE(SignedDivideLong, assembler) { | 541 ASSEMBLER_TEST_GENERATE(SignedDivideLong, assembler) { |
584 __ movq(RAX, Immediate(kLargeConstant)); | 542 __ movq(RAX, Immediate(kLargeConstant)); |
585 __ movq(RDX, Immediate(123)); | 543 __ movq(RDX, Immediate(123)); |
586 __ cqo(); // Clear RDX. | 544 __ cqo(); // Clear RDX. |
587 __ movq(RCX, Immediate(42)); | 545 __ movq(RCX, Immediate(42)); |
588 __ idivq(RCX); | 546 __ idivq(RCX); |
589 __ ret(); | 547 __ ret(); |
590 } | 548 } |
591 | 549 |
592 | |
593 ASSEMBLER_TEST_RUN(SignedDivideLong, test) { | 550 ASSEMBLER_TEST_RUN(SignedDivideLong, test) { |
594 typedef int64_t (*SignedDivideLong)(); | 551 typedef int64_t (*SignedDivideLong)(); |
595 EXPECT_EQ(kLargeConstant / 42, | 552 EXPECT_EQ(kLargeConstant / 42, |
596 reinterpret_cast<SignedDivideLong>(test->entry())()); | 553 reinterpret_cast<SignedDivideLong>(test->entry())()); |
597 } | 554 } |
598 | 555 |
599 | |
600 ASSEMBLER_TEST_GENERATE(UnsignedDivideLong, assembler) { | 556 ASSEMBLER_TEST_GENERATE(UnsignedDivideLong, assembler) { |
601 const int64_t low = 0; | 557 const int64_t low = 0; |
602 const int64_t high = 0xf000000000000000; | 558 const int64_t high = 0xf000000000000000; |
603 const int64_t divisor = 0xffffffffffffffff; | 559 const int64_t divisor = 0xffffffffffffffff; |
604 __ movq(RAX, Immediate(low)); | 560 __ movq(RAX, Immediate(low)); |
605 __ movq(RDX, Immediate(high)); | 561 __ movq(RDX, Immediate(high)); |
606 __ movq(RCX, Immediate(divisor)); | 562 __ movq(RCX, Immediate(divisor)); |
607 __ divq(RCX); // RAX = RDX:RAX / RCX = | 563 __ divq(RCX); // RAX = RDX:RAX / RCX = |
608 // = 0xf0000000000000000000000000000000 / | 564 // = 0xf0000000000000000000000000000000 / |
609 // 0xffffffffffffffff = 0xf000000000000000 | 565 // 0xffffffffffffffff = 0xf000000000000000 |
610 __ ret(); | 566 __ ret(); |
611 } | 567 } |
612 | 568 |
613 | |
614 ASSEMBLER_TEST_RUN(UnsignedDivideLong, test) { | 569 ASSEMBLER_TEST_RUN(UnsignedDivideLong, test) { |
615 typedef uint64_t (*UnsignedDivideLong)(); | 570 typedef uint64_t (*UnsignedDivideLong)(); |
616 EXPECT_EQ(0xf000000000000000, | 571 EXPECT_EQ(0xf000000000000000, |
617 reinterpret_cast<UnsignedDivideLong>(test->entry())()); | 572 reinterpret_cast<UnsignedDivideLong>(test->entry())()); |
618 } | 573 } |
619 | 574 |
620 | |
621 ASSEMBLER_TEST_GENERATE(Negate, assembler) { | 575 ASSEMBLER_TEST_GENERATE(Negate, assembler) { |
622 __ movq(RCX, Immediate(42)); | 576 __ movq(RCX, Immediate(42)); |
623 __ negq(RCX); | 577 __ negq(RCX); |
624 __ movq(RAX, RCX); | 578 __ movq(RAX, RCX); |
625 __ ret(); | 579 __ ret(); |
626 } | 580 } |
627 | 581 |
628 | |
629 ASSEMBLER_TEST_RUN(Negate, test) { | 582 ASSEMBLER_TEST_RUN(Negate, test) { |
630 typedef int (*Negate)(); | 583 typedef int (*Negate)(); |
631 EXPECT_EQ(-42, reinterpret_cast<Negate>(test->entry())()); | 584 EXPECT_EQ(-42, reinterpret_cast<Negate>(test->entry())()); |
632 } | 585 } |
633 | 586 |
634 | |
635 ASSEMBLER_TEST_GENERATE(BitScanReverse, assembler) { | 587 ASSEMBLER_TEST_GENERATE(BitScanReverse, assembler) { |
636 __ pushq(CallingConventions::kArg1Reg); | 588 __ pushq(CallingConventions::kArg1Reg); |
637 __ movq(RCX, Address(RSP, 0)); | 589 __ movq(RCX, Address(RSP, 0)); |
638 __ movq(RAX, Immediate(666)); // Marker for conditional write. | 590 __ movq(RAX, Immediate(666)); // Marker for conditional write. |
639 __ bsrq(RAX, RCX); | 591 __ bsrq(RAX, RCX); |
640 __ popq(RCX); | 592 __ popq(RCX); |
641 __ ret(); | 593 __ ret(); |
642 } | 594 } |
643 | 595 |
644 | |
645 ASSEMBLER_TEST_RUN(BitScanReverse, test) { | 596 ASSEMBLER_TEST_RUN(BitScanReverse, test) { |
646 typedef int (*Bsr)(int input); | 597 typedef int (*Bsr)(int input); |
647 Bsr call = reinterpret_cast<Bsr>(test->entry()); | 598 Bsr call = reinterpret_cast<Bsr>(test->entry()); |
648 EXPECT_EQ(666, call(0)); | 599 EXPECT_EQ(666, call(0)); |
649 EXPECT_EQ(0, call(1)); | 600 EXPECT_EQ(0, call(1)); |
650 EXPECT_EQ(1, call(2)); | 601 EXPECT_EQ(1, call(2)); |
651 EXPECT_EQ(1, call(3)); | 602 EXPECT_EQ(1, call(3)); |
652 EXPECT_EQ(2, call(4)); | 603 EXPECT_EQ(2, call(4)); |
653 EXPECT_EQ(5, call(42)); | 604 EXPECT_EQ(5, call(42)); |
654 EXPECT_EQ(31, call(-1)); | 605 EXPECT_EQ(31, call(-1)); |
655 } | 606 } |
656 | 607 |
657 | |
658 ASSEMBLER_TEST_GENERATE(MoveExtend, assembler) { | 608 ASSEMBLER_TEST_GENERATE(MoveExtend, assembler) { |
659 __ movq(RDX, Immediate(0xffff)); | 609 __ movq(RDX, Immediate(0xffff)); |
660 __ movzxb(RAX, RDX); // RAX = 0xff | 610 __ movzxb(RAX, RDX); // RAX = 0xff |
661 __ movsxw(R8, RDX); // R8 = -1 | 611 __ movsxw(R8, RDX); // R8 = -1 |
662 __ movzxw(RCX, RDX); // RCX = 0xffff | 612 __ movzxw(RCX, RDX); // RCX = 0xffff |
663 __ addq(R8, RCX); | 613 __ addq(R8, RCX); |
664 __ addq(RAX, R8); | 614 __ addq(RAX, R8); |
665 __ ret(); | 615 __ ret(); |
666 } | 616 } |
667 | 617 |
668 | |
669 ASSEMBLER_TEST_RUN(MoveExtend, test) { | 618 ASSEMBLER_TEST_RUN(MoveExtend, test) { |
670 typedef int (*MoveExtend)(); | 619 typedef int (*MoveExtend)(); |
671 EXPECT_EQ(0xff - 1 + 0xffff, reinterpret_cast<MoveExtend>(test->entry())()); | 620 EXPECT_EQ(0xff - 1 + 0xffff, reinterpret_cast<MoveExtend>(test->entry())()); |
672 } | 621 } |
673 | 622 |
674 | |
675 ASSEMBLER_TEST_GENERATE(MoveExtend32, assembler) { | 623 ASSEMBLER_TEST_GENERATE(MoveExtend32, assembler) { |
676 __ movq(RDX, Immediate(0xffffffff)); | 624 __ movq(RDX, Immediate(0xffffffff)); |
677 __ movsxd(RDX, RDX); | 625 __ movsxd(RDX, RDX); |
678 __ movq(RAX, Immediate(0x7fffffff)); | 626 __ movq(RAX, Immediate(0x7fffffff)); |
679 __ movsxd(RAX, RAX); | 627 __ movsxd(RAX, RAX); |
680 __ addq(RAX, RDX); | 628 __ addq(RAX, RDX); |
681 __ ret(); | 629 __ ret(); |
682 } | 630 } |
683 | 631 |
684 | |
685 ASSEMBLER_TEST_RUN(MoveExtend32, test) { | 632 ASSEMBLER_TEST_RUN(MoveExtend32, test) { |
686 typedef intptr_t (*MoveExtend)(); | 633 typedef intptr_t (*MoveExtend)(); |
687 EXPECT_EQ(0x7ffffffe, reinterpret_cast<MoveExtend>(test->entry())()); | 634 EXPECT_EQ(0x7ffffffe, reinterpret_cast<MoveExtend>(test->entry())()); |
688 } | 635 } |
689 | 636 |
690 | |
691 ASSEMBLER_TEST_GENERATE(MoveExtendMemory, assembler) { | 637 ASSEMBLER_TEST_GENERATE(MoveExtendMemory, assembler) { |
692 __ movq(RDX, Immediate(0x123456781234ffff)); | 638 __ movq(RDX, Immediate(0x123456781234ffff)); |
693 | 639 |
694 __ pushq(RDX); | 640 __ pushq(RDX); |
695 __ movzxb(RAX, Address(RSP, 0)); // RAX = 0xff | 641 __ movzxb(RAX, Address(RSP, 0)); // RAX = 0xff |
696 __ movsxw(R8, Address(RSP, 0)); // R8 = -1 | 642 __ movsxw(R8, Address(RSP, 0)); // R8 = -1 |
697 __ movzxw(RCX, Address(RSP, 0)); // RCX = 0xffff | 643 __ movzxw(RCX, Address(RSP, 0)); // RCX = 0xffff |
698 __ addq(RSP, Immediate(kWordSize)); | 644 __ addq(RSP, Immediate(kWordSize)); |
699 | 645 |
700 __ addq(R8, RCX); | 646 __ addq(R8, RCX); |
701 __ addq(RAX, R8); | 647 __ addq(RAX, R8); |
702 __ ret(); | 648 __ ret(); |
703 } | 649 } |
704 | 650 |
705 | |
706 ASSEMBLER_TEST_RUN(MoveExtendMemory, test) { | 651 ASSEMBLER_TEST_RUN(MoveExtendMemory, test) { |
707 typedef int (*MoveExtendMemory)(); | 652 typedef int (*MoveExtendMemory)(); |
708 EXPECT_EQ(0xff - 1 + 0xffff, | 653 EXPECT_EQ(0xff - 1 + 0xffff, |
709 reinterpret_cast<MoveExtendMemory>(test->entry())()); | 654 reinterpret_cast<MoveExtendMemory>(test->entry())()); |
710 } | 655 } |
711 | 656 |
712 | |
713 ASSEMBLER_TEST_GENERATE(MoveExtend32Memory, assembler) { | 657 ASSEMBLER_TEST_GENERATE(MoveExtend32Memory, assembler) { |
714 __ pushq(Immediate(0xffffffff)); | 658 __ pushq(Immediate(0xffffffff)); |
715 __ pushq(Immediate(0x7fffffff)); | 659 __ pushq(Immediate(0x7fffffff)); |
716 __ movsxd(RDX, Address(RSP, kWordSize)); | 660 __ movsxd(RDX, Address(RSP, kWordSize)); |
717 __ movsxd(RAX, Address(RSP, 0)); | 661 __ movsxd(RAX, Address(RSP, 0)); |
718 __ addq(RSP, Immediate(kWordSize * 2)); | 662 __ addq(RSP, Immediate(kWordSize * 2)); |
719 | 663 |
720 __ addq(RAX, RDX); | 664 __ addq(RAX, RDX); |
721 __ ret(); | 665 __ ret(); |
722 } | 666 } |
723 | 667 |
724 | |
725 ASSEMBLER_TEST_RUN(MoveExtend32Memory, test) { | 668 ASSEMBLER_TEST_RUN(MoveExtend32Memory, test) { |
726 typedef intptr_t (*MoveExtend)(); | 669 typedef intptr_t (*MoveExtend)(); |
727 EXPECT_EQ(0x7ffffffe, reinterpret_cast<MoveExtend>(test->entry())()); | 670 EXPECT_EQ(0x7ffffffe, reinterpret_cast<MoveExtend>(test->entry())()); |
728 } | 671 } |
729 | 672 |
730 | |
731 ASSEMBLER_TEST_GENERATE(MoveWord, assembler) { | 673 ASSEMBLER_TEST_GENERATE(MoveWord, assembler) { |
732 __ xorq(RAX, RAX); | 674 __ xorq(RAX, RAX); |
733 __ pushq(Immediate(0)); | 675 __ pushq(Immediate(0)); |
734 __ movq(RAX, RSP); | 676 __ movq(RAX, RSP); |
735 __ movq(RCX, Immediate(-1)); | 677 __ movq(RCX, Immediate(-1)); |
736 __ movw(Address(RAX, 0), RCX); | 678 __ movw(Address(RAX, 0), RCX); |
737 __ movzxw(RAX, Address(RAX, 0)); // RAX = 0xffff | 679 __ movzxw(RAX, Address(RAX, 0)); // RAX = 0xffff |
738 __ addq(RSP, Immediate(kWordSize)); | 680 __ addq(RSP, Immediate(kWordSize)); |
739 __ ret(); | 681 __ ret(); |
740 } | 682 } |
741 | 683 |
742 | |
743 ASSEMBLER_TEST_RUN(MoveWord, test) { | 684 ASSEMBLER_TEST_RUN(MoveWord, test) { |
744 typedef int (*MoveWord)(); | 685 typedef int (*MoveWord)(); |
745 EXPECT_EQ(0xffff, reinterpret_cast<MoveWord>(test->entry())()); | 686 EXPECT_EQ(0xffff, reinterpret_cast<MoveWord>(test->entry())()); |
746 } | 687 } |
747 | 688 |
748 | |
749 ASSEMBLER_TEST_GENERATE(MoveWordRex, assembler) { | 689 ASSEMBLER_TEST_GENERATE(MoveWordRex, assembler) { |
750 __ pushq(Immediate(0)); | 690 __ pushq(Immediate(0)); |
751 __ movq(R8, RSP); | 691 __ movq(R8, RSP); |
752 __ movq(R9, Immediate(-1)); | 692 __ movq(R9, Immediate(-1)); |
753 __ movw(Address(R8, 0), R9); | 693 __ movw(Address(R8, 0), R9); |
754 __ movzxw(R8, Address(R8, 0)); // 0xffff | 694 __ movzxw(R8, Address(R8, 0)); // 0xffff |
755 __ xorq(RAX, RAX); | 695 __ xorq(RAX, RAX); |
756 __ addq(RAX, R8); // RAX = 0xffff | 696 __ addq(RAX, R8); // RAX = 0xffff |
757 __ addq(RSP, Immediate(kWordSize)); | 697 __ addq(RSP, Immediate(kWordSize)); |
758 __ ret(); | 698 __ ret(); |
759 } | 699 } |
760 | 700 |
761 | |
762 ASSEMBLER_TEST_RUN(MoveWordRex, test) { | 701 ASSEMBLER_TEST_RUN(MoveWordRex, test) { |
763 typedef int (*MoveWordRex)(); | 702 typedef int (*MoveWordRex)(); |
764 EXPECT_EQ(0xffff, reinterpret_cast<MoveWordRex>(test->entry())()); | 703 EXPECT_EQ(0xffff, reinterpret_cast<MoveWordRex>(test->entry())()); |
765 } | 704 } |
766 | 705 |
767 | |
768 ASSEMBLER_TEST_GENERATE(LongAddReg, assembler) { | 706 ASSEMBLER_TEST_GENERATE(LongAddReg, assembler) { |
769 __ pushq(CallingConventions::kArg2Reg); | 707 __ pushq(CallingConventions::kArg2Reg); |
770 __ pushq(CallingConventions::kArg1Reg); | 708 __ pushq(CallingConventions::kArg1Reg); |
771 __ movl(RAX, Address(RSP, 0)); // left low. | 709 __ movl(RAX, Address(RSP, 0)); // left low. |
772 __ movl(RDX, Address(RSP, 4)); // left high. | 710 __ movl(RDX, Address(RSP, 4)); // left high. |
773 __ movl(RCX, Address(RSP, 8)); // right low. | 711 __ movl(RCX, Address(RSP, 8)); // right low. |
774 __ movl(R8, Address(RSP, 12)); // right high | 712 __ movl(R8, Address(RSP, 12)); // right high |
775 __ addl(RAX, RCX); | 713 __ addl(RAX, RCX); |
776 __ adcl(RDX, R8); | 714 __ adcl(RDX, R8); |
777 // Result is in RAX/RDX. | 715 // Result is in RAX/RDX. |
778 __ movl(Address(RSP, 0), RAX); // result low. | 716 __ movl(Address(RSP, 0), RAX); // result low. |
779 __ movl(Address(RSP, 4), RDX); // result high. | 717 __ movl(Address(RSP, 4), RDX); // result high. |
780 __ popq(RAX); | 718 __ popq(RAX); |
781 __ popq(RDX); | 719 __ popq(RDX); |
782 __ ret(); | 720 __ ret(); |
783 } | 721 } |
784 | 722 |
785 | |
786 ASSEMBLER_TEST_RUN(LongAddReg, test) { | 723 ASSEMBLER_TEST_RUN(LongAddReg, test) { |
787 typedef int64_t (*LongAddRegCode)(int64_t a, int64_t b); | 724 typedef int64_t (*LongAddRegCode)(int64_t a, int64_t b); |
788 int64_t a = 12; | 725 int64_t a = 12; |
789 int64_t b = 14; | 726 int64_t b = 14; |
790 int64_t res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); | 727 int64_t res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); |
791 EXPECT_EQ((a + b), res); | 728 EXPECT_EQ((a + b), res); |
792 a = 2147483647; | 729 a = 2147483647; |
793 b = 600000; | 730 b = 600000; |
794 res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); | 731 res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); |
795 EXPECT_EQ((a + b), res); | 732 EXPECT_EQ((a + b), res); |
796 } | 733 } |
797 | 734 |
798 | |
799 ASSEMBLER_TEST_GENERATE(LongAddImmediate, assembler) { | 735 ASSEMBLER_TEST_GENERATE(LongAddImmediate, assembler) { |
800 __ pushq(CallingConventions::kArg1Reg); | 736 __ pushq(CallingConventions::kArg1Reg); |
801 __ movl(RAX, Address(RSP, 0)); // left low. | 737 __ movl(RAX, Address(RSP, 0)); // left low. |
802 __ movl(RDX, Address(RSP, 4)); // left high. | 738 __ movl(RDX, Address(RSP, 4)); // left high. |
803 __ addl(RAX, Immediate(12)); // right low immediate. | 739 __ addl(RAX, Immediate(12)); // right low immediate. |
804 __ adcl(RDX, Immediate(11)); // right high immediate. | 740 __ adcl(RDX, Immediate(11)); // right high immediate. |
805 // Result is in RAX/RDX. | 741 // Result is in RAX/RDX. |
806 __ movl(Address(RSP, 0), RAX); // result low. | 742 __ movl(Address(RSP, 0), RAX); // result low. |
807 __ movl(Address(RSP, 4), RDX); // result high. | 743 __ movl(Address(RSP, 4), RDX); // result high. |
808 __ popq(RAX); | 744 __ popq(RAX); |
809 __ ret(); | 745 __ ret(); |
810 } | 746 } |
811 | 747 |
812 | |
813 ASSEMBLER_TEST_RUN(LongAddImmediate, test) { | 748 ASSEMBLER_TEST_RUN(LongAddImmediate, test) { |
814 typedef int64_t (*LongAddImmediateCode)(int64_t a); | 749 typedef int64_t (*LongAddImmediateCode)(int64_t a); |
815 int64_t a = (13LL << 32) + 14; | 750 int64_t a = (13LL << 32) + 14; |
816 int64_t b = (11LL << 32) + 12; | 751 int64_t b = (11LL << 32) + 12; |
817 int64_t res = reinterpret_cast<LongAddImmediateCode>(test->entry())(a); | 752 int64_t res = reinterpret_cast<LongAddImmediateCode>(test->entry())(a); |
818 EXPECT_EQ((a + b), res); | 753 EXPECT_EQ((a + b), res); |
819 a = (13LL << 32) - 1; | 754 a = (13LL << 32) - 1; |
820 res = reinterpret_cast<LongAddImmediateCode>(test->entry())(a); | 755 res = reinterpret_cast<LongAddImmediateCode>(test->entry())(a); |
821 EXPECT_EQ((a + b), res); | 756 EXPECT_EQ((a + b), res); |
822 } | 757 } |
823 | 758 |
824 | |
825 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { | 759 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { |
826 __ pushq(CallingConventions::kArg2Reg); | 760 __ pushq(CallingConventions::kArg2Reg); |
827 __ pushq(CallingConventions::kArg1Reg); | 761 __ pushq(CallingConventions::kArg1Reg); |
828 __ movl(RAX, Address(RSP, 0)); // left low. | 762 __ movl(RAX, Address(RSP, 0)); // left low. |
829 __ movl(RDX, Address(RSP, 4)); // left high. | 763 __ movl(RDX, Address(RSP, 4)); // left high. |
830 __ addl(RAX, Address(RSP, 8)); // low. | 764 __ addl(RAX, Address(RSP, 8)); // low. |
831 __ adcl(RDX, Address(RSP, 12)); // high. | 765 __ adcl(RDX, Address(RSP, 12)); // high. |
832 // Result is in RAX/RDX. | 766 // Result is in RAX/RDX. |
833 __ movl(Address(RSP, 0), RAX); // result low. | 767 __ movl(Address(RSP, 0), RAX); // result low. |
834 __ movl(Address(RSP, 4), RDX); // result high. | 768 __ movl(Address(RSP, 4), RDX); // result high. |
835 __ popq(RAX); | 769 __ popq(RAX); |
836 __ popq(RDX); | 770 __ popq(RDX); |
837 __ ret(); | 771 __ ret(); |
838 } | 772 } |
839 | 773 |
840 | |
841 ASSEMBLER_TEST_RUN(LongAddAddress, test) { | 774 ASSEMBLER_TEST_RUN(LongAddAddress, test) { |
842 typedef int64_t (*LongAddAddressCode)(int64_t a, int64_t b); | 775 typedef int64_t (*LongAddAddressCode)(int64_t a, int64_t b); |
843 int64_t a = 12; | 776 int64_t a = 12; |
844 int64_t b = 14; | 777 int64_t b = 14; |
845 int64_t res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); | 778 int64_t res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); |
846 EXPECT_EQ((a + b), res); | 779 EXPECT_EQ((a + b), res); |
847 a = 2147483647; | 780 a = 2147483647; |
848 b = 600000; | 781 b = 600000; |
849 res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); | 782 res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); |
850 EXPECT_EQ((a + b), res); | 783 EXPECT_EQ((a + b), res); |
851 } | 784 } |
852 | 785 |
853 | |
854 ASSEMBLER_TEST_GENERATE(LongSubReg, assembler) { | 786 ASSEMBLER_TEST_GENERATE(LongSubReg, assembler) { |
855 __ pushq(CallingConventions::kArg2Reg); | 787 __ pushq(CallingConventions::kArg2Reg); |
856 __ pushq(CallingConventions::kArg1Reg); | 788 __ pushq(CallingConventions::kArg1Reg); |
857 __ movl(RAX, Address(RSP, 0)); // left low. | 789 __ movl(RAX, Address(RSP, 0)); // left low. |
858 __ movl(RDX, Address(RSP, 4)); // left high. | 790 __ movl(RDX, Address(RSP, 4)); // left high. |
859 __ movl(RCX, Address(RSP, 8)); // right low. | 791 __ movl(RCX, Address(RSP, 8)); // right low. |
860 __ movl(R8, Address(RSP, 12)); // right high | 792 __ movl(R8, Address(RSP, 12)); // right high |
861 __ subl(RAX, RCX); | 793 __ subl(RAX, RCX); |
862 __ sbbl(RDX, R8); | 794 __ sbbl(RDX, R8); |
863 // Result is in RAX/RDX. | 795 // Result is in RAX/RDX. |
864 __ movl(Address(RSP, 0), RAX); // result low. | 796 __ movl(Address(RSP, 0), RAX); // result low. |
865 __ movl(Address(RSP, 4), RDX); // result high. | 797 __ movl(Address(RSP, 4), RDX); // result high. |
866 __ popq(RAX); | 798 __ popq(RAX); |
867 __ popq(RDX); | 799 __ popq(RDX); |
868 __ ret(); | 800 __ ret(); |
869 } | 801 } |
870 | 802 |
871 | |
872 ASSEMBLER_TEST_RUN(LongSubReg, test) { | 803 ASSEMBLER_TEST_RUN(LongSubReg, test) { |
873 typedef int64_t (*LongSubRegCode)(int64_t a, int64_t b); | 804 typedef int64_t (*LongSubRegCode)(int64_t a, int64_t b); |
874 int64_t a = 12; | 805 int64_t a = 12; |
875 int64_t b = 14; | 806 int64_t b = 14; |
876 int64_t res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); | 807 int64_t res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); |
877 EXPECT_EQ((a - b), res); | 808 EXPECT_EQ((a - b), res); |
878 a = 600000; | 809 a = 600000; |
879 b = 2147483647; | 810 b = 2147483647; |
880 res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); | 811 res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); |
881 EXPECT_EQ((a - b), res); | 812 EXPECT_EQ((a - b), res); |
882 } | 813 } |
883 | 814 |
884 | |
885 ASSEMBLER_TEST_GENERATE(LongSubImmediate, assembler) { | 815 ASSEMBLER_TEST_GENERATE(LongSubImmediate, assembler) { |
886 __ pushq(CallingConventions::kArg1Reg); | 816 __ pushq(CallingConventions::kArg1Reg); |
887 __ movl(RAX, Address(RSP, 0)); // left low. | 817 __ movl(RAX, Address(RSP, 0)); // left low. |
888 __ movl(RDX, Address(RSP, 4)); // left high. | 818 __ movl(RDX, Address(RSP, 4)); // left high. |
889 __ subl(RAX, Immediate(12)); // right low immediate. | 819 __ subl(RAX, Immediate(12)); // right low immediate. |
890 __ sbbl(RDX, Immediate(11)); // right high immediate. | 820 __ sbbl(RDX, Immediate(11)); // right high immediate. |
891 // Result is in RAX/RDX. | 821 // Result is in RAX/RDX. |
892 __ movl(Address(RSP, 0), RAX); // result low. | 822 __ movl(Address(RSP, 0), RAX); // result low. |
893 __ movl(Address(RSP, 4), RDX); // result high. | 823 __ movl(Address(RSP, 4), RDX); // result high. |
894 __ popq(RAX); | 824 __ popq(RAX); |
895 __ ret(); | 825 __ ret(); |
896 } | 826 } |
897 | 827 |
898 | |
899 ASSEMBLER_TEST_RUN(LongSubImmediate, test) { | 828 ASSEMBLER_TEST_RUN(LongSubImmediate, test) { |
900 typedef int64_t (*LongSubImmediateCode)(int64_t a); | 829 typedef int64_t (*LongSubImmediateCode)(int64_t a); |
901 int64_t a = (13LL << 32) + 14; | 830 int64_t a = (13LL << 32) + 14; |
902 int64_t b = (11LL << 32) + 12; | 831 int64_t b = (11LL << 32) + 12; |
903 int64_t res = reinterpret_cast<LongSubImmediateCode>(test->entry())(a); | 832 int64_t res = reinterpret_cast<LongSubImmediateCode>(test->entry())(a); |
904 EXPECT_EQ((a - b), res); | 833 EXPECT_EQ((a - b), res); |
905 a = (13LL << 32) + 10; | 834 a = (13LL << 32) + 10; |
906 res = reinterpret_cast<LongSubImmediateCode>(test->entry())(a); | 835 res = reinterpret_cast<LongSubImmediateCode>(test->entry())(a); |
907 EXPECT_EQ((a - b), res); | 836 EXPECT_EQ((a - b), res); |
908 } | 837 } |
909 | 838 |
910 | |
911 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { | 839 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { |
912 __ pushq(CallingConventions::kArg2Reg); | 840 __ pushq(CallingConventions::kArg2Reg); |
913 __ pushq(CallingConventions::kArg1Reg); | 841 __ pushq(CallingConventions::kArg1Reg); |
914 __ movl(RAX, Address(RSP, 0)); // left low. | 842 __ movl(RAX, Address(RSP, 0)); // left low. |
915 __ movl(RDX, Address(RSP, 4)); // left high. | 843 __ movl(RDX, Address(RSP, 4)); // left high. |
916 __ subl(RAX, Address(RSP, 8)); // low. | 844 __ subl(RAX, Address(RSP, 8)); // low. |
917 __ sbbl(RDX, Address(RSP, 12)); // high. | 845 __ sbbl(RDX, Address(RSP, 12)); // high. |
918 // Result is in RAX/RDX. | 846 // Result is in RAX/RDX. |
919 __ movl(Address(RSP, 0), RAX); // result low. | 847 __ movl(Address(RSP, 0), RAX); // result low. |
920 __ movl(Address(RSP, 4), RDX); // result high. | 848 __ movl(Address(RSP, 4), RDX); // result high. |
921 __ popq(RAX); | 849 __ popq(RAX); |
922 __ popq(RDX); | 850 __ popq(RDX); |
923 __ ret(); | 851 __ ret(); |
924 } | 852 } |
925 | 853 |
926 | |
927 ASSEMBLER_TEST_RUN(LongSubAddress, test) { | 854 ASSEMBLER_TEST_RUN(LongSubAddress, test) { |
928 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); | 855 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); |
929 int64_t a = 12; | 856 int64_t a = 12; |
930 int64_t b = 14; | 857 int64_t b = 14; |
931 int64_t res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); | 858 int64_t res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); |
932 EXPECT_EQ((a - b), res); | 859 EXPECT_EQ((a - b), res); |
933 a = 600000; | 860 a = 600000; |
934 b = 2147483647; | 861 b = 2147483647; |
935 res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); | 862 res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); |
936 EXPECT_EQ((a - b), res); | 863 EXPECT_EQ((a - b), res); |
937 } | 864 } |
938 | 865 |
939 | |
940 ASSEMBLER_TEST_GENERATE(AddReg, assembler) { | 866 ASSEMBLER_TEST_GENERATE(AddReg, assembler) { |
941 __ movq(R10, CallingConventions::kArg1Reg); // al. | 867 __ movq(R10, CallingConventions::kArg1Reg); // al. |
942 __ addq(R10, CallingConventions::kArg3Reg); // bl. | 868 __ addq(R10, CallingConventions::kArg3Reg); // bl. |
943 __ movq(RAX, CallingConventions::kArg2Reg); // ah. | 869 __ movq(RAX, CallingConventions::kArg2Reg); // ah. |
944 __ adcq(RAX, CallingConventions::kArg4Reg); // bh. | 870 __ adcq(RAX, CallingConventions::kArg4Reg); // bh. |
945 // RAX = high64(ah:al + bh:bl). | 871 // RAX = high64(ah:al + bh:bl). |
946 __ ret(); | 872 __ ret(); |
947 } | 873 } |
948 | 874 |
949 | |
950 ASSEMBLER_TEST_RUN(AddReg, test) { | 875 ASSEMBLER_TEST_RUN(AddReg, test) { |
951 typedef int64_t (*AddRegCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); | 876 typedef int64_t (*AddRegCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); |
952 int64_t al = 11; | 877 int64_t al = 11; |
953 int64_t ah = 12; | 878 int64_t ah = 12; |
954 int64_t bl = 13; | 879 int64_t bl = 13; |
955 int64_t bh = 14; | 880 int64_t bh = 14; |
956 int64_t res = reinterpret_cast<AddRegCode>(test->entry())(al, ah, bl, bh); | 881 int64_t res = reinterpret_cast<AddRegCode>(test->entry())(al, ah, bl, bh); |
957 EXPECT_EQ((ah + bh), res); | 882 EXPECT_EQ((ah + bh), res); |
958 al = -1; | 883 al = -1; |
959 res = reinterpret_cast<AddRegCode>(test->entry())(al, ah, bl, bh); | 884 res = reinterpret_cast<AddRegCode>(test->entry())(al, ah, bl, bh); |
960 EXPECT_EQ((ah + bh + 1), res); | 885 EXPECT_EQ((ah + bh + 1), res); |
961 } | 886 } |
962 | 887 |
963 | |
964 ASSEMBLER_TEST_GENERATE(AddImmediate, assembler) { | 888 ASSEMBLER_TEST_GENERATE(AddImmediate, assembler) { |
965 __ movq(R10, CallingConventions::kArg1Reg); // al. | 889 __ movq(R10, CallingConventions::kArg1Reg); // al. |
966 __ addq(R10, Immediate(13)); // bl. | 890 __ addq(R10, Immediate(13)); // bl. |
967 __ movq(RAX, CallingConventions::kArg2Reg); // ah. | 891 __ movq(RAX, CallingConventions::kArg2Reg); // ah. |
968 __ adcq(RAX, Immediate(14)); // bh. | 892 __ adcq(RAX, Immediate(14)); // bh. |
969 // RAX = high64(ah:al + bh:bl). | 893 // RAX = high64(ah:al + bh:bl). |
970 __ ret(); | 894 __ ret(); |
971 } | 895 } |
972 | 896 |
973 | |
974 ASSEMBLER_TEST_RUN(AddImmediate, test) { | 897 ASSEMBLER_TEST_RUN(AddImmediate, test) { |
975 typedef int64_t (*AddImmediateCode)(int64_t al, int64_t ah); | 898 typedef int64_t (*AddImmediateCode)(int64_t al, int64_t ah); |
976 int64_t al = 11; | 899 int64_t al = 11; |
977 int64_t ah = 12; | 900 int64_t ah = 12; |
978 int64_t bh = 14; | 901 int64_t bh = 14; |
979 int64_t res = reinterpret_cast<AddImmediateCode>(test->entry())(al, ah); | 902 int64_t res = reinterpret_cast<AddImmediateCode>(test->entry())(al, ah); |
980 EXPECT_EQ((ah + bh), res); | 903 EXPECT_EQ((ah + bh), res); |
981 al = -1; | 904 al = -1; |
982 res = reinterpret_cast<AddImmediateCode>(test->entry())(al, ah); | 905 res = reinterpret_cast<AddImmediateCode>(test->entry())(al, ah); |
983 EXPECT_EQ((ah + bh + 1), res); | 906 EXPECT_EQ((ah + bh + 1), res); |
984 } | 907 } |
985 | 908 |
986 | |
987 ASSEMBLER_TEST_GENERATE(AddAddress, assembler) { | 909 ASSEMBLER_TEST_GENERATE(AddAddress, assembler) { |
988 __ pushq(CallingConventions::kArg4Reg); | 910 __ pushq(CallingConventions::kArg4Reg); |
989 __ pushq(CallingConventions::kArg3Reg); | 911 __ pushq(CallingConventions::kArg3Reg); |
990 __ pushq(CallingConventions::kArg2Reg); | 912 __ pushq(CallingConventions::kArg2Reg); |
991 __ pushq(CallingConventions::kArg1Reg); | 913 __ pushq(CallingConventions::kArg1Reg); |
992 __ movq(R10, Address(RSP, 0 * kWordSize)); // al. | 914 __ movq(R10, Address(RSP, 0 * kWordSize)); // al. |
993 __ addq(R10, Address(RSP, 2 * kWordSize)); // bl. | 915 __ addq(R10, Address(RSP, 2 * kWordSize)); // bl. |
994 __ movq(RAX, Address(RSP, 1 * kWordSize)); // ah. | 916 __ movq(RAX, Address(RSP, 1 * kWordSize)); // ah. |
995 __ adcq(RAX, Address(RSP, 3 * kWordSize)); // bh. | 917 __ adcq(RAX, Address(RSP, 3 * kWordSize)); // bh. |
996 // RAX = high64(ah:al + bh:bl). | 918 // RAX = high64(ah:al + bh:bl). |
997 __ Drop(4); | 919 __ Drop(4); |
998 __ ret(); | 920 __ ret(); |
999 } | 921 } |
1000 | 922 |
1001 | |
1002 ASSEMBLER_TEST_RUN(AddAddress, test) { | 923 ASSEMBLER_TEST_RUN(AddAddress, test) { |
1003 typedef int64_t (*AddCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); | 924 typedef int64_t (*AddCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); |
1004 int64_t al = 11; | 925 int64_t al = 11; |
1005 int64_t ah = 12; | 926 int64_t ah = 12; |
1006 int64_t bl = 13; | 927 int64_t bl = 13; |
1007 int64_t bh = 14; | 928 int64_t bh = 14; |
1008 int64_t res = reinterpret_cast<AddCode>(test->entry())(al, ah, bl, bh); | 929 int64_t res = reinterpret_cast<AddCode>(test->entry())(al, ah, bl, bh); |
1009 EXPECT_EQ((ah + bh), res); | 930 EXPECT_EQ((ah + bh), res); |
1010 al = -1; | 931 al = -1; |
1011 res = reinterpret_cast<AddCode>(test->entry())(al, ah, bl, bh); | 932 res = reinterpret_cast<AddCode>(test->entry())(al, ah, bl, bh); |
1012 EXPECT_EQ((ah + bh + 1), res); | 933 EXPECT_EQ((ah + bh + 1), res); |
1013 } | 934 } |
1014 | 935 |
1015 | |
1016 ASSEMBLER_TEST_GENERATE(SubReg, assembler) { | 936 ASSEMBLER_TEST_GENERATE(SubReg, assembler) { |
1017 __ movq(R10, CallingConventions::kArg1Reg); // al. | 937 __ movq(R10, CallingConventions::kArg1Reg); // al. |
1018 __ subq(R10, CallingConventions::kArg3Reg); // bl. | 938 __ subq(R10, CallingConventions::kArg3Reg); // bl. |
1019 __ movq(RAX, CallingConventions::kArg2Reg); // ah. | 939 __ movq(RAX, CallingConventions::kArg2Reg); // ah. |
1020 __ sbbq(RAX, CallingConventions::kArg4Reg); // bh. | 940 __ sbbq(RAX, CallingConventions::kArg4Reg); // bh. |
1021 // RAX = high64(ah:al - bh:bl). | 941 // RAX = high64(ah:al - bh:bl). |
1022 __ ret(); | 942 __ ret(); |
1023 } | 943 } |
1024 | 944 |
1025 | |
1026 ASSEMBLER_TEST_RUN(SubReg, test) { | 945 ASSEMBLER_TEST_RUN(SubReg, test) { |
1027 typedef int64_t (*SubRegCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); | 946 typedef int64_t (*SubRegCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); |
1028 int64_t al = 14; | 947 int64_t al = 14; |
1029 int64_t ah = 13; | 948 int64_t ah = 13; |
1030 int64_t bl = 12; | 949 int64_t bl = 12; |
1031 int64_t bh = 11; | 950 int64_t bh = 11; |
1032 int64_t res = reinterpret_cast<SubRegCode>(test->entry())(al, ah, bl, bh); | 951 int64_t res = reinterpret_cast<SubRegCode>(test->entry())(al, ah, bl, bh); |
1033 EXPECT_EQ((ah - bh), res); | 952 EXPECT_EQ((ah - bh), res); |
1034 al = 10; | 953 al = 10; |
1035 res = reinterpret_cast<SubRegCode>(test->entry())(al, ah, bl, bh); | 954 res = reinterpret_cast<SubRegCode>(test->entry())(al, ah, bl, bh); |
1036 EXPECT_EQ((ah - bh - 1), res); | 955 EXPECT_EQ((ah - bh - 1), res); |
1037 } | 956 } |
1038 | 957 |
1039 | |
1040 ASSEMBLER_TEST_GENERATE(SubImmediate, assembler) { | 958 ASSEMBLER_TEST_GENERATE(SubImmediate, assembler) { |
1041 __ movq(R10, CallingConventions::kArg1Reg); // al. | 959 __ movq(R10, CallingConventions::kArg1Reg); // al. |
1042 __ subq(R10, Immediate(12)); // bl. | 960 __ subq(R10, Immediate(12)); // bl. |
1043 __ movq(RAX, CallingConventions::kArg2Reg); // ah. | 961 __ movq(RAX, CallingConventions::kArg2Reg); // ah. |
1044 __ sbbq(RAX, Immediate(11)); // bh. | 962 __ sbbq(RAX, Immediate(11)); // bh. |
1045 // RAX = high64(ah:al - bh:bl). | 963 // RAX = high64(ah:al - bh:bl). |
1046 __ ret(); | 964 __ ret(); |
1047 } | 965 } |
1048 | 966 |
1049 | |
1050 ASSEMBLER_TEST_RUN(SubImmediate, test) { | 967 ASSEMBLER_TEST_RUN(SubImmediate, test) { |
1051 typedef int64_t (*SubImmediateCode)(int64_t al, int64_t ah); | 968 typedef int64_t (*SubImmediateCode)(int64_t al, int64_t ah); |
1052 int64_t al = 14; | 969 int64_t al = 14; |
1053 int64_t ah = 13; | 970 int64_t ah = 13; |
1054 int64_t bh = 11; | 971 int64_t bh = 11; |
1055 int64_t res = reinterpret_cast<SubImmediateCode>(test->entry())(al, ah); | 972 int64_t res = reinterpret_cast<SubImmediateCode>(test->entry())(al, ah); |
1056 EXPECT_EQ((ah - bh), res); | 973 EXPECT_EQ((ah - bh), res); |
1057 al = 10; | 974 al = 10; |
1058 res = reinterpret_cast<SubImmediateCode>(test->entry())(al, ah); | 975 res = reinterpret_cast<SubImmediateCode>(test->entry())(al, ah); |
1059 EXPECT_EQ((ah - bh - 1), res); | 976 EXPECT_EQ((ah - bh - 1), res); |
1060 } | 977 } |
1061 | 978 |
1062 | |
1063 ASSEMBLER_TEST_GENERATE(SubAddress, assembler) { | 979 ASSEMBLER_TEST_GENERATE(SubAddress, assembler) { |
1064 __ pushq(CallingConventions::kArg4Reg); | 980 __ pushq(CallingConventions::kArg4Reg); |
1065 __ pushq(CallingConventions::kArg3Reg); | 981 __ pushq(CallingConventions::kArg3Reg); |
1066 __ pushq(CallingConventions::kArg2Reg); | 982 __ pushq(CallingConventions::kArg2Reg); |
1067 __ pushq(CallingConventions::kArg1Reg); | 983 __ pushq(CallingConventions::kArg1Reg); |
1068 __ movq(R10, Address(RSP, 0 * kWordSize)); // al. | 984 __ movq(R10, Address(RSP, 0 * kWordSize)); // al. |
1069 __ subq(R10, Address(RSP, 2 * kWordSize)); // bl. | 985 __ subq(R10, Address(RSP, 2 * kWordSize)); // bl. |
1070 __ movq(RAX, Address(RSP, 1 * kWordSize)); // ah. | 986 __ movq(RAX, Address(RSP, 1 * kWordSize)); // ah. |
1071 __ sbbq(RAX, Address(RSP, 3 * kWordSize)); // bh. | 987 __ sbbq(RAX, Address(RSP, 3 * kWordSize)); // bh. |
1072 // RAX = high64(ah:al - bh:bl). | 988 // RAX = high64(ah:al - bh:bl). |
1073 __ Drop(4); | 989 __ Drop(4); |
1074 __ ret(); | 990 __ ret(); |
1075 } | 991 } |
1076 | 992 |
1077 | |
1078 ASSEMBLER_TEST_RUN(SubAddress, test) { | 993 ASSEMBLER_TEST_RUN(SubAddress, test) { |
1079 typedef int64_t (*SubCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); | 994 typedef int64_t (*SubCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); |
1080 int64_t al = 14; | 995 int64_t al = 14; |
1081 int64_t ah = 13; | 996 int64_t ah = 13; |
1082 int64_t bl = 12; | 997 int64_t bl = 12; |
1083 int64_t bh = 11; | 998 int64_t bh = 11; |
1084 int64_t res = reinterpret_cast<SubCode>(test->entry())(al, ah, bl, bh); | 999 int64_t res = reinterpret_cast<SubCode>(test->entry())(al, ah, bl, bh); |
1085 EXPECT_EQ((ah - bh), res); | 1000 EXPECT_EQ((ah - bh), res); |
1086 al = 10; | 1001 al = 10; |
1087 res = reinterpret_cast<SubCode>(test->entry())(al, ah, bl, bh); | 1002 res = reinterpret_cast<SubCode>(test->entry())(al, ah, bl, bh); |
1088 EXPECT_EQ((ah - bh - 1), res); | 1003 EXPECT_EQ((ah - bh - 1), res); |
1089 } | 1004 } |
1090 | 1005 |
1091 | |
1092 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { | 1006 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { |
1093 __ movq(R10, Immediate(-1)); | 1007 __ movq(R10, Immediate(-1)); |
1094 __ orl(Address(CallingConventions::kArg1Reg, 0), R10); | 1008 __ orl(Address(CallingConventions::kArg1Reg, 0), R10); |
1095 __ orl(Address(CallingConventions::kArg2Reg, 0), R10); | 1009 __ orl(Address(CallingConventions::kArg2Reg, 0), R10); |
1096 __ movl(RCX, Immediate(42)); | 1010 __ movl(RCX, Immediate(42)); |
1097 __ xorl(RCX, RCX); | 1011 __ xorl(RCX, RCX); |
1098 __ orl(RCX, Immediate(256)); | 1012 __ orl(RCX, Immediate(256)); |
1099 __ movl(RAX, Immediate(4)); | 1013 __ movl(RAX, Immediate(4)); |
1100 __ orl(RCX, RAX); | 1014 __ orl(RCX, RAX); |
1101 __ movl(RAX, Immediate(0xfff0)); | 1015 __ movl(RAX, Immediate(0xfff0)); |
1102 __ andl(RCX, RAX); | 1016 __ andl(RCX, RAX); |
1103 __ movl(RAX, Immediate(1)); | 1017 __ movl(RAX, Immediate(1)); |
1104 __ orl(RCX, RAX); | 1018 __ orl(RCX, RAX); |
1105 __ movl(RAX, RCX); | 1019 __ movl(RAX, RCX); |
1106 __ ret(); | 1020 __ ret(); |
1107 } | 1021 } |
1108 | 1022 |
1109 | |
1110 ASSEMBLER_TEST_RUN(Bitwise, test) { | 1023 ASSEMBLER_TEST_RUN(Bitwise, test) { |
1111 uint64_t f1 = 0; | 1024 uint64_t f1 = 0; |
1112 uint64_t f2 = 0; | 1025 uint64_t f2 = 0; |
1113 typedef int (*Bitwise)(void*, void*); | 1026 typedef int (*Bitwise)(void*, void*); |
1114 int result = reinterpret_cast<Bitwise>(test->entry())(&f1, &f2); | 1027 int result = reinterpret_cast<Bitwise>(test->entry())(&f1, &f2); |
1115 EXPECT_EQ(256 + 1, result); | 1028 EXPECT_EQ(256 + 1, result); |
1116 EXPECT_EQ(kMaxUint32, f1); | 1029 EXPECT_EQ(kMaxUint32, f1); |
1117 EXPECT_EQ(kMaxUint32, f2); | 1030 EXPECT_EQ(kMaxUint32, f2); |
1118 } | 1031 } |
1119 | 1032 |
1120 | |
1121 ASSEMBLER_TEST_GENERATE(Bitwise64, assembler) { | 1033 ASSEMBLER_TEST_GENERATE(Bitwise64, assembler) { |
1122 Label error; | 1034 Label error; |
1123 __ movq(RAX, Immediate(42)); | 1035 __ movq(RAX, Immediate(42)); |
1124 __ pushq(RAX); | 1036 __ pushq(RAX); |
1125 __ xorq(RAX, Address(RSP, 0)); | 1037 __ xorq(RAX, Address(RSP, 0)); |
1126 __ popq(RCX); | 1038 __ popq(RCX); |
1127 __ cmpq(RAX, Immediate(0)); | 1039 __ cmpq(RAX, Immediate(0)); |
1128 __ j(NOT_EQUAL, &error); | 1040 __ j(NOT_EQUAL, &error); |
1129 __ movq(RCX, Immediate(0xFF)); | 1041 __ movq(RCX, Immediate(0xFF)); |
1130 __ movq(RAX, Immediate(0x5)); | 1042 __ movq(RAX, Immediate(0x5)); |
(...skipping 17 matching lines...) Expand all Loading... |
1148 __ orq(RCX, Address(RSP, 0)); | 1060 __ orq(RCX, Address(RSP, 0)); |
1149 __ xorq(RCX, Immediate(0)); | 1061 __ xorq(RCX, Immediate(0)); |
1150 __ popq(RAX); | 1062 __ popq(RAX); |
1151 __ movq(RAX, RCX); | 1063 __ movq(RAX, RCX); |
1152 __ ret(); | 1064 __ ret(); |
1153 __ Bind(&error); | 1065 __ Bind(&error); |
1154 __ movq(RAX, Immediate(-1)); | 1066 __ movq(RAX, Immediate(-1)); |
1155 __ ret(); | 1067 __ ret(); |
1156 } | 1068 } |
1157 | 1069 |
1158 | |
1159 ASSEMBLER_TEST_RUN(Bitwise64, test) { | 1070 ASSEMBLER_TEST_RUN(Bitwise64, test) { |
1160 typedef int (*Bitwise64)(); | 1071 typedef int (*Bitwise64)(); |
1161 EXPECT_EQ(256 + 1, reinterpret_cast<Bitwise64>(test->entry())()); | 1072 EXPECT_EQ(256 + 1, reinterpret_cast<Bitwise64>(test->entry())()); |
1162 } | 1073 } |
1163 | 1074 |
1164 | |
1165 ASSEMBLER_TEST_GENERATE(LogicalOps, assembler) { | 1075 ASSEMBLER_TEST_GENERATE(LogicalOps, assembler) { |
1166 Label donetest1; | 1076 Label donetest1; |
1167 __ movl(RAX, Immediate(4)); | 1077 __ movl(RAX, Immediate(4)); |
1168 __ andl(RAX, Immediate(2)); | 1078 __ andl(RAX, Immediate(2)); |
1169 __ cmpl(RAX, Immediate(0)); | 1079 __ cmpl(RAX, Immediate(0)); |
1170 __ j(EQUAL, &donetest1); | 1080 __ j(EQUAL, &donetest1); |
1171 // Be sure to skip this crashing code. | 1081 // Be sure to skip this crashing code. |
1172 __ movl(RAX, Immediate(0)); | 1082 __ movl(RAX, Immediate(0)); |
1173 __ movl(Address(RAX, 0), RAX); | 1083 __ movl(Address(RAX, 0), RAX); |
1174 __ Bind(&donetest1); | 1084 __ Bind(&donetest1); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 __ cmpq(RDX, Immediate(shifted)); | 1331 __ cmpq(RDX, Immediate(shifted)); |
1422 __ j(EQUAL, &donetest15d); | 1332 __ j(EQUAL, &donetest15d); |
1423 __ int3(); | 1333 __ int3(); |
1424 __ Bind(&donetest15d); | 1334 __ Bind(&donetest15d); |
1425 } | 1335 } |
1426 | 1336 |
1427 __ movl(RAX, Immediate(0)); | 1337 __ movl(RAX, Immediate(0)); |
1428 __ ret(); | 1338 __ ret(); |
1429 } | 1339 } |
1430 | 1340 |
1431 | |
1432 ASSEMBLER_TEST_RUN(LogicalOps, test) { | 1341 ASSEMBLER_TEST_RUN(LogicalOps, test) { |
1433 typedef int (*LogicalOpsCode)(); | 1342 typedef int (*LogicalOpsCode)(); |
1434 EXPECT_EQ(0, reinterpret_cast<LogicalOpsCode>(test->entry())()); | 1343 EXPECT_EQ(0, reinterpret_cast<LogicalOpsCode>(test->entry())()); |
1435 } | 1344 } |
1436 | 1345 |
1437 | |
1438 ASSEMBLER_TEST_GENERATE(LogicalOps64, assembler) { | 1346 ASSEMBLER_TEST_GENERATE(LogicalOps64, assembler) { |
1439 Label donetest1; | 1347 Label donetest1; |
1440 __ movq(RAX, Immediate(4)); | 1348 __ movq(RAX, Immediate(4)); |
1441 __ andq(RAX, Immediate(2)); | 1349 __ andq(RAX, Immediate(2)); |
1442 __ cmpq(RAX, Immediate(0)); | 1350 __ cmpq(RAX, Immediate(0)); |
1443 __ j(EQUAL, &donetest1); | 1351 __ j(EQUAL, &donetest1); |
1444 __ int3(); | 1352 __ int3(); |
1445 __ Bind(&donetest1); | 1353 __ Bind(&donetest1); |
1446 | 1354 |
1447 Label donetest2; | 1355 Label donetest2; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1611 __ cmpq(R15, Immediate(2)); | 1519 __ cmpq(R15, Immediate(2)); |
1612 __ j(EQUAL, &donetest15); | 1520 __ j(EQUAL, &donetest15); |
1613 __ int3(); | 1521 __ int3(); |
1614 __ Bind(&donetest15); | 1522 __ Bind(&donetest15); |
1615 __ popq(R15); // Callee saved. | 1523 __ popq(R15); // Callee saved. |
1616 | 1524 |
1617 __ movq(RAX, Immediate(0)); | 1525 __ movq(RAX, Immediate(0)); |
1618 __ ret(); | 1526 __ ret(); |
1619 } | 1527 } |
1620 | 1528 |
1621 | |
1622 ASSEMBLER_TEST_RUN(LogicalOps64, test) { | 1529 ASSEMBLER_TEST_RUN(LogicalOps64, test) { |
1623 typedef int (*LogicalOpsCode)(); | 1530 typedef int (*LogicalOpsCode)(); |
1624 EXPECT_EQ(0, reinterpret_cast<LogicalOpsCode>(test->entry())()); | 1531 EXPECT_EQ(0, reinterpret_cast<LogicalOpsCode>(test->entry())()); |
1625 } | 1532 } |
1626 | 1533 |
1627 | |
1628 ASSEMBLER_TEST_GENERATE(LogicalTestL, assembler) { | 1534 ASSEMBLER_TEST_GENERATE(LogicalTestL, assembler) { |
1629 Label donetest1; | 1535 Label donetest1; |
1630 __ movl(RAX, Immediate(4)); | 1536 __ movl(RAX, Immediate(4)); |
1631 __ movl(RCX, Immediate(2)); | 1537 __ movl(RCX, Immediate(2)); |
1632 __ testl(RAX, RCX); | 1538 __ testl(RAX, RCX); |
1633 __ j(EQUAL, &donetest1); | 1539 __ j(EQUAL, &donetest1); |
1634 // Be sure to skip this crashing code. | 1540 // Be sure to skip this crashing code. |
1635 __ movl(RAX, Immediate(0)); | 1541 __ movl(RAX, Immediate(0)); |
1636 __ movl(Address(RAX, 0), RAX); | 1542 __ movl(Address(RAX, 0), RAX); |
1637 __ Bind(&donetest1); | 1543 __ Bind(&donetest1); |
(...skipping 23 matching lines...) Expand all Loading... |
1661 __ j(NOT_EQUAL, &donetest4); | 1567 __ j(NOT_EQUAL, &donetest4); |
1662 // Be sure to skip this crashing code. | 1568 // Be sure to skip this crashing code. |
1663 __ movl(RAX, Immediate(0)); | 1569 __ movl(RAX, Immediate(0)); |
1664 __ movl(Address(RAX, 0), RAX); | 1570 __ movl(Address(RAX, 0), RAX); |
1665 __ Bind(&donetest4); | 1571 __ Bind(&donetest4); |
1666 | 1572 |
1667 __ movl(RAX, Immediate(0)); | 1573 __ movl(RAX, Immediate(0)); |
1668 __ ret(); | 1574 __ ret(); |
1669 } | 1575 } |
1670 | 1576 |
1671 | |
1672 ASSEMBLER_TEST_RUN(LogicalTestL, test) { | 1577 ASSEMBLER_TEST_RUN(LogicalTestL, test) { |
1673 typedef int (*LogicalTestCode)(); | 1578 typedef int (*LogicalTestCode)(); |
1674 EXPECT_EQ(0, reinterpret_cast<LogicalTestCode>(test->entry())()); | 1579 EXPECT_EQ(0, reinterpret_cast<LogicalTestCode>(test->entry())()); |
1675 } | 1580 } |
1676 | 1581 |
1677 | |
1678 ASSEMBLER_TEST_GENERATE(LogicalTestQ, assembler) { | 1582 ASSEMBLER_TEST_GENERATE(LogicalTestQ, assembler) { |
1679 Label donetest1; | 1583 Label donetest1; |
1680 __ movq(RAX, Immediate(4)); | 1584 __ movq(RAX, Immediate(4)); |
1681 __ movq(RCX, Immediate(2)); | 1585 __ movq(RCX, Immediate(2)); |
1682 __ testq(RAX, RCX); | 1586 __ testq(RAX, RCX); |
1683 __ j(EQUAL, &donetest1); | 1587 __ j(EQUAL, &donetest1); |
1684 // Be sure to skip this crashing code. | 1588 // Be sure to skip this crashing code. |
1685 __ movq(RAX, Immediate(0)); | 1589 __ movq(RAX, Immediate(0)); |
1686 __ movq(Address(RAX, 0), RAX); | 1590 __ movq(Address(RAX, 0), RAX); |
1687 __ Bind(&donetest1); | 1591 __ Bind(&donetest1); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1729 __ j(NOT_EQUAL, &donetest6); | 1633 __ j(NOT_EQUAL, &donetest6); |
1730 // Be sure to skip this crashing code. | 1634 // Be sure to skip this crashing code. |
1731 __ movq(RAX, Immediate(0)); | 1635 __ movq(RAX, Immediate(0)); |
1732 __ movq(Address(RAX, 0), RAX); | 1636 __ movq(Address(RAX, 0), RAX); |
1733 __ Bind(&donetest6); | 1637 __ Bind(&donetest6); |
1734 | 1638 |
1735 __ movq(RAX, Immediate(0)); | 1639 __ movq(RAX, Immediate(0)); |
1736 __ ret(); | 1640 __ ret(); |
1737 } | 1641 } |
1738 | 1642 |
1739 | |
1740 ASSEMBLER_TEST_RUN(LogicalTestQ, test) { | 1643 ASSEMBLER_TEST_RUN(LogicalTestQ, test) { |
1741 typedef int (*LogicalTestCode)(); | 1644 typedef int (*LogicalTestCode)(); |
1742 EXPECT_EQ(0, reinterpret_cast<LogicalTestCode>(test->entry())()); | 1645 EXPECT_EQ(0, reinterpret_cast<LogicalTestCode>(test->entry())()); |
1743 } | 1646 } |
1744 | 1647 |
1745 | |
1746 ASSEMBLER_TEST_GENERATE(CompareSwapEQ, assembler) { | 1648 ASSEMBLER_TEST_GENERATE(CompareSwapEQ, assembler) { |
1747 __ movq(RAX, Immediate(0)); | 1649 __ movq(RAX, Immediate(0)); |
1748 __ pushq(RAX); | 1650 __ pushq(RAX); |
1749 __ movq(RAX, Immediate(4)); | 1651 __ movq(RAX, Immediate(4)); |
1750 __ movq(RCX, Immediate(0)); | 1652 __ movq(RCX, Immediate(0)); |
1751 __ movq(Address(RSP, 0), RAX); | 1653 __ movq(Address(RSP, 0), RAX); |
1752 __ LockCmpxchgq(Address(RSP, 0), RCX); | 1654 __ LockCmpxchgq(Address(RSP, 0), RCX); |
1753 __ popq(RAX); | 1655 __ popq(RAX); |
1754 __ ret(); | 1656 __ ret(); |
1755 } | 1657 } |
1756 | 1658 |
1757 | |
1758 ASSEMBLER_TEST_RUN(CompareSwapEQ, test) { | 1659 ASSEMBLER_TEST_RUN(CompareSwapEQ, test) { |
1759 typedef int (*CompareSwapEQCode)(); | 1660 typedef int (*CompareSwapEQCode)(); |
1760 EXPECT_EQ(0, reinterpret_cast<CompareSwapEQCode>(test->entry())()); | 1661 EXPECT_EQ(0, reinterpret_cast<CompareSwapEQCode>(test->entry())()); |
1761 } | 1662 } |
1762 | 1663 |
1763 | |
1764 ASSEMBLER_TEST_GENERATE(CompareSwapNEQ, assembler) { | 1664 ASSEMBLER_TEST_GENERATE(CompareSwapNEQ, assembler) { |
1765 __ movq(RAX, Immediate(0)); | 1665 __ movq(RAX, Immediate(0)); |
1766 __ pushq(RAX); | 1666 __ pushq(RAX); |
1767 __ movq(RAX, Immediate(2)); | 1667 __ movq(RAX, Immediate(2)); |
1768 __ movq(RCX, Immediate(4)); | 1668 __ movq(RCX, Immediate(4)); |
1769 __ movq(Address(RSP, 0), RCX); | 1669 __ movq(Address(RSP, 0), RCX); |
1770 __ LockCmpxchgq(Address(RSP, 0), RCX); | 1670 __ LockCmpxchgq(Address(RSP, 0), RCX); |
1771 __ popq(RAX); | 1671 __ popq(RAX); |
1772 __ ret(); | 1672 __ ret(); |
1773 } | 1673 } |
1774 | 1674 |
1775 | |
1776 ASSEMBLER_TEST_RUN(CompareSwapNEQ, test) { | 1675 ASSEMBLER_TEST_RUN(CompareSwapNEQ, test) { |
1777 typedef int (*CompareSwapNEQCode)(); | 1676 typedef int (*CompareSwapNEQCode)(); |
1778 EXPECT_EQ(4, reinterpret_cast<CompareSwapNEQCode>(test->entry())()); | 1677 EXPECT_EQ(4, reinterpret_cast<CompareSwapNEQCode>(test->entry())()); |
1779 } | 1678 } |
1780 | 1679 |
1781 | |
1782 ASSEMBLER_TEST_GENERATE(CompareSwapEQ32, assembler) { | 1680 ASSEMBLER_TEST_GENERATE(CompareSwapEQ32, assembler) { |
1783 __ movq(RAX, Immediate(0x100000000)); | 1681 __ movq(RAX, Immediate(0x100000000)); |
1784 __ pushq(RAX); | 1682 __ pushq(RAX); |
1785 __ movq(RAX, Immediate(4)); | 1683 __ movq(RAX, Immediate(4)); |
1786 __ movq(RCX, Immediate(0)); | 1684 __ movq(RCX, Immediate(0)); |
1787 // 32 bit store of 4. | 1685 // 32 bit store of 4. |
1788 __ movl(Address(RSP, 0), RAX); | 1686 __ movl(Address(RSP, 0), RAX); |
1789 // Compare 32 bit memory location with RAX (4) and write 0. | 1687 // Compare 32 bit memory location with RAX (4) and write 0. |
1790 __ LockCmpxchgl(Address(RSP, 0), RCX); | 1688 __ LockCmpxchgl(Address(RSP, 0), RCX); |
1791 // Pop unchanged high word and zeroed out low word. | 1689 // Pop unchanged high word and zeroed out low word. |
1792 __ popq(RAX); | 1690 __ popq(RAX); |
1793 __ ret(); | 1691 __ ret(); |
1794 } | 1692 } |
1795 | 1693 |
1796 | |
1797 ASSEMBLER_TEST_RUN(CompareSwapEQ32, test) { | 1694 ASSEMBLER_TEST_RUN(CompareSwapEQ32, test) { |
1798 typedef intptr_t (*CompareSwapEQ32Code)(); | 1695 typedef intptr_t (*CompareSwapEQ32Code)(); |
1799 EXPECT_EQ(0x100000000, | 1696 EXPECT_EQ(0x100000000, |
1800 reinterpret_cast<CompareSwapEQ32Code>(test->entry())()); | 1697 reinterpret_cast<CompareSwapEQ32Code>(test->entry())()); |
1801 } | 1698 } |
1802 | 1699 |
1803 | |
1804 ASSEMBLER_TEST_GENERATE(CompareSwapNEQ32, assembler) { | 1700 ASSEMBLER_TEST_GENERATE(CompareSwapNEQ32, assembler) { |
1805 __ movq(RAX, Immediate(0x100000000)); | 1701 __ movq(RAX, Immediate(0x100000000)); |
1806 __ pushq(RAX); | 1702 __ pushq(RAX); |
1807 __ movq(RAX, Immediate(2)); | 1703 __ movq(RAX, Immediate(2)); |
1808 __ movq(RCX, Immediate(4)); | 1704 __ movq(RCX, Immediate(4)); |
1809 __ movl(Address(RSP, 0), RCX); | 1705 __ movl(Address(RSP, 0), RCX); |
1810 __ LockCmpxchgl(Address(RSP, 0), RCX); | 1706 __ LockCmpxchgl(Address(RSP, 0), RCX); |
1811 __ popq(RAX); | 1707 __ popq(RAX); |
1812 __ ret(); | 1708 __ ret(); |
1813 } | 1709 } |
1814 | 1710 |
1815 | |
1816 ASSEMBLER_TEST_RUN(CompareSwapNEQ32, test) { | 1711 ASSEMBLER_TEST_RUN(CompareSwapNEQ32, test) { |
1817 typedef intptr_t (*CompareSwapNEQ32Code)(); | 1712 typedef intptr_t (*CompareSwapNEQ32Code)(); |
1818 EXPECT_EQ(0x100000004l, | 1713 EXPECT_EQ(0x100000004l, |
1819 reinterpret_cast<CompareSwapNEQ32Code>(test->entry())()); | 1714 reinterpret_cast<CompareSwapNEQ32Code>(test->entry())()); |
1820 } | 1715 } |
1821 | 1716 |
1822 | |
1823 ASSEMBLER_TEST_GENERATE(Exchange, assembler) { | 1717 ASSEMBLER_TEST_GENERATE(Exchange, assembler) { |
1824 __ movq(RAX, Immediate(kLargeConstant)); | 1718 __ movq(RAX, Immediate(kLargeConstant)); |
1825 __ movq(RDX, Immediate(kAnotherLargeConstant)); | 1719 __ movq(RDX, Immediate(kAnotherLargeConstant)); |
1826 __ xchgq(RAX, RDX); | 1720 __ xchgq(RAX, RDX); |
1827 __ subq(RAX, RDX); | 1721 __ subq(RAX, RDX); |
1828 __ ret(); | 1722 __ ret(); |
1829 } | 1723 } |
1830 | 1724 |
1831 | |
1832 ASSEMBLER_TEST_RUN(Exchange, test) { | 1725 ASSEMBLER_TEST_RUN(Exchange, test) { |
1833 typedef int64_t (*Exchange)(); | 1726 typedef int64_t (*Exchange)(); |
1834 EXPECT_EQ(kAnotherLargeConstant - kLargeConstant, | 1727 EXPECT_EQ(kAnotherLargeConstant - kLargeConstant, |
1835 reinterpret_cast<Exchange>(test->entry())()); | 1728 reinterpret_cast<Exchange>(test->entry())()); |
1836 } | 1729 } |
1837 | 1730 |
1838 | |
1839 ASSEMBLER_TEST_GENERATE(LargeConstant, assembler) { | 1731 ASSEMBLER_TEST_GENERATE(LargeConstant, assembler) { |
1840 __ movq(RAX, Immediate(kLargeConstant)); | 1732 __ movq(RAX, Immediate(kLargeConstant)); |
1841 __ ret(); | 1733 __ ret(); |
1842 } | 1734 } |
1843 | 1735 |
1844 | |
1845 ASSEMBLER_TEST_RUN(LargeConstant, test) { | 1736 ASSEMBLER_TEST_RUN(LargeConstant, test) { |
1846 typedef int64_t (*LargeConstantCode)(); | 1737 typedef int64_t (*LargeConstantCode)(); |
1847 EXPECT_EQ(kLargeConstant, | 1738 EXPECT_EQ(kLargeConstant, |
1848 reinterpret_cast<LargeConstantCode>(test->entry())()); | 1739 reinterpret_cast<LargeConstantCode>(test->entry())()); |
1849 } | 1740 } |
1850 | 1741 |
1851 | |
1852 static int ComputeStackSpaceReservation(int needed, int fixed) { | 1742 static int ComputeStackSpaceReservation(int needed, int fixed) { |
1853 return (OS::ActivationFrameAlignment() > 1) | 1743 return (OS::ActivationFrameAlignment() > 1) |
1854 ? Utils::RoundUp(needed + fixed, OS::ActivationFrameAlignment()) - | 1744 ? Utils::RoundUp(needed + fixed, OS::ActivationFrameAlignment()) - |
1855 fixed | 1745 fixed |
1856 : needed; | 1746 : needed; |
1857 } | 1747 } |
1858 | 1748 |
1859 | |
1860 static int LeafReturn42() { | 1749 static int LeafReturn42() { |
1861 return 42; | 1750 return 42; |
1862 } | 1751 } |
1863 | 1752 |
1864 | |
1865 static int LeafReturnArgument(int x) { | 1753 static int LeafReturnArgument(int x) { |
1866 return x + 87; | 1754 return x + 87; |
1867 } | 1755 } |
1868 | 1756 |
1869 | |
1870 ASSEMBLER_TEST_GENERATE(CallSimpleLeaf, assembler) { | 1757 ASSEMBLER_TEST_GENERATE(CallSimpleLeaf, assembler) { |
1871 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); | 1758 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); |
1872 ExternalLabel call2(reinterpret_cast<uword>(LeafReturnArgument)); | 1759 ExternalLabel call2(reinterpret_cast<uword>(LeafReturnArgument)); |
1873 int space = ComputeStackSpaceReservation(0, 8); | 1760 int space = ComputeStackSpaceReservation(0, 8); |
1874 __ subq(RSP, Immediate(space)); | 1761 __ subq(RSP, Immediate(space)); |
1875 __ call(&call1); | 1762 __ call(&call1); |
1876 __ addq(RSP, Immediate(space)); | 1763 __ addq(RSP, Immediate(space)); |
1877 space = ComputeStackSpaceReservation(0, 8); | 1764 space = ComputeStackSpaceReservation(0, 8); |
1878 __ subq(RSP, Immediate(space)); | 1765 __ subq(RSP, Immediate(space)); |
1879 __ movl(CallingConventions::kArg1Reg, RAX); | 1766 __ movl(CallingConventions::kArg1Reg, RAX); |
1880 __ call(&call2); | 1767 __ call(&call2); |
1881 __ addq(RSP, Immediate(space)); | 1768 __ addq(RSP, Immediate(space)); |
1882 __ ret(); | 1769 __ ret(); |
1883 } | 1770 } |
1884 | 1771 |
1885 | |
1886 ASSEMBLER_TEST_RUN(CallSimpleLeaf, test) { | 1772 ASSEMBLER_TEST_RUN(CallSimpleLeaf, test) { |
1887 typedef int (*CallSimpleLeafCode)(); | 1773 typedef int (*CallSimpleLeafCode)(); |
1888 EXPECT_EQ(42 + 87, reinterpret_cast<CallSimpleLeafCode>(test->entry())()); | 1774 EXPECT_EQ(42 + 87, reinterpret_cast<CallSimpleLeafCode>(test->entry())()); |
1889 } | 1775 } |
1890 | 1776 |
1891 | |
1892 ASSEMBLER_TEST_GENERATE(JumpSimpleLeaf, assembler) { | 1777 ASSEMBLER_TEST_GENERATE(JumpSimpleLeaf, assembler) { |
1893 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); | 1778 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); |
1894 Label L; | 1779 Label L; |
1895 int space = ComputeStackSpaceReservation(0, 8); | 1780 int space = ComputeStackSpaceReservation(0, 8); |
1896 __ subq(RSP, Immediate(space)); | 1781 __ subq(RSP, Immediate(space)); |
1897 __ call(&L); | 1782 __ call(&L); |
1898 __ addq(RSP, Immediate(space)); | 1783 __ addq(RSP, Immediate(space)); |
1899 __ ret(); | 1784 __ ret(); |
1900 __ Bind(&L); | 1785 __ Bind(&L); |
1901 __ jmp(&call1); | 1786 __ jmp(&call1); |
1902 } | 1787 } |
1903 | 1788 |
1904 | |
1905 ASSEMBLER_TEST_RUN(JumpSimpleLeaf, test) { | 1789 ASSEMBLER_TEST_RUN(JumpSimpleLeaf, test) { |
1906 typedef int (*JumpSimpleLeafCode)(); | 1790 typedef int (*JumpSimpleLeafCode)(); |
1907 EXPECT_EQ(42, reinterpret_cast<JumpSimpleLeafCode>(test->entry())()); | 1791 EXPECT_EQ(42, reinterpret_cast<JumpSimpleLeafCode>(test->entry())()); |
1908 } | 1792 } |
1909 | 1793 |
1910 | |
1911 ASSEMBLER_TEST_GENERATE(JumpIndirect, assembler) { | 1794 ASSEMBLER_TEST_GENERATE(JumpIndirect, assembler) { |
1912 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); | 1795 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); |
1913 __ movq(Address(CallingConventions::kArg1Reg, 0), Immediate(call1.address())); | 1796 __ movq(Address(CallingConventions::kArg1Reg, 0), Immediate(call1.address())); |
1914 __ jmp(Address(CallingConventions::kArg1Reg, 0)); | 1797 __ jmp(Address(CallingConventions::kArg1Reg, 0)); |
1915 } | 1798 } |
1916 | 1799 |
1917 | |
1918 ASSEMBLER_TEST_RUN(JumpIndirect, test) { | 1800 ASSEMBLER_TEST_RUN(JumpIndirect, test) { |
1919 uword temp = 0; | 1801 uword temp = 0; |
1920 typedef int (*JumpIndirect)(uword*); | 1802 typedef int (*JumpIndirect)(uword*); |
1921 EXPECT_EQ(42, reinterpret_cast<JumpIndirect>(test->entry())(&temp)); | 1803 EXPECT_EQ(42, reinterpret_cast<JumpIndirect>(test->entry())(&temp)); |
1922 } | 1804 } |
1923 | 1805 |
1924 | |
1925 ASSEMBLER_TEST_GENERATE(SingleFPMoves, assembler) { | 1806 ASSEMBLER_TEST_GENERATE(SingleFPMoves, assembler) { |
1926 __ movq(RAX, Immediate(bit_cast<int32_t, float>(234.0f))); | 1807 __ movq(RAX, Immediate(bit_cast<int32_t, float>(234.0f))); |
1927 __ movd(XMM0, RAX); | 1808 __ movd(XMM0, RAX); |
1928 __ movss(XMM1, XMM0); | 1809 __ movss(XMM1, XMM0); |
1929 __ movss(XMM2, XMM1); | 1810 __ movss(XMM2, XMM1); |
1930 __ movss(XMM3, XMM2); | 1811 __ movss(XMM3, XMM2); |
1931 __ movss(XMM4, XMM3); | 1812 __ movss(XMM4, XMM3); |
1932 __ movss(XMM5, XMM4); | 1813 __ movss(XMM5, XMM4); |
1933 __ movss(XMM6, XMM5); | 1814 __ movss(XMM6, XMM5); |
1934 __ movss(XMM7, XMM6); | 1815 __ movss(XMM7, XMM6); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1969 __ movss(XMM4, XMM5); | 1850 __ movss(XMM4, XMM5); |
1970 __ movss(XMM3, XMM4); | 1851 __ movss(XMM3, XMM4); |
1971 __ movss(XMM2, XMM3); | 1852 __ movss(XMM2, XMM3); |
1972 __ movss(XMM1, XMM2); | 1853 __ movss(XMM1, XMM2); |
1973 __ movss(XMM0, XMM1); | 1854 __ movss(XMM0, XMM1); |
1974 __ popq(RAX); | 1855 __ popq(RAX); |
1975 __ popq(R15); // Callee saved. | 1856 __ popq(R15); // Callee saved. |
1976 __ ret(); | 1857 __ ret(); |
1977 } | 1858 } |
1978 | 1859 |
1979 | |
1980 ASSEMBLER_TEST_RUN(SingleFPMoves, test) { | 1860 ASSEMBLER_TEST_RUN(SingleFPMoves, test) { |
1981 typedef float (*SingleFPMovesCode)(); | 1861 typedef float (*SingleFPMovesCode)(); |
1982 EXPECT_EQ(234, reinterpret_cast<SingleFPMovesCode>(test->entry())()); | 1862 EXPECT_EQ(234, reinterpret_cast<SingleFPMovesCode>(test->entry())()); |
1983 } | 1863 } |
1984 | 1864 |
1985 | |
1986 ASSEMBLER_TEST_GENERATE(SingleFPMoves2, assembler) { | 1865 ASSEMBLER_TEST_GENERATE(SingleFPMoves2, assembler) { |
1987 __ movq(RAX, Immediate(bit_cast<int32_t, float>(234.0f))); | 1866 __ movq(RAX, Immediate(bit_cast<int32_t, float>(234.0f))); |
1988 __ movd(XMM0, RAX); | 1867 __ movd(XMM0, RAX); |
1989 __ movd(XMM8, RAX); | 1868 __ movd(XMM8, RAX); |
1990 __ movss(XMM1, XMM8); | 1869 __ movss(XMM1, XMM8); |
1991 __ pushq(RAX); | 1870 __ pushq(RAX); |
1992 __ movq(Address(RSP, 0), Immediate(0)); | 1871 __ movq(Address(RSP, 0), Immediate(0)); |
1993 __ movss(XMM0, Address(RSP, 0)); | 1872 __ movss(XMM0, Address(RSP, 0)); |
1994 __ movss(Address(RSP, 0), XMM1); | 1873 __ movss(Address(RSP, 0), XMM1); |
1995 __ movss(XMM0, Address(RSP, 0)); | 1874 __ movss(XMM0, Address(RSP, 0)); |
1996 __ movq(Address(RSP, 0), Immediate(0)); | 1875 __ movq(Address(RSP, 0), Immediate(0)); |
1997 __ movss(XMM9, XMM8); | 1876 __ movss(XMM9, XMM8); |
1998 __ movss(Address(RSP, 0), XMM9); | 1877 __ movss(Address(RSP, 0), XMM9); |
1999 __ movss(XMM8, Address(RSP, 0)); | 1878 __ movss(XMM8, Address(RSP, 0)); |
2000 __ movss(XMM0, XMM8); | 1879 __ movss(XMM0, XMM8); |
2001 __ popq(RAX); | 1880 __ popq(RAX); |
2002 __ ret(); | 1881 __ ret(); |
2003 } | 1882 } |
2004 | 1883 |
2005 | |
2006 ASSEMBLER_TEST_RUN(SingleFPMoves2, test) { | 1884 ASSEMBLER_TEST_RUN(SingleFPMoves2, test) { |
2007 typedef float (*SingleFPMoves2Code)(); | 1885 typedef float (*SingleFPMoves2Code)(); |
2008 EXPECT_EQ(234, reinterpret_cast<SingleFPMoves2Code>(test->entry())()); | 1886 EXPECT_EQ(234, reinterpret_cast<SingleFPMoves2Code>(test->entry())()); |
2009 } | 1887 } |
2010 | 1888 |
2011 | |
2012 ASSEMBLER_TEST_GENERATE(PackedDoubleAdd, assembler) { | 1889 ASSEMBLER_TEST_GENERATE(PackedDoubleAdd, assembler) { |
2013 static const struct ALIGN16 { | 1890 static const struct ALIGN16 { |
2014 double a; | 1891 double a; |
2015 double b; | 1892 double b; |
2016 } constant0 = {1.0, 2.0}; | 1893 } constant0 = {1.0, 2.0}; |
2017 static const struct ALIGN16 { | 1894 static const struct ALIGN16 { |
2018 double a; | 1895 double a; |
2019 double b; | 1896 double b; |
2020 } constant1 = {3.0, 4.0}; | 1897 } constant1 = {3.0, 4.0}; |
2021 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 1898 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2022 __ movups(XMM10, Address(RAX, 0)); | 1899 __ movups(XMM10, Address(RAX, 0)); |
2023 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); | 1900 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); |
2024 __ movups(XMM11, Address(RAX, 0)); | 1901 __ movups(XMM11, Address(RAX, 0)); |
2025 __ addpd(XMM10, XMM11); | 1902 __ addpd(XMM10, XMM11); |
2026 __ movaps(XMM0, XMM10); | 1903 __ movaps(XMM0, XMM10); |
2027 __ ret(); | 1904 __ ret(); |
2028 } | 1905 } |
2029 | 1906 |
2030 | |
2031 ASSEMBLER_TEST_RUN(PackedDoubleAdd, test) { | 1907 ASSEMBLER_TEST_RUN(PackedDoubleAdd, test) { |
2032 typedef double (*PackedDoubleAdd)(); | 1908 typedef double (*PackedDoubleAdd)(); |
2033 double res = reinterpret_cast<PackedDoubleAdd>(test->entry())(); | 1909 double res = reinterpret_cast<PackedDoubleAdd>(test->entry())(); |
2034 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); | 1910 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); |
2035 } | 1911 } |
2036 | 1912 |
2037 | |
2038 ASSEMBLER_TEST_GENERATE(PackedDoubleSub, assembler) { | 1913 ASSEMBLER_TEST_GENERATE(PackedDoubleSub, assembler) { |
2039 static const struct ALIGN16 { | 1914 static const struct ALIGN16 { |
2040 double a; | 1915 double a; |
2041 double b; | 1916 double b; |
2042 } constant0 = {1.0, 2.0}; | 1917 } constant0 = {1.0, 2.0}; |
2043 static const struct ALIGN16 { | 1918 static const struct ALIGN16 { |
2044 double a; | 1919 double a; |
2045 double b; | 1920 double b; |
2046 } constant1 = {3.0, 4.0}; | 1921 } constant1 = {3.0, 4.0}; |
2047 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 1922 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2048 __ movups(XMM10, Address(RAX, 0)); | 1923 __ movups(XMM10, Address(RAX, 0)); |
2049 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); | 1924 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); |
2050 __ movups(XMM11, Address(RAX, 0)); | 1925 __ movups(XMM11, Address(RAX, 0)); |
2051 __ subpd(XMM10, XMM11); | 1926 __ subpd(XMM10, XMM11); |
2052 __ movaps(XMM0, XMM10); | 1927 __ movaps(XMM0, XMM10); |
2053 __ ret(); | 1928 __ ret(); |
2054 } | 1929 } |
2055 | 1930 |
2056 | |
2057 ASSEMBLER_TEST_RUN(PackedDoubleSub, test) { | 1931 ASSEMBLER_TEST_RUN(PackedDoubleSub, test) { |
2058 typedef double (*PackedDoubleSub)(); | 1932 typedef double (*PackedDoubleSub)(); |
2059 double res = reinterpret_cast<PackedDoubleSub>(test->entry())(); | 1933 double res = reinterpret_cast<PackedDoubleSub>(test->entry())(); |
2060 EXPECT_FLOAT_EQ(-2.0, res, 0.000001f); | 1934 EXPECT_FLOAT_EQ(-2.0, res, 0.000001f); |
2061 } | 1935 } |
2062 | 1936 |
2063 | |
2064 static void EnterTestFrame(Assembler* assembler) { | 1937 static void EnterTestFrame(Assembler* assembler) { |
2065 COMPILE_ASSERT(THR != CallingConventions::kArg1Reg); | 1938 COMPILE_ASSERT(THR != CallingConventions::kArg1Reg); |
2066 COMPILE_ASSERT(CODE_REG != CallingConventions::kArg2Reg); | 1939 COMPILE_ASSERT(CODE_REG != CallingConventions::kArg2Reg); |
2067 __ EnterFrame(0); | 1940 __ EnterFrame(0); |
2068 __ pushq(CODE_REG); | 1941 __ pushq(CODE_REG); |
2069 __ pushq(PP); | 1942 __ pushq(PP); |
2070 __ pushq(THR); | 1943 __ pushq(THR); |
2071 __ movq(CODE_REG, Address(CallingConventions::kArg1Reg, | 1944 __ movq(CODE_REG, Address(CallingConventions::kArg1Reg, |
2072 VMHandles::kOffsetOfRawPtrInHandle)); | 1945 VMHandles::kOffsetOfRawPtrInHandle)); |
2073 __ movq(THR, CallingConventions::kArg2Reg); | 1946 __ movq(THR, CallingConventions::kArg2Reg); |
2074 __ LoadPoolPointer(PP); | 1947 __ LoadPoolPointer(PP); |
2075 } | 1948 } |
2076 | 1949 |
2077 | |
2078 static void LeaveTestFrame(Assembler* assembler) { | 1950 static void LeaveTestFrame(Assembler* assembler) { |
2079 __ popq(THR); | 1951 __ popq(THR); |
2080 __ popq(PP); | 1952 __ popq(PP); |
2081 __ popq(CODE_REG); | 1953 __ popq(CODE_REG); |
2082 __ LeaveFrame(); | 1954 __ LeaveFrame(); |
2083 } | 1955 } |
2084 | 1956 |
2085 | |
2086 ASSEMBLER_TEST_GENERATE(PackedDoubleNegate, assembler) { | 1957 ASSEMBLER_TEST_GENERATE(PackedDoubleNegate, assembler) { |
2087 static const struct ALIGN16 { | 1958 static const struct ALIGN16 { |
2088 double a; | 1959 double a; |
2089 double b; | 1960 double b; |
2090 } constant0 = {1.0, 2.0}; | 1961 } constant0 = {1.0, 2.0}; |
2091 EnterTestFrame(assembler); | 1962 EnterTestFrame(assembler); |
2092 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 1963 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2093 __ movups(XMM10, Address(RAX, 0)); | 1964 __ movups(XMM10, Address(RAX, 0)); |
2094 __ negatepd(XMM10); | 1965 __ negatepd(XMM10); |
2095 __ movaps(XMM0, XMM10); | 1966 __ movaps(XMM0, XMM10); |
2096 LeaveTestFrame(assembler); | 1967 LeaveTestFrame(assembler); |
2097 __ ret(); | 1968 __ ret(); |
2098 } | 1969 } |
2099 | 1970 |
2100 | |
2101 ASSEMBLER_TEST_RUN(PackedDoubleNegate, test) { | 1971 ASSEMBLER_TEST_RUN(PackedDoubleNegate, test) { |
2102 double res = test->InvokeWithCodeAndThread<double>(); | 1972 double res = test->InvokeWithCodeAndThread<double>(); |
2103 EXPECT_FLOAT_EQ(-1.0, res, 0.000001f); | 1973 EXPECT_FLOAT_EQ(-1.0, res, 0.000001f); |
2104 } | 1974 } |
2105 | 1975 |
2106 | |
2107 ASSEMBLER_TEST_GENERATE(PackedDoubleAbsolute, assembler) { | 1976 ASSEMBLER_TEST_GENERATE(PackedDoubleAbsolute, assembler) { |
2108 static const struct ALIGN16 { | 1977 static const struct ALIGN16 { |
2109 double a; | 1978 double a; |
2110 double b; | 1979 double b; |
2111 } constant0 = {-1.0, 2.0}; | 1980 } constant0 = {-1.0, 2.0}; |
2112 EnterTestFrame(assembler); | 1981 EnterTestFrame(assembler); |
2113 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 1982 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2114 __ movups(XMM10, Address(RAX, 0)); | 1983 __ movups(XMM10, Address(RAX, 0)); |
2115 __ abspd(XMM10); | 1984 __ abspd(XMM10); |
2116 __ movaps(XMM0, XMM10); | 1985 __ movaps(XMM0, XMM10); |
2117 LeaveTestFrame(assembler); | 1986 LeaveTestFrame(assembler); |
2118 __ ret(); | 1987 __ ret(); |
2119 } | 1988 } |
2120 | 1989 |
2121 | |
2122 ASSEMBLER_TEST_RUN(PackedDoubleAbsolute, test) { | 1990 ASSEMBLER_TEST_RUN(PackedDoubleAbsolute, test) { |
2123 double res = test->InvokeWithCodeAndThread<double>(); | 1991 double res = test->InvokeWithCodeAndThread<double>(); |
2124 EXPECT_FLOAT_EQ(1.0, res, 0.000001f); | 1992 EXPECT_FLOAT_EQ(1.0, res, 0.000001f); |
2125 } | 1993 } |
2126 | 1994 |
2127 | |
2128 ASSEMBLER_TEST_GENERATE(PackedDoubleMul, assembler) { | 1995 ASSEMBLER_TEST_GENERATE(PackedDoubleMul, assembler) { |
2129 static const struct ALIGN16 { | 1996 static const struct ALIGN16 { |
2130 double a; | 1997 double a; |
2131 double b; | 1998 double b; |
2132 } constant0 = {3.0, 2.0}; | 1999 } constant0 = {3.0, 2.0}; |
2133 static const struct ALIGN16 { | 2000 static const struct ALIGN16 { |
2134 double a; | 2001 double a; |
2135 double b; | 2002 double b; |
2136 } constant1 = {3.0, 4.0}; | 2003 } constant1 = {3.0, 4.0}; |
2137 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 2004 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2138 __ movups(XMM10, Address(RAX, 0)); | 2005 __ movups(XMM10, Address(RAX, 0)); |
2139 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); | 2006 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); |
2140 __ movups(XMM11, Address(RAX, 0)); | 2007 __ movups(XMM11, Address(RAX, 0)); |
2141 __ mulpd(XMM10, XMM11); | 2008 __ mulpd(XMM10, XMM11); |
2142 __ movaps(XMM0, XMM10); | 2009 __ movaps(XMM0, XMM10); |
2143 __ ret(); | 2010 __ ret(); |
2144 } | 2011 } |
2145 | 2012 |
2146 | |
2147 ASSEMBLER_TEST_RUN(PackedDoubleMul, test) { | 2013 ASSEMBLER_TEST_RUN(PackedDoubleMul, test) { |
2148 typedef double (*PackedDoubleMul)(); | 2014 typedef double (*PackedDoubleMul)(); |
2149 double res = reinterpret_cast<PackedDoubleMul>(test->entry())(); | 2015 double res = reinterpret_cast<PackedDoubleMul>(test->entry())(); |
2150 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 2016 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
2151 } | 2017 } |
2152 | 2018 |
2153 | |
2154 ASSEMBLER_TEST_GENERATE(PackedDoubleDiv, assembler) { | 2019 ASSEMBLER_TEST_GENERATE(PackedDoubleDiv, assembler) { |
2155 static const struct ALIGN16 { | 2020 static const struct ALIGN16 { |
2156 double a; | 2021 double a; |
2157 double b; | 2022 double b; |
2158 } constant0 = {9.0, 2.0}; | 2023 } constant0 = {9.0, 2.0}; |
2159 static const struct ALIGN16 { | 2024 static const struct ALIGN16 { |
2160 double a; | 2025 double a; |
2161 double b; | 2026 double b; |
2162 } constant1 = {3.0, 4.0}; | 2027 } constant1 = {3.0, 4.0}; |
2163 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 2028 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2164 __ movups(XMM10, Address(RAX, 0)); | 2029 __ movups(XMM10, Address(RAX, 0)); |
2165 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); | 2030 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); |
2166 __ movups(XMM11, Address(RAX, 0)); | 2031 __ movups(XMM11, Address(RAX, 0)); |
2167 __ divpd(XMM10, XMM11); | 2032 __ divpd(XMM10, XMM11); |
2168 __ movaps(XMM0, XMM10); | 2033 __ movaps(XMM0, XMM10); |
2169 __ ret(); | 2034 __ ret(); |
2170 } | 2035 } |
2171 | 2036 |
2172 | |
2173 ASSEMBLER_TEST_RUN(PackedDoubleDiv, test) { | 2037 ASSEMBLER_TEST_RUN(PackedDoubleDiv, test) { |
2174 typedef double (*PackedDoubleDiv)(); | 2038 typedef double (*PackedDoubleDiv)(); |
2175 double res = reinterpret_cast<PackedDoubleDiv>(test->entry())(); | 2039 double res = reinterpret_cast<PackedDoubleDiv>(test->entry())(); |
2176 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); | 2040 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); |
2177 } | 2041 } |
2178 | 2042 |
2179 | |
2180 ASSEMBLER_TEST_GENERATE(PackedDoubleSqrt, assembler) { | 2043 ASSEMBLER_TEST_GENERATE(PackedDoubleSqrt, assembler) { |
2181 static const struct ALIGN16 { | 2044 static const struct ALIGN16 { |
2182 double a; | 2045 double a; |
2183 double b; | 2046 double b; |
2184 } constant0 = {16.0, 2.0}; | 2047 } constant0 = {16.0, 2.0}; |
2185 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 2048 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2186 __ movups(XMM10, Address(RAX, 0)); | 2049 __ movups(XMM10, Address(RAX, 0)); |
2187 __ sqrtpd(XMM10); | 2050 __ sqrtpd(XMM10); |
2188 __ movaps(XMM0, XMM10); | 2051 __ movaps(XMM0, XMM10); |
2189 __ ret(); | 2052 __ ret(); |
2190 } | 2053 } |
2191 | 2054 |
2192 | |
2193 ASSEMBLER_TEST_RUN(PackedDoubleSqrt, test) { | 2055 ASSEMBLER_TEST_RUN(PackedDoubleSqrt, test) { |
2194 typedef double (*PackedDoubleSqrt)(); | 2056 typedef double (*PackedDoubleSqrt)(); |
2195 double res = reinterpret_cast<PackedDoubleSqrt>(test->entry())(); | 2057 double res = reinterpret_cast<PackedDoubleSqrt>(test->entry())(); |
2196 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); | 2058 EXPECT_FLOAT_EQ(4.0, res, 0.000001f); |
2197 } | 2059 } |
2198 | 2060 |
2199 | |
2200 ASSEMBLER_TEST_GENERATE(PackedDoubleMin, assembler) { | 2061 ASSEMBLER_TEST_GENERATE(PackedDoubleMin, assembler) { |
2201 static const struct ALIGN16 { | 2062 static const struct ALIGN16 { |
2202 double a; | 2063 double a; |
2203 double b; | 2064 double b; |
2204 } constant0 = {9.0, 2.0}; | 2065 } constant0 = {9.0, 2.0}; |
2205 static const struct ALIGN16 { | 2066 static const struct ALIGN16 { |
2206 double a; | 2067 double a; |
2207 double b; | 2068 double b; |
2208 } constant1 = {3.0, 4.0}; | 2069 } constant1 = {3.0, 4.0}; |
2209 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 2070 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2210 __ movups(XMM10, Address(RAX, 0)); | 2071 __ movups(XMM10, Address(RAX, 0)); |
2211 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); | 2072 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); |
2212 __ movups(XMM11, Address(RAX, 0)); | 2073 __ movups(XMM11, Address(RAX, 0)); |
2213 __ minpd(XMM10, XMM11); | 2074 __ minpd(XMM10, XMM11); |
2214 __ movaps(XMM0, XMM10); | 2075 __ movaps(XMM0, XMM10); |
2215 __ ret(); | 2076 __ ret(); |
2216 } | 2077 } |
2217 | 2078 |
2218 | |
2219 ASSEMBLER_TEST_RUN(PackedDoubleMin, test) { | 2079 ASSEMBLER_TEST_RUN(PackedDoubleMin, test) { |
2220 typedef double (*PackedDoubleMin)(); | 2080 typedef double (*PackedDoubleMin)(); |
2221 double res = reinterpret_cast<PackedDoubleMin>(test->entry())(); | 2081 double res = reinterpret_cast<PackedDoubleMin>(test->entry())(); |
2222 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); | 2082 EXPECT_FLOAT_EQ(3.0, res, 0.000001f); |
2223 } | 2083 } |
2224 | 2084 |
2225 | |
2226 ASSEMBLER_TEST_GENERATE(PackedDoubleMax, assembler) { | 2085 ASSEMBLER_TEST_GENERATE(PackedDoubleMax, assembler) { |
2227 static const struct ALIGN16 { | 2086 static const struct ALIGN16 { |
2228 double a; | 2087 double a; |
2229 double b; | 2088 double b; |
2230 } constant0 = {9.0, 2.0}; | 2089 } constant0 = {9.0, 2.0}; |
2231 static const struct ALIGN16 { | 2090 static const struct ALIGN16 { |
2232 double a; | 2091 double a; |
2233 double b; | 2092 double b; |
2234 } constant1 = {3.0, 4.0}; | 2093 } constant1 = {3.0, 4.0}; |
2235 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 2094 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2236 __ movups(XMM10, Address(RAX, 0)); | 2095 __ movups(XMM10, Address(RAX, 0)); |
2237 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); | 2096 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant1))); |
2238 __ movups(XMM11, Address(RAX, 0)); | 2097 __ movups(XMM11, Address(RAX, 0)); |
2239 __ maxpd(XMM10, XMM11); | 2098 __ maxpd(XMM10, XMM11); |
2240 __ movaps(XMM0, XMM10); | 2099 __ movaps(XMM0, XMM10); |
2241 __ ret(); | 2100 __ ret(); |
2242 } | 2101 } |
2243 | 2102 |
2244 | |
2245 ASSEMBLER_TEST_RUN(PackedDoubleMax, test) { | 2103 ASSEMBLER_TEST_RUN(PackedDoubleMax, test) { |
2246 typedef double (*PackedDoubleMax)(); | 2104 typedef double (*PackedDoubleMax)(); |
2247 double res = reinterpret_cast<PackedDoubleMax>(test->entry())(); | 2105 double res = reinterpret_cast<PackedDoubleMax>(test->entry())(); |
2248 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 2106 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
2249 } | 2107 } |
2250 | 2108 |
2251 | |
2252 ASSEMBLER_TEST_GENERATE(PackedDoubleShuffle, assembler) { | 2109 ASSEMBLER_TEST_GENERATE(PackedDoubleShuffle, assembler) { |
2253 static const struct ALIGN16 { | 2110 static const struct ALIGN16 { |
2254 double a; | 2111 double a; |
2255 double b; | 2112 double b; |
2256 } constant0 = {2.0, 9.0}; | 2113 } constant0 = {2.0, 9.0}; |
2257 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 2114 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2258 __ movups(XMM10, Address(RAX, 0)); | 2115 __ movups(XMM10, Address(RAX, 0)); |
2259 // Splat Y across all lanes. | 2116 // Splat Y across all lanes. |
2260 __ shufpd(XMM10, XMM10, Immediate(0x33)); | 2117 __ shufpd(XMM10, XMM10, Immediate(0x33)); |
2261 // Splat X across all lanes. | 2118 // Splat X across all lanes. |
2262 __ shufpd(XMM10, XMM10, Immediate(0x0)); | 2119 __ shufpd(XMM10, XMM10, Immediate(0x0)); |
2263 // Set return value. | 2120 // Set return value. |
2264 __ movaps(XMM0, XMM10); | 2121 __ movaps(XMM0, XMM10); |
2265 __ ret(); | 2122 __ ret(); |
2266 } | 2123 } |
2267 | 2124 |
2268 | |
2269 ASSEMBLER_TEST_RUN(PackedDoubleShuffle, test) { | 2125 ASSEMBLER_TEST_RUN(PackedDoubleShuffle, test) { |
2270 typedef double (*PackedDoubleShuffle)(); | 2126 typedef double (*PackedDoubleShuffle)(); |
2271 double res = reinterpret_cast<PackedDoubleShuffle>(test->entry())(); | 2127 double res = reinterpret_cast<PackedDoubleShuffle>(test->entry())(); |
2272 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); | 2128 EXPECT_FLOAT_EQ(9.0, res, 0.000001f); |
2273 } | 2129 } |
2274 | 2130 |
2275 | |
2276 ASSEMBLER_TEST_GENERATE(PackedDoubleToSingle, assembler) { | 2131 ASSEMBLER_TEST_GENERATE(PackedDoubleToSingle, assembler) { |
2277 static const struct ALIGN16 { | 2132 static const struct ALIGN16 { |
2278 double a; | 2133 double a; |
2279 double b; | 2134 double b; |
2280 } constant0 = {9.0, 2.0}; | 2135 } constant0 = {9.0, 2.0}; |
2281 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 2136 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2282 __ movups(XMM11, Address(RAX, 0)); | 2137 __ movups(XMM11, Address(RAX, 0)); |
2283 __ cvtpd2ps(XMM10, XMM11); | 2138 __ cvtpd2ps(XMM10, XMM11); |
2284 __ movaps(XMM0, XMM10); | 2139 __ movaps(XMM0, XMM10); |
2285 __ ret(); | 2140 __ ret(); |
2286 } | 2141 } |
2287 | 2142 |
2288 | |
2289 ASSEMBLER_TEST_RUN(PackedDoubleToSingle, test) { | 2143 ASSEMBLER_TEST_RUN(PackedDoubleToSingle, test) { |
2290 typedef float (*PackedDoubleToSingle)(); | 2144 typedef float (*PackedDoubleToSingle)(); |
2291 float res = reinterpret_cast<PackedDoubleToSingle>(test->entry())(); | 2145 float res = reinterpret_cast<PackedDoubleToSingle>(test->entry())(); |
2292 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); | 2146 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); |
2293 } | 2147 } |
2294 | 2148 |
2295 | |
2296 ASSEMBLER_TEST_GENERATE(PackedSingleToDouble, assembler) { | 2149 ASSEMBLER_TEST_GENERATE(PackedSingleToDouble, assembler) { |
2297 static const struct ALIGN16 { | 2150 static const struct ALIGN16 { |
2298 float a; | 2151 float a; |
2299 float b; | 2152 float b; |
2300 float c; | 2153 float c; |
2301 float d; | 2154 float d; |
2302 } constant0 = {9.0f, 2.0f, 3.0f, 4.0f}; | 2155 } constant0 = {9.0f, 2.0f, 3.0f, 4.0f}; |
2303 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); | 2156 __ movq(RAX, Immediate(reinterpret_cast<uword>(&constant0))); |
2304 __ movups(XMM11, Address(RAX, 0)); | 2157 __ movups(XMM11, Address(RAX, 0)); |
2305 __ cvtps2pd(XMM10, XMM11); | 2158 __ cvtps2pd(XMM10, XMM11); |
2306 __ movaps(XMM0, XMM10); | 2159 __ movaps(XMM0, XMM10); |
2307 __ ret(); | 2160 __ ret(); |
2308 } | 2161 } |
2309 | 2162 |
2310 | |
2311 ASSEMBLER_TEST_RUN(PackedSingleToDouble, test) { | 2163 ASSEMBLER_TEST_RUN(PackedSingleToDouble, test) { |
2312 typedef double (*PackedSingleToDouble)(); | 2164 typedef double (*PackedSingleToDouble)(); |
2313 double res = reinterpret_cast<PackedSingleToDouble>(test->entry())(); | 2165 double res = reinterpret_cast<PackedSingleToDouble>(test->entry())(); |
2314 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); | 2166 EXPECT_FLOAT_EQ(9.0f, res, 0.000001f); |
2315 } | 2167 } |
2316 | 2168 |
2317 | |
2318 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) { | 2169 ASSEMBLER_TEST_GENERATE(SingleFPOperations, assembler) { |
2319 __ pushq(RBX); | 2170 __ pushq(RBX); |
2320 __ pushq(RCX); | 2171 __ pushq(RCX); |
2321 __ movq(RBX, Immediate(bit_cast<int32_t, float>(12.3f))); | 2172 __ movq(RBX, Immediate(bit_cast<int32_t, float>(12.3f))); |
2322 __ movd(XMM0, RBX); | 2173 __ movd(XMM0, RBX); |
2323 __ movd(XMM8, RBX); | 2174 __ movd(XMM8, RBX); |
2324 __ movq(RCX, Immediate(bit_cast<int32_t, float>(3.4f))); | 2175 __ movq(RCX, Immediate(bit_cast<int32_t, float>(3.4f))); |
2325 __ movd(XMM1, RCX); | 2176 __ movd(XMM1, RCX); |
2326 __ movd(XMM9, RCX); | 2177 __ movd(XMM9, RCX); |
2327 __ addss(XMM0, XMM1); // 15.7f | 2178 __ addss(XMM0, XMM1); // 15.7f |
2328 __ mulss(XMM0, XMM1); // 53.38f | 2179 __ mulss(XMM0, XMM1); // 53.38f |
2329 __ subss(XMM0, XMM1); // 49.98f | 2180 __ subss(XMM0, XMM1); // 49.98f |
2330 __ divss(XMM0, XMM1); // 14.7f | 2181 __ divss(XMM0, XMM1); // 14.7f |
2331 __ addss(XMM8, XMM9); // 15.7f | 2182 __ addss(XMM8, XMM9); // 15.7f |
2332 __ mulss(XMM8, XMM9); // 53.38f | 2183 __ mulss(XMM8, XMM9); // 53.38f |
2333 __ subss(XMM8, XMM9); // 49.98f | 2184 __ subss(XMM8, XMM9); // 49.98f |
2334 __ divss(XMM8, XMM9); // 14.7f | 2185 __ divss(XMM8, XMM9); // 14.7f |
2335 __ subss(XMM0, XMM8); // 0.0f | 2186 __ subss(XMM0, XMM8); // 0.0f |
2336 __ popq(RCX); | 2187 __ popq(RCX); |
2337 __ popq(RBX); | 2188 __ popq(RBX); |
2338 __ ret(); | 2189 __ ret(); |
2339 } | 2190 } |
2340 | 2191 |
2341 | |
2342 ASSEMBLER_TEST_RUN(SingleFPOperations, test) { | 2192 ASSEMBLER_TEST_RUN(SingleFPOperations, test) { |
2343 typedef float (*SingleFPOperationsCode)(); | 2193 typedef float (*SingleFPOperationsCode)(); |
2344 float res = reinterpret_cast<SingleFPOperationsCode>(test->entry())(); | 2194 float res = reinterpret_cast<SingleFPOperationsCode>(test->entry())(); |
2345 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); | 2195 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); |
2346 } | 2196 } |
2347 | 2197 |
2348 ASSEMBLER_TEST_GENERATE(PackedFPOperations, assembler) { | 2198 ASSEMBLER_TEST_GENERATE(PackedFPOperations, assembler) { |
2349 __ movq(RAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 2199 __ movq(RAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
2350 __ movd(XMM10, RAX); | 2200 __ movd(XMM10, RAX); |
2351 __ shufps(XMM10, XMM10, Immediate(0x0)); | 2201 __ shufps(XMM10, XMM10, Immediate(0x0)); |
2352 __ movq(RAX, Immediate(bit_cast<int32_t, float>(3.4f))); | 2202 __ movq(RAX, Immediate(bit_cast<int32_t, float>(3.4f))); |
2353 __ movd(XMM9, RAX); | 2203 __ movd(XMM9, RAX); |
2354 __ shufps(XMM9, XMM9, Immediate(0x0)); | 2204 __ shufps(XMM9, XMM9, Immediate(0x0)); |
2355 __ addps(XMM10, XMM9); // 15.7f | 2205 __ addps(XMM10, XMM9); // 15.7f |
2356 __ mulps(XMM10, XMM9); // 53.38f | 2206 __ mulps(XMM10, XMM9); // 53.38f |
2357 __ subps(XMM10, XMM9); // 49.98f | 2207 __ subps(XMM10, XMM9); // 49.98f |
2358 __ divps(XMM10, XMM9); // 14.7f | 2208 __ divps(XMM10, XMM9); // 14.7f |
2359 __ movaps(XMM0, XMM10); | 2209 __ movaps(XMM0, XMM10); |
2360 __ shufps(XMM0, XMM0, Immediate(0x55)); // Copy second lane into all 4 lanes. | 2210 __ shufps(XMM0, XMM0, Immediate(0x55)); // Copy second lane into all 4 lanes. |
2361 __ ret(); | 2211 __ ret(); |
2362 } | 2212 } |
2363 | 2213 |
2364 | |
2365 ASSEMBLER_TEST_RUN(PackedFPOperations, test) { | 2214 ASSEMBLER_TEST_RUN(PackedFPOperations, test) { |
2366 typedef float (*PackedFPOperationsCode)(); | 2215 typedef float (*PackedFPOperationsCode)(); |
2367 float res = reinterpret_cast<PackedFPOperationsCode>(test->entry())(); | 2216 float res = reinterpret_cast<PackedFPOperationsCode>(test->entry())(); |
2368 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); | 2217 EXPECT_FLOAT_EQ(14.7f, res, 0.001f); |
2369 } | 2218 } |
2370 | 2219 |
2371 | |
2372 ASSEMBLER_TEST_GENERATE(PackedIntOperations, assembler) { | 2220 ASSEMBLER_TEST_GENERATE(PackedIntOperations, assembler) { |
2373 __ movl(RAX, Immediate(0x2)); | 2221 __ movl(RAX, Immediate(0x2)); |
2374 __ movd(XMM0, RAX); | 2222 __ movd(XMM0, RAX); |
2375 __ shufps(XMM0, XMM0, Immediate(0x0)); | 2223 __ shufps(XMM0, XMM0, Immediate(0x0)); |
2376 __ movl(RAX, Immediate(0x1)); | 2224 __ movl(RAX, Immediate(0x1)); |
2377 __ movd(XMM1, RAX); | 2225 __ movd(XMM1, RAX); |
2378 __ shufps(XMM1, XMM1, Immediate(0x0)); | 2226 __ shufps(XMM1, XMM1, Immediate(0x0)); |
2379 __ addpl(XMM0, XMM1); // 0x3 | 2227 __ addpl(XMM0, XMM1); // 0x3 |
2380 __ addpl(XMM0, XMM0); // 0x6 | 2228 __ addpl(XMM0, XMM0); // 0x6 |
2381 __ subpl(XMM0, XMM1); // 0x5 | 2229 __ subpl(XMM0, XMM1); // 0x5 |
2382 __ pushq(RAX); | 2230 __ pushq(RAX); |
2383 __ movss(Address(RSP, 0), XMM0); | 2231 __ movss(Address(RSP, 0), XMM0); |
2384 __ popq(RAX); | 2232 __ popq(RAX); |
2385 __ ret(); | 2233 __ ret(); |
2386 } | 2234 } |
2387 | 2235 |
2388 | |
2389 ASSEMBLER_TEST_RUN(PackedIntOperations, test) { | 2236 ASSEMBLER_TEST_RUN(PackedIntOperations, test) { |
2390 typedef uint32_t (*PackedIntOperationsCode)(); | 2237 typedef uint32_t (*PackedIntOperationsCode)(); |
2391 uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())(); | 2238 uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())(); |
2392 EXPECT_EQ(static_cast<uword>(0x5), res); | 2239 EXPECT_EQ(static_cast<uword>(0x5), res); |
2393 } | 2240 } |
2394 | 2241 |
2395 | |
2396 ASSEMBLER_TEST_GENERATE(PackedIntOperations2, assembler) { | 2242 ASSEMBLER_TEST_GENERATE(PackedIntOperations2, assembler) { |
2397 // Note: on Windows 64 XMM6-XMM15 are callee save. | 2243 // Note: on Windows 64 XMM6-XMM15 are callee save. |
2398 const intptr_t cpu_register_set = 0; | 2244 const intptr_t cpu_register_set = 0; |
2399 const intptr_t fpu_register_set = | 2245 const intptr_t fpu_register_set = |
2400 ((1 << XMM10) | (1 << XMM11)) & CallingConventions::kVolatileXmmRegisters; | 2246 ((1 << XMM10) | (1 << XMM11)) & CallingConventions::kVolatileXmmRegisters; |
2401 __ PushRegisters(cpu_register_set, fpu_register_set); | 2247 __ PushRegisters(cpu_register_set, fpu_register_set); |
2402 __ movl(RAX, Immediate(0x2)); | 2248 __ movl(RAX, Immediate(0x2)); |
2403 __ movd(XMM10, RAX); | 2249 __ movd(XMM10, RAX); |
2404 __ shufps(XMM10, XMM10, Immediate(0x0)); | 2250 __ shufps(XMM10, XMM10, Immediate(0x0)); |
2405 __ movl(RAX, Immediate(0x1)); | 2251 __ movl(RAX, Immediate(0x1)); |
2406 __ movd(XMM11, RAX); | 2252 __ movd(XMM11, RAX); |
2407 __ shufps(XMM11, XMM11, Immediate(0x0)); | 2253 __ shufps(XMM11, XMM11, Immediate(0x0)); |
2408 __ addpl(XMM10, XMM11); // 0x3 | 2254 __ addpl(XMM10, XMM11); // 0x3 |
2409 __ addpl(XMM10, XMM10); // 0x6 | 2255 __ addpl(XMM10, XMM10); // 0x6 |
2410 __ subpl(XMM10, XMM11); // 0x5 | 2256 __ subpl(XMM10, XMM11); // 0x5 |
2411 __ pushq(RAX); | 2257 __ pushq(RAX); |
2412 __ movss(Address(RSP, 0), XMM10); | 2258 __ movss(Address(RSP, 0), XMM10); |
2413 __ popq(RAX); | 2259 __ popq(RAX); |
2414 __ PopRegisters(cpu_register_set, fpu_register_set); | 2260 __ PopRegisters(cpu_register_set, fpu_register_set); |
2415 __ ret(); | 2261 __ ret(); |
2416 } | 2262 } |
2417 | 2263 |
2418 | |
2419 ASSEMBLER_TEST_RUN(PackedIntOperations2, test) { | 2264 ASSEMBLER_TEST_RUN(PackedIntOperations2, test) { |
2420 typedef uint32_t (*PackedIntOperationsCode)(); | 2265 typedef uint32_t (*PackedIntOperationsCode)(); |
2421 uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())(); | 2266 uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())(); |
2422 EXPECT_EQ(static_cast<uword>(0x5), res); | 2267 EXPECT_EQ(static_cast<uword>(0x5), res); |
2423 } | 2268 } |
2424 | 2269 |
2425 | |
2426 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) { | 2270 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) { |
2427 __ movq(RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2271 __ movq(RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2428 __ movd(XMM0, RAX); | 2272 __ movd(XMM0, RAX); |
2429 __ shufps(XMM0, XMM0, Immediate(0x0)); | 2273 __ shufps(XMM0, XMM0, Immediate(0x0)); |
2430 | 2274 |
2431 __ movaps(XMM11, XMM0); // Copy XMM0 | 2275 __ movaps(XMM11, XMM0); // Copy XMM0 |
2432 __ reciprocalps(XMM11); // 0.25 | 2276 __ reciprocalps(XMM11); // 0.25 |
2433 __ sqrtps(XMM11); // 0.5 | 2277 __ sqrtps(XMM11); // 0.5 |
2434 __ rsqrtps(XMM0); // ~0.5 | 2278 __ rsqrtps(XMM0); // ~0.5 |
2435 __ subps(XMM0, XMM11); // ~0.0 | 2279 __ subps(XMM0, XMM11); // ~0.0 |
2436 __ shufps(XMM0, XMM0, Immediate(0x00)); // Copy second lane into all 4 lanes. | 2280 __ shufps(XMM0, XMM0, Immediate(0x00)); // Copy second lane into all 4 lanes. |
2437 __ ret(); | 2281 __ ret(); |
2438 } | 2282 } |
2439 | 2283 |
2440 | |
2441 ASSEMBLER_TEST_RUN(PackedFPOperations2, test) { | 2284 ASSEMBLER_TEST_RUN(PackedFPOperations2, test) { |
2442 typedef float (*PackedFPOperations2Code)(); | 2285 typedef float (*PackedFPOperations2Code)(); |
2443 float res = reinterpret_cast<PackedFPOperations2Code>(test->entry())(); | 2286 float res = reinterpret_cast<PackedFPOperations2Code>(test->entry())(); |
2444 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); | 2287 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); |
2445 } | 2288 } |
2446 | 2289 |
2447 | |
2448 ASSEMBLER_TEST_GENERATE(PackedCompareEQ, assembler) { | 2290 ASSEMBLER_TEST_GENERATE(PackedCompareEQ, assembler) { |
2449 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 2291 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
2450 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2292 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2451 __ cmppseq(XMM0, XMM1); | 2293 __ cmppseq(XMM0, XMM1); |
2452 __ pushq(RAX); | 2294 __ pushq(RAX); |
2453 __ movss(Address(RSP, 0), XMM0); | 2295 __ movss(Address(RSP, 0), XMM0); |
2454 __ popq(RAX); | 2296 __ popq(RAX); |
2455 __ ret(); | 2297 __ ret(); |
2456 } | 2298 } |
2457 | 2299 |
2458 | |
2459 ASSEMBLER_TEST_RUN(PackedCompareEQ, test) { | 2300 ASSEMBLER_TEST_RUN(PackedCompareEQ, test) { |
2460 typedef uint32_t (*PackedCompareEQCode)(); | 2301 typedef uint32_t (*PackedCompareEQCode)(); |
2461 uint32_t res = reinterpret_cast<PackedCompareEQCode>(test->entry())(); | 2302 uint32_t res = reinterpret_cast<PackedCompareEQCode>(test->entry())(); |
2462 EXPECT_EQ(static_cast<uword>(0x0), res); | 2303 EXPECT_EQ(static_cast<uword>(0x0), res); |
2463 } | 2304 } |
2464 | 2305 |
2465 | |
2466 ASSEMBLER_TEST_GENERATE(PackedCompareNEQ, assembler) { | 2306 ASSEMBLER_TEST_GENERATE(PackedCompareNEQ, assembler) { |
2467 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 2307 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
2468 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2308 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2469 __ cmppsneq(XMM0, XMM1); | 2309 __ cmppsneq(XMM0, XMM1); |
2470 __ pushq(RAX); | 2310 __ pushq(RAX); |
2471 __ movss(Address(RSP, 0), XMM0); | 2311 __ movss(Address(RSP, 0), XMM0); |
2472 __ popq(RAX); | 2312 __ popq(RAX); |
2473 __ ret(); | 2313 __ ret(); |
2474 } | 2314 } |
2475 | 2315 |
2476 | |
2477 ASSEMBLER_TEST_RUN(PackedCompareNEQ, test) { | 2316 ASSEMBLER_TEST_RUN(PackedCompareNEQ, test) { |
2478 typedef uint32_t (*PackedCompareNEQCode)(); | 2317 typedef uint32_t (*PackedCompareNEQCode)(); |
2479 uint32_t res = reinterpret_cast<PackedCompareNEQCode>(test->entry())(); | 2318 uint32_t res = reinterpret_cast<PackedCompareNEQCode>(test->entry())(); |
2480 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); | 2319 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
2481 } | 2320 } |
2482 | 2321 |
2483 | |
2484 ASSEMBLER_TEST_GENERATE(PackedCompareLT, assembler) { | 2322 ASSEMBLER_TEST_GENERATE(PackedCompareLT, assembler) { |
2485 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 2323 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
2486 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2324 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2487 __ cmppslt(XMM0, XMM1); | 2325 __ cmppslt(XMM0, XMM1); |
2488 __ pushq(RAX); | 2326 __ pushq(RAX); |
2489 __ movss(Address(RSP, 0), XMM0); | 2327 __ movss(Address(RSP, 0), XMM0); |
2490 __ popq(RAX); | 2328 __ popq(RAX); |
2491 __ ret(); | 2329 __ ret(); |
2492 } | 2330 } |
2493 | 2331 |
2494 | |
2495 ASSEMBLER_TEST_RUN(PackedCompareLT, test) { | 2332 ASSEMBLER_TEST_RUN(PackedCompareLT, test) { |
2496 typedef uint32_t (*PackedCompareLTCode)(); | 2333 typedef uint32_t (*PackedCompareLTCode)(); |
2497 uint32_t res = reinterpret_cast<PackedCompareLTCode>(test->entry())(); | 2334 uint32_t res = reinterpret_cast<PackedCompareLTCode>(test->entry())(); |
2498 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); | 2335 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
2499 } | 2336 } |
2500 | 2337 |
2501 | |
2502 ASSEMBLER_TEST_GENERATE(PackedCompareLE, assembler) { | 2338 ASSEMBLER_TEST_GENERATE(PackedCompareLE, assembler) { |
2503 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 2339 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
2504 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2340 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2505 __ cmppsle(XMM0, XMM1); | 2341 __ cmppsle(XMM0, XMM1); |
2506 __ pushq(RAX); | 2342 __ pushq(RAX); |
2507 __ movss(Address(RSP, 0), XMM0); | 2343 __ movss(Address(RSP, 0), XMM0); |
2508 __ popq(RAX); | 2344 __ popq(RAX); |
2509 __ ret(); | 2345 __ ret(); |
2510 } | 2346 } |
2511 | 2347 |
2512 | |
2513 ASSEMBLER_TEST_RUN(PackedCompareLE, test) { | 2348 ASSEMBLER_TEST_RUN(PackedCompareLE, test) { |
2514 typedef uint32_t (*PackedCompareLECode)(); | 2349 typedef uint32_t (*PackedCompareLECode)(); |
2515 uint32_t res = reinterpret_cast<PackedCompareLECode>(test->entry())(); | 2350 uint32_t res = reinterpret_cast<PackedCompareLECode>(test->entry())(); |
2516 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); | 2351 EXPECT_EQ(static_cast<uword>(0xFFFFFFFF), res); |
2517 } | 2352 } |
2518 | 2353 |
2519 | |
2520 ASSEMBLER_TEST_GENERATE(PackedCompareNLT, assembler) { | 2354 ASSEMBLER_TEST_GENERATE(PackedCompareNLT, assembler) { |
2521 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 2355 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
2522 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2356 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2523 __ cmppsnlt(XMM0, XMM1); | 2357 __ cmppsnlt(XMM0, XMM1); |
2524 __ pushq(RAX); | 2358 __ pushq(RAX); |
2525 __ movss(Address(RSP, 0), XMM0); | 2359 __ movss(Address(RSP, 0), XMM0); |
2526 __ popq(RAX); | 2360 __ popq(RAX); |
2527 __ ret(); | 2361 __ ret(); |
2528 } | 2362 } |
2529 | 2363 |
2530 | |
2531 ASSEMBLER_TEST_RUN(PackedCompareNLT, test) { | 2364 ASSEMBLER_TEST_RUN(PackedCompareNLT, test) { |
2532 typedef uint32_t (*PackedCompareNLTCode)(); | 2365 typedef uint32_t (*PackedCompareNLTCode)(); |
2533 uint32_t res = reinterpret_cast<PackedCompareNLTCode>(test->entry())(); | 2366 uint32_t res = reinterpret_cast<PackedCompareNLTCode>(test->entry())(); |
2534 EXPECT_EQ(static_cast<uword>(0x0), res); | 2367 EXPECT_EQ(static_cast<uword>(0x0), res); |
2535 } | 2368 } |
2536 | 2369 |
2537 | |
2538 ASSEMBLER_TEST_GENERATE(PackedCompareNLE, assembler) { | 2370 ASSEMBLER_TEST_GENERATE(PackedCompareNLE, assembler) { |
2539 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 2371 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
2540 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2372 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2541 __ cmppsnle(XMM0, XMM1); | 2373 __ cmppsnle(XMM0, XMM1); |
2542 __ pushq(RAX); | 2374 __ pushq(RAX); |
2543 __ movss(Address(RSP, 0), XMM0); | 2375 __ movss(Address(RSP, 0), XMM0); |
2544 __ popq(RAX); | 2376 __ popq(RAX); |
2545 __ ret(); | 2377 __ ret(); |
2546 } | 2378 } |
2547 | 2379 |
2548 | |
2549 ASSEMBLER_TEST_RUN(PackedCompareNLE, test) { | 2380 ASSEMBLER_TEST_RUN(PackedCompareNLE, test) { |
2550 typedef uint32_t (*PackedCompareNLECode)(); | 2381 typedef uint32_t (*PackedCompareNLECode)(); |
2551 uint32_t res = reinterpret_cast<PackedCompareNLECode>(test->entry())(); | 2382 uint32_t res = reinterpret_cast<PackedCompareNLECode>(test->entry())(); |
2552 EXPECT_EQ(static_cast<uword>(0x0), res); | 2383 EXPECT_EQ(static_cast<uword>(0x0), res); |
2553 } | 2384 } |
2554 | 2385 |
2555 | |
2556 ASSEMBLER_TEST_GENERATE(PackedNegate, assembler) { | 2386 ASSEMBLER_TEST_GENERATE(PackedNegate, assembler) { |
2557 EnterTestFrame(assembler); | 2387 EnterTestFrame(assembler); |
2558 __ movl(RAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 2388 __ movl(RAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
2559 __ movd(XMM0, RAX); | 2389 __ movd(XMM0, RAX); |
2560 __ shufps(XMM0, XMM0, Immediate(0x0)); | 2390 __ shufps(XMM0, XMM0, Immediate(0x0)); |
2561 __ negateps(XMM0); | 2391 __ negateps(XMM0); |
2562 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. | 2392 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. |
2563 LeaveTestFrame(assembler); | 2393 LeaveTestFrame(assembler); |
2564 __ ret(); | 2394 __ ret(); |
2565 } | 2395 } |
2566 | 2396 |
2567 | |
2568 ASSEMBLER_TEST_RUN(PackedNegate, test) { | 2397 ASSEMBLER_TEST_RUN(PackedNegate, test) { |
2569 float res = test->InvokeWithCodeAndThread<float>(); | 2398 float res = test->InvokeWithCodeAndThread<float>(); |
2570 EXPECT_FLOAT_EQ(-12.3f, res, 0.001f); | 2399 EXPECT_FLOAT_EQ(-12.3f, res, 0.001f); |
2571 } | 2400 } |
2572 | 2401 |
2573 | |
2574 ASSEMBLER_TEST_GENERATE(PackedAbsolute, assembler) { | 2402 ASSEMBLER_TEST_GENERATE(PackedAbsolute, assembler) { |
2575 EnterTestFrame(assembler); | 2403 EnterTestFrame(assembler); |
2576 __ movl(RAX, Immediate(bit_cast<int32_t, float>(-15.3f))); | 2404 __ movl(RAX, Immediate(bit_cast<int32_t, float>(-15.3f))); |
2577 __ movd(XMM0, RAX); | 2405 __ movd(XMM0, RAX); |
2578 __ shufps(XMM0, XMM0, Immediate(0x0)); | 2406 __ shufps(XMM0, XMM0, Immediate(0x0)); |
2579 __ absps(XMM0); | 2407 __ absps(XMM0); |
2580 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. | 2408 __ shufps(XMM0, XMM0, Immediate(0xAA)); // Copy third lane into all 4 lanes. |
2581 LeaveTestFrame(assembler); | 2409 LeaveTestFrame(assembler); |
2582 __ ret(); | 2410 __ ret(); |
2583 } | 2411 } |
2584 | 2412 |
2585 | |
2586 ASSEMBLER_TEST_RUN(PackedAbsolute, test) { | 2413 ASSEMBLER_TEST_RUN(PackedAbsolute, test) { |
2587 float res = test->InvokeWithCodeAndThread<float>(); | 2414 float res = test->InvokeWithCodeAndThread<float>(); |
2588 EXPECT_FLOAT_EQ(15.3f, res, 0.001f); | 2415 EXPECT_FLOAT_EQ(15.3f, res, 0.001f); |
2589 } | 2416 } |
2590 | 2417 |
2591 | |
2592 ASSEMBLER_TEST_GENERATE(PackedSetWZero, assembler) { | 2418 ASSEMBLER_TEST_GENERATE(PackedSetWZero, assembler) { |
2593 EnterTestFrame(assembler); | 2419 EnterTestFrame(assembler); |
2594 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(12.3f))); | 2420 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(12.3f))); |
2595 __ zerowps(XMM0); | 2421 __ zerowps(XMM0); |
2596 __ shufps(XMM0, XMM0, Immediate(0xFF)); // Copy the W lane which is now 0.0. | 2422 __ shufps(XMM0, XMM0, Immediate(0xFF)); // Copy the W lane which is now 0.0. |
2597 LeaveTestFrame(assembler); | 2423 LeaveTestFrame(assembler); |
2598 __ ret(); | 2424 __ ret(); |
2599 } | 2425 } |
2600 | 2426 |
2601 | |
2602 ASSEMBLER_TEST_RUN(PackedSetWZero, test) { | 2427 ASSEMBLER_TEST_RUN(PackedSetWZero, test) { |
2603 float res = test->InvokeWithCodeAndThread<float>(); | 2428 float res = test->InvokeWithCodeAndThread<float>(); |
2604 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); | 2429 EXPECT_FLOAT_EQ(0.0f, res, 0.001f); |
2605 } | 2430 } |
2606 | 2431 |
2607 | |
2608 ASSEMBLER_TEST_GENERATE(PackedMin, assembler) { | 2432 ASSEMBLER_TEST_GENERATE(PackedMin, assembler) { |
2609 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 2433 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
2610 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2434 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2611 __ minps(XMM0, XMM1); | 2435 __ minps(XMM0, XMM1); |
2612 __ ret(); | 2436 __ ret(); |
2613 } | 2437 } |
2614 | 2438 |
2615 | |
2616 ASSEMBLER_TEST_RUN(PackedMin, test) { | 2439 ASSEMBLER_TEST_RUN(PackedMin, test) { |
2617 typedef float (*PackedMinCode)(); | 2440 typedef float (*PackedMinCode)(); |
2618 float res = reinterpret_cast<PackedMinCode>(test->entry())(); | 2441 float res = reinterpret_cast<PackedMinCode>(test->entry())(); |
2619 EXPECT_FLOAT_EQ(2.0f, res, 0.001f); | 2442 EXPECT_FLOAT_EQ(2.0f, res, 0.001f); |
2620 } | 2443 } |
2621 | 2444 |
2622 | |
2623 ASSEMBLER_TEST_GENERATE(PackedMax, assembler) { | 2445 ASSEMBLER_TEST_GENERATE(PackedMax, assembler) { |
2624 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); | 2446 __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(2.0f))); |
2625 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); | 2447 __ set1ps(XMM1, RAX, Immediate(bit_cast<int32_t, float>(4.0f))); |
2626 __ maxps(XMM0, XMM1); | 2448 __ maxps(XMM0, XMM1); |
2627 __ ret(); | 2449 __ ret(); |
2628 } | 2450 } |
2629 | 2451 |
2630 | |
2631 ASSEMBLER_TEST_RUN(PackedMax, test) { | 2452 ASSEMBLER_TEST_RUN(PackedMax, test) { |
2632 typedef float (*PackedMaxCode)(); | 2453 typedef float (*PackedMaxCode)(); |
2633 float res = reinterpret_cast<PackedMaxCode>(test->entry())(); | 2454 float res = reinterpret_cast<PackedMaxCode>(test->entry())(); |
2634 EXPECT_FLOAT_EQ(4.0f, res, 0.001f); | 2455 EXPECT_FLOAT_EQ(4.0f, res, 0.001f); |
2635 } | 2456 } |
2636 | 2457 |
2637 | |
2638 ASSEMBLER_TEST_GENERATE(PackedLogicalOr, assembler) { | 2458 ASSEMBLER_TEST_GENERATE(PackedLogicalOr, assembler) { |
2639 static const struct ALIGN16 { | 2459 static const struct ALIGN16 { |
2640 uint32_t a; | 2460 uint32_t a; |
2641 uint32_t b; | 2461 uint32_t b; |
2642 uint32_t c; | 2462 uint32_t c; |
2643 uint32_t d; | 2463 uint32_t d; |
2644 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; | 2464 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; |
2645 static const struct ALIGN16 { | 2465 static const struct ALIGN16 { |
2646 uint32_t a; | 2466 uint32_t a; |
2647 uint32_t b; | 2467 uint32_t b; |
2648 uint32_t c; | 2468 uint32_t c; |
2649 uint32_t d; | 2469 uint32_t d; |
2650 } constant2 = {0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; | 2470 } constant2 = {0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; |
2651 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); | 2471 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); |
2652 __ movups(XMM0, Address(RAX, 0)); | 2472 __ movups(XMM0, Address(RAX, 0)); |
2653 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant2))); | 2473 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant2))); |
2654 __ movups(XMM1, Address(RAX, 0)); | 2474 __ movups(XMM1, Address(RAX, 0)); |
2655 __ orps(XMM0, XMM1); | 2475 __ orps(XMM0, XMM1); |
2656 __ pushq(RAX); | 2476 __ pushq(RAX); |
2657 __ movss(Address(RSP, 0), XMM0); | 2477 __ movss(Address(RSP, 0), XMM0); |
2658 __ popq(RAX); | 2478 __ popq(RAX); |
2659 __ ret(); | 2479 __ ret(); |
2660 } | 2480 } |
2661 | 2481 |
2662 | |
2663 ASSEMBLER_TEST_RUN(PackedLogicalOr, test) { | 2482 ASSEMBLER_TEST_RUN(PackedLogicalOr, test) { |
2664 typedef uint32_t (*PackedLogicalOrCode)(); | 2483 typedef uint32_t (*PackedLogicalOrCode)(); |
2665 uint32_t res = reinterpret_cast<PackedLogicalOrCode>(test->entry())(); | 2484 uint32_t res = reinterpret_cast<PackedLogicalOrCode>(test->entry())(); |
2666 EXPECT_EQ(0xFFFFFFFF, res); | 2485 EXPECT_EQ(0xFFFFFFFF, res); |
2667 } | 2486 } |
2668 | 2487 |
2669 | |
2670 ASSEMBLER_TEST_GENERATE(PackedLogicalAnd, assembler) { | 2488 ASSEMBLER_TEST_GENERATE(PackedLogicalAnd, assembler) { |
2671 static const struct ALIGN16 { | 2489 static const struct ALIGN16 { |
2672 uint32_t a; | 2490 uint32_t a; |
2673 uint32_t b; | 2491 uint32_t b; |
2674 uint32_t c; | 2492 uint32_t c; |
2675 uint32_t d; | 2493 uint32_t d; |
2676 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; | 2494 } constant1 = {0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0}; |
2677 static const struct ALIGN16 { | 2495 static const struct ALIGN16 { |
2678 uint32_t a; | 2496 uint32_t a; |
2679 uint32_t b; | 2497 uint32_t b; |
2680 uint32_t c; | 2498 uint32_t c; |
2681 uint32_t d; | 2499 uint32_t d; |
2682 } constant2 = {0x0F0FFF0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; | 2500 } constant2 = {0x0F0FFF0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F}; |
2683 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); | 2501 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); |
2684 __ movups(XMM0, Address(RAX, 0)); | 2502 __ movups(XMM0, Address(RAX, 0)); |
2685 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant2))); | 2503 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant2))); |
2686 __ andps(XMM0, Address(RAX, 0)); | 2504 __ andps(XMM0, Address(RAX, 0)); |
2687 __ pushq(RAX); | 2505 __ pushq(RAX); |
2688 __ movss(Address(RSP, 0), XMM0); | 2506 __ movss(Address(RSP, 0), XMM0); |
2689 __ popq(RAX); | 2507 __ popq(RAX); |
2690 __ ret(); | 2508 __ ret(); |
2691 } | 2509 } |
2692 | 2510 |
2693 | |
2694 ASSEMBLER_TEST_RUN(PackedLogicalAnd, test) { | 2511 ASSEMBLER_TEST_RUN(PackedLogicalAnd, test) { |
2695 typedef uint32_t (*PackedLogicalAndCode)(); | 2512 typedef uint32_t (*PackedLogicalAndCode)(); |
2696 uint32_t res = reinterpret_cast<PackedLogicalAndCode>(test->entry())(); | 2513 uint32_t res = reinterpret_cast<PackedLogicalAndCode>(test->entry())(); |
2697 EXPECT_EQ(static_cast<uword>(0x0000F000), res); | 2514 EXPECT_EQ(static_cast<uword>(0x0000F000), res); |
2698 } | 2515 } |
2699 | 2516 |
2700 | |
2701 ASSEMBLER_TEST_GENERATE(PackedLogicalNot, assembler) { | 2517 ASSEMBLER_TEST_GENERATE(PackedLogicalNot, assembler) { |
2702 static const struct ALIGN16 { | 2518 static const struct ALIGN16 { |
2703 uint32_t a; | 2519 uint32_t a; |
2704 uint32_t b; | 2520 uint32_t b; |
2705 uint32_t c; | 2521 uint32_t c; |
2706 uint32_t d; | 2522 uint32_t d; |
2707 } constant1 = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; | 2523 } constant1 = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; |
2708 EnterTestFrame(assembler); | 2524 EnterTestFrame(assembler); |
2709 __ LoadImmediate(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); | 2525 __ LoadImmediate(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1))); |
2710 __ movups(XMM9, Address(RAX, 0)); | 2526 __ movups(XMM9, Address(RAX, 0)); |
2711 __ notps(XMM9); | 2527 __ notps(XMM9); |
2712 __ movaps(XMM0, XMM9); | 2528 __ movaps(XMM0, XMM9); |
2713 __ pushq(RAX); | 2529 __ pushq(RAX); |
2714 __ movss(Address(RSP, 0), XMM0); | 2530 __ movss(Address(RSP, 0), XMM0); |
2715 __ popq(RAX); | 2531 __ popq(RAX); |
2716 LeaveTestFrame(assembler); | 2532 LeaveTestFrame(assembler); |
2717 __ ret(); | 2533 __ ret(); |
2718 } | 2534 } |
2719 | 2535 |
2720 | |
2721 ASSEMBLER_TEST_RUN(PackedLogicalNot, test) { | 2536 ASSEMBLER_TEST_RUN(PackedLogicalNot, test) { |
2722 uint32_t res = test->InvokeWithCodeAndThread<uint32_t>(); | 2537 uint32_t res = test->InvokeWithCodeAndThread<uint32_t>(); |
2723 EXPECT_EQ(static_cast<uword>(0x0), res); | 2538 EXPECT_EQ(static_cast<uword>(0x0), res); |
2724 } | 2539 } |
2725 | 2540 |
2726 | |
2727 ASSEMBLER_TEST_GENERATE(PackedMoveHighLow, assembler) { | 2541 ASSEMBLER_TEST_GENERATE(PackedMoveHighLow, assembler) { |
2728 static const struct ALIGN16 { | 2542 static const struct ALIGN16 { |
2729 float a; | 2543 float a; |
2730 float b; | 2544 float b; |
2731 float c; | 2545 float c; |
2732 float d; | 2546 float d; |
2733 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 2547 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
2734 static const struct ALIGN16 { | 2548 static const struct ALIGN16 { |
2735 float a; | 2549 float a; |
2736 float b; | 2550 float b; |
(...skipping 11 matching lines...) Expand all Loading... |
2748 __ xorps(XMM1, XMM1); | 2562 __ xorps(XMM1, XMM1); |
2749 // XMM1 = 7.0f, 8.0f, 3.0f, 4.0f. | 2563 // XMM1 = 7.0f, 8.0f, 3.0f, 4.0f. |
2750 __ movaps(XMM1, XMM9); | 2564 __ movaps(XMM1, XMM9); |
2751 __ shufps(XMM9, XMM9, Immediate(0x00)); // 7.0f. | 2565 __ shufps(XMM9, XMM9, Immediate(0x00)); // 7.0f. |
2752 __ shufps(XMM1, XMM1, Immediate(0x55)); // 8.0f. | 2566 __ shufps(XMM1, XMM1, Immediate(0x55)); // 8.0f. |
2753 __ addss(XMM9, XMM1); // 15.0f. | 2567 __ addss(XMM9, XMM1); // 15.0f. |
2754 __ movaps(XMM0, XMM9); | 2568 __ movaps(XMM0, XMM9); |
2755 __ ret(); | 2569 __ ret(); |
2756 } | 2570 } |
2757 | 2571 |
2758 | |
2759 ASSEMBLER_TEST_RUN(PackedMoveHighLow, test) { | 2572 ASSEMBLER_TEST_RUN(PackedMoveHighLow, test) { |
2760 typedef float (*PackedMoveHighLow)(); | 2573 typedef float (*PackedMoveHighLow)(); |
2761 float res = reinterpret_cast<PackedMoveHighLow>(test->entry())(); | 2574 float res = reinterpret_cast<PackedMoveHighLow>(test->entry())(); |
2762 EXPECT_FLOAT_EQ(15.0f, res, 0.001f); | 2575 EXPECT_FLOAT_EQ(15.0f, res, 0.001f); |
2763 } | 2576 } |
2764 | 2577 |
2765 | |
2766 ASSEMBLER_TEST_GENERATE(PackedMoveLowHigh, assembler) { | 2578 ASSEMBLER_TEST_GENERATE(PackedMoveLowHigh, assembler) { |
2767 static const struct ALIGN16 { | 2579 static const struct ALIGN16 { |
2768 float a; | 2580 float a; |
2769 float b; | 2581 float b; |
2770 float c; | 2582 float c; |
2771 float d; | 2583 float d; |
2772 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 2584 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
2773 static const struct ALIGN16 { | 2585 static const struct ALIGN16 { |
2774 float a; | 2586 float a; |
2775 float b; | 2587 float b; |
(...skipping 11 matching lines...) Expand all Loading... |
2787 __ xorps(XMM1, XMM1); | 2599 __ xorps(XMM1, XMM1); |
2788 // XMM1 = 1.0f, 2.0f, 5.0f, 6.0f | 2600 // XMM1 = 1.0f, 2.0f, 5.0f, 6.0f |
2789 __ movaps(XMM1, XMM9); | 2601 __ movaps(XMM1, XMM9); |
2790 __ shufps(XMM9, XMM9, Immediate(0xAA)); // 5.0f. | 2602 __ shufps(XMM9, XMM9, Immediate(0xAA)); // 5.0f. |
2791 __ shufps(XMM1, XMM1, Immediate(0xFF)); // 6.0f. | 2603 __ shufps(XMM1, XMM1, Immediate(0xFF)); // 6.0f. |
2792 __ addss(XMM9, XMM1); // 11.0f. | 2604 __ addss(XMM9, XMM1); // 11.0f. |
2793 __ movaps(XMM0, XMM9); | 2605 __ movaps(XMM0, XMM9); |
2794 __ ret(); | 2606 __ ret(); |
2795 } | 2607 } |
2796 | 2608 |
2797 | |
2798 ASSEMBLER_TEST_RUN(PackedMoveLowHigh, test) { | 2609 ASSEMBLER_TEST_RUN(PackedMoveLowHigh, test) { |
2799 typedef float (*PackedMoveLowHigh)(); | 2610 typedef float (*PackedMoveLowHigh)(); |
2800 float res = reinterpret_cast<PackedMoveLowHigh>(test->entry())(); | 2611 float res = reinterpret_cast<PackedMoveLowHigh>(test->entry())(); |
2801 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); | 2612 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); |
2802 } | 2613 } |
2803 | 2614 |
2804 | |
2805 ASSEMBLER_TEST_GENERATE(PackedUnpackLow, assembler) { | 2615 ASSEMBLER_TEST_GENERATE(PackedUnpackLow, assembler) { |
2806 static const struct ALIGN16 { | 2616 static const struct ALIGN16 { |
2807 float a; | 2617 float a; |
2808 float b; | 2618 float b; |
2809 float c; | 2619 float c; |
2810 float d; | 2620 float d; |
2811 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 2621 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
2812 static const struct ALIGN16 { | 2622 static const struct ALIGN16 { |
2813 float a; | 2623 float a; |
2814 float b; | 2624 float b; |
(...skipping 10 matching lines...) Expand all Loading... |
2825 __ unpcklps(XMM9, XMM1); | 2635 __ unpcklps(XMM9, XMM1); |
2826 // XMM1 = 1.0f, 5.0f, 2.0f, 6.0f. | 2636 // XMM1 = 1.0f, 5.0f, 2.0f, 6.0f. |
2827 __ movaps(XMM1, XMM9); | 2637 __ movaps(XMM1, XMM9); |
2828 __ shufps(XMM9, XMM9, Immediate(0x55)); | 2638 __ shufps(XMM9, XMM9, Immediate(0x55)); |
2829 __ shufps(XMM1, XMM1, Immediate(0xFF)); | 2639 __ shufps(XMM1, XMM1, Immediate(0xFF)); |
2830 __ addss(XMM9, XMM1); // 11.0f. | 2640 __ addss(XMM9, XMM1); // 11.0f. |
2831 __ movaps(XMM0, XMM9); | 2641 __ movaps(XMM0, XMM9); |
2832 __ ret(); | 2642 __ ret(); |
2833 } | 2643 } |
2834 | 2644 |
2835 | |
2836 ASSEMBLER_TEST_RUN(PackedUnpackLow, test) { | 2645 ASSEMBLER_TEST_RUN(PackedUnpackLow, test) { |
2837 typedef float (*PackedUnpackLow)(); | 2646 typedef float (*PackedUnpackLow)(); |
2838 float res = reinterpret_cast<PackedUnpackLow>(test->entry())(); | 2647 float res = reinterpret_cast<PackedUnpackLow>(test->entry())(); |
2839 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); | 2648 EXPECT_FLOAT_EQ(11.0f, res, 0.001f); |
2840 } | 2649 } |
2841 | 2650 |
2842 | |
2843 ASSEMBLER_TEST_GENERATE(PackedUnpackHigh, assembler) { | 2651 ASSEMBLER_TEST_GENERATE(PackedUnpackHigh, assembler) { |
2844 static const struct ALIGN16 { | 2652 static const struct ALIGN16 { |
2845 float a; | 2653 float a; |
2846 float b; | 2654 float b; |
2847 float c; | 2655 float c; |
2848 float d; | 2656 float d; |
2849 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 2657 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
2850 static const struct ALIGN16 { | 2658 static const struct ALIGN16 { |
2851 float a; | 2659 float a; |
2852 float b; | 2660 float b; |
(...skipping 10 matching lines...) Expand all Loading... |
2863 __ unpckhps(XMM9, XMM1); | 2671 __ unpckhps(XMM9, XMM1); |
2864 // XMM1 = 3.0f, 7.0f, 4.0f, 8.0f. | 2672 // XMM1 = 3.0f, 7.0f, 4.0f, 8.0f. |
2865 __ movaps(XMM1, XMM9); | 2673 __ movaps(XMM1, XMM9); |
2866 __ shufps(XMM9, XMM9, Immediate(0x00)); | 2674 __ shufps(XMM9, XMM9, Immediate(0x00)); |
2867 __ shufps(XMM1, XMM1, Immediate(0xAA)); | 2675 __ shufps(XMM1, XMM1, Immediate(0xAA)); |
2868 __ addss(XMM9, XMM1); // 7.0f. | 2676 __ addss(XMM9, XMM1); // 7.0f. |
2869 __ movaps(XMM0, XMM9); | 2677 __ movaps(XMM0, XMM9); |
2870 __ ret(); | 2678 __ ret(); |
2871 } | 2679 } |
2872 | 2680 |
2873 | |
2874 ASSEMBLER_TEST_RUN(PackedUnpackHigh, test) { | 2681 ASSEMBLER_TEST_RUN(PackedUnpackHigh, test) { |
2875 typedef float (*PackedUnpackHigh)(); | 2682 typedef float (*PackedUnpackHigh)(); |
2876 float res = reinterpret_cast<PackedUnpackHigh>(test->entry())(); | 2683 float res = reinterpret_cast<PackedUnpackHigh>(test->entry())(); |
2877 EXPECT_FLOAT_EQ(7.0f, res, 0.001f); | 2684 EXPECT_FLOAT_EQ(7.0f, res, 0.001f); |
2878 } | 2685 } |
2879 | 2686 |
2880 | |
2881 ASSEMBLER_TEST_GENERATE(PackedUnpackLowPair, assembler) { | 2687 ASSEMBLER_TEST_GENERATE(PackedUnpackLowPair, assembler) { |
2882 static const struct ALIGN16 { | 2688 static const struct ALIGN16 { |
2883 float a; | 2689 float a; |
2884 float b; | 2690 float b; |
2885 float c; | 2691 float c; |
2886 float d; | 2692 float d; |
2887 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 2693 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
2888 static const struct ALIGN16 { | 2694 static const struct ALIGN16 { |
2889 float a; | 2695 float a; |
2890 float b; | 2696 float b; |
(...skipping 10 matching lines...) Expand all Loading... |
2901 __ unpcklpd(XMM9, XMM1); | 2707 __ unpcklpd(XMM9, XMM1); |
2902 // XMM1 = 1.0f, 2.0f, 5.0f, 6.0f. | 2708 // XMM1 = 1.0f, 2.0f, 5.0f, 6.0f. |
2903 __ movaps(XMM1, XMM9); | 2709 __ movaps(XMM1, XMM9); |
2904 __ shufps(XMM9, XMM9, Immediate(0x00)); | 2710 __ shufps(XMM9, XMM9, Immediate(0x00)); |
2905 __ shufps(XMM1, XMM1, Immediate(0xAA)); | 2711 __ shufps(XMM1, XMM1, Immediate(0xAA)); |
2906 __ addss(XMM9, XMM1); // 6.0f. | 2712 __ addss(XMM9, XMM1); // 6.0f. |
2907 __ movaps(XMM0, XMM9); | 2713 __ movaps(XMM0, XMM9); |
2908 __ ret(); | 2714 __ ret(); |
2909 } | 2715 } |
2910 | 2716 |
2911 | |
2912 ASSEMBLER_TEST_RUN(PackedUnpackLowPair, test) { | 2717 ASSEMBLER_TEST_RUN(PackedUnpackLowPair, test) { |
2913 typedef float (*PackedUnpackLowPair)(); | 2718 typedef float (*PackedUnpackLowPair)(); |
2914 float res = reinterpret_cast<PackedUnpackLowPair>(test->entry())(); | 2719 float res = reinterpret_cast<PackedUnpackLowPair>(test->entry())(); |
2915 EXPECT_FLOAT_EQ(6.0f, res, 0.001f); | 2720 EXPECT_FLOAT_EQ(6.0f, res, 0.001f); |
2916 } | 2721 } |
2917 | 2722 |
2918 | |
2919 ASSEMBLER_TEST_GENERATE(PackedUnpackHighPair, assembler) { | 2723 ASSEMBLER_TEST_GENERATE(PackedUnpackHighPair, assembler) { |
2920 static const struct ALIGN16 { | 2724 static const struct ALIGN16 { |
2921 float a; | 2725 float a; |
2922 float b; | 2726 float b; |
2923 float c; | 2727 float c; |
2924 float d; | 2728 float d; |
2925 } constant0 = {1.0, 2.0, 3.0, 4.0}; | 2729 } constant0 = {1.0, 2.0, 3.0, 4.0}; |
2926 static const struct ALIGN16 { | 2730 static const struct ALIGN16 { |
2927 float a; | 2731 float a; |
2928 float b; | 2732 float b; |
(...skipping 10 matching lines...) Expand all Loading... |
2939 __ unpckhpd(XMM9, XMM1); | 2743 __ unpckhpd(XMM9, XMM1); |
2940 // XMM1 = 3.0f, 4.0f, 7.0f, 8.0f. | 2744 // XMM1 = 3.0f, 4.0f, 7.0f, 8.0f. |
2941 __ movaps(XMM1, XMM9); | 2745 __ movaps(XMM1, XMM9); |
2942 __ shufps(XMM9, XMM9, Immediate(0x55)); | 2746 __ shufps(XMM9, XMM9, Immediate(0x55)); |
2943 __ shufps(XMM1, XMM1, Immediate(0xFF)); | 2747 __ shufps(XMM1, XMM1, Immediate(0xFF)); |
2944 __ addss(XMM9, XMM1); // 12.0f. | 2748 __ addss(XMM9, XMM1); // 12.0f. |
2945 __ movaps(XMM0, XMM9); | 2749 __ movaps(XMM0, XMM9); |
2946 __ ret(); | 2750 __ ret(); |
2947 } | 2751 } |
2948 | 2752 |
2949 | |
2950 ASSEMBLER_TEST_RUN(PackedUnpackHighPair, test) { | 2753 ASSEMBLER_TEST_RUN(PackedUnpackHighPair, test) { |
2951 typedef float (*PackedUnpackHighPair)(); | 2754 typedef float (*PackedUnpackHighPair)(); |
2952 float res = reinterpret_cast<PackedUnpackHighPair>(test->entry())(); | 2755 float res = reinterpret_cast<PackedUnpackHighPair>(test->entry())(); |
2953 EXPECT_FLOAT_EQ(12.0f, res, 0.001f); | 2756 EXPECT_FLOAT_EQ(12.0f, res, 0.001f); |
2954 } | 2757 } |
2955 | 2758 |
2956 | |
2957 ASSEMBLER_TEST_GENERATE(DoubleFPMoves, assembler) { | 2759 ASSEMBLER_TEST_GENERATE(DoubleFPMoves, assembler) { |
2958 __ movq(RAX, Immediate(bit_cast<int64_t, double>(1024.67))); | 2760 __ movq(RAX, Immediate(bit_cast<int64_t, double>(1024.67))); |
2959 __ pushq(R15); // Callee saved. | 2761 __ pushq(R15); // Callee saved. |
2960 __ pushq(RAX); | 2762 __ pushq(RAX); |
2961 __ movsd(XMM0, Address(RSP, 0)); | 2763 __ movsd(XMM0, Address(RSP, 0)); |
2962 __ movsd(XMM1, XMM0); | 2764 __ movsd(XMM1, XMM0); |
2963 __ movsd(XMM2, XMM1); | 2765 __ movsd(XMM2, XMM1); |
2964 __ movsd(XMM3, XMM2); | 2766 __ movsd(XMM3, XMM2); |
2965 __ movsd(XMM4, XMM3); | 2767 __ movsd(XMM4, XMM3); |
2966 __ movsd(XMM5, XMM4); | 2768 __ movsd(XMM5, XMM4); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3001 __ movaps(XMM4, XMM5); | 2803 __ movaps(XMM4, XMM5); |
3002 __ movaps(XMM3, XMM4); | 2804 __ movaps(XMM3, XMM4); |
3003 __ movaps(XMM2, XMM3); | 2805 __ movaps(XMM2, XMM3); |
3004 __ movaps(XMM1, XMM2); | 2806 __ movaps(XMM1, XMM2); |
3005 __ movaps(XMM0, XMM1); | 2807 __ movaps(XMM0, XMM1); |
3006 __ popq(RAX); | 2808 __ popq(RAX); |
3007 __ popq(R15); // Callee saved. | 2809 __ popq(R15); // Callee saved. |
3008 __ ret(); | 2810 __ ret(); |
3009 } | 2811 } |
3010 | 2812 |
3011 | |
3012 ASSEMBLER_TEST_RUN(DoubleFPMoves, test) { | 2813 ASSEMBLER_TEST_RUN(DoubleFPMoves, test) { |
3013 typedef double (*DoubleFPMovesCode)(); | 2814 typedef double (*DoubleFPMovesCode)(); |
3014 EXPECT_FLOAT_EQ(1024.67, reinterpret_cast<DoubleFPMovesCode>(test->entry())(), | 2815 EXPECT_FLOAT_EQ(1024.67, reinterpret_cast<DoubleFPMovesCode>(test->entry())(), |
3015 0.001); | 2816 0.001); |
3016 } | 2817 } |
3017 | 2818 |
3018 | |
3019 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) { | 2819 ASSEMBLER_TEST_GENERATE(DoubleFPOperations, assembler) { |
3020 __ movq(RAX, Immediate(bit_cast<int64_t, double>(12.3))); | 2820 __ movq(RAX, Immediate(bit_cast<int64_t, double>(12.3))); |
3021 __ pushq(RAX); | 2821 __ pushq(RAX); |
3022 __ movsd(XMM0, Address(RSP, 0)); | 2822 __ movsd(XMM0, Address(RSP, 0)); |
3023 __ movsd(XMM8, Address(RSP, 0)); | 2823 __ movsd(XMM8, Address(RSP, 0)); |
3024 __ movq(RAX, Immediate(bit_cast<int64_t, double>(3.4))); | 2824 __ movq(RAX, Immediate(bit_cast<int64_t, double>(3.4))); |
3025 __ movq(Address(RSP, 0), RAX); | 2825 __ movq(Address(RSP, 0), RAX); |
3026 __ movsd(XMM12, Address(RSP, 0)); | 2826 __ movsd(XMM12, Address(RSP, 0)); |
3027 __ addsd(XMM8, XMM12); // 15.7 | 2827 __ addsd(XMM8, XMM12); // 15.7 |
3028 __ mulsd(XMM8, XMM12); // 53.38 | 2828 __ mulsd(XMM8, XMM12); // 53.38 |
3029 __ subsd(XMM8, XMM12); // 49.98 | 2829 __ subsd(XMM8, XMM12); // 49.98 |
3030 __ divsd(XMM8, XMM12); // 14.7 | 2830 __ divsd(XMM8, XMM12); // 14.7 |
3031 __ sqrtsd(XMM8, XMM8); // 3.834 | 2831 __ sqrtsd(XMM8, XMM8); // 3.834 |
3032 __ movsd(XMM1, Address(RSP, 0)); | 2832 __ movsd(XMM1, Address(RSP, 0)); |
3033 __ addsd(XMM0, XMM1); // 15.7 | 2833 __ addsd(XMM0, XMM1); // 15.7 |
3034 __ mulsd(XMM0, XMM1); // 53.38 | 2834 __ mulsd(XMM0, XMM1); // 53.38 |
3035 __ subsd(XMM0, XMM1); // 49.98 | 2835 __ subsd(XMM0, XMM1); // 49.98 |
3036 __ divsd(XMM0, XMM1); // 14.7 | 2836 __ divsd(XMM0, XMM1); // 14.7 |
3037 __ sqrtsd(XMM0, XMM0); // 3.834057902 | 2837 __ sqrtsd(XMM0, XMM0); // 3.834057902 |
3038 __ addsd(XMM0, XMM8); // 7.6681 | 2838 __ addsd(XMM0, XMM8); // 7.6681 |
3039 __ popq(RAX); | 2839 __ popq(RAX); |
3040 __ ret(); | 2840 __ ret(); |
3041 } | 2841 } |
3042 | 2842 |
3043 | |
3044 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) { | 2843 ASSEMBLER_TEST_RUN(DoubleFPOperations, test) { |
3045 typedef double (*SingleFPOperationsCode)(); | 2844 typedef double (*SingleFPOperationsCode)(); |
3046 double res = reinterpret_cast<SingleFPOperationsCode>(test->entry())(); | 2845 double res = reinterpret_cast<SingleFPOperationsCode>(test->entry())(); |
3047 EXPECT_FLOAT_EQ(7.668, res, 0.001); | 2846 EXPECT_FLOAT_EQ(7.668, res, 0.001); |
3048 } | 2847 } |
3049 | 2848 |
3050 | |
3051 ASSEMBLER_TEST_GENERATE(Int32ToDoubleConversion, assembler) { | 2849 ASSEMBLER_TEST_GENERATE(Int32ToDoubleConversion, assembler) { |
3052 // Fill upper bits with garbage. | 2850 // Fill upper bits with garbage. |
3053 __ movq(R11, Immediate(0x1111111100000006)); | 2851 __ movq(R11, Immediate(0x1111111100000006)); |
3054 __ cvtsi2sdl(XMM0, R11); | 2852 __ cvtsi2sdl(XMM0, R11); |
3055 // Fill upper bits with garbage. | 2853 // Fill upper bits with garbage. |
3056 __ movq(R11, Immediate(0x2222222200000008)); | 2854 __ movq(R11, Immediate(0x2222222200000008)); |
3057 __ cvtsi2sdl(XMM8, R11); | 2855 __ cvtsi2sdl(XMM8, R11); |
3058 __ subsd(XMM0, XMM8); | 2856 __ subsd(XMM0, XMM8); |
3059 __ ret(); | 2857 __ ret(); |
3060 } | 2858 } |
3061 | 2859 |
3062 | |
3063 ASSEMBLER_TEST_RUN(Int32ToDoubleConversion, test) { | 2860 ASSEMBLER_TEST_RUN(Int32ToDoubleConversion, test) { |
3064 typedef double (*Int32ToDoubleConversion)(); | 2861 typedef double (*Int32ToDoubleConversion)(); |
3065 double res = reinterpret_cast<Int32ToDoubleConversion>(test->entry())(); | 2862 double res = reinterpret_cast<Int32ToDoubleConversion>(test->entry())(); |
3066 EXPECT_FLOAT_EQ(-2.0, res, 0.001); | 2863 EXPECT_FLOAT_EQ(-2.0, res, 0.001); |
3067 } | 2864 } |
3068 | 2865 |
3069 | |
3070 ASSEMBLER_TEST_GENERATE(Int64ToDoubleConversion, assembler) { | 2866 ASSEMBLER_TEST_GENERATE(Int64ToDoubleConversion, assembler) { |
3071 __ movq(RDX, Immediate(12LL << 32)); | 2867 __ movq(RDX, Immediate(12LL << 32)); |
3072 __ cvtsi2sdq(XMM0, RDX); | 2868 __ cvtsi2sdq(XMM0, RDX); |
3073 __ movsd(XMM15, XMM0); // Move to high register | 2869 __ movsd(XMM15, XMM0); // Move to high register |
3074 __ addsd(XMM0, XMM0); // Stomp XMM0 | 2870 __ addsd(XMM0, XMM0); // Stomp XMM0 |
3075 __ movsd(XMM0, XMM15); // Move back to XMM0 | 2871 __ movsd(XMM0, XMM15); // Move back to XMM0 |
3076 __ ret(); | 2872 __ ret(); |
3077 } | 2873 } |
3078 | 2874 |
3079 | |
3080 ASSEMBLER_TEST_RUN(Int64ToDoubleConversion, test) { | 2875 ASSEMBLER_TEST_RUN(Int64ToDoubleConversion, test) { |
3081 typedef double (*Int64ToDoubleConversionCode)(); | 2876 typedef double (*Int64ToDoubleConversionCode)(); |
3082 double res = reinterpret_cast<Int64ToDoubleConversionCode>(test->entry())(); | 2877 double res = reinterpret_cast<Int64ToDoubleConversionCode>(test->entry())(); |
3083 EXPECT_FLOAT_EQ(static_cast<double>(12LL << 32), res, 0.001); | 2878 EXPECT_FLOAT_EQ(static_cast<double>(12LL << 32), res, 0.001); |
3084 } | 2879 } |
3085 | 2880 |
3086 | |
3087 ASSEMBLER_TEST_GENERATE(DoubleToInt64Conversion, assembler) { | 2881 ASSEMBLER_TEST_GENERATE(DoubleToInt64Conversion, assembler) { |
3088 __ movq(RAX, Immediate(bit_cast<int64_t, double>(12.3))); | 2882 __ movq(RAX, Immediate(bit_cast<int64_t, double>(12.3))); |
3089 __ pushq(RAX); | 2883 __ pushq(RAX); |
3090 __ movsd(XMM9, Address(RSP, 0)); | 2884 __ movsd(XMM9, Address(RSP, 0)); |
3091 __ movsd(XMM6, Address(RSP, 0)); | 2885 __ movsd(XMM6, Address(RSP, 0)); |
3092 __ popq(RAX); | 2886 __ popq(RAX); |
3093 __ cvttsd2siq(R10, XMM6); | 2887 __ cvttsd2siq(R10, XMM6); |
3094 __ cvttsd2siq(RDX, XMM6); | 2888 __ cvttsd2siq(RDX, XMM6); |
3095 __ cvttsd2siq(R10, XMM9); | 2889 __ cvttsd2siq(R10, XMM9); |
3096 __ cvttsd2siq(RDX, XMM9); | 2890 __ cvttsd2siq(RDX, XMM9); |
3097 __ subq(RDX, R10); | 2891 __ subq(RDX, R10); |
3098 __ movq(RAX, RDX); | 2892 __ movq(RAX, RDX); |
3099 __ ret(); | 2893 __ ret(); |
3100 } | 2894 } |
3101 | 2895 |
3102 | |
3103 ASSEMBLER_TEST_RUN(DoubleToInt64Conversion, test) { | 2896 ASSEMBLER_TEST_RUN(DoubleToInt64Conversion, test) { |
3104 typedef int64_t (*DoubleToInt64ConversionCode)(); | 2897 typedef int64_t (*DoubleToInt64ConversionCode)(); |
3105 int64_t res = reinterpret_cast<DoubleToInt64ConversionCode>(test->entry())(); | 2898 int64_t res = reinterpret_cast<DoubleToInt64ConversionCode>(test->entry())(); |
3106 EXPECT_EQ(0, res); | 2899 EXPECT_EQ(0, res); |
3107 } | 2900 } |
3108 | 2901 |
3109 | |
3110 ASSEMBLER_TEST_GENERATE(TestObjectCompare, assembler) { | 2902 ASSEMBLER_TEST_GENERATE(TestObjectCompare, assembler) { |
3111 ObjectStore* object_store = Isolate::Current()->object_store(); | 2903 ObjectStore* object_store = Isolate::Current()->object_store(); |
3112 const Object& obj = Object::ZoneHandle(object_store->smi_class()); | 2904 const Object& obj = Object::ZoneHandle(object_store->smi_class()); |
3113 Label fail; | 2905 Label fail; |
3114 EnterTestFrame(assembler); | 2906 EnterTestFrame(assembler); |
3115 __ LoadObject(RAX, obj); | 2907 __ LoadObject(RAX, obj); |
3116 __ CompareObject(RAX, obj); | 2908 __ CompareObject(RAX, obj); |
3117 __ j(NOT_EQUAL, &fail); | 2909 __ j(NOT_EQUAL, &fail); |
3118 __ LoadObject(RCX, obj); | 2910 __ LoadObject(RCX, obj); |
3119 __ CompareObject(RCX, obj); | 2911 __ CompareObject(RCX, obj); |
(...skipping 14 matching lines...) Expand all Loading... |
3134 __ j(NOT_EQUAL, &fail); | 2926 __ j(NOT_EQUAL, &fail); |
3135 __ movl(RAX, Immediate(1)); // OK | 2927 __ movl(RAX, Immediate(1)); // OK |
3136 LeaveTestFrame(assembler); | 2928 LeaveTestFrame(assembler); |
3137 __ ret(); | 2929 __ ret(); |
3138 __ Bind(&fail); | 2930 __ Bind(&fail); |
3139 __ movl(RAX, Immediate(0)); // Fail. | 2931 __ movl(RAX, Immediate(0)); // Fail. |
3140 LeaveTestFrame(assembler); | 2932 LeaveTestFrame(assembler); |
3141 __ ret(); | 2933 __ ret(); |
3142 } | 2934 } |
3143 | 2935 |
3144 | |
3145 ASSEMBLER_TEST_RUN(TestObjectCompare, test) { | 2936 ASSEMBLER_TEST_RUN(TestObjectCompare, test) { |
3146 bool res = test->InvokeWithCodeAndThread<bool>(); | 2937 bool res = test->InvokeWithCodeAndThread<bool>(); |
3147 EXPECT_EQ(true, res); | 2938 EXPECT_EQ(true, res); |
3148 } | 2939 } |
3149 | 2940 |
3150 | |
3151 ASSEMBLER_TEST_GENERATE(TestNop, assembler) { | 2941 ASSEMBLER_TEST_GENERATE(TestNop, assembler) { |
3152 __ nop(1); | 2942 __ nop(1); |
3153 __ nop(2); | 2943 __ nop(2); |
3154 __ nop(3); | 2944 __ nop(3); |
3155 __ nop(4); | 2945 __ nop(4); |
3156 __ nop(5); | 2946 __ nop(5); |
3157 __ nop(6); | 2947 __ nop(6); |
3158 __ nop(7); | 2948 __ nop(7); |
3159 __ nop(8); | 2949 __ nop(8); |
3160 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. | 2950 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. |
3161 __ ret(); | 2951 __ ret(); |
3162 } | 2952 } |
3163 | 2953 |
3164 | |
3165 ASSEMBLER_TEST_RUN(TestNop, test) { | 2954 ASSEMBLER_TEST_RUN(TestNop, test) { |
3166 typedef int (*TestNop)(); | 2955 typedef int (*TestNop)(); |
3167 int res = reinterpret_cast<TestNop>(test->payload_start())(); | 2956 int res = reinterpret_cast<TestNop>(test->payload_start())(); |
3168 EXPECT_EQ(36, res); // 36 nop bytes emitted. | 2957 EXPECT_EQ(36, res); // 36 nop bytes emitted. |
3169 } | 2958 } |
3170 | 2959 |
3171 | |
3172 ASSEMBLER_TEST_GENERATE(TestAlign0, assembler) { | 2960 ASSEMBLER_TEST_GENERATE(TestAlign0, assembler) { |
3173 __ Align(4, 0); | 2961 __ Align(4, 0); |
3174 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. | 2962 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. |
3175 __ ret(); | 2963 __ ret(); |
3176 } | 2964 } |
3177 | 2965 |
3178 | |
3179 ASSEMBLER_TEST_RUN(TestAlign0, test) { | 2966 ASSEMBLER_TEST_RUN(TestAlign0, test) { |
3180 typedef int (*TestAlign0)(); | 2967 typedef int (*TestAlign0)(); |
3181 int res = reinterpret_cast<TestAlign0>(test->payload_start())(); | 2968 int res = reinterpret_cast<TestAlign0>(test->payload_start())(); |
3182 EXPECT_EQ(0, res); // 0 bytes emitted. | 2969 EXPECT_EQ(0, res); // 0 bytes emitted. |
3183 } | 2970 } |
3184 | 2971 |
3185 | |
3186 ASSEMBLER_TEST_GENERATE(TestAlign1, assembler) { | 2972 ASSEMBLER_TEST_GENERATE(TestAlign1, assembler) { |
3187 __ nop(1); | 2973 __ nop(1); |
3188 __ Align(4, 0); | 2974 __ Align(4, 0); |
3189 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. | 2975 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. |
3190 __ ret(); | 2976 __ ret(); |
3191 } | 2977 } |
3192 | 2978 |
3193 | |
3194 ASSEMBLER_TEST_RUN(TestAlign1, test) { | 2979 ASSEMBLER_TEST_RUN(TestAlign1, test) { |
3195 typedef int (*TestAlign1)(); | 2980 typedef int (*TestAlign1)(); |
3196 int res = reinterpret_cast<TestAlign1>(test->payload_start())(); | 2981 int res = reinterpret_cast<TestAlign1>(test->payload_start())(); |
3197 EXPECT_EQ(4, res); // 4 bytes emitted. | 2982 EXPECT_EQ(4, res); // 4 bytes emitted. |
3198 } | 2983 } |
3199 | 2984 |
3200 | |
3201 ASSEMBLER_TEST_GENERATE(TestAlign1Offset1, assembler) { | 2985 ASSEMBLER_TEST_GENERATE(TestAlign1Offset1, assembler) { |
3202 __ nop(1); | 2986 __ nop(1); |
3203 __ Align(4, 1); | 2987 __ Align(4, 1); |
3204 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. | 2988 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. |
3205 __ ret(); | 2989 __ ret(); |
3206 } | 2990 } |
3207 | 2991 |
3208 | |
3209 ASSEMBLER_TEST_RUN(TestAlign1Offset1, test) { | 2992 ASSEMBLER_TEST_RUN(TestAlign1Offset1, test) { |
3210 typedef int (*TestAlign1Offset1)(); | 2993 typedef int (*TestAlign1Offset1)(); |
3211 int res = reinterpret_cast<TestAlign1Offset1>(test->payload_start())(); | 2994 int res = reinterpret_cast<TestAlign1Offset1>(test->payload_start())(); |
3212 EXPECT_EQ(3, res); // 3 bytes emitted. | 2995 EXPECT_EQ(3, res); // 3 bytes emitted. |
3213 } | 2996 } |
3214 | 2997 |
3215 | |
3216 ASSEMBLER_TEST_GENERATE(TestAlignLarge, assembler) { | 2998 ASSEMBLER_TEST_GENERATE(TestAlignLarge, assembler) { |
3217 __ nop(1); | 2999 __ nop(1); |
3218 __ Align(16, 0); | 3000 __ Align(16, 0); |
3219 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. | 3001 __ movq(RAX, Immediate(assembler->CodeSize())); // Return code size. |
3220 __ ret(); | 3002 __ ret(); |
3221 } | 3003 } |
3222 | 3004 |
3223 | |
3224 ASSEMBLER_TEST_RUN(TestAlignLarge, test) { | 3005 ASSEMBLER_TEST_RUN(TestAlignLarge, test) { |
3225 typedef int (*TestAlignLarge)(); | 3006 typedef int (*TestAlignLarge)(); |
3226 int res = reinterpret_cast<TestAlignLarge>(test->payload_start())(); | 3007 int res = reinterpret_cast<TestAlignLarge>(test->payload_start())(); |
3227 EXPECT_EQ(16, res); // 16 bytes emitted. | 3008 EXPECT_EQ(16, res); // 16 bytes emitted. |
3228 } | 3009 } |
3229 | 3010 |
3230 | |
3231 ASSEMBLER_TEST_GENERATE(TestAdds, assembler) { | 3011 ASSEMBLER_TEST_GENERATE(TestAdds, assembler) { |
3232 __ movq(RAX, Immediate(4)); | 3012 __ movq(RAX, Immediate(4)); |
3233 __ pushq(RAX); | 3013 __ pushq(RAX); |
3234 __ addq(Address(RSP, 0), Immediate(5)); | 3014 __ addq(Address(RSP, 0), Immediate(5)); |
3235 // TOS: 9 | 3015 // TOS: 9 |
3236 __ addq(Address(RSP, 0), Immediate(-2)); | 3016 __ addq(Address(RSP, 0), Immediate(-2)); |
3237 // TOS: 7 | 3017 // TOS: 7 |
3238 __ movq(RCX, Immediate(3)); | 3018 __ movq(RCX, Immediate(3)); |
3239 __ addq(Address(RSP, 0), RCX); | 3019 __ addq(Address(RSP, 0), RCX); |
3240 // TOS: 10 | 3020 // TOS: 10 |
3241 __ movq(RAX, Immediate(10)); | 3021 __ movq(RAX, Immediate(10)); |
3242 __ addq(RAX, Address(RSP, 0)); | 3022 __ addq(RAX, Address(RSP, 0)); |
3243 // RAX: 20 | 3023 // RAX: 20 |
3244 __ popq(RCX); | 3024 __ popq(RCX); |
3245 __ ret(); | 3025 __ ret(); |
3246 } | 3026 } |
3247 | 3027 |
3248 | |
3249 ASSEMBLER_TEST_RUN(TestAdds, test) { | 3028 ASSEMBLER_TEST_RUN(TestAdds, test) { |
3250 typedef int (*TestAdds)(); | 3029 typedef int (*TestAdds)(); |
3251 int res = reinterpret_cast<TestAdds>(test->entry())(); | 3030 int res = reinterpret_cast<TestAdds>(test->entry())(); |
3252 EXPECT_EQ(20, res); | 3031 EXPECT_EQ(20, res); |
3253 } | 3032 } |
3254 | 3033 |
3255 | |
3256 ASSEMBLER_TEST_GENERATE(TestNot, assembler) { | 3034 ASSEMBLER_TEST_GENERATE(TestNot, assembler) { |
3257 __ movq(RAX, Immediate(0xFFFFFFFF00000000)); | 3035 __ movq(RAX, Immediate(0xFFFFFFFF00000000)); |
3258 __ notq(RAX); | 3036 __ notq(RAX); |
3259 __ ret(); | 3037 __ ret(); |
3260 } | 3038 } |
3261 | 3039 |
3262 | |
3263 ASSEMBLER_TEST_RUN(TestNot, test) { | 3040 ASSEMBLER_TEST_RUN(TestNot, test) { |
3264 typedef int (*TestNot)(); | 3041 typedef int (*TestNot)(); |
3265 unsigned int res = reinterpret_cast<TestNot>(test->entry())(); | 3042 unsigned int res = reinterpret_cast<TestNot>(test->entry())(); |
3266 EXPECT_EQ(0xFFFFFFFF, res); | 3043 EXPECT_EQ(0xFFFFFFFF, res); |
3267 } | 3044 } |
3268 | 3045 |
3269 | |
3270 ASSEMBLER_TEST_GENERATE(TestNotInt32, assembler) { | 3046 ASSEMBLER_TEST_GENERATE(TestNotInt32, assembler) { |
3271 __ movq(RAX, Immediate(0x0)); | 3047 __ movq(RAX, Immediate(0x0)); |
3272 __ notl(RAX); | 3048 __ notl(RAX); |
3273 __ ret(); | 3049 __ ret(); |
3274 } | 3050 } |
3275 | 3051 |
3276 | |
3277 ASSEMBLER_TEST_RUN(TestNotInt32, test) { | 3052 ASSEMBLER_TEST_RUN(TestNotInt32, test) { |
3278 typedef int (*TestNot)(); | 3053 typedef int (*TestNot)(); |
3279 unsigned int res = reinterpret_cast<TestNot>(test->entry())(); | 3054 unsigned int res = reinterpret_cast<TestNot>(test->entry())(); |
3280 EXPECT_EQ(0xFFFFFFFF, res); | 3055 EXPECT_EQ(0xFFFFFFFF, res); |
3281 } | 3056 } |
3282 | 3057 |
3283 | |
3284 ASSEMBLER_TEST_GENERATE(XorpdZeroing, assembler) { | 3058 ASSEMBLER_TEST_GENERATE(XorpdZeroing, assembler) { |
3285 __ pushq(RAX); | 3059 __ pushq(RAX); |
3286 __ movsd(Address(RSP, 0), XMM0); | 3060 __ movsd(Address(RSP, 0), XMM0); |
3287 __ xorpd(XMM0, Address(RSP, 0)); | 3061 __ xorpd(XMM0, Address(RSP, 0)); |
3288 __ popq(RAX); | 3062 __ popq(RAX); |
3289 __ ret(); | 3063 __ ret(); |
3290 } | 3064 } |
3291 | 3065 |
3292 | |
3293 ASSEMBLER_TEST_RUN(XorpdZeroing, test) { | 3066 ASSEMBLER_TEST_RUN(XorpdZeroing, test) { |
3294 typedef double (*XorpdZeroingCode)(double d); | 3067 typedef double (*XorpdZeroingCode)(double d); |
3295 double res = reinterpret_cast<XorpdZeroingCode>(test->entry())(12.56e3); | 3068 double res = reinterpret_cast<XorpdZeroingCode>(test->entry())(12.56e3); |
3296 EXPECT_FLOAT_EQ(0.0, res, 0.0001); | 3069 EXPECT_FLOAT_EQ(0.0, res, 0.0001); |
3297 } | 3070 } |
3298 | 3071 |
3299 | |
3300 ASSEMBLER_TEST_GENERATE(XorpdZeroing2, assembler) { | 3072 ASSEMBLER_TEST_GENERATE(XorpdZeroing2, assembler) { |
3301 Label done; | 3073 Label done; |
3302 __ xorpd(XMM15, XMM15); | 3074 __ xorpd(XMM15, XMM15); |
3303 __ xorpd(XMM0, XMM0); | 3075 __ xorpd(XMM0, XMM0); |
3304 __ xorpd(XMM0, XMM15); | 3076 __ xorpd(XMM0, XMM15); |
3305 __ comisd(XMM0, XMM15); | 3077 __ comisd(XMM0, XMM15); |
3306 __ j(ZERO, &done); | 3078 __ j(ZERO, &done); |
3307 __ int3(); | 3079 __ int3(); |
3308 __ Bind(&done); | 3080 __ Bind(&done); |
3309 __ ret(); | 3081 __ ret(); |
3310 } | 3082 } |
3311 | 3083 |
3312 | |
3313 ASSEMBLER_TEST_RUN(XorpdZeroing2, test) { | 3084 ASSEMBLER_TEST_RUN(XorpdZeroing2, test) { |
3314 typedef double (*XorpdZeroing2Code)(double d); | 3085 typedef double (*XorpdZeroing2Code)(double d); |
3315 double res = reinterpret_cast<XorpdZeroing2Code>(test->entry())(12.56e3); | 3086 double res = reinterpret_cast<XorpdZeroing2Code>(test->entry())(12.56e3); |
3316 EXPECT_FLOAT_EQ(0.0, res, 0.0001); | 3087 EXPECT_FLOAT_EQ(0.0, res, 0.0001); |
3317 } | 3088 } |
3318 | 3089 |
3319 | |
3320 ASSEMBLER_TEST_GENERATE(Pxor, assembler) { | 3090 ASSEMBLER_TEST_GENERATE(Pxor, assembler) { |
3321 __ pxor(XMM0, XMM0); | 3091 __ pxor(XMM0, XMM0); |
3322 __ ret(); | 3092 __ ret(); |
3323 } | 3093 } |
3324 | 3094 |
3325 | |
3326 ASSEMBLER_TEST_RUN(Pxor, test) { | 3095 ASSEMBLER_TEST_RUN(Pxor, test) { |
3327 typedef double (*PxorCode)(double d); | 3096 typedef double (*PxorCode)(double d); |
3328 double res = reinterpret_cast<PxorCode>(test->entry())(12.3456e3); | 3097 double res = reinterpret_cast<PxorCode>(test->entry())(12.3456e3); |
3329 EXPECT_FLOAT_EQ(0.0, res, 0.0); | 3098 EXPECT_FLOAT_EQ(0.0, res, 0.0); |
3330 } | 3099 } |
3331 | 3100 |
3332 | |
3333 ASSEMBLER_TEST_GENERATE(SquareRootDouble, assembler) { | 3101 ASSEMBLER_TEST_GENERATE(SquareRootDouble, assembler) { |
3334 __ sqrtsd(XMM0, XMM0); | 3102 __ sqrtsd(XMM0, XMM0); |
3335 __ ret(); | 3103 __ ret(); |
3336 } | 3104 } |
3337 | 3105 |
3338 | |
3339 ASSEMBLER_TEST_RUN(SquareRootDouble, test) { | 3106 ASSEMBLER_TEST_RUN(SquareRootDouble, test) { |
3340 typedef double (*SquareRootDoubleCode)(double d); | 3107 typedef double (*SquareRootDoubleCode)(double d); |
3341 const double kDoubleConst = .7; | 3108 const double kDoubleConst = .7; |
3342 double res = | 3109 double res = |
3343 reinterpret_cast<SquareRootDoubleCode>(test->entry())(kDoubleConst); | 3110 reinterpret_cast<SquareRootDoubleCode>(test->entry())(kDoubleConst); |
3344 EXPECT_FLOAT_EQ(sqrt(kDoubleConst), res, 0.0001); | 3111 EXPECT_FLOAT_EQ(sqrt(kDoubleConst), res, 0.0001); |
3345 } | 3112 } |
3346 | 3113 |
3347 | |
3348 // Called from assembler_test.cc. | 3114 // Called from assembler_test.cc. |
3349 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { | 3115 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { |
3350 __ pushq(CODE_REG); | 3116 __ pushq(CODE_REG); |
3351 __ pushq(THR); | 3117 __ pushq(THR); |
3352 __ movq(THR, CallingConventions::kArg3Reg); | 3118 __ movq(THR, CallingConventions::kArg3Reg); |
3353 __ StoreIntoObject(CallingConventions::kArg2Reg, | 3119 __ StoreIntoObject(CallingConventions::kArg2Reg, |
3354 FieldAddress(CallingConventions::kArg2Reg, | 3120 FieldAddress(CallingConventions::kArg2Reg, |
3355 GrowableObjectArray::data_offset()), | 3121 GrowableObjectArray::data_offset()), |
3356 CallingConventions::kArg1Reg); | 3122 CallingConventions::kArg1Reg); |
3357 __ popq(THR); | 3123 __ popq(THR); |
3358 __ popq(CODE_REG); | 3124 __ popq(CODE_REG); |
3359 __ ret(); | 3125 __ ret(); |
3360 } | 3126 } |
3361 | 3127 |
3362 | |
3363 ASSEMBLER_TEST_GENERATE(DoubleFPUStackMoves, assembler) { | 3128 ASSEMBLER_TEST_GENERATE(DoubleFPUStackMoves, assembler) { |
3364 int64_t l = bit_cast<int64_t, double>(1024.67); | 3129 int64_t l = bit_cast<int64_t, double>(1024.67); |
3365 __ movq(RAX, Immediate(l)); | 3130 __ movq(RAX, Immediate(l)); |
3366 __ pushq(RAX); | 3131 __ pushq(RAX); |
3367 __ fldl(Address(RSP, 0)); | 3132 __ fldl(Address(RSP, 0)); |
3368 __ movq(Address(RSP, 0), Immediate(0)); | 3133 __ movq(Address(RSP, 0), Immediate(0)); |
3369 __ fstpl(Address(RSP, 0)); | 3134 __ fstpl(Address(RSP, 0)); |
3370 __ popq(RAX); | 3135 __ popq(RAX); |
3371 __ ret(); | 3136 __ ret(); |
3372 } | 3137 } |
3373 | 3138 |
3374 | |
3375 ASSEMBLER_TEST_RUN(DoubleFPUStackMoves, test) { | 3139 ASSEMBLER_TEST_RUN(DoubleFPUStackMoves, test) { |
3376 typedef int64_t (*DoubleFPUStackMovesCode)(); | 3140 typedef int64_t (*DoubleFPUStackMovesCode)(); |
3377 int64_t res = reinterpret_cast<DoubleFPUStackMovesCode>(test->entry())(); | 3141 int64_t res = reinterpret_cast<DoubleFPUStackMovesCode>(test->entry())(); |
3378 EXPECT_FLOAT_EQ(1024.67, (bit_cast<double, int64_t>(res)), 0.001); | 3142 EXPECT_FLOAT_EQ(1024.67, (bit_cast<double, int64_t>(res)), 0.001); |
3379 } | 3143 } |
3380 | 3144 |
3381 | |
3382 ASSEMBLER_TEST_GENERATE(Sine, assembler) { | 3145 ASSEMBLER_TEST_GENERATE(Sine, assembler) { |
3383 __ pushq(RAX); | 3146 __ pushq(RAX); |
3384 __ movsd(Address(RSP, 0), XMM0); | 3147 __ movsd(Address(RSP, 0), XMM0); |
3385 __ fldl(Address(RSP, 0)); | 3148 __ fldl(Address(RSP, 0)); |
3386 __ fsin(); | 3149 __ fsin(); |
3387 __ fstpl(Address(RSP, 0)); | 3150 __ fstpl(Address(RSP, 0)); |
3388 __ movsd(XMM0, Address(RSP, 0)); | 3151 __ movsd(XMM0, Address(RSP, 0)); |
3389 __ popq(RAX); | 3152 __ popq(RAX); |
3390 __ ret(); | 3153 __ ret(); |
3391 } | 3154 } |
3392 | 3155 |
3393 | |
3394 ASSEMBLER_TEST_RUN(Sine, test) { | 3156 ASSEMBLER_TEST_RUN(Sine, test) { |
3395 typedef double (*SineCode)(double d); | 3157 typedef double (*SineCode)(double d); |
3396 const double kDoubleConst = 0.7; | 3158 const double kDoubleConst = 0.7; |
3397 double res = reinterpret_cast<SineCode>(test->entry())(kDoubleConst); | 3159 double res = reinterpret_cast<SineCode>(test->entry())(kDoubleConst); |
3398 EXPECT_FLOAT_EQ(sin(kDoubleConst), res, 0.0001); | 3160 EXPECT_FLOAT_EQ(sin(kDoubleConst), res, 0.0001); |
3399 } | 3161 } |
3400 | 3162 |
3401 | |
3402 ASSEMBLER_TEST_GENERATE(Cosine, assembler) { | 3163 ASSEMBLER_TEST_GENERATE(Cosine, assembler) { |
3403 __ pushq(RAX); | 3164 __ pushq(RAX); |
3404 __ movsd(Address(RSP, 0), XMM0); | 3165 __ movsd(Address(RSP, 0), XMM0); |
3405 __ fldl(Address(RSP, 0)); | 3166 __ fldl(Address(RSP, 0)); |
3406 __ fcos(); | 3167 __ fcos(); |
3407 __ fstpl(Address(RSP, 0)); | 3168 __ fstpl(Address(RSP, 0)); |
3408 __ movsd(XMM0, Address(RSP, 0)); | 3169 __ movsd(XMM0, Address(RSP, 0)); |
3409 __ popq(RAX); | 3170 __ popq(RAX); |
3410 __ ret(); | 3171 __ ret(); |
3411 } | 3172 } |
3412 | 3173 |
3413 | |
3414 ASSEMBLER_TEST_RUN(Cosine, test) { | 3174 ASSEMBLER_TEST_RUN(Cosine, test) { |
3415 typedef double (*CosineCode)(double f); | 3175 typedef double (*CosineCode)(double f); |
3416 const double kDoubleConst = 0.7; | 3176 const double kDoubleConst = 0.7; |
3417 double res = reinterpret_cast<CosineCode>(test->entry())(kDoubleConst); | 3177 double res = reinterpret_cast<CosineCode>(test->entry())(kDoubleConst); |
3418 EXPECT_FLOAT_EQ(cos(kDoubleConst), res, 0.0001); | 3178 EXPECT_FLOAT_EQ(cos(kDoubleConst), res, 0.0001); |
3419 } | 3179 } |
3420 | 3180 |
3421 | |
3422 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion, assembler) { | 3181 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion, assembler) { |
3423 __ movq(RDX, Immediate(6)); | 3182 __ movq(RDX, Immediate(6)); |
3424 __ cvtsi2sdq(XMM0, RDX); | 3183 __ cvtsi2sdq(XMM0, RDX); |
3425 __ ret(); | 3184 __ ret(); |
3426 } | 3185 } |
3427 | 3186 |
3428 | |
3429 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { | 3187 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { |
3430 typedef double (*IntToDoubleConversionCode)(); | 3188 typedef double (*IntToDoubleConversionCode)(); |
3431 double res = reinterpret_cast<IntToDoubleConversionCode>(test->entry())(); | 3189 double res = reinterpret_cast<IntToDoubleConversionCode>(test->entry())(); |
3432 EXPECT_FLOAT_EQ(6.0, res, 0.001); | 3190 EXPECT_FLOAT_EQ(6.0, res, 0.001); |
3433 } | 3191 } |
3434 | 3192 |
3435 | |
3436 ASSEMBLER_TEST_GENERATE(DoubleToDoubleTrunc, assembler) { | 3193 ASSEMBLER_TEST_GENERATE(DoubleToDoubleTrunc, assembler) { |
3437 __ roundsd(XMM0, XMM0, Assembler::kRoundToZero); | 3194 __ roundsd(XMM0, XMM0, Assembler::kRoundToZero); |
3438 __ ret(); | 3195 __ ret(); |
3439 } | 3196 } |
3440 | 3197 |
3441 | |
3442 ASSEMBLER_TEST_RUN(DoubleToDoubleTrunc, test) { | 3198 ASSEMBLER_TEST_RUN(DoubleToDoubleTrunc, test) { |
3443 typedef double (*DoubleToDoubleTruncCode)(double d); | 3199 typedef double (*DoubleToDoubleTruncCode)(double d); |
3444 double res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(12.3); | 3200 double res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(12.3); |
3445 EXPECT_EQ(12.0, res); | 3201 EXPECT_EQ(12.0, res); |
3446 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(12.8); | 3202 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(12.8); |
3447 EXPECT_EQ(12.0, res); | 3203 EXPECT_EQ(12.0, res); |
3448 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(-12.3); | 3204 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(-12.3); |
3449 EXPECT_EQ(-12.0, res); | 3205 EXPECT_EQ(-12.0, res); |
3450 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(-12.8); | 3206 res = reinterpret_cast<DoubleToDoubleTruncCode>(test->entry())(-12.8); |
3451 EXPECT_EQ(-12.0, res); | 3207 EXPECT_EQ(-12.0, res); |
3452 } | 3208 } |
3453 | 3209 |
3454 | |
3455 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) { | 3210 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) { |
3456 EnterTestFrame(assembler); | 3211 EnterTestFrame(assembler); |
3457 #if defined(HOST_OS_WINDOWS) | 3212 #if defined(HOST_OS_WINDOWS) |
3458 // First argument is code object, second argument is thread. MSVC passes | 3213 // First argument is code object, second argument is thread. MSVC passes |
3459 // third argument in XMM2. | 3214 // third argument in XMM2. |
3460 __ DoubleAbs(XMM2); | 3215 __ DoubleAbs(XMM2); |
3461 __ movaps(XMM0, XMM2); | 3216 __ movaps(XMM0, XMM2); |
3462 #else | 3217 #else |
3463 // SysV ABI allocates integral and double registers for arguments | 3218 // SysV ABI allocates integral and double registers for arguments |
3464 // independently. | 3219 // independently. |
3465 __ DoubleAbs(XMM0); | 3220 __ DoubleAbs(XMM0); |
3466 #endif | 3221 #endif |
3467 LeaveTestFrame(assembler); | 3222 LeaveTestFrame(assembler); |
3468 __ ret(); | 3223 __ ret(); |
3469 } | 3224 } |
3470 | 3225 |
3471 | |
3472 ASSEMBLER_TEST_RUN(DoubleAbs, test) { | 3226 ASSEMBLER_TEST_RUN(DoubleAbs, test) { |
3473 double val = -12.45; | 3227 double val = -12.45; |
3474 double res = test->InvokeWithCodeAndThread<double, double>(val); | 3228 double res = test->InvokeWithCodeAndThread<double, double>(val); |
3475 EXPECT_FLOAT_EQ(-val, res, 0.001); | 3229 EXPECT_FLOAT_EQ(-val, res, 0.001); |
3476 val = 12.45; | 3230 val = 12.45; |
3477 res = test->InvokeWithCodeAndThread<double, double>(val); | 3231 res = test->InvokeWithCodeAndThread<double, double>(val); |
3478 EXPECT_FLOAT_EQ(val, res, 0.001); | 3232 EXPECT_FLOAT_EQ(val, res, 0.001); |
3479 } | 3233 } |
3480 | 3234 |
3481 | |
3482 ASSEMBLER_TEST_GENERATE(ExtractSignBits, assembler) { | 3235 ASSEMBLER_TEST_GENERATE(ExtractSignBits, assembler) { |
3483 __ movmskpd(RAX, XMM0); | 3236 __ movmskpd(RAX, XMM0); |
3484 __ andq(RAX, Immediate(0x1)); | 3237 __ andq(RAX, Immediate(0x1)); |
3485 __ ret(); | 3238 __ ret(); |
3486 } | 3239 } |
3487 | 3240 |
3488 | |
3489 ASSEMBLER_TEST_RUN(ExtractSignBits, test) { | 3241 ASSEMBLER_TEST_RUN(ExtractSignBits, test) { |
3490 typedef int (*ExtractSignBits)(double d); | 3242 typedef int (*ExtractSignBits)(double d); |
3491 int res = reinterpret_cast<ExtractSignBits>(test->entry())(1.0); | 3243 int res = reinterpret_cast<ExtractSignBits>(test->entry())(1.0); |
3492 EXPECT_EQ(0, res); | 3244 EXPECT_EQ(0, res); |
3493 res = reinterpret_cast<ExtractSignBits>(test->entry())(-1.0); | 3245 res = reinterpret_cast<ExtractSignBits>(test->entry())(-1.0); |
3494 EXPECT_EQ(1, res); | 3246 EXPECT_EQ(1, res); |
3495 res = reinterpret_cast<ExtractSignBits>(test->entry())(-0.0); | 3247 res = reinterpret_cast<ExtractSignBits>(test->entry())(-0.0); |
3496 EXPECT_EQ(1, res); | 3248 EXPECT_EQ(1, res); |
3497 } | 3249 } |
3498 | 3250 |
3499 | |
3500 ASSEMBLER_TEST_GENERATE(TestSetCC, assembler) { | 3251 ASSEMBLER_TEST_GENERATE(TestSetCC, assembler) { |
3501 __ movq(RAX, Immediate(0xFFFFFFFF)); | 3252 __ movq(RAX, Immediate(0xFFFFFFFF)); |
3502 __ cmpq(RAX, RAX); | 3253 __ cmpq(RAX, RAX); |
3503 __ setcc(NOT_EQUAL, AL); | 3254 __ setcc(NOT_EQUAL, AL); |
3504 __ ret(); | 3255 __ ret(); |
3505 } | 3256 } |
3506 | 3257 |
3507 | |
3508 ASSEMBLER_TEST_RUN(TestSetCC, test) { | 3258 ASSEMBLER_TEST_RUN(TestSetCC, test) { |
3509 typedef uword (*TestSetCC)(); | 3259 typedef uword (*TestSetCC)(); |
3510 uword res = reinterpret_cast<TestSetCC>(test->entry())(); | 3260 uword res = reinterpret_cast<TestSetCC>(test->entry())(); |
3511 EXPECT_EQ(0xFFFFFF00, res); | 3261 EXPECT_EQ(0xFFFFFF00, res); |
3512 } | 3262 } |
3513 | 3263 |
3514 | |
3515 ASSEMBLER_TEST_GENERATE(TestRepMovsBytes, assembler) { | 3264 ASSEMBLER_TEST_GENERATE(TestRepMovsBytes, assembler) { |
3516 __ pushq(RSI); | 3265 __ pushq(RSI); |
3517 __ pushq(RDI); | 3266 __ pushq(RDI); |
3518 __ pushq(CallingConventions::kArg1Reg); // from. | 3267 __ pushq(CallingConventions::kArg1Reg); // from. |
3519 __ pushq(CallingConventions::kArg2Reg); // to. | 3268 __ pushq(CallingConventions::kArg2Reg); // to. |
3520 __ pushq(CallingConventions::kArg3Reg); // count. | 3269 __ pushq(CallingConventions::kArg3Reg); // count. |
3521 __ movq(RSI, Address(RSP, 2 * kWordSize)); // from. | 3270 __ movq(RSI, Address(RSP, 2 * kWordSize)); // from. |
3522 __ movq(RDI, Address(RSP, 1 * kWordSize)); // to. | 3271 __ movq(RDI, Address(RSP, 1 * kWordSize)); // to. |
3523 __ movq(RCX, Address(RSP, 0 * kWordSize)); // count. | 3272 __ movq(RCX, Address(RSP, 0 * kWordSize)); // count. |
3524 __ rep_movsb(); | 3273 __ rep_movsb(); |
3525 // Remove saved arguments. | 3274 // Remove saved arguments. |
3526 __ popq(RAX); | 3275 __ popq(RAX); |
3527 __ popq(RAX); | 3276 __ popq(RAX); |
3528 __ popq(RAX); | 3277 __ popq(RAX); |
3529 __ popq(RDI); | 3278 __ popq(RDI); |
3530 __ popq(RSI); | 3279 __ popq(RSI); |
3531 __ ret(); | 3280 __ ret(); |
3532 } | 3281 } |
3533 | 3282 |
3534 | |
3535 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) { | 3283 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) { |
3536 const char* from = "0123456789"; | 3284 const char* from = "0123456789"; |
3537 const char* to = new char[10]; | 3285 const char* to = new char[10]; |
3538 typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count); | 3286 typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count); |
3539 reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10); | 3287 reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10); |
3540 EXPECT_EQ(to[0], '0'); | 3288 EXPECT_EQ(to[0], '0'); |
3541 for (int i = 0; i < 10; i++) { | 3289 for (int i = 0; i < 10; i++) { |
3542 EXPECT_EQ(from[i], to[i]); | 3290 EXPECT_EQ(from[i], to[i]); |
3543 } | 3291 } |
3544 delete[] to; | 3292 delete[] to; |
3545 } | 3293 } |
3546 | 3294 |
3547 | |
3548 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) { | 3295 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) { |
3549 __ cmpq(CallingConventions::kArg1Reg, CallingConventions::kArg2Reg); | 3296 __ cmpq(CallingConventions::kArg1Reg, CallingConventions::kArg2Reg); |
3550 __ movq(RDX, Immediate(1)); // Greater equal. | 3297 __ movq(RDX, Immediate(1)); // Greater equal. |
3551 __ movq(RCX, Immediate(-1)); // Less | 3298 __ movq(RCX, Immediate(-1)); // Less |
3552 __ cmovlessq(RAX, RCX); | 3299 __ cmovlessq(RAX, RCX); |
3553 __ cmovgeq(RAX, RDX); | 3300 __ cmovgeq(RAX, RDX); |
3554 __ ret(); | 3301 __ ret(); |
3555 } | 3302 } |
3556 | 3303 |
3557 | |
3558 ASSEMBLER_TEST_RUN(ConditionalMovesCompare, test) { | 3304 ASSEMBLER_TEST_RUN(ConditionalMovesCompare, test) { |
3559 typedef int (*ConditionalMovesCompareCode)(int i, int j); | 3305 typedef int (*ConditionalMovesCompareCode)(int i, int j); |
3560 int res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(10, 5); | 3306 int res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(10, 5); |
3561 EXPECT_EQ(1, res); // Greater equal. | 3307 EXPECT_EQ(1, res); // Greater equal. |
3562 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(5, 5); | 3308 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(5, 5); |
3563 EXPECT_EQ(1, res); // Greater equal. | 3309 EXPECT_EQ(1, res); // Greater equal. |
3564 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(2, 5); | 3310 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(2, 5); |
3565 EXPECT_EQ(-1, res); // Less. | 3311 EXPECT_EQ(-1, res); // Less. |
3566 } | 3312 } |
3567 | 3313 |
3568 | |
3569 ASSEMBLER_TEST_GENERATE(BitTest, assembler) { | 3314 ASSEMBLER_TEST_GENERATE(BitTest, assembler) { |
3570 __ movq(RAX, Immediate(4)); | 3315 __ movq(RAX, Immediate(4)); |
3571 __ movq(R11, Immediate(2)); | 3316 __ movq(R11, Immediate(2)); |
3572 __ btq(RAX, R11); | 3317 __ btq(RAX, R11); |
3573 Label ok; | 3318 Label ok; |
3574 __ j(CARRY, &ok); | 3319 __ j(CARRY, &ok); |
3575 __ int3(); | 3320 __ int3(); |
3576 __ Bind(&ok); | 3321 __ Bind(&ok); |
3577 __ movq(RAX, Immediate(1)); | 3322 __ movq(RAX, Immediate(1)); |
3578 __ ret(); | 3323 __ ret(); |
3579 } | 3324 } |
3580 | 3325 |
3581 | |
3582 ASSEMBLER_TEST_RUN(BitTest, test) { | 3326 ASSEMBLER_TEST_RUN(BitTest, test) { |
3583 typedef int (*BitTest)(); | 3327 typedef int (*BitTest)(); |
3584 EXPECT_EQ(1, reinterpret_cast<BitTest>(test->entry())()); | 3328 EXPECT_EQ(1, reinterpret_cast<BitTest>(test->entry())()); |
3585 } | 3329 } |
3586 | 3330 |
3587 | |
3588 // Return 1 if equal, 0 if not equal. | 3331 // Return 1 if equal, 0 if not equal. |
3589 ASSEMBLER_TEST_GENERATE(ConditionalMovesEqual, assembler) { | 3332 ASSEMBLER_TEST_GENERATE(ConditionalMovesEqual, assembler) { |
3590 __ movq(RDX, CallingConventions::kArg1Reg); | 3333 __ movq(RDX, CallingConventions::kArg1Reg); |
3591 __ xorq(RAX, RAX); | 3334 __ xorq(RAX, RAX); |
3592 __ movq(RCX, Immediate(1)); | 3335 __ movq(RCX, Immediate(1)); |
3593 __ cmpq(RDX, Immediate(785)); | 3336 __ cmpq(RDX, Immediate(785)); |
3594 __ cmoveq(RAX, RCX); | 3337 __ cmoveq(RAX, RCX); |
3595 __ ret(); | 3338 __ ret(); |
3596 } | 3339 } |
3597 | 3340 |
3598 | |
3599 ASSEMBLER_TEST_RUN(ConditionalMovesEqual, test) { | 3341 ASSEMBLER_TEST_RUN(ConditionalMovesEqual, test) { |
3600 typedef int (*ConditionalMovesEqualCode)(int i); | 3342 typedef int (*ConditionalMovesEqualCode)(int i); |
3601 int res = reinterpret_cast<ConditionalMovesEqualCode>(test->entry())(785); | 3343 int res = reinterpret_cast<ConditionalMovesEqualCode>(test->entry())(785); |
3602 EXPECT_EQ(1, res); | 3344 EXPECT_EQ(1, res); |
3603 res = reinterpret_cast<ConditionalMovesEqualCode>(test->entry())(-12); | 3345 res = reinterpret_cast<ConditionalMovesEqualCode>(test->entry())(-12); |
3604 EXPECT_EQ(0, res); | 3346 EXPECT_EQ(0, res); |
3605 } | 3347 } |
3606 | 3348 |
3607 | |
3608 // Return 1 if overflow, 0 if no overflow. | 3349 // Return 1 if overflow, 0 if no overflow. |
3609 ASSEMBLER_TEST_GENERATE(ConditionalMovesNoOverflow, assembler) { | 3350 ASSEMBLER_TEST_GENERATE(ConditionalMovesNoOverflow, assembler) { |
3610 __ movq(RDX, CallingConventions::kArg1Reg); | 3351 __ movq(RDX, CallingConventions::kArg1Reg); |
3611 __ addq(RDX, CallingConventions::kArg2Reg); | 3352 __ addq(RDX, CallingConventions::kArg2Reg); |
3612 __ movq(RAX, Immediate(1)); | 3353 __ movq(RAX, Immediate(1)); |
3613 __ movq(RCX, Immediate(0)); | 3354 __ movq(RCX, Immediate(0)); |
3614 __ cmovnoq(RAX, RCX); | 3355 __ cmovnoq(RAX, RCX); |
3615 __ ret(); | 3356 __ ret(); |
3616 } | 3357 } |
3617 | 3358 |
3618 | |
3619 ASSEMBLER_TEST_RUN(ConditionalMovesNoOverflow, test) { | 3359 ASSEMBLER_TEST_RUN(ConditionalMovesNoOverflow, test) { |
3620 typedef int (*ConditionalMovesNoOverflowCode)(int64_t i, int64_t j); | 3360 typedef int (*ConditionalMovesNoOverflowCode)(int64_t i, int64_t j); |
3621 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())( | 3361 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())( |
3622 0x7fffffffffffffff, 2); | 3362 0x7fffffffffffffff, 2); |
3623 EXPECT_EQ(1, res); | 3363 EXPECT_EQ(1, res); |
3624 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); | 3364 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); |
3625 EXPECT_EQ(0, res); | 3365 EXPECT_EQ(0, res); |
3626 } | 3366 } |
3627 | 3367 |
3628 } // namespace dart | 3368 } // namespace dart |
3629 | 3369 |
3630 #endif // defined TARGET_ARCH_X64 | 3370 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |