| 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 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 case CodeStub::RegExpExec: { | 1083 case CodeStub::RegExpExec: { |
| 1084 RegExpExecStub stub; | 1084 RegExpExecStub stub; |
| 1085 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1085 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1086 break; | 1086 break; |
| 1087 } | 1087 } |
| 1088 case CodeStub::SubString: { | 1088 case CodeStub::SubString: { |
| 1089 SubStringStub stub; | 1089 SubStringStub stub; |
| 1090 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1090 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1091 break; | 1091 break; |
| 1092 } | 1092 } |
| 1093 case CodeStub::NumberToString: { | |
| 1094 NumberToStringStub stub; | |
| 1095 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 1096 break; | |
| 1097 } | |
| 1098 case CodeStub::StringCompare: { | 1093 case CodeStub::StringCompare: { |
| 1099 StringCompareStub stub; | 1094 StringCompareStub stub; |
| 1100 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1095 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1101 break; | 1096 break; |
| 1102 } | 1097 } |
| 1103 case CodeStub::TranscendentalCache: { | 1098 case CodeStub::TranscendentalCache: { |
| 1104 __ ldr(r0, MemOperand(sp, 0)); | 1099 __ ldr(r0, MemOperand(sp, 0)); |
| 1105 TranscendentalCacheStub stub(instr->transcendental_type(), | 1100 TranscendentalCacheStub stub(instr->transcendental_type(), |
| 1106 TranscendentalCacheStub::TAGGED); | 1101 TranscendentalCacheStub::TAGGED); |
| 1107 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1102 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| (...skipping 1839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2947 __ Jump(lr); | 2942 __ Jump(lr); |
| 2948 | 2943 |
| 2949 if (no_frame_start != -1) { | 2944 if (no_frame_start != -1) { |
| 2950 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 2945 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 2951 } | 2946 } |
| 2952 } | 2947 } |
| 2953 | 2948 |
| 2954 | 2949 |
| 2955 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 2950 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { |
| 2956 Register result = ToRegister(instr->result()); | 2951 Register result = ToRegister(instr->result()); |
| 2957 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell()))); | 2952 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell().handle()))); |
| 2958 __ ldr(result, FieldMemOperand(ip, Cell::kValueOffset)); | 2953 __ ldr(result, FieldMemOperand(ip, Cell::kValueOffset)); |
| 2959 if (instr->hydrogen()->RequiresHoleCheck()) { | 2954 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2960 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2955 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 2961 __ cmp(result, ip); | 2956 __ cmp(result, ip); |
| 2962 DeoptimizeIf(eq, instr->environment()); | 2957 DeoptimizeIf(eq, instr->environment()); |
| 2963 } | 2958 } |
| 2964 } | 2959 } |
| 2965 | 2960 |
| 2966 | 2961 |
| 2967 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2962 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 2968 ASSERT(ToRegister(instr->global_object()).is(r0)); | 2963 ASSERT(ToRegister(instr->global_object()).is(r0)); |
| 2969 ASSERT(ToRegister(instr->result()).is(r0)); | 2964 ASSERT(ToRegister(instr->result()).is(r0)); |
| 2970 | 2965 |
| 2971 __ mov(r2, Operand(instr->name())); | 2966 __ mov(r2, Operand(instr->name())); |
| 2972 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET | 2967 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET |
| 2973 : RelocInfo::CODE_TARGET_CONTEXT; | 2968 : RelocInfo::CODE_TARGET_CONTEXT; |
| 2974 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2969 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 2975 CallCode(ic, mode, instr); | 2970 CallCode(ic, mode, instr); |
| 2976 } | 2971 } |
| 2977 | 2972 |
| 2978 | 2973 |
| 2979 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { | 2974 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { |
| 2980 Register value = ToRegister(instr->value()); | 2975 Register value = ToRegister(instr->value()); |
| 2981 Register cell = scratch0(); | 2976 Register cell = scratch0(); |
| 2982 | 2977 |
| 2983 // Load the cell. | 2978 // Load the cell. |
| 2984 __ mov(cell, Operand(instr->hydrogen()->cell())); | 2979 __ mov(cell, Operand(instr->hydrogen()->cell().handle())); |
| 2985 | 2980 |
| 2986 // If the cell we are storing to contains the hole it could have | 2981 // If the cell we are storing to contains the hole it could have |
| 2987 // been deleted from the property dictionary. In that case, we need | 2982 // been deleted from the property dictionary. In that case, we need |
| 2988 // to update the property details in the property dictionary to mark | 2983 // to update the property details in the property dictionary to mark |
| 2989 // it as no longer deleted. | 2984 // it as no longer deleted. |
| 2990 if (instr->hydrogen()->RequiresHoleCheck()) { | 2985 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2991 // We use a temp to check the payload (CompareRoot might clobber ip). | 2986 // We use a temp to check the payload (CompareRoot might clobber ip). |
| 2992 Register payload = ToRegister(instr->temp()); | 2987 Register payload = ToRegister(instr->temp()); |
| 2993 __ ldr(payload, FieldMemOperand(cell, Cell::kValueOffset)); | 2988 __ ldr(payload, FieldMemOperand(cell, Cell::kValueOffset)); |
| 2994 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); | 2989 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3872 ToRegister(instr->right()).is(r2)); | 3867 ToRegister(instr->right()).is(r2)); |
| 3873 ASSERT(ToDoubleRegister(instr->left()).is(d1)); | 3868 ASSERT(ToDoubleRegister(instr->left()).is(d1)); |
| 3874 ASSERT(ToDoubleRegister(instr->result()).is(d3)); | 3869 ASSERT(ToDoubleRegister(instr->result()).is(d3)); |
| 3875 | 3870 |
| 3876 if (exponent_type.IsSmi()) { | 3871 if (exponent_type.IsSmi()) { |
| 3877 MathPowStub stub(MathPowStub::TAGGED); | 3872 MathPowStub stub(MathPowStub::TAGGED); |
| 3878 __ CallStub(&stub); | 3873 __ CallStub(&stub); |
| 3879 } else if (exponent_type.IsTagged()) { | 3874 } else if (exponent_type.IsTagged()) { |
| 3880 Label no_deopt; | 3875 Label no_deopt; |
| 3881 __ JumpIfSmi(r2, &no_deopt); | 3876 __ JumpIfSmi(r2, &no_deopt); |
| 3882 __ ldr(r7, FieldMemOperand(r2, HeapObject::kMapOffset)); | 3877 __ ldr(r6, FieldMemOperand(r2, HeapObject::kMapOffset)); |
| 3883 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 3878 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 3884 __ cmp(r7, Operand(ip)); | 3879 __ cmp(r6, Operand(ip)); |
| 3885 DeoptimizeIf(ne, instr->environment()); | 3880 DeoptimizeIf(ne, instr->environment()); |
| 3886 __ bind(&no_deopt); | 3881 __ bind(&no_deopt); |
| 3887 MathPowStub stub(MathPowStub::TAGGED); | 3882 MathPowStub stub(MathPowStub::TAGGED); |
| 3888 __ CallStub(&stub); | 3883 __ CallStub(&stub); |
| 3889 } else if (exponent_type.IsInteger32()) { | 3884 } else if (exponent_type.IsInteger32()) { |
| 3890 MathPowStub stub(MathPowStub::INTEGER); | 3885 MathPowStub stub(MathPowStub::INTEGER); |
| 3891 __ CallStub(&stub); | 3886 __ CallStub(&stub); |
| 3892 } else { | 3887 } else { |
| 3893 ASSERT(exponent_type.IsDouble()); | 3888 ASSERT(exponent_type.IsDouble()); |
| 3894 MathPowStub stub(MathPowStub::DOUBLE); | 3889 MathPowStub stub(MathPowStub::DOUBLE); |
| (...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4861 | 4856 |
| 4862 void LCodeGen::EmitNumberUntagD(Register input_reg, | 4857 void LCodeGen::EmitNumberUntagD(Register input_reg, |
| 4863 DwVfpRegister result_reg, | 4858 DwVfpRegister result_reg, |
| 4864 bool can_convert_undefined_to_nan, | 4859 bool can_convert_undefined_to_nan, |
| 4865 bool deoptimize_on_minus_zero, | 4860 bool deoptimize_on_minus_zero, |
| 4866 LEnvironment* env, | 4861 LEnvironment* env, |
| 4867 NumberUntagDMode mode) { | 4862 NumberUntagDMode mode) { |
| 4868 Register scratch = scratch0(); | 4863 Register scratch = scratch0(); |
| 4869 SwVfpRegister flt_scratch = double_scratch0().low(); | 4864 SwVfpRegister flt_scratch = double_scratch0().low(); |
| 4870 ASSERT(!result_reg.is(double_scratch0())); | 4865 ASSERT(!result_reg.is(double_scratch0())); |
| 4871 | 4866 Label convert, load_smi, done; |
| 4872 Label load_smi, heap_number, done; | |
| 4873 | |
| 4874 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 4867 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
| 4875 // Smi check. | 4868 // Smi check. |
| 4876 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 4869 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); |
| 4877 | |
| 4878 // Heap number map check. | 4870 // Heap number map check. |
| 4879 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4871 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
| 4880 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4872 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 4881 __ cmp(scratch, Operand(ip)); | 4873 __ cmp(scratch, Operand(ip)); |
| 4882 if (!can_convert_undefined_to_nan) { | 4874 if (can_convert_undefined_to_nan) { |
| 4875 __ b(ne, &convert); |
| 4876 } else { |
| 4883 DeoptimizeIf(ne, env); | 4877 DeoptimizeIf(ne, env); |
| 4884 } else { | |
| 4885 Label heap_number, convert; | |
| 4886 __ b(eq, &heap_number); | |
| 4887 | |
| 4888 // Convert undefined (and hole) to NaN. | |
| 4889 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | |
| 4890 __ cmp(input_reg, Operand(ip)); | |
| 4891 DeoptimizeIf(ne, env); | |
| 4892 | |
| 4893 __ bind(&convert); | |
| 4894 __ LoadRoot(scratch, Heap::kNanValueRootIndex); | |
| 4895 __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag); | |
| 4896 __ jmp(&done); | |
| 4897 | |
| 4898 __ bind(&heap_number); | |
| 4899 } | 4878 } |
| 4900 // Heap number to double register conversion. | 4879 // load heap number |
| 4901 __ vldr(result_reg, input_reg, HeapNumber::kValueOffset - kHeapObjectTag); | 4880 __ vldr(result_reg, input_reg, HeapNumber::kValueOffset - kHeapObjectTag); |
| 4902 if (deoptimize_on_minus_zero) { | 4881 if (deoptimize_on_minus_zero) { |
| 4903 __ VmovLow(scratch, result_reg); | 4882 __ VmovLow(scratch, result_reg); |
| 4904 __ cmp(scratch, Operand::Zero()); | 4883 __ cmp(scratch, Operand::Zero()); |
| 4905 __ b(ne, &done); | 4884 __ b(ne, &done); |
| 4906 __ VmovHigh(scratch, result_reg); | 4885 __ VmovHigh(scratch, result_reg); |
| 4907 __ cmp(scratch, Operand(HeapNumber::kSignMask)); | 4886 __ cmp(scratch, Operand(HeapNumber::kSignMask)); |
| 4908 DeoptimizeIf(eq, env); | 4887 DeoptimizeIf(eq, env); |
| 4909 } | 4888 } |
| 4910 __ jmp(&done); | 4889 __ jmp(&done); |
| 4890 if (can_convert_undefined_to_nan) { |
| 4891 __ bind(&convert); |
| 4892 // Convert undefined (and hole) to NaN. |
| 4893 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 4894 __ cmp(input_reg, Operand(ip)); |
| 4895 DeoptimizeIf(ne, env); |
| 4896 __ LoadRoot(scratch, Heap::kNanValueRootIndex); |
| 4897 __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag); |
| 4898 __ jmp(&done); |
| 4899 } |
| 4911 } else { | 4900 } else { |
| 4912 __ SmiUntag(scratch, input_reg); | 4901 __ SmiUntag(scratch, input_reg); |
| 4913 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); | 4902 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); |
| 4914 } | 4903 } |
| 4915 | |
| 4916 // Smi to double register conversion | 4904 // Smi to double register conversion |
| 4917 __ bind(&load_smi); | 4905 __ bind(&load_smi); |
| 4918 // scratch: untagged value of input_reg | 4906 // scratch: untagged value of input_reg |
| 4919 __ vmov(flt_scratch, scratch); | 4907 __ vmov(flt_scratch, scratch); |
| 4920 __ vcvt_f64_s32(result_reg, flt_scratch); | 4908 __ vcvt_f64_s32(result_reg, flt_scratch); |
| 4921 __ bind(&done); | 4909 __ bind(&done); |
| 4922 } | 4910 } |
| 4923 | 4911 |
| 4924 | 4912 |
| 4925 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 4913 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5386 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { | 5374 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { |
| 5387 ASSERT(ToRegister(instr->value()).is(r0)); | 5375 ASSERT(ToRegister(instr->value()).is(r0)); |
| 5388 __ push(r0); | 5376 __ push(r0); |
| 5389 CallRuntime(Runtime::kToFastProperties, 1, instr); | 5377 CallRuntime(Runtime::kToFastProperties, 1, instr); |
| 5390 } | 5378 } |
| 5391 | 5379 |
| 5392 | 5380 |
| 5393 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 5381 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { |
| 5394 Label materialized; | 5382 Label materialized; |
| 5395 // Registers will be used as follows: | 5383 // Registers will be used as follows: |
| 5396 // r7 = literals array. | 5384 // r6 = literals array. |
| 5397 // r1 = regexp literal. | 5385 // r1 = regexp literal. |
| 5398 // r0 = regexp literal clone. | 5386 // r0 = regexp literal clone. |
| 5399 // r2 and r4-r6 are used as temporaries. | 5387 // r2-5 are used as temporaries. |
| 5400 int literal_offset = | 5388 int literal_offset = |
| 5401 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); | 5389 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); |
| 5402 __ LoadHeapObject(r7, instr->hydrogen()->literals()); | 5390 __ LoadHeapObject(r6, instr->hydrogen()->literals()); |
| 5403 __ ldr(r1, FieldMemOperand(r7, literal_offset)); | 5391 __ ldr(r1, FieldMemOperand(r6, literal_offset)); |
| 5404 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 5392 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 5405 __ cmp(r1, ip); | 5393 __ cmp(r1, ip); |
| 5406 __ b(ne, &materialized); | 5394 __ b(ne, &materialized); |
| 5407 | 5395 |
| 5408 // Create regexp literal using runtime function | 5396 // Create regexp literal using runtime function |
| 5409 // Result will be in r0. | 5397 // Result will be in r0. |
| 5410 __ mov(r6, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); | 5398 __ mov(r5, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); |
| 5411 __ mov(r5, Operand(instr->hydrogen()->pattern())); | 5399 __ mov(r4, Operand(instr->hydrogen()->pattern())); |
| 5412 __ mov(r4, Operand(instr->hydrogen()->flags())); | 5400 __ mov(r3, Operand(instr->hydrogen()->flags())); |
| 5413 __ Push(r7, r6, r5, r4); | 5401 __ Push(r6, r5, r4, r3); |
| 5414 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); | 5402 CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); |
| 5415 __ mov(r1, r0); | 5403 __ mov(r1, r0); |
| 5416 | 5404 |
| 5417 __ bind(&materialized); | 5405 __ bind(&materialized); |
| 5418 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 5406 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
| 5419 Label allocated, runtime_allocate; | 5407 Label allocated, runtime_allocate; |
| 5420 | 5408 |
| 5421 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); | 5409 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); |
| 5422 __ jmp(&allocated); | 5410 __ jmp(&allocated); |
| 5423 | 5411 |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5794 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5782 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5795 __ ldr(result, FieldMemOperand(scratch, | 5783 __ ldr(result, FieldMemOperand(scratch, |
| 5796 FixedArray::kHeaderSize - kPointerSize)); | 5784 FixedArray::kHeaderSize - kPointerSize)); |
| 5797 __ bind(&done); | 5785 __ bind(&done); |
| 5798 } | 5786 } |
| 5799 | 5787 |
| 5800 | 5788 |
| 5801 #undef __ | 5789 #undef __ |
| 5802 | 5790 |
| 5803 } } // namespace v8::internal | 5791 } } // namespace v8::internal |
| OLD | NEW |