OLD | NEW |
---|---|
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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...) Loading... | |
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 |
OLD | NEW |