OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1196 } | 1196 } |
1197 | 1197 |
1198 | 1198 |
1199 case Token::BIT_OR: | 1199 case Token::BIT_OR: |
1200 case Token::BIT_XOR: | 1200 case Token::BIT_XOR: |
1201 case Token::BIT_AND: { | 1201 case Token::BIT_AND: { |
1202 if (both_sides_are_smi) { | 1202 if (both_sides_are_smi) { |
1203 switch (op) { | 1203 switch (op) { |
1204 case Token::BIT_OR: __ orr(tos, tos, Operand(value)); break; | 1204 case Token::BIT_OR: __ orr(tos, tos, Operand(value)); break; |
1205 case Token::BIT_XOR: __ eor(tos, tos, Operand(value)); break; | 1205 case Token::BIT_XOR: __ eor(tos, tos, Operand(value)); break; |
1206 case Token::BIT_AND: __ and_(tos, tos, Operand(value)); break; | 1206 case Token::BIT_AND: __ And(tos, tos, Operand(value)); break; |
1207 default: UNREACHABLE(); | 1207 default: UNREACHABLE(); |
1208 } | 1208 } |
1209 frame_->EmitPush(tos, TypeInfo::Smi()); | 1209 frame_->EmitPush(tos, TypeInfo::Smi()); |
1210 } else { | 1210 } else { |
1211 DeferredCode* deferred = | 1211 DeferredCode* deferred = |
1212 new DeferredInlineSmiOperation(op, int_value, reversed, mode, tos); | 1212 new DeferredInlineSmiOperation(op, int_value, reversed, mode, tos); |
1213 __ tst(tos, Operand(kSmiTagMask)); | 1213 __ tst(tos, Operand(kSmiTagMask)); |
1214 deferred->Branch(ne); | 1214 deferred->Branch(ne); |
1215 switch (op) { | 1215 switch (op) { |
1216 case Token::BIT_OR: __ orr(tos, tos, Operand(value)); break; | 1216 case Token::BIT_OR: __ orr(tos, tos, Operand(value)); break; |
1217 case Token::BIT_XOR: __ eor(tos, tos, Operand(value)); break; | 1217 case Token::BIT_XOR: __ eor(tos, tos, Operand(value)); break; |
1218 case Token::BIT_AND: __ and_(tos, tos, Operand(value)); break; | 1218 case Token::BIT_AND: __ And(tos, tos, Operand(value)); break; |
1219 default: UNREACHABLE(); | 1219 default: UNREACHABLE(); |
1220 } | 1220 } |
1221 deferred->BindExit(); | 1221 deferred->BindExit(); |
1222 TypeInfo result_type = | 1222 TypeInfo result_type = |
1223 (op == Token::BIT_AND) ? TypeInfo::Smi() : TypeInfo::Integer32(); | 1223 (op == Token::BIT_AND) ? TypeInfo::Smi() : TypeInfo::Integer32(); |
1224 frame_->EmitPush(tos, result_type); | 1224 frame_->EmitPush(tos, result_type); |
1225 } | 1225 } |
1226 break; | 1226 break; |
1227 } | 1227 } |
1228 | 1228 |
(...skipping 5392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6621 __ orr(exponent, exponent, Operand(exponent_word_for_1), LeaveCC, eq); | 6621 __ orr(exponent, exponent, Operand(exponent_word_for_1), LeaveCC, eq); |
6622 // 1, 0 and -1 all have 0 for the second word. | 6622 // 1, 0 and -1 all have 0 for the second word. |
6623 __ mov(mantissa, Operand(0)); | 6623 __ mov(mantissa, Operand(0)); |
6624 __ Ret(); | 6624 __ Ret(); |
6625 | 6625 |
6626 __ bind(¬_special); | 6626 __ bind(¬_special); |
6627 // Count leading zeros. Uses mantissa for a scratch register on pre-ARM5. | 6627 // Count leading zeros. Uses mantissa for a scratch register on pre-ARM5. |
6628 // Gets the wrong answer for 0, but we already checked for that case above. | 6628 // Gets the wrong answer for 0, but we already checked for that case above. |
6629 __ CountLeadingZeros(source_, mantissa, zeros_); | 6629 __ CountLeadingZeros(source_, mantissa, zeros_); |
6630 // Compute exponent and or it into the exponent register. | 6630 // Compute exponent and or it into the exponent register. |
6631 // We use mantissa as a scratch register here. | 6631 // We use mantissa as a scratch register here. Use a fudge factor to |
6632 __ rsb(mantissa, zeros_, Operand(31 + HeapNumber::kExponentBias)); | 6632 // divide the constant 31 + HeapNumber::kExponentBias, 0x41d, into two parts |
6633 // that fit in the ARM's constant field. | |
6634 int fudge = 0x400; | |
6635 __ rsb(mantissa, zeros_, Operand(31 + HeapNumber::kExponentBias - fudge)); | |
6636 __ add(mantissa, mantissa, Operand(fudge)); | |
6633 __ orr(exponent, | 6637 __ orr(exponent, |
6634 exponent, | 6638 exponent, |
6635 Operand(mantissa, LSL, HeapNumber::kExponentShift)); | 6639 Operand(mantissa, LSL, HeapNumber::kExponentShift)); |
6636 // Shift up the source chopping the top bit off. | 6640 // Shift up the source chopping the top bit off. |
6637 __ add(zeros_, zeros_, Operand(1)); | 6641 __ add(zeros_, zeros_, Operand(1)); |
6638 // This wouldn't work for 1.0 or -1.0 as the shift would be 32 which means 0. | 6642 // This wouldn't work for 1.0 or -1.0 as the shift would be 32 which means 0. |
6639 __ mov(source_, Operand(source_, LSL, zeros_)); | 6643 __ mov(source_, Operand(source_, LSL, zeros_)); |
6640 // Compute lower part of fraction (last 12 bits). | 6644 // Compute lower part of fraction (last 12 bits). |
6641 __ mov(mantissa, Operand(source_, LSL, HeapNumber::kMantissaBitsInTopWord)); | 6645 __ mov(mantissa, Operand(source_, LSL, HeapNumber::kMantissaBitsInTopWord)); |
6642 // And the top (top 20 bits). | 6646 // And the top (top 20 bits). |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6695 | 6699 |
6696 // Handle the case where the lhs and rhs are the same object. | 6700 // Handle the case where the lhs and rhs are the same object. |
6697 // Equality is almost reflexive (everything but NaN), so this is a test | 6701 // Equality is almost reflexive (everything but NaN), so this is a test |
6698 // for "identity and not NaN". | 6702 // for "identity and not NaN". |
6699 static void EmitIdenticalObjectComparison(MacroAssembler* masm, | 6703 static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
6700 Label* slow, | 6704 Label* slow, |
6701 Condition cc, | 6705 Condition cc, |
6702 bool never_nan_nan) { | 6706 bool never_nan_nan) { |
6703 Label not_identical; | 6707 Label not_identical; |
6704 Label heap_number, return_equal; | 6708 Label heap_number, return_equal; |
6705 Register exp_mask_reg = r5; | |
6706 __ cmp(r0, r1); | 6709 __ cmp(r0, r1); |
6707 __ b(ne, ¬_identical); | 6710 __ b(ne, ¬_identical); |
6708 | 6711 |
6709 // The two objects are identical. If we know that one of them isn't NaN then | 6712 // The two objects are identical. If we know that one of them isn't NaN then |
6710 // we now know they test equal. | 6713 // we now know they test equal. |
6711 if (cc != eq || !never_nan_nan) { | 6714 if (cc != eq || !never_nan_nan) { |
6712 __ mov(exp_mask_reg, Operand(HeapNumber::kExponentMask)); | |
6713 | |
6714 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), | 6715 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), |
6715 // so we do the second best thing - test it ourselves. | 6716 // so we do the second best thing - test it ourselves. |
6716 // They are both equal and they are not both Smis so both of them are not | 6717 // They are both equal and they are not both Smis so both of them are not |
6717 // Smis. If it's not a heap number, then return equal. | 6718 // Smis. If it's not a heap number, then return equal. |
6718 if (cc == lt || cc == gt) { | 6719 if (cc == lt || cc == gt) { |
6719 __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE); | 6720 __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE); |
6720 __ b(ge, slow); | 6721 __ b(ge, slow); |
6721 } else { | 6722 } else { |
6722 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); | 6723 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); |
6723 __ b(eq, &heap_number); | 6724 __ b(eq, &heap_number); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6764 if (cc != lt && cc != gt) { | 6765 if (cc != lt && cc != gt) { |
6765 __ bind(&heap_number); | 6766 __ bind(&heap_number); |
6766 // It is a heap number, so return non-equal if it's NaN and equal if it's | 6767 // It is a heap number, so return non-equal if it's NaN and equal if it's |
6767 // not NaN. | 6768 // not NaN. |
6768 | 6769 |
6769 // The representation of NaN values has all exponent bits (52..62) set, | 6770 // The representation of NaN values has all exponent bits (52..62) set, |
6770 // and not all mantissa bits (0..51) clear. | 6771 // and not all mantissa bits (0..51) clear. |
6771 // Read top bits of double representation (second word of value). | 6772 // Read top bits of double representation (second word of value). |
6772 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | 6773 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); |
6773 // Test that exponent bits are all set. | 6774 // Test that exponent bits are all set. |
6774 __ and_(r3, r2, Operand(exp_mask_reg)); | 6775 __ Sbfx(r3, r2, HeapNumber::kExponentShift, HeapNumber::kExponentBits); |
6775 __ cmp(r3, Operand(exp_mask_reg)); | 6776 // NaNs have all-one exponents so they sign extend to -1. |
6777 __ cmp(r3, Operand(-1)); | |
6776 __ b(ne, &return_equal); | 6778 __ b(ne, &return_equal); |
6777 | 6779 |
6778 // Shift out flag and all exponent bits, retaining only mantissa. | 6780 // Shift out flag and all exponent bits, retaining only mantissa. |
6779 __ mov(r2, Operand(r2, LSL, HeapNumber::kNonMantissaBitsInTopWord)); | 6781 __ mov(r2, Operand(r2, LSL, HeapNumber::kNonMantissaBitsInTopWord)); |
6780 // Or with all low-bits of mantissa. | 6782 // Or with all low-bits of mantissa. |
6781 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | 6783 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); |
6782 __ orr(r0, r3, Operand(r2), SetCC); | 6784 __ orr(r0, r3, Operand(r2), SetCC); |
6783 // For equal we already have the right value in r0: Return zero (equal) | 6785 // For equal we already have the right value in r0: Return zero (equal) |
6784 // if all bits in mantissa are zero (it's an Infinity) and non-zero if | 6786 // if all bits in mantissa are zero (it's an Infinity) and non-zero if |
6785 // not (it's a NaN). For <= and >= we need to load r0 with the failing | 6787 // not (it's a NaN). For <= and >= we need to load r0 with the failing |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6886 } | 6888 } |
6887 | 6889 |
6888 | 6890 |
6889 void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cc) { | 6891 void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cc) { |
6890 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset); | 6892 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset); |
6891 Register rhs_exponent = exp_first ? r0 : r1; | 6893 Register rhs_exponent = exp_first ? r0 : r1; |
6892 Register lhs_exponent = exp_first ? r2 : r3; | 6894 Register lhs_exponent = exp_first ? r2 : r3; |
6893 Register rhs_mantissa = exp_first ? r1 : r0; | 6895 Register rhs_mantissa = exp_first ? r1 : r0; |
6894 Register lhs_mantissa = exp_first ? r3 : r2; | 6896 Register lhs_mantissa = exp_first ? r3 : r2; |
6895 Label one_is_nan, neither_is_nan; | 6897 Label one_is_nan, neither_is_nan; |
6896 Label lhs_not_nan_exp_mask_is_loaded; | |
6897 | 6898 |
6898 Register exp_mask_reg = r5; | 6899 __ Sbfx(r4, lhs_exponent, HeapNumber::kExponentShift, HeapNumber::kExponentBit s); |
Søren Thygesen Gjesse
2010/06/14 07:56:47
Long line.
Erik Corry
2010/06/14 21:05:46
Done.
| |
6899 | 6900 // NaNs have all-one exponents so they sign extend to -1. |
6900 __ mov(exp_mask_reg, Operand(HeapNumber::kExponentMask)); | 6901 __ cmp(r4, Operand(-1)); |
6901 __ and_(r4, lhs_exponent, Operand(exp_mask_reg)); | 6902 __ b(ne, lhs_not_nan); |
6902 __ cmp(r4, Operand(exp_mask_reg)); | |
6903 __ b(ne, &lhs_not_nan_exp_mask_is_loaded); | |
6904 __ mov(r4, | 6903 __ mov(r4, |
6905 Operand(lhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord), | 6904 Operand(lhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord), |
6906 SetCC); | 6905 SetCC); |
6907 __ b(ne, &one_is_nan); | 6906 __ b(ne, &one_is_nan); |
6908 __ cmp(lhs_mantissa, Operand(0)); | 6907 __ cmp(lhs_mantissa, Operand(0)); |
6909 __ b(ne, &one_is_nan); | 6908 __ b(ne, &one_is_nan); |
6910 | 6909 |
6911 __ bind(lhs_not_nan); | 6910 __ bind(lhs_not_nan); |
6912 __ mov(exp_mask_reg, Operand(HeapNumber::kExponentMask)); | 6911 __ Sbfx(r4, rhs_exponent, HeapNumber::kExponentShift, HeapNumber::kExponentBit s); |
Søren Thygesen Gjesse
2010/06/14 07:56:47
Long line.
Erik Corry
2010/06/14 21:05:46
Done.
| |
6913 __ bind(&lhs_not_nan_exp_mask_is_loaded); | 6912 // NaNs have all-one exponents so they sign extend to -1. |
6914 __ and_(r4, rhs_exponent, Operand(exp_mask_reg)); | 6913 __ cmp(r4, Operand(-1)); |
6915 __ cmp(r4, Operand(exp_mask_reg)); | |
6916 __ b(ne, &neither_is_nan); | 6914 __ b(ne, &neither_is_nan); |
6917 __ mov(r4, | 6915 __ mov(r4, |
6918 Operand(rhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord), | 6916 Operand(rhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord), |
6919 SetCC); | 6917 SetCC); |
6920 __ b(ne, &one_is_nan); | 6918 __ b(ne, &one_is_nan); |
6921 __ cmp(rhs_mantissa, Operand(0)); | 6919 __ cmp(rhs_mantissa, Operand(0)); |
6922 __ b(eq, &neither_is_nan); | 6920 __ b(eq, &neither_is_nan); |
6923 | 6921 |
6924 __ bind(&one_is_nan); | 6922 __ bind(&one_is_nan); |
6925 // NaN comparisons always fail. | 6923 // NaN comparisons always fail. |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7626 static void GetInt32(MacroAssembler* masm, | 7624 static void GetInt32(MacroAssembler* masm, |
7627 Register source, | 7625 Register source, |
7628 Register dest, | 7626 Register dest, |
7629 Register scratch, | 7627 Register scratch, |
7630 Register scratch2, | 7628 Register scratch2, |
7631 Label* slow) { | 7629 Label* slow) { |
7632 Label right_exponent, done; | 7630 Label right_exponent, done; |
7633 // Get exponent word. | 7631 // Get exponent word. |
7634 __ ldr(scratch, FieldMemOperand(source, HeapNumber::kExponentOffset)); | 7632 __ ldr(scratch, FieldMemOperand(source, HeapNumber::kExponentOffset)); |
7635 // Get exponent alone in scratch2. | 7633 // Get exponent alone in scratch2. |
7636 __ and_(scratch2, scratch, Operand(HeapNumber::kExponentMask)); | 7634 __ Ubfx(scratch2, scratch, HeapNumber::kExponentShift, HeapNumber::kExponentBi ts); |
Søren Thygesen Gjesse
2010/06/14 07:56:47
Long line.
Erik Corry
2010/06/14 21:05:46
Done.
| |
7637 // Load dest with zero. We use this either for the final shift or | 7635 // Load dest with zero. We use this either for the final shift or |
7638 // for the answer. | 7636 // for the answer. |
7639 __ mov(dest, Operand(0)); | 7637 __ mov(dest, Operand(0)); |
7640 // Check whether the exponent matches a 32 bit signed int that is not a Smi. | 7638 // Check whether the exponent matches a 32 bit signed int that is not a Smi. |
7641 // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). This is | 7639 // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). This is |
7642 // the exponent that we are fastest at and also the highest exponent we can | 7640 // the exponent that we are fastest at and also the highest exponent we can |
7643 // handle here. | 7641 // handle here. |
7644 const uint32_t non_smi_exponent = | 7642 const uint32_t non_smi_exponent = HeapNumber::kExponentBias + 30; |
7645 (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift; | 7643 // The non_smi_exponent, 0x41d, is too big for ARM's immediate field so we |
7646 __ cmp(scratch2, Operand(non_smi_exponent)); | 7644 // split it up to avoid a constant pool entry. You can't do that in general |
7645 // for cmp because of the overflow flag, but we know the exponent is in the | |
7646 // range 0-2047 so there is no overflow. | |
7647 int fudge_factor = 0x400; | |
7648 __ sub(scratch2, scratch2, Operand(fudge_factor)); | |
7649 __ cmp(scratch2, Operand(non_smi_exponent - fudge_factor)); | |
7647 // If we have a match of the int32-but-not-Smi exponent then skip some logic. | 7650 // If we have a match of the int32-but-not-Smi exponent then skip some logic. |
7648 __ b(eq, &right_exponent); | 7651 __ b(eq, &right_exponent); |
7649 // If the exponent is higher than that then go to slow case. This catches | 7652 // If the exponent is higher than that then go to slow case. This catches |
7650 // numbers that don't fit in a signed int32, infinities and NaNs. | 7653 // numbers that don't fit in a signed int32, infinities and NaNs. |
7651 __ b(gt, slow); | 7654 __ b(gt, slow); |
7652 | 7655 |
7653 // We know the exponent is smaller than 30 (biased). If it is less than | 7656 // We know the exponent is smaller than 30 (biased). If it is less than |
7654 // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, ie | 7657 // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, ie |
7655 // it rounds to zero. | 7658 // it rounds to zero. |
7656 const uint32_t zero_exponent = | 7659 const uint32_t zero_exponent = HeapNumber::kExponentBias + 0; |
7657 (HeapNumber::kExponentBias + 0) << HeapNumber::kExponentShift; | 7660 __ sub(scratch2, scratch2, Operand(zero_exponent - fudge_factor), SetCC); |
7658 __ sub(scratch2, scratch2, Operand(zero_exponent), SetCC); | |
7659 // Dest already has a Smi zero. | 7661 // Dest already has a Smi zero. |
7660 __ b(lt, &done); | 7662 __ b(lt, &done); |
7661 if (!CpuFeatures::IsSupported(VFP3)) { | 7663 if (!CpuFeatures::IsSupported(VFP3)) { |
7662 // We have a shifted exponent between 0 and 30 in scratch2. | 7664 // We have an exponent between 0 and 30 in scratch2. Subtract from 30 to |
7663 __ mov(dest, Operand(scratch2, LSR, HeapNumber::kExponentShift)); | 7665 // get how much to shift down. |
7664 // We now have the exponent in dest. Subtract from 30 to get | 7666 __ rsb(dest, scratch2, Operand(30)); |
7665 // how much to shift down. | |
7666 __ rsb(dest, dest, Operand(30)); | |
7667 } | 7667 } |
7668 __ bind(&right_exponent); | 7668 __ bind(&right_exponent); |
7669 if (CpuFeatures::IsSupported(VFP3)) { | 7669 if (CpuFeatures::IsSupported(VFP3)) { |
7670 CpuFeatures::Scope scope(VFP3); | 7670 CpuFeatures::Scope scope(VFP3); |
7671 // ARMv7 VFP3 instructions implementing double precision to integer | 7671 // ARMv7 VFP3 instructions implementing double precision to integer |
7672 // conversion using round to zero. | 7672 // conversion using round to zero. |
7673 __ ldr(scratch2, FieldMemOperand(source, HeapNumber::kMantissaOffset)); | 7673 __ ldr(scratch2, FieldMemOperand(source, HeapNumber::kMantissaOffset)); |
7674 __ vmov(d7, scratch2, scratch); | 7674 __ vmov(d7, scratch2, scratch); |
7675 __ vcvt_s32_f64(s15, d7); | 7675 __ vcvt_s32_f64(s15, d7); |
7676 __ vmov(dest, s15); | 7676 __ vmov(dest, s15); |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8275 | 8275 |
8276 __ bind(&loaded); | 8276 __ bind(&loaded); |
8277 // r2 = low 32 bits of double value | 8277 // r2 = low 32 bits of double value |
8278 // r3 = high 32 bits of double value | 8278 // r3 = high 32 bits of double value |
8279 // Compute hash: | 8279 // Compute hash: |
8280 // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1); | 8280 // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1); |
8281 __ eor(r1, r2, Operand(r3)); | 8281 __ eor(r1, r2, Operand(r3)); |
8282 __ eor(r1, r1, Operand(r1, LSR, 16)); | 8282 __ eor(r1, r1, Operand(r1, LSR, 16)); |
8283 __ eor(r1, r1, Operand(r1, LSR, 8)); | 8283 __ eor(r1, r1, Operand(r1, LSR, 8)); |
8284 ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize)); | 8284 ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize)); |
8285 if (CpuFeatures::IsSupported(ARMv7)) { | 8285 __ And(r1, r1, Operand(TranscendentalCache::kCacheSize - 1)); |
8286 const int kTranscendentalCacheSizeBits = 9; | |
8287 ASSERT_EQ(1 << kTranscendentalCacheSizeBits, | |
8288 TranscendentalCache::kCacheSize); | |
8289 __ ubfx(r1, r1, 0, kTranscendentalCacheSizeBits); | |
8290 } else { | |
8291 __ and_(r1, r1, Operand(TranscendentalCache::kCacheSize - 1)); | |
8292 } | |
8293 | 8286 |
8294 // r2 = low 32 bits of double value. | 8287 // r2 = low 32 bits of double value. |
8295 // r3 = high 32 bits of double value. | 8288 // r3 = high 32 bits of double value. |
8296 // r1 = TranscendentalCache::hash(double value). | 8289 // r1 = TranscendentalCache::hash(double value). |
8297 __ mov(r0, | 8290 __ mov(r0, |
8298 Operand(ExternalReference::transcendental_cache_array_address())); | 8291 Operand(ExternalReference::transcendental_cache_array_address())); |
8299 // r0 points to cache array. | 8292 // r0 points to cache array. |
8300 __ ldr(r0, MemOperand(r0, type_ * sizeof(TranscendentalCache::caches_[0]))); | 8293 __ ldr(r0, MemOperand(r0, type_ * sizeof(TranscendentalCache::caches_[0]))); |
8301 // r0 points to the cache for the type type_. | 8294 // r0 points to the cache for the type type_. |
8302 // If NULL, the cache hasn't been initialized yet, so go through runtime. | 8295 // If NULL, the cache hasn't been initialized yet, so go through runtime. |
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10655 __ bind(&string_add_runtime); | 10648 __ bind(&string_add_runtime); |
10656 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 10649 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
10657 } | 10650 } |
10658 | 10651 |
10659 | 10652 |
10660 #undef __ | 10653 #undef __ |
10661 | 10654 |
10662 } } // namespace v8::internal | 10655 } } // namespace v8::internal |
10663 | 10656 |
10664 #endif // V8_TARGET_ARCH_ARM | 10657 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |