| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| (...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 ASSERT(kSmiTagShift == 1); | 857 ASSERT(kSmiTagShift == 1); |
| 858 ASSERT(kSmiTag == 0); | 858 ASSERT(kSmiTag == 0); |
| 859 Label fall_through, overflow; | 859 Label fall_through, overflow; |
| 860 | 860 |
| 861 TestBothArgumentsSmis(assembler, &fall_through); | 861 TestBothArgumentsSmis(assembler, &fall_through); |
| 862 __ BranchUnsignedGreater(T0, Smi::RawValue(Smi::kBits), &fall_through); | 862 __ BranchUnsignedGreater(T0, Smi::RawValue(Smi::kBits), &fall_through); |
| 863 __ SmiUntag(T0); | 863 __ SmiUntag(T0); |
| 864 | 864 |
| 865 // Check for overflow by shifting left and shifting back arithmetically. | 865 // Check for overflow by shifting left and shifting back arithmetically. |
| 866 // If the result is different from the original, there was overflow. | 866 // If the result is different from the original, there was overflow. |
| 867 __ mov(T2, T1); | 867 __ sllv(TMP, T1, T0); |
| 868 __ sllv(T1, T1, T0); | 868 __ srav(TMP, TMP, T0); |
| 869 __ srlv(T1, T1, T0); | 869 __ bne(TMP, T1, &overflow); |
| 870 __ bne(T1, T2, &overflow); | |
| 871 | 870 |
| 872 // No overflow, result in V0. | 871 // No overflow, result in V0. |
| 873 __ Ret(); | 872 __ Ret(); |
| 874 __ delay_slot()->sllv(V0, T1, T0); | 873 __ delay_slot()->sllv(V0, T1, T0); |
| 875 | 874 |
| 876 __ Bind(&overflow); | 875 __ Bind(&overflow); |
| 877 // Arguments are Smi but the shift produced an overflow to Mint. | 876 // Arguments are Smi but the shift produced an overflow to Mint. |
| 878 __ bltz(T2, &fall_through); | 877 __ bltz(T1, &fall_through); |
| 879 __ SmiUntag(T2); | 878 __ SmiUntag(T1); |
| 880 | 879 |
| 881 // Pull off high bits that will be shifted off of T2 by making a mask | 880 // Pull off high bits that will be shifted off of T1 by making a mask |
| 882 // ((1 << T0) - 1), shifting it to the right, masking T2, then shifting back. | 881 // ((1 << T0) - 1), shifting it to the right, masking T1, then shifting back. |
| 883 // high bits = (((1 << T0) - 1) << (32 - T0)) & T2) >> (32 - T0) | 882 // high bits = (((1 << T0) - 1) << (32 - T0)) & T1) >> (32 - T0) |
| 884 // lo bits = T2 << T0 | 883 // lo bits = T1 << T0 |
| 885 __ LoadImmediate(T3, 1); | 884 __ LoadImmediate(T3, 1); |
| 886 __ sllv(T3, T3, T0); // T3 <- T3 << T0 | 885 __ sllv(T3, T3, T0); // T3 <- T3 << T0 |
| 887 __ addiu(T3, T3, Immediate(-1)); // T3 <- T3 - 1 | 886 __ addiu(T3, T3, Immediate(-1)); // T3 <- T3 - 1 |
| 888 __ addu(T4, ZR, T0); // T4 <- -T0 | 887 __ subu(T4, ZR, T0); // T4 <- -T0 |
| 889 __ addiu(T4, T4, Immediate(32)); // T4 <- 32 - T0 | 888 __ addiu(T4, T4, Immediate(32)); // T4 <- 32 - T0 |
| 890 __ sllv(T3, T3, T4); // T3 <- T3 << T4 | 889 __ sllv(T3, T3, T4); // T3 <- T3 << T4 |
| 891 __ and_(T3, T3, T2); // T3 <- T3 & T2 | 890 __ and_(T3, T3, T1); // T3 <- T3 & T1 |
| 892 __ srlv(T3, T3, T4); // T3 <- T3 >> T4 | 891 __ srlv(T3, T3, T4); // T3 <- T3 >> T4 |
| 893 // Now T3 has the bits that fall off of T2 on a left shift. | 892 // Now T3 has the bits that fall off of T1 on a left shift. |
| 894 __ sllv(T0, T2, T0); // T0 gets low bits. | 893 __ sllv(T0, T1, T0); // T0 gets low bits. |
| 895 | 894 |
| 896 const Class& mint_class = Class::Handle( | 895 const Class& mint_class = Class::Handle( |
| 897 Isolate::Current()->object_store()->mint_class()); | 896 Isolate::Current()->object_store()->mint_class()); |
| 898 __ TryAllocate(mint_class, &fall_through, V0); | 897 __ TryAllocate(mint_class, &fall_through, V0); |
| 899 | 898 |
| 900 __ sw(T0, FieldAddress(V0, Mint::value_offset())); | 899 __ sw(T0, FieldAddress(V0, Mint::value_offset())); |
| 901 __ Ret(); | 900 __ Ret(); |
| 902 __ delay_slot()->sw(T3, FieldAddress(V0, Mint::value_offset() + kWordSize)); | 901 __ delay_slot()->sw(T3, FieldAddress(V0, Mint::value_offset() + kWordSize)); |
| 903 __ Bind(&fall_through); | 902 __ Bind(&fall_through); |
| 904 return false; | 903 return false; |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 __ srl(T0, T0, 31); // Get the sign bit down to bit 0 of T0. | 1363 __ srl(T0, T0, 31); // Get the sign bit down to bit 0 of T0. |
| 1365 __ andi(CMPRES, T0, Immediate(1)); // Check if the bit is set. | 1364 __ andi(CMPRES, T0, Immediate(1)); // Check if the bit is set. |
| 1366 __ bne(T0, ZR, &is_true); // Sign bit set. True. | 1365 __ bne(T0, ZR, &is_true); // Sign bit set. True. |
| 1367 __ b(&is_false); | 1366 __ b(&is_false); |
| 1368 return true; | 1367 return true; |
| 1369 } | 1368 } |
| 1370 | 1369 |
| 1371 | 1370 |
| 1372 bool Intrinsifier::Double_toInt(Assembler* assembler) { | 1371 bool Intrinsifier::Double_toInt(Assembler* assembler) { |
| 1373 __ lw(T0, Address(SP, 0 * kWordSize)); | 1372 __ lw(T0, Address(SP, 0 * kWordSize)); |
| 1374 __ lwc1(F0, FieldAddress(T0, Double::value_offset())); | 1373 __ LoadDFromOffset(D0, T0, Double::value_offset() - kHeapObjectTag); |
| 1375 __ lwc1(F1, FieldAddress(T0, Double::value_offset() + kWordSize)); | 1374 |
| 1376 __ cvtwd(F2, D0); | 1375 __ cvtwd(F2, D0); |
| 1377 __ mfc1(V0, F2); | 1376 __ mfc1(V0, F2); |
| 1377 |
| 1378 // Overflow is signaled with minint. | 1378 // Overflow is signaled with minint. |
| 1379 Label fall_through; | 1379 Label fall_through; |
| 1380 // Check for overflow and that it fits into Smi. | 1380 // Check for overflow and that it fits into Smi. |
| 1381 __ BranchSignedLess(V0, 0xC0000000, &fall_through); | 1381 __ LoadImmediate(TMP, 0xC0000000); |
| 1382 __ subu(CMPRES, V0, TMP); |
| 1383 __ bltz(CMPRES, &fall_through); |
| 1382 __ Ret(); | 1384 __ Ret(); |
| 1383 __ delay_slot()->SmiTag(V0); | 1385 __ delay_slot()->SmiTag(V0); |
| 1384 __ Bind(&fall_through); | 1386 __ Bind(&fall_through); |
| 1385 return false; | 1387 return false; |
| 1386 } | 1388 } |
| 1387 | 1389 |
| 1388 | 1390 |
| 1389 bool Intrinsifier::Math_sqrt(Assembler* assembler) { | 1391 bool Intrinsifier::Math_sqrt(Assembler* assembler) { |
| 1390 Label fall_through, is_smi, double_op; | 1392 Label fall_through, is_smi, double_op; |
| 1391 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | 1393 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1767 __ Bind(&ok); | 1769 __ Bind(&ok); |
| 1768 __ Ret(); | 1770 __ Ret(); |
| 1769 | 1771 |
| 1770 __ Bind(&fall_through); | 1772 __ Bind(&fall_through); |
| 1771 return false; | 1773 return false; |
| 1772 } | 1774 } |
| 1773 | 1775 |
| 1774 } // namespace dart | 1776 } // namespace dart |
| 1775 | 1777 |
| 1776 #endif // defined TARGET_ARCH_MIPS | 1778 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |