| 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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 } else { | 177 } else { |
| 178 true_condition = NegateCondition(true_condition); | 178 true_condition = NegateCondition(true_condition); |
| 179 } | 179 } |
| 180 } | 180 } |
| 181 | 181 |
| 182 __ mov(result, Operand(1), true_condition); | 182 __ mov(result, Operand(1), true_condition); |
| 183 | 183 |
| 184 if (is_power_of_two_kind) { | 184 if (is_power_of_two_kind) { |
| 185 const intptr_t shift = | 185 const intptr_t shift = |
| 186 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); | 186 Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value)); |
| 187 __ Lsl(result, result, shift + kSmiTagSize); | 187 __ Lsl(result, result, Operand(shift + kSmiTagSize)); |
| 188 } else { | 188 } else { |
| 189 __ sub(result, result, Operand(1)); | 189 __ sub(result, result, Operand(1)); |
| 190 const int32_t val = | 190 const int32_t val = |
| 191 Smi::RawValue(true_value) - Smi::RawValue(false_value); | 191 Smi::RawValue(true_value) - Smi::RawValue(false_value); |
| 192 __ AndImmediate(result, result, val); | 192 __ AndImmediate(result, result, val); |
| 193 if (false_value != 0) { | 193 if (false_value != 0) { |
| 194 __ AddImmediate(result, Smi::RawValue(false_value)); | 194 __ AddImmediate(result, Smi::RawValue(false_value)); |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 } | 197 } |
| (...skipping 2655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2853 : NULL; | 2853 : NULL; |
| 2854 if (locs.in(1).IsConstant()) { | 2854 if (locs.in(1).IsConstant()) { |
| 2855 const Object& constant = locs.in(1).constant(); | 2855 const Object& constant = locs.in(1).constant(); |
| 2856 ASSERT(constant.IsSmi()); | 2856 ASSERT(constant.IsSmi()); |
| 2857 // Immediate shift operation takes 5 bits for the count. | 2857 // Immediate shift operation takes 5 bits for the count. |
| 2858 const intptr_t kCountLimit = 0x1F; | 2858 const intptr_t kCountLimit = 0x1F; |
| 2859 const intptr_t value = Smi::Cast(constant).Value(); | 2859 const intptr_t value = Smi::Cast(constant).Value(); |
| 2860 ASSERT((0 < value) && (value < kCountLimit)); | 2860 ASSERT((0 < value) && (value < kCountLimit)); |
| 2861 if (shift_left->can_overflow()) { | 2861 if (shift_left->can_overflow()) { |
| 2862 // Check for overflow (preserve left). | 2862 // Check for overflow (preserve left). |
| 2863 __ Lsl(IP, left, value); | 2863 __ Lsl(IP, left, Operand(value)); |
| 2864 __ cmp(left, Operand(IP, ASR, value)); | 2864 __ cmp(left, Operand(IP, ASR, value)); |
| 2865 __ b(deopt, NE); // Overflow. | 2865 __ b(deopt, NE); // Overflow. |
| 2866 } | 2866 } |
| 2867 // Shift for result now we know there is no overflow. | 2867 // Shift for result now we know there is no overflow. |
| 2868 __ Lsl(result, left, value); | 2868 __ Lsl(result, left, Operand(value)); |
| 2869 return; | 2869 return; |
| 2870 } | 2870 } |
| 2871 | 2871 |
| 2872 // Right (locs.in(1)) is not constant. | 2872 // Right (locs.in(1)) is not constant. |
| 2873 const Register right = locs.in(1).reg(); | 2873 const Register right = locs.in(1).reg(); |
| 2874 Range* right_range = shift_left->right()->definition()->range(); | 2874 Range* right_range = shift_left->right()->definition()->range(); |
| 2875 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) { | 2875 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) { |
| 2876 // TODO(srdjan): Implement code below for is_truncating(). | 2876 // TODO(srdjan): Implement code below for is_truncating(). |
| 2877 // If left is constant, we know the maximal allowed size for right. | 2877 // If left is constant, we know the maximal allowed size for right. |
| 2878 const Object& obj = shift_left->left()->BoundConstant(); | 2878 const Object& obj = shift_left->left()->BoundConstant(); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3115 } else { | 3115 } else { |
| 3116 __ LoadImmediate(IP, imm); | 3116 __ LoadImmediate(IP, imm); |
| 3117 __ eor(result, left, Operand(IP)); | 3117 __ eor(result, left, Operand(IP)); |
| 3118 } | 3118 } |
| 3119 break; | 3119 break; |
| 3120 } | 3120 } |
| 3121 case Token::kSHR: { | 3121 case Token::kSHR: { |
| 3122 // sarl operation masks the count to 5 bits. | 3122 // sarl operation masks the count to 5 bits. |
| 3123 const intptr_t kCountLimit = 0x1F; | 3123 const intptr_t kCountLimit = 0x1F; |
| 3124 intptr_t value = Smi::Cast(constant).Value(); | 3124 intptr_t value = Smi::Cast(constant).Value(); |
| 3125 __ Asr(result, left, Utils::Minimum(value + kSmiTagSize, kCountLimit)); | 3125 __ Asr(result, left, |
| 3126 Operand(Utils::Minimum(value + kSmiTagSize, kCountLimit))); |
| 3126 __ SmiTag(result); | 3127 __ SmiTag(result); |
| 3127 break; | 3128 break; |
| 3128 } | 3129 } |
| 3129 | 3130 |
| 3130 default: | 3131 default: |
| 3131 UNREACHABLE(); | 3132 UNREACHABLE(); |
| 3132 break; | 3133 break; |
| 3133 } | 3134 } |
| 3134 return; | 3135 return; |
| 3135 } | 3136 } |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3306 : NULL; | 3307 : NULL; |
| 3307 ASSERT(locs.in(1).IsConstant()); | 3308 ASSERT(locs.in(1).IsConstant()); |
| 3308 const Object& constant = locs.in(1).constant(); | 3309 const Object& constant = locs.in(1).constant(); |
| 3309 ASSERT(constant.IsSmi()); | 3310 ASSERT(constant.IsSmi()); |
| 3310 // Immediate shift operation takes 5 bits for the count. | 3311 // Immediate shift operation takes 5 bits for the count. |
| 3311 const intptr_t kCountLimit = 0x1F; | 3312 const intptr_t kCountLimit = 0x1F; |
| 3312 const intptr_t value = Smi::Cast(constant).Value(); | 3313 const intptr_t value = Smi::Cast(constant).Value(); |
| 3313 ASSERT((0 < value) && (value < kCountLimit)); | 3314 ASSERT((0 < value) && (value < kCountLimit)); |
| 3314 if (shift_left->can_overflow()) { | 3315 if (shift_left->can_overflow()) { |
| 3315 // Check for overflow (preserve left). | 3316 // Check for overflow (preserve left). |
| 3316 __ Lsl(IP, left, value); | 3317 __ Lsl(IP, left, Operand(value)); |
| 3317 __ cmp(left, Operand(IP, ASR, value)); | 3318 __ cmp(left, Operand(IP, ASR, value)); |
| 3318 __ b(deopt, NE); // Overflow. | 3319 __ b(deopt, NE); // Overflow. |
| 3319 } | 3320 } |
| 3320 // Shift for result now we know there is no overflow. | 3321 // Shift for result now we know there is no overflow. |
| 3321 __ Lsl(result, left, value); | 3322 __ Lsl(result, left, Operand(value)); |
| 3322 } | 3323 } |
| 3323 | 3324 |
| 3324 | 3325 |
| 3325 LocationSummary* BinaryInt32OpInstr::MakeLocationSummary(Isolate* isolate, | 3326 LocationSummary* BinaryInt32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 3326 bool opt) const { | 3327 bool opt) const { |
| 3327 const intptr_t kNumInputs = 2; | 3328 const intptr_t kNumInputs = 2; |
| 3328 // Calculate number of temporaries. | 3329 // Calculate number of temporaries. |
| 3329 intptr_t num_temps = 0; | 3330 intptr_t num_temps = 0; |
| 3330 if (((op_kind() == Token::kSHL) && can_overflow()) || | 3331 if (((op_kind() == Token::kSHL) && can_overflow()) || |
| 3331 (op_kind() == Token::kSHR)) { | 3332 (op_kind() == Token::kSHR)) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3449 __ eor(result, left, o); | 3450 __ eor(result, left, o); |
| 3450 } else { | 3451 } else { |
| 3451 __ LoadImmediate(IP, value); | 3452 __ LoadImmediate(IP, value); |
| 3452 __ eor(result, left, Operand(IP)); | 3453 __ eor(result, left, Operand(IP)); |
| 3453 } | 3454 } |
| 3454 break; | 3455 break; |
| 3455 } | 3456 } |
| 3456 case Token::kSHR: { | 3457 case Token::kSHR: { |
| 3457 // sarl operation masks the count to 5 bits. | 3458 // sarl operation masks the count to 5 bits. |
| 3458 const intptr_t kCountLimit = 0x1F; | 3459 const intptr_t kCountLimit = 0x1F; |
| 3459 __ Asr(result, left, Utils::Minimum(value, kCountLimit)); | 3460 __ Asr(result, left, Operand(Utils::Minimum(value, kCountLimit))); |
| 3460 break; | 3461 break; |
| 3461 } | 3462 } |
| 3462 | 3463 |
| 3463 default: | 3464 default: |
| 3464 UNREACHABLE(); | 3465 UNREACHABLE(); |
| 3465 break; | 3466 break; |
| 3466 } | 3467 } |
| 3467 return; | 3468 return; |
| 3468 } | 3469 } |
| 3469 | 3470 |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4116 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4117 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4117 const QRegister value = locs()->in(0).fpu_reg(); | 4118 const QRegister value = locs()->in(0).fpu_reg(); |
| 4118 const DRegister dvalue0 = EvenDRegisterOf(value); | 4119 const DRegister dvalue0 = EvenDRegisterOf(value); |
| 4119 const DRegister dvalue1 = OddDRegisterOf(value); | 4120 const DRegister dvalue1 = OddDRegisterOf(value); |
| 4120 | 4121 |
| 4121 const Register out = locs()->out(0).reg(); | 4122 const Register out = locs()->out(0).reg(); |
| 4122 const Register temp = locs()->temp(0).reg(); | 4123 const Register temp = locs()->temp(0).reg(); |
| 4123 | 4124 |
| 4124 // X lane. | 4125 // X lane. |
| 4125 __ vmovrs(out, EvenSRegisterOf(dvalue0)); | 4126 __ vmovrs(out, EvenSRegisterOf(dvalue0)); |
| 4126 __ Lsr(out, out, 31); | 4127 __ Lsr(out, out, Operand(31)); |
| 4127 // Y lane. | 4128 // Y lane. |
| 4128 __ vmovrs(temp, OddSRegisterOf(dvalue0)); | 4129 __ vmovrs(temp, OddSRegisterOf(dvalue0)); |
| 4129 __ Lsr(temp, temp, 31); | 4130 __ Lsr(temp, temp, Operand(31)); |
| 4130 __ orr(out, out, Operand(temp, LSL, 1)); | 4131 __ orr(out, out, Operand(temp, LSL, 1)); |
| 4131 // Z lane. | 4132 // Z lane. |
| 4132 __ vmovrs(temp, EvenSRegisterOf(dvalue1)); | 4133 __ vmovrs(temp, EvenSRegisterOf(dvalue1)); |
| 4133 __ Lsr(temp, temp, 31); | 4134 __ Lsr(temp, temp, Operand(31)); |
| 4134 __ orr(out, out, Operand(temp, LSL, 2)); | 4135 __ orr(out, out, Operand(temp, LSL, 2)); |
| 4135 // W lane. | 4136 // W lane. |
| 4136 __ vmovrs(temp, OddSRegisterOf(dvalue1)); | 4137 __ vmovrs(temp, OddSRegisterOf(dvalue1)); |
| 4137 __ Lsr(temp, temp, 31); | 4138 __ Lsr(temp, temp, Operand(31)); |
| 4138 __ orr(out, out, Operand(temp, LSL, 3)); | 4139 __ orr(out, out, Operand(temp, LSL, 3)); |
| 4139 // Tag. | 4140 // Tag. |
| 4140 __ SmiTag(out); | 4141 __ SmiTag(out); |
| 4141 } | 4142 } |
| 4142 | 4143 |
| 4143 | 4144 |
| 4144 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( | 4145 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( |
| 4145 Isolate* isolate, bool opt) const { | 4146 Isolate* isolate, bool opt) const { |
| 4146 const intptr_t kNumInputs = 4; | 4147 const intptr_t kNumInputs = 4; |
| 4147 const intptr_t kNumTemps = 0; | 4148 const intptr_t kNumTemps = 0; |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4669 const QRegister q = locs()->in(0).fpu_reg(); | 4670 const QRegister q = locs()->in(0).fpu_reg(); |
| 4670 | 4671 |
| 4671 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) { | 4672 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) { |
| 4672 const DRegister dvalue0 = EvenDRegisterOf(q); | 4673 const DRegister dvalue0 = EvenDRegisterOf(q); |
| 4673 const DRegister dvalue1 = OddDRegisterOf(q); | 4674 const DRegister dvalue1 = OddDRegisterOf(q); |
| 4674 | 4675 |
| 4675 const Register out = locs()->out(0).reg(); | 4676 const Register out = locs()->out(0).reg(); |
| 4676 | 4677 |
| 4677 // Upper 32-bits of X lane. | 4678 // Upper 32-bits of X lane. |
| 4678 __ vmovrs(out, OddSRegisterOf(dvalue0)); | 4679 __ vmovrs(out, OddSRegisterOf(dvalue0)); |
| 4679 __ Lsr(out, out, 31); | 4680 __ Lsr(out, out, Operand(31)); |
| 4680 // Upper 32-bits of Y lane. | 4681 // Upper 32-bits of Y lane. |
| 4681 __ vmovrs(TMP, OddSRegisterOf(dvalue1)); | 4682 __ vmovrs(TMP, OddSRegisterOf(dvalue1)); |
| 4682 __ Lsr(TMP, TMP, 31); | 4683 __ Lsr(TMP, TMP, Operand(31)); |
| 4683 __ orr(out, out, Operand(TMP, LSL, 1)); | 4684 __ orr(out, out, Operand(TMP, LSL, 1)); |
| 4684 // Tag. | 4685 // Tag. |
| 4685 __ SmiTag(out); | 4686 __ SmiTag(out); |
| 4686 return; | 4687 return; |
| 4687 } | 4688 } |
| 4688 ASSERT(representation() == kUnboxedFloat64x2); | 4689 ASSERT(representation() == kUnboxedFloat64x2); |
| 4689 const QRegister r = locs()->out(0).fpu_reg(); | 4690 const QRegister r = locs()->out(0).fpu_reg(); |
| 4690 | 4691 |
| 4691 const DRegister dvalue0 = EvenDRegisterOf(q); | 4692 const DRegister dvalue0 = EvenDRegisterOf(q); |
| 4692 const DRegister dvalue1 = OddDRegisterOf(q); | 4693 const DRegister dvalue1 = OddDRegisterOf(q); |
| (...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6299 return; | 6300 return; |
| 6300 } else if (shift == 0) { | 6301 } else if (shift == 0) { |
| 6301 // Nothing to do for zero shift amount. | 6302 // Nothing to do for zero shift amount. |
| 6302 __ mov(out_lo, Operand(left_lo)); | 6303 __ mov(out_lo, Operand(left_lo)); |
| 6303 __ mov(out_hi, Operand(left_hi)); | 6304 __ mov(out_hi, Operand(left_hi)); |
| 6304 return; | 6305 return; |
| 6305 } | 6306 } |
| 6306 switch (op_kind()) { | 6307 switch (op_kind()) { |
| 6307 case Token::kSHR: { | 6308 case Token::kSHR: { |
| 6308 if (shift < 32) { | 6309 if (shift < 32) { |
| 6309 __ Lsl(out_lo, left_hi, 32 - shift); | 6310 __ Lsl(out_lo, left_hi, Operand(32 - shift)); |
| 6310 __ orr(out_lo, out_lo, Operand(left_lo, LSR, shift)); | 6311 __ orr(out_lo, out_lo, Operand(left_lo, LSR, shift)); |
| 6311 __ Asr(out_hi, left_hi, shift); | 6312 __ Asr(out_hi, left_hi, Operand(shift)); |
| 6312 } else { | 6313 } else { |
| 6313 if (shift == 32) { | 6314 if (shift == 32) { |
| 6314 __ mov(out_lo, Operand(left_hi)); | 6315 __ mov(out_lo, Operand(left_hi)); |
| 6315 } else { | 6316 } else { |
| 6316 __ Asr(out_lo, left_hi, shift - 32); | 6317 __ Asr(out_lo, left_hi, Operand(shift - 32)); |
| 6317 } | 6318 } |
| 6318 __ Asr(out_hi, left_hi, 31); | 6319 __ Asr(out_hi, left_hi, Operand(31)); |
| 6319 } | 6320 } |
| 6320 break; | 6321 break; |
| 6321 } | 6322 } |
| 6322 case Token::kSHL: { | 6323 case Token::kSHL: { |
| 6323 if (shift < 32) { | 6324 if (shift < 32) { |
| 6324 __ Lsr(out_hi, left_lo, 32 - shift); | 6325 __ Lsr(out_hi, left_lo, Operand(32 - shift)); |
| 6325 __ orr(out_hi, out_hi, Operand(left_hi, LSL, shift)); | 6326 __ orr(out_hi, out_hi, Operand(left_hi, LSL, shift)); |
| 6326 __ Lsl(out_lo, left_lo, shift); | 6327 __ Lsl(out_lo, left_lo, Operand(shift)); |
| 6327 } else { | 6328 } else { |
| 6328 if (shift == 32) { | 6329 if (shift == 32) { |
| 6329 __ mov(out_hi, Operand(left_lo)); | 6330 __ mov(out_hi, Operand(left_lo)); |
| 6330 } else { | 6331 } else { |
| 6331 __ Lsl(out_hi, left_lo, shift - 32); | 6332 __ Lsl(out_hi, left_lo, Operand(shift - 32)); |
| 6332 } | 6333 } |
| 6333 __ mov(out_lo, Operand(0)); | 6334 __ mov(out_lo, Operand(0)); |
| 6334 } | 6335 } |
| 6335 // Check for overflow. | 6336 // Check for overflow. |
| 6336 if (can_overflow()) { | 6337 if (can_overflow()) { |
| 6337 // Compare high word from input with shifted high word from output. | 6338 // Compare high word from input with shifted high word from output. |
| 6338 if (shift > 31) { | 6339 if (shift > 31) { |
| 6339 __ cmp(left_hi, Operand(out_hi)); | 6340 __ cmp(left_hi, Operand(out_hi)); |
| 6340 } else { | 6341 } else { |
| 6341 __ cmp(left_hi, Operand(out_hi, ASR, shift)); | 6342 __ cmp(left_hi, Operand(out_hi, ASR, shift)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 6362 } | 6363 } |
| 6363 | 6364 |
| 6364 __ mov(out_lo, Operand(left_lo)); | 6365 __ mov(out_lo, Operand(left_lo)); |
| 6365 __ mov(out_hi, Operand(left_hi)); | 6366 __ mov(out_hi, Operand(left_hi)); |
| 6366 | 6367 |
| 6367 switch (op_kind()) { | 6368 switch (op_kind()) { |
| 6368 case Token::kSHR: { | 6369 case Token::kSHR: { |
| 6369 __ cmp(shift, Operand(32)); | 6370 __ cmp(shift, Operand(32)); |
| 6370 | 6371 |
| 6371 __ mov(out_lo, Operand(out_hi), HI); | 6372 __ mov(out_lo, Operand(out_hi), HI); |
| 6372 __ Asr(out_hi, out_hi, 31, HI); | 6373 __ Asr(out_hi, out_hi, Operand(31), HI); |
| 6373 __ sub(shift, shift, Operand(32), HI); | 6374 __ sub(shift, shift, Operand(32), HI); |
| 6374 | 6375 |
| 6375 __ rsb(IP, shift, Operand(32)); | 6376 __ rsb(IP, shift, Operand(32)); |
| 6376 __ mov(IP, Operand(out_hi, LSL, IP)); | 6377 __ mov(IP, Operand(out_hi, LSL, IP)); |
| 6377 __ orr(out_lo, IP, Operand(out_lo, LSR, shift)); | 6378 __ orr(out_lo, IP, Operand(out_lo, LSR, shift)); |
| 6378 __ Asr(out_hi, out_hi, shift); | 6379 __ Asr(out_hi, out_hi, shift); |
| 6379 break; | 6380 break; |
| 6380 } | 6381 } |
| 6381 case Token::kSHL: { | 6382 case Token::kSHL: { |
| 6382 __ rsbs(IP, shift, Operand(32)); | 6383 __ rsbs(IP, shift, Operand(32)); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6540 } else if (shift_value < 0) { | 6541 } else if (shift_value < 0) { |
| 6541 // Invalid shift value. | 6542 // Invalid shift value. |
| 6542 __ b(deopt); | 6543 __ b(deopt); |
| 6543 } else if (shift_value > kShifterLimit) { | 6544 } else if (shift_value > kShifterLimit) { |
| 6544 // Result is 0. | 6545 // Result is 0. |
| 6545 __ eor(out, out, Operand(out)); | 6546 __ eor(out, out, Operand(out)); |
| 6546 } else { | 6547 } else { |
| 6547 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). | 6548 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). |
| 6548 switch (op_kind()) { | 6549 switch (op_kind()) { |
| 6549 case Token::kSHR: | 6550 case Token::kSHR: |
| 6550 __ Lsr(out, left, shift_value); | 6551 __ Lsr(out, left, Operand(shift_value)); |
| 6551 break; | 6552 break; |
| 6552 case Token::kSHL: | 6553 case Token::kSHL: |
| 6553 __ Lsl(out, left, shift_value); | 6554 __ Lsl(out, left, Operand(shift_value)); |
| 6554 break; | 6555 break; |
| 6555 default: | 6556 default: |
| 6556 UNREACHABLE(); | 6557 UNREACHABLE(); |
| 6557 } | 6558 } |
| 6558 } | 6559 } |
| 6559 return; | 6560 return; |
| 6560 } | 6561 } |
| 6561 | 6562 |
| 6562 // Non constant shift value. | 6563 // Non constant shift value. |
| 6563 | |
| 6564 Register shifter = locs()->in(1).reg(); | 6564 Register shifter = locs()->in(1).reg(); |
| 6565 | 6565 |
| 6566 __ mov(temp, Operand(shifter)); | 6566 __ mov(temp, Operand(shifter)); |
| 6567 __ SmiUntag(temp); | 6567 __ SmiUntag(temp); |
| 6568 __ CompareImmediate(temp, 0); | 6568 __ CompareImmediate(temp, 0); |
| 6569 // If shift value is < 0, deoptimize. | 6569 // If shift value is < 0, deoptimize. |
| 6570 __ b(deopt, LT); | 6570 __ b(deopt, LT); |
| 6571 __ CompareImmediate(temp, kShifterLimit); | 6571 __ CompareImmediate(temp, kShifterLimit); |
| 6572 // > kShifterLimit, result is 0. | 6572 // > kShifterLimit, result is 0. |
| 6573 __ eor(out, out, Operand(out), HI); | 6573 __ eor(out, out, Operand(out), HI); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6647 __ TestImmediate(value, 0xC0000000); | 6647 __ TestImmediate(value, 0xC0000000); |
| 6648 } | 6648 } |
| 6649 __ b(&done, EQ); | 6649 __ b(&done, EQ); |
| 6650 BoxAllocationSlowPath::Allocate( | 6650 BoxAllocationSlowPath::Allocate( |
| 6651 compiler, | 6651 compiler, |
| 6652 this, | 6652 this, |
| 6653 compiler->mint_class(), | 6653 compiler->mint_class(), |
| 6654 out, | 6654 out, |
| 6655 temp); | 6655 temp); |
| 6656 if (from_representation() == kUnboxedInt32) { | 6656 if (from_representation() == kUnboxedInt32) { |
| 6657 __ Asr(temp, value, kBitsPerWord - 1); | 6657 __ Asr(temp, value, Operand(kBitsPerWord - 1)); |
| 6658 } else { | 6658 } else { |
| 6659 ASSERT(from_representation() == kUnboxedUint32); | 6659 ASSERT(from_representation() == kUnboxedUint32); |
| 6660 __ eor(temp, temp, Operand(temp)); | 6660 __ eor(temp, temp, Operand(temp)); |
| 6661 } | 6661 } |
| 6662 __ StoreToOffset(kWord, | 6662 __ StoreToOffset(kWord, |
| 6663 value, | 6663 value, |
| 6664 out, | 6664 out, |
| 6665 Mint::value_offset() - kHeapObjectTag); | 6665 Mint::value_offset() - kHeapObjectTag); |
| 6666 __ StoreToOffset(kWord, | 6666 __ StoreToOffset(kWord, |
| 6667 temp, | 6667 temp, |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7031 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 7031 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 7032 #if defined(DEBUG) | 7032 #if defined(DEBUG) |
| 7033 __ LoadImmediate(R4, kInvalidObjectPointer); | 7033 __ LoadImmediate(R4, kInvalidObjectPointer); |
| 7034 __ LoadImmediate(R5, kInvalidObjectPointer); | 7034 __ LoadImmediate(R5, kInvalidObjectPointer); |
| 7035 #endif | 7035 #endif |
| 7036 } | 7036 } |
| 7037 | 7037 |
| 7038 } // namespace dart | 7038 } // namespace dart |
| 7039 | 7039 |
| 7040 #endif // defined TARGET_ARCH_ARM | 7040 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |