| 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" |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 __ ret(); | 379 __ ret(); |
| 380 } | 380 } |
| 381 | 381 |
| 382 | 382 |
| 383 ASSEMBLER_TEST_RUN(SignedMultiply, test) { | 383 ASSEMBLER_TEST_RUN(SignedMultiply, test) { |
| 384 typedef int (*SignedMultiply)(); | 384 typedef int (*SignedMultiply)(); |
| 385 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply>(test->entry())()); | 385 EXPECT_EQ(8000, reinterpret_cast<SignedMultiply>(test->entry())()); |
| 386 } | 386 } |
| 387 | 387 |
| 388 | 388 |
| 389 ASSEMBLER_TEST_GENERATE(UnsignedMultiply, assembler) { |
| 390 __ movl(RAX, Immediate(-1)); // RAX = 0xFFFFFFFF |
| 391 __ movl(RCX, Immediate(16)); // RCX = 0x10 |
| 392 __ mull(RCX); // RDX:RAX = RAX * RCX = 0x0FFFFFFFF0 |
| 393 __ movq(RAX, RDX); // Return high32(0x0FFFFFFFF0) == 0x0F |
| 394 __ ret(); |
| 395 } |
| 396 |
| 397 |
| 398 ASSEMBLER_TEST_RUN(UnsignedMultiply, test) { |
| 399 typedef int (*UnsignedMultiply)(); |
| 400 EXPECT_EQ(15, reinterpret_cast<UnsignedMultiply>(test->entry())()); |
| 401 } |
| 402 |
| 403 |
| 389 ASSEMBLER_TEST_GENERATE(SignedMultiply64, assembler) { | 404 ASSEMBLER_TEST_GENERATE(SignedMultiply64, assembler) { |
| 390 __ pushq(R15); // Callee saved. | 405 __ pushq(R15); // Callee saved. |
| 391 __ movq(RAX, Immediate(2)); | 406 __ movq(RAX, Immediate(2)); |
| 392 __ movq(RCX, Immediate(4)); | 407 __ movq(RCX, Immediate(4)); |
| 393 __ imulq(RAX, RCX); | 408 __ imulq(RAX, RCX); |
| 394 | 409 |
| 395 __ movq(R8, Immediate(2)); | 410 __ movq(R8, Immediate(2)); |
| 396 __ movq(R9, Immediate(4)); | 411 __ movq(R9, Immediate(4)); |
| 397 __ pushq(R9); | 412 __ pushq(R9); |
| 398 __ imulq(R8, Address(RSP, 0)); | 413 __ imulq(R8, Address(RSP, 0)); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 __ ret(); | 516 __ ret(); |
| 502 } | 517 } |
| 503 | 518 |
| 504 | 519 |
| 505 ASSEMBLER_TEST_RUN(SignedDivide, test) { | 520 ASSEMBLER_TEST_RUN(SignedDivide, test) { |
| 506 typedef int32_t (*SignedDivide)(); | 521 typedef int32_t (*SignedDivide)(); |
| 507 EXPECT_EQ(-87 / 42, reinterpret_cast<SignedDivide>(test->entry())()); | 522 EXPECT_EQ(-87 / 42, reinterpret_cast<SignedDivide>(test->entry())()); |
| 508 } | 523 } |
| 509 | 524 |
| 510 | 525 |
| 526 ASSEMBLER_TEST_GENERATE(UnsignedDivide, assembler) { |
| 527 const int32_t low = 0; |
| 528 const int32_t high = 0xf0000000; |
| 529 const int32_t divisor = 0xffffffff; |
| 530 __ movl(RAX, Immediate(low)); |
| 531 __ movl(RDX, Immediate(high)); |
| 532 __ movl(RCX, Immediate(divisor)); |
| 533 __ divl(RCX); // RAX = RDX:RAX / RCX = |
| 534 // = 0xf000000000000000 / 0xffffffff = 0xf0000000 |
| 535 __ ret(); |
| 536 } |
| 537 |
| 538 |
| 539 ASSEMBLER_TEST_RUN(UnsignedDivide, test) { |
| 540 typedef uint32_t (*UnsignedDivide)(); |
| 541 EXPECT_EQ(0xf0000000, reinterpret_cast<UnsignedDivide>(test->entry())()); |
| 542 } |
| 543 |
| 544 |
| 511 ASSEMBLER_TEST_GENERATE(SignedDivideLong, assembler) { | 545 ASSEMBLER_TEST_GENERATE(SignedDivideLong, assembler) { |
| 512 __ movq(RAX, Immediate(kLargeConstant)); | 546 __ movq(RAX, Immediate(kLargeConstant)); |
| 513 __ movq(RDX, Immediate(123)); | 547 __ movq(RDX, Immediate(123)); |
| 514 __ cqo(); // Clear RDX. | 548 __ cqo(); // Clear RDX. |
| 515 __ movq(RCX, Immediate(42)); | 549 __ movq(RCX, Immediate(42)); |
| 516 __ idivq(RCX); | 550 __ idivq(RCX); |
| 517 __ ret(); | 551 __ ret(); |
| 518 } | 552 } |
| 519 | 553 |
| 520 | 554 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 __ ret(); | 676 __ ret(); |
| 643 } | 677 } |
| 644 | 678 |
| 645 | 679 |
| 646 ASSEMBLER_TEST_RUN(MoveWordRex, test) { | 680 ASSEMBLER_TEST_RUN(MoveWordRex, test) { |
| 647 typedef int (*MoveWordRex)(); | 681 typedef int (*MoveWordRex)(); |
| 648 EXPECT_EQ(0xffff, reinterpret_cast<MoveWordRex>(test->entry())()); | 682 EXPECT_EQ(0xffff, reinterpret_cast<MoveWordRex>(test->entry())()); |
| 649 } | 683 } |
| 650 | 684 |
| 651 | 685 |
| 686 ASSEMBLER_TEST_GENERATE(LongAddReg, assembler) { |
| 687 __ pushq(CallingConventions::kArg2Reg); |
| 688 __ pushq(CallingConventions::kArg1Reg); |
| 689 __ movl(RAX, Address(RSP, 0)); // left low. |
| 690 __ movl(RDX, Address(RSP, 4)); // left high. |
| 691 __ movl(RCX, Address(RSP, 8)); // right low. |
| 692 __ movl(RBX, Address(RSP, 12)); // right high |
| 693 __ addl(RAX, RCX); |
| 694 __ adcl(RDX, RBX); |
| 695 // Result is in RAX/RDX. |
| 696 __ movl(Address(RSP, 0), RAX); // result low. |
| 697 __ movl(Address(RSP, 4), RDX); // result high. |
| 698 __ popq(RAX); |
| 699 __ popq(RDX); |
| 700 __ ret(); |
| 701 } |
| 702 |
| 703 |
| 704 ASSEMBLER_TEST_RUN(LongAddReg, test) { |
| 705 typedef int64_t (*LongAddRegCode)(int64_t a, int64_t b); |
| 706 int64_t a = 12; |
| 707 int64_t b = 14; |
| 708 int64_t res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); |
| 709 EXPECT_EQ((a + b), res); |
| 710 a = 2147483647; |
| 711 b = 600000; |
| 712 res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); |
| 713 EXPECT_EQ((a + b), res); |
| 714 } |
| 715 |
| 716 |
| 717 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { |
| 718 __ pushq(CallingConventions::kArg2Reg); |
| 719 __ pushq(CallingConventions::kArg1Reg); |
| 720 __ movl(RAX, Address(RSP, 0)); // left low. |
| 721 __ movl(RDX, Address(RSP, 4)); // left high. |
| 722 __ addl(RAX, Address(RSP, 8)); // low. |
| 723 __ adcl(RDX, Address(RSP, 12)); // high. |
| 724 // Result is in RAX/RDX. |
| 725 __ movl(Address(RSP, 0), RAX); // result low. |
| 726 __ movl(Address(RSP, 4), RDX); // result high. |
| 727 __ popq(RAX); |
| 728 __ popq(RDX); |
| 729 __ ret(); |
| 730 } |
| 731 |
| 732 |
| 733 ASSEMBLER_TEST_RUN(LongAddAddress, test) { |
| 734 typedef int64_t (*LongAddAddressCode)(int64_t a, int64_t b); |
| 735 int64_t a = 12; |
| 736 int64_t b = 14; |
| 737 int64_t res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); |
| 738 EXPECT_EQ((a + b), res); |
| 739 a = 2147483647; |
| 740 b = 600000; |
| 741 res = reinterpret_cast<LongAddAddressCode>(test->entry())(a, b); |
| 742 EXPECT_EQ((a + b), res); |
| 743 } |
| 744 |
| 745 |
| 746 ASSEMBLER_TEST_GENERATE(LongSubReg, assembler) { |
| 747 __ pushq(CallingConventions::kArg2Reg); |
| 748 __ pushq(CallingConventions::kArg1Reg); |
| 749 __ movl(RAX, Address(RSP, 0)); // left low. |
| 750 __ movl(RDX, Address(RSP, 4)); // left high. |
| 751 __ movl(RCX, Address(RSP, 8)); // right low. |
| 752 __ movl(RBX, Address(RSP, 12)); // right high |
| 753 __ subl(RAX, RCX); |
| 754 __ sbbl(RDX, RBX); |
| 755 // Result is in RAX/RDX. |
| 756 __ movl(Address(RSP, 0), RAX); // result low. |
| 757 __ movl(Address(RSP, 4), RDX); // result high. |
| 758 __ popq(RAX); |
| 759 __ popq(RDX); |
| 760 __ ret(); |
| 761 } |
| 762 |
| 763 |
| 764 ASSEMBLER_TEST_RUN(LongSubReg, test) { |
| 765 typedef int64_t (*LongSubRegCode)(int64_t a, int64_t b); |
| 766 int64_t a = 12; |
| 767 int64_t b = 14; |
| 768 int64_t res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); |
| 769 EXPECT_EQ((a - b), res); |
| 770 a = 600000; |
| 771 b = 2147483647; |
| 772 res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); |
| 773 EXPECT_EQ((a - b), res); |
| 774 } |
| 775 |
| 776 |
| 777 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { |
| 778 __ pushq(CallingConventions::kArg2Reg); |
| 779 __ pushq(CallingConventions::kArg1Reg); |
| 780 __ movl(RAX, Address(RSP, 0)); // left low. |
| 781 __ movl(RDX, Address(RSP, 4)); // left high. |
| 782 __ subl(RAX, Address(RSP, 8)); // low. |
| 783 __ sbbl(RDX, Address(RSP, 12)); // high. |
| 784 // Result is in RAX/RDX. |
| 785 __ movl(Address(RSP, 0), RAX); // result low. |
| 786 __ movl(Address(RSP, 4), RDX); // result high. |
| 787 __ popq(RAX); |
| 788 __ popq(RDX); |
| 789 __ ret(); |
| 790 } |
| 791 |
| 792 |
| 793 ASSEMBLER_TEST_RUN(LongSubAddress, test) { |
| 794 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); |
| 795 int64_t a = 12; |
| 796 int64_t b = 14; |
| 797 int64_t res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); |
| 798 EXPECT_EQ((a - b), res); |
| 799 a = 600000; |
| 800 b = 2147483647; |
| 801 res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); |
| 802 EXPECT_EQ((a - b), res); |
| 803 } |
| 804 |
| 805 |
| 652 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { | 806 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { |
| 653 __ movl(RCX, Immediate(42)); | 807 __ movl(RCX, Immediate(42)); |
| 654 __ xorl(RCX, RCX); | 808 __ xorl(RCX, RCX); |
| 655 __ orl(RCX, Immediate(256)); | 809 __ orl(RCX, Immediate(256)); |
| 656 __ movl(RAX, Immediate(4)); | 810 __ movl(RAX, Immediate(4)); |
| 657 __ orl(RCX, RAX); | 811 __ orl(RCX, RAX); |
| 658 __ movl(RAX, Immediate(0xfff0)); | 812 __ movl(RAX, Immediate(0xfff0)); |
| 659 __ andl(RCX, RAX); | 813 __ andl(RCX, RAX); |
| 660 __ movl(RAX, Immediate(1)); | 814 __ movl(RAX, Immediate(1)); |
| 661 __ orl(RCX, RAX); | 815 __ orl(RCX, RAX); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 __ movl(RCX, Immediate(3)); | 1052 __ movl(RCX, Immediate(3)); |
| 899 __ shlq(RAX, Immediate(31)); | 1053 __ shlq(RAX, Immediate(31)); |
| 900 __ sarl(RAX, RCX); | 1054 __ sarl(RAX, RCX); |
| 901 __ cmpl(RAX, Immediate(0xfffffffff0000000)); | 1055 __ cmpl(RAX, Immediate(0xfffffffff0000000)); |
| 902 __ j(EQUAL, &donetest13a); | 1056 __ j(EQUAL, &donetest13a); |
| 903 // Be sure to skip this crashing code. | 1057 // Be sure to skip this crashing code. |
| 904 __ movl(RAX, Immediate(0)); | 1058 __ movl(RAX, Immediate(0)); |
| 905 __ movl(Address(RAX, 0), RAX); | 1059 __ movl(Address(RAX, 0), RAX); |
| 906 __ Bind(&donetest13a); | 1060 __ Bind(&donetest13a); |
| 907 | 1061 |
| 1062 Label donetest15a; |
| 1063 const int32_t left = 0xff000000; |
| 1064 const int32_t right = 0xffffffff; |
| 1065 const int32_t shifted = 0xf0000003; |
| 1066 __ movl(RDX, Immediate(left)); |
| 1067 __ movl(RAX, Immediate(right)); |
| 1068 __ movl(RCX, Immediate(2)); |
| 1069 __ shll(RDX, RCX); // RDX = 0xff000000 << 2 == 0xfc000000 |
| 1070 __ shldl(RDX, RAX, Immediate(2)); // RDX = high32(0xfc000000:0xffffffff << 2) |
| 1071 // = 0xf0000003 |
| 1072 __ cmpl(RDX, Immediate(shifted)); |
| 1073 __ j(EQUAL, &donetest15a); |
| 1074 __ int3(); |
| 1075 __ Bind(&donetest15a); |
| 1076 |
| 908 __ movl(RAX, Immediate(0)); | 1077 __ movl(RAX, Immediate(0)); |
| 909 __ ret(); | 1078 __ ret(); |
| 910 } | 1079 } |
| 911 | 1080 |
| 912 | 1081 |
| 913 ASSEMBLER_TEST_RUN(LogicalOps, test) { | 1082 ASSEMBLER_TEST_RUN(LogicalOps, test) { |
| 914 typedef int (*LogicalOpsCode)(); | 1083 typedef int (*LogicalOpsCode)(); |
| 915 EXPECT_EQ(0, reinterpret_cast<LogicalOpsCode>(test->entry())()); | 1084 EXPECT_EQ(0, reinterpret_cast<LogicalOpsCode>(test->entry())()); |
| 916 } | 1085 } |
| 917 | 1086 |
| (...skipping 2108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3026 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>( | 3195 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>( |
| 3027 test->entry())(0x7fffffffffffffff, 2); | 3196 test->entry())(0x7fffffffffffffff, 2); |
| 3028 EXPECT_EQ(1, res); | 3197 EXPECT_EQ(1, res); |
| 3029 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); | 3198 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); |
| 3030 EXPECT_EQ(0, res); | 3199 EXPECT_EQ(0, res); |
| 3031 } | 3200 } |
| 3032 | 3201 |
| 3033 } // namespace dart | 3202 } // namespace dart |
| 3034 | 3203 |
| 3035 #endif // defined TARGET_ARCH_X64 | 3204 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |