Index: src/compiler/x64/code-generator-x64.cc |
diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc |
index 4dc75592ec2b189a5581a5ce1f89399cd40a02b2..3826e17c144081a198c1d619373c45a937a442d9 100644 |
--- a/src/compiler/x64/code-generator-x64.cc |
+++ b/src/compiler/x64/code-generator-x64.cc |
@@ -2359,24 +2359,47 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, |
} |
} else if (source->IsFPRegister()) { |
XMMRegister src = g.ToDoubleRegister(source); |
+ MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
if (destination->IsFPRegister()) { |
XMMRegister dst = g.ToDoubleRegister(destination); |
- __ Movapd(dst, src); |
+ if (rep != MachineRepresentation::kSimd128) { |
Benedikt Meurer
2016/07/10 17:21:06
Can't we always do Movapd here?
bbudge
2016/07/10 22:45:22
You're right. Replaced original code.
|
+ __ Movapd(dst, src); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
+ __ movups(dst, src); |
+ } |
} else { |
DCHECK(destination->IsFPStackSlot()); |
Operand dst = g.ToOperand(destination); |
- __ Movsd(dst, src); |
+ if (rep != MachineRepresentation::kSimd128) { |
+ __ Movsd(dst, src); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
+ __ movups(dst, src); |
Benedikt Meurer
2016/07/10 17:21:06
You should introduce Movups, that uses AVX instruc
bbudge
2016/07/10 22:45:22
Done.
|
+ } |
} |
} else if (source->IsFPStackSlot()) { |
DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); |
Operand src = g.ToOperand(source); |
+ MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
if (destination->IsFPRegister()) { |
XMMRegister dst = g.ToDoubleRegister(destination); |
- __ Movsd(dst, src); |
+ if (rep != MachineRepresentation::kSimd128) { |
+ __ Movsd(dst, src); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
+ __ movups(dst, src); |
+ } |
} else { |
Operand dst = g.ToOperand(destination); |
- __ Movsd(kScratchDoubleReg, src); |
- __ Movsd(dst, kScratchDoubleReg); |
+ if (rep != MachineRepresentation::kSimd128) { |
+ __ Movsd(kScratchDoubleReg, src); |
+ __ Movsd(dst, kScratchDoubleReg); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
+ __ movups(kScratchDoubleReg, src); |
+ __ movups(dst, kScratchDoubleReg); |
+ } |
} |
} else { |
UNREACHABLE(); |
@@ -2408,31 +2431,60 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, |
} else if ((source->IsStackSlot() && destination->IsStackSlot()) || |
(source->IsFPStackSlot() && destination->IsFPStackSlot())) { |
// Memory-memory. |
- Register tmp = kScratchRegister; |
Operand src = g.ToOperand(source); |
Operand dst = g.ToOperand(destination); |
- __ movq(tmp, dst); |
- __ pushq(src); |
- frame_access_state()->IncreaseSPDelta(1); |
- src = g.ToOperand(source); |
- __ movq(src, tmp); |
- frame_access_state()->IncreaseSPDelta(-1); |
- dst = g.ToOperand(destination); |
- __ popq(dst); |
+ MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
+ if (rep != MachineRepresentation::kSimd128) { |
+ Register tmp = kScratchRegister; |
+ __ movq(tmp, dst); |
+ __ pushq(src); |
+ frame_access_state()->IncreaseSPDelta(1); |
+ src = g.ToOperand(source); |
+ __ movq(src, tmp); |
+ frame_access_state()->IncreaseSPDelta(-1); |
+ dst = g.ToOperand(destination); |
+ __ popq(dst); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
+ // Use the XOR trick to swap without a temporary. |
+ __ movups(kScratchDoubleReg, src); |
+ __ xorps(kScratchDoubleReg, dst); // scratch contains src ^ dst. |
+ __ movups(src, kScratchDoubleReg); |
+ __ xorps(kScratchDoubleReg, dst); // scratch contains src. |
+ __ movups(dst, kScratchDoubleReg); |
+ __ xorps(kScratchDoubleReg, src); // scratch contains dst. |
+ __ movups(src, kScratchDoubleReg); |
+ } |
} else if (source->IsFPRegister() && destination->IsFPRegister()) { |
// XMM register-register swap. |
XMMRegister src = g.ToDoubleRegister(source); |
XMMRegister dst = g.ToDoubleRegister(destination); |
- __ Movapd(kScratchDoubleReg, src); |
- __ Movapd(src, dst); |
- __ Movapd(dst, kScratchDoubleReg); |
+ MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
+ if (rep != MachineRepresentation::kSimd128) { |
+ __ Movapd(kScratchDoubleReg, src); |
+ __ Movapd(src, dst); |
+ __ Movapd(dst, kScratchDoubleReg); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
+ __ movups(kScratchDoubleReg, src); |
+ __ movups(src, dst); |
+ __ movups(dst, kScratchDoubleReg); |
+ } |
} else if (source->IsFPRegister() && destination->IsFPStackSlot()) { |
// XMM register-memory swap. |
XMMRegister src = g.ToDoubleRegister(source); |
Operand dst = g.ToOperand(destination); |
- __ Movsd(kScratchDoubleReg, src); |
- __ Movsd(src, dst); |
- __ Movsd(dst, kScratchDoubleReg); |
+ MachineRepresentation rep = LocationOperand::cast(source)->representation(); |
+ if (rep != MachineRepresentation::kSimd128) { |
+ __ Movsd(kScratchDoubleReg, src); |
+ __ Movsd(src, dst); |
+ __ Movsd(dst, kScratchDoubleReg); |
+ } else { |
+ DCHECK_EQ(MachineRepresentation::kSimd128, rep); |
+ __ movups(kScratchDoubleReg, src); |
+ __ movups(src, dst); |
+ __ movups(dst, kScratchDoubleReg); |
+ } |
} else { |
// No other combinations are possible. |
UNREACHABLE(); |