[arm] Support float registers for moves and swaps.
Uses float registers s0-s31 for moves and swaps when rep is kFloat32. Changes bitcast to use float registers. LOG=N BUG=v8:4124 Review-Url: https://codereview.chromium.org/2039843003 Cr-Commit-Position: refs/heads/master@{#36791}
This commit is contained in:
parent
d84fe42108
commit
9eb756fb30
@ -268,6 +268,11 @@ void MacroAssembler::Move(Register dst, Register src, Condition cond) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::Move(SwVfpRegister dst, SwVfpRegister src) {
|
||||
if (!dst.is(src)) {
|
||||
vmov(dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::Move(DwVfpRegister dst, DwVfpRegister src) {
|
||||
if (!dst.is(src)) {
|
||||
@ -275,7 +280,6 @@ void MacroAssembler::Move(DwVfpRegister dst, DwVfpRegister src) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Mls(Register dst, Register src1, Register src2,
|
||||
Register srcA, Condition cond) {
|
||||
if (CpuFeatures::IsSupported(ARMv7)) {
|
||||
|
@ -170,6 +170,7 @@ class MacroAssembler: public Assembler {
|
||||
mov(dst, src, sbit, cond);
|
||||
}
|
||||
}
|
||||
void Move(SwVfpRegister dst, SwVfpRegister src);
|
||||
void Move(DwVfpRegister dst, DwVfpRegister src);
|
||||
|
||||
void Load(Register dst, const MemOperand& src, Representation r);
|
||||
|
@ -1108,6 +1108,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
DCHECK_EQ(LeaveCC, i.OutputSBit());
|
||||
break;
|
||||
}
|
||||
case kArmVmovU32F32:
|
||||
__ vmov(i.OutputRegister(), i.InputFloat32Register(0));
|
||||
DCHECK_EQ(LeaveCC, i.OutputSBit());
|
||||
break;
|
||||
case kArmVmovLowU32F64:
|
||||
__ VmovLow(i.OutputRegister(), i.InputFloat64Register(0));
|
||||
DCHECK_EQ(LeaveCC, i.OutputSBit());
|
||||
@ -1591,23 +1595,50 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
|
||||
}
|
||||
}
|
||||
} else if (source->IsFPRegister()) {
|
||||
DwVfpRegister src = g.ToDoubleRegister(source);
|
||||
if (destination->IsFPRegister()) {
|
||||
DwVfpRegister dst = g.ToDoubleRegister(destination);
|
||||
__ Move(dst, src);
|
||||
MachineRepresentation rep = LocationOperand::cast(source)->representation();
|
||||
if (rep == MachineRepresentation::kFloat64) {
|
||||
DwVfpRegister src = g.ToDoubleRegister(source);
|
||||
if (destination->IsFPRegister()) {
|
||||
DwVfpRegister dst = g.ToDoubleRegister(destination);
|
||||
__ Move(dst, src);
|
||||
} else {
|
||||
DCHECK(destination->IsFPStackSlot());
|
||||
__ vstr(src, g.ToMemOperand(destination));
|
||||
}
|
||||
} else {
|
||||
DCHECK(destination->IsFPStackSlot());
|
||||
__ vstr(src, g.ToMemOperand(destination));
|
||||
DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
||||
SwVfpRegister src = g.ToFloat32Register(source);
|
||||
if (destination->IsFPRegister()) {
|
||||
SwVfpRegister dst = g.ToFloat32Register(destination);
|
||||
__ Move(dst, src);
|
||||
} else {
|
||||
DCHECK(destination->IsFPStackSlot());
|
||||
__ vstr(src, g.ToMemOperand(destination));
|
||||
}
|
||||
}
|
||||
} else if (source->IsFPStackSlot()) {
|
||||
DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot());
|
||||
MemOperand src = g.ToMemOperand(source);
|
||||
MachineRepresentation rep =
|
||||
LocationOperand::cast(destination)->representation();
|
||||
if (destination->IsFPRegister()) {
|
||||
__ vldr(g.ToDoubleRegister(destination), src);
|
||||
if (rep == MachineRepresentation::kFloat64) {
|
||||
__ vldr(g.ToDoubleRegister(destination), src);
|
||||
} else {
|
||||
DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
||||
__ vldr(g.ToFloat32Register(destination), src);
|
||||
}
|
||||
} else {
|
||||
DwVfpRegister temp = kScratchDoubleReg;
|
||||
__ vldr(temp, src);
|
||||
__ vstr(temp, g.ToMemOperand(destination));
|
||||
DCHECK(destination->IsFPStackSlot());
|
||||
if (rep == MachineRepresentation::kFloat64) {
|
||||
DwVfpRegister temp = kScratchDoubleReg;
|
||||
__ vldr(temp, src);
|
||||
__ vstr(temp, g.ToMemOperand(destination));
|
||||
} else {
|
||||
DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
||||
SwVfpRegister temp = kScratchDoubleReg.low();
|
||||
__ vldr(temp, src);
|
||||
__ vstr(temp, g.ToMemOperand(destination));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
@ -1647,34 +1678,61 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
|
||||
__ str(temp_0, dst);
|
||||
__ vstr(temp_1, src);
|
||||
} else if (source->IsFPRegister()) {
|
||||
DwVfpRegister temp = kScratchDoubleReg;
|
||||
DwVfpRegister src = g.ToDoubleRegister(source);
|
||||
if (destination->IsFPRegister()) {
|
||||
DwVfpRegister dst = g.ToDoubleRegister(destination);
|
||||
__ Move(temp, src);
|
||||
__ Move(src, dst);
|
||||
__ Move(dst, temp);
|
||||
MachineRepresentation rep = LocationOperand::cast(source)->representation();
|
||||
LowDwVfpRegister temp = kScratchDoubleReg;
|
||||
if (rep == MachineRepresentation::kFloat64) {
|
||||
DwVfpRegister src = g.ToDoubleRegister(source);
|
||||
if (destination->IsFPRegister()) {
|
||||
DwVfpRegister dst = g.ToDoubleRegister(destination);
|
||||
__ Move(temp, src);
|
||||
__ Move(src, dst);
|
||||
__ Move(dst, temp);
|
||||
} else {
|
||||
DCHECK(destination->IsFPStackSlot());
|
||||
MemOperand dst = g.ToMemOperand(destination);
|
||||
__ Move(temp, src);
|
||||
__ vldr(src, dst);
|
||||
__ vstr(temp, dst);
|
||||
}
|
||||
} else {
|
||||
DCHECK(destination->IsFPStackSlot());
|
||||
MemOperand dst = g.ToMemOperand(destination);
|
||||
__ Move(temp, src);
|
||||
__ vldr(src, dst);
|
||||
__ vstr(temp, dst);
|
||||
DCHECK_EQ(MachineRepresentation::kFloat32, rep);
|
||||
SwVfpRegister src = g.ToFloat32Register(source);
|
||||
if (destination->IsFPRegister()) {
|
||||
SwVfpRegister dst = g.ToFloat32Register(destination);
|
||||
__ Move(temp.low(), src);
|
||||
__ Move(src, dst);
|
||||
__ Move(dst, temp.low());
|
||||
} else {
|
||||
DCHECK(destination->IsFPStackSlot());
|
||||
MemOperand dst = g.ToMemOperand(destination);
|
||||
__ Move(temp.low(), src);
|
||||
__ vldr(src, dst);
|
||||
__ vstr(temp.low(), dst);
|
||||
}
|
||||
}
|
||||
} else if (source->IsFPStackSlot()) {
|
||||
DCHECK(destination->IsFPStackSlot());
|
||||
Register temp_0 = kScratchReg;
|
||||
DwVfpRegister temp_1 = kScratchDoubleReg;
|
||||
LowDwVfpRegister temp_1 = kScratchDoubleReg;
|
||||
MemOperand src0 = g.ToMemOperand(source);
|
||||
MemOperand src1(src0.rn(), src0.offset() + kPointerSize);
|
||||
MemOperand dst0 = g.ToMemOperand(destination);
|
||||
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);
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
} else {
|
||||
// No other combinations are possible.
|
||||
UNREACHABLE();
|
||||
|
@ -93,6 +93,7 @@ namespace compiler {
|
||||
V(ArmVcvtU32F32) \
|
||||
V(ArmVcvtS32F64) \
|
||||
V(ArmVcvtU32F64) \
|
||||
V(ArmVmovU32F32) \
|
||||
V(ArmVmovLowU32F64) \
|
||||
V(ArmVmovLowF64U32) \
|
||||
V(ArmVmovHighU32F64) \
|
||||
|
@ -95,6 +95,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
|
||||
case kArmVcvtU32F32:
|
||||
case kArmVcvtS32F64:
|
||||
case kArmVcvtU32F64:
|
||||
case kArmVmovU32F32:
|
||||
case kArmVmovLowU32F64:
|
||||
case kArmVmovLowF64U32:
|
||||
case kArmVmovHighU32F64:
|
||||
|
@ -1213,7 +1213,7 @@ void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) {
|
||||
|
||||
|
||||
void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
|
||||
VisitRR(this, kArmVmovLowU32F64, node);
|
||||
VisitRR(this, kArmVmovU32F32, node);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user