| 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 2261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2272 summary->set_in(1, Location::Constant(right_constant->value())); | 2272 summary->set_in(1, Location::Constant(right_constant->value())); |
| 2273 summary->AddTemp(Location::RequiresRegister()); | 2273 summary->AddTemp(Location::RequiresRegister()); |
| 2274 } else { | 2274 } else { |
| 2275 summary->set_in(1, Location::RequiresRegister()); | 2275 summary->set_in(1, Location::RequiresRegister()); |
| 2276 summary->AddTemp(Location::RequiresRegister()); | 2276 summary->AddTemp(Location::RequiresRegister()); |
| 2277 summary->AddTemp(Location::RequiresFpuRegister()); | 2277 summary->AddTemp(Location::RequiresFpuRegister()); |
| 2278 } | 2278 } |
| 2279 summary->set_out(Location::RequiresRegister()); | 2279 summary->set_out(Location::RequiresRegister()); |
| 2280 return summary; | 2280 return summary; |
| 2281 } | 2281 } |
| 2282 if (op_kind() == Token::kMOD) { |
| 2283 summary->set_in(0, Location::RequiresRegister()); |
| 2284 summary->set_in(1, Location::RequiresRegister()); |
| 2285 summary->AddTemp(Location::RequiresRegister()); |
| 2286 summary->AddTemp(Location::RequiresFpuRegister()); |
| 2287 summary->set_out(Location::RequiresRegister()); |
| 2288 return summary; |
| 2289 } |
| 2282 summary->set_in(0, Location::RequiresRegister()); | 2290 summary->set_in(0, Location::RequiresRegister()); |
| 2283 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | 2291 summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| 2284 if (((op_kind() == Token::kSHL) && !is_truncating()) || | 2292 if (((op_kind() == Token::kSHL) && !is_truncating()) || |
| 2285 (op_kind() == Token::kSHR)) { | 2293 (op_kind() == Token::kSHR)) { |
| 2286 summary->AddTemp(Location::RequiresRegister()); | 2294 summary->AddTemp(Location::RequiresRegister()); |
| 2287 } | 2295 } |
| 2288 // We make use of 3-operand instructions by not requiring result register | 2296 // We make use of 3-operand instructions by not requiring result register |
| 2289 // to be identical to first input register as on Intel. | 2297 // to be identical to first input register as on Intel. |
| 2290 summary->set_out(Location::RequiresRegister()); | 2298 summary->set_out(Location::RequiresRegister()); |
| 2291 return summary; | 2299 return summary; |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2500 | 2508 |
| 2501 __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 2509 __ IntegerDivide(result, temp, IP, dtemp, DTMP); |
| 2502 | 2510 |
| 2503 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 2511 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 2504 // case we cannot tag the result. | 2512 // case we cannot tag the result. |
| 2505 __ CompareImmediate(result, 0x40000000); | 2513 __ CompareImmediate(result, 0x40000000); |
| 2506 __ b(deopt, EQ); | 2514 __ b(deopt, EQ); |
| 2507 __ SmiTag(result); | 2515 __ SmiTag(result); |
| 2508 break; | 2516 break; |
| 2509 } | 2517 } |
| 2518 case Token::kMOD: { |
| 2519 // Handle divide by zero in runtime. |
| 2520 __ cmp(right, ShifterOperand(0)); |
| 2521 __ b(deopt, EQ); |
| 2522 Register temp = locs()->temp(0).reg(); |
| 2523 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 2524 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2525 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2526 |
| 2527 __ IntegerDivide(result, temp, IP, dtemp, DTMP); |
| 2528 |
| 2529 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2530 __ mls(result, IP, result, temp); // result <- left - right * result |
| 2531 __ SmiTag(result); |
| 2532 // res = left % right; |
| 2533 // if (res < 0) { |
| 2534 // if (right < 0) { |
| 2535 // res = res - right; |
| 2536 // } else { |
| 2537 // res = res + right; |
| 2538 // } |
| 2539 // } |
| 2540 Label done; |
| 2541 __ cmp(result, ShifterOperand(0)); |
| 2542 __ b(&done, GE); |
| 2543 // Result is negative, adjust it. |
| 2544 __ cmp(right, ShifterOperand(0)); |
| 2545 __ sub(result, result, ShifterOperand(right), LT); |
| 2546 __ add(result, result, ShifterOperand(right), GE); |
| 2547 __ Bind(&done); |
| 2548 break; |
| 2549 } |
| 2510 case Token::kSHR: { | 2550 case Token::kSHR: { |
| 2511 if (CanDeoptimize()) { | 2551 if (CanDeoptimize()) { |
| 2512 __ CompareImmediate(right, 0); | 2552 __ CompareImmediate(right, 0); |
| 2513 __ b(deopt, LT); | 2553 __ b(deopt, LT); |
| 2514 } | 2554 } |
| 2515 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. | 2555 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2516 // sarl operation masks the count to 5 bits. | 2556 // sarl operation masks the count to 5 bits. |
| 2517 const intptr_t kCountLimit = 0x1F; | 2557 const intptr_t kCountLimit = 0x1F; |
| 2518 Range* right_range = this->right()->definition()->range(); | 2558 Range* right_range = this->right()->definition()->range(); |
| 2519 if ((right_range == NULL) || | 2559 if ((right_range == NULL) || |
| 2520 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { | 2560 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { |
| 2521 __ CompareImmediate(IP, kCountLimit); | 2561 __ CompareImmediate(IP, kCountLimit); |
| 2522 __ LoadImmediate(IP, kCountLimit, GT); | 2562 __ LoadImmediate(IP, kCountLimit, GT); |
| 2523 } | 2563 } |
| 2524 Register temp = locs()->temp(0).reg(); | 2564 Register temp = locs()->temp(0).reg(); |
| 2525 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. | 2565 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2526 __ Asr(result, temp, IP); | 2566 __ Asr(result, temp, IP); |
| 2527 __ SmiTag(result); | 2567 __ SmiTag(result); |
| 2528 break; | 2568 break; |
| 2529 } | 2569 } |
| 2530 case Token::kDIV: { | 2570 case Token::kDIV: { |
| 2531 // Dispatches to 'Double./'. | 2571 // Dispatches to 'Double./'. |
| 2532 // TODO(srdjan): Implement as conversion to double and double division. | 2572 // TODO(srdjan): Implement as conversion to double and double division. |
| 2533 UNREACHABLE(); | 2573 UNREACHABLE(); |
| 2534 break; | 2574 break; |
| 2535 } | 2575 } |
| 2536 case Token::kMOD: { | |
| 2537 // TODO(srdjan): Implement. | |
| 2538 UNREACHABLE(); | |
| 2539 break; | |
| 2540 } | |
| 2541 case Token::kOR: | 2576 case Token::kOR: |
| 2542 case Token::kAND: { | 2577 case Token::kAND: { |
| 2543 // Flow graph builder has dissected this operation to guarantee correct | 2578 // Flow graph builder has dissected this operation to guarantee correct |
| 2544 // behavior (short-circuit evaluation). | 2579 // behavior (short-circuit evaluation). |
| 2545 UNREACHABLE(); | 2580 UNREACHABLE(); |
| 2546 break; | 2581 break; |
| 2547 } | 2582 } |
| 2548 default: | 2583 default: |
| 2549 UNREACHABLE(); | 2584 UNREACHABLE(); |
| 2550 break; | 2585 break; |
| (...skipping 2053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4604 compiler->GenerateCall(token_pos(), | 4639 compiler->GenerateCall(token_pos(), |
| 4605 &label, | 4640 &label, |
| 4606 PcDescriptors::kOther, | 4641 PcDescriptors::kOther, |
| 4607 locs()); | 4642 locs()); |
| 4608 __ Drop(2); // Discard type arguments and receiver. | 4643 __ Drop(2); // Discard type arguments and receiver. |
| 4609 } | 4644 } |
| 4610 | 4645 |
| 4611 } // namespace dart | 4646 } // namespace dart |
| 4612 | 4647 |
| 4613 #endif // defined TARGET_ARCH_ARM | 4648 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |