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

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: 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/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 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 int deoptimization_index = deoptimizations_.length(); 775 int deoptimization_index = deoptimizations_.length();
776 int pc_offset = masm()->pc_offset(); 776 int pc_offset = masm()->pc_offset();
777 environment->Register(deoptimization_index, 777 environment->Register(deoptimization_index,
778 translation.index(), 778 translation.index(),
779 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 779 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
780 deoptimizations_.Add(environment, zone()); 780 deoptimizations_.Add(environment, zone());
781 } 781 }
782 } 782 }
783 783
784 784
785 void LCodeGen::DeoptimizeIf(Condition cc, 785 void LCodeGen::DeoptimizeIf(Condition condition,
786 LEnvironment* environment, 786 LEnvironment* environment,
787 Deoptimizer::BailoutType bailout_type) { 787 Deoptimizer::BailoutType bailout_type) {
788 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 788 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
789 ASSERT(environment->HasBeenRegistered()); 789 ASSERT(environment->HasBeenRegistered());
790 int id = environment->deoptimization_index(); 790 int id = environment->deoptimization_index();
791 ASSERT(info()->IsOptimizing() || info()->IsStub()); 791 ASSERT(info()->IsOptimizing() || info()->IsStub());
792 Address entry = 792 Address entry =
793 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 793 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
794 if (entry == NULL) { 794 if (entry == NULL) {
795 Abort(kBailoutWasNotPrepared); 795 Abort(kBailoutWasNotPrepared);
796 return; 796 return;
797 } 797 }
798 798
799 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. 799 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM.
800 if (FLAG_deopt_every_n_times == 1 && 800 if (FLAG_deopt_every_n_times == 1 &&
801 !info()->IsStub() && 801 !info()->IsStub() &&
802 info()->opt_count() == id) { 802 info()->opt_count() == id) {
803 ASSERT(frame_is_built_); 803 ASSERT(frame_is_built_);
804 __ Call(entry, RelocInfo::RUNTIME_ENTRY); 804 __ Call(entry, RelocInfo::RUNTIME_ENTRY);
805 return; 805 return;
806 } 806 }
807 807
808 if (FLAG_trap_on_deopt && info()->IsOptimizing()) { 808 if (FLAG_trap_on_deopt && info()->IsOptimizing()) {
809 __ stop("trap_on_deopt", cc); 809 __ stop("trap_on_deopt", condition);
810 } 810 }
811 811
812 ASSERT(info()->IsStub() || frame_is_built_); 812 ASSERT(info()->IsStub() || frame_is_built_);
813 if (cc == al && frame_is_built_) { 813 if (condition == al && frame_is_built_) {
814 __ Call(entry, RelocInfo::RUNTIME_ENTRY); 814 __ Call(entry, RelocInfo::RUNTIME_ENTRY);
815 } else { 815 } else {
816 // We often have several deopts to the same entry, reuse the last 816 // We often have several deopts to the same entry, reuse the last
817 // jump entry if this is the case. 817 // jump entry if this is the case.
818 if (deopt_jump_table_.is_empty() || 818 if (deopt_jump_table_.is_empty() ||
819 (deopt_jump_table_.last().address != entry) || 819 (deopt_jump_table_.last().address != entry) ||
820 (deopt_jump_table_.last().bailout_type != bailout_type) || 820 (deopt_jump_table_.last().bailout_type != bailout_type) ||
821 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) { 821 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) {
822 Deoptimizer::JumpTableEntry table_entry(entry, 822 Deoptimizer::JumpTableEntry table_entry(entry,
823 bailout_type, 823 bailout_type,
824 !frame_is_built_); 824 !frame_is_built_);
825 deopt_jump_table_.Add(table_entry, zone()); 825 deopt_jump_table_.Add(table_entry, zone());
826 } 826 }
827 __ b(cc, &deopt_jump_table_.last().label); 827 __ b(condition, &deopt_jump_table_.last().label);
828 } 828 }
829 } 829 }
830 830
831 831
832 void LCodeGen::DeoptimizeIf(Condition cc, 832 void LCodeGen::DeoptimizeIf(Condition condition,
833 LEnvironment* environment) { 833 LEnvironment* environment) {
834 Deoptimizer::BailoutType bailout_type = info()->IsStub() 834 Deoptimizer::BailoutType bailout_type = info()->IsStub()
835 ? Deoptimizer::LAZY 835 ? Deoptimizer::LAZY
836 : Deoptimizer::EAGER; 836 : Deoptimizer::EAGER;
837 DeoptimizeIf(cc, environment, bailout_type); 837 DeoptimizeIf(condition, environment, bailout_type);
838 } 838 }
839 839
840 840
841 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 841 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
842 ZoneList<Handle<Map> > maps(1, zone()); 842 ZoneList<Handle<Map> > maps(1, zone());
843 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 843 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
844 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 844 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
845 RelocInfo::Mode mode = it.rinfo()->rmode(); 845 RelocInfo::Mode mode = it.rinfo()->rmode();
846 if (mode == RelocInfo::EMBEDDED_OBJECT && 846 if (mode == RelocInfo::EMBEDDED_OBJECT &&
847 it.rinfo()->target_object()->IsMap()) { 847 it.rinfo()->target_object()->IsMap()) {
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 2131
2132 2132
2133 int LCodeGen::GetNextEmittedBlock() const { 2133 int LCodeGen::GetNextEmittedBlock() const {
2134 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { 2134 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
2135 if (!chunk_->GetLabel(i)->HasReplacement()) return i; 2135 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
2136 } 2136 }
2137 return -1; 2137 return -1;
2138 } 2138 }
2139 2139
2140 template<class InstrType> 2140 template<class InstrType>
2141 void LCodeGen::EmitBranch(InstrType instr, Condition cc) { 2141 void LCodeGen::EmitBranch(InstrType instr, Condition condition) {
2142 int left_block = instr->TrueDestination(chunk_); 2142 int left_block = instr->TrueDestination(chunk_);
2143 int right_block = instr->FalseDestination(chunk_); 2143 int right_block = instr->FalseDestination(chunk_);
2144 2144
2145 int next_block = GetNextEmittedBlock(); 2145 int next_block = GetNextEmittedBlock();
2146 2146
2147 if (right_block == left_block || cc == al) { 2147 if (right_block == left_block || condition == al) {
2148 EmitGoto(left_block); 2148 EmitGoto(left_block);
2149 } else if (left_block == next_block) { 2149 } else if (left_block == next_block) {
2150 __ b(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block)); 2150 __ b(NegateCondition(condition), 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(condition, chunk_->GetAssemblyLabel(left_block));
2153 } else { 2153 } else {
2154 __ b(cc, chunk_->GetAssemblyLabel(left_block)); 2154 __ b(condition, 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 condition) {
2162 int false_block = instr->FalseDestination(chunk_);
2163 __ b(condition, 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...) Expand 10 before | Expand all | Expand 10 after
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 __ mov(ip, Operand(factory()->the_hole_value()));
2426 __ cmp(input_reg, ip);
2427 EmitBranch(instr, eq);
2428 return;
2429 }
2430
2431 DwVfpRegister input_reg = ToDoubleRegister(instr->object());
2432 __ VFPCompareAndSetFlags(input_reg, input_reg);
2433 EmitFalseBranch(instr, vc);
2434
2435 Register scratch = scratch0();
2436 __ VmovHigh(scratch, input_reg);
2437 __ cmp(scratch, Operand(kHoleNanUpper32));
2438 EmitBranch(instr, eq);
2439 }
2440
2441
2415 Condition LCodeGen::EmitIsObject(Register input, 2442 Condition LCodeGen::EmitIsObject(Register input,
2416 Register temp1, 2443 Register temp1,
2417 Label* is_not_object, 2444 Label* is_not_object,
2418 Label* is_object) { 2445 Label* is_object) {
2419 Register temp2 = scratch0(); 2446 Register temp2 = scratch0();
2420 __ JumpIfSmi(input, is_not_object); 2447 __ JumpIfSmi(input, is_not_object);
2421 2448
2422 __ LoadRoot(temp2, Heap::kNullValueRootIndex); 2449 __ LoadRoot(temp2, Heap::kNullValueRootIndex);
2423 __ cmp(input, temp2); 2450 __ cmp(input, temp2);
2424 __ b(eq, is_object); 2451 __ b(eq, is_object);
(...skipping 1863 matching lines...) Expand 10 before | Expand all | Expand 10 after
4288 4315
4289 // Name is always in r2. 4316 // Name is always in r2.
4290 __ mov(r2, Operand(instr->name())); 4317 __ mov(r2, Operand(instr->name()));
4291 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4318 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4292 ? isolate()->builtins()->StoreIC_Initialize_Strict() 4319 ? isolate()->builtins()->StoreIC_Initialize_Strict()
4293 : isolate()->builtins()->StoreIC_Initialize(); 4320 : isolate()->builtins()->StoreIC_Initialize();
4294 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); 4321 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
4295 } 4322 }
4296 4323
4297 4324
4298 void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) { 4325 void LCodeGen::ApplyCheckIf(Condition condition, LBoundsCheck* check) {
4299 if (FLAG_debug_code && check->hydrogen()->skip_check()) { 4326 if (FLAG_debug_code && check->hydrogen()->skip_check()) {
4300 Label done; 4327 Label done;
4301 __ b(NegateCondition(cc), &done); 4328 __ b(NegateCondition(condition), &done);
4302 __ stop("eliminated bounds check failed"); 4329 __ stop("eliminated bounds check failed");
4303 __ bind(&done); 4330 __ bind(&done);
4304 } else { 4331 } else {
4305 DeoptimizeIf(cc, check->environment()); 4332 DeoptimizeIf(condition, check->environment());
4306 } 4333 }
4307 } 4334 }
4308 4335
4309 4336
4310 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 4337 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4311 if (instr->hydrogen()->skip_check()) return; 4338 if (instr->hydrogen()->skip_check()) return;
4312 4339
4313 if (instr->index()->IsConstantOperand()) { 4340 if (instr->index()->IsConstantOperand()) {
4314 int constant_index = 4341 int constant_index =
4315 ToInteger32(LConstantOperand::cast(instr->index())); 4342 ToInteger32(LConstantOperand::cast(instr->index()));
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
4819 private: 4846 private:
4820 LNumberTagD* instr_; 4847 LNumberTagD* instr_;
4821 }; 4848 };
4822 4849
4823 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); 4850 DwVfpRegister input_reg = ToDoubleRegister(instr->value());
4824 Register scratch = scratch0(); 4851 Register scratch = scratch0();
4825 Register reg = ToRegister(instr->result()); 4852 Register reg = ToRegister(instr->result());
4826 Register temp1 = ToRegister(instr->temp()); 4853 Register temp1 = ToRegister(instr->temp());
4827 Register temp2 = ToRegister(instr->temp2()); 4854 Register temp2 = ToRegister(instr->temp2());
4828 4855
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); 4856 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4853 if (FLAG_inline_new) { 4857 if (FLAG_inline_new) {
4854 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4858 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4855 // We want the untagged address first for performance 4859 // We want the untagged address first for performance
4856 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), 4860 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
4857 DONT_TAG_RESULT); 4861 DONT_TAG_RESULT);
4858 } else { 4862 } else {
4859 __ jmp(deferred->entry()); 4863 __ jmp(deferred->entry());
4860 } 4864 }
4861 __ bind(deferred->exit()); 4865 __ bind(deferred->exit());
4862 __ vstr(input_reg, reg, HeapNumber::kValueOffset); 4866 __ vstr(input_reg, reg, HeapNumber::kValueOffset);
4863 // Now that we have finished with the object's real address tag it 4867 // Now that we have finished with the object's real address tag it
4864 __ add(reg, reg, Operand(kHeapObjectTag)); 4868 __ add(reg, reg, Operand(kHeapObjectTag));
4865 __ bind(&done);
4866 } 4869 }
4867 4870
4868 4871
4869 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4872 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4870 // TODO(3095996): Get rid of this. For now, we need to make the 4873 // TODO(3095996): Get rid of this. For now, we need to make the
4871 // result register contain a valid pointer because it is already 4874 // result register contain a valid pointer because it is already
4872 // contained in the register pointer map. 4875 // contained in the register pointer map.
4873 Register reg = ToRegister(instr->result()); 4876 Register reg = ToRegister(instr->result());
4874 __ mov(reg, Operand::Zero()); 4877 __ mov(reg, Operand::Zero());
4875 4878
(...skipping 19 matching lines...) Expand all
4895 __ SmiUntag(result, input, SetCC); 4898 __ SmiUntag(result, input, SetCC);
4896 DeoptimizeIf(cs, instr->environment()); 4899 DeoptimizeIf(cs, instr->environment());
4897 } else { 4900 } else {
4898 __ SmiUntag(result, input); 4901 __ SmiUntag(result, input);
4899 } 4902 }
4900 } 4903 }
4901 4904
4902 4905
4903 void LCodeGen::EmitNumberUntagD(Register input_reg, 4906 void LCodeGen::EmitNumberUntagD(Register input_reg,
4904 DwVfpRegister result_reg, 4907 DwVfpRegister result_reg,
4905 bool allow_undefined_as_nan, 4908 bool can_convert_undefined_to_nan,
4906 bool deoptimize_on_minus_zero, 4909 bool deoptimize_on_minus_zero,
4907 LEnvironment* env, 4910 LEnvironment* env,
4908 NumberUntagDMode mode) { 4911 NumberUntagDMode mode) {
4909 Register scratch = scratch0(); 4912 Register scratch = scratch0();
4910 SwVfpRegister flt_scratch = double_scratch0().low(); 4913 SwVfpRegister flt_scratch = double_scratch0().low();
4911 ASSERT(!result_reg.is(double_scratch0())); 4914 ASSERT(!result_reg.is(double_scratch0()));
4912 4915
4913 Label load_smi, heap_number, done; 4916 Label load_smi, heap_number, done;
4914 4917
4915 STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE > 4918 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4916 NUMBER_CANDIDATE_IS_ANY_TAGGED);
4917 if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4918 // Smi check. 4919 // Smi check.
4919 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4920 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4920 4921
4921 // Heap number map check. 4922 // Heap number map check.
4922 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4923 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4923 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4924 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4924 __ cmp(scratch, Operand(ip)); 4925 __ cmp(scratch, Operand(ip));
4925 if (!allow_undefined_as_nan) { 4926 if (!can_convert_undefined_to_nan) {
4926 DeoptimizeIf(ne, env); 4927 DeoptimizeIf(ne, env);
4927 } else { 4928 } else {
4928 Label heap_number, convert; 4929 Label heap_number, convert;
4929 __ b(eq, &heap_number); 4930 __ b(eq, &heap_number);
4930 4931
4931 // Convert undefined (and hole) to NaN. 4932 // Convert undefined (and hole) to NaN.
4932 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 4933 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
4933 __ cmp(input_reg, Operand(ip)); 4934 __ 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); 4935 DeoptimizeIf(ne, env);
4940 4936
4941 __ bind(&convert); 4937 __ bind(&convert);
4942 __ LoadRoot(scratch, Heap::kNanValueRootIndex); 4938 __ LoadRoot(scratch, Heap::kNanValueRootIndex);
4943 __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag); 4939 __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag);
4944 __ jmp(&done); 4940 __ jmp(&done);
4945 4941
4946 __ bind(&heap_number); 4942 __ bind(&heap_number);
4947 } 4943 }
4948 // Heap number to double register conversion. 4944 // Heap number to double register conversion.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
5069 5065
5070 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 5066 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5071 LOperand* input = instr->value(); 5067 LOperand* input = instr->value();
5072 ASSERT(input->IsRegister()); 5068 ASSERT(input->IsRegister());
5073 LOperand* result = instr->result(); 5069 LOperand* result = instr->result();
5074 ASSERT(result->IsDoubleRegister()); 5070 ASSERT(result->IsDoubleRegister());
5075 5071
5076 Register input_reg = ToRegister(input); 5072 Register input_reg = ToRegister(input);
5077 DwVfpRegister result_reg = ToDoubleRegister(result); 5073 DwVfpRegister result_reg = ToDoubleRegister(result);
5078 5074
5079 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED;
5080 HValue* value = instr->hydrogen()->value(); 5075 HValue* value = instr->hydrogen()->value();
5081 if (value->type().IsSmi()) { 5076 NumberUntagDMode mode = value->representation().IsSmi()
5082 mode = NUMBER_CANDIDATE_IS_SMI; 5077 ? 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 5078
5092 EmitNumberUntagD(input_reg, result_reg, 5079 EmitNumberUntagD(input_reg, result_reg,
5093 instr->hydrogen()->allow_undefined_as_nan(), 5080 instr->hydrogen()->can_convert_undefined_to_nan(),
5094 instr->hydrogen()->deoptimize_on_minus_zero(), 5081 instr->hydrogen()->deoptimize_on_minus_zero(),
5095 instr->environment(), 5082 instr->environment(),
5096 mode); 5083 mode);
5097 } 5084 }
5098 5085
5099 5086
5100 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5087 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5101 Register result_reg = ToRegister(instr->result()); 5088 Register result_reg = ToRegister(instr->result());
5102 Register scratch1 = scratch0(); 5089 Register scratch1 = scratch0();
5103 Register scratch2 = ToRegister(instr->temp()); 5090 Register scratch2 = ToRegister(instr->temp());
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
5856 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5843 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5857 __ ldr(result, FieldMemOperand(scratch, 5844 __ ldr(result, FieldMemOperand(scratch,
5858 FixedArray::kHeaderSize - kPointerSize)); 5845 FixedArray::kHeaderSize - kPointerSize));
5859 __ bind(&done); 5846 __ bind(&done);
5860 } 5847 }
5861 5848
5862 5849
5863 #undef __ 5850 #undef __
5864 5851
5865 } } // namespace v8::internal 5852 } } // 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
This is Rietveld 408576698