OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 } | 750 } |
751 addiu(sp, sp, 4 * NumSaved); | 751 addiu(sp, sp, 4 * NumSaved); |
752 } | 752 } |
753 | 753 |
754 | 754 |
755 void MacroAssembler::Ext(Register rt, | 755 void MacroAssembler::Ext(Register rt, |
756 Register rs, | 756 Register rs, |
757 uint16_t pos, | 757 uint16_t pos, |
758 uint16_t size) { | 758 uint16_t size) { |
759 ASSERT(pos < 32); | 759 ASSERT(pos < 32); |
760 ASSERT(pos + size < 32); | 760 ASSERT(pos + size < 33); |
761 | 761 |
762 if (mips32r2) { | 762 if (mips32r2) { |
763 ext_(rt, rs, pos, size); | 763 ext_(rt, rs, pos, size); |
764 } else { | 764 } else { |
765 // Move rs to rt and shift it left then right to get the | 765 // Move rs to rt and shift it left then right to get the |
766 // desired bitfield on the right side and zeroes on the left. | 766 // desired bitfield on the right side and zeroes on the left. |
767 sll(rt, rs, 32 - (pos + size)); | 767 int shift_left = 32 - (pos + size); |
768 srl(rt, rt, 32 - size); | 768 if (shift_left > 0) { |
| 769 sll(rt, rs, shift_left); |
| 770 } |
| 771 |
| 772 int shift_right = 32 - size; |
| 773 if (shift_right > 0) { |
| 774 srl(rt, rt, shift_right); |
| 775 } |
769 } | 776 } |
770 } | 777 } |
771 | 778 |
772 | 779 |
773 void MacroAssembler::Ins(Register rt, | 780 void MacroAssembler::Ins(Register rt, |
774 Register rs, | 781 Register rs, |
775 uint16_t pos, | 782 uint16_t pos, |
776 uint16_t size) { | 783 uint16_t size) { |
777 ASSERT(pos < 32); | 784 ASSERT(pos < 32); |
778 ASSERT(pos + size < 32); | 785 ASSERT(pos + size < 32); |
(...skipping 21 matching lines...) Expand all Loading... |
800 // t8 now contains the chunk from rs on the left and zeroes. | 807 // t8 now contains the chunk from rs on the left and zeroes. |
801 srl(t8, t8, 32 - size - pos); | 808 srl(t8, t8, 32 - size - pos); |
802 // t8 now contains the original chunk from rs in | 809 // t8 now contains the original chunk from rs in |
803 // the middle (proper position). | 810 // the middle (proper position). |
804 or_(rt, rt, t8); | 811 or_(rt, rt, t8); |
805 // rt now contains the result of the ins instruction in R2 mode. | 812 // rt now contains the result of the ins instruction in R2 mode. |
806 } | 813 } |
807 } | 814 } |
808 | 815 |
809 | 816 |
810 void MacroAssembler::Cvt_d_uw(FPURegister fd, FPURegister fs) { | 817 void MacroAssembler::Cvt_d_uw(FPURegister fd, |
811 // Move the data from fs to t4. | 818 FPURegister fs, |
812 mfc1(t4, fs); | 819 FPURegister scratch) { |
813 return Cvt_d_uw(fd, t4); | 820 // Move the data from fs to t8. |
| 821 mfc1(t8, fs); |
| 822 Cvt_d_uw(fd, t8, scratch); |
814 } | 823 } |
815 | 824 |
816 | 825 |
817 void MacroAssembler::Cvt_d_uw(FPURegister fd, Register rs) { | 826 void MacroAssembler::Cvt_d_uw(FPURegister fd, |
| 827 Register rs, |
| 828 FPURegister scratch) { |
818 // Convert rs to a FP value in fd (and fd + 1). | 829 // Convert rs to a FP value in fd (and fd + 1). |
819 // We do this by converting rs minus the MSB to avoid sign conversion, | 830 // We do this by converting rs minus the MSB to avoid sign conversion, |
820 // then adding 2^31-1 and 1 to the result. | 831 // then adding 2^31 to the result (if needed). |
821 | 832 |
822 ASSERT(!fd.is(f20)); | 833 ASSERT(!fd.is(scratch)); |
823 ASSERT(!rs.is(t9)); | 834 ASSERT(!rs.is(t9)); |
824 ASSERT(!rs.is(t8)); | 835 ASSERT(!rs.is(at)); |
825 | 836 |
826 // Save rs's MSB to t8. | 837 // Save rs's MSB to t9. |
827 And(t8, rs, 0x80000000); | 838 Ext(t9, rs, 31, 1); |
828 // Remove rs's MSB. | 839 // Remove rs's MSB. |
829 And(t9, rs, 0x7FFFFFFF); | 840 Ext(at, rs, 0, 31); |
830 // Move t9 to fd. | 841 // Move the result to fd. |
831 mtc1(t9, fd); | 842 mtc1(at, fd); |
832 | 843 |
833 // Convert fd to a real FP value. | 844 // Convert fd to a real FP value. |
834 cvt_d_w(fd, fd); | 845 cvt_d_w(fd, fd); |
835 | 846 |
836 Label conversion_done; | 847 Label conversion_done; |
837 | 848 |
838 // If rs's MSB was 0, it's done. | 849 // If rs's MSB was 0, it's done. |
839 // Otherwise we need to add that to the FP register. | 850 // Otherwise we need to add that to the FP register. |
840 Branch(&conversion_done, eq, t8, Operand(zero_reg)); | 851 Branch(&conversion_done, eq, t9, Operand(zero_reg)); |
841 | 852 |
842 // First load 2^31 - 1 into f20. | 853 // Load 2^31 into f20 as its float representation. |
843 Or(t9, zero_reg, 0x7FFFFFFF); | 854 li(at, 0x41E00000); |
844 mtc1(t9, f20); | 855 mtc1(at, FPURegister::from_code(scratch.code() + 1)); |
| 856 mtc1(zero_reg, scratch); |
| 857 // Add it to fd. |
| 858 add_d(fd, fd, scratch); |
845 | 859 |
846 // Convert it to FP and add it to fd. | |
847 cvt_d_w(f20, f20); | |
848 add_d(fd, fd, f20); | |
849 // Now add 1. | |
850 Or(t9, zero_reg, 1); | |
851 mtc1(t9, f20); | |
852 | |
853 cvt_d_w(f20, f20); | |
854 add_d(fd, fd, f20); | |
855 bind(&conversion_done); | 860 bind(&conversion_done); |
856 } | 861 } |
857 | 862 |
858 | 863 |
859 void MacroAssembler::Trunc_uw_d(FPURegister fd, FPURegister fs) { | 864 void MacroAssembler::Trunc_uw_d(FPURegister fd, |
860 Trunc_uw_d(fs, t4); | 865 FPURegister fs, |
861 mtc1(t4, fd); | 866 FPURegister scratch) { |
| 867 Trunc_uw_d(fs, t8, scratch); |
| 868 mtc1(t8, fd); |
862 } | 869 } |
863 | 870 |
864 | 871 |
865 void MacroAssembler::Trunc_uw_d(FPURegister fd, Register rs) { | 872 void MacroAssembler::Trunc_uw_d(FPURegister fd, |
866 ASSERT(!fd.is(f22)); | 873 Register rs, |
867 ASSERT(!rs.is(t8)); | 874 FPURegister scratch) { |
| 875 ASSERT(!fd.is(scratch)); |
| 876 ASSERT(!rs.is(at)); |
868 | 877 |
869 // Load 2^31 into f22. | 878 // Load 2^31 into scratch as its float representation. |
870 Or(t8, zero_reg, 0x80000000); | 879 li(at, 0x41E00000); |
871 Cvt_d_uw(f22, t8); | 880 mtc1(at, FPURegister::from_code(scratch.code() + 1)); |
872 | 881 mtc1(zero_reg, scratch); |
873 // Test if f22 > fd. | 882 // Test if scratch > fd. |
874 c(OLT, D, fd, f22); | 883 c(OLT, D, fd, scratch); |
875 | 884 |
876 Label simple_convert; | 885 Label simple_convert; |
877 // If fd < 2^31 we can convert it normally. | 886 // If fd < 2^31 we can convert it normally. |
878 bc1t(&simple_convert); | 887 bc1t(&simple_convert); |
879 | 888 |
880 // First we subtract 2^31 from fd, then trunc it to rs | 889 // First we subtract 2^31 from fd, then trunc it to rs |
881 // and add 2^31 to rs. | 890 // and add 2^31 to rs. |
882 | 891 sub_d(scratch, fd, scratch); |
883 sub_d(f22, fd, f22); | 892 trunc_w_d(scratch, scratch); |
884 trunc_w_d(f22, f22); | 893 mfc1(rs, scratch); |
885 mfc1(rs, f22); | 894 Or(rs, rs, 1 << 31); |
886 or_(rs, rs, t8); | |
887 | 895 |
888 Label done; | 896 Label done; |
889 Branch(&done); | 897 Branch(&done); |
890 // Simple conversion. | 898 // Simple conversion. |
891 bind(&simple_convert); | 899 bind(&simple_convert); |
892 trunc_w_d(f22, fd); | 900 trunc_w_d(scratch, fd); |
893 mfc1(rs, f22); | 901 mfc1(rs, scratch); |
894 | 902 |
895 bind(&done); | 903 bind(&done); |
896 } | 904 } |
897 | 905 |
898 | 906 |
899 // Tries to get a signed int32 out of a double precision floating point heap | 907 // Tries to get a signed int32 out of a double precision floating point heap |
900 // number. Rounds towards 0. Branch to 'not_int32' if the double is out of the | 908 // number. Rounds towards 0. Branch to 'not_int32' if the double is out of the |
901 // 32bits signed integer range. | 909 // 32bits signed integer range. |
902 // This method implementation differs from the ARM version for performance | 910 // This method implementation differs from the ARM version for performance |
903 // reasons. | 911 // reasons. |
(...skipping 3385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4289 opcode == BGTZL); | 4297 opcode == BGTZL); |
4290 opcode = (cond == eq) ? BEQ : BNE; | 4298 opcode = (cond == eq) ? BEQ : BNE; |
4291 instr = (instr & ~kOpcodeMask) | opcode; | 4299 instr = (instr & ~kOpcodeMask) | opcode; |
4292 masm_.emit(instr); | 4300 masm_.emit(instr); |
4293 } | 4301 } |
4294 | 4302 |
4295 | 4303 |
4296 } } // namespace v8::internal | 4304 } } // namespace v8::internal |
4297 | 4305 |
4298 #endif // V8_TARGET_ARCH_MIPS | 4306 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |