Chromium Code Reviews| Index: src/ia32/lithium-gap-resolver-ia32.cc |
| diff --git a/src/ia32/lithium-gap-resolver-ia32.cc b/src/ia32/lithium-gap-resolver-ia32.cc |
| index b062ba5d31187ff1353f4b4fd7a78ee4576bf987..6c7e375ad69ba2498bc7e011b93b3a416da46d55 100644 |
| --- a/src/ia32/lithium-gap-resolver-ia32.cc |
| +++ b/src/ia32/lithium-gap-resolver-ia32.cc |
| @@ -324,29 +324,61 @@ void LGapResolver::EmitMove(int index) { |
| } |
| } else if (source->IsDoubleRegister()) { |
| - CpuFeatureScope scope(cgen_->masm(), SSE2); |
| - XMMRegister src = cgen_->ToDoubleRegister(source); |
| - if (destination->IsDoubleRegister()) { |
| - XMMRegister dst = cgen_->ToDoubleRegister(destination); |
| - __ movaps(dst, src); |
| + if (CpuFeatures::IsSupported(SSE2)) { |
| + CpuFeatureScope scope(cgen_->masm(), SSE2); |
| + XMMRegister src = cgen_->ToDoubleRegister(source); |
| + if (destination->IsDoubleRegister()) { |
| + XMMRegister dst = cgen_->ToDoubleRegister(destination); |
| + __ movaps(dst, src); |
| + } else { |
| + ASSERT(destination->IsDoubleStackSlot()); |
| + Operand dst = cgen_->ToOperand(destination); |
| + __ movdbl(dst, src); |
| + } |
| } else { |
| + // load from the register onto the stack, store in destination, which must |
| + // be a double stack slot in the non-SSE2 case. |
| + ASSERT(source->index() == 0); // source is on top of the stack |
| ASSERT(destination->IsDoubleStackSlot()); |
| Operand dst = cgen_->ToOperand(destination); |
| - __ movdbl(dst, src); |
| + cgen_->ReadX87Operand(dst); |
| } |
| } else if (source->IsDoubleStackSlot()) { |
| - CpuFeatureScope scope(cgen_->masm(), SSE2); |
| - ASSERT(destination->IsDoubleRegister() || |
| - destination->IsDoubleStackSlot()); |
| - Operand src = cgen_->ToOperand(source); |
| - if (destination->IsDoubleRegister()) { |
| - XMMRegister dst = cgen_->ToDoubleRegister(destination); |
| - __ movdbl(dst, src); |
| + if (CpuFeatures::IsSupported(SSE2)) { |
| + CpuFeatureScope scope(cgen_->masm(), SSE2); |
| + ASSERT(destination->IsDoubleRegister() || |
| + destination->IsDoubleStackSlot()); |
| + Operand src = cgen_->ToOperand(source); |
| + if (destination->IsDoubleRegister()) { |
| + XMMRegister dst = cgen_->ToDoubleRegister(destination); |
| + __ movdbl(dst, src); |
| + } else { |
| + // We rely on having xmm0 available as a fixed scratch register. |
| + Operand dst = cgen_->ToOperand(destination); |
| + __ movdbl(xmm0, src); |
| + __ movdbl(dst, xmm0); |
| + } |
| } else { |
| - // We rely on having xmm0 available as a fixed scratch register. |
| - Operand dst = cgen_->ToOperand(destination); |
| - __ movdbl(xmm0, src); |
| - __ movdbl(dst, xmm0); |
| + // load from the stack slot on top of the floating point stack, and then |
| + // store in destination. If destination is a double register, then it |
| + // represents the top of the stack and nothing needs to be done. |
| + if (destination->IsDoubleStackSlot()) { |
| + Register tmp = EnsureTempRegister(); |
| + Operand src0 = cgen_->ToOperand(source); |
| + Operand src1 = cgen_->HighOperand(source); |
| + Operand dst0 = cgen_->ToOperand(destination); |
| + Operand dst1 = cgen_->HighOperand(destination); |
| + __ mov(tmp, src0); // Then use tmp to copy source to destination. |
| + __ mov(dst0, tmp); |
| + __ mov(tmp, src1); |
| + __ mov(dst1, tmp); |
| + } else { |
| + Operand src = cgen_->ToOperand(source); |
| + if (cgen_->X87StackNonEmpty()) { |
| + cgen_->PopX87(); |
|
danno
2013/04/09 07:37:07
Slightly faster might be to just store rather that
mvstanton
2013/04/09 08:49:13
Hmm, I'm looking at the x87 instructions, and all
|
| + } |
| + cgen_->PushX87DoubleOperand(src); |
| + } |
| } |
| } else { |
| UNREACHABLE(); |
| @@ -419,21 +451,19 @@ void LGapResolver::EmitSwap(int index) { |
| __ movaps(xmm0, src); |
| __ movaps(src, dst); |
| __ movaps(dst, xmm0); |
| - |
| } else if (source->IsDoubleRegister() || destination->IsDoubleRegister()) { |
| CpuFeatureScope scope(cgen_->masm(), SSE2); |
| // XMM register-memory swap. We rely on having xmm0 |
| // available as a fixed scratch register. |
| ASSERT(source->IsDoubleStackSlot() || destination->IsDoubleStackSlot()); |
| XMMRegister reg = cgen_->ToDoubleRegister(source->IsDoubleRegister() |
| - ? source |
| - : destination); |
| + ? source |
| + : destination); |
| Operand other = |
| cgen_->ToOperand(source->IsDoubleRegister() ? destination : source); |
| __ movdbl(xmm0, other); |
| __ movdbl(other, reg); |
| __ movdbl(reg, Operand(xmm0)); |
| - |
| } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) { |
| CpuFeatureScope scope(cgen_->masm(), SSE2); |
| // Double-width memory-to-memory. Spill on demand to use a general |