| 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 |