Chromium Code Reviews| Index: src/arm/stub-cache-arm.cc |
| diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc |
| index f2d45e190af4679ee81638192e871e8e230b4d78..cf92b692ae97107dcc516aedde97e999888fb0b4 100644 |
| --- a/src/arm/stub-cache-arm.cc |
| +++ b/src/arm/stub-cache-arm.cc |
| @@ -978,63 +978,10 @@ static void StoreIntAsFloat(MacroAssembler* masm, |
| Register fval, |
| Register scratch1, |
| Register scratch2) { |
| - if (CpuFeatures::IsSupported(VFP2)) { |
| - CpuFeatureScope scope(masm, VFP2); |
| - __ vmov(s0, ival); |
| - __ add(scratch1, dst, Operand(wordoffset, LSL, 2)); |
| - __ vcvt_f32_s32(s0, s0); |
| - __ vstr(s0, scratch1, 0); |
| - } else { |
| - Label not_special, done; |
| - // Move sign bit from source to destination. This works because the sign |
| - // bit in the exponent word of the double has the same position and polarity |
| - // as the 2's complement sign bit in a Smi. |
| - ASSERT(kBinary32SignMask == 0x80000000u); |
| - |
| - __ and_(fval, ival, Operand(kBinary32SignMask), SetCC); |
| - // Negate value if it is negative. |
| - __ rsb(ival, ival, Operand::Zero(), LeaveCC, ne); |
| - |
| - // We have -1, 0 or 1, which we treat specially. Register ival contains |
| - // absolute value: it is either equal to 1 (special case of -1 and 1), |
| - // greater than 1 (not a special case) or less than 1 (special case of 0). |
| - __ cmp(ival, Operand(1)); |
| - __ b(gt, ¬_special); |
| - |
| - // For 1 or -1 we need to or in the 0 exponent (biased). |
| - static const uint32_t exponent_word_for_1 = |
| - kBinary32ExponentBias << kBinary32ExponentShift; |
| - |
| - __ orr(fval, fval, Operand(exponent_word_for_1), LeaveCC, eq); |
| - __ b(&done); |
| - |
| - __ bind(¬_special); |
| - // Count leading zeros. |
| - // Gets the wrong answer for 0, but we already checked for that case above. |
| - Register zeros = scratch2; |
| - __ CountLeadingZeros(zeros, ival, scratch1); |
| - |
| - // Compute exponent and or it into the exponent register. |
| - __ rsb(scratch1, |
| - zeros, |
| - Operand((kBitsPerInt - 1) + kBinary32ExponentBias)); |
| - |
| - __ orr(fval, |
| - fval, |
| - Operand(scratch1, LSL, kBinary32ExponentShift)); |
| - |
| - // Shift up the source chopping the top bit off. |
| - __ add(zeros, zeros, Operand(1)); |
| - // This wouldn't work for 1 and -1 as the shift would be 32 which means 0. |
| - __ mov(ival, Operand(ival, LSL, zeros)); |
| - // And the top (top 20 bits). |
| - __ orr(fval, |
| - fval, |
| - Operand(ival, LSR, kBitsPerInt - kBinary32MantissaBits)); |
| - |
| - __ bind(&done); |
| - __ str(fval, MemOperand(dst, wordoffset, LSL, 2)); |
| - } |
| + __ vmov(s0, ival); |
| + __ add(scratch1, dst, Operand(wordoffset, LSL, 2)); |
| + __ vcvt_f32_s32(s0, s0); |
| + __ vstr(s0, scratch1, 0); |
| } |
| @@ -2089,11 +2036,6 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| // -- sp[argc * 4] : receiver |
| // ----------------------------------- |
| - if (!CpuFeatures::IsSupported(VFP2)) { |
| - return Handle<Code>::null(); |
| - } |
| - |
| - CpuFeatureScope scope_vfp2(masm(), VFP2); |
| const int argc = arguments().immediate(); |
| // If the object is not a JSObject or we got an unexpected number of |
| // arguments, bail out to the regular call. |
| @@ -3133,36 +3075,6 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( |
| } |
| -static bool IsElementTypeSigned(ElementsKind elements_kind) { |
| - switch (elements_kind) { |
| - case EXTERNAL_BYTE_ELEMENTS: |
| - case EXTERNAL_SHORT_ELEMENTS: |
| - case EXTERNAL_INT_ELEMENTS: |
| - return true; |
| - |
| - case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| - case EXTERNAL_PIXEL_ELEMENTS: |
| - return false; |
| - |
| - case EXTERNAL_FLOAT_ELEMENTS: |
| - case EXTERNAL_DOUBLE_ELEMENTS: |
| - case FAST_ELEMENTS: |
| - case FAST_SMI_ELEMENTS: |
| - case FAST_DOUBLE_ELEMENTS: |
| - case FAST_HOLEY_ELEMENTS: |
| - case FAST_HOLEY_SMI_ELEMENTS: |
| - case FAST_HOLEY_DOUBLE_ELEMENTS: |
| - case DICTIONARY_ELEMENTS: |
| - case NON_STRICT_ARGUMENTS_ELEMENTS: |
| - UNREACHABLE(); |
| - return false; |
| - } |
| - return false; |
| -} |
| - |
| - |
| static void GenerateSmiKeyCheck(MacroAssembler* masm, |
| Register key, |
| Register scratch0, |
| @@ -3170,29 +3082,23 @@ static void GenerateSmiKeyCheck(MacroAssembler* masm, |
| DwVfpRegister double_scratch0, |
| DwVfpRegister double_scratch1, |
| Label* fail) { |
| - if (CpuFeatures::IsSupported(VFP2)) { |
| - CpuFeatureScope scope(masm, VFP2); |
| - Label key_ok; |
| - // Check for smi or a smi inside a heap number. We convert the heap |
| - // number and check if the conversion is exact and fits into the smi |
| - // range. |
| - __ JumpIfSmi(key, &key_ok); |
| - __ CheckMap(key, |
| - scratch0, |
| - Heap::kHeapNumberMapRootIndex, |
| - fail, |
| - DONT_DO_SMI_CHECK); |
| - __ sub(ip, key, Operand(kHeapObjectTag)); |
| - __ vldr(double_scratch0, ip, HeapNumber::kValueOffset); |
| - __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1); |
| - __ b(ne, fail); |
| - __ TrySmiTag(scratch0, fail, scratch1); |
| - __ mov(key, scratch0); |
| - __ bind(&key_ok); |
| - } else { |
| - // Check that the key is a smi. |
| - __ JumpIfNotSmi(key, fail); |
| - } |
| + Label key_ok; |
| + // Check for smi or a smi inside a heap number. We convert the heap |
| + // number and check if the conversion is exact and fits into the smi |
| + // range. |
| + __ JumpIfSmi(key, &key_ok); |
| + __ CheckMap(key, |
| + scratch0, |
| + Heap::kHeapNumberMapRootIndex, |
| + fail, |
| + DONT_DO_SMI_CHECK); |
| + __ sub(ip, key, Operand(kHeapObjectTag)); |
| + __ vldr(double_scratch0, ip, HeapNumber::kValueOffset); |
| + __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1); |
| + __ b(ne, fail); |
| + __ TrySmiTag(scratch0, fail, scratch1); |
| + __ mov(key, scratch0); |
| + __ bind(&key_ok); |
| } |
| @@ -3268,22 +3174,12 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( |
| __ add(r3, r3, Operand(key, LSL, 2)); |
| // r3: effective address of the double element |
| FloatingPointHelper::Destination destination; |
| - if (CpuFeatures::IsSupported(VFP2)) { |
| - destination = FloatingPointHelper::kVFPRegisters; |
| - } else { |
| - destination = FloatingPointHelper::kCoreRegisters; |
| - } |
| + destination = FloatingPointHelper::kVFPRegisters; |
| FloatingPointHelper::ConvertIntToDouble( |
| masm, r5, destination, |
| d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent. |
| r4, s2); // These are: scratch2, single_scratch. |
| - if (destination == FloatingPointHelper::kVFPRegisters) { |
| - CpuFeatureScope scope(masm, VFP2); |
| - __ vstr(d0, r3, 0); |
| - } else { |
| - __ str(r6, MemOperand(r3, 0)); |
| - __ str(r7, MemOperand(r3, Register::kSizeInBytes)); |
| - } |
| + __ vstr(d0, r3, 0); |
| break; |
| case FAST_ELEMENTS: |
| case FAST_SMI_ELEMENTS: |
| @@ -3313,200 +3209,58 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( |
| // The WebGL specification leaves the behavior of storing NaN and |
| // +/-Infinity into integer arrays basically undefined. For more |
| // reproducible behavior, convert these to zero. |
| - if (CpuFeatures::IsSupported(VFP2)) { |
| - CpuFeatureScope scope(masm, VFP2); |
| - |
| - if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| - // vldr requires offset to be a multiple of 4 so we can not |
| - // include -kHeapObjectTag into it. |
| - __ sub(r5, r0, Operand(kHeapObjectTag)); |
| - __ vldr(d0, r5, HeapNumber::kValueOffset); |
| - __ add(r5, r3, Operand(key, LSL, 1)); |
| - __ vcvt_f32_f64(s0, d0); |
| - __ vstr(s0, r5, 0); |
| - } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| - __ sub(r5, r0, Operand(kHeapObjectTag)); |
| - __ vldr(d0, r5, HeapNumber::kValueOffset); |
| - __ add(r5, r3, Operand(key, LSL, 2)); |
| - __ vstr(d0, r5, 0); |
| - } else { |
| - // Hoisted load. vldr requires offset to be a multiple of 4 so we can |
| - // not include -kHeapObjectTag into it. |
| - __ sub(r5, value, Operand(kHeapObjectTag)); |
| - __ vldr(d0, r5, HeapNumber::kValueOffset); |
| - __ ECMAToInt32VFP(r5, d0, d1, r6, r7, r9); |
| - |
| - switch (elements_kind) { |
| - case EXTERNAL_BYTE_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| - __ strb(r5, MemOperand(r3, key, LSR, 1)); |
| - break; |
| - case EXTERNAL_SHORT_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| - __ strh(r5, MemOperand(r3, key, LSL, 0)); |
| - break; |
| - case EXTERNAL_INT_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| - __ str(r5, MemOperand(r3, key, LSL, 1)); |
| - break; |
| - case EXTERNAL_PIXEL_ELEMENTS: |
| - case EXTERNAL_FLOAT_ELEMENTS: |
| - case EXTERNAL_DOUBLE_ELEMENTS: |
| - case FAST_ELEMENTS: |
| - case FAST_SMI_ELEMENTS: |
| - case FAST_DOUBLE_ELEMENTS: |
| - case FAST_HOLEY_ELEMENTS: |
| - case FAST_HOLEY_SMI_ELEMENTS: |
| - case FAST_HOLEY_DOUBLE_ELEMENTS: |
| - case DICTIONARY_ELEMENTS: |
| - case NON_STRICT_ARGUMENTS_ELEMENTS: |
| - UNREACHABLE(); |
| - break; |
| - } |
| + |
| + if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| + // vldr requires offset to be a multiple of 4 so we can not |
| + // include -kHeapObjectTag into it. |
| + __ sub(r5, r0, Operand(kHeapObjectTag)); |
| + __ vldr(d0, r5, HeapNumber::kValueOffset); |
| + __ add(r5, r3, Operand(key, LSL, 1)); |
| + __ vcvt_f32_f64(s0, d0); |
| + __ vstr(s0, r5, 0); |
| + } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| + __ sub(r5, r0, Operand(kHeapObjectTag)); |
| + __ vldr(d0, r5, HeapNumber::kValueOffset); |
| + __ add(r5, r3, Operand(key, LSL, 2)); |
| + __ vstr(d0, r5, 0); |
| + } else { |
| + // Hoisted load. vldr requires offset to be a multiple of 4 so we can |
| + // not include -kHeapObjectTag into it. |
| + __ sub(r5, value, Operand(kHeapObjectTag)); |
| + __ vldr(d0, r5, HeapNumber::kValueOffset); |
| + __ ECMAToInt32VFP(r5, d0, d1, r6, r7, r9); |
| + |
| + switch (elements_kind) { |
| + case EXTERNAL_BYTE_ELEMENTS: |
| + case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| + __ strb(r5, MemOperand(r3, key, LSR, 1)); |
| + break; |
| + case EXTERNAL_SHORT_ELEMENTS: |
| + case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| + __ strh(r5, MemOperand(r3, key, LSL, 0)); |
| + break; |
| + case EXTERNAL_INT_ELEMENTS: |
| + case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| + __ str(r5, MemOperand(r3, key, LSL, 1)); |
| + break; |
| + case EXTERNAL_PIXEL_ELEMENTS: |
| + case EXTERNAL_FLOAT_ELEMENTS: |
| + case EXTERNAL_DOUBLE_ELEMENTS: |
| + case FAST_ELEMENTS: |
| + case FAST_SMI_ELEMENTS: |
| + case FAST_DOUBLE_ELEMENTS: |
| + case FAST_HOLEY_ELEMENTS: |
| + case FAST_HOLEY_SMI_ELEMENTS: |
| + case FAST_HOLEY_DOUBLE_ELEMENTS: |
| + case DICTIONARY_ELEMENTS: |
| + case NON_STRICT_ARGUMENTS_ELEMENTS: |
| + UNREACHABLE(); |
| + break; |
| } |
|
Rodolph Perfetta
2013/04/04 15:30:04
the if (elements_kind == EXTERNAL_FLOAT_ELEMENTS)
danno
2013/04/08 19:45:33
Done.
|
| // Entry registers are intact, r0 holds the value which is the return |
| // value. |
| __ Ret(); |
| - } else { |
| - // VFP3 is not available do manual conversions. |
| - __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset)); |
| - __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset)); |
| - |
| - if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| - Label done, nan_or_infinity_or_zero; |
| - static const int kMantissaInHiWordShift = |
| - kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; |
| - |
| - static const int kMantissaInLoWordShift = |
| - kBitsPerInt - kMantissaInHiWordShift; |
| - |
| - // Test for all special exponent values: zeros, subnormal numbers, NaNs |
| - // and infinities. All these should be converted to 0. |
| - __ mov(r7, Operand(HeapNumber::kExponentMask)); |
| - __ and_(r9, r5, Operand(r7), SetCC); |
| - __ b(eq, &nan_or_infinity_or_zero); |
| - |
| - __ teq(r9, Operand(r7)); |
| - __ mov(r9, Operand(kBinary32ExponentMask), LeaveCC, eq); |
| - __ b(eq, &nan_or_infinity_or_zero); |
| - |
| - // Rebias exponent. |
| - __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift)); |
| - __ add(r9, |
| - r9, |
| - Operand(kBinary32ExponentBias - HeapNumber::kExponentBias)); |
| - |
| - __ cmp(r9, Operand(kBinary32MaxExponent)); |
| - __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, gt); |
| - __ orr(r5, r5, Operand(kBinary32ExponentMask), LeaveCC, gt); |
| - __ b(gt, &done); |
| - |
| - __ cmp(r9, Operand(kBinary32MinExponent)); |
| - __ and_(r5, r5, Operand(HeapNumber::kSignMask), LeaveCC, lt); |
| - __ b(lt, &done); |
| - |
| - __ and_(r7, r5, Operand(HeapNumber::kSignMask)); |
| - __ and_(r5, r5, Operand(HeapNumber::kMantissaMask)); |
| - __ orr(r7, r7, Operand(r5, LSL, kMantissaInHiWordShift)); |
| - __ orr(r7, r7, Operand(r6, LSR, kMantissaInLoWordShift)); |
| - __ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift)); |
| - |
| - __ bind(&done); |
| - __ str(r5, MemOperand(r3, key, LSL, 1)); |
| - // Entry registers are intact, r0 holds the value which is the return |
| - // value. |
| - __ Ret(); |
| - |
| - __ bind(&nan_or_infinity_or_zero); |
| - __ and_(r7, r5, Operand(HeapNumber::kSignMask)); |
| - __ and_(r5, r5, Operand(HeapNumber::kMantissaMask)); |
| - __ orr(r9, r9, r7); |
| - __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift)); |
| - __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift)); |
| - __ b(&done); |
| - } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| - __ add(r7, r3, Operand(key, LSL, 2)); |
| - // r7: effective address of destination element. |
| - __ str(r6, MemOperand(r7, 0)); |
| - __ str(r5, MemOperand(r7, Register::kSizeInBytes)); |
| - __ Ret(); |
| - } else { |
| - bool is_signed_type = IsElementTypeSigned(elements_kind); |
| - int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; |
| - int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; |
| - |
| - Label done, sign; |
| - |
| - // Test for all special exponent values: zeros, subnormal numbers, NaNs |
| - // and infinities. All these should be converted to 0. |
| - __ mov(r7, Operand(HeapNumber::kExponentMask)); |
| - __ and_(r9, r5, Operand(r7), SetCC); |
| - __ mov(r5, Operand::Zero(), LeaveCC, eq); |
| - __ b(eq, &done); |
| - |
| - __ teq(r9, Operand(r7)); |
| - __ mov(r5, Operand::Zero(), LeaveCC, eq); |
| - __ b(eq, &done); |
| - |
| - // Unbias exponent. |
| - __ mov(r9, Operand(r9, LSR, HeapNumber::kExponentShift)); |
| - __ sub(r9, r9, Operand(HeapNumber::kExponentBias), SetCC); |
| - // If exponent is negative then result is 0. |
| - __ mov(r5, Operand::Zero(), LeaveCC, mi); |
| - __ b(mi, &done); |
| - |
| - // If exponent is too big then result is minimal value. |
| - __ cmp(r9, Operand(meaningfull_bits - 1)); |
| - __ mov(r5, Operand(min_value), LeaveCC, ge); |
| - __ b(ge, &done); |
| - |
| - __ and_(r7, r5, Operand(HeapNumber::kSignMask), SetCC); |
| - __ and_(r5, r5, Operand(HeapNumber::kMantissaMask)); |
| - __ orr(r5, r5, Operand(1u << HeapNumber::kMantissaBitsInTopWord)); |
| - |
| - __ rsb(r9, r9, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC); |
| - __ mov(r5, Operand(r5, LSR, r9), LeaveCC, pl); |
| - __ b(pl, &sign); |
| - |
| - __ rsb(r9, r9, Operand::Zero()); |
| - __ mov(r5, Operand(r5, LSL, r9)); |
| - __ rsb(r9, r9, Operand(meaningfull_bits)); |
| - __ orr(r5, r5, Operand(r6, LSR, r9)); |
| - |
| - __ bind(&sign); |
| - __ teq(r7, Operand::Zero()); |
| - __ rsb(r5, r5, Operand::Zero(), LeaveCC, ne); |
| - |
| - __ bind(&done); |
| - switch (elements_kind) { |
| - case EXTERNAL_BYTE_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| - __ strb(r5, MemOperand(r3, key, LSR, 1)); |
| - break; |
| - case EXTERNAL_SHORT_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| - __ strh(r5, MemOperand(r3, key, LSL, 0)); |
| - break; |
| - case EXTERNAL_INT_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| - __ str(r5, MemOperand(r3, key, LSL, 1)); |
| - break; |
| - case EXTERNAL_PIXEL_ELEMENTS: |
| - case EXTERNAL_FLOAT_ELEMENTS: |
| - case EXTERNAL_DOUBLE_ELEMENTS: |
| - case FAST_ELEMENTS: |
| - case FAST_SMI_ELEMENTS: |
| - case FAST_DOUBLE_ELEMENTS: |
| - case FAST_HOLEY_ELEMENTS: |
| - case FAST_HOLEY_SMI_ELEMENTS: |
| - case FAST_HOLEY_DOUBLE_ELEMENTS: |
| - case DICTIONARY_ELEMENTS: |
| - case NON_STRICT_ARGUMENTS_ELEMENTS: |
| - UNREACHABLE(); |
| - break; |
| - } |
| - } |
| } |
| } |