OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2544 // Jump to the cached code (tail call). | 2544 // Jump to the cached code (tail call). |
2545 Counters* counters = masm()->isolate()->counters(); | 2545 Counters* counters = masm()->isolate()->counters(); |
2546 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 2546 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); |
2547 ASSERT(function->is_compiled()); | 2547 ASSERT(function->is_compiled()); |
2548 Handle<Code> code(function->code()); | 2548 Handle<Code> code(function->code()); |
2549 ParameterCount expected(function->shared()->formal_parameter_count()); | 2549 ParameterCount expected(function->shared()->formal_parameter_count()); |
2550 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2550 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
2551 ? CALL_AS_FUNCTION | 2551 ? CALL_AS_FUNCTION |
2552 : CALL_AS_METHOD; | 2552 : CALL_AS_METHOD; |
2553 if (V8::UseCrankshaft()) { | 2553 if (V8::UseCrankshaft()) { |
2554 UNIMPLEMENTED_MIPS(); | 2554 // TODO(kasperl): For now, we always call indirectly through the |
| 2555 // code field in the function to allow recompilation to take effect |
| 2556 // without changing any of the call sites. |
| 2557 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 2558 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, |
| 2559 NullCallWrapper(), call_kind); |
2555 } else { | 2560 } else { |
2556 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET, | 2561 __ InvokeCode(code, expected, arguments(), RelocInfo::CODE_TARGET, |
2557 JUMP_FUNCTION, call_kind); | 2562 JUMP_FUNCTION, call_kind); |
2558 } | 2563 } |
2559 | 2564 |
2560 // Handle call cache miss. | 2565 // Handle call cache miss. |
2561 __ bind(&miss); | 2566 __ bind(&miss); |
2562 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); | 2567 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); |
2563 MaybeObject* maybe_result = GenerateMissBranch(); | 2568 MaybeObject* maybe_result = GenerateMissBranch(); |
2564 if (maybe_result->IsFailure()) return maybe_result; | 2569 if (maybe_result->IsFailure()) return maybe_result; |
(...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3821 | 3826 |
3822 // This stub is meant to be tail-jumped to, the receiver must already | 3827 // This stub is meant to be tail-jumped to, the receiver must already |
3823 // have been verified by the caller to not be a smi. | 3828 // have been verified by the caller to not be a smi. |
3824 | 3829 |
3825 // Check that the key is a smi. | 3830 // Check that the key is a smi. |
3826 __ JumpIfNotSmi(key, &miss_force_generic); | 3831 __ JumpIfNotSmi(key, &miss_force_generic); |
3827 | 3832 |
3828 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 3833 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
3829 | 3834 |
3830 // Check that the index is in range. | 3835 // Check that the index is in range. |
3831 __ SmiUntag(t0, key); | |
3832 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); | 3836 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); |
3833 // Unsigned comparison catches both negative and too-large values. | 3837 // Unsigned comparison catches both negative and too-large values. |
3834 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); | 3838 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); |
3835 | 3839 |
3836 // Handle both smis and HeapNumbers in the fast path. Go to the | 3840 // Handle both smis and HeapNumbers in the fast path. Go to the |
3837 // runtime for all other kinds of values. | 3841 // runtime for all other kinds of values. |
3838 // a3: external array. | 3842 // a3: external array. |
3839 // t0: key (integer). | |
3840 | 3843 |
3841 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { | 3844 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { |
3842 // Double to pixel conversion is only implemented in the runtime for now. | 3845 // Double to pixel conversion is only implemented in the runtime for now. |
3843 __ JumpIfNotSmi(value, &slow); | 3846 __ JumpIfNotSmi(value, &slow); |
3844 } else { | 3847 } else { |
3845 __ JumpIfNotSmi(value, &check_heap_number); | 3848 __ JumpIfNotSmi(value, &check_heap_number); |
3846 } | 3849 } |
3847 __ SmiUntag(t1, value); | 3850 __ SmiUntag(t1, value); |
3848 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); | 3851 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); |
3849 | 3852 |
3850 // a3: base pointer of external storage. | 3853 // a3: base pointer of external storage. |
3851 // t0: key (integer). | |
3852 // t1: value (integer). | 3854 // t1: value (integer). |
3853 | 3855 |
3854 switch (elements_kind) { | 3856 switch (elements_kind) { |
3855 case EXTERNAL_PIXEL_ELEMENTS: { | 3857 case EXTERNAL_PIXEL_ELEMENTS: { |
3856 // Clamp the value to [0..255]. | 3858 // Clamp the value to [0..255]. |
3857 // v0 is used as a scratch register here. | 3859 // v0 is used as a scratch register here. |
3858 Label done; | 3860 Label done; |
3859 __ li(v0, Operand(255)); | 3861 __ li(v0, Operand(255)); |
3860 // Normal branch: nop in delay slot. | 3862 // Normal branch: nop in delay slot. |
3861 __ Branch(&done, gt, t1, Operand(v0)); | 3863 __ Branch(&done, gt, t1, Operand(v0)); |
3862 // Use delay slot in this branch. | 3864 // Use delay slot in this branch. |
3863 __ Branch(USE_DELAY_SLOT, &done, lt, t1, Operand(zero_reg)); | 3865 __ Branch(USE_DELAY_SLOT, &done, lt, t1, Operand(zero_reg)); |
3864 __ mov(v0, zero_reg); // In delay slot. | 3866 __ mov(v0, zero_reg); // In delay slot. |
3865 __ mov(v0, t1); // Value is in range 0..255. | 3867 __ mov(v0, t1); // Value is in range 0..255. |
3866 __ bind(&done); | 3868 __ bind(&done); |
3867 __ mov(t1, v0); | 3869 __ mov(t1, v0); |
3868 __ addu(t8, a3, t0); | 3870 |
| 3871 __ srl(t8, key, 1); |
| 3872 __ addu(t8, a3, t8); |
3869 __ sb(t1, MemOperand(t8, 0)); | 3873 __ sb(t1, MemOperand(t8, 0)); |
3870 } | 3874 } |
3871 break; | 3875 break; |
3872 case EXTERNAL_BYTE_ELEMENTS: | 3876 case EXTERNAL_BYTE_ELEMENTS: |
3873 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3877 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3874 __ addu(t8, a3, t0); | 3878 __ srl(t8, key, 1); |
| 3879 __ addu(t8, a3, t8); |
3875 __ sb(t1, MemOperand(t8, 0)); | 3880 __ sb(t1, MemOperand(t8, 0)); |
3876 break; | 3881 break; |
3877 case EXTERNAL_SHORT_ELEMENTS: | 3882 case EXTERNAL_SHORT_ELEMENTS: |
3878 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3883 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3879 __ sll(t8, t0, 1); | 3884 __ addu(t8, a3, key); |
3880 __ addu(t8, a3, t8); | |
3881 __ sh(t1, MemOperand(t8, 0)); | 3885 __ sh(t1, MemOperand(t8, 0)); |
3882 break; | 3886 break; |
3883 case EXTERNAL_INT_ELEMENTS: | 3887 case EXTERNAL_INT_ELEMENTS: |
3884 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3888 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3885 __ sll(t8, t0, 2); | 3889 __ sll(t8, key, 1); |
3886 __ addu(t8, a3, t8); | 3890 __ addu(t8, a3, t8); |
3887 __ sw(t1, MemOperand(t8, 0)); | 3891 __ sw(t1, MemOperand(t8, 0)); |
3888 break; | 3892 break; |
3889 case EXTERNAL_FLOAT_ELEMENTS: | 3893 case EXTERNAL_FLOAT_ELEMENTS: |
3890 // Perform int-to-float conversion and store to memory. | 3894 // Perform int-to-float conversion and store to memory. |
| 3895 __ SmiUntag(t0, key); |
3891 StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4); | 3896 StoreIntAsFloat(masm, a3, t0, t1, t2, t3, t4); |
3892 break; | 3897 break; |
3893 case EXTERNAL_DOUBLE_ELEMENTS: | 3898 case EXTERNAL_DOUBLE_ELEMENTS: |
3894 __ sll(t8, t0, 3); | 3899 __ sll(t8, key, 2); |
3895 __ addu(a3, a3, t8); | 3900 __ addu(a3, a3, t8); |
3896 // a3: effective address of the double element | 3901 // a3: effective address of the double element |
3897 FloatingPointHelper::Destination destination; | 3902 FloatingPointHelper::Destination destination; |
3898 if (CpuFeatures::IsSupported(FPU)) { | 3903 if (CpuFeatures::IsSupported(FPU)) { |
3899 destination = FloatingPointHelper::kFPURegisters; | 3904 destination = FloatingPointHelper::kFPURegisters; |
3900 } else { | 3905 } else { |
3901 destination = FloatingPointHelper::kCoreRegisters; | 3906 destination = FloatingPointHelper::kCoreRegisters; |
3902 } | 3907 } |
3903 FloatingPointHelper::ConvertIntToDouble( | 3908 FloatingPointHelper::ConvertIntToDouble( |
3904 masm, t1, destination, | 3909 masm, t1, destination, |
3905 f0, t2, t3, // These are: double_dst, dst1, dst2. | 3910 f0, t2, t3, // These are: double_dst, dst1, dst2. |
3906 t0, f2); // These are: scratch2, single_scratch. | 3911 t0, f2); // These are: scratch2, single_scratch. |
3907 if (destination == FloatingPointHelper::kFPURegisters) { | 3912 if (destination == FloatingPointHelper::kFPURegisters) { |
3908 CpuFeatures::Scope scope(FPU); | 3913 CpuFeatures::Scope scope(FPU); |
3909 __ sdc1(f0, MemOperand(a3, 0)); | 3914 __ sdc1(f0, MemOperand(a3, 0)); |
3910 } else { | 3915 } else { |
3911 __ sw(t2, MemOperand(a3, 0)); | 3916 __ sw(t2, MemOperand(a3, 0)); |
3912 __ sw(t3, MemOperand(a3, Register::kSizeInBytes)); | 3917 __ sw(t3, MemOperand(a3, Register::kSizeInBytes)); |
3913 } | 3918 } |
3914 break; | 3919 break; |
3915 case FAST_ELEMENTS: | 3920 case FAST_ELEMENTS: |
3916 case FAST_DOUBLE_ELEMENTS: | 3921 case FAST_DOUBLE_ELEMENTS: |
3917 case DICTIONARY_ELEMENTS: | 3922 case DICTIONARY_ELEMENTS: |
3918 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3923 case NON_STRICT_ARGUMENTS_ELEMENTS: |
3919 UNREACHABLE(); | 3924 UNREACHABLE(); |
3920 break; | 3925 break; |
3921 } | 3926 } |
3922 | 3927 |
3923 // Entry registers are intact, a0 holds the value which is the return value. | 3928 // Entry registers are intact, a0 holds the value which is the return value. |
3924 __ mov(v0, value); | 3929 __ mov(v0, a0); |
3925 __ Ret(); | 3930 __ Ret(); |
3926 | 3931 |
3927 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { | 3932 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) { |
3928 // a3: external array. | 3933 // a3: external array. |
3929 // t0: index (integer). | |
3930 __ bind(&check_heap_number); | 3934 __ bind(&check_heap_number); |
3931 __ GetObjectType(value, t1, t2); | 3935 __ GetObjectType(value, t1, t2); |
3932 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE)); | 3936 __ Branch(&slow, ne, t2, Operand(HEAP_NUMBER_TYPE)); |
3933 | 3937 |
3934 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); | 3938 __ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset)); |
3935 | 3939 |
3936 // a3: base pointer of external storage. | 3940 // a3: base pointer of external storage. |
3937 // t0: key (integer). | |
3938 | 3941 |
3939 // The WebGL specification leaves the behavior of storing NaN and | 3942 // The WebGL specification leaves the behavior of storing NaN and |
3940 // +/-Infinity into integer arrays basically undefined. For more | 3943 // +/-Infinity into integer arrays basically undefined. For more |
3941 // reproducible behavior, convert these to zero. | 3944 // reproducible behavior, convert these to zero. |
3942 | 3945 |
3943 if (CpuFeatures::IsSupported(FPU)) { | 3946 if (CpuFeatures::IsSupported(FPU)) { |
3944 CpuFeatures::Scope scope(FPU); | 3947 CpuFeatures::Scope scope(FPU); |
3945 | 3948 |
3946 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset)); | 3949 __ ldc1(f0, FieldMemOperand(a0, HeapNumber::kValueOffset)); |
3947 | 3950 |
3948 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3951 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3949 __ cvt_s_d(f0, f0); | 3952 __ cvt_s_d(f0, f0); |
3950 __ sll(t8, t0, 2); | 3953 __ sll(t8, key, 1); |
3951 __ addu(t8, a3, t8); | 3954 __ addu(t8, a3, t8); |
3952 __ swc1(f0, MemOperand(t8, 0)); | 3955 __ swc1(f0, MemOperand(t8, 0)); |
3953 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3956 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3954 __ sll(t8, t0, 3); | 3957 __ sll(t8, key, 2); |
3955 __ addu(t8, a3, t8); | 3958 __ addu(t8, a3, t8); |
3956 __ sdc1(f0, MemOperand(t8, 0)); | 3959 __ sdc1(f0, MemOperand(t8, 0)); |
3957 } else { | 3960 } else { |
3958 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5); | 3961 __ EmitECMATruncate(t3, f0, f2, t2, t1, t5); |
3959 | 3962 |
3960 switch (elements_kind) { | 3963 switch (elements_kind) { |
3961 case EXTERNAL_BYTE_ELEMENTS: | 3964 case EXTERNAL_BYTE_ELEMENTS: |
3962 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3965 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3963 __ addu(t8, a3, t0); | 3966 __ srl(t8, key, 1); |
| 3967 __ addu(t8, a3, t8); |
3964 __ sb(t3, MemOperand(t8, 0)); | 3968 __ sb(t3, MemOperand(t8, 0)); |
3965 break; | 3969 break; |
3966 case EXTERNAL_SHORT_ELEMENTS: | 3970 case EXTERNAL_SHORT_ELEMENTS: |
3967 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3971 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3968 __ sll(t8, t0, 1); | 3972 __ addu(t8, a3, key); |
3969 __ addu(t8, a3, t8); | |
3970 __ sh(t3, MemOperand(t8, 0)); | 3973 __ sh(t3, MemOperand(t8, 0)); |
3971 break; | 3974 break; |
3972 case EXTERNAL_INT_ELEMENTS: | 3975 case EXTERNAL_INT_ELEMENTS: |
3973 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3976 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3974 __ sll(t8, t0, 2); | 3977 __ sll(t8, key, 1); |
3975 __ addu(t8, a3, t8); | 3978 __ addu(t8, a3, t8); |
3976 __ sw(t3, MemOperand(t8, 0)); | 3979 __ sw(t3, MemOperand(t8, 0)); |
3977 break; | 3980 break; |
3978 case EXTERNAL_PIXEL_ELEMENTS: | 3981 case EXTERNAL_PIXEL_ELEMENTS: |
3979 case EXTERNAL_FLOAT_ELEMENTS: | 3982 case EXTERNAL_FLOAT_ELEMENTS: |
3980 case EXTERNAL_DOUBLE_ELEMENTS: | 3983 case EXTERNAL_DOUBLE_ELEMENTS: |
3981 case FAST_ELEMENTS: | 3984 case FAST_ELEMENTS: |
3982 case FAST_DOUBLE_ELEMENTS: | 3985 case FAST_DOUBLE_ELEMENTS: |
3983 case DICTIONARY_ELEMENTS: | 3986 case DICTIONARY_ELEMENTS: |
3984 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3987 case NON_STRICT_ARGUMENTS_ELEMENTS: |
3985 UNREACHABLE(); | 3988 UNREACHABLE(); |
3986 break; | 3989 break; |
3987 } | 3990 } |
3988 } | 3991 } |
3989 | 3992 |
3990 // Entry registers are intact, a0 holds the value | 3993 // Entry registers are intact, a0 holds the value |
3991 // which is the return value. | 3994 // which is the return value. |
3992 __ mov(v0, value); | 3995 __ mov(v0, a0); |
3993 __ Ret(); | 3996 __ Ret(); |
3994 } else { | 3997 } else { |
3995 // FPU is not available, do manual conversions. | 3998 // FPU is not available, do manual conversions. |
3996 | 3999 |
3997 __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset)); | 4000 __ lw(t3, FieldMemOperand(value, HeapNumber::kExponentOffset)); |
3998 __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset)); | 4001 __ lw(t4, FieldMemOperand(value, HeapNumber::kMantissaOffset)); |
3999 | 4002 |
4000 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4003 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
4001 Label done, nan_or_infinity_or_zero; | 4004 Label done, nan_or_infinity_or_zero; |
4002 static const int kMantissaInHiWordShift = | 4005 static const int kMantissaInHiWordShift = |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4037 __ And(t7, t3, Operand(HeapNumber::kSignMask)); | 4040 __ And(t7, t3, Operand(HeapNumber::kSignMask)); |
4038 __ And(t3, t3, Operand(HeapNumber::kMantissaMask)); | 4041 __ And(t3, t3, Operand(HeapNumber::kMantissaMask)); |
4039 __ sll(t3, t3, kMantissaInHiWordShift); | 4042 __ sll(t3, t3, kMantissaInHiWordShift); |
4040 __ or_(t7, t7, t3); | 4043 __ or_(t7, t7, t3); |
4041 __ srl(t4, t4, kMantissaInLoWordShift); | 4044 __ srl(t4, t4, kMantissaInLoWordShift); |
4042 __ or_(t7, t7, t4); | 4045 __ or_(t7, t7, t4); |
4043 __ sll(t6, t6, kBinary32ExponentShift); | 4046 __ sll(t6, t6, kBinary32ExponentShift); |
4044 __ or_(t3, t7, t6); | 4047 __ or_(t3, t7, t6); |
4045 | 4048 |
4046 __ bind(&done); | 4049 __ bind(&done); |
4047 __ sll(t9, a1, 2); | 4050 __ sll(t9, key, 1); |
4048 __ addu(t9, a2, t9); | 4051 __ addu(t9, a2, t9); |
4049 __ sw(t3, MemOperand(t9, 0)); | 4052 __ sw(t3, MemOperand(t9, 0)); |
4050 | 4053 |
4051 // Entry registers are intact, a0 holds the value which is the return | 4054 // Entry registers are intact, a0 holds the value which is the return |
4052 // value. | 4055 // value. |
4053 __ mov(v0, value); | 4056 __ mov(v0, a0); |
4054 __ Ret(); | 4057 __ Ret(); |
4055 | 4058 |
4056 __ bind(&nan_or_infinity_or_zero); | 4059 __ bind(&nan_or_infinity_or_zero); |
4057 __ And(t7, t3, Operand(HeapNumber::kSignMask)); | 4060 __ And(t7, t3, Operand(HeapNumber::kSignMask)); |
4058 __ And(t3, t3, Operand(HeapNumber::kMantissaMask)); | 4061 __ And(t3, t3, Operand(HeapNumber::kMantissaMask)); |
4059 __ or_(t6, t6, t7); | 4062 __ or_(t6, t6, t7); |
4060 __ sll(t3, t3, kMantissaInHiWordShift); | 4063 __ sll(t3, t3, kMantissaInHiWordShift); |
4061 __ or_(t6, t6, t3); | 4064 __ or_(t6, t6, t3); |
4062 __ srl(t4, t4, kMantissaInLoWordShift); | 4065 __ srl(t4, t4, kMantissaInLoWordShift); |
4063 __ or_(t3, t6, t4); | 4066 __ or_(t3, t6, t4); |
4064 __ Branch(&done); | 4067 __ Branch(&done); |
4065 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4068 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
4066 __ sll(t8, t0, 3); | 4069 __ sll(t8, t0, 3); |
4067 __ addu(t8, a3, t8); | 4070 __ addu(t8, a3, t8); |
4068 // t8: effective address of destination element. | 4071 // t8: effective address of destination element. |
4069 __ sw(t4, MemOperand(t8, 0)); | 4072 __ sw(t4, MemOperand(t8, 0)); |
4070 __ sw(t3, MemOperand(t8, Register::kSizeInBytes)); | 4073 __ sw(t3, MemOperand(t8, Register::kSizeInBytes)); |
| 4074 __ mov(v0, a0); |
4071 __ Ret(); | 4075 __ Ret(); |
4072 } else { | 4076 } else { |
4073 bool is_signed_type = IsElementTypeSigned(elements_kind); | 4077 bool is_signed_type = IsElementTypeSigned(elements_kind); |
4074 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; | 4078 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; |
4075 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; | 4079 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; |
4076 | 4080 |
4077 Label done, sign; | 4081 Label done, sign; |
4078 | 4082 |
4079 // Test for all special exponent values: zeros, subnormal numbers, NaNs | 4083 // Test for all special exponent values: zeros, subnormal numbers, NaNs |
4080 // and infinities. All these should be converted to 0. | 4084 // and infinities. All these should be converted to 0. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4123 __ subu(t2, t3, zero_reg); | 4127 __ subu(t2, t3, zero_reg); |
4124 __ movz(t3, t2, t5); // Only if t5 is zero. | 4128 __ movz(t3, t2, t5); // Only if t5 is zero. |
4125 | 4129 |
4126 __ bind(&done); | 4130 __ bind(&done); |
4127 | 4131 |
4128 // Result is in t3. | 4132 // Result is in t3. |
4129 // This switch block should be exactly the same as above (FPU mode). | 4133 // This switch block should be exactly the same as above (FPU mode). |
4130 switch (elements_kind) { | 4134 switch (elements_kind) { |
4131 case EXTERNAL_BYTE_ELEMENTS: | 4135 case EXTERNAL_BYTE_ELEMENTS: |
4132 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 4136 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
4133 __ addu(t8, a3, t0); | 4137 __ srl(t8, key, 1); |
| 4138 __ addu(t8, a3, t8); |
4134 __ sb(t3, MemOperand(t8, 0)); | 4139 __ sb(t3, MemOperand(t8, 0)); |
4135 break; | 4140 break; |
4136 case EXTERNAL_SHORT_ELEMENTS: | 4141 case EXTERNAL_SHORT_ELEMENTS: |
4137 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 4142 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
4138 __ sll(t8, t0, 1); | 4143 __ addu(t8, a3, key); |
4139 __ addu(t8, a3, t8); | |
4140 __ sh(t3, MemOperand(t8, 0)); | 4144 __ sh(t3, MemOperand(t8, 0)); |
4141 break; | 4145 break; |
4142 case EXTERNAL_INT_ELEMENTS: | 4146 case EXTERNAL_INT_ELEMENTS: |
4143 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 4147 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
4144 __ sll(t8, t0, 2); | 4148 __ sll(t8, key, 1); |
4145 __ addu(t8, a3, t8); | 4149 __ addu(t8, a3, t8); |
4146 __ sw(t3, MemOperand(t8, 0)); | 4150 __ sw(t3, MemOperand(t8, 0)); |
4147 break; | 4151 break; |
4148 case EXTERNAL_PIXEL_ELEMENTS: | 4152 case EXTERNAL_PIXEL_ELEMENTS: |
4149 case EXTERNAL_FLOAT_ELEMENTS: | 4153 case EXTERNAL_FLOAT_ELEMENTS: |
4150 case EXTERNAL_DOUBLE_ELEMENTS: | 4154 case EXTERNAL_DOUBLE_ELEMENTS: |
4151 case FAST_ELEMENTS: | 4155 case FAST_ELEMENTS: |
4152 case FAST_DOUBLE_ELEMENTS: | 4156 case FAST_DOUBLE_ELEMENTS: |
4153 case DICTIONARY_ELEMENTS: | 4157 case DICTIONARY_ELEMENTS: |
4154 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4158 case NON_STRICT_ARGUMENTS_ELEMENTS: |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4488 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4492 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
4489 __ Jump(ic, RelocInfo::CODE_TARGET); | 4493 __ Jump(ic, RelocInfo::CODE_TARGET); |
4490 } | 4494 } |
4491 | 4495 |
4492 | 4496 |
4493 #undef __ | 4497 #undef __ |
4494 | 4498 |
4495 } } // namespace v8::internal | 4499 } } // namespace v8::internal |
4496 | 4500 |
4497 #endif // V8_TARGET_ARCH_MIPS | 4501 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |