OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/arm64/lithium-codegen-arm64.h" | 7 #include "src/arm64/lithium-codegen-arm64.h" |
8 #include "src/arm64/lithium-gap-resolver-arm64.h" | 8 #include "src/arm64/lithium-gap-resolver-arm64.h" |
| 9 #include "src/base/bits.h" |
9 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
10 #include "src/hydrogen-osr.h" | 11 #include "src/hydrogen-osr.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 | 15 |
15 | 16 |
16 class SafepointGenerator FINAL : public CallWrapper { | 17 class SafepointGenerator FINAL : public CallWrapper { |
17 public: | 18 public: |
18 SafepointGenerator(LCodeGen* codegen, | 19 SafepointGenerator(LCodeGen* codegen, |
(...skipping 2210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2229 // If we are below the lower bound, set the C flag and clear the Z flag | 2230 // If we are below the lower bound, set the C flag and clear the Z flag |
2230 // to force a deopt. | 2231 // to force a deopt. |
2231 __ Ccmp(scratch, last, CFlag, hs); | 2232 __ Ccmp(scratch, last, CFlag, hs); |
2232 DeoptimizeIf(hi, instr->environment()); | 2233 DeoptimizeIf(hi, instr->environment()); |
2233 } | 2234 } |
2234 } else { | 2235 } else { |
2235 uint8_t mask; | 2236 uint8_t mask; |
2236 uint8_t tag; | 2237 uint8_t tag; |
2237 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); | 2238 instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); |
2238 | 2239 |
2239 if (IsPowerOf2(mask)) { | 2240 if (base::bits::IsPowerOfTwo32(mask)) { |
2240 DCHECK((tag == 0) || (tag == mask)); | 2241 DCHECK((tag == 0) || (tag == mask)); |
2241 if (tag == 0) { | 2242 if (tag == 0) { |
2242 DeoptimizeIfBitSet(scratch, MaskToBit(mask), instr->environment()); | 2243 DeoptimizeIfBitSet(scratch, MaskToBit(mask), instr->environment()); |
2243 } else { | 2244 } else { |
2244 DeoptimizeIfBitClear(scratch, MaskToBit(mask), instr->environment()); | 2245 DeoptimizeIfBitClear(scratch, MaskToBit(mask), instr->environment()); |
2245 } | 2246 } |
2246 } else { | 2247 } else { |
2247 if (tag == 0) { | 2248 if (tag == 0) { |
2248 __ Tst(scratch, mask); | 2249 __ Tst(scratch, mask); |
2249 } else { | 2250 } else { |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2662 | 2663 |
2663 Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); | 2664 Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); |
2664 Deoptimize(instr->environment(), &type); | 2665 Deoptimize(instr->environment(), &type); |
2665 } | 2666 } |
2666 | 2667 |
2667 | 2668 |
2668 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { | 2669 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { |
2669 Register dividend = ToRegister32(instr->dividend()); | 2670 Register dividend = ToRegister32(instr->dividend()); |
2670 int32_t divisor = instr->divisor(); | 2671 int32_t divisor = instr->divisor(); |
2671 Register result = ToRegister32(instr->result()); | 2672 Register result = ToRegister32(instr->result()); |
2672 DCHECK(divisor == kMinInt || IsPowerOf2(Abs(divisor))); | 2673 DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); |
2673 DCHECK(!result.is(dividend)); | 2674 DCHECK(!result.is(dividend)); |
2674 | 2675 |
2675 // Check for (0 / -x) that will produce negative zero. | 2676 // Check for (0 / -x) that will produce negative zero. |
2676 HDiv* hdiv = instr->hydrogen(); | 2677 HDiv* hdiv = instr->hydrogen(); |
2677 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { | 2678 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { |
2678 DeoptimizeIfZero(dividend, instr->environment()); | 2679 DeoptimizeIfZero(dividend, instr->environment()); |
2679 } | 2680 } |
2680 // Check for (kMinInt / -1). | 2681 // Check for (kMinInt / -1). |
2681 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { | 2682 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { |
2682 // Test dividend for kMinInt by subtracting one (cmp) and checking for | 2683 // Test dividend for kMinInt by subtracting one (cmp) and checking for |
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4353 } else { | 4354 } else { |
4354 __ Add(result, left, left); | 4355 __ Add(result, left, left); |
4355 } | 4356 } |
4356 break; | 4357 break; |
4357 | 4358 |
4358 default: | 4359 default: |
4359 // Multiplication by constant powers of two (and some related values) | 4360 // Multiplication by constant powers of two (and some related values) |
4360 // can be done efficiently with shifted operands. | 4361 // can be done efficiently with shifted operands. |
4361 int32_t right_abs = Abs(right); | 4362 int32_t right_abs = Abs(right); |
4362 | 4363 |
4363 if (IsPowerOf2(right_abs)) { | 4364 if (base::bits::IsPowerOfTwo32(right_abs)) { |
4364 int right_log2 = WhichPowerOf2(right_abs); | 4365 int right_log2 = WhichPowerOf2(right_abs); |
4365 | 4366 |
4366 if (can_overflow) { | 4367 if (can_overflow) { |
4367 Register scratch = result; | 4368 Register scratch = result; |
4368 DCHECK(!AreAliased(scratch, left)); | 4369 DCHECK(!AreAliased(scratch, left)); |
4369 __ Cls(scratch, left); | 4370 __ Cls(scratch, left); |
4370 __ Cmp(scratch, right_log2); | 4371 __ Cmp(scratch, right_log2); |
4371 DeoptimizeIf(lt, instr->environment()); | 4372 DeoptimizeIf(lt, instr->environment()); |
4372 } | 4373 } |
4373 | 4374 |
(...skipping 12 matching lines...) Expand all Loading... |
4386 return; | 4387 return; |
4387 } | 4388 } |
4388 | 4389 |
4389 | 4390 |
4390 // For the following cases, we could perform a conservative overflow check | 4391 // For the following cases, we could perform a conservative overflow check |
4391 // with CLS as above. However the few cycles saved are likely not worth | 4392 // with CLS as above. However the few cycles saved are likely not worth |
4392 // the risk of deoptimizing more often than required. | 4393 // the risk of deoptimizing more often than required. |
4393 DCHECK(!can_overflow); | 4394 DCHECK(!can_overflow); |
4394 | 4395 |
4395 if (right >= 0) { | 4396 if (right >= 0) { |
4396 if (IsPowerOf2(right - 1)) { | 4397 if (base::bits::IsPowerOfTwo32(right - 1)) { |
4397 // result = left + left << log2(right - 1) | 4398 // result = left + left << log2(right - 1) |
4398 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1))); | 4399 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1))); |
4399 } else if (IsPowerOf2(right + 1)) { | 4400 } else if (base::bits::IsPowerOfTwo32(right + 1)) { |
4400 // result = -left + left << log2(right + 1) | 4401 // result = -left + left << log2(right + 1) |
4401 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(right + 1))); | 4402 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(right + 1))); |
4402 __ Neg(result, result); | 4403 __ Neg(result, result); |
4403 } else { | 4404 } else { |
4404 UNREACHABLE(); | 4405 UNREACHABLE(); |
4405 } | 4406 } |
4406 } else { | 4407 } else { |
4407 if (IsPowerOf2(-right + 1)) { | 4408 if (base::bits::IsPowerOfTwo32(-right + 1)) { |
4408 // result = left - left << log2(-right + 1) | 4409 // result = left - left << log2(-right + 1) |
4409 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1))); | 4410 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1))); |
4410 } else if (IsPowerOf2(-right - 1)) { | 4411 } else if (base::bits::IsPowerOfTwo32(-right - 1)) { |
4411 // result = -left - left << log2(-right - 1) | 4412 // result = -left - left << log2(-right - 1) |
4412 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(-right - 1))); | 4413 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(-right - 1))); |
4413 __ Neg(result, result); | 4414 __ Neg(result, result); |
4414 } else { | 4415 } else { |
4415 UNREACHABLE(); | 4416 UNREACHABLE(); |
4416 } | 4417 } |
4417 } | 4418 } |
4418 } | 4419 } |
4419 } | 4420 } |
4420 | 4421 |
(...skipping 1600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6021 Handle<ScopeInfo> scope_info = instr->scope_info(); | 6022 Handle<ScopeInfo> scope_info = instr->scope_info(); |
6022 __ Push(scope_info); | 6023 __ Push(scope_info); |
6023 __ Push(ToRegister(instr->function())); | 6024 __ Push(ToRegister(instr->function())); |
6024 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6025 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
6025 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6026 RecordSafepoint(Safepoint::kNoLazyDeopt); |
6026 } | 6027 } |
6027 | 6028 |
6028 | 6029 |
6029 | 6030 |
6030 } } // namespace v8::internal | 6031 } } // namespace v8::internal |
OLD | NEW |