OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1879 __ j(cc, chunk_->GetAssemblyLabel(left_block)); | 1879 __ j(cc, chunk_->GetAssemblyLabel(left_block)); |
1880 } else { | 1880 } else { |
1881 __ j(cc, chunk_->GetAssemblyLabel(left_block)); | 1881 __ j(cc, chunk_->GetAssemblyLabel(left_block)); |
1882 if (cc != always) { | 1882 if (cc != always) { |
1883 __ jmp(chunk_->GetAssemblyLabel(right_block)); | 1883 __ jmp(chunk_->GetAssemblyLabel(right_block)); |
1884 } | 1884 } |
1885 } | 1885 } |
1886 } | 1886 } |
1887 | 1887 |
1888 | 1888 |
| 1889 template<class InstrType> |
| 1890 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) { |
| 1891 int false_block = instr->FalseDestination(chunk_); |
| 1892 __ j(cc, chunk_->GetAssemblyLabel(false_block)); |
| 1893 } |
| 1894 |
| 1895 |
1889 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 1896 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
1890 __ int3(); | 1897 __ int3(); |
1891 } | 1898 } |
1892 | 1899 |
1893 | 1900 |
1894 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { | 1901 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { |
1895 Representation r = instr->hydrogen()->value()->representation(); | 1902 Representation r = instr->hydrogen()->value()->representation(); |
1896 if (r.IsSmiOrInteger32() || r.IsDouble()) { | 1903 if (r.IsSmiOrInteger32() || r.IsDouble()) { |
1897 EmitBranch(instr, no_condition); | 1904 EmitBranch(instr, no_condition); |
1898 } else { | 1905 } else { |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2152 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); | 2159 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); |
2153 __ CmpObject(left, right); | 2160 __ CmpObject(left, right); |
2154 } else { | 2161 } else { |
2155 Register right = ToRegister(instr->right()); | 2162 Register right = ToRegister(instr->right()); |
2156 __ cmpq(left, right); | 2163 __ cmpq(left, right); |
2157 } | 2164 } |
2158 EmitBranch(instr, equal); | 2165 EmitBranch(instr, equal); |
2159 } | 2166 } |
2160 | 2167 |
2161 | 2168 |
| 2169 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { |
| 2170 if (instr->hydrogen()->representation().IsTagged()) { |
| 2171 Register input_reg = ToRegister(instr->object()); |
| 2172 __ Cmp(input_reg, factory()->the_hole_value()); |
| 2173 EmitBranch(instr, equal); |
| 2174 return; |
| 2175 } |
| 2176 |
| 2177 XMMRegister input_reg = ToDoubleRegister(instr->object()); |
| 2178 __ ucomisd(input_reg, input_reg); |
| 2179 EmitFalseBranch(instr, parity_odd); |
| 2180 |
| 2181 __ subq(rsp, Immediate(kDoubleSize)); |
| 2182 __ movsd(MemOperand(rsp, 0), input_reg); |
| 2183 __ addq(rsp, Immediate(kDoubleSize)); |
| 2184 |
| 2185 int size = sizeof(kHoleNanUpper32); |
| 2186 __ cmpl(MemOperand(rsp, -size), |
| 2187 Immediate(kHoleNanUpper32)); |
| 2188 EmitBranch(instr, equal); |
| 2189 } |
| 2190 |
| 2191 |
2162 Condition LCodeGen::EmitIsObject(Register input, | 2192 Condition LCodeGen::EmitIsObject(Register input, |
2163 Label* is_not_object, | 2193 Label* is_not_object, |
2164 Label* is_object) { | 2194 Label* is_object) { |
2165 ASSERT(!input.is(kScratchRegister)); | 2195 ASSERT(!input.is(kScratchRegister)); |
2166 | 2196 |
2167 __ JumpIfSmi(input, is_not_object); | 2197 __ JumpIfSmi(input, is_not_object); |
2168 | 2198 |
2169 __ CompareRoot(input, Heap::kNullValueRootIndex); | 2199 __ CompareRoot(input, Heap::kNullValueRootIndex); |
2170 __ j(equal, is_object); | 2200 __ j(equal, is_object); |
2171 | 2201 |
(...skipping 2430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4602 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } | 4632 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } |
4603 virtual LInstruction* instr() { return instr_; } | 4633 virtual LInstruction* instr() { return instr_; } |
4604 private: | 4634 private: |
4605 LNumberTagD* instr_; | 4635 LNumberTagD* instr_; |
4606 }; | 4636 }; |
4607 | 4637 |
4608 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4638 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
4609 Register reg = ToRegister(instr->result()); | 4639 Register reg = ToRegister(instr->result()); |
4610 Register tmp = ToRegister(instr->temp()); | 4640 Register tmp = ToRegister(instr->temp()); |
4611 | 4641 |
4612 bool convert_hole = false; | |
4613 HValue* change_input = instr->hydrogen()->value(); | |
4614 if (change_input->IsLoadKeyed()) { | |
4615 HLoadKeyed* load = HLoadKeyed::cast(change_input); | |
4616 convert_hole = load->UsesMustHandleHole(); | |
4617 } | |
4618 | |
4619 Label no_special_nan_handling; | |
4620 Label done; | |
4621 if (convert_hole) { | |
4622 XMMRegister input_reg = ToDoubleRegister(instr->value()); | |
4623 __ ucomisd(input_reg, input_reg); | |
4624 __ j(parity_odd, &no_special_nan_handling); | |
4625 __ subq(rsp, Immediate(kDoubleSize)); | |
4626 __ movsd(MemOperand(rsp, 0), input_reg); | |
4627 __ cmpl(MemOperand(rsp, sizeof(kHoleNanLower32)), | |
4628 Immediate(kHoleNanUpper32)); | |
4629 Label canonicalize; | |
4630 __ j(not_equal, &canonicalize); | |
4631 __ addq(rsp, Immediate(kDoubleSize)); | |
4632 __ Move(reg, factory()->the_hole_value()); | |
4633 __ jmp(&done); | |
4634 __ bind(&canonicalize); | |
4635 __ addq(rsp, Immediate(kDoubleSize)); | |
4636 __ Set(kScratchRegister, BitCast<uint64_t>( | |
4637 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | |
4638 __ movq(input_reg, kScratchRegister); | |
4639 } | |
4640 | |
4641 __ bind(&no_special_nan_handling); | |
4642 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); | 4642 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); |
4643 if (FLAG_inline_new) { | 4643 if (FLAG_inline_new) { |
4644 __ AllocateHeapNumber(reg, tmp, deferred->entry()); | 4644 __ AllocateHeapNumber(reg, tmp, deferred->entry()); |
4645 } else { | 4645 } else { |
4646 __ jmp(deferred->entry()); | 4646 __ jmp(deferred->entry()); |
4647 } | 4647 } |
4648 __ bind(deferred->exit()); | 4648 __ bind(deferred->exit()); |
4649 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); | 4649 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); |
4650 | |
4651 __ bind(&done); | |
4652 } | 4650 } |
4653 | 4651 |
4654 | 4652 |
4655 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 4653 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
4656 // TODO(3095996): Get rid of this. For now, we need to make the | 4654 // TODO(3095996): Get rid of this. For now, we need to make the |
4657 // result register contain a valid pointer because it is already | 4655 // result register contain a valid pointer because it is already |
4658 // contained in the register pointer map. | 4656 // contained in the register pointer map. |
4659 Register reg = ToRegister(instr->result()); | 4657 Register reg = ToRegister(instr->result()); |
4660 __ Move(reg, Smi::FromInt(0)); | 4658 __ Move(reg, Smi::FromInt(0)); |
4661 | 4659 |
(...skipping 23 matching lines...) Expand all Loading... |
4685 DeoptimizeIf(NegateCondition(is_smi), instr->environment()); | 4683 DeoptimizeIf(NegateCondition(is_smi), instr->environment()); |
4686 } else { | 4684 } else { |
4687 __ AssertSmi(input); | 4685 __ AssertSmi(input); |
4688 } | 4686 } |
4689 __ SmiToInteger32(input, input); | 4687 __ SmiToInteger32(input, input); |
4690 } | 4688 } |
4691 | 4689 |
4692 | 4690 |
4693 void LCodeGen::EmitNumberUntagD(Register input_reg, | 4691 void LCodeGen::EmitNumberUntagD(Register input_reg, |
4694 XMMRegister result_reg, | 4692 XMMRegister result_reg, |
4695 bool allow_undefined_as_nan, | 4693 bool can_convert_undefined_to_nan, |
4696 bool deoptimize_on_minus_zero, | 4694 bool deoptimize_on_minus_zero, |
4697 LEnvironment* env, | 4695 LEnvironment* env, |
4698 NumberUntagDMode mode) { | 4696 NumberUntagDMode mode) { |
4699 Label load_smi, done; | 4697 Label load_smi, done; |
4700 | 4698 |
4701 STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE > | 4699 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
4702 NUMBER_CANDIDATE_IS_ANY_TAGGED); | |
4703 if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) { | |
4704 // Smi check. | 4700 // Smi check. |
4705 __ JumpIfSmi(input_reg, &load_smi, Label::kNear); | 4701 __ JumpIfSmi(input_reg, &load_smi, Label::kNear); |
4706 | 4702 |
4707 // Heap number map check. | 4703 // Heap number map check. |
4708 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), | 4704 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
4709 Heap::kHeapNumberMapRootIndex); | 4705 Heap::kHeapNumberMapRootIndex); |
4710 if (!allow_undefined_as_nan) { | 4706 if (!can_convert_undefined_to_nan) { |
4711 DeoptimizeIf(not_equal, env); | 4707 DeoptimizeIf(not_equal, env); |
4712 } else { | 4708 } else { |
4713 Label heap_number, convert; | 4709 Label heap_number, convert; |
4714 __ j(equal, &heap_number, Label::kNear); | 4710 __ j(equal, &heap_number, Label::kNear); |
4715 | 4711 |
4716 // Convert undefined (and hole) to NaN. Compute NaN as 0/0. | 4712 // Convert undefined (and hole) to NaN. Compute NaN as 0/0. |
4717 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); | 4713 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); |
4718 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) { | |
4719 __ j(equal, &convert, Label::kNear); | |
4720 __ CompareRoot(input_reg, Heap::kTheHoleValueRootIndex); | |
4721 } | |
4722 DeoptimizeIf(not_equal, env); | 4714 DeoptimizeIf(not_equal, env); |
4723 | 4715 |
4724 __ bind(&convert); | 4716 __ bind(&convert); |
4725 __ xorps(result_reg, result_reg); | 4717 __ xorps(result_reg, result_reg); |
4726 __ divsd(result_reg, result_reg); | 4718 __ divsd(result_reg, result_reg); |
4727 __ jmp(&done, Label::kNear); | 4719 __ jmp(&done, Label::kNear); |
4728 | 4720 |
4729 __ bind(&heap_number); | 4721 __ bind(&heap_number); |
4730 } | 4722 } |
4731 // Heap number to XMM conversion. | 4723 // Heap number to XMM conversion. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4824 | 4816 |
4825 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { | 4817 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { |
4826 LOperand* input = instr->value(); | 4818 LOperand* input = instr->value(); |
4827 ASSERT(input->IsRegister()); | 4819 ASSERT(input->IsRegister()); |
4828 LOperand* result = instr->result(); | 4820 LOperand* result = instr->result(); |
4829 ASSERT(result->IsDoubleRegister()); | 4821 ASSERT(result->IsDoubleRegister()); |
4830 | 4822 |
4831 Register input_reg = ToRegister(input); | 4823 Register input_reg = ToRegister(input); |
4832 XMMRegister result_reg = ToDoubleRegister(result); | 4824 XMMRegister result_reg = ToDoubleRegister(result); |
4833 | 4825 |
4834 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED; | |
4835 HValue* value = instr->hydrogen()->value(); | 4826 HValue* value = instr->hydrogen()->value(); |
4836 if (value->type().IsSmi()) { | 4827 NumberUntagDMode mode = value->representation().IsSmi() |
4837 mode = NUMBER_CANDIDATE_IS_SMI; | 4828 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; |
4838 } else if (value->IsLoadKeyed()) { | |
4839 HLoadKeyed* load = HLoadKeyed::cast(value); | |
4840 if (load->UsesMustHandleHole()) { | |
4841 mode = NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE; | |
4842 } | |
4843 } | |
4844 | 4829 |
4845 EmitNumberUntagD(input_reg, result_reg, | 4830 EmitNumberUntagD(input_reg, result_reg, |
4846 instr->hydrogen()->allow_undefined_as_nan(), | 4831 instr->hydrogen()->can_convert_undefined_to_nan(), |
4847 instr->hydrogen()->deoptimize_on_minus_zero(), | 4832 instr->hydrogen()->deoptimize_on_minus_zero(), |
4848 instr->environment(), | 4833 instr->environment(), |
4849 mode); | 4834 mode); |
4850 } | 4835 } |
4851 | 4836 |
4852 | 4837 |
4853 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 4838 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
4854 LOperand* input = instr->value(); | 4839 LOperand* input = instr->value(); |
4855 ASSERT(input->IsDoubleRegister()); | 4840 ASSERT(input->IsDoubleRegister()); |
4856 LOperand* result = instr->result(); | 4841 LOperand* result = instr->result(); |
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5617 FixedArray::kHeaderSize - kPointerSize)); | 5602 FixedArray::kHeaderSize - kPointerSize)); |
5618 __ bind(&done); | 5603 __ bind(&done); |
5619 } | 5604 } |
5620 | 5605 |
5621 | 5606 |
5622 #undef __ | 5607 #undef __ |
5623 | 5608 |
5624 } } // namespace v8::internal | 5609 } } // namespace v8::internal |
5625 | 5610 |
5626 #endif // V8_TARGET_ARCH_X64 | 5611 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |