Commit c701bd2e authored by Bill Budge's avatar Bill Budge Committed by Commit Bot

[Turbofan] Fix x64 128 bit swaps when AVX is not supported.

- Changes x64 AssembleSwap to push/pop to swap 128 bit slot swaps.
- Reorders instructions to simplify 32/64 bit FP slot swaps.
- Refactor ia32 version of this, eliminating OffsetOperand in favor of
  existing ToOperand.

Bug: v8:6020
Change-Id: Ie0ae4c581c9aeb88ee786797851c3c77d5210a3d
Reviewed-on: https://chromium-review.googlesource.com/669748
Commit-Queue: Bill Budge <bbudge@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48096}
parent 21bbdec5
......@@ -60,11 +60,6 @@ class IA32OperandConverter : public InstructionOperandConverter {
offset.offset() + extra);
}
Operand OffsetOperand(InstructionOperand* op, int offset) {
DCHECK(op->IsFPStackSlot());
return ToOperand(op, offset);
}
Immediate ToImmediate(InstructionOperand* operand) {
Constant constant = ToConstant(operand);
if (constant.type() == Constant::kInt32 &&
......@@ -2924,7 +2919,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
} else {
DCHECK(destination->IsFPStackSlot());
Operand dst0 = g.ToOperand(destination);
Operand dst1 = g.OffsetOperand(destination, kPointerSize);
Operand dst1 = g.ToOperand(destination, kPointerSize);
__ Move(dst0, Immediate(lower));
__ Move(dst1, Immediate(upper));
}
......@@ -3051,8 +3046,8 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
__ movsd(kScratchDoubleReg, dst0); // Save dst in scratch register.
__ push(src0); // Then use stack to copy src to destination.
__ pop(dst0);
__ push(g.OffsetOperand(source, kPointerSize));
__ pop(g.OffsetOperand(destination, kPointerSize));
__ push(g.ToOperand(source, kPointerSize));
__ pop(g.ToOperand(destination, kPointerSize));
__ movsd(src0, kScratchDoubleReg);
} else if (rep == MachineRepresentation::kFloat32) {
__ movss(kScratchDoubleReg, dst0); // Save dst in scratch register.
......@@ -3064,12 +3059,12 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
__ movups(kScratchDoubleReg, dst0); // Save dst in scratch register.
__ push(src0); // Then use stack to copy src to destination.
__ pop(dst0);
__ push(g.OffsetOperand(source, kPointerSize));
__ pop(g.OffsetOperand(destination, kPointerSize));
__ push(g.OffsetOperand(source, 2 * kPointerSize));
__ pop(g.OffsetOperand(destination, 2 * kPointerSize));
__ push(g.OffsetOperand(source, 3 * kPointerSize));
__ pop(g.OffsetOperand(destination, 3 * kPointerSize));
__ push(g.ToOperand(source, kPointerSize));
__ pop(g.ToOperand(destination, kPointerSize));
__ push(g.ToOperand(source, 2 * kPointerSize));
__ pop(g.ToOperand(destination, 2 * kPointerSize));
__ push(g.ToOperand(source, 3 * kPointerSize));
__ pop(g.ToOperand(destination, 3 * kPointerSize));
__ movups(src0, kScratchDoubleReg);
}
} else {
......
......@@ -3344,28 +3344,30 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
if (rep != MachineRepresentation::kSimd128) {
Register tmp = kScratchRegister;
__ movq(tmp, dst);
__ pushq(src);
__ pushq(src); // Then use stack to copy src to destination.
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kPointerSize);
frame_access_state()->IncreaseSPDelta(1);
src = g.ToOperand(source);
__ movq(src, tmp);
frame_access_state()->IncreaseSPDelta(-1);
dst = g.ToOperand(destination);
__ popq(dst);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
-kPointerSize);
__ movq(src, tmp);
} else {
// Use the XOR trick to swap without a temporary. The xorps may read
// from or write to an unaligned address, causing a slowdown, but swaps
// between slots should be rare.
__ 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);
// Without AVX, misaligned reads and writes will trap. Move using the
// stack, in two parts.
__ movups(kScratchDoubleReg, dst); // Save dst in scratch register.
__ pushq(src); // Then use stack to copy src to destination.
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kPointerSize);
__ popq(dst);
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
-kPointerSize);
__ pushq(g.ToOperand(source, kPointerSize));
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kPointerSize);
__ popq(g.ToOperand(destination, kPointerSize));
unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
-kPointerSize);
__ movups(src, kScratchDoubleReg);
}
} else if (source->IsFPRegister() && destination->IsFPRegister()) {
// XMM register-register swap.
......
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