Chromium Code Reviews| Index: src/compiler/arm/code-generator-arm.cc | 
| diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc | 
| index c473b9b6aa5d04923149a5c41f4b1f5d27beb5f6..ad30c666d3a76204d947e8b82e0bedae5f772f5f 100644 | 
| --- a/src/compiler/arm/code-generator-arm.cc | 
| +++ b/src/compiler/arm/code-generator-arm.cc | 
| @@ -1891,8 +1891,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, | 
| DCHECK(destination->IsDoubleStackSlot()); | 
| __ vstr(src, g.ToMemOperand(destination)); | 
| } | 
| - } else { | 
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 
| + } else if (rep == MachineRepresentation::kFloat32) { | 
| // GapResolver may give us reg codes that don't map to actual s-registers. | 
| // Generate code to work around those cases. | 
| int src_code = LocationOperand::cast(source)->register_code(); | 
| @@ -1903,6 +1902,19 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, | 
| DCHECK(destination->IsFloatStackSlot()); | 
| __ VmovExtended(g.ToMemOperand(destination), src_code, kScratchReg); | 
| } | 
| + } else { | 
| + DCHECK_EQ(MachineRepresentation::kSimd128, rep); | 
| + QwNeonRegister src = g.ToSimd128Register(source); | 
| + if (destination->IsSimd128Register()) { | 
| + QwNeonRegister dst = g.ToSimd128Register(destination); | 
| + __ Move(dst, src); | 
| + } else { | 
| + DCHECK(destination->IsSimd128StackSlot()); | 
| + MemOperand dst = g.ToMemOperand(destination); | 
| + __ vstr(src.low(), dst); | 
| 
 
martyn.capewell
2016/11/23 20:08:46
TODO here to implement this using vst1, when the i
 
bbudge
2016/11/24 02:22:53
I switched to vst1.
 
 | 
| + dst.set_offset(dst.offset() + kDoubleSize); | 
| + __ vstr(src.high(), dst); | 
| + } | 
| } | 
| } else if (source->IsFPStackSlot()) { | 
| MemOperand src = g.ToMemOperand(source); | 
| @@ -1911,24 +1923,37 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, | 
| if (destination->IsFPRegister()) { | 
| if (rep == MachineRepresentation::kFloat64) { | 
| __ vldr(g.ToDoubleRegister(destination), src); | 
| - } else { | 
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 
| + } else if (rep == MachineRepresentation::kFloat32) { | 
| // GapResolver may give us reg codes that don't map to actual | 
| // s-registers. Generate code to work around those cases. | 
| int dst_code = LocationOperand::cast(destination)->register_code(); | 
| __ VmovExtended(dst_code, src, kScratchReg); | 
| + } else { | 
| + DCHECK_EQ(MachineRepresentation::kSimd128, rep); | 
| + QwNeonRegister dst = g.ToSimd128Register(destination); | 
| + __ vldr(dst.high(), src); | 
| 
 
martyn.capewell
2016/11/23 20:08:46
TODO here to implement this using vld1, when the i
 
bbudge
2016/11/24 02:22:53
Switched to vld1.
 
 | 
| + src.set_offset(src.offset() - 4); | 
| + __ vldr(dst.low(), src); | 
| } | 
| - } else { | 
| + } else if (rep == MachineRepresentation::kFloat64) { | 
| DCHECK(destination->IsFPStackSlot()); | 
| if (rep == MachineRepresentation::kFloat64) { | 
| DwVfpRegister temp = kScratchDoubleReg; | 
| __ vldr(temp, src); | 
| __ vstr(temp, g.ToMemOperand(destination)); | 
| - } else { | 
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 
| + } else if (rep == MachineRepresentation::kFloat32) { | 
| SwVfpRegister temp = kScratchDoubleReg.low(); | 
| __ vldr(temp, src); | 
| __ vstr(temp, g.ToMemOperand(destination)); | 
| + } else { | 
| + DCHECK_EQ(MachineRepresentation::kSimd128, rep); | 
| + MemOperand dst = g.ToMemOperand(destination); | 
| + __ vldr(kScratchDoubleReg, src); | 
| 
 
martyn.capewell
2016/11/23 20:08:46
TODO here to implement this using vld1/vst1 and re
 
bbudge
2016/11/24 02:22:53
Switched to vld1/vst1.
 
 | 
| + __ vstr(kScratchDoubleReg, dst); | 
| + src.set_offset(src.offset() + kDoubleSize); | 
| + dst.set_offset(dst.offset() + kDoubleSize); | 
| + __ vldr(kScratchDoubleReg, src); | 
| + __ vstr(kScratchDoubleReg, dst); | 
| } | 
| } | 
| } else { | 
| @@ -1936,7 +1961,6 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, | 
| } | 
| } | 
| - | 
| void CodeGenerator::AssembleSwap(InstructionOperand* source, | 
| InstructionOperand* destination) { | 
| ArmOperandConverter g(this, nullptr); | 
| @@ -1975,7 +1999,7 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, | 
| DwVfpRegister src = g.ToDoubleRegister(source); | 
| if (destination->IsFPRegister()) { | 
| DwVfpRegister dst = g.ToDoubleRegister(destination); | 
| - __ vswp(src, dst); | 
| + __ Swap(src, dst); | 
| } else { | 
| DCHECK(destination->IsFPStackSlot()); | 
| MemOperand dst = g.ToMemOperand(destination); | 
| @@ -1983,8 +2007,7 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, | 
| __ vldr(src, dst); | 
| __ vstr(temp, dst); | 
| } | 
| - } else { | 
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 
| + } else if (rep == MachineRepresentation::kFloat32) { | 
| int src_code = LocationOperand::cast(source)->register_code(); | 
| if (destination->IsFPRegister()) { | 
| int dst_code = LocationOperand::cast(destination)->register_code(); | 
| @@ -1998,29 +2021,56 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, | 
| __ VmovExtended(src_code, dst, kScratchReg); | 
| __ vstr(temp.low(), dst); | 
| } | 
| + } else { | 
| + DCHECK_EQ(MachineRepresentation::kSimd128, rep); | 
| + QwNeonRegister src = g.ToSimd128Register(source); | 
| + if (destination->IsFPRegister()) { | 
| + QwNeonRegister dst = g.ToSimd128Register(destination); | 
| + __ Swap(src, dst); | 
| + } else { | 
| + DCHECK(destination->IsFPStackSlot()); | 
| + MemOperand dst = g.ToMemOperand(destination); | 
| + QwNeonRegister temp = kScratchQuadReg; | 
| + MemOperand dst2(dst.rn(), dst.offset() + kDoubleSize); | 
| + __ Move(temp, src); | 
| + __ vldr(src.low(), dst); | 
| + __ vldr(src.high(), dst2); | 
| + __ vstr(temp.low(), dst); | 
| + __ vstr(temp.high(), dst2); | 
| + __ vmov(kDoubleRegZero, 0); // Restore the 0 register. | 
| 
 
martyn.capewell
2016/11/23 20:08:46
This is relatively expensive, which is why we stat
 
bbudge
2016/11/24 02:22:53
Added veor for d- and q- registers.
 
 | 
| + } | 
| } | 
| } else if (source->IsFPStackSlot()) { | 
| DCHECK(destination->IsFPStackSlot()); | 
| - Register temp_0 = kScratchReg; | 
| - LowDwVfpRegister temp_1 = kScratchDoubleReg; | 
| - MemOperand src0 = g.ToMemOperand(source); | 
| - MemOperand dst0 = g.ToMemOperand(destination); | 
| + LowDwVfpRegister temp = kScratchDoubleReg; | 
| + LowDwVfpRegister zero = kDoubleRegZero; | 
| + MemOperand src = g.ToMemOperand(source); | 
| + MemOperand dst = g.ToMemOperand(destination); | 
| MachineRepresentation rep = LocationOperand::cast(source)->representation(); | 
| if (rep == MachineRepresentation::kFloat64) { | 
| - MemOperand src1(src0.rn(), src0.offset() + kPointerSize); | 
| - MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize); | 
| - __ vldr(temp_1, dst0); // Save destination in temp_1. | 
| - __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. | 
| - __ str(temp_0, dst0); | 
| - __ ldr(temp_0, src1); | 
| - __ str(temp_0, dst1); | 
| - __ vstr(temp_1, src0); | 
| + __ vldr(temp, dst); | 
| + __ vldr(zero, src); | 
| + __ vstr(temp, src); | 
| + __ vstr(zero, dst); | 
| + __ vmov(kDoubleRegZero, 0); // Restore the 0 register. | 
| + } else if (rep == MachineRepresentation::kFloat32) { | 
| + __ vldr(temp.low(), dst); | 
| + __ vldr(temp.high(), src); | 
| + __ vstr(temp.low(), src); | 
| + __ vstr(temp.high(), dst); | 
| } else { | 
| - DCHECK_EQ(MachineRepresentation::kFloat32, rep); | 
| - __ vldr(temp_1.low(), dst0); // Save destination in temp_1. | 
| - __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. | 
| - __ str(temp_0, dst0); | 
| - __ vstr(temp_1.low(), src0); | 
| + DCHECK_EQ(MachineRepresentation::kSimd128, rep); | 
| + __ vldr(temp, dst); | 
| + __ vldr(zero, src); | 
| + __ vstr(temp, src); | 
| + __ vstr(zero, dst); | 
| + src.set_offset(src.offset() + kDoubleSize); | 
| + dst.set_offset(dst.offset() + kDoubleSize); | 
| + __ vldr(temp, dst); | 
| + __ vldr(zero, src); | 
| + __ vstr(temp, src); | 
| + __ vstr(zero, dst); | 
| + __ vmov(kDoubleRegZero, 0); // Restore the 0 register. | 
| } | 
| } else { | 
| // No other combinations are possible. |