Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 22152003: Never hchange nan-hole to hole or hole to nan-hole. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Also change in header Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698