Index: src/ia32/codegen-ia32.cc |
=================================================================== |
--- src/ia32/codegen-ia32.cc (revision 3492) |
+++ src/ia32/codegen-ia32.cc (working copy) |
@@ -764,6 +764,7 @@ |
// Takes the operands in edx and eax and loads them as integers in eax |
// and ecx. |
static void LoadAsIntegers(MacroAssembler* masm, |
+ bool use_sse3, |
Label* operand_conversion_failure); |
// Test if operands are numbers (smi or HeapNumber objects), and load |
// them into xmm0 and xmm1 if they are. Jump to label not_numbers if |
@@ -7242,6 +7243,7 @@ |
Label operand_conversion_failure; |
FloatingPointHelper::LoadAsIntegers( |
masm, |
+ use_sse3_, |
&operand_conversion_failure); |
switch (op_) { |
case Token::BIT_OR: __ or_(eax, Operand(ecx)); break; |
@@ -7425,6 +7427,7 @@ |
// trashed registers. |
void IntegerConvert(MacroAssembler* masm, |
Register source, |
+ bool use_sse3, |
Label* conversion_failure) { |
Label done, right_exponent, normal_exponent; |
Register scratch = ebx; |
@@ -7434,109 +7437,127 @@ |
// Get exponent alone in scratch2. |
__ mov(scratch2, scratch); |
__ and_(scratch2, HeapNumber::kExponentMask); |
- // Load ecx with zero. We use this either for the final shift or |
- // for the answer. |
- __ xor_(ecx, Operand(ecx)); |
- // Check whether the exponent matches a 32 bit signed int that cannot be |
- // represented by a Smi. A non-smi 32 bit integer is 1.xxx * 2^30 so the |
- // exponent is 30 (biased). This is the exponent that we are fastest at and |
- // also the highest exponent we can handle here. |
- const uint32_t non_smi_exponent = |
- (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift; |
- __ cmp(Operand(scratch2), Immediate(non_smi_exponent)); |
- // If we have a match of the int32-but-not-Smi exponent then skip some logic. |
- __ j(equal, &right_exponent); |
- // If the exponent is higher than that then go to slow case. This catches |
- // numbers that don't fit in a signed int32, infinities and NaNs. |
- __ j(less, &normal_exponent); |
+ if (use_sse3) { |
+ CpuFeatures::Scope scope(SSE3); |
+ // Check whether the exponent is too big for a 64 bit signed integer. |
+ const uint32_t too_big_exponent = |
+ (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; |
+ __ cmp(Operand(scratch2), Immediate(too_big_exponent)); |
+ __ j(greater_equal, conversion_failure); |
+ // Load x87 register with heap number. |
+ __ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); |
+ // Reserve space for 64 bit answer. |
+ __ sub(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. |
+ // Do conversion, which cannot fail because we checked the exponent. |
+ __ fisttp_d(Operand(esp, 0)); |
+ __ mov(ecx, Operand(esp, 0)); // Load low word of answer into ecx. |
+ __ add(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. |
+ } else { |
+ // Load ecx with zero. We use this either for the final shift or |
+ // for the answer. |
+ __ xor_(ecx, Operand(ecx)); |
+ // Check whether the exponent matches a 32 bit signed int that cannot be |
+ // represented by a Smi. A non-smi 32 bit integer is 1.xxx * 2^30 so the |
+ // exponent is 30 (biased). This is the exponent that we are fastest at and |
+ // also the highest exponent we can handle here. |
+ const uint32_t non_smi_exponent = |
+ (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift; |
+ __ cmp(Operand(scratch2), Immediate(non_smi_exponent)); |
+ // If we have a match of the int32-but-not-Smi exponent then skip some logic. |
+ __ j(equal, &right_exponent); |
+ // If the exponent is higher than that then go to slow case. This catches |
+ // numbers that don't fit in a signed int32, infinities and NaNs. |
+ __ j(less, &normal_exponent); |
- { |
- // Handle a big exponent. The only reason we have this code is that the >>> |
- // operator has a tendency to generate numbers with an exponent of 31. |
- const uint32_t big_non_smi_exponent = |
- (HeapNumber::kExponentBias + 31) << HeapNumber::kExponentShift; |
- __ cmp(Operand(scratch2), Immediate(big_non_smi_exponent)); |
- __ j(not_equal, conversion_failure); |
- // We have the big exponent, typically from >>>. This means the number is |
- // in the range 2^31 to 2^32 - 1. Get the top bits of the mantissa. |
- __ mov(scratch2, scratch); |
- __ and_(scratch2, HeapNumber::kMantissaMask); |
+ { |
+ // Handle a big exponent. The only reason we have this code is that the >>> |
+ // operator has a tendency to generate numbers with an exponent of 31. |
+ const uint32_t big_non_smi_exponent = |
+ (HeapNumber::kExponentBias + 31) << HeapNumber::kExponentShift; |
+ __ cmp(Operand(scratch2), Immediate(big_non_smi_exponent)); |
+ __ j(not_equal, conversion_failure); |
+ // We have the big exponent, typically from >>>. This means the number is |
+ // in the range 2^31 to 2^32 - 1. Get the top bits of the mantissa. |
+ __ mov(scratch2, scratch); |
+ __ and_(scratch2, HeapNumber::kMantissaMask); |
+ // Put back the implicit 1. |
+ __ or_(scratch2, 1 << HeapNumber::kExponentShift); |
+ // Shift up the mantissa bits to take up the space the exponent used to |
+ // take. We just orred in the implicit bit so that took care of one and |
+ // we want to use the full unsigned range so we subtract 1 bit from the |
+ // shift distance. |
+ const int big_shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 1; |
+ __ shl(scratch2, big_shift_distance); |
+ // Get the second half of the double. |
+ __ mov(ecx, FieldOperand(source, HeapNumber::kMantissaOffset)); |
+ // Shift down 21 bits to get the most significant 11 bits or the low |
+ // mantissa word. |
+ __ shr(ecx, 32 - big_shift_distance); |
+ __ or_(ecx, Operand(scratch2)); |
+ // We have the answer in ecx, but we may need to negate it. |
+ __ test(scratch, Operand(scratch)); |
+ __ j(positive, &done); |
+ __ neg(ecx); |
+ __ jmp(&done); |
+ } |
+ |
+ __ bind(&normal_exponent); |
+ // Exponent word in scratch, exponent part of exponent word in scratch2. |
+ // Zero in ecx. |
+ // We know the exponent is smaller than 30 (biased). If it is less than |
+ // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, ie |
+ // it rounds to zero. |
+ const uint32_t zero_exponent = |
+ (HeapNumber::kExponentBias + 0) << HeapNumber::kExponentShift; |
+ __ sub(Operand(scratch2), Immediate(zero_exponent)); |
+ // ecx already has a Smi zero. |
+ __ j(less, &done); |
+ |
+ // We have a shifted exponent between 0 and 30 in scratch2. |
+ __ shr(scratch2, HeapNumber::kExponentShift); |
+ __ mov(ecx, Immediate(30)); |
+ __ sub(ecx, Operand(scratch2)); |
+ |
+ __ bind(&right_exponent); |
+ // Here ecx is the shift, scratch is the exponent word. |
+ // Get the top bits of the mantissa. |
+ __ and_(scratch, HeapNumber::kMantissaMask); |
// Put back the implicit 1. |
- __ or_(scratch2, 1 << HeapNumber::kExponentShift); |
+ __ or_(scratch, 1 << HeapNumber::kExponentShift); |
// Shift up the mantissa bits to take up the space the exponent used to |
- // take. We just orred in the implicit bit so that took care of one and |
- // we want to use the full unsigned range so we subtract 1 bit from the |
- // shift distance. |
- const int big_shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 1; |
- __ shl(scratch2, big_shift_distance); |
- // Get the second half of the double. |
- __ mov(ecx, FieldOperand(source, HeapNumber::kMantissaOffset)); |
- // Shift down 21 bits to get the most significant 11 bits or the low |
- // mantissa word. |
- __ shr(ecx, 32 - big_shift_distance); |
- __ or_(ecx, Operand(scratch2)); |
- // We have the answer in ecx, but we may need to negate it. |
- __ test(scratch, Operand(scratch)); |
- __ j(positive, &done); |
- __ neg(ecx); |
+ // take. We have kExponentShift + 1 significant bits int he low end of the |
+ // word. Shift them to the top bits. |
+ const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2; |
+ __ shl(scratch, shift_distance); |
+ // Get the second half of the double. For some exponents we don't |
+ // actually need this because the bits get shifted out again, but |
+ // it's probably slower to test than just to do it. |
+ __ mov(scratch2, FieldOperand(source, HeapNumber::kMantissaOffset)); |
+ // Shift down 22 bits to get the most significant 10 bits or the low mantissa |
+ // word. |
+ __ shr(scratch2, 32 - shift_distance); |
+ __ or_(scratch2, Operand(scratch)); |
+ // Move down according to the exponent. |
+ __ shr_cl(scratch2); |
+ // Now the unsigned answer is in scratch2. We need to move it to ecx and |
+ // we may need to fix the sign. |
+ Label negative; |
+ __ xor_(ecx, Operand(ecx)); |
+ __ cmp(ecx, FieldOperand(source, HeapNumber::kExponentOffset)); |
+ __ j(greater, &negative); |
+ __ mov(ecx, scratch2); |
__ jmp(&done); |
+ __ bind(&negative); |
+ __ sub(ecx, Operand(scratch2)); |
+ __ bind(&done); |
} |
- |
- __ bind(&normal_exponent); |
- // Exponent word in scratch, exponent part of exponent word in scratch2. |
- // Zero in ecx. |
- // We know the exponent is smaller than 30 (biased). If it is less than |
- // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, ie |
- // it rounds to zero. |
- const uint32_t zero_exponent = |
- (HeapNumber::kExponentBias + 0) << HeapNumber::kExponentShift; |
- __ sub(Operand(scratch2), Immediate(zero_exponent)); |
- // ecx already has a Smi zero. |
- __ j(less, &done); |
- |
- // We have a shifted exponent between 0 and 30 in scratch2. |
- __ shr(scratch2, HeapNumber::kExponentShift); |
- __ mov(ecx, Immediate(30)); |
- __ sub(ecx, Operand(scratch2)); |
- |
- __ bind(&right_exponent); |
- // Here ecx is the shift, scratch is the exponent word. |
- // Get the top bits of the mantissa. |
- __ and_(scratch, HeapNumber::kMantissaMask); |
- // Put back the implicit 1. |
- __ or_(scratch, 1 << HeapNumber::kExponentShift); |
- // Shift up the mantissa bits to take up the space the exponent used to |
- // take. We have kExponentShift + 1 significant bits int he low end of the |
- // word. Shift them to the top bits. |
- const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2; |
- __ shl(scratch, shift_distance); |
- // Get the second half of the double. For some exponents we don't |
- // actually need this because the bits get shifted out again, but |
- // it's probably slower to test than just to do it. |
- __ mov(scratch2, FieldOperand(source, HeapNumber::kMantissaOffset)); |
- // Shift down 22 bits to get the most significant 10 bits or the low mantissa |
- // word. |
- __ shr(scratch2, 32 - shift_distance); |
- __ or_(scratch2, Operand(scratch)); |
- // Move down according to the exponent. |
- __ shr_cl(scratch2); |
- // Now the unsigned answer is in scratch2. We need to move it to ecx and |
- // we may need to fix the sign. |
- Label negative; |
- __ xor_(ecx, Operand(ecx)); |
- __ cmp(ecx, FieldOperand(source, HeapNumber::kExponentOffset)); |
- __ j(greater, &negative); |
- __ mov(ecx, scratch2); |
- __ jmp(&done); |
- __ bind(&negative); |
- __ sub(ecx, Operand(scratch2)); |
- __ bind(&done); |
} |
// Input: edx, eax are the left and right objects of a bit op. |
// Output: eax, ecx are left and right integers for a bit op. |
void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm, |
+ bool use_sse3, |
Label* conversion_failure) { |
// Check float operands. |
Label arg1_is_object, arg2_is_object, load_arg2; |
@@ -7552,7 +7573,7 @@ |
__ cmp(ebx, Factory::heap_number_map()); |
__ j(not_equal, conversion_failure); |
// Get the untagged integer version of the edx heap number in ecx. |
- IntegerConvert(masm, edx, conversion_failure); |
+ IntegerConvert(masm, edx, use_sse3, conversion_failure); |
__ mov(edx, ecx); |
// Here edx has the untagged integer, eax has a Smi or a heap number. |
@@ -7569,7 +7590,7 @@ |
__ cmp(ebx, Factory::heap_number_map()); |
__ j(not_equal, conversion_failure); |
// Get the untagged integer version of the eax heap number in ecx. |
- IntegerConvert(masm, eax, conversion_failure); |
+ IntegerConvert(masm, eax, use_sse3, conversion_failure); |
__ bind(&done); |
__ mov(eax, edx); |
} |