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(); |
+ } |
+ 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 |