Commit 929c6191 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Quickfix for DoMathPowHalf.

TEST=regress-397.js

Review URL: http://codereview.chromium.org/8769037

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10140 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 33615c61
...@@ -2057,6 +2057,16 @@ void Assembler::ucomisd(XMMRegister dst, XMMRegister src) { ...@@ -2057,6 +2057,16 @@ void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
} }
void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
EMIT(0x2E);
emit_sse_operand(dst, src);
}
void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) { void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
ASSERT(CpuFeatures::IsEnabled(SSE4_1)); ASSERT(CpuFeatures::IsEnabled(SSE4_1));
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
......
...@@ -987,6 +987,7 @@ class Assembler : public AssemblerBase { ...@@ -987,6 +987,7 @@ class Assembler : public AssemblerBase {
void andpd(XMMRegister dst, XMMRegister src); void andpd(XMMRegister dst, XMMRegister src);
void ucomisd(XMMRegister dst, XMMRegister src); void ucomisd(XMMRegister dst, XMMRegister src);
void ucomisd(XMMRegister dst, const Operand& src);
enum RoundingMode { enum RoundingMode {
kRoundToNearest = 0x0, kRoundToNearest = 0x0,
......
...@@ -3003,13 +3003,9 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -3003,13 +3003,9 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// Check base in xmm1 for NaN or +/-Infinity // Check base in xmm1 for NaN or +/-Infinity
const int kExponentShift = kBitsPerByte * const int kExponentShift = kBitsPerByte *
(HeapNumber::kExponentOffset - HeapNumber::kMantissaOffset); (HeapNumber::kExponentOffset - HeapNumber::kMantissaOffset);
if (CpuFeatures::IsSupported(SSE4_1)) { __ movsd(xmm4, xmm1);
__ extractps(ecx, xmm1, kExponentShift); __ psrlq(xmm4, kExponentShift);
} else { __ movd(ecx, xmm4);
__ movsd(xmm4, xmm1);
__ psrlq(xmm4, kExponentShift);
__ movd(ecx, xmm4);
}
__ and_(ecx, HeapNumber::kExponentMask); __ and_(ecx, HeapNumber::kExponentMask);
__ cmp(ecx, Immediate(HeapNumber::kExponentMask)); __ cmp(ecx, Immediate(HeapNumber::kExponentMask));
__ j(equal, &generic_runtime); __ j(equal, &generic_runtime);
......
...@@ -2938,9 +2938,28 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { ...@@ -2938,9 +2938,28 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
XMMRegister xmm_scratch = xmm0; XMMRegister xmm_scratch = xmm0;
XMMRegister input_reg = ToDoubleRegister(instr->value()); XMMRegister input_reg = ToDoubleRegister(instr->value());
ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
Label return_infinity, done;
// Check base for +/- infinity.
__ push(ecx); // TODO(1848): reserve this register.
__ mov(ecx, factory()->infinity_value());
__ ucomisd(input_reg, FieldOperand(ecx, HeapNumber::kValueOffset));
__ j(equal, &return_infinity, Label::kNear);
__ xorps(xmm_scratch, xmm_scratch);
__ subsd(xmm_scratch, input_reg);
__ ucomisd(xmm_scratch, FieldOperand(ecx, HeapNumber::kValueOffset));
__ j(equal, &return_infinity, Label::kNear);
__ pop(ecx);
__ xorps(xmm_scratch, xmm_scratch); __ xorps(xmm_scratch, xmm_scratch);
__ addsd(input_reg, xmm_scratch); // Convert -0 to +0. __ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
__ sqrtsd(input_reg, input_reg); __ sqrtsd(input_reg, input_reg);
__ jmp(&done, Label::kNear);
__ bind(&return_infinity);
__ movdbl(input_reg, FieldOperand(ecx, HeapNumber::kValueOffset));
__ pop(ecx);
__ bind(&done);
} }
......
...@@ -25,10 +25,19 @@ ...@@ -25,10 +25,19 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// See http://code.google.com/p/v8/issues/detail?id=397 // See http://code.google.com/p/v8/issues/detail?id=397
assertEquals("Infinity", String(Math.pow(Infinity, 0.5)));
assertEquals(0, Math.pow(Infinity, -0.5));
assertEquals("Infinity", String(Math.pow(-Infinity, 0.5))); function test() {
assertEquals(0, Math.pow(-Infinity, -0.5)); assertEquals("Infinity", String(Math.pow(Infinity, 0.5)));
assertEquals(0, Math.pow(Infinity, -0.5));
assertEquals("Infinity", String(Math.pow(-Infinity, 0.5)));
assertEquals(0, Math.pow(-Infinity, -0.5));
}
test();
test();
%OptimizeFunctionOnNextCall(test);
test();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment