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/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 3003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3014 // IP: result bits 32..63. | 3014 // IP: result bits 32..63. |
3015 __ cmp(IP, Operand(result, ASR, 31)); | 3015 __ cmp(IP, Operand(result, ASR, 31)); |
3016 __ b(deopt, NE); | 3016 __ b(deopt, NE); |
3017 } else { | 3017 } else { |
3018 if (TargetCPUFeatures::arm_version() == ARMv7) { | 3018 if (TargetCPUFeatures::arm_version() == ARMv7) { |
3019 __ LoadImmediate(IP, value); | 3019 __ LoadImmediate(IP, value); |
3020 __ smull(result, IP, left, IP); | 3020 __ smull(result, IP, left, IP); |
3021 // IP: result bits 32..63. | 3021 // IP: result bits 32..63. |
3022 __ cmp(IP, Operand(result, ASR, 31)); | 3022 __ cmp(IP, Operand(result, ASR, 31)); |
3023 __ b(deopt, NE); | 3023 __ b(deopt, NE); |
3024 } else { | 3024 } else if (TargetCPUFeatures::can_divide()) { |
3025 const QRegister qtmp = locs()->temp(0).fpu_reg(); | 3025 const QRegister qtmp = locs()->temp(0).fpu_reg(); |
3026 const DRegister dtmp0 = EvenDRegisterOf(qtmp); | 3026 const DRegister dtmp0 = EvenDRegisterOf(qtmp); |
3027 const DRegister dtmp1 = OddDRegisterOf(qtmp); | 3027 const DRegister dtmp1 = OddDRegisterOf(qtmp); |
3028 __ LoadImmediate(IP, value); | 3028 __ LoadImmediate(IP, value); |
3029 __ CheckMultSignedOverflow(left, IP, result, dtmp0, dtmp1, deopt); | 3029 __ CheckMultSignedOverflow(left, IP, result, dtmp0, dtmp1, deopt); |
3030 __ mul(result, left, IP); | 3030 __ mul(result, left, IP); |
| 3031 } else { |
| 3032 __ b(deopt); |
3031 } | 3033 } |
3032 } | 3034 } |
3033 } | 3035 } |
3034 break; | 3036 break; |
3035 } | 3037 } |
3036 case Token::kTRUNCDIV: { | 3038 case Token::kTRUNCDIV: { |
3037 const intptr_t value = Smi::Cast(constant).Value(); | 3039 const intptr_t value = Smi::Cast(constant).Value(); |
3038 if (value == 1) { | 3040 if (value == 1) { |
3039 __ MoveRegister(result, left); | 3041 __ MoveRegister(result, left); |
3040 break; | 3042 break; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3153 case Token::kMUL: { | 3155 case Token::kMUL: { |
3154 __ SmiUntag(IP, left); | 3156 __ SmiUntag(IP, left); |
3155 if (deopt == NULL) { | 3157 if (deopt == NULL) { |
3156 __ mul(result, IP, right); | 3158 __ mul(result, IP, right); |
3157 } else { | 3159 } else { |
3158 if (TargetCPUFeatures::arm_version() == ARMv7) { | 3160 if (TargetCPUFeatures::arm_version() == ARMv7) { |
3159 __ smull(result, IP, IP, right); | 3161 __ smull(result, IP, IP, right); |
3160 // IP: result bits 32..63. | 3162 // IP: result bits 32..63. |
3161 __ cmp(IP, Operand(result, ASR, 31)); | 3163 __ cmp(IP, Operand(result, ASR, 31)); |
3162 __ b(deopt, NE); | 3164 __ b(deopt, NE); |
3163 } else { | 3165 } else if (TargetCPUFeatures::can_divide()) { |
3164 const QRegister qtmp = locs()->temp(0).fpu_reg(); | 3166 const QRegister qtmp = locs()->temp(0).fpu_reg(); |
3165 const DRegister dtmp0 = EvenDRegisterOf(qtmp); | 3167 const DRegister dtmp0 = EvenDRegisterOf(qtmp); |
3166 const DRegister dtmp1 = OddDRegisterOf(qtmp); | 3168 const DRegister dtmp1 = OddDRegisterOf(qtmp); |
3167 __ CheckMultSignedOverflow(IP, right, result, dtmp0, dtmp1, deopt); | 3169 __ CheckMultSignedOverflow(IP, right, result, dtmp0, dtmp1, deopt); |
3168 __ mul(result, IP, right); | 3170 __ mul(result, IP, right); |
| 3171 } else { |
| 3172 __ b(deopt); |
3169 } | 3173 } |
3170 } | 3174 } |
3171 break; | 3175 break; |
3172 } | 3176 } |
3173 case Token::kBIT_AND: { | 3177 case Token::kBIT_AND: { |
3174 // No overflow check. | 3178 // No overflow check. |
3175 __ and_(result, left, Operand(right)); | 3179 __ and_(result, left, Operand(right)); |
3176 break; | 3180 break; |
3177 } | 3181 } |
3178 case Token::kBIT_OR: { | 3182 case Token::kBIT_OR: { |
3179 // No overflow check. | 3183 // No overflow check. |
3180 __ orr(result, left, Operand(right)); | 3184 __ orr(result, left, Operand(right)); |
3181 break; | 3185 break; |
3182 } | 3186 } |
3183 case Token::kBIT_XOR: { | 3187 case Token::kBIT_XOR: { |
3184 // No overflow check. | 3188 // No overflow check. |
3185 __ eor(result, left, Operand(right)); | 3189 __ eor(result, left, Operand(right)); |
3186 break; | 3190 break; |
3187 } | 3191 } |
3188 case Token::kTRUNCDIV: { | 3192 case Token::kTRUNCDIV: { |
3189 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 3193 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
3190 // Handle divide by zero in runtime. | 3194 // Handle divide by zero in runtime. |
3191 __ cmp(right, Operand(0)); | 3195 __ cmp(right, Operand(0)); |
3192 __ b(deopt, EQ); | 3196 __ b(deopt, EQ); |
3193 } | 3197 } |
3194 const Register temp = locs()->temp(0).reg(); | 3198 const Register temp = locs()->temp(0).reg(); |
3195 const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 3199 if (TargetCPUFeatures::can_divide()) { |
3196 __ SmiUntag(temp, left); | 3200 const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
3197 __ SmiUntag(IP, right); | 3201 __ SmiUntag(temp, left); |
3198 | 3202 __ SmiUntag(IP, right); |
3199 __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 3203 __ IntegerDivide(result, temp, IP, dtemp, DTMP); |
| 3204 } else { |
| 3205 __ b(deopt); |
| 3206 } |
3200 | 3207 |
3201 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 3208 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
3202 // case we cannot tag the result. | 3209 // case we cannot tag the result. |
3203 __ CompareImmediate(result, 0x40000000); | 3210 __ CompareImmediate(result, 0x40000000); |
3204 __ b(deopt, EQ); | 3211 __ b(deopt, EQ); |
3205 __ SmiTag(result); | 3212 __ SmiTag(result); |
3206 break; | 3213 break; |
3207 } | 3214 } |
3208 case Token::kMOD: { | 3215 case Token::kMOD: { |
3209 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 3216 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
3210 // Handle divide by zero in runtime. | 3217 // Handle divide by zero in runtime. |
3211 __ cmp(right, Operand(0)); | 3218 __ cmp(right, Operand(0)); |
3212 __ b(deopt, EQ); | 3219 __ b(deopt, EQ); |
3213 } | 3220 } |
3214 const Register temp = locs()->temp(0).reg(); | 3221 const Register temp = locs()->temp(0).reg(); |
3215 const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 3222 if (TargetCPUFeatures::can_divide()) { |
3216 __ SmiUntag(temp, left); | 3223 const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
3217 __ SmiUntag(IP, right); | 3224 __ SmiUntag(temp, left); |
3218 | 3225 __ SmiUntag(IP, right); |
3219 __ IntegerDivide(result, temp, IP, dtemp, DTMP); | 3226 __ IntegerDivide(result, temp, IP, dtemp, DTMP); |
3220 | 3227 } else { |
| 3228 __ b(deopt); |
| 3229 } |
3221 __ SmiUntag(IP, right); | 3230 __ SmiUntag(IP, right); |
3222 __ mls(result, IP, result, temp); // result <- left - right * result | 3231 __ mls(result, IP, result, temp); // result <- left - right * result |
3223 __ SmiTag(result); | 3232 __ SmiTag(result); |
3224 // res = left % right; | 3233 // res = left % right; |
3225 // if (res < 0) { | 3234 // if (res < 0) { |
3226 // if (right < 0) { | 3235 // if (right < 0) { |
3227 // res = res - right; | 3236 // res = res - right; |
3228 // } else { | 3237 // } else { |
3229 // res = res + right; | 3238 // res = res + right; |
3230 // } | 3239 // } |
(...skipping 2156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5387 PairLocation* pair = locs()->out(0).AsPairLocation(); | 5396 PairLocation* pair = locs()->out(0).AsPairLocation(); |
5388 const Register result_div = pair->At(0).reg(); | 5397 const Register result_div = pair->At(0).reg(); |
5389 const Register result_mod = pair->At(1).reg(); | 5398 const Register result_mod = pair->At(1).reg(); |
5390 Range* right_range = InputAt(1)->definition()->range(); | 5399 Range* right_range = InputAt(1)->definition()->range(); |
5391 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { | 5400 if ((right_range == NULL) || right_range->Overlaps(0, 0)) { |
5392 // Handle divide by zero in runtime. | 5401 // Handle divide by zero in runtime. |
5393 __ cmp(right, Operand(0)); | 5402 __ cmp(right, Operand(0)); |
5394 __ b(deopt, EQ); | 5403 __ b(deopt, EQ); |
5395 } | 5404 } |
5396 const Register temp = locs()->temp(0).reg(); | 5405 const Register temp = locs()->temp(0).reg(); |
5397 const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); | 5406 if (TargetCPUFeatures::can_divide()) { |
5398 | 5407 const DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); |
5399 __ SmiUntag(temp, left); | 5408 __ SmiUntag(temp, left); |
5400 __ SmiUntag(IP, right); | 5409 __ SmiUntag(IP, right); |
5401 | 5410 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); |
5402 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); | 5411 } else { |
| 5412 __ b(deopt); |
| 5413 } |
5403 | 5414 |
5404 // Check the corner case of dividing the 'MIN_SMI' with -1, in which | 5415 // Check the corner case of dividing the 'MIN_SMI' with -1, in which |
5405 // case we cannot tag the result. | 5416 // case we cannot tag the result. |
5406 __ CompareImmediate(result_div, 0x40000000); | 5417 __ CompareImmediate(result_div, 0x40000000); |
5407 __ b(deopt, EQ); | 5418 __ b(deopt, EQ); |
5408 __ SmiUntag(IP, right); | 5419 __ SmiUntag(IP, right); |
5409 // result_mod <- left - right * result_div. | 5420 // result_mod <- left - right * result_div. |
5410 __ mls(result_mod, IP, result_div, temp); | 5421 __ mls(result_mod, IP, result_div, temp); |
5411 __ SmiTag(result_div); | 5422 __ SmiTag(result_div); |
5412 __ SmiTag(result_mod); | 5423 __ SmiTag(result_mod); |
(...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6663 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 6674 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
6664 #if defined(DEBUG) | 6675 #if defined(DEBUG) |
6665 __ LoadImmediate(R4, kInvalidObjectPointer); | 6676 __ LoadImmediate(R4, kInvalidObjectPointer); |
6666 __ LoadImmediate(R5, kInvalidObjectPointer); | 6677 __ LoadImmediate(R5, kInvalidObjectPointer); |
6667 #endif | 6678 #endif |
6668 } | 6679 } |
6669 | 6680 |
6670 } // namespace dart | 6681 } // namespace dart |
6671 | 6682 |
6672 #endif // defined TARGET_ARCH_ARM | 6683 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |