Chromium Code Reviews| 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 5493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5504 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 5504 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
| 5505 LOperand* input = instr->value(); | 5505 LOperand* input = instr->value(); |
| 5506 ASSERT(input->IsDoubleRegister()); | 5506 ASSERT(input->IsDoubleRegister()); |
| 5507 LOperand* result = instr->result(); | 5507 LOperand* result = instr->result(); |
| 5508 ASSERT(result->IsRegister()); | 5508 ASSERT(result->IsRegister()); |
| 5509 CpuFeatureScope scope(masm(), SSE2); | 5509 CpuFeatureScope scope(masm(), SSE2); |
| 5510 | 5510 |
| 5511 XMMRegister input_reg = ToDoubleRegister(input); | 5511 XMMRegister input_reg = ToDoubleRegister(input); |
| 5512 Register result_reg = ToRegister(result); | 5512 Register result_reg = ToRegister(result); |
| 5513 | 5513 |
| 5514 __ cvttsd2si(result_reg, Operand(input_reg)); | |
|
Yang
2013/07/11 12:00:27
I wonder why this isn't put into the DoubleToIStub
danno
2013/07/11 16:00:23
Well, the stub works on a buffer that points to th
| |
| 5515 | |
| 5514 if (instr->truncating()) { | 5516 if (instr->truncating()) { |
| 5515 // Performs a truncating conversion of a floating point number as used by | 5517 // Performs a truncating conversion of a floating point number as used by |
| 5516 // the JS bitwise operations. | 5518 // the JS bitwise operations. |
| 5517 __ cvttsd2si(result_reg, Operand(input_reg)); | 5519 Label fast_case_succeeded; |
| 5518 __ cmp(result_reg, 0x80000000u); | 5520 __ cmp(result_reg, 0x80000000u); |
| 5519 if (CpuFeatures::IsSupported(SSE3)) { | 5521 __ j(not_equal, &fast_case_succeeded); |
| 5520 // This will deoptimize if the exponent of the input in out of range. | 5522 __ sub(esp, Immediate(kDoubleSize)); |
| 5521 CpuFeatureScope scope(masm(), SSE3); | 5523 __ movdbl(MemOperand(esp, 0), input_reg); |
| 5522 Label convert, done; | 5524 DoubleToIStub stub(esp, result_reg, 0, true); |
| 5523 __ j(not_equal, &done, Label::kNear); | 5525 __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); |
| 5524 __ sub(Operand(esp), Immediate(kDoubleSize)); | 5526 __ add(esp, Immediate(kDoubleSize)); |
| 5525 __ movdbl(Operand(esp, 0), input_reg); | 5527 __ bind(&fast_case_succeeded); |
| 5526 // Get exponent alone and check for too-big exponent. | |
| 5527 __ mov(result_reg, Operand(esp, sizeof(int32_t))); | |
| 5528 __ and_(result_reg, HeapNumber::kExponentMask); | |
| 5529 const uint32_t kTooBigExponent = | |
| 5530 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | |
| 5531 __ cmp(Operand(result_reg), Immediate(kTooBigExponent)); | |
| 5532 __ j(less, &convert, Label::kNear); | |
| 5533 __ add(Operand(esp), Immediate(kDoubleSize)); | |
| 5534 DeoptimizeIf(no_condition, instr->environment()); | |
| 5535 __ bind(&convert); | |
| 5536 // Do conversion, which cannot fail because we checked the exponent. | |
| 5537 __ fld_d(Operand(esp, 0)); | |
| 5538 __ fisttp_d(Operand(esp, 0)); | |
| 5539 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. | |
| 5540 __ add(Operand(esp), Immediate(kDoubleSize)); | |
| 5541 __ bind(&done); | |
| 5542 } else { | |
| 5543 Label done; | |
| 5544 Register temp_reg = ToRegister(instr->temp()); | |
| 5545 XMMRegister xmm_scratch = xmm0; | |
| 5546 | |
| 5547 // If cvttsd2si succeeded, we're done. Otherwise, we attempt | |
| 5548 // manual conversion. | |
| 5549 __ j(not_equal, &done, Label::kNear); | |
| 5550 | |
| 5551 // Get high 32 bits of the input in result_reg and temp_reg. | |
| 5552 __ pshufd(xmm_scratch, input_reg, 1); | |
| 5553 __ movd(Operand(temp_reg), xmm_scratch); | |
| 5554 __ mov(result_reg, temp_reg); | |
| 5555 | |
| 5556 // Prepare negation mask in temp_reg. | |
| 5557 __ sar(temp_reg, kBitsPerInt - 1); | |
| 5558 | |
| 5559 // Extract the exponent from result_reg and subtract adjusted | |
| 5560 // bias from it. The adjustment is selected in a way such that | |
| 5561 // when the difference is zero, the answer is in the low 32 bits | |
| 5562 // of the input, otherwise a shift has to be performed. | |
| 5563 __ shr(result_reg, HeapNumber::kExponentShift); | |
| 5564 __ and_(result_reg, | |
| 5565 HeapNumber::kExponentMask >> HeapNumber::kExponentShift); | |
| 5566 __ sub(Operand(result_reg), | |
| 5567 Immediate(HeapNumber::kExponentBias + | |
| 5568 HeapNumber::kExponentBits + | |
| 5569 HeapNumber::kMantissaBits)); | |
| 5570 // Don't handle big (> kMantissaBits + kExponentBits == 63) or | |
| 5571 // special exponents. | |
| 5572 DeoptimizeIf(greater, instr->environment()); | |
| 5573 | |
| 5574 // Zero out the sign and the exponent in the input (by shifting | |
| 5575 // it to the left) and restore the implicit mantissa bit, | |
| 5576 // i.e. convert the input to unsigned int64 shifted left by | |
| 5577 // kExponentBits. | |
| 5578 ExternalReference minus_zero = ExternalReference::address_of_minus_zero(); | |
| 5579 // Minus zero has the most significant bit set and the other | |
| 5580 // bits cleared. | |
| 5581 __ movdbl(xmm_scratch, Operand::StaticVariable(minus_zero)); | |
| 5582 __ psllq(input_reg, HeapNumber::kExponentBits); | |
| 5583 __ por(input_reg, xmm_scratch); | |
| 5584 | |
| 5585 // Get the amount to shift the input right in xmm_scratch. | |
| 5586 __ neg(result_reg); | |
| 5587 __ movd(xmm_scratch, Operand(result_reg)); | |
| 5588 | |
| 5589 // Shift the input right and extract low 32 bits. | |
| 5590 __ psrlq(input_reg, xmm_scratch); | |
| 5591 __ movd(Operand(result_reg), input_reg); | |
| 5592 | |
| 5593 // Use the prepared mask in temp_reg to negate the result if necessary. | |
| 5594 __ xor_(result_reg, Operand(temp_reg)); | |
| 5595 __ sub(result_reg, Operand(temp_reg)); | |
| 5596 __ bind(&done); | |
| 5597 } | |
| 5598 } else { | 5528 } else { |
| 5599 Label done; | 5529 Label done; |
| 5600 __ cvttsd2si(result_reg, Operand(input_reg)); | |
| 5601 __ cvtsi2sd(xmm0, Operand(result_reg)); | 5530 __ cvtsi2sd(xmm0, Operand(result_reg)); |
| 5602 __ ucomisd(xmm0, input_reg); | 5531 __ ucomisd(xmm0, input_reg); |
| 5603 DeoptimizeIf(not_equal, instr->environment()); | 5532 DeoptimizeIf(not_equal, instr->environment()); |
| 5604 DeoptimizeIf(parity_even, instr->environment()); // NaN. | 5533 DeoptimizeIf(parity_even, instr->environment()); // NaN. |
| 5605 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 5534 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 5606 // The integer converted back is equal to the original. We | 5535 // The integer converted back is equal to the original. We |
| 5607 // only have to test if we got -0 as an input. | 5536 // only have to test if we got -0 as an input. |
| 5608 __ test(result_reg, Operand(result_reg)); | 5537 __ test(result_reg, Operand(result_reg)); |
| 5609 __ j(not_zero, &done, Label::kNear); | 5538 __ j(not_zero, &done, Label::kNear); |
| 5610 __ movmskpd(result_reg, input_reg); | 5539 __ movmskpd(result_reg, input_reg); |
| (...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6543 FixedArray::kHeaderSize - kPointerSize)); | 6472 FixedArray::kHeaderSize - kPointerSize)); |
| 6544 __ bind(&done); | 6473 __ bind(&done); |
| 6545 } | 6474 } |
| 6546 | 6475 |
| 6547 | 6476 |
| 6548 #undef __ | 6477 #undef __ |
| 6549 | 6478 |
| 6550 } } // namespace v8::internal | 6479 } } // namespace v8::internal |
| 6551 | 6480 |
| 6552 #endif // V8_TARGET_ARCH_IA32 | 6481 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |