Chromium Code Reviews

Side by Side Diff: src/arm/lithium-codegen-arm.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: Port to ARM / x64 Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/hydrogen.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2139 matching lines...)
2150 __ b(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block)); 2150 __ b(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block));
2151 } else if (right_block == next_block) { 2151 } else if (right_block == next_block) {
2152 __ b(cc, chunk_->GetAssemblyLabel(left_block)); 2152 __ b(cc, chunk_->GetAssemblyLabel(left_block));
2153 } else { 2153 } else {
2154 __ b(cc, chunk_->GetAssemblyLabel(left_block)); 2154 __ b(cc, chunk_->GetAssemblyLabel(left_block));
2155 __ b(chunk_->GetAssemblyLabel(right_block)); 2155 __ b(chunk_->GetAssemblyLabel(right_block));
2156 } 2156 }
2157 } 2157 }
2158 2158
2159 2159
2160 template<class InstrType>
2161 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
Rodolph Perfetta 2013/08/13 15:08:14 cc is actually a valid ARM condition code (carry c
Toon Verwaest 2013/08/13 15:16:50 I used the same signature as the function above (E
Rodolph Perfetta 2013/08/13 15:22:02 It would be better to change it above too. If this
2162 int false_block = instr->FalseDestination(chunk_);
2163 __ b(cc, chunk_->GetAssemblyLabel(false_block));
2164 }
2165
2166
2160 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 2167 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
2161 __ stop("LBreak"); 2168 __ stop("LBreak");
2162 } 2169 }
2163 2170
2164 2171
2165 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { 2172 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
2166 Representation r = instr->hydrogen()->value()->representation(); 2173 Representation r = instr->hydrogen()->value()->representation();
2167 if (r.IsSmiOrInteger32() || r.IsDouble()) { 2174 if (r.IsSmiOrInteger32() || r.IsDouble()) {
2168 EmitBranch(instr, al); 2175 EmitBranch(instr, al);
2169 } else { 2176 } else {
(...skipping 235 matching lines...)
2405 2412
2406 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2413 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
2407 Register left = ToRegister(instr->left()); 2414 Register left = ToRegister(instr->left());
2408 Register right = ToRegister(instr->right()); 2415 Register right = ToRegister(instr->right());
2409 2416
2410 __ cmp(left, Operand(right)); 2417 __ cmp(left, Operand(right));
2411 EmitBranch(instr, eq); 2418 EmitBranch(instr, eq);
2412 } 2419 }
2413 2420
2414 2421
2422 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2423 if (instr->hydrogen()->representation().IsTagged()) {
2424 Register input_reg = ToRegister(instr->object());
2425 Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
2426 __ mov(ip, Operand(Handle<Object>(cell)));
Rodolph Perfetta 2013/08/13 15:08:14 Shouldn't this be: mov(ip, factory()->the_hole_val
Toon Verwaest 2013/08/13 15:16:50 Makes a lot of sense. Wrongly copy pasted from bel
2427 __ cmp(input_reg, ip);
2428 EmitBranch(instr, eq);
2429 return;
2430 }
2431
2432 DwVfpRegister input_reg = ToDoubleRegister(instr->object());
2433 __ VFPCompareAndSetFlags(input_reg, input_reg);
2434 EmitFalseBranch(instr, vc);
2435
2436 Register scratch = scratch0();
2437 __ VmovHigh(scratch, input_reg);
2438 __ cmp(scratch, Operand(kHoleNanUpper32));
2439 EmitBranch(instr, eq);
2440 }
2441
2442
2415 Condition LCodeGen::EmitIsObject(Register input, 2443 Condition LCodeGen::EmitIsObject(Register input,
2416 Register temp1, 2444 Register temp1,
2417 Label* is_not_object, 2445 Label* is_not_object,
2418 Label* is_object) { 2446 Label* is_object) {
2419 Register temp2 = scratch0(); 2447 Register temp2 = scratch0();
2420 __ JumpIfSmi(input, is_not_object); 2448 __ JumpIfSmi(input, is_not_object);
2421 2449
2422 __ LoadRoot(temp2, Heap::kNullValueRootIndex); 2450 __ LoadRoot(temp2, Heap::kNullValueRootIndex);
2423 __ cmp(input, temp2); 2451 __ cmp(input, temp2);
2424 __ b(eq, is_object); 2452 __ b(eq, is_object);
(...skipping 2394 matching lines...)
4819 private: 4847 private:
4820 LNumberTagD* instr_; 4848 LNumberTagD* instr_;
4821 }; 4849 };
4822 4850
4823 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); 4851 DwVfpRegister input_reg = ToDoubleRegister(instr->value());
4824 Register scratch = scratch0(); 4852 Register scratch = scratch0();
4825 Register reg = ToRegister(instr->result()); 4853 Register reg = ToRegister(instr->result());
4826 Register temp1 = ToRegister(instr->temp()); 4854 Register temp1 = ToRegister(instr->temp());
4827 Register temp2 = ToRegister(instr->temp2()); 4855 Register temp2 = ToRegister(instr->temp2());
4828 4856
4829 bool convert_hole = false;
4830 HValue* change_input = instr->hydrogen()->value();
4831 if (change_input->IsLoadKeyed()) {
4832 HLoadKeyed* load = HLoadKeyed::cast(change_input);
4833 convert_hole = load->UsesMustHandleHole();
4834 }
4835
4836 Label no_special_nan_handling;
4837 Label done;
4838 if (convert_hole) {
4839 DwVfpRegister input_reg = ToDoubleRegister(instr->value());
4840 __ VFPCompareAndSetFlags(input_reg, input_reg);
4841 __ b(vc, &no_special_nan_handling);
4842 __ VmovHigh(scratch, input_reg);
4843 __ cmp(scratch, Operand(kHoleNanUpper32));
4844 // If not the hole NaN, force the NaN to be canonical.
4845 __ VFPCanonicalizeNaN(input_reg, ne);
4846 __ b(ne, &no_special_nan_handling);
4847 __ Move(reg, factory()->the_hole_value());
4848 __ b(&done);
4849 }
4850
4851 __ bind(&no_special_nan_handling);
4852 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4857 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4853 if (FLAG_inline_new) { 4858 if (FLAG_inline_new) {
4854 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4859 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4855 // We want the untagged address first for performance 4860 // We want the untagged address first for performance
4856 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), 4861 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
4857 DONT_TAG_RESULT); 4862 DONT_TAG_RESULT);
4858 } else { 4863 } else {
4859 __ jmp(deferred->entry()); 4864 __ jmp(deferred->entry());
4860 } 4865 }
4861 __ bind(deferred->exit()); 4866 __ bind(deferred->exit());
4862 __ vstr(input_reg, reg, HeapNumber::kValueOffset); 4867 __ vstr(input_reg, reg, HeapNumber::kValueOffset);
4863 // Now that we have finished with the object's real address tag it 4868 // Now that we have finished with the object's real address tag it
4864 __ add(reg, reg, Operand(kHeapObjectTag)); 4869 __ add(reg, reg, Operand(kHeapObjectTag));
4865 __ bind(&done);
4866 } 4870 }
4867 4871
4868 4872
4869 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4873 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4870 // TODO(3095996): Get rid of this. For now, we need to make the 4874 // TODO(3095996): Get rid of this. For now, we need to make the
4871 // result register contain a valid pointer because it is already 4875 // result register contain a valid pointer because it is already
4872 // contained in the register pointer map. 4876 // contained in the register pointer map.
4873 Register reg = ToRegister(instr->result()); 4877 Register reg = ToRegister(instr->result());
4874 __ mov(reg, Operand::Zero()); 4878 __ mov(reg, Operand::Zero());
4875 4879
(...skipping 19 matching lines...)
4895 __ SmiUntag(result, input, SetCC); 4899 __ SmiUntag(result, input, SetCC);
4896 DeoptimizeIf(cs, instr->environment()); 4900 DeoptimizeIf(cs, instr->environment());
4897 } else { 4901 } else {
4898 __ SmiUntag(result, input); 4902 __ SmiUntag(result, input);
4899 } 4903 }
4900 } 4904 }
4901 4905
4902 4906
4903 void LCodeGen::EmitNumberUntagD(Register input_reg, 4907 void LCodeGen::EmitNumberUntagD(Register input_reg,
4904 DwVfpRegister result_reg, 4908 DwVfpRegister result_reg,
4905 bool allow_undefined_as_nan, 4909 bool can_convert_undefined_to_nan,
4906 bool deoptimize_on_minus_zero, 4910 bool deoptimize_on_minus_zero,
4907 LEnvironment* env, 4911 LEnvironment* env,
4908 NumberUntagDMode mode) { 4912 NumberUntagDMode mode) {
4909 Register scratch = scratch0(); 4913 Register scratch = scratch0();
4910 SwVfpRegister flt_scratch = double_scratch0().low(); 4914 SwVfpRegister flt_scratch = double_scratch0().low();
4911 ASSERT(!result_reg.is(double_scratch0())); 4915 ASSERT(!result_reg.is(double_scratch0()));
4912 4916
4913 Label load_smi, heap_number, done; 4917 Label load_smi, heap_number, done;
4914 4918
4915 STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE > 4919 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4916 NUMBER_CANDIDATE_IS_ANY_TAGGED);
4917 if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4918 // Smi check. 4920 // Smi check.
4919 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4921 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4920 4922
4921 // Heap number map check. 4923 // Heap number map check.
4922 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4924 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4923 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4925 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4924 __ cmp(scratch, Operand(ip)); 4926 __ cmp(scratch, Operand(ip));
4925 if (!allow_undefined_as_nan) { 4927 if (!can_convert_undefined_to_nan) {
4926 DeoptimizeIf(ne, env); 4928 DeoptimizeIf(ne, env);
4927 } else { 4929 } else {
4928 Label heap_number, convert; 4930 Label heap_number, convert;
4929 __ b(eq, &heap_number); 4931 __ b(eq, &heap_number);
4930 4932
4931 // Convert undefined (and hole) to NaN. 4933 // Convert undefined (and hole) to NaN.
4932 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 4934 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
4933 __ cmp(input_reg, Operand(ip)); 4935 __ cmp(input_reg, Operand(ip));
4934 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) {
4935 __ b(eq, &convert);
4936 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
4937 __ cmp(input_reg, Operand(ip));
4938 }
4939 DeoptimizeIf(ne, env); 4936 DeoptimizeIf(ne, env);
4940 4937
4941 __ bind(&convert); 4938 __ bind(&convert);
4942 __ LoadRoot(scratch, Heap::kNanValueRootIndex); 4939 __ LoadRoot(scratch, Heap::kNanValueRootIndex);
4943 __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag); 4940 __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag);
4944 __ jmp(&done); 4941 __ jmp(&done);
4945 4942
4946 __ bind(&heap_number); 4943 __ bind(&heap_number);
4947 } 4944 }
4948 // Heap number to double register conversion. 4945 // Heap number to double register conversion.
(...skipping 120 matching lines...)
5069 5066
5070 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 5067 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5071 LOperand* input = instr->value(); 5068 LOperand* input = instr->value();
5072 ASSERT(input->IsRegister()); 5069 ASSERT(input->IsRegister());
5073 LOperand* result = instr->result(); 5070 LOperand* result = instr->result();
5074 ASSERT(result->IsDoubleRegister()); 5071 ASSERT(result->IsDoubleRegister());
5075 5072
5076 Register input_reg = ToRegister(input); 5073 Register input_reg = ToRegister(input);
5077 DwVfpRegister result_reg = ToDoubleRegister(result); 5074 DwVfpRegister result_reg = ToDoubleRegister(result);
5078 5075
5079 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED;
5080 HValue* value = instr->hydrogen()->value(); 5076 HValue* value = instr->hydrogen()->value();
5081 if (value->type().IsSmi()) { 5077 NumberUntagDMode mode = value->representation().IsSmi()
5082 mode = NUMBER_CANDIDATE_IS_SMI; 5078 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
5083 } else if (value->IsLoadKeyed()) {
5084 HLoadKeyed* load = HLoadKeyed::cast(value);
5085 if (load->UsesMustHandleHole()) {
5086 if (load->hole_mode() == ALLOW_RETURN_HOLE) {
5087 mode = NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE;
5088 }
5089 }
5090 }
5091 5079
5092 EmitNumberUntagD(input_reg, result_reg, 5080 EmitNumberUntagD(input_reg, result_reg,
5093 instr->hydrogen()->allow_undefined_as_nan(), 5081 instr->hydrogen()->can_convert_undefined_to_nan(),
5094 instr->hydrogen()->deoptimize_on_minus_zero(), 5082 instr->hydrogen()->deoptimize_on_minus_zero(),
5095 instr->environment(), 5083 instr->environment(),
5096 mode); 5084 mode);
5097 } 5085 }
5098 5086
5099 5087
5100 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5088 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5101 Register result_reg = ToRegister(instr->result()); 5089 Register result_reg = ToRegister(instr->result());
5102 Register scratch1 = scratch0(); 5090 Register scratch1 = scratch0();
5103 Register scratch2 = ToRegister(instr->temp()); 5091 Register scratch2 = ToRegister(instr->temp());
(...skipping 752 matching lines...)
5856 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5844 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5857 __ ldr(result, FieldMemOperand(scratch, 5845 __ ldr(result, FieldMemOperand(scratch,
5858 FixedArray::kHeaderSize - kPointerSize)); 5846 FixedArray::kHeaderSize - kPointerSize));
5859 __ bind(&done); 5847 __ bind(&done);
5860 } 5848 }
5861 5849
5862 5850
5863 #undef __ 5851 #undef __
5864 5852
5865 } } // namespace v8::internal 5853 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine