OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 __ ret(0); | 744 __ ret(0); |
745 | 745 |
746 CodeDesc desc; | 746 CodeDesc desc; |
747 masm->GetCode(&desc); | 747 masm->GetCode(&desc); |
748 // Call the function from C++. | 748 // Call the function from C++. |
749 int result = FUNCTION_CAST<F0>(buffer)(); | 749 int result = FUNCTION_CAST<F0>(buffer)(); |
750 CHECK_EQ(0, result); | 750 CHECK_EQ(0, result); |
751 } | 751 } |
752 | 752 |
753 | 753 |
754 | |
755 | |
756 static void SmiAddTest(MacroAssembler* masm, | 754 static void SmiAddTest(MacroAssembler* masm, |
757 Label* exit, | 755 Label* exit, |
758 int id, | 756 int id, |
759 int first, | 757 int first, |
760 int second) { | 758 int second) { |
761 __ movl(rcx, Immediate(first)); | 759 __ movl(rcx, Immediate(first)); |
762 __ Integer32ToSmi(rcx, rcx); | 760 __ Integer32ToSmi(rcx, rcx); |
763 __ movl(rdx, Immediate(second)); | 761 __ movl(rdx, Immediate(second)); |
764 __ Integer32ToSmi(rdx, rdx); | 762 __ Integer32ToSmi(rdx, rdx); |
765 __ movl(r8, Immediate(first + second)); | 763 __ movl(r8, Immediate(first + second)); |
(...skipping 29 matching lines...) Expand all Loading... |
795 __ cmpq(r9, r8); | 793 __ cmpq(r9, r8); |
796 __ j(not_equal, exit); | 794 __ j(not_equal, exit); |
797 | 795 |
798 __ incq(rax); | 796 __ incq(rax); |
799 __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), exit); | 797 __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), exit); |
800 __ cmpq(rcx, r8); | 798 __ cmpq(rcx, r8); |
801 __ j(not_equal, exit); | 799 __ j(not_equal, exit); |
802 } | 800 } |
803 | 801 |
804 | 802 |
| 803 static void SmiAddOverflowTest(MacroAssembler* masm, |
| 804 Label* exit, |
| 805 int id, |
| 806 int x) { |
| 807 // Adds a Smi to x so that the addition overflows. |
| 808 ASSERT(x != 0); // Can't overflow by adding a Smi. |
| 809 int y_max = (x > 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue - x - 1); |
| 810 int y_min = (x > 0) ? (Smi::kMaxValue - x + 1) : (Smi::kMinValue + 0); |
| 811 |
| 812 __ movl(rax, Immediate(id)); |
| 813 __ Move(rcx, Smi::FromInt(x)); |
| 814 __ movq(r11, rcx); // Store original Smi value of x in r11. |
| 815 __ Move(rdx, Smi::FromInt(y_min)); |
| 816 { |
| 817 Label overflow_ok; |
| 818 __ SmiAdd(r9, rcx, rdx, &overflow_ok); |
| 819 __ jmp(exit); |
| 820 __ bind(&overflow_ok); |
| 821 __ incq(rax); |
| 822 __ cmpq(rcx, r11); |
| 823 __ j(not_equal, exit); |
| 824 } |
| 825 |
| 826 { |
| 827 Label overflow_ok; |
| 828 __ incq(rax); |
| 829 __ SmiAdd(rcx, rcx, rdx, &overflow_ok); |
| 830 __ jmp(exit); |
| 831 __ bind(&overflow_ok); |
| 832 __ incq(rax); |
| 833 __ cmpq(rcx, r11); |
| 834 __ j(not_equal, exit); |
| 835 } |
| 836 |
| 837 __ movq(rcx, r11); |
| 838 { |
| 839 Label overflow_ok; |
| 840 __ incq(rax); |
| 841 __ SmiAddConstant(r9, rcx, Smi::FromInt(y_min), &overflow_ok); |
| 842 __ jmp(exit); |
| 843 __ bind(&overflow_ok); |
| 844 __ incq(rax); |
| 845 __ cmpq(rcx, r11); |
| 846 __ j(not_equal, exit); |
| 847 } |
| 848 |
| 849 { |
| 850 Label overflow_ok; |
| 851 __ incq(rax); |
| 852 __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_min), &overflow_ok); |
| 853 __ jmp(exit); |
| 854 __ bind(&overflow_ok); |
| 855 __ incq(rax); |
| 856 __ cmpq(rcx, r11); |
| 857 __ j(not_equal, exit); |
| 858 } |
| 859 |
| 860 __ Move(rdx, Smi::FromInt(y_max)); |
| 861 |
| 862 { |
| 863 Label overflow_ok; |
| 864 __ incq(rax); |
| 865 __ SmiAdd(r9, rcx, rdx, &overflow_ok); |
| 866 __ jmp(exit); |
| 867 __ bind(&overflow_ok); |
| 868 __ incq(rax); |
| 869 __ cmpq(rcx, r11); |
| 870 __ j(not_equal, exit); |
| 871 } |
| 872 |
| 873 { |
| 874 Label overflow_ok; |
| 875 __ incq(rax); |
| 876 __ SmiAdd(rcx, rcx, rdx, &overflow_ok); |
| 877 __ jmp(exit); |
| 878 __ bind(&overflow_ok); |
| 879 __ incq(rax); |
| 880 __ cmpq(rcx, r11); |
| 881 __ j(not_equal, exit); |
| 882 } |
| 883 |
| 884 __ movq(rcx, r11); |
| 885 { |
| 886 Label overflow_ok; |
| 887 __ incq(rax); |
| 888 __ SmiAddConstant(r9, rcx, Smi::FromInt(y_max), &overflow_ok); |
| 889 __ jmp(exit); |
| 890 __ bind(&overflow_ok); |
| 891 __ incq(rax); |
| 892 __ cmpq(rcx, r11); |
| 893 __ j(not_equal, exit); |
| 894 } |
| 895 |
| 896 { |
| 897 Label overflow_ok; |
| 898 __ incq(rax); |
| 899 __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_max), &overflow_ok); |
| 900 __ jmp(exit); |
| 901 __ bind(&overflow_ok); |
| 902 __ incq(rax); |
| 903 __ cmpq(rcx, r11); |
| 904 __ j(not_equal, exit); |
| 905 } |
| 906 } |
| 907 |
| 908 |
805 TEST(SmiAdd) { | 909 TEST(SmiAdd) { |
806 v8::internal::V8::Initialize(NULL); | 910 v8::internal::V8::Initialize(NULL); |
807 // Allocate an executable page of memory. | 911 // Allocate an executable page of memory. |
808 size_t actual_size; | 912 size_t actual_size; |
809 byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize, | 913 byte* buffer = |
810 &actual_size, | 914 static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize * 2, |
811 true)); | 915 &actual_size, |
| 916 true)); |
812 CHECK(buffer); | 917 CHECK(buffer); |
813 Isolate* isolate = CcTest::i_isolate(); | 918 Isolate* isolate = CcTest::i_isolate(); |
814 HandleScope handles(isolate); | 919 HandleScope handles(isolate); |
815 MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); | 920 MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); |
816 | 921 |
817 MacroAssembler* masm = &assembler; | 922 MacroAssembler* masm = &assembler; |
818 masm->set_allow_stub_calls(false); | 923 masm->set_allow_stub_calls(false); |
819 EntryCode(masm); | 924 EntryCode(masm); |
820 Label exit; | 925 Label exit; |
821 | 926 |
822 // No-overflow tests. | 927 // No-overflow tests. |
823 SmiAddTest(masm, &exit, 0x10, 1, 2); | 928 SmiAddTest(masm, &exit, 0x10, 1, 2); |
824 SmiAddTest(masm, &exit, 0x20, 1, -2); | 929 SmiAddTest(masm, &exit, 0x20, 1, -2); |
825 SmiAddTest(masm, &exit, 0x30, -1, 2); | 930 SmiAddTest(masm, &exit, 0x30, -1, 2); |
826 SmiAddTest(masm, &exit, 0x40, -1, -2); | 931 SmiAddTest(masm, &exit, 0x40, -1, -2); |
827 SmiAddTest(masm, &exit, 0x50, 0x1000, 0x2000); | 932 SmiAddTest(masm, &exit, 0x50, 0x1000, 0x2000); |
828 SmiAddTest(masm, &exit, 0x60, Smi::kMinValue, 5); | 933 SmiAddTest(masm, &exit, 0x60, Smi::kMinValue, 5); |
829 SmiAddTest(masm, &exit, 0x70, Smi::kMaxValue, -5); | 934 SmiAddTest(masm, &exit, 0x70, Smi::kMaxValue, -5); |
830 SmiAddTest(masm, &exit, 0x80, Smi::kMaxValue, Smi::kMinValue); | 935 SmiAddTest(masm, &exit, 0x80, Smi::kMaxValue, Smi::kMinValue); |
831 | 936 |
| 937 SmiAddOverflowTest(masm, &exit, 0x90, -1); |
| 938 SmiAddOverflowTest(masm, &exit, 0xA0, 1); |
| 939 SmiAddOverflowTest(masm, &exit, 0xB0, 1024); |
| 940 SmiAddOverflowTest(masm, &exit, 0xC0, Smi::kMaxValue); |
| 941 SmiAddOverflowTest(masm, &exit, 0xD0, -2); |
| 942 SmiAddOverflowTest(masm, &exit, 0xE0, -42000); |
| 943 SmiAddOverflowTest(masm, &exit, 0xF0, Smi::kMinValue); |
| 944 |
832 __ xor_(rax, rax); // Success. | 945 __ xor_(rax, rax); // Success. |
833 __ bind(&exit); | 946 __ bind(&exit); |
834 ExitCode(masm); | 947 ExitCode(masm); |
835 __ ret(0); | 948 __ ret(0); |
836 | 949 |
837 CodeDesc desc; | 950 CodeDesc desc; |
838 masm->GetCode(&desc); | 951 masm->GetCode(&desc); |
839 // Call the function from C++. | 952 // Call the function from C++. |
840 int result = FUNCTION_CAST<F0>(buffer)(); | 953 int result = FUNCTION_CAST<F0>(buffer)(); |
841 CHECK_EQ(0, result); | 954 CHECK_EQ(0, result); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 __ SmiSubConstant(r9, rcx, Smi::FromInt(second), exit); | 992 __ SmiSubConstant(r9, rcx, Smi::FromInt(second), exit); |
880 __ cmpq(r9, r8); | 993 __ cmpq(r9, r8); |
881 __ j(not_equal, exit); | 994 __ j(not_equal, exit); |
882 | 995 |
883 __ incq(rax); // Test 5. | 996 __ incq(rax); // Test 5. |
884 __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), exit); | 997 __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), exit); |
885 __ cmpq(rcx, r8); | 998 __ cmpq(rcx, r8); |
886 __ j(not_equal, exit); | 999 __ j(not_equal, exit); |
887 } | 1000 } |
888 | 1001 |
| 1002 |
889 static void SmiSubOverflowTest(MacroAssembler* masm, | 1003 static void SmiSubOverflowTest(MacroAssembler* masm, |
890 Label* exit, | 1004 Label* exit, |
891 int id, | 1005 int id, |
892 int x) { | 1006 int x) { |
893 // Subtracts a Smi from x so that the subtraction overflows. | 1007 // Subtracts a Smi from x so that the subtraction overflows. |
894 ASSERT(x != -1); // Can't overflow by subtracting a Smi. | 1008 ASSERT(x != -1); // Can't overflow by subtracting a Smi. |
895 int y_max = (x < 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue + 0); | 1009 int y_max = (x < 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue + 0); |
896 int y_min = (x < 0) ? (Smi::kMaxValue + x + 2) : (Smi::kMinValue + x); | 1010 int y_min = (x < 0) ? (Smi::kMaxValue + x + 2) : (Smi::kMinValue + x); |
897 | 1011 |
898 __ movl(rax, Immediate(id)); | 1012 __ movl(rax, Immediate(id)); |
(...skipping 1616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2515 CodeDesc desc; | 2629 CodeDesc desc; |
2516 masm->GetCode(&desc); | 2630 masm->GetCode(&desc); |
2517 // Call the function from C++. | 2631 // Call the function from C++. |
2518 int result = FUNCTION_CAST<F0>(buffer)(); | 2632 int result = FUNCTION_CAST<F0>(buffer)(); |
2519 CHECK_EQ(0, result); | 2633 CHECK_EQ(0, result); |
2520 } | 2634 } |
2521 | 2635 |
2522 | 2636 |
2523 | 2637 |
2524 #undef __ | 2638 #undef __ |
OLD | NEW |