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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
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 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 | 1281 |
1282 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { | 1282 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { |
1283 CompareDoubles(assembler, LS); | 1283 CompareDoubles(assembler, LS); |
1284 } | 1284 } |
1285 | 1285 |
1286 | 1286 |
1287 // Expects left argument to be double (receiver). Right argument is unknown. | 1287 // Expects left argument to be double (receiver). Right argument is unknown. |
1288 // Both arguments are on stack. | 1288 // Both arguments are on stack. |
1289 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { | 1289 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { |
1290 if (TargetCPUFeatures::vfp_supported()) { | 1290 if (TargetCPUFeatures::vfp_supported()) { |
1291 Label fall_through; | 1291 Label fall_through, is_smi, double_op; |
1292 | 1292 |
1293 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through); | 1293 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
1294 // Both arguments are double, right operand is in R0. | 1294 // Both arguments are double, right operand is in R0. |
1295 __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag); | 1295 __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag); |
| 1296 __ Bind(&double_op); |
1296 __ ldr(R0, Address(SP, 1 * kWordSize)); // Left argument. | 1297 __ ldr(R0, Address(SP, 1 * kWordSize)); // Left argument. |
1297 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag); | 1298 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag); |
1298 switch (kind) { | 1299 switch (kind) { |
1299 case Token::kADD: __ vaddd(D0, D0, D1); break; | 1300 case Token::kADD: __ vaddd(D0, D0, D1); break; |
1300 case Token::kSUB: __ vsubd(D0, D0, D1); break; | 1301 case Token::kSUB: __ vsubd(D0, D0, D1); break; |
1301 case Token::kMUL: __ vmuld(D0, D0, D1); break; | 1302 case Token::kMUL: __ vmuld(D0, D0, D1); break; |
1302 case Token::kDIV: __ vdivd(D0, D0, D1); break; | 1303 case Token::kDIV: __ vdivd(D0, D0, D1); break; |
1303 default: UNREACHABLE(); | 1304 default: UNREACHABLE(); |
1304 } | 1305 } |
1305 const Class& double_class = Class::Handle( | 1306 const Class& double_class = Class::Handle( |
1306 Isolate::Current()->object_store()->double_class()); | 1307 Isolate::Current()->object_store()->double_class()); |
1307 __ TryAllocate(double_class, &fall_through, R0, R1); // Result register. | 1308 __ TryAllocate(double_class, &fall_through, R0, R1); // Result register. |
1308 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag); | 1309 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag); |
1309 __ Ret(); | 1310 __ Ret(); |
| 1311 __ Bind(&is_smi); // Convert R0 to a double. |
| 1312 __ SmiUntag(R0); |
| 1313 __ vmovsr(S0, R0); |
| 1314 __ vcvtdi(D1, S0); |
| 1315 __ b(&double_op); // Then do the comparison. |
1310 __ Bind(&fall_through); | 1316 __ Bind(&fall_through); |
1311 } | 1317 } |
1312 } | 1318 } |
1313 | 1319 |
1314 | 1320 |
1315 void Intrinsifier::Double_add(Assembler* assembler) { | 1321 void Intrinsifier::Double_add(Assembler* assembler) { |
1316 DoubleArithmeticOperations(assembler, Token::kADD); | 1322 DoubleArithmeticOperations(assembler, Token::kADD); |
1317 } | 1323 } |
1318 | 1324 |
1319 | 1325 |
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2114 | 2120 |
2115 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { | 2121 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { |
2116 __ LoadIsolate(R0); | 2122 __ LoadIsolate(R0); |
2117 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); | 2123 __ ldr(R0, Address(R0, Isolate::current_tag_offset())); |
2118 __ Ret(); | 2124 __ Ret(); |
2119 } | 2125 } |
2120 | 2126 |
2121 } // namespace dart | 2127 } // namespace dart |
2122 | 2128 |
2123 #endif // defined TARGET_ARCH_ARM | 2129 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |