| 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 2658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2856 : NULL; | 2856 : NULL; |
| 2857 if (locs.in(1).IsConstant()) { | 2857 if (locs.in(1).IsConstant()) { |
| 2858 const Object& constant = locs.in(1).constant(); | 2858 const Object& constant = locs.in(1).constant(); |
| 2859 ASSERT(constant.IsSmi()); | 2859 ASSERT(constant.IsSmi()); |
| 2860 // Immediate shift operation takes 5 bits for the count. | 2860 // Immediate shift operation takes 5 bits for the count. |
| 2861 const intptr_t kCountLimit = 0x1F; | 2861 const intptr_t kCountLimit = 0x1F; |
| 2862 const intptr_t value = Smi::Cast(constant).Value(); | 2862 const intptr_t value = Smi::Cast(constant).Value(); |
| 2863 ASSERT((0 < value) && (value < kCountLimit)); | 2863 ASSERT((0 < value) && (value < kCountLimit)); |
| 2864 if (shift_left->can_overflow()) { | 2864 if (shift_left->can_overflow()) { |
| 2865 // Check for overflow (preserve left). | 2865 // Check for overflow (preserve left). |
| 2866 __ Lsl(IP, left, value); | 2866 __ Lsl(IP, left, Operand(value)); |
| 2867 __ cmp(left, Operand(IP, ASR, value)); | 2867 __ cmp(left, Operand(IP, ASR, value)); |
| 2868 __ b(deopt, NE); // Overflow. | 2868 __ b(deopt, NE); // Overflow. |
| 2869 } | 2869 } |
| 2870 // Shift for result now we know there is no overflow. | 2870 // Shift for result now we know there is no overflow. |
| 2871 __ Lsl(result, left, value); | 2871 __ Lsl(result, left, Operand(value)); |
| 2872 return; | 2872 return; |
| 2873 } | 2873 } |
| 2874 | 2874 |
| 2875 // Right (locs.in(1)) is not constant. | 2875 // Right (locs.in(1)) is not constant. |
| 2876 const Register right = locs.in(1).reg(); | 2876 const Register right = locs.in(1).reg(); |
| 2877 Range* right_range = shift_left->right()->definition()->range(); | 2877 Range* right_range = shift_left->right()->definition()->range(); |
| 2878 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) { | 2878 if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) { |
| 2879 // TODO(srdjan): Implement code below for is_truncating(). | 2879 // TODO(srdjan): Implement code below for is_truncating(). |
| 2880 // If left is constant, we know the maximal allowed size for right. | 2880 // If left is constant, we know the maximal allowed size for right. |
| 2881 const Object& obj = shift_left->left()->BoundConstant(); | 2881 const Object& obj = shift_left->left()->BoundConstant(); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3118 } else { | 3118 } else { |
| 3119 __ LoadImmediate(IP, imm); | 3119 __ LoadImmediate(IP, imm); |
| 3120 __ eor(result, left, Operand(IP)); | 3120 __ eor(result, left, Operand(IP)); |
| 3121 } | 3121 } |
| 3122 break; | 3122 break; |
| 3123 } | 3123 } |
| 3124 case Token::kSHR: { | 3124 case Token::kSHR: { |
| 3125 // sarl operation masks the count to 5 bits. | 3125 // sarl operation masks the count to 5 bits. |
| 3126 const intptr_t kCountLimit = 0x1F; | 3126 const intptr_t kCountLimit = 0x1F; |
| 3127 intptr_t value = Smi::Cast(constant).Value(); | 3127 intptr_t value = Smi::Cast(constant).Value(); |
| 3128 __ Asr(result, left, Utils::Minimum(value + kSmiTagSize, kCountLimit)); | 3128 __ Asr(result, left, |
| 3129 Operand(Utils::Minimum(value + kSmiTagSize, kCountLimit))); |
| 3129 __ SmiTag(result); | 3130 __ SmiTag(result); |
| 3130 break; | 3131 break; |
| 3131 } | 3132 } |
| 3132 | 3133 |
| 3133 default: | 3134 default: |
| 3134 UNREACHABLE(); | 3135 UNREACHABLE(); |
| 3135 break; | 3136 break; |
| 3136 } | 3137 } |
| 3137 return; | 3138 return; |
| 3138 } | 3139 } |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3309 : NULL; | 3310 : NULL; |
| 3310 ASSERT(locs.in(1).IsConstant()); | 3311 ASSERT(locs.in(1).IsConstant()); |
| 3311 const Object& constant = locs.in(1).constant(); | 3312 const Object& constant = locs.in(1).constant(); |
| 3312 ASSERT(constant.IsSmi()); | 3313 ASSERT(constant.IsSmi()); |
| 3313 // Immediate shift operation takes 5 bits for the count. | 3314 // Immediate shift operation takes 5 bits for the count. |
| 3314 const intptr_t kCountLimit = 0x1F; | 3315 const intptr_t kCountLimit = 0x1F; |
| 3315 const intptr_t value = Smi::Cast(constant).Value(); | 3316 const intptr_t value = Smi::Cast(constant).Value(); |
| 3316 ASSERT((0 < value) && (value < kCountLimit)); | 3317 ASSERT((0 < value) && (value < kCountLimit)); |
| 3317 if (shift_left->can_overflow()) { | 3318 if (shift_left->can_overflow()) { |
| 3318 // Check for overflow (preserve left). | 3319 // Check for overflow (preserve left). |
| 3319 __ Lsl(IP, left, value); | 3320 __ Lsl(IP, left, Operand(value)); |
| 3320 __ cmp(left, Operand(IP, ASR, value)); | 3321 __ cmp(left, Operand(IP, ASR, value)); |
| 3321 __ b(deopt, NE); // Overflow. | 3322 __ b(deopt, NE); // Overflow. |
| 3322 } | 3323 } |
| 3323 // Shift for result now we know there is no overflow. | 3324 // Shift for result now we know there is no overflow. |
| 3324 __ Lsl(result, left, value); | 3325 __ Lsl(result, left, Operand(value)); |
| 3325 } | 3326 } |
| 3326 | 3327 |
| 3327 | 3328 |
| 3328 LocationSummary* BinaryInt32OpInstr::MakeLocationSummary(Isolate* isolate, | 3329 LocationSummary* BinaryInt32OpInstr::MakeLocationSummary(Isolate* isolate, |
| 3329 bool opt) const { | 3330 bool opt) const { |
| 3330 const intptr_t kNumInputs = 2; | 3331 const intptr_t kNumInputs = 2; |
| 3331 // Calculate number of temporaries. | 3332 // Calculate number of temporaries. |
| 3332 intptr_t num_temps = 0; | 3333 intptr_t num_temps = 0; |
| 3333 if (((op_kind() == Token::kSHL) && can_overflow()) || | 3334 if (((op_kind() == Token::kSHL) && can_overflow()) || |
| 3334 (op_kind() == Token::kSHR)) { | 3335 (op_kind() == Token::kSHR)) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3452 __ eor(result, left, o); | 3453 __ eor(result, left, o); |
| 3453 } else { | 3454 } else { |
| 3454 __ LoadImmediate(IP, value); | 3455 __ LoadImmediate(IP, value); |
| 3455 __ eor(result, left, Operand(IP)); | 3456 __ eor(result, left, Operand(IP)); |
| 3456 } | 3457 } |
| 3457 break; | 3458 break; |
| 3458 } | 3459 } |
| 3459 case Token::kSHR: { | 3460 case Token::kSHR: { |
| 3460 // sarl operation masks the count to 5 bits. | 3461 // sarl operation masks the count to 5 bits. |
| 3461 const intptr_t kCountLimit = 0x1F; | 3462 const intptr_t kCountLimit = 0x1F; |
| 3462 __ Asr(result, left, Utils::Minimum(value, kCountLimit)); | 3463 __ Asr(result, left, Operand(Utils::Minimum(value, kCountLimit))); |
| 3463 break; | 3464 break; |
| 3464 } | 3465 } |
| 3465 | 3466 |
| 3466 default: | 3467 default: |
| 3467 UNREACHABLE(); | 3468 UNREACHABLE(); |
| 3468 break; | 3469 break; |
| 3469 } | 3470 } |
| 3470 return; | 3471 return; |
| 3471 } | 3472 } |
| 3472 | 3473 |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4119 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4120 void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4120 const QRegister value = locs()->in(0).fpu_reg(); | 4121 const QRegister value = locs()->in(0).fpu_reg(); |
| 4121 const DRegister dvalue0 = EvenDRegisterOf(value); | 4122 const DRegister dvalue0 = EvenDRegisterOf(value); |
| 4122 const DRegister dvalue1 = OddDRegisterOf(value); | 4123 const DRegister dvalue1 = OddDRegisterOf(value); |
| 4123 | 4124 |
| 4124 const Register out = locs()->out(0).reg(); | 4125 const Register out = locs()->out(0).reg(); |
| 4125 const Register temp = locs()->temp(0).reg(); | 4126 const Register temp = locs()->temp(0).reg(); |
| 4126 | 4127 |
| 4127 // X lane. | 4128 // X lane. |
| 4128 __ vmovrs(out, EvenSRegisterOf(dvalue0)); | 4129 __ vmovrs(out, EvenSRegisterOf(dvalue0)); |
| 4129 __ Lsr(out, out, 31); | 4130 __ Lsr(out, out, Operand(31)); |
| 4130 // Y lane. | 4131 // Y lane. |
| 4131 __ vmovrs(temp, OddSRegisterOf(dvalue0)); | 4132 __ vmovrs(temp, OddSRegisterOf(dvalue0)); |
| 4132 __ Lsr(temp, temp, 31); | 4133 __ Lsr(temp, temp, Operand(31)); |
| 4133 __ orr(out, out, Operand(temp, LSL, 1)); | 4134 __ orr(out, out, Operand(temp, LSL, 1)); |
| 4134 // Z lane. | 4135 // Z lane. |
| 4135 __ vmovrs(temp, EvenSRegisterOf(dvalue1)); | 4136 __ vmovrs(temp, EvenSRegisterOf(dvalue1)); |
| 4136 __ Lsr(temp, temp, 31); | 4137 __ Lsr(temp, temp, Operand(31)); |
| 4137 __ orr(out, out, Operand(temp, LSL, 2)); | 4138 __ orr(out, out, Operand(temp, LSL, 2)); |
| 4138 // W lane. | 4139 // W lane. |
| 4139 __ vmovrs(temp, OddSRegisterOf(dvalue1)); | 4140 __ vmovrs(temp, OddSRegisterOf(dvalue1)); |
| 4140 __ Lsr(temp, temp, 31); | 4141 __ Lsr(temp, temp, Operand(31)); |
| 4141 __ orr(out, out, Operand(temp, LSL, 3)); | 4142 __ orr(out, out, Operand(temp, LSL, 3)); |
| 4142 // Tag. | 4143 // Tag. |
| 4143 __ SmiTag(out); | 4144 __ SmiTag(out); |
| 4144 } | 4145 } |
| 4145 | 4146 |
| 4146 | 4147 |
| 4147 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( | 4148 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary( |
| 4148 Isolate* isolate, bool opt) const { | 4149 Isolate* isolate, bool opt) const { |
| 4149 const intptr_t kNumInputs = 4; | 4150 const intptr_t kNumInputs = 4; |
| 4150 const intptr_t kNumTemps = 0; | 4151 const intptr_t kNumTemps = 0; |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4672 const QRegister q = locs()->in(0).fpu_reg(); | 4673 const QRegister q = locs()->in(0).fpu_reg(); |
| 4673 | 4674 |
| 4674 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) { | 4675 if ((op_kind() == MethodRecognizer::kFloat64x2GetSignMask)) { |
| 4675 const DRegister dvalue0 = EvenDRegisterOf(q); | 4676 const DRegister dvalue0 = EvenDRegisterOf(q); |
| 4676 const DRegister dvalue1 = OddDRegisterOf(q); | 4677 const DRegister dvalue1 = OddDRegisterOf(q); |
| 4677 | 4678 |
| 4678 const Register out = locs()->out(0).reg(); | 4679 const Register out = locs()->out(0).reg(); |
| 4679 | 4680 |
| 4680 // Upper 32-bits of X lane. | 4681 // Upper 32-bits of X lane. |
| 4681 __ vmovrs(out, OddSRegisterOf(dvalue0)); | 4682 __ vmovrs(out, OddSRegisterOf(dvalue0)); |
| 4682 __ Lsr(out, out, 31); | 4683 __ Lsr(out, out, Operand(31)); |
| 4683 // Upper 32-bits of Y lane. | 4684 // Upper 32-bits of Y lane. |
| 4684 __ vmovrs(TMP, OddSRegisterOf(dvalue1)); | 4685 __ vmovrs(TMP, OddSRegisterOf(dvalue1)); |
| 4685 __ Lsr(TMP, TMP, 31); | 4686 __ Lsr(TMP, TMP, Operand(31)); |
| 4686 __ orr(out, out, Operand(TMP, LSL, 1)); | 4687 __ orr(out, out, Operand(TMP, LSL, 1)); |
| 4687 // Tag. | 4688 // Tag. |
| 4688 __ SmiTag(out); | 4689 __ SmiTag(out); |
| 4689 return; | 4690 return; |
| 4690 } | 4691 } |
| 4691 ASSERT(representation() == kUnboxedFloat64x2); | 4692 ASSERT(representation() == kUnboxedFloat64x2); |
| 4692 const QRegister r = locs()->out(0).fpu_reg(); | 4693 const QRegister r = locs()->out(0).fpu_reg(); |
| 4693 | 4694 |
| 4694 const DRegister dvalue0 = EvenDRegisterOf(q); | 4695 const DRegister dvalue0 = EvenDRegisterOf(q); |
| 4695 const DRegister dvalue1 = OddDRegisterOf(q); | 4696 const DRegister dvalue1 = OddDRegisterOf(q); |
| (...skipping 1590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6286 return; | 6287 return; |
| 6287 } else if (shift == 0) { | 6288 } else if (shift == 0) { |
| 6288 // Nothing to do for zero shift amount. | 6289 // Nothing to do for zero shift amount. |
| 6289 __ mov(out_lo, Operand(left_lo)); | 6290 __ mov(out_lo, Operand(left_lo)); |
| 6290 __ mov(out_hi, Operand(left_hi)); | 6291 __ mov(out_hi, Operand(left_hi)); |
| 6291 return; | 6292 return; |
| 6292 } | 6293 } |
| 6293 switch (op_kind()) { | 6294 switch (op_kind()) { |
| 6294 case Token::kSHR: { | 6295 case Token::kSHR: { |
| 6295 if (shift < 32) { | 6296 if (shift < 32) { |
| 6296 __ Lsl(out_lo, left_hi, 32 - shift); | 6297 __ Lsl(out_lo, left_hi, Operand(32 - shift)); |
| 6297 __ orr(out_lo, out_lo, Operand(left_lo, LSR, shift)); | 6298 __ orr(out_lo, out_lo, Operand(left_lo, LSR, shift)); |
| 6298 __ Asr(out_hi, left_hi, shift); | 6299 __ Asr(out_hi, left_hi, Operand(shift)); |
| 6299 } else { | 6300 } else { |
| 6300 if (shift == 32) { | 6301 if (shift == 32) { |
| 6301 __ mov(out_lo, Operand(left_hi)); | 6302 __ mov(out_lo, Operand(left_hi)); |
| 6302 } else { | 6303 } else { |
| 6303 __ Asr(out_lo, left_hi, shift - 32); | 6304 __ Asr(out_lo, left_hi, Operand(shift - 32)); |
| 6304 } | 6305 } |
| 6305 __ Asr(out_hi, left_hi, 31); | 6306 __ Asr(out_hi, left_hi, Operand(31)); |
| 6306 } | 6307 } |
| 6307 break; | 6308 break; |
| 6308 } | 6309 } |
| 6309 case Token::kSHL: { | 6310 case Token::kSHL: { |
| 6310 if (shift < 32) { | 6311 if (shift < 32) { |
| 6311 __ Lsr(out_hi, left_lo, 32 - shift); | 6312 __ Lsr(out_hi, left_lo, Operand(32 - shift)); |
| 6312 __ orr(out_hi, out_hi, Operand(left_hi, LSL, shift)); | 6313 __ orr(out_hi, out_hi, Operand(left_hi, LSL, shift)); |
| 6313 __ Lsl(out_lo, left_lo, shift); | 6314 __ Lsl(out_lo, left_lo, Operand(shift)); |
| 6314 } else { | 6315 } else { |
| 6315 if (shift == 32) { | 6316 if (shift == 32) { |
| 6316 __ mov(out_hi, Operand(left_lo)); | 6317 __ mov(out_hi, Operand(left_lo)); |
| 6317 } else { | 6318 } else { |
| 6318 __ Lsl(out_hi, left_lo, shift - 32); | 6319 __ Lsl(out_hi, left_lo, Operand(shift - 32)); |
| 6319 } | 6320 } |
| 6320 __ mov(out_lo, Operand(0)); | 6321 __ mov(out_lo, Operand(0)); |
| 6321 } | 6322 } |
| 6322 // Check for overflow. | 6323 // Check for overflow. |
| 6323 if (can_overflow()) { | 6324 if (can_overflow()) { |
| 6324 // Compare high word from input with shifted high word from output. | 6325 // Compare high word from input with shifted high word from output. |
| 6325 if (shift > 31) { | 6326 if (shift > 31) { |
| 6326 __ cmp(left_hi, Operand(out_hi)); | 6327 __ cmp(left_hi, Operand(out_hi)); |
| 6327 } else { | 6328 } else { |
| 6328 __ cmp(left_hi, Operand(out_hi, ASR, shift)); | 6329 __ cmp(left_hi, Operand(out_hi, ASR, shift)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 6349 } | 6350 } |
| 6350 | 6351 |
| 6351 __ mov(out_lo, Operand(left_lo)); | 6352 __ mov(out_lo, Operand(left_lo)); |
| 6352 __ mov(out_hi, Operand(left_hi)); | 6353 __ mov(out_hi, Operand(left_hi)); |
| 6353 | 6354 |
| 6354 switch (op_kind()) { | 6355 switch (op_kind()) { |
| 6355 case Token::kSHR: { | 6356 case Token::kSHR: { |
| 6356 __ cmp(shift, Operand(32)); | 6357 __ cmp(shift, Operand(32)); |
| 6357 | 6358 |
| 6358 __ mov(out_lo, Operand(out_hi), HI); | 6359 __ mov(out_lo, Operand(out_hi), HI); |
| 6359 __ Asr(out_hi, out_hi, 31, HI); | 6360 __ Asr(out_hi, out_hi, Operand(31), HI); |
| 6360 __ sub(shift, shift, Operand(32), HI); | 6361 __ sub(shift, shift, Operand(32), HI); |
| 6361 | 6362 |
| 6362 __ rsb(IP, shift, Operand(32)); | 6363 __ rsb(IP, shift, Operand(32)); |
| 6363 __ mov(IP, Operand(out_hi, LSL, IP)); | 6364 __ mov(IP, Operand(out_hi, LSL, IP)); |
| 6364 __ orr(out_lo, IP, Operand(out_lo, LSR, shift)); | 6365 __ orr(out_lo, IP, Operand(out_lo, LSR, shift)); |
| 6365 __ Asr(out_hi, out_hi, shift); | 6366 __ Asr(out_hi, out_hi, shift); |
| 6366 break; | 6367 break; |
| 6367 } | 6368 } |
| 6368 case Token::kSHL: { | 6369 case Token::kSHL: { |
| 6369 __ rsbs(IP, shift, Operand(32)); | 6370 __ rsbs(IP, shift, Operand(32)); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6527 } else if (shift_value < 0) { | 6528 } else if (shift_value < 0) { |
| 6528 // Invalid shift value. | 6529 // Invalid shift value. |
| 6529 __ b(deopt); | 6530 __ b(deopt); |
| 6530 } else if (shift_value > kShifterLimit) { | 6531 } else if (shift_value > kShifterLimit) { |
| 6531 // Result is 0. | 6532 // Result is 0. |
| 6532 __ eor(out, out, Operand(out)); | 6533 __ eor(out, out, Operand(out)); |
| 6533 } else { | 6534 } else { |
| 6534 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). | 6535 // Do the shift: (shift_value > 0) && (shift_value <= kShifterLimit). |
| 6535 switch (op_kind()) { | 6536 switch (op_kind()) { |
| 6536 case Token::kSHR: | 6537 case Token::kSHR: |
| 6537 __ Lsr(out, left, shift_value); | 6538 __ Lsr(out, left, Operand(shift_value)); |
| 6538 break; | 6539 break; |
| 6539 case Token::kSHL: | 6540 case Token::kSHL: |
| 6540 __ Lsl(out, left, shift_value); | 6541 __ Lsl(out, left, Operand(shift_value)); |
| 6541 break; | 6542 break; |
| 6542 default: | 6543 default: |
| 6543 UNREACHABLE(); | 6544 UNREACHABLE(); |
| 6544 } | 6545 } |
| 6545 } | 6546 } |
| 6546 return; | 6547 return; |
| 6547 } | 6548 } |
| 6548 | 6549 |
| 6549 // Non constant shift value. | 6550 // Non constant shift value. |
| 6550 | |
| 6551 Register shifter = locs()->in(1).reg(); | 6551 Register shifter = locs()->in(1).reg(); |
| 6552 | 6552 |
| 6553 __ mov(temp, Operand(shifter)); | 6553 __ mov(temp, Operand(shifter)); |
| 6554 __ SmiUntag(temp); | 6554 __ SmiUntag(temp); |
| 6555 __ CompareImmediate(temp, 0); | 6555 __ CompareImmediate(temp, 0); |
| 6556 // If shift value is < 0, deoptimize. | 6556 // If shift value is < 0, deoptimize. |
| 6557 __ b(deopt, LT); | 6557 __ b(deopt, LT); |
| 6558 __ CompareImmediate(temp, kShifterLimit); | 6558 __ CompareImmediate(temp, kShifterLimit); |
| 6559 // > kShifterLimit, result is 0. | 6559 // > kShifterLimit, result is 0. |
| 6560 __ eor(out, out, Operand(out), HI); | 6560 __ eor(out, out, Operand(out), HI); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6634 __ TestImmediate(value, 0xC0000000); | 6634 __ TestImmediate(value, 0xC0000000); |
| 6635 } | 6635 } |
| 6636 __ b(&done, EQ); | 6636 __ b(&done, EQ); |
| 6637 BoxAllocationSlowPath::Allocate( | 6637 BoxAllocationSlowPath::Allocate( |
| 6638 compiler, | 6638 compiler, |
| 6639 this, | 6639 this, |
| 6640 compiler->mint_class(), | 6640 compiler->mint_class(), |
| 6641 out, | 6641 out, |
| 6642 temp); | 6642 temp); |
| 6643 if (from_representation() == kUnboxedInt32) { | 6643 if (from_representation() == kUnboxedInt32) { |
| 6644 __ Asr(temp, value, kBitsPerWord - 1); | 6644 __ Asr(temp, value, Operand(kBitsPerWord - 1)); |
| 6645 } else { | 6645 } else { |
| 6646 ASSERT(from_representation() == kUnboxedUint32); | 6646 ASSERT(from_representation() == kUnboxedUint32); |
| 6647 __ eor(temp, temp, Operand(temp)); | 6647 __ eor(temp, temp, Operand(temp)); |
| 6648 } | 6648 } |
| 6649 __ StoreToOffset(kWord, | 6649 __ StoreToOffset(kWord, |
| 6650 value, | 6650 value, |
| 6651 out, | 6651 out, |
| 6652 Mint::value_offset() - kHeapObjectTag); | 6652 Mint::value_offset() - kHeapObjectTag); |
| 6653 __ StoreToOffset(kWord, | 6653 __ StoreToOffset(kWord, |
| 6654 temp, | 6654 temp, |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7005 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 7005 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 7006 #if defined(DEBUG) | 7006 #if defined(DEBUG) |
| 7007 __ LoadImmediate(R4, kInvalidObjectPointer); | 7007 __ LoadImmediate(R4, kInvalidObjectPointer); |
| 7008 __ LoadImmediate(R5, kInvalidObjectPointer); | 7008 __ LoadImmediate(R5, kInvalidObjectPointer); |
| 7009 #endif | 7009 #endif |
| 7010 } | 7010 } |
| 7011 | 7011 |
| 7012 } // namespace dart | 7012 } // namespace dart |
| 7013 | 7013 |
| 7014 #endif // defined TARGET_ARCH_ARM | 7014 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |