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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/crankshaft/x64/lithium-codegen-x64.h" | 7 #include "src/crankshaft/x64/lithium-codegen-x64.h" |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1965 } else { | 1965 } else { |
1966 DCHECK(r.IsTagged()); | 1966 DCHECK(r.IsTagged()); |
1967 Register reg = ToRegister(instr->value()); | 1967 Register reg = ToRegister(instr->value()); |
1968 HType type = instr->hydrogen()->value()->type(); | 1968 HType type = instr->hydrogen()->value()->type(); |
1969 if (type.IsBoolean()) { | 1969 if (type.IsBoolean()) { |
1970 DCHECK(!info()->IsStub()); | 1970 DCHECK(!info()->IsStub()); |
1971 __ CompareRoot(reg, Heap::kTrueValueRootIndex); | 1971 __ CompareRoot(reg, Heap::kTrueValueRootIndex); |
1972 EmitBranch(instr, equal); | 1972 EmitBranch(instr, equal); |
1973 } else if (type.IsSmi()) { | 1973 } else if (type.IsSmi()) { |
1974 DCHECK(!info()->IsStub()); | 1974 DCHECK(!info()->IsStub()); |
1975 __ SmiCompare(reg, Smi::kZero); | 1975 __ SmiCompare(reg, Smi::FromInt(0)); |
1976 EmitBranch(instr, not_equal); | 1976 EmitBranch(instr, not_equal); |
1977 } else if (type.IsJSArray()) { | 1977 } else if (type.IsJSArray()) { |
1978 DCHECK(!info()->IsStub()); | 1978 DCHECK(!info()->IsStub()); |
1979 EmitBranch(instr, no_condition); | 1979 EmitBranch(instr, no_condition); |
1980 } else if (type.IsHeapNumber()) { | 1980 } else if (type.IsHeapNumber()) { |
1981 DCHECK(!info()->IsStub()); | 1981 DCHECK(!info()->IsStub()); |
1982 XMMRegister xmm_scratch = double_scratch0(); | 1982 XMMRegister xmm_scratch = double_scratch0(); |
1983 __ Xorpd(xmm_scratch, xmm_scratch); | 1983 __ Xorpd(xmm_scratch, xmm_scratch); |
1984 __ Ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); | 1984 __ Ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); |
1985 EmitBranch(instr, not_equal); | 1985 EmitBranch(instr, not_equal); |
(...skipping 21 matching lines...) Expand all Loading... |
2007 __ j(equal, instr->FalseLabel(chunk_)); | 2007 __ j(equal, instr->FalseLabel(chunk_)); |
2008 } | 2008 } |
2009 if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { | 2009 if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { |
2010 // 'null' -> false. | 2010 // 'null' -> false. |
2011 __ CompareRoot(reg, Heap::kNullValueRootIndex); | 2011 __ CompareRoot(reg, Heap::kNullValueRootIndex); |
2012 __ j(equal, instr->FalseLabel(chunk_)); | 2012 __ j(equal, instr->FalseLabel(chunk_)); |
2013 } | 2013 } |
2014 | 2014 |
2015 if (expected.Contains(ToBooleanICStub::SMI)) { | 2015 if (expected.Contains(ToBooleanICStub::SMI)) { |
2016 // Smis: 0 -> false, all other -> true. | 2016 // Smis: 0 -> false, all other -> true. |
2017 __ Cmp(reg, Smi::kZero); | 2017 __ Cmp(reg, Smi::FromInt(0)); |
2018 __ j(equal, instr->FalseLabel(chunk_)); | 2018 __ j(equal, instr->FalseLabel(chunk_)); |
2019 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | 2019 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); |
2020 } else if (expected.NeedsMap()) { | 2020 } else if (expected.NeedsMap()) { |
2021 // If we need a map later and have a Smi -> deopt. | 2021 // If we need a map later and have a Smi -> deopt. |
2022 __ testb(reg, Immediate(kSmiTagMask)); | 2022 __ testb(reg, Immediate(kSmiTagMask)); |
2023 DeoptimizeIf(zero, instr, DeoptimizeReason::kSmi); | 2023 DeoptimizeIf(zero, instr, DeoptimizeReason::kSmi); |
2024 } | 2024 } |
2025 | 2025 |
2026 const Register map = kScratchRegister; | 2026 const Register map = kScratchRegister; |
2027 if (expected.NeedsMap()) { | 2027 if (expected.NeedsMap()) { |
(...skipping 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4154 | 4154 |
4155 __ bind(deferred->exit()); | 4155 __ bind(deferred->exit()); |
4156 } | 4156 } |
4157 | 4157 |
4158 | 4158 |
4159 void LCodeGen::DoDeferredMaybeGrowElements(LMaybeGrowElements* instr) { | 4159 void LCodeGen::DoDeferredMaybeGrowElements(LMaybeGrowElements* instr) { |
4160 // TODO(3095996): Get rid of this. For now, we need to make the | 4160 // TODO(3095996): Get rid of this. For now, we need to make the |
4161 // result register contain a valid pointer because it is already | 4161 // result register contain a valid pointer because it is already |
4162 // contained in the register pointer map. | 4162 // contained in the register pointer map. |
4163 Register result = rax; | 4163 Register result = rax; |
4164 __ Move(result, Smi::kZero); | 4164 __ Move(result, Smi::FromInt(0)); |
4165 | 4165 |
4166 // We have to call a stub. | 4166 // We have to call a stub. |
4167 { | 4167 { |
4168 PushSafepointRegistersScope scope(this); | 4168 PushSafepointRegistersScope scope(this); |
4169 if (instr->object()->IsConstantOperand()) { | 4169 if (instr->object()->IsConstantOperand()) { |
4170 LConstantOperand* constant_object = | 4170 LConstantOperand* constant_object = |
4171 LConstantOperand::cast(instr->object()); | 4171 LConstantOperand::cast(instr->object()); |
4172 if (IsSmiConstant(constant_object)) { | 4172 if (IsSmiConstant(constant_object)) { |
4173 Smi* immediate = ToSmi(constant_object); | 4173 Smi* immediate = ToSmi(constant_object); |
4174 __ Move(result, immediate); | 4174 __ Move(result, immediate); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4523 __ bind(deferred->exit()); | 4523 __ bind(deferred->exit()); |
4524 __ Movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); | 4524 __ Movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); |
4525 } | 4525 } |
4526 | 4526 |
4527 | 4527 |
4528 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 4528 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
4529 // TODO(3095996): Get rid of this. For now, we need to make the | 4529 // TODO(3095996): Get rid of this. For now, we need to make the |
4530 // result register contain a valid pointer because it is already | 4530 // result register contain a valid pointer because it is already |
4531 // contained in the register pointer map. | 4531 // contained in the register pointer map. |
4532 Register reg = ToRegister(instr->result()); | 4532 Register reg = ToRegister(instr->result()); |
4533 __ Move(reg, Smi::kZero); | 4533 __ Move(reg, Smi::FromInt(0)); |
4534 | 4534 |
4535 { | 4535 { |
4536 PushSafepointRegistersScope scope(this); | 4536 PushSafepointRegistersScope scope(this); |
4537 // Reset the context register. | 4537 // Reset the context register. |
4538 if (!reg.is(rsi)) { | 4538 if (!reg.is(rsi)) { |
4539 __ Move(rsi, 0); | 4539 __ Move(rsi, 0); |
4540 } | 4540 } |
4541 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4541 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
4542 RecordSafepointWithRegisters( | 4542 RecordSafepointWithRegisters( |
4543 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4543 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5087 __ FastAllocate(size, result, temp, flags); | 5087 __ FastAllocate(size, result, temp, flags); |
5088 } | 5088 } |
5089 } | 5089 } |
5090 | 5090 |
5091 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { | 5091 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { |
5092 Register result = ToRegister(instr->result()); | 5092 Register result = ToRegister(instr->result()); |
5093 | 5093 |
5094 // TODO(3095996): Get rid of this. For now, we need to make the | 5094 // TODO(3095996): Get rid of this. For now, we need to make the |
5095 // result register contain a valid pointer because it is already | 5095 // result register contain a valid pointer because it is already |
5096 // contained in the register pointer map. | 5096 // contained in the register pointer map. |
5097 __ Move(result, Smi::kZero); | 5097 __ Move(result, Smi::FromInt(0)); |
5098 | 5098 |
5099 PushSafepointRegistersScope scope(this); | 5099 PushSafepointRegistersScope scope(this); |
5100 if (instr->size()->IsRegister()) { | 5100 if (instr->size()->IsRegister()) { |
5101 Register size = ToRegister(instr->size()); | 5101 Register size = ToRegister(instr->size()); |
5102 DCHECK(!size.is(result)); | 5102 DCHECK(!size.is(result)); |
5103 __ Integer32ToSmi(size, size); | 5103 __ Integer32ToSmi(size, size); |
5104 __ Push(size); | 5104 __ Push(size); |
5105 } else { | 5105 } else { |
5106 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 5106 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
5107 __ Push(Smi::FromInt(size)); | 5107 __ Push(Smi::FromInt(size)); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5395 CallRuntime(Runtime::kForInEnumerate, instr); | 5395 CallRuntime(Runtime::kForInEnumerate, instr); |
5396 __ bind(&use_cache); | 5396 __ bind(&use_cache); |
5397 } | 5397 } |
5398 | 5398 |
5399 | 5399 |
5400 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { | 5400 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { |
5401 Register map = ToRegister(instr->map()); | 5401 Register map = ToRegister(instr->map()); |
5402 Register result = ToRegister(instr->result()); | 5402 Register result = ToRegister(instr->result()); |
5403 Label load_cache, done; | 5403 Label load_cache, done; |
5404 __ EnumLength(result, map); | 5404 __ EnumLength(result, map); |
5405 __ Cmp(result, Smi::kZero); | 5405 __ Cmp(result, Smi::FromInt(0)); |
5406 __ j(not_equal, &load_cache, Label::kNear); | 5406 __ j(not_equal, &load_cache, Label::kNear); |
5407 __ LoadRoot(result, Heap::kEmptyFixedArrayRootIndex); | 5407 __ LoadRoot(result, Heap::kEmptyFixedArrayRootIndex); |
5408 __ jmp(&done, Label::kNear); | 5408 __ jmp(&done, Label::kNear); |
5409 __ bind(&load_cache); | 5409 __ bind(&load_cache); |
5410 __ LoadInstanceDescriptors(map, result); | 5410 __ LoadInstanceDescriptors(map, result); |
5411 __ movp(result, | 5411 __ movp(result, |
5412 FieldOperand(result, DescriptorArray::kEnumCacheOffset)); | 5412 FieldOperand(result, DescriptorArray::kEnumCacheOffset)); |
5413 __ movp(result, | 5413 __ movp(result, |
5414 FieldOperand(result, FixedArray::SizeFor(instr->idx()))); | 5414 FieldOperand(result, FixedArray::SizeFor(instr->idx()))); |
5415 __ bind(&done); | 5415 __ bind(&done); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5496 __ bind(deferred->exit()); | 5496 __ bind(deferred->exit()); |
5497 __ bind(&done); | 5497 __ bind(&done); |
5498 } | 5498 } |
5499 | 5499 |
5500 #undef __ | 5500 #undef __ |
5501 | 5501 |
5502 } // namespace internal | 5502 } // namespace internal |
5503 } // namespace v8 | 5503 } // namespace v8 |
5504 | 5504 |
5505 #endif // V8_TARGET_ARCH_X64 | 5505 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |