[arm][turbofan] Fix Double stack swap on Armv6.

The FuzzAssembleSwap test was failing with "--arm-arch=armv6". The reason was
that we were assuming we always had 2 D registers available as scratches, which
isn't the case if VFP32DREGS isn't enabled.

Change-Id: Ie97b48fd36fcbdbc6e137412c148a0bf58b498a6
Reviewed-on: https://chromium-review.googlesource.com/957733
Commit-Queue: Pierre Langlois <pierre.langlois@arm.com>
Reviewed-by: Bill Budge <bbudge@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52132}
This commit is contained in:
Pierre Langlois 2018-03-12 15:59:36 +00:00 committed by Commit Bot
parent 1126d4e44c
commit 8985083369
2 changed files with 30 additions and 11 deletions

View File

@ -1820,15 +1820,14 @@ class UseScratchRegisterScope {
return reg;
}
// Check if we have registers available to acquire.
bool CanAcquire() const { return *assembler_->GetScratchRegisterList() != 0; }
bool CanAcquireD() const { return CanAcquireVfp<DwVfpRegister>(); }
private:
friend class Assembler;
friend class TurboAssembler;
// Check if we have registers available to acquire.
// These methods are kept private intentionally to restrict their usage to the
// assemblers. Choosing to emit a difference instruction sequence depending on
// the availability of scratch registers is generally their job.
bool CanAcquire() const { return *assembler_->GetScratchRegisterList() != 0; }
template <typename T>
bool CanAcquireVfp() const;

View File

@ -3305,12 +3305,32 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
__ vstr(temp_1, dst);
} else if (source->IsDoubleStackSlot()) {
UseScratchRegisterScope temps(tasm());
DwVfpRegister temp_0 = temps.AcquireD();
DwVfpRegister temp_1 = temps.AcquireD();
__ vldr(temp_0, dst);
__ vldr(temp_1, src);
__ vstr(temp_0, src);
__ vstr(temp_1, dst);
LowDwVfpRegister temp = temps.AcquireLowD();
if (temps.CanAcquireD()) {
DwVfpRegister temp_0 = temp;
DwVfpRegister temp_1 = temps.AcquireD();
__ vldr(temp_0, dst);
__ vldr(temp_1, src);
__ vstr(temp_0, src);
__ vstr(temp_1, dst);
} else {
// We only have a single D register available. However, we can split
// it into 2 S registers and swap the slots 32 bits at a time.
MemOperand src0 = src;
MemOperand dst0 = dst;
MemOperand src1(src.rn(), src.offset() + kFloatSize);
MemOperand dst1(dst.rn(), dst.offset() + kFloatSize);
SwVfpRegister temp_0 = temp.low();
SwVfpRegister temp_1 = temp.high();
__ vldr(temp_0, dst0);
__ vldr(temp_1, src0);
__ vstr(temp_0, src0);
__ vstr(temp_1, dst0);
__ vldr(temp_0, dst1);
__ vldr(temp_1, src1);
__ vstr(temp_0, src1);
__ vstr(temp_1, dst1);
}
} else {
DCHECK(source->IsSimd128StackSlot());
MemOperand src0 = src;