| 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 |