Bug 1019831: SIMD x86-x64: MoveResolver and MoveEmitter for Int32x4; r=sunfish

--HG--
extra : rebase_source : 2df9a4ee6021b51db7a8999e44fce39ba72f04e2
This commit is contained in:
Benjamin Bouvier 2014-08-07 17:57:35 +02:00
parent a462b19fa5
commit 827ec5eabb
4 changed files with 48 additions and 6 deletions

View File

@ -1571,10 +1571,11 @@ CodeGenerator::visitMoveGroup(LMoveGroup *group)
#else
case LDefinition::BOX:
#endif
case LDefinition::GENERAL: moveType = MoveOp::GENERAL; break;
case LDefinition::INT32: moveType = MoveOp::INT32; break;
case LDefinition::FLOAT32: moveType = MoveOp::FLOAT32; break;
case LDefinition::DOUBLE: moveType = MoveOp::DOUBLE; break;
case LDefinition::GENERAL: moveType = MoveOp::GENERAL; break;
case LDefinition::INT32: moveType = MoveOp::INT32; break;
case LDefinition::FLOAT32: moveType = MoveOp::FLOAT32; break;
case LDefinition::DOUBLE: moveType = MoveOp::DOUBLE; break;
case LDefinition::INT32X4: moveType = MoveOp::INT32X4; break;
default: MOZ_ASSUME_UNREACHABLE("Unexpected move type");
}

View File

@ -141,7 +141,8 @@ class MoveOp
GENERAL,
INT32,
FLOAT32,
DOUBLE
DOUBLE,
INT32X4
};
protected:

View File

@ -141,6 +141,9 @@ MoveEmitterX86::emit(const MoveResolver &moves)
case MoveOp::GENERAL:
emitGeneralMove(from, to);
break;
case MoveOp::INT32X4:
emitInt32X4Move(from, to);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unexpected move type");
}
@ -157,7 +160,7 @@ MoveEmitterX86::cycleSlot()
{
if (pushedAtCycle_ == -1) {
// Reserve stack for cycle resolution
masm.reserveStack(sizeof(double));
masm.reserveStack(Simd128DataSize);
pushedAtCycle_ = masm.framePushed();
}
@ -225,6 +228,14 @@ MoveEmitterX86::breakCycle(const MoveOperand &to, MoveOp::Type type)
// This case handles (A -> B), which we reach first. We save B, then allow
// the original move to continue.
switch (type) {
case MoveOp::INT32X4:
if (to.isMemory()) {
masm.loadAlignedInt32x4(toAddress(to), ScratchSimdReg);
masm.storeAlignedInt32x4(ScratchSimdReg, cycleSlot());
} else {
masm.storeAlignedInt32x4(to.floatReg(), cycleSlot());
}
break;
case MoveOp::FLOAT32:
if (to.isMemory()) {
masm.loadFloat32(toAddress(to), ScratchFloat32Reg);
@ -270,6 +281,16 @@ MoveEmitterX86::completeCycle(const MoveOperand &to, MoveOp::Type type)
// This case handles (B -> A), which we reach last. We emit a move from the
// saved value of B, to A.
switch (type) {
case MoveOp::INT32X4:
JS_ASSERT(pushedAtCycle_ != -1);
JS_ASSERT(pushedAtCycle_ - pushedAtStart_ >= Simd128DataSize);
if (to.isMemory()) {
masm.loadAlignedInt32x4(cycleSlot(), ScratchSimdReg);
masm.storeAlignedInt32x4(ScratchSimdReg, toAddress(to));
} else {
masm.loadAlignedInt32x4(cycleSlot(), to.floatReg());
}
break;
case MoveOp::FLOAT32:
JS_ASSERT(pushedAtCycle_ != -1);
JS_ASSERT(pushedAtCycle_ - pushedAtStart_ >= sizeof(float));
@ -411,6 +432,24 @@ MoveEmitterX86::emitDoubleMove(const MoveOperand &from, const MoveOperand &to)
}
}
void
MoveEmitterX86::emitInt32X4Move(const MoveOperand &from, const MoveOperand &to)
{
if (from.isFloatReg()) {
if (to.isFloatReg())
masm.moveAlignedInt32x4(from.floatReg(), to.floatReg());
else
masm.storeAlignedInt32x4(from.floatReg(), toAddress(to));
} else if (to.isFloatReg()) {
masm.loadAlignedInt32x4(toAddress(from), to.floatReg());
} else {
// Memory to memory move.
JS_ASSERT(from.isMemory());
masm.loadAlignedInt32x4(toAddress(from), ScratchSimdReg);
masm.storeAlignedInt32x4(ScratchSimdReg, toAddress(to));
}
}
void
MoveEmitterX86::assertDone()
{

View File

@ -47,6 +47,7 @@ class MoveEmitterX86
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 emitInt32X4Move(const MoveOperand &from, const MoveOperand &to);
void breakCycle(const MoveOperand &to, MoveOp::Type type);
void completeCycle(const MoveOperand &to, MoveOp::Type type);