Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 18612005: Implement truncated d-to-i with a stub on x86 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add support for all register combinations Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698