[assembler][ia32] Don't clobber random registers

The fallback for {Pinsrd} and {Pextrd} for the non-avx and non-sse
variant clobbered the {xmm0} register. This CL fixes this by storing
the values on the stack and modifying them there instead.
The alternative would have been to pass in a scratch register. But this
path is not commonly used and we cannot express in the API whether the
scratch register is needed or not. So we would sometimes have to spill a
register to pass it as scratch register even though it is then unused.

R=titzer@chromium.org
CC=​mstarzinger@chromium.org

Bug: v8:6600
Change-Id: Ieae53b892cc55eed4fcfa3d0e7f82f3e1afe72be
Reviewed-on: https://chromium-review.googlesource.com/1219633
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55800}
This commit is contained in:
Clemens Hammacher 2018-09-11 15:47:29 +02:00 committed by Commit Bot
parent ae9a577c47
commit c887e40c9a
3 changed files with 34 additions and 29 deletions

View File

@ -1463,10 +1463,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
break;
case kSSEFloat64InsertLowWord32:
__ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0, true);
__ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0);
break;
case kSSEFloat64InsertHighWord32:
__ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1, true);
__ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1);
break;
case kSSEFloat64LoadLowWord32:
__ movd(i.OutputDoubleRegister(), i.InputOperand(0));

View File

@ -1509,37 +1509,44 @@ void TurboAssembler::Pextrd(Register dst, XMMRegister src, int8_t imm8) {
pextrd(dst, src, imm8);
return;
}
DCHECK_LT(imm8, 4);
pshufd(xmm0, src, imm8);
movd(dst, xmm0);
// Without AVX or SSE, we can only have 64-bit values in xmm registers.
// We don't have an xmm scratch register, so move the data via the stack. This
// path is rarely required, so it's acceptable to be slow.
DCHECK_LT(imm8, 2);
sub(esp, Immediate(kDoubleSize));
movsd(Operand(esp, 0), src);
mov(dst, Operand(esp, imm8 * kUInt32Size));
add(esp, Immediate(kDoubleSize));
}
void TurboAssembler::Pinsrd(XMMRegister dst, Operand src, int8_t imm8,
bool is_64_bits) {
void TurboAssembler::Pinsrd(XMMRegister dst, Operand src, int8_t imm8) {
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(this, AVX);
vpinsrd(dst, dst, src, imm8);
return;
}
if (CpuFeatures::IsSupported(SSE4_1)) {
CpuFeatureScope sse_scope(this, SSE4_1);
pinsrd(dst, src, imm8);
return;
}
if (is_64_bits) {
movd(xmm0, src);
if (imm8 == 1) {
punpckldq(dst, xmm0);
} else {
DCHECK_EQ(0, imm8);
psrlq(dst, 32);
punpckldq(xmm0, dst);
movaps(dst, xmm0);
}
// Without AVX or SSE, we can only have 64-bit values in xmm registers.
// We don't have an xmm scratch register, so move the data via the stack. This
// path is rarely required, so it's acceptable to be slow.
DCHECK_LT(imm8, 2);
sub(esp, Immediate(kDoubleSize));
// Write original content of {dst} to the stack.
movsd(Operand(esp, 0), dst);
// Overwrite the portion specified in {imm8}.
if (src.is_reg_only()) {
mov(Operand(esp, imm8 * kUInt32Size), src.reg());
} else {
DCHECK_LT(imm8, 4);
push(eax);
mov(eax, src);
pinsrw(dst, eax, imm8 * 2);
shr(eax, 16);
pinsrw(dst, eax, imm8 * 2 + 1);
pop(eax);
movss(dst, src);
movss(Operand(esp, imm8 * kUInt32Size), dst);
}
// Load back the full value into {dst}.
movsd(dst, Operand(esp, 0));
add(esp, Immediate(kDoubleSize));
}
void TurboAssembler::Lzcnt(Register dst, Operand src) {

View File

@ -401,12 +401,10 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void Pextrb(Register dst, XMMRegister src, int8_t imm8);
void Pextrw(Register dst, XMMRegister src, int8_t imm8);
void Pextrd(Register dst, XMMRegister src, int8_t imm8);
void Pinsrd(XMMRegister dst, Register src, int8_t imm8,
bool is_64_bits = false) {
Pinsrd(dst, Operand(src), imm8, is_64_bits);
void Pinsrd(XMMRegister dst, Register src, int8_t imm8) {
Pinsrd(dst, Operand(src), imm8);
}
void Pinsrd(XMMRegister dst, Operand src, int8_t imm8,
bool is_64_bits = false);
void Pinsrd(XMMRegister dst, Operand src, int8_t imm8);
// Expression support
// cvtsi2sd instruction only writes to the low 64-bit of dst register, which