зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1021716: SIMD x86x-64: Implement MSimdSwizzle; r=sunfish
This commit is contained in:
Родитель
5e55d9abaa
Коммит
39ac3875bc
|
@ -229,6 +229,42 @@ class LSimdSignMaskX4 : public LInstructionHelper<1, 1, 0>
|
|||
}
|
||||
};
|
||||
|
||||
// Base class for both int32x4 and float32x4 shuffle instructions.
|
||||
class LSimdSwizzleBase : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LSimdSwizzleBase(const LAllocation &base)
|
||||
{
|
||||
setOperand(0, base);
|
||||
}
|
||||
|
||||
const LAllocation *getBase() {
|
||||
return getOperand(0);
|
||||
}
|
||||
|
||||
SimdLane laneX() const { return mir_->toSimdSwizzle()->laneX(); }
|
||||
SimdLane laneY() const { return mir_->toSimdSwizzle()->laneY(); }
|
||||
SimdLane laneZ() const { return mir_->toSimdSwizzle()->laneZ(); }
|
||||
SimdLane laneW() const { return mir_->toSimdSwizzle()->laneW(); }
|
||||
};
|
||||
|
||||
// Shuffles a int32x4 into another int32x4 vector.
|
||||
class LSimdSwizzleI : public LSimdSwizzleBase
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SimdSwizzleI);
|
||||
LSimdSwizzleI(const LAllocation &base) : LSimdSwizzleBase(base)
|
||||
{}
|
||||
};
|
||||
// Shuffles a float32x4 into another float32x4 vector.
|
||||
class LSimdSwizzleF : public LSimdSwizzleBase
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(SimdSwizzleF);
|
||||
LSimdSwizzleF(const LAllocation &base) : LSimdSwizzleBase(base)
|
||||
{}
|
||||
};
|
||||
|
||||
// Binary SIMD comparison operation between two SIMD operands
|
||||
class LSimdBinaryComp: public LInstructionHelper<1, 2, 0>
|
||||
{
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
_(SimdInsertElementI) \
|
||||
_(SimdInsertElementF) \
|
||||
_(SimdSignMaskX4) \
|
||||
_(SimdSwizzleI) \
|
||||
_(SimdSwizzleF) \
|
||||
_(SimdUnaryArithIx4) \
|
||||
_(SimdUnaryArithFx4) \
|
||||
_(SimdBinaryCompIx4) \
|
||||
|
|
|
@ -3808,6 +3808,28 @@ LIRGenerator::visitSimdSignMask(MSimdSignMask *ins)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitSimdSwizzle(MSimdSwizzle *ins)
|
||||
{
|
||||
MOZ_ASSERT(IsSimdType(ins->input()->type()));
|
||||
MOZ_ASSERT(IsSimdType(ins->type()));
|
||||
|
||||
if (ins->input()->type() == MIRType_Int32x4) {
|
||||
LUse use = useRegisterAtStart(ins->input());
|
||||
LSimdSwizzleI *lir = new (alloc()) LSimdSwizzleI(use);
|
||||
return define(lir, ins);
|
||||
}
|
||||
|
||||
if (ins->input()->type() == MIRType_Float32x4) {
|
||||
LUse use = useRegisterAtStart(ins->input());
|
||||
LSimdSwizzleF *lir = new (alloc()) LSimdSwizzleF(use);
|
||||
return define(lir, ins);
|
||||
}
|
||||
|
||||
MOZ_CRASH("Unknown SIMD kind when getting lane");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitSimdUnaryArith(MSimdUnaryArith *ins)
|
||||
{
|
||||
|
|
|
@ -272,6 +272,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||
bool visitSimdExtractElement(MSimdExtractElement *ins);
|
||||
bool visitSimdInsertElement(MSimdInsertElement *ins);
|
||||
bool visitSimdSignMask(MSimdSignMask *ins);
|
||||
bool visitSimdSwizzle(MSimdSwizzle *ins);
|
||||
bool visitSimdUnaryArith(MSimdUnaryArith *ins);
|
||||
bool visitSimdBinaryComp(MSimdBinaryComp *ins);
|
||||
bool visitSimdBinaryArith(MSimdBinaryArith *ins);
|
||||
|
|
|
@ -1575,6 +1575,72 @@ class MSimdSignMask : public MUnaryInstruction
|
|||
ALLOW_CLONE(MSimdSignMask)
|
||||
};
|
||||
|
||||
// Applies a shuffle operation to the input, putting the input lanes as
|
||||
// indicated in the output register's lanes. This implements the SIMD.js
|
||||
// "shuffle" function, that takes one vector and one mask.
|
||||
class MSimdSwizzle : public MUnaryInstruction
|
||||
{
|
||||
protected:
|
||||
// As of now, there are at most 4 lanes.
|
||||
SimdLane laneX_;
|
||||
SimdLane laneY_;
|
||||
SimdLane laneZ_;
|
||||
SimdLane laneW_;
|
||||
|
||||
MSimdSwizzle(MDefinition *obj, MIRType type,
|
||||
SimdLane laneX, SimdLane laneY, SimdLane laneZ, SimdLane laneW)
|
||||
: MUnaryInstruction(obj),
|
||||
laneX_(laneX), laneY_(laneY), laneZ_(laneZ), laneW_(laneW)
|
||||
{
|
||||
MOZ_ASSERT(IsSimdType(obj->type()));
|
||||
// Returned value needs to be in a vector too
|
||||
MOZ_ASSERT(IsSimdType(type));
|
||||
MOZ_ASSERT(SimdTypeToScalarType(obj->type()) == type);
|
||||
|
||||
mozilla::DebugOnly<uint32_t> expectedLength = SimdTypeToLength(obj->type());
|
||||
MOZ_ASSERT(uint32_t(laneX_) < expectedLength);
|
||||
MOZ_ASSERT(uint32_t(laneY_) < expectedLength);
|
||||
MOZ_ASSERT(uint32_t(laneZ_) < expectedLength);
|
||||
MOZ_ASSERT(uint32_t(laneW_) < expectedLength);
|
||||
|
||||
setResultType(type);
|
||||
setMovable();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(SimdSwizzle);
|
||||
|
||||
static MSimdSwizzle *NewAsmJS(TempAllocator &alloc, MDefinition *obj, MIRType type,
|
||||
SimdLane laneX, SimdLane laneY, SimdLane laneZ, SimdLane laneW)
|
||||
{
|
||||
return new(alloc) MSimdSwizzle(obj, type, laneX, laneY, laneZ, laneW);
|
||||
}
|
||||
|
||||
SimdLane laneX() const { return laneX_; }
|
||||
SimdLane laneY() const { return laneY_; }
|
||||
SimdLane laneZ() const { return laneZ_; }
|
||||
SimdLane laneW() const { return laneW_; }
|
||||
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::None();
|
||||
}
|
||||
bool congruentTo(const MDefinition *ins) const {
|
||||
if (!ins->isSimdSwizzle())
|
||||
return false;
|
||||
const MSimdSwizzle *other = ins->toSimdSwizzle();
|
||||
if (other->laneX_ != laneX_ ||
|
||||
other->laneY_ != laneY_ ||
|
||||
other->laneZ_ != laneZ_ ||
|
||||
other->laneW_ != laneW_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return congruentIfOperandsEqual(other);
|
||||
}
|
||||
|
||||
ALLOW_CLONE(MSimdSwizzle)
|
||||
};
|
||||
|
||||
class MSimdUnaryArith : public MUnaryInstruction
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace jit {
|
|||
_(SimdExtractElement) \
|
||||
_(SimdInsertElement) \
|
||||
_(SimdSignMask) \
|
||||
_(SimdSwizzle) \
|
||||
_(SimdUnaryArith) \
|
||||
_(SimdBinaryComp) \
|
||||
_(SimdBinaryArith) \
|
||||
|
|
|
@ -119,6 +119,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor
|
|||
SAFE_OP(SimdExtractElement)
|
||||
SAFE_OP(SimdInsertElement)
|
||||
SAFE_OP(SimdSignMask)
|
||||
SAFE_OP(SimdSwizzle)
|
||||
SAFE_OP(SimdUnaryArith)
|
||||
SAFE_OP(SimdBinaryComp)
|
||||
SAFE_OP(SimdBinaryArith)
|
||||
|
|
|
@ -222,6 +222,8 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
|||
bool visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdExtractElementF(LSimdExtractElementF *ins) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdSignMaskX4(LSimdSignMaskX4 *ins) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdSwizzleI(LSimdSwizzleI *lir) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdSwizzleF(LSimdSwizzleF *lir) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdBinaryCompFx4(LSimdBinaryCompFx4 *lir) { MOZ_CRASH("NYI"); }
|
||||
bool visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir) { MOZ_CRASH("NYI"); }
|
||||
|
|
|
@ -2388,6 +2388,30 @@ CodeGeneratorX86Shared::visitSimdSignMaskX4(LSimdSignMaskX4 *ins)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitSimdSwizzleI(LSimdSwizzleI *ins)
|
||||
{
|
||||
FloatRegister input = ToFloatRegister(ins->input());
|
||||
FloatRegister output = ToFloatRegister(ins->output());
|
||||
|
||||
uint32_t mask = MacroAssembler::ComputeShuffleMask(ins->laneX(), ins->laneY(), ins->laneZ(),
|
||||
ins->laneW());
|
||||
masm.shuffleInt32(mask, input, output);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitSimdSwizzleF(LSimdSwizzleF *ins)
|
||||
{
|
||||
FloatRegister input = ToFloatRegister(ins->input());
|
||||
FloatRegister output = ToFloatRegister(ins->output());
|
||||
|
||||
uint32_t mask = MacroAssembler::ComputeShuffleMask(ins->laneX(), ins->laneY(), ins->laneZ(),
|
||||
ins->laneW());
|
||||
masm.shuffleFloat32(mask, input, output);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *ins)
|
||||
{
|
||||
|
|
|
@ -219,6 +219,8 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
|||
bool visitSimdInsertElementI(LSimdInsertElementI *lir);
|
||||
bool visitSimdInsertElementF(LSimdInsertElementF *lir);
|
||||
bool visitSimdSignMaskX4(LSimdSignMaskX4 *ins);
|
||||
bool visitSimdSwizzleI(LSimdSwizzleI *lir);
|
||||
bool visitSimdSwizzleF(LSimdSwizzleF *lir);
|
||||
bool visitSimdUnaryArithIx4(LSimdUnaryArithIx4 *lir);
|
||||
bool visitSimdUnaryArithFx4(LSimdUnaryArithFx4 *lir);
|
||||
bool visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir);
|
||||
|
|
Загрузка…
Ссылка в новой задаче