mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 1019831: SIMD x86-x64: MoveResolver and MoveEmitter for Int32x4; r=sunfish
--HG-- extra : rebase_source : 2df9a4ee6021b51db7a8999e44fce39ba72f04e2
This commit is contained in:
parent
a462b19fa5
commit
827ec5eabb
@ -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");
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,8 @@ class MoveOp
|
||||
GENERAL,
|
||||
INT32,
|
||||
FLOAT32,
|
||||
DOUBLE
|
||||
DOUBLE,
|
||||
INT32X4
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user