Chromium Code Reviews| 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(); |