зеркало из 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
|
// Binary SIMD comparison operation between two SIMD operands
|
||||||
class LSimdBinaryComp: public LInstructionHelper<1, 2, 0>
|
class LSimdBinaryComp: public LInstructionHelper<1, 2, 0>
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
_(SimdInsertElementI) \
|
_(SimdInsertElementI) \
|
||||||
_(SimdInsertElementF) \
|
_(SimdInsertElementF) \
|
||||||
_(SimdSignMaskX4) \
|
_(SimdSignMaskX4) \
|
||||||
|
_(SimdSwizzleI) \
|
||||||
|
_(SimdSwizzleF) \
|
||||||
_(SimdUnaryArithIx4) \
|
_(SimdUnaryArithIx4) \
|
||||||
_(SimdUnaryArithFx4) \
|
_(SimdUnaryArithFx4) \
|
||||||
_(SimdBinaryCompIx4) \
|
_(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
|
bool
|
||||||
LIRGenerator::visitSimdUnaryArith(MSimdUnaryArith *ins)
|
LIRGenerator::visitSimdUnaryArith(MSimdUnaryArith *ins)
|
||||||
{
|
{
|
||||||
|
|
|
@ -272,6 +272,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||||
bool visitSimdExtractElement(MSimdExtractElement *ins);
|
bool visitSimdExtractElement(MSimdExtractElement *ins);
|
||||||
bool visitSimdInsertElement(MSimdInsertElement *ins);
|
bool visitSimdInsertElement(MSimdInsertElement *ins);
|
||||||
bool visitSimdSignMask(MSimdSignMask *ins);
|
bool visitSimdSignMask(MSimdSignMask *ins);
|
||||||
|
bool visitSimdSwizzle(MSimdSwizzle *ins);
|
||||||
bool visitSimdUnaryArith(MSimdUnaryArith *ins);
|
bool visitSimdUnaryArith(MSimdUnaryArith *ins);
|
||||||
bool visitSimdBinaryComp(MSimdBinaryComp *ins);
|
bool visitSimdBinaryComp(MSimdBinaryComp *ins);
|
||||||
bool visitSimdBinaryArith(MSimdBinaryArith *ins);
|
bool visitSimdBinaryArith(MSimdBinaryArith *ins);
|
||||||
|
|
|
@ -1575,6 +1575,72 @@ class MSimdSignMask : public MUnaryInstruction
|
||||||
ALLOW_CLONE(MSimdSignMask)
|
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
|
class MSimdUnaryArith : public MUnaryInstruction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace jit {
|
||||||
_(SimdExtractElement) \
|
_(SimdExtractElement) \
|
||||||
_(SimdInsertElement) \
|
_(SimdInsertElement) \
|
||||||
_(SimdSignMask) \
|
_(SimdSignMask) \
|
||||||
|
_(SimdSwizzle) \
|
||||||
_(SimdUnaryArith) \
|
_(SimdUnaryArith) \
|
||||||
_(SimdBinaryComp) \
|
_(SimdBinaryComp) \
|
||||||
_(SimdBinaryArith) \
|
_(SimdBinaryArith) \
|
||||||
|
|
|
@ -119,6 +119,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor
|
||||||
SAFE_OP(SimdExtractElement)
|
SAFE_OP(SimdExtractElement)
|
||||||
SAFE_OP(SimdInsertElement)
|
SAFE_OP(SimdInsertElement)
|
||||||
SAFE_OP(SimdSignMask)
|
SAFE_OP(SimdSignMask)
|
||||||
|
SAFE_OP(SimdSwizzle)
|
||||||
SAFE_OP(SimdUnaryArith)
|
SAFE_OP(SimdUnaryArith)
|
||||||
SAFE_OP(SimdBinaryComp)
|
SAFE_OP(SimdBinaryComp)
|
||||||
SAFE_OP(SimdBinaryArith)
|
SAFE_OP(SimdBinaryArith)
|
||||||
|
|
|
@ -222,6 +222,8 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
||||||
bool visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_CRASH("NYI"); }
|
bool visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_CRASH("NYI"); }
|
||||||
bool visitSimdExtractElementF(LSimdExtractElementF *ins) { MOZ_CRASH("NYI"); }
|
bool visitSimdExtractElementF(LSimdExtractElementF *ins) { MOZ_CRASH("NYI"); }
|
||||||
bool visitSimdSignMaskX4(LSimdSignMaskX4 *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 visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir) { MOZ_CRASH("NYI"); }
|
||||||
bool visitSimdBinaryCompFx4(LSimdBinaryCompFx4 *lir) { MOZ_CRASH("NYI"); }
|
bool visitSimdBinaryCompFx4(LSimdBinaryCompFx4 *lir) { MOZ_CRASH("NYI"); }
|
||||||
bool visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir) { MOZ_CRASH("NYI"); }
|
bool visitSimdBinaryArithIx4(LSimdBinaryArithIx4 *lir) { MOZ_CRASH("NYI"); }
|
||||||
|
|
|
@ -2388,6 +2388,30 @@ CodeGeneratorX86Shared::visitSimdSignMaskX4(LSimdSignMaskX4 *ins)
|
||||||
return true;
|
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
|
bool
|
||||||
CodeGeneratorX86Shared::visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *ins)
|
CodeGeneratorX86Shared::visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *ins)
|
||||||
{
|
{
|
||||||
|
|
|
@ -219,6 +219,8 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
||||||
bool visitSimdInsertElementI(LSimdInsertElementI *lir);
|
bool visitSimdInsertElementI(LSimdInsertElementI *lir);
|
||||||
bool visitSimdInsertElementF(LSimdInsertElementF *lir);
|
bool visitSimdInsertElementF(LSimdInsertElementF *lir);
|
||||||
bool visitSimdSignMaskX4(LSimdSignMaskX4 *ins);
|
bool visitSimdSignMaskX4(LSimdSignMaskX4 *ins);
|
||||||
|
bool visitSimdSwizzleI(LSimdSwizzleI *lir);
|
||||||
|
bool visitSimdSwizzleF(LSimdSwizzleF *lir);
|
||||||
bool visitSimdUnaryArithIx4(LSimdUnaryArithIx4 *lir);
|
bool visitSimdUnaryArithIx4(LSimdUnaryArithIx4 *lir);
|
||||||
bool visitSimdUnaryArithFx4(LSimdUnaryArithFx4 *lir);
|
bool visitSimdUnaryArithFx4(LSimdUnaryArithFx4 *lir);
|
||||||
bool visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir);
|
bool visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *lir);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче