Bug 950703 - SpiderMonkey: Move float32 values with 32-bit move instructions. r=jandem

This commit is contained in:
Dan Gohman 2013-12-17 08:46:37 -08:00
parent f3d377a9ee
commit ae4c4ef18c
6 changed files with 70 additions and 4 deletions

View File

@ -1416,6 +1416,12 @@ MacroAssemblerARM::ma_vmov(FloatRegister src, FloatRegister dest, Condition cc)
as_vmov(dest, src, cc);
}
void
MacroAssemblerARM::ma_vmov_f32(FloatRegister src, FloatRegister dest, Condition cc)
{
as_vmov(VFPRegister(dest).singleOverlay(), VFPRegister(src).singleOverlay(), cc);
}
void
MacroAssemblerARM::ma_vneg(FloatRegister src, FloatRegister dest, Condition cc)
{

View File

@ -318,6 +318,7 @@ class MacroAssemblerARM : public Assembler
void ma_vneg(FloatRegister src, FloatRegister dest, Condition cc = Always);
void ma_vmov(FloatRegister src, FloatRegister dest, Condition cc = Always);
void ma_vmov_f32(FloatRegister src, FloatRegister dest, Condition cc = Always);
void ma_vabs(FloatRegister src, FloatRegister dest, Condition cc = Always);
void ma_vabs_f32(FloatRegister src, FloatRegister dest, Condition cc = Always);

View File

@ -224,6 +224,29 @@ MoveEmitterARM::emitMove(const MoveOperand &from, const MoveOperand &to)
}
}
void
MoveEmitterARM::emitFloat32Move(const MoveOperand &from, const MoveOperand &to)
{
if (from.isFloatReg()) {
if (to.isFloatReg())
masm.ma_vmov_f32(from.floatReg(), to.floatReg());
else
masm.ma_vstr(VFPRegister(from.floatReg()).singleOverlay(),
toOperand(to, true));
} else if (to.isFloatReg()) {
masm.ma_vldr(toOperand(from, true),
VFPRegister(to.floatReg()).singleOverlay());
} else {
// Memory to memory move.
JS_ASSERT(from.isMemory());
FloatRegister reg = ScratchFloatReg;
masm.ma_vldr(toOperand(from, true),
VFPRegister(reg).singleOverlay());
masm.ma_vstr(VFPRegister(reg).singleOverlay(),
toOperand(to, true));
}
}
void
MoveEmitterARM::emitDoubleMove(const MoveOperand &from, const MoveOperand &to)
{
@ -235,7 +258,7 @@ MoveEmitterARM::emitDoubleMove(const MoveOperand &from, const MoveOperand &to)
} else if (to.isFloatReg()) {
masm.ma_vldr(toOperand(from, true), to.floatReg());
} else {
// Memory to memory float move.
// Memory to memory move.
JS_ASSERT(from.isMemory());
FloatRegister reg = ScratchFloatReg;
masm.ma_vldr(toOperand(from, true), reg);
@ -262,6 +285,8 @@ MoveEmitterARM::emit(const MoveOp &move)
switch (move.type()) {
case MoveOp::FLOAT32:
emitFloat32Move(from, to);
break;
case MoveOp::DOUBLE:
emitDoubleMove(from, to);
break;

View File

@ -28,7 +28,6 @@ class MoveEmitterARM
// stack space has been allocated for that particular spill.
int32_t pushedAtCycle_;
int32_t pushedAtSpill_;
int32_t pushedAtDoubleSpill_;
// These are registers that are available for temporary use. They may be
// assigned InvalidReg. If no corresponding spill space has been assigned,
@ -41,10 +40,10 @@ class MoveEmitterARM
FloatRegister tempFloatReg();
Operand cycleSlot() const;
Operand spillSlot() const;
Operand doubleSpillSlot() const;
Operand toOperand(const MoveOperand &operand, bool isFloat) const;
void emitMove(const MoveOperand &from, const MoveOperand &to);
void emitFloat32Move(const MoveOperand &from, const MoveOperand &to);
void emitDoubleMove(const MoveOperand &from, const MoveOperand &to);
void breakCycle(const MoveOperand &from, const MoveOperand &to, MoveOp::Type type);
void completeCycle(const MoveOperand &from, const MoveOperand &to, MoveOp::Type type);

View File

@ -130,6 +130,8 @@ MoveEmitterX86::emit(const MoveResolver &moves)
// A normal move which is not part of a cycle.
switch (move.type()) {
case MoveOp::FLOAT32:
emitFloat32Move(from, to);
break;
case MoveOp::DOUBLE:
emitDoubleMove(from, to);
break;
@ -221,6 +223,13 @@ MoveEmitterX86::breakCycle(const MoveOperand &to, MoveOp::Type type)
// the original move to continue.
switch (type) {
case MoveOp::FLOAT32:
if (to.isMemory()) {
masm.loadFloat32(toAddress(to), ScratchFloatReg);
masm.storeFloat32(ScratchFloatReg, cycleSlot());
} else {
masm.storeFloat32(to.floatReg(), cycleSlot());
}
break;
case MoveOp::DOUBLE:
if (to.isMemory()) {
masm.loadDouble(toAddress(to), ScratchFloatReg);
@ -248,6 +257,13 @@ MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Type type)
// saved value of B, to A.
switch (type) {
case MoveOp::FLOAT32:
if (to.isMemory()) {
masm.loadFloat32(cycleSlot(), ScratchFloatReg);
masm.storeFloat32(ScratchFloatReg, toAddress(to));
} else {
masm.loadFloat32(cycleSlot(), to.floatReg());
}
break;
case MoveOp::DOUBLE:
if (to.isMemory()) {
masm.loadDouble(cycleSlot(), ScratchFloatReg);
@ -308,6 +324,24 @@ MoveEmitterX86::emitGeneralMove(const MoveOperand &from, const MoveOperand &to)
}
}
void
MoveEmitterX86::emitFloat32Move(const MoveOperand &from, const MoveOperand &to)
{
if (from.isFloatReg()) {
if (to.isFloatReg())
masm.moveFloat32(from.floatReg(), to.floatReg());
else
masm.storeFloat32(from.floatReg(), toAddress(to));
} else if (to.isFloatReg()) {
masm.loadFloat32(toAddress(from), to.floatReg());
} else {
// Memory to memory move.
JS_ASSERT(from.isMemory());
masm.loadFloat32(toAddress(from), ScratchFloatReg);
masm.storeFloat32(ScratchFloatReg, toAddress(to));
}
}
void
MoveEmitterX86::emitDoubleMove(const MoveOperand &from, const MoveOperand &to)
{
@ -319,7 +353,7 @@ MoveEmitterX86::emitDoubleMove(const MoveOperand &from, const MoveOperand &to)
} else if (to.isFloatReg()) {
masm.loadDouble(toAddress(from), to.floatReg());
} else {
// Memory to memory float move.
// Memory to memory move.
JS_ASSERT(from.isMemory());
masm.loadDouble(toAddress(from), ScratchFloatReg);
masm.storeDouble(ScratchFloatReg, toAddress(to));

View File

@ -44,6 +44,7 @@ class MoveEmitterX86
bool maybeEmitOptimizedCycle(const MoveResolver &moves, size_t i,
bool allGeneralRegs, bool allFloatRegs, size_t swapCount);
void emitGeneralMove(const MoveOperand &from, const MoveOperand &to);
void emitFloat32Move(const MoveOperand &from, const MoveOperand &to);
void emitDoubleMove(const MoveOperand &from, const MoveOperand &to);
void breakCycle(const MoveOperand &to, MoveOp::Type type);
void completeCycle(const MoveOperand &to, MoveOp::Type type);