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 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1375 | 1375 |
1376 | 1376 |
1377 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { | 1377 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { |
1378 CompareDoubles(assembler, LE); | 1378 CompareDoubles(assembler, LE); |
1379 } | 1379 } |
1380 | 1380 |
1381 | 1381 |
1382 // Expects left argument to be double (receiver). Right argument is unknown. | 1382 // Expects left argument to be double (receiver). Right argument is unknown. |
1383 // Both arguments are on stack. | 1383 // Both arguments are on stack. |
1384 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { | 1384 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { |
1385 Label fall_through; | 1385 Label fall_through, is_smi, double_op; |
1386 | 1386 |
1387 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through); | 1387 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
1388 // Both arguments are double, right operand is in T0. | 1388 // Both arguments are double, right operand is in T0. |
1389 __ lwc1(F2, FieldAddress(T0, Double::value_offset())); | 1389 __ lwc1(F2, FieldAddress(T0, Double::value_offset())); |
1390 __ lwc1(F3, FieldAddress(T0, Double::value_offset() + kWordSize)); | 1390 __ lwc1(F3, FieldAddress(T0, Double::value_offset() + kWordSize)); |
1391 __ Bind(&double_op); | |
1391 __ lw(T0, Address(SP, 1 * kWordSize)); // Left argument. | 1392 __ lw(T0, Address(SP, 1 * kWordSize)); // Left argument. |
1392 __ lwc1(F0, FieldAddress(T0, Double::value_offset())); | 1393 __ lwc1(F0, FieldAddress(T0, Double::value_offset())); |
1393 __ lwc1(F1, FieldAddress(T0, Double::value_offset() + kWordSize)); | 1394 __ lwc1(F1, FieldAddress(T0, Double::value_offset() + kWordSize)); |
1394 switch (kind) { | 1395 switch (kind) { |
1395 case Token::kADD: __ addd(D0, D0, D1); break; | 1396 case Token::kADD: __ addd(D0, D0, D1); break; |
1396 case Token::kSUB: __ subd(D0, D0, D1); break; | 1397 case Token::kSUB: __ subd(D0, D0, D1); break; |
1397 case Token::kMUL: __ muld(D0, D0, D1); break; | 1398 case Token::kMUL: __ muld(D0, D0, D1); break; |
1398 case Token::kDIV: __ divd(D0, D0, D1); break; | 1399 case Token::kDIV: __ divd(D0, D0, D1); break; |
1399 default: UNREACHABLE(); | 1400 default: UNREACHABLE(); |
1400 } | 1401 } |
1401 const Class& double_class = Class::Handle( | 1402 const Class& double_class = Class::Handle( |
1402 Isolate::Current()->object_store()->double_class()); | 1403 Isolate::Current()->object_store()->double_class()); |
1403 __ TryAllocate(double_class, &fall_through, V0, T1); // Result register. | 1404 __ TryAllocate(double_class, &fall_through, V0, T1); // Result register. |
1404 __ swc1(F0, FieldAddress(V0, Double::value_offset())); | 1405 __ swc1(F0, FieldAddress(V0, Double::value_offset())); |
1405 __ Ret(); | 1406 __ Ret(); |
1406 __ delay_slot()->swc1(F1, | 1407 __ delay_slot()->swc1(F1, |
1407 FieldAddress(V0, Double::value_offset() + kWordSize)); | 1408 FieldAddress(V0, Double::value_offset() + kWordSize)); |
1409 | |
1410 __ Bind(&is_smi); | |
1411 __ SmiUntag(T0); | |
1412 __ mtc1(T0, STMP1); | |
1413 __ cvtdw(D1, STMP1); | |
1414 __ b(&double_op); | |
zra
2016/03/22 17:12:21
It looks like you can use the delay slot here.
Florian Schneider
2016/03/25 16:09:47
Done. Here and for comparisons.
| |
1415 | |
1408 __ Bind(&fall_through); | 1416 __ Bind(&fall_through); |
1409 } | 1417 } |
1410 | 1418 |
1411 | 1419 |
1412 void Intrinsifier::Double_add(Assembler* assembler) { | 1420 void Intrinsifier::Double_add(Assembler* assembler) { |
1413 DoubleArithmeticOperations(assembler, Token::kADD); | 1421 DoubleArithmeticOperations(assembler, Token::kADD); |
1414 } | 1422 } |
1415 | 1423 |
1416 | 1424 |
1417 void Intrinsifier::Double_mul(Assembler* assembler) { | 1425 void Intrinsifier::Double_mul(Assembler* assembler) { |
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2222 | 2230 |
2223 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { | 2231 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { |
2224 __ LoadIsolate(V0); | 2232 __ LoadIsolate(V0); |
2225 __ Ret(); | 2233 __ Ret(); |
2226 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset())); | 2234 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset())); |
2227 } | 2235 } |
2228 | 2236 |
2229 } // namespace dart | 2237 } // namespace dart |
2230 | 2238 |
2231 #endif // defined TARGET_ARCH_MIPS | 2239 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |