Index: src/arm/stub-cache-arm.cc |
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc |
index 676fa0f5ea743889644c2fd26411fb4e354989ec..d03eb36e07646010c114432c91148e80b06af621 100644 |
--- a/src/arm/stub-cache-arm.cc |
+++ b/src/arm/stub-cache-arm.cc |
@@ -975,66 +975,11 @@ static void StoreIntAsFloat(MacroAssembler* masm, |
Register dst, |
Register wordoffset, |
Register ival, |
- 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)); |
- } |
+ Register scratch1) { |
+ __ vmov(s0, ival); |
+ __ add(scratch1, dst, Operand(wordoffset, LSL, 2)); |
+ __ vcvt_f32_s32(s0, s0); |
+ __ vstr(s0, scratch1, 0); |
} |
@@ -2082,11 +2027,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. |
@@ -3126,36 +3066,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, |
@@ -3163,29 +3073,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); |
} |
@@ -3255,28 +3159,18 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( |
case EXTERNAL_FLOAT_ELEMENTS: |
// Perform int-to-float conversion and store to memory. |
__ SmiUntag(r4, key); |
- StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); |
+ StoreIntAsFloat(masm, r3, r4, r5, r7); |
break; |
case EXTERNAL_DOUBLE_ELEMENTS: |
__ 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: |
@@ -3306,201 +3200,59 @@ 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; |
- } |
- } |
- // Entry registers are intact, r0 holds the value which is the return |
- // value. |
- __ Ret(); |
+ 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 { |
- // 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; |
- } |
+ // 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); |
+ __ ECMAToInt32(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; |
} |
} |
+ |
+ // Entry registers are intact, r0 holds the value which is the return |
+ // value. |
+ __ Ret(); |
} |
// Slow case, key and receiver still in r0 and r1. |