| 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/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 2248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2259 summary->set_in(1, Location::Constant(right_constant->value())); | 2259 summary->set_in(1, Location::Constant(right_constant->value())); |
| 2260 summary->AddTemp(Location::RequiresRegister()); | 2260 summary->AddTemp(Location::RequiresRegister()); |
| 2261 } else { | 2261 } else { |
| 2262 summary->set_in(1, Location::RequiresRegister()); | 2262 summary->set_in(1, Location::RequiresRegister()); |
| 2263 summary->AddTemp(Location::RequiresRegister()); | 2263 summary->AddTemp(Location::RequiresRegister()); |
| 2264 summary->AddTemp(Location::RequiresFpuRegister()); | 2264 summary->AddTemp(Location::RequiresFpuRegister()); |
| 2265 } | 2265 } |
| 2266 summary->set_out(Location::RequiresRegister()); | 2266 summary->set_out(Location::RequiresRegister()); |
| 2267 return summary; | 2267 return summary; |
| 2268 } | 2268 } |
| 2269 if (op_kind() == Token::kTRUNCDIVMOD) { |
| 2270 summary->set_in(0, Location::RequiresRegister()); |
| 2271 summary->set_in(1, Location::RequiresRegister()); |
| 2272 summary->AddTemp(Location::RequiresRegister()); |
| 2273 summary->AddTemp(Location::RequiresFpuRegister()); |
| 2274 summary->AddTemp(Location::RequiresRegister()); // result_div. |
| 2275 summary->AddTemp(Location::RequiresRegister()); // result_mod. |
| 2276 summary->set_out(Location::RequiresRegister()); |
| 2277 return summary; |
| 2278 } |
| 2269 if (op_kind() == Token::kMOD) { | 2279 if (op_kind() == Token::kMOD) { |
| 2270 summary->set_in(0, Location::RequiresRegister()); | 2280 summary->set_in(0, Location::RequiresRegister()); |
| 2271 summary->set_in(1, Location::RequiresRegister()); | 2281 summary->set_in(1, Location::RequiresRegister()); |
| 2272 summary->AddTemp(Location::RequiresRegister()); | 2282 summary->AddTemp(Location::RequiresRegister()); |
| 2273 summary->AddTemp(Location::RequiresFpuRegister()); | 2283 summary->AddTemp(Location::RequiresFpuRegister()); |
| 2274 summary->set_out(Location::RequiresRegister()); | 2284 summary->set_out(Location::RequiresRegister()); |
| 2275 return summary; | 2285 return summary; |
| 2276 } | 2286 } |
| 2277 summary->set_in(0, Location::RequiresRegister()); | 2287 summary->set_in(0, Location::RequiresRegister()); |
| 2278 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | 2288 summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2527 Label done; | 2537 Label done; |
| 2528 __ cmp(result, ShifterOperand(0)); | 2538 __ cmp(result, ShifterOperand(0)); |
| 2529 __ b(&done, GE); | 2539 __ b(&done, GE); |
| 2530 // Result is negative, adjust it. | 2540 // Result is negative, adjust it. |
| 2531 __ cmp(right, ShifterOperand(0)); | 2541 __ cmp(right, ShifterOperand(0)); |
| 2532 __ sub(result, result, ShifterOperand(right), LT); | 2542 __ sub(result, result, ShifterOperand(right), LT); |
| 2533 __ add(result, result, ShifterOperand(right), GE); | 2543 __ add(result, result, ShifterOperand(right), GE); |
| 2534 __ Bind(&done); | 2544 __ Bind(&done); |
| 2535 break; | 2545 break; |
| 2536 } | 2546 } |
| 2547 case Token::kTRUNCDIVMOD: { |
| 2548 // Handle divide by zero in runtime. |
| 2549 __ cmp(right, ShifterOperand(0)); |
| 2550 __ b(deopt, EQ); |
| 2551 Register temp = locs()->temp(0).reg(); |
| 2552 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 2553 Register result_div = locs()->temp(2).reg(); |
| 2554 Register result_mod = locs()->temp(3).reg(); |
| 2555 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2556 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2557 |
| 2558 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); |
| 2559 |
| 2560 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 2561 // case we cannot tag the result. |
| 2562 __ CompareImmediate(result_div, 0x40000000); |
| 2563 __ b(deopt, EQ); |
| 2564 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2565 // result_mod <- left - right * result_div. |
| 2566 __ mls(result_mod, IP, result_div, temp); |
| 2567 __ SmiTag(result_div); |
| 2568 __ SmiTag(result_mod); |
| 2569 // Correct MOD result: |
| 2570 // res = left % right; |
| 2571 // if (res < 0) { |
| 2572 // if (right < 0) { |
| 2573 // res = res - right; |
| 2574 // } else { |
| 2575 // res = res + right; |
| 2576 // } |
| 2577 // } |
| 2578 Label done; |
| 2579 __ cmp(result_mod, ShifterOperand(0)); |
| 2580 __ b(&done, GE); |
| 2581 // Result is negative, adjust it. |
| 2582 __ cmp(right, ShifterOperand(0)); |
| 2583 __ sub(result_mod, result_mod, ShifterOperand(right), LT); |
| 2584 __ add(result_mod, result_mod, ShifterOperand(right), GE); |
| 2585 __ Bind(&done); |
| 2586 |
| 2587 __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld))); |
| 2588 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays. |
| 2589 // [0]: divide resut, [1]: mod result. |
| 2590 __ mov(temp, ShifterOperand(0 + |
| 2591 FlowGraphCompiler::DataOffsetFor(kArrayCid) - kHeapObjectTag)); |
| 2592 Address store_address(result, temp, LSL, 0); |
| 2593 __ StoreIntoObjectNoBarrier(result, store_address, result_div); |
| 2594 __ add(temp, temp, ShifterOperand(kWordSize)); |
| 2595 __ StoreIntoObjectNoBarrier(result, store_address, result_mod); |
| 2596 break; |
| 2597 } |
| 2537 case Token::kSHR: { | 2598 case Token::kSHR: { |
| 2538 if (CanDeoptimize()) { | 2599 if (CanDeoptimize()) { |
| 2539 __ CompareImmediate(right, 0); | 2600 __ CompareImmediate(right, 0); |
| 2540 __ b(deopt, LT); | 2601 __ b(deopt, LT); |
| 2541 } | 2602 } |
| 2542 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. | 2603 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2543 // sarl operation masks the count to 5 bits. | 2604 // sarl operation masks the count to 5 bits. |
| 2544 const intptr_t kCountLimit = 0x1F; | 2605 const intptr_t kCountLimit = 0x1F; |
| 2545 Range* right_range = this->right()->definition()->range(); | 2606 Range* right_range = this->right()->definition()->range(); |
| 2546 if ((right_range == NULL) || | 2607 if ((right_range == NULL) || |
| (...skipping 2066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4613 compiler->GenerateCall(token_pos(), | 4674 compiler->GenerateCall(token_pos(), |
| 4614 &label, | 4675 &label, |
| 4615 PcDescriptors::kOther, | 4676 PcDescriptors::kOther, |
| 4616 locs()); | 4677 locs()); |
| 4617 __ Drop(2); // Discard type arguments and receiver. | 4678 __ Drop(2); // Discard type arguments and receiver. |
| 4618 } | 4679 } |
| 4619 | 4680 |
| 4620 } // namespace dart | 4681 } // namespace dart |
| 4621 | 4682 |
| 4622 #endif // defined TARGET_ARCH_ARM | 4683 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |