| 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 2362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2373 } | 2373 } |
| 2374 | 2374 |
| 2375 default: | 2375 default: |
| 2376 UNREACHABLE(); | 2376 UNREACHABLE(); |
| 2377 break; | 2377 break; |
| 2378 } | 2378 } |
| 2379 return; | 2379 return; |
| 2380 } | 2380 } |
| 2381 | 2381 |
| 2382 Register right = locs()->in(1).reg(); | 2382 Register right = locs()->in(1).reg(); |
| 2383 Range* right_range = this->right()->definition()->range(); |
| 2383 switch (op_kind()) { | 2384 switch (op_kind()) { |
| 2384 case Token::kADD: { | 2385 case Token::kADD: { |
| 2385 if (deopt == NULL) { | 2386 if (deopt == NULL) { |
| 2386 __ add(result, left, ShifterOperand(right)); | 2387 __ add(result, left, ShifterOperand(right)); |
| 2387 } else { | 2388 } else { |
| 2388 __ adds(result, left, ShifterOperand(right)); | 2389 __ adds(result, left, ShifterOperand(right)); |
| 2389 __ b(deopt, VS); | 2390 __ b(deopt, VS); |
| 2390 } | 2391 } |
| 2391 break; | 2392 break; |
| 2392 } | 2393 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2420 // No overflow check. | 2421 // No overflow check. |
| 2421 __ orr(result, left, ShifterOperand(right)); | 2422 __ orr(result, left, ShifterOperand(right)); |
| 2422 break; | 2423 break; |
| 2423 } | 2424 } |
| 2424 case Token::kBIT_XOR: { | 2425 case Token::kBIT_XOR: { |
| 2425 // No overflow check. | 2426 // No overflow check. |
| 2426 __ eor(result, left, ShifterOperand(right)); | 2427 __ eor(result, left, ShifterOperand(right)); |
| 2427 break; | 2428 break; |
| 2428 } | 2429 } |
| 2429 case Token::kTRUNCDIV: { | 2430 case Token::kTRUNCDIV: { |
| 2430 // Handle divide by zero in runtime. | 2431 if ((right_range == NULL) || right_range->IsWithin(0, 0)) { |
| 2431 __ cmp(right, ShifterOperand(0)); | 2432 // Handle divide by zero in runtime. |
| 2432 __ b(deopt, EQ); | 2433 __ cmp(right, ShifterOperand(0)); |
| 2434 __ b(deopt, EQ); |
| 2435 } |
| 2433 Register temp = locs()->temp(0).reg(); | 2436 Register temp = locs()->temp(0).reg(); |
| 2434 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 2437 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 2435 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. | 2438 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2436 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. | 2439 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2437 | 2440 |
| 2438 __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 2441 __ IntegerDivide(result, temp, IP, dtemp, DTMP); |
| 2439 | 2442 |
| 2440 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 2443 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| 2441 // case we cannot tag the result. | 2444 // case we cannot tag the result. |
| 2442 __ CompareImmediate(result, 0x40000000); | 2445 __ CompareImmediate(result, 0x40000000); |
| 2443 __ b(deopt, EQ); | 2446 __ b(deopt, EQ); |
| 2444 __ SmiTag(result); | 2447 __ SmiTag(result); |
| 2445 break; | 2448 break; |
| 2446 } | 2449 } |
| 2447 case Token::kMOD: { | 2450 case Token::kMOD: { |
| 2448 // Handle divide by zero in runtime. | 2451 if ((right_range == NULL) || right_range->IsWithin(0, 0)) { |
| 2449 __ cmp(right, ShifterOperand(0)); | 2452 // Handle divide by zero in runtime. |
| 2450 __ b(deopt, EQ); | 2453 __ cmp(right, ShifterOperand(0)); |
| 2454 __ b(deopt, EQ); |
| 2455 } |
| 2451 Register temp = locs()->temp(0).reg(); | 2456 Register temp = locs()->temp(0).reg(); |
| 2452 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 2457 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 2453 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. | 2458 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2454 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. | 2459 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2455 | 2460 |
| 2456 __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 2461 __ IntegerDivide(result, temp, IP, dtemp, DTMP); |
| 2457 | 2462 |
| 2458 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. | 2463 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2459 __ mls(result, IP, result, temp); // result <- left - right * result | 2464 __ mls(result, IP, result, temp); // result <- left - right * result |
| 2460 __ SmiTag(result); | 2465 __ SmiTag(result); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2477 break; | 2482 break; |
| 2478 } | 2483 } |
| 2479 case Token::kSHR: { | 2484 case Token::kSHR: { |
| 2480 if (CanDeoptimize()) { | 2485 if (CanDeoptimize()) { |
| 2481 __ CompareImmediate(right, 0); | 2486 __ CompareImmediate(right, 0); |
| 2482 __ b(deopt, LT); | 2487 __ b(deopt, LT); |
| 2483 } | 2488 } |
| 2484 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. | 2489 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 2485 // sarl operation masks the count to 5 bits. | 2490 // sarl operation masks the count to 5 bits. |
| 2486 const intptr_t kCountLimit = 0x1F; | 2491 const intptr_t kCountLimit = 0x1F; |
| 2487 Range* right_range = this->right()->definition()->range(); | |
| 2488 if ((right_range == NULL) || | 2492 if ((right_range == NULL) || |
| 2489 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { | 2493 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { |
| 2490 __ CompareImmediate(IP, kCountLimit); | 2494 __ CompareImmediate(IP, kCountLimit); |
| 2491 __ LoadImmediate(IP, kCountLimit, GT); | 2495 __ LoadImmediate(IP, kCountLimit, GT); |
| 2492 } | 2496 } |
| 2493 Register temp = locs()->temp(0).reg(); | 2497 Register temp = locs()->temp(0).reg(); |
| 2494 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. | 2498 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 2495 __ Asr(result, temp, IP); | 2499 __ Asr(result, temp, IP); |
| 2496 __ SmiTag(result); | 2500 __ SmiTag(result); |
| 2497 break; | 2501 break; |
| (...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4087 | 4091 |
| 4088 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4092 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4089 Label* deopt = NULL; | 4093 Label* deopt = NULL; |
| 4090 if (CanDeoptimize()) { | 4094 if (CanDeoptimize()) { |
| 4091 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); | 4095 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); |
| 4092 } | 4096 } |
| 4093 if (kind() == MergedMathInstr::kTruncDivMod) { | 4097 if (kind() == MergedMathInstr::kTruncDivMod) { |
| 4094 Register left = locs()->in(0).reg(); | 4098 Register left = locs()->in(0).reg(); |
| 4095 Register right = locs()->in(1).reg(); | 4099 Register right = locs()->in(1).reg(); |
| 4096 Register result = locs()->out().reg(); | 4100 Register result = locs()->out().reg(); |
| 4097 // Handle divide by zero in runtime. | 4101 Range* right_range = InputAt(1)->definition()->range(); |
| 4098 __ cmp(right, ShifterOperand(0)); | 4102 if ((right_range == NULL) || right_range->IsWithin(0, 0)) { |
| 4099 __ b(deopt, EQ); | 4103 // Handle divide by zero in runtime. |
| 4104 __ cmp(right, ShifterOperand(0)); |
| 4105 __ b(deopt, EQ); |
| 4106 } |
| 4100 Register temp = locs()->temp(0).reg(); | 4107 Register temp = locs()->temp(0).reg(); |
| 4101 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 4108 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
| 4102 Register result_div = locs()->temp(2).reg(); | 4109 Register result_div = locs()->temp(2).reg(); |
| 4103 Register result_mod = locs()->temp(3).reg(); | 4110 Register result_mod = locs()->temp(3).reg(); |
| 4104 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. | 4111 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. |
| 4105 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. | 4112 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. |
| 4106 | 4113 |
| 4107 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); | 4114 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); |
| 4108 | 4115 |
| 4109 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 4116 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4629 compiler->GenerateCall(token_pos(), | 4636 compiler->GenerateCall(token_pos(), |
| 4630 &label, | 4637 &label, |
| 4631 PcDescriptors::kOther, | 4638 PcDescriptors::kOther, |
| 4632 locs()); | 4639 locs()); |
| 4633 __ Drop(2); // Discard type arguments and receiver. | 4640 __ Drop(2); // Discard type arguments and receiver. |
| 4634 } | 4641 } |
| 4635 | 4642 |
| 4636 } // namespace dart | 4643 } // namespace dart |
| 4637 | 4644 |
| 4638 #endif // defined TARGET_ARCH_ARM | 4645 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |