OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 5656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5667 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 5667 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
5668 LOperand* input = instr->value(); | 5668 LOperand* input = instr->value(); |
5669 ASSERT(input->IsDoubleRegister()); | 5669 ASSERT(input->IsDoubleRegister()); |
5670 LOperand* result = instr->result(); | 5670 LOperand* result = instr->result(); |
5671 ASSERT(result->IsRegister()); | 5671 ASSERT(result->IsRegister()); |
5672 CpuFeatureScope scope(masm(), SSE2); | 5672 CpuFeatureScope scope(masm(), SSE2); |
5673 | 5673 |
5674 XMMRegister input_reg = ToDoubleRegister(input); | 5674 XMMRegister input_reg = ToDoubleRegister(input); |
5675 Register result_reg = ToRegister(result); | 5675 Register result_reg = ToRegister(result); |
5676 | 5676 |
| 5677 __ cvttsd2si(result_reg, Operand(input_reg)); |
| 5678 |
5677 if (instr->truncating()) { | 5679 if (instr->truncating()) { |
5678 // Performs a truncating conversion of a floating point number as used by | 5680 // Performs a truncating conversion of a floating point number as used by |
5679 // the JS bitwise operations. | 5681 // the JS bitwise operations. |
5680 __ cvttsd2si(result_reg, Operand(input_reg)); | 5682 Label fast_case_succeeded; |
5681 __ cmp(result_reg, 0x80000000u); | 5683 __ cmp(result_reg, 0x80000000u); |
5682 if (CpuFeatures::IsSupported(SSE3)) { | 5684 __ j(not_equal, &fast_case_succeeded); |
5683 // This will deoptimize if the exponent of the input in out of range. | 5685 __ sub(esp, Immediate(kDoubleSize)); |
5684 CpuFeatureScope scope(masm(), SSE3); | 5686 __ movdbl(MemOperand(esp, 0), input_reg); |
5685 Label convert, done; | 5687 DoubleToIStub stub(esp, result_reg, 0, true); |
5686 __ j(not_equal, &done, Label::kNear); | 5688 __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); |
5687 __ sub(Operand(esp), Immediate(kDoubleSize)); | 5689 __ add(esp, Immediate(kDoubleSize)); |
5688 __ movdbl(Operand(esp, 0), input_reg); | 5690 __ bind(&fast_case_succeeded); |
5689 // Get exponent alone and check for too-big exponent. | |
5690 __ mov(result_reg, Operand(esp, sizeof(int32_t))); | |
5691 __ and_(result_reg, HeapNumber::kExponentMask); | |
5692 const uint32_t kTooBigExponent = | |
5693 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | |
5694 __ cmp(Operand(result_reg), Immediate(kTooBigExponent)); | |
5695 __ j(less, &convert, Label::kNear); | |
5696 __ add(Operand(esp), Immediate(kDoubleSize)); | |
5697 DeoptimizeIf(no_condition, instr->environment()); | |
5698 __ bind(&convert); | |
5699 // Do conversion, which cannot fail because we checked the exponent. | |
5700 __ fld_d(Operand(esp, 0)); | |
5701 __ fisttp_d(Operand(esp, 0)); | |
5702 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. | |
5703 __ add(Operand(esp), Immediate(kDoubleSize)); | |
5704 __ bind(&done); | |
5705 } else { | |
5706 Label done; | |
5707 Register temp_reg = ToRegister(instr->temp()); | |
5708 XMMRegister xmm_scratch = xmm0; | |
5709 | |
5710 // If cvttsd2si succeeded, we're done. Otherwise, we attempt | |
5711 // manual conversion. | |
5712 __ j(not_equal, &done, Label::kNear); | |
5713 | |
5714 // Get high 32 bits of the input in result_reg and temp_reg. | |
5715 __ pshufd(xmm_scratch, input_reg, 1); | |
5716 __ movd(Operand(temp_reg), xmm_scratch); | |
5717 __ mov(result_reg, temp_reg); | |
5718 | |
5719 // Prepare negation mask in temp_reg. | |
5720 __ sar(temp_reg, kBitsPerInt - 1); | |
5721 | |
5722 // Extract the exponent from result_reg and subtract adjusted | |
5723 // bias from it. The adjustment is selected in a way such that | |
5724 // when the difference is zero, the answer is in the low 32 bits | |
5725 // of the input, otherwise a shift has to be performed. | |
5726 __ shr(result_reg, HeapNumber::kExponentShift); | |
5727 __ and_(result_reg, | |
5728 HeapNumber::kExponentMask >> HeapNumber::kExponentShift); | |
5729 __ sub(Operand(result_reg), | |
5730 Immediate(HeapNumber::kExponentBias + | |
5731 HeapNumber::kExponentBits + | |
5732 HeapNumber::kMantissaBits)); | |
5733 // Don't handle big (> kMantissaBits + kExponentBits == 63) or | |
5734 // special exponents. | |
5735 DeoptimizeIf(greater, instr->environment()); | |
5736 | |
5737 // Zero out the sign and the exponent in the input (by shifting | |
5738 // it to the left) and restore the implicit mantissa bit, | |
5739 // i.e. convert the input to unsigned int64 shifted left by | |
5740 // kExponentBits. | |
5741 ExternalReference minus_zero = ExternalReference::address_of_minus_zero(); | |
5742 // Minus zero has the most significant bit set and the other | |
5743 // bits cleared. | |
5744 __ movdbl(xmm_scratch, Operand::StaticVariable(minus_zero)); | |
5745 __ psllq(input_reg, HeapNumber::kExponentBits); | |
5746 __ por(input_reg, xmm_scratch); | |
5747 | |
5748 // Get the amount to shift the input right in xmm_scratch. | |
5749 __ neg(result_reg); | |
5750 __ movd(xmm_scratch, Operand(result_reg)); | |
5751 | |
5752 // Shift the input right and extract low 32 bits. | |
5753 __ psrlq(input_reg, xmm_scratch); | |
5754 __ movd(Operand(result_reg), input_reg); | |
5755 | |
5756 // Use the prepared mask in temp_reg to negate the result if necessary. | |
5757 __ xor_(result_reg, Operand(temp_reg)); | |
5758 __ sub(result_reg, Operand(temp_reg)); | |
5759 __ bind(&done); | |
5760 } | |
5761 } else { | 5691 } else { |
5762 Label done; | 5692 Label done; |
5763 __ cvttsd2si(result_reg, Operand(input_reg)); | |
5764 __ cvtsi2sd(xmm0, Operand(result_reg)); | 5693 __ cvtsi2sd(xmm0, Operand(result_reg)); |
5765 __ ucomisd(xmm0, input_reg); | 5694 __ ucomisd(xmm0, input_reg); |
5766 DeoptimizeIf(not_equal, instr->environment()); | 5695 DeoptimizeIf(not_equal, instr->environment()); |
5767 DeoptimizeIf(parity_even, instr->environment()); // NaN. | 5696 DeoptimizeIf(parity_even, instr->environment()); // NaN. |
5768 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 5697 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
5769 // The integer converted back is equal to the original. We | 5698 // The integer converted back is equal to the original. We |
5770 // only have to test if we got -0 as an input. | 5699 // only have to test if we got -0 as an input. |
5771 __ test(result_reg, Operand(result_reg)); | 5700 __ test(result_reg, Operand(result_reg)); |
5772 __ j(not_zero, &done, Label::kNear); | 5701 __ j(not_zero, &done, Label::kNear); |
5773 __ movmskpd(result_reg, input_reg); | 5702 __ movmskpd(result_reg, input_reg); |
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6674 FixedArray::kHeaderSize - kPointerSize)); | 6603 FixedArray::kHeaderSize - kPointerSize)); |
6675 __ bind(&done); | 6604 __ bind(&done); |
6676 } | 6605 } |
6677 | 6606 |
6678 | 6607 |
6679 #undef __ | 6608 #undef __ |
6680 | 6609 |
6681 } } // namespace v8::internal | 6610 } } // namespace v8::internal |
6682 | 6611 |
6683 #endif // V8_TARGET_ARCH_IA32 | 6612 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |