OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2923 CallFunctionNoFeedback(masm, | 2923 CallFunctionNoFeedback(masm, |
2924 arg_count(), | 2924 arg_count(), |
2925 true, | 2925 true, |
2926 CallAsMethod()); | 2926 CallAsMethod()); |
2927 | 2927 |
2928 // Unreachable. | 2928 // Unreachable. |
2929 __ stop("Unexpected code address"); | 2929 __ stop("Unexpected code address"); |
2930 } | 2930 } |
2931 | 2931 |
2932 | 2932 |
2933 void CallIC_RoundStub::Generate(MacroAssembler* masm) { | |
2934 Register function = a1; | |
2935 Register vector = a2; | |
2936 Register slot = a3; | |
2937 | |
2938 Register temp1 = a0; | |
2939 Register temp2 = a4; | |
2940 DoubleRegister double_temp1 = f12; | |
2941 DoubleRegister double_temp2 = f14; | |
2942 Label tail, miss; | |
2943 | |
2944 // Ensure nobody has snuck in another function. | |
2945 __ BranchIfNotBuiltin(function, temp1, kMathRound, &miss); | |
2946 | |
2947 if (arg_count() > 0) { | |
2948 __ ld(temp1, MemOperand(sp, (arg_count() - 1) * kPointerSize)); | |
2949 Handle<Map> map = isolate()->factory()->heap_number_map(); | |
2950 __ CheckMap(temp1, temp2, map, &tail, DO_SMI_CHECK); | |
2951 __ ldc1(double_temp1, FieldMemOperand(temp1, HeapNumber::kValueOffset)); | |
2952 | |
2953 // If the number is >0, it doesn't round to -0 | |
2954 __ Move(double_temp2, 0.0); | |
2955 __ BranchF64(&tail, nullptr, gt, double_temp1, double_temp2); | |
2956 | |
2957 // If the number is <-.5, it doesn't round to -0 | |
2958 __ Move(double_temp2, -.5); | |
2959 __ BranchF64(&tail, nullptr, lt, double_temp1, double_temp2); | |
2960 | |
2961 // +0 doesn't round to -0 | |
2962 __ FmoveHigh(temp1, double_temp1); | |
2963 __ Branch(&tail, ne, temp1, Operand(0xffffffff80000000)); | |
2964 | |
2965 __ SmiUntag(temp1, slot); | |
2966 __ dsll(temp1, temp1, kPointerSizeLog2); | |
paul.l...
2015/05/04 18:22:39
Use SmiScale(temp1, slot, kPointerSizeLog2) here t
| |
2967 __ Daddu(temp1, temp1, vector); | |
2968 __ li(temp2, Operand(Smi::FromInt(kHasReturnedMinusZeroSentinel))); | |
2969 __ sd(temp2, | |
2970 FieldMemOperand(temp1, FixedArray::kHeaderSize + kPointerSize)); | |
2971 } | |
2972 | |
2973 __ bind(&tail); | |
2974 // The slow case, we need this no matter what to complete a call after a miss. | |
2975 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | |
2976 | |
2977 // Unreachable. | |
2978 __ stop("Unreachable"); | |
2979 | |
2980 __ bind(&miss); | |
2981 GenerateMiss(masm); | |
2982 __ Branch(&tail); | |
2983 } | |
2984 | |
2985 | |
2986 void CallIC_FloorStub::Generate(MacroAssembler* masm) { | |
2987 Register function = a1; | |
2988 Register vector = a2; | |
2989 Register slot = a3; | |
2990 | |
2991 Register temp1 = a0; | |
2992 Register temp2 = a4; | |
2993 DoubleRegister double_temp = f12; | |
2994 Label tail, miss; | |
2995 | |
2996 // Ensure nobody has snuck in another function. | |
2997 __ BranchIfNotBuiltin(function, temp1, kMathFloor, &miss); | |
2998 | |
2999 if (arg_count() > 0) { | |
3000 __ ld(temp1, MemOperand(sp, (arg_count() - 1) * kPointerSize)); | |
3001 Handle<Map> map = isolate()->factory()->heap_number_map(); | |
3002 __ CheckMap(temp1, temp2, map, &tail, DO_SMI_CHECK); | |
3003 __ ldc1(double_temp, FieldMemOperand(temp1, HeapNumber::kValueOffset)); | |
3004 | |
3005 // Only -0 floors to -0. | |
3006 __ FmoveHigh(temp1, double_temp); | |
3007 __ Branch(&tail, ne, temp1, Operand(0xffffffff80000000)); | |
3008 __ FmoveLow(temp1, double_temp); | |
3009 __ Branch(&tail, ne, temp1, Operand(zero_reg)); | |
3010 | |
3011 __ SmiUntag(temp1, slot); | |
3012 __ dsll(temp1, temp1, kPointerSizeLog2); | |
3013 __ Daddu(temp1, temp1, vector); | |
3014 __ li(temp2, Operand(Smi::FromInt(kHasReturnedMinusZeroSentinel))); | |
3015 __ sd(temp2, | |
3016 FieldMemOperand(temp1, FixedArray::kHeaderSize + kPointerSize)); | |
3017 } | |
3018 | |
3019 __ bind(&tail); | |
3020 // The slow case, we need this no matter what to complete a call after a miss. | |
3021 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | |
3022 | |
3023 // Unreachable. | |
3024 __ stop("Unreachable"); | |
3025 | |
3026 __ bind(&miss); | |
3027 GenerateMiss(masm); | |
3028 __ Branch(&tail); | |
3029 } | |
3030 | |
3031 | |
3032 void CallIC_CeilStub::Generate(MacroAssembler* masm) { | |
3033 Register function = a1; | |
3034 Register vector = a2; | |
3035 Register slot = a3; | |
3036 | |
3037 Register temp1 = a0; | |
3038 Register temp2 = a4; | |
3039 DoubleRegister double_temp1 = f12; | |
3040 DoubleRegister double_temp2 = f14; | |
3041 Label tail, miss; | |
3042 | |
3043 // Ensure nobody has snuck in another function. | |
3044 __ BranchIfNotBuiltin(function, temp1, kMathCeil, &miss); | |
3045 | |
3046 if (arg_count() > 0) { | |
3047 __ ld(temp1, MemOperand(sp, (arg_count() - 1) * kPointerSize)); | |
3048 Handle<Map> map = isolate()->factory()->heap_number_map(); | |
3049 __ CheckMap(temp1, temp2, map, &tail, DO_SMI_CHECK); | |
3050 __ ldc1(double_temp1, FieldMemOperand(temp1, HeapNumber::kValueOffset)); | |
3051 | |
3052 // If the number is >0, it doesn't round to -0 | |
3053 __ Move(double_temp2, 0.0); | |
3054 __ BranchF64(&tail, nullptr, gt, double_temp1, double_temp2); | |
3055 | |
3056 // If the number is <=-1, it doesn't round to -0 | |
3057 __ Move(double_temp2, -1.0); | |
3058 __ BranchF64(&tail, nullptr, le, double_temp1, double_temp2); | |
3059 | |
3060 // +0 doesn't round to -0. | |
3061 __ FmoveHigh(temp1, double_temp1); | |
3062 __ Branch(&tail, ne, temp1, Operand(0xffffffff80000000)); | |
3063 | |
3064 __ SmiUntag(temp1, slot); | |
3065 __ dsll(temp1, temp1, kPointerSizeLog2); | |
3066 __ Daddu(temp1, temp1, vector); | |
3067 __ li(temp2, Operand(Smi::FromInt(kHasReturnedMinusZeroSentinel))); | |
3068 __ sd(temp2, | |
3069 FieldMemOperand(temp1, FixedArray::kHeaderSize + kPointerSize)); | |
3070 } | |
3071 | |
3072 __ bind(&tail); | |
3073 // The slow case, we need this no matter what to complete a call after a miss. | |
3074 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | |
3075 | |
3076 // Unreachable. | |
3077 __ stop("Unreachable"); | |
3078 | |
3079 __ bind(&miss); | |
3080 GenerateMiss(masm); | |
3081 __ Branch(&tail); | |
3082 } | |
3083 | |
3084 | |
2933 void CallICStub::Generate(MacroAssembler* masm) { | 3085 void CallICStub::Generate(MacroAssembler* masm) { |
2934 // a1 - function | 3086 // a1 - function |
2935 // a3 - slot id (Smi) | 3087 // a3 - slot id (Smi) |
2936 // a2 - vector | 3088 // a2 - vector |
2937 const int with_types_offset = | 3089 const int with_types_offset = |
2938 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 3090 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
2939 const int generic_offset = | 3091 const int generic_offset = |
2940 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | 3092 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
2941 Label extra_checks_or_miss, slow_start; | 3093 Label extra_checks_or_miss, slow_start; |
2942 Label slow, non_function, wrap, cont; | 3094 Label slow, non_function, wrap, cont; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3033 | 3185 |
3034 // Goto miss case if we do not have a function. | 3186 // Goto miss case if we do not have a function. |
3035 __ GetObjectType(a1, a4, a4); | 3187 __ GetObjectType(a1, a4, a4); |
3036 __ Branch(&miss, ne, a4, Operand(JS_FUNCTION_TYPE)); | 3188 __ Branch(&miss, ne, a4, Operand(JS_FUNCTION_TYPE)); |
3037 | 3189 |
3038 // Make sure the function is not the Array() function, which requires special | 3190 // Make sure the function is not the Array() function, which requires special |
3039 // behavior on MISS. | 3191 // behavior on MISS. |
3040 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); | 3192 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); |
3041 __ Branch(&miss, eq, a1, Operand(a4)); | 3193 __ Branch(&miss, eq, a1, Operand(a4)); |
3042 | 3194 |
3195 // Some builtin functions require special handling, miss to the runtime. | |
3196 __ ld(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | |
3197 __ ld(t0, FieldMemOperand(t0, SharedFunctionInfo::kFunctionDataOffset)); | |
3198 __ Branch(&miss, ne, t0, Operand(Smi::FromInt(0))); | |
3199 | |
3043 // Update stats. | 3200 // Update stats. |
3044 __ ld(a4, FieldMemOperand(a2, with_types_offset)); | 3201 __ ld(a4, FieldMemOperand(a2, with_types_offset)); |
3045 __ Daddu(a4, a4, Operand(Smi::FromInt(1))); | 3202 __ Daddu(a4, a4, Operand(Smi::FromInt(1))); |
3046 __ sd(a4, FieldMemOperand(a2, with_types_offset)); | 3203 __ sd(a4, FieldMemOperand(a2, with_types_offset)); |
3047 | 3204 |
3048 // Store the function. Use a stub since we need a frame for allocation. | 3205 // Store the function. Use a stub since we need a frame for allocation. |
3049 // a2 - vector | 3206 // a2 - vector |
3050 // a3 - slot | 3207 // a3 - slot |
3051 // a1 - function | 3208 // a1 - function |
3052 { | 3209 { |
(...skipping 1574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4627 } | 4784 } |
4628 | 4785 |
4629 | 4786 |
4630 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { | 4787 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { |
4631 EmitLoadTypeFeedbackVector(masm, a2); | 4788 EmitLoadTypeFeedbackVector(masm, a2); |
4632 CallIC_ArrayStub stub(isolate(), state()); | 4789 CallIC_ArrayStub stub(isolate(), state()); |
4633 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 4790 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
4634 } | 4791 } |
4635 | 4792 |
4636 | 4793 |
4794 void CallIC_RoundTrampolineStub::Generate(MacroAssembler* masm) { | |
4795 EmitLoadTypeFeedbackVector(masm, a2); | |
4796 CallIC_RoundStub stub(isolate(), state()); | |
4797 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | |
4798 } | |
4799 | |
4800 | |
4801 void CallIC_FloorTrampolineStub::Generate(MacroAssembler* masm) { | |
4802 EmitLoadTypeFeedbackVector(masm, a2); | |
4803 CallIC_FloorStub stub(isolate(), state()); | |
4804 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | |
4805 } | |
4806 | |
4807 | |
4808 void CallIC_CeilTrampolineStub::Generate(MacroAssembler* masm) { | |
4809 EmitLoadTypeFeedbackVector(masm, a2); | |
4810 CallIC_CeilStub stub(isolate(), state()); | |
4811 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | |
4812 } | |
4813 | |
4814 | |
4637 void VectorRawLoadStub::Generate(MacroAssembler* masm) { | 4815 void VectorRawLoadStub::Generate(MacroAssembler* masm) { |
4638 GenerateImpl(masm, false); | 4816 GenerateImpl(masm, false); |
4639 } | 4817 } |
4640 | 4818 |
4641 | 4819 |
4642 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) { | 4820 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) { |
4643 GenerateImpl(masm, true); | 4821 GenerateImpl(masm, true); |
4644 } | 4822 } |
4645 | 4823 |
4646 | 4824 |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5537 kStackUnwindSpace, kInvalidStackOffset, | 5715 kStackUnwindSpace, kInvalidStackOffset, |
5538 MemOperand(fp, 6 * kPointerSize), NULL); | 5716 MemOperand(fp, 6 * kPointerSize), NULL); |
5539 } | 5717 } |
5540 | 5718 |
5541 | 5719 |
5542 #undef __ | 5720 #undef __ |
5543 | 5721 |
5544 } } // namespace v8::internal | 5722 } } // namespace v8::internal |
5545 | 5723 |
5546 #endif // V8_TARGET_ARCH_MIPS64 | 5724 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |