Bug 1136226 - Remove SimdLane enumeration. r=sunfish

We're about to add 16-lane and 8-lane SIMD types to IonMonkey, so we don't want
an enum to identify lanes. Just use an unsigned instead.

Also note that SIMD.js no longer has the .x .y .z .w properties.

Change a few lane < 4 checks to use the number of lanes in the Simd type.
This commit is contained in:
Jakob Stoklund Olesen 2016-05-09 16:48:30 -07:00
parent 6d3b936823
commit 186e2e7b81
10 changed files with 59 additions and 90 deletions

View File

@ -488,9 +488,9 @@ class MOZ_STACK_CLASS ExprIter : private Policy
MOZ_MUST_USE bool readSimdShiftByScalar(ValType simdType, Value* lhs,
Value* rhs);
MOZ_MUST_USE bool readSimdBooleanReduction(ValType simdType, Value* input);
MOZ_MUST_USE bool readExtractLane(ValType simdType, jit::SimdLane* lane,
MOZ_MUST_USE bool readExtractLane(ValType simdType, uint8_t* lane,
Value* vector);
MOZ_MUST_USE bool readReplaceLane(ValType simdType, jit::SimdLane* lane,
MOZ_MUST_USE bool readReplaceLane(ValType simdType, uint8_t* lane,
Value* vector, Value* scalar);
MOZ_MUST_USE bool readSplat(ValType simdType, Value* scalar);
MOZ_MUST_USE bool readSwizzle(ValType simdType, uint8_t (* lanes)[4], Value* vector);
@ -1591,7 +1591,7 @@ ExprIter<Policy>::readSimdBooleanReduction(ValType simdType, Value* input)
template <typename Policy>
inline bool
ExprIter<Policy>::readExtractLane(ValType simdType, jit::SimdLane* lane, Value* vector)
ExprIter<Policy>::readExtractLane(ValType simdType, uint8_t* lane, Value* vector)
{
MOZ_ASSERT(Classify(expr_) == ExprKind::ExtractLane);
@ -1601,7 +1601,7 @@ ExprIter<Policy>::readExtractLane(ValType simdType, jit::SimdLane* lane, Value*
if (Validate && laneBits >= NumSimdElements(simdType))
return fail("simd lane out of bounds for simd type");
if (Output)
*lane = jit::SimdLane(laneBits);
*lane = uint8_t(laneBits);
if (!popWithType(ToExprType(simdType), vector))
return false;
@ -1613,8 +1613,7 @@ ExprIter<Policy>::readExtractLane(ValType simdType, jit::SimdLane* lane, Value*
template <typename Policy>
inline bool
ExprIter<Policy>::readReplaceLane(ValType simdType, jit::SimdLane* lane, Value* vector,
Value* scalar)
ExprIter<Policy>::readReplaceLane(ValType simdType, uint8_t* lane, Value* vector, Value* scalar)
{
MOZ_ASSERT(Classify(expr_) == ExprKind::ReplaceLane);
@ -1624,7 +1623,7 @@ ExprIter<Policy>::readReplaceLane(ValType simdType, jit::SimdLane* lane, Value*
if (Validate && laneBits >= NumSimdElements(simdType))
return fail("simd lane out of bounds for simd type");
if (Output)
*lane = jit::SimdLane(laneBits);
*lane = uint8_t(laneBits);
if (!popWithType(ToExprType(SimdElementType(simdType)), scalar))
return false;

View File

@ -364,7 +364,7 @@ class FunctionCompiler
return ins;
}
MDefinition* insertElementSimd(MDefinition* vec, MDefinition* val, SimdLane lane, MIRType type)
MDefinition* insertElementSimd(MDefinition* vec, MDefinition* val, unsigned lane, MIRType type)
{
if (inDeadCode())
return nullptr;
@ -699,7 +699,7 @@ class FunctionCompiler
curBlock_->add(MAsmJSInterruptCheck::New(alloc()));
}
MDefinition* extractSimdElement(SimdLane lane, MDefinition* base, MIRType type, SimdSign sign)
MDefinition* extractSimdElement(unsigned lane, MDefinition* base, MIRType type, SimdSign sign)
{
if (inDeadCode())
return nullptr;
@ -2373,7 +2373,7 @@ SimdToLaneType(ValType type)
static bool
EmitExtractLane(FunctionCompiler& f, ValType operandType, SimdSign sign)
{
jit::SimdLane lane;
uint8_t lane;
MDefinition* vector;
if (!f.iter().readExtractLane(operandType, &lane, &vector))
return false;
@ -2398,7 +2398,7 @@ EmitSimdReplaceLane(FunctionCompiler& f, ValType simdType)
if (IsSimdBoolType(simdType))
f.iter().setResult(EmitSimdBooleanLaneExpr(f, f.iter().getResult()));
jit::SimdLane lane;
uint8_t lane;
MDefinition* vector;
MDefinition* scalar;
if (!f.iter().readReplaceLane(simdType, &lane, &vector, &scalar))

View File

@ -706,15 +706,6 @@ SimdTypeToLaneArgumentType(MIRType type)
return laneType == MIRType::Boolean ? MIRType::Int32 : laneType;
}
// Indicates a lane in a SIMD register: X for the first lane, Y for the second,
// Z for the third (if any), W for the fourth (if any).
enum SimdLane {
LaneX = 0x0,
LaneY = 0x1,
LaneZ = 0x2,
LaneW = 0x3
};
#ifdef DEBUG
// Track the pipeline of opcodes which has produced a snapshot.

View File

@ -3626,8 +3626,8 @@ IonBuilder::inlineSimdExtractLane(CallInfo& callInfo, JSNative native, SimdType
MDefinition* arg = callInfo.getArg(1);
if (!arg->isConstant() || arg->type() != MIRType::Int32)
return InliningStatus_NotInlined;
int32_t lane = arg->toConstant()->toInt32();
if (lane < 0 || lane >= 4)
unsigned lane = arg->toConstant()->toInt32();
if (lane >= GetSimdLanes(type))
return InliningStatus_NotInlined;
// Original vector.
@ -3641,7 +3641,7 @@ IonBuilder::inlineSimdExtractLane(CallInfo& callInfo, JSNative native, SimdType
laneType = MIRType::Double;
MSimdExtractElement* ins =
MSimdExtractElement::New(alloc(), orig, laneType, SimdLane(lane), sign);
MSimdExtractElement::New(alloc(), orig, laneType, lane, sign);
current->add(ins);
current->push(ins);
callInfo.setImplicitlyUsedUnchecked();
@ -3660,8 +3660,8 @@ IonBuilder::inlineSimdReplaceLane(CallInfo& callInfo, JSNative native, SimdType
if (!arg->isConstant() || arg->type() != MIRType::Int32)
return InliningStatus_NotInlined;
int32_t lane = arg->toConstant()->toInt32();
if (lane < 0 || lane >= 4)
unsigned lane = arg->toConstant()->toInt32();
if (lane >= GetSimdLanes(type))
return InliningStatus_NotInlined;
// Original vector.
@ -3673,7 +3673,7 @@ IonBuilder::inlineSimdReplaceLane(CallInfo& callInfo, JSNative native, SimdType
if (SimdTypeToLaneType(vecType) == MIRType::Boolean)
value = convertToBooleanSimdLane(value);
MSimdInsertElement* ins = MSimdInsertElement::New(alloc(), orig, value, SimdLane(lane));
MSimdInsertElement* ins = MSimdInsertElement::New(alloc(), orig, value, lane);
return boxSimd(callInfo, ins, templateObj);
}

View File

@ -1388,7 +1388,7 @@ void
MSimdInsertElement::printOpcode(GenericPrinter& out) const
{
MDefinition::printOpcode(out);
out.printf(" (%s)", MSimdInsertElement::LaneName(lane()));
out.printf(" (lane %u)", lane());
}
void

View File

@ -1758,15 +1758,15 @@ class MSimdExtractElement
public SimdPolicy<0>::Data
{
protected:
SimdLane lane_;
unsigned lane_;
SimdSign sign_;
MSimdExtractElement(MDefinition* obj, MIRType laneType, SimdLane lane, SimdSign sign)
MSimdExtractElement(MDefinition* obj, MIRType laneType, unsigned lane, SimdSign sign)
: MUnaryInstruction(obj), lane_(lane), sign_(sign)
{
MIRType vecType = obj->type();
MOZ_ASSERT(IsSimdType(vecType));
MOZ_ASSERT(uint32_t(lane) < SimdTypeToLength(vecType));
MOZ_ASSERT(lane < SimdTypeToLength(vecType));
MOZ_ASSERT(!IsSimdType(laneType));
MOZ_ASSERT((sign != SimdSign::NotApplicable) == IsIntegerSimdType(vecType),
"Signedness must be specified for integer SIMD extractLanes");
@ -1792,12 +1792,12 @@ class MSimdExtractElement
INSTRUCTION_HEADER(SimdExtractElement)
static MSimdExtractElement* New(TempAllocator& alloc, MDefinition* obj, MIRType scalarType,
SimdLane lane, SimdSign sign)
unsigned lane, SimdSign sign)
{
return new(alloc) MSimdExtractElement(obj, scalarType, lane, sign);
}
SimdLane lane() const {
unsigned lane() const {
return lane_;
}
@ -1825,13 +1825,14 @@ class MSimdInsertElement
public MixPolicy< SimdSameAsReturnedTypePolicy<0>, SimdScalarPolicy<1> >::Data
{
private:
SimdLane lane_;
unsigned lane_;
MSimdInsertElement(MDefinition* vec, MDefinition* val, SimdLane lane)
MSimdInsertElement(MDefinition* vec, MDefinition* val, unsigned lane)
: MBinaryInstruction(vec, val), lane_(lane)
{
MIRType type = vec->type();
MOZ_ASSERT(IsSimdType(type));
MOZ_ASSERT(lane < SimdTypeToLength(type));
setMovable();
setResultType(type);
}
@ -1840,7 +1841,7 @@ class MSimdInsertElement
INSTRUCTION_HEADER(SimdInsertElement)
static MSimdInsertElement* New(TempAllocator& alloc, MDefinition* vec, MDefinition* val,
SimdLane lane)
unsigned lane)
{
return new(alloc) MSimdInsertElement(vec, val, lane);
}
@ -1851,20 +1852,10 @@ class MSimdInsertElement
MDefinition* value() {
return getOperand(1);
}
SimdLane lane() const {
unsigned lane() const {
return lane_;
}
static const char* LaneName(SimdLane lane) {
switch (lane) {
case LaneX: return "lane x";
case LaneY: return "lane y";
case LaneZ: return "lane z";
case LaneW: return "lane w";
}
MOZ_CRASH("unknown lane");
}
bool canConsumeFloat32(MUse* use) const override {
return use == getUseFor(1) && SimdTypeToLaneType(type()) == MIRType::Float32;
}

View File

@ -236,18 +236,9 @@ class LSimdExtractElementBase : public LInstructionHelper<1, 1, 0>
const LAllocation* getBase() {
return getOperand(0);
}
SimdLane lane() const {
unsigned lane() const {
return mir_->toSimdExtractElement()->lane();
}
const char* extraName() const {
switch (lane()) {
case LaneX: return "lane x";
case LaneY: return "lane y";
case LaneZ: return "lane z";
case LaneW: return "lane w";
}
return "unknown lane";
}
};
// Extracts an element from a given SIMD bool32x4 lane.
@ -289,7 +280,7 @@ class LSimdExtractElementU2D : public LInstructionHelper<1, 1, 1>
setOperand(0, base);
setTemp(0, temp);
}
SimdLane lane() const {
unsigned lane() const {
return mir_->toSimdExtractElement()->lane();
}
const LDefinition* temp() {
@ -314,12 +305,9 @@ class LSimdInsertElementBase : public LInstructionHelper<1, 2, 0>
const LAllocation* value() {
return getOperand(1);
}
SimdLane lane() const {
unsigned lane() const {
return mir_->toSimdInsertElement()->lane();
}
const char* extraName() const {
return MSimdInsertElement::LaneName(lane());
}
};
// Replace an element from a given SIMD integer or boolean lane with a given value.

View File

@ -3013,14 +3013,14 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_ASSERT(HasSSE41());
masm.vroundss_irr(mode, src1.encoding(), src0.encoding(), dest.encoding());
}
unsigned vinsertpsMask(SimdLane sourceLane, SimdLane destLane, unsigned zeroMask = 0)
unsigned vinsertpsMask(unsigned sourceLane, unsigned destLane, unsigned zeroMask = 0)
{
// Note that the sourceLane bits are ignored in the case of a source
// memory operand, and the source is the given 32-bits memory location.
MOZ_ASSERT(zeroMask < 16);
unsigned ret = zeroMask ;
ret |= unsigned(destLane) << 4;
ret |= unsigned(sourceLane) << 6;
ret |= destLane << 4;
ret |= sourceLane << 6;
MOZ_ASSERT(ret < 256);
return ret;
}

View File

@ -2679,7 +2679,7 @@ CodeGeneratorX86Shared::visitSimdReinterpretCast(LSimdReinterpretCast* ins)
void
CodeGeneratorX86Shared::emitSimdExtractLane(FloatRegister input, Register output, unsigned lane)
{
if (lane == LaneX) {
if (lane == 0) {
// The value we want to extract is in the low double-word
masm.moveLowInt32(input, output);
} else if (AssemblerX86Shared::HasSSE41()) {
@ -2729,12 +2729,12 @@ CodeGeneratorX86Shared::visitSimdExtractElementF(LSimdExtractElementF* ins)
FloatRegister input = ToFloatRegister(ins->input());
FloatRegister output = ToFloatRegister(ins->output());
SimdLane lane = ins->lane();
if (lane == LaneX) {
unsigned lane = ins->lane();
if (lane == 0) {
// The value we want to extract is in the low double-word
if (input != output)
masm.moveFloat32(input, output);
} else if (lane == LaneZ) {
} else if (lane == 2) {
masm.moveHighPairToLowPairFloat32(input, output);
} else {
uint32_t mask = MacroAssembler::ComputeShuffleMask(lane);
@ -2782,7 +2782,7 @@ CodeGeneratorX86Shared::visitSimdInsertElementF(LSimdInsertElementF* ins)
FloatRegister output = ToFloatRegister(ins->output());
MOZ_ASSERT(vector == output); // defineReuseInput(0)
if (ins->lane() == SimdLane::LaneX) {
if (ins->lane() == 0) {
// As both operands are registers, vmovss doesn't modify the upper bits
// of the destination operand.
if (value != output)
@ -2792,7 +2792,7 @@ CodeGeneratorX86Shared::visitSimdInsertElementF(LSimdInsertElementF* ins)
if (AssemblerX86Shared::HasSSE41()) {
// The input value is in the low float32 of the 'value' FloatRegister.
masm.vinsertps(masm.vinsertpsMask(SimdLane::LaneX, ins->lane()), value, output, output);
masm.vinsertps(masm.vinsertpsMask(0, ins->lane()), value, output, output);
return;
}
@ -3018,21 +3018,21 @@ CodeGeneratorX86Shared::visitSimdShuffle(LSimdShuffle* ins)
// SSE4.1 vinsertps can handle any single element.
unsigned numLanesUnchanged = (x == 0) + (y == 1) + (z == 2) + (w == 3);
if (AssemblerX86Shared::HasSSE41() && numLanesUnchanged == 3) {
SimdLane srcLane;
SimdLane dstLane;
unsigned srcLane;
unsigned dstLane;
if (x >= 4) {
srcLane = SimdLane(x - 4);
dstLane = LaneX;
srcLane = x - 4;
dstLane = 0;
} else if (y >= 4) {
srcLane = SimdLane(y - 4);
dstLane = LaneY;
srcLane = y - 4;
dstLane = 1;
} else if (z >= 4) {
srcLane = SimdLane(z - 4);
dstLane = LaneZ;
srcLane = z - 4;
dstLane = 2;
} else {
MOZ_ASSERT(w >= 4);
srcLane = SimdLane(w - 4);
dstLane = LaneW;
srcLane = w - 4;
dstLane = 3;
}
masm.vinsertps(masm.vinsertpsMask(srcLane, dstLane), rhs, lhs, out);
return;
@ -3046,14 +3046,14 @@ CodeGeneratorX86Shared::visitSimdShuffle(LSimdShuffle* ins)
// T = (Rw Rw Lz Lz) = vshufps(firstMask, lhs, rhs, rhsCopy)
firstMask = MacroAssembler::ComputeShuffleMask(w, w, z, z);
// (Lx Ly Lz Rw) = (Lx Ly Tz Tx) = vshufps(secondMask, T, lhs, out)
secondMask = MacroAssembler::ComputeShuffleMask(x, y, LaneZ, LaneX);
secondMask = MacroAssembler::ComputeShuffleMask(x, y, 2, 0);
} else {
MOZ_ASSERT(z >= 4);
z %= 4;
// T = (Rz Rz Lw Lw) = vshufps(firstMask, lhs, rhs, rhsCopy)
firstMask = MacroAssembler::ComputeShuffleMask(z, z, w, w);
// (Lx Ly Rz Lw) = (Lx Ly Tx Tz) = vshufps(secondMask, T, lhs, out)
secondMask = MacroAssembler::ComputeShuffleMask(x, y, LaneX, LaneZ);
secondMask = MacroAssembler::ComputeShuffleMask(x, y, 0, 2);
}
masm.vshufps(firstMask, lhs, rhsCopy, rhsCopy);
@ -3068,14 +3068,14 @@ CodeGeneratorX86Shared::visitSimdShuffle(LSimdShuffle* ins)
// T = (Ry Ry Lx Lx) = vshufps(firstMask, lhs, rhs, rhsCopy)
firstMask = MacroAssembler::ComputeShuffleMask(y, y, x, x);
// (Lx Ry Lz Lw) = (Tz Tx Lz Lw) = vshufps(secondMask, lhs, T, out)
secondMask = MacroAssembler::ComputeShuffleMask(LaneZ, LaneX, z, w);
secondMask = MacroAssembler::ComputeShuffleMask(2, 0, z, w);
} else {
MOZ_ASSERT(x >= 4);
x %= 4;
// T = (Rx Rx Ly Ly) = vshufps(firstMask, lhs, rhs, rhsCopy)
firstMask = MacroAssembler::ComputeShuffleMask(x, x, y, y);
// (Rx Ly Lz Lw) = (Tx Tz Lz Lw) = vshufps(secondMask, lhs, T, out)
secondMask = MacroAssembler::ComputeShuffleMask(LaneX, LaneZ, z, w);
secondMask = MacroAssembler::ComputeShuffleMask(0, 2, z, w);
}
masm.vshufps(firstMask, lhs, rhsCopy, rhsCopy);
@ -3316,14 +3316,14 @@ CodeGeneratorX86Shared::visitSimdBinaryArithIx4(LSimdBinaryArithIx4* ins)
// scratch contains (Rx, _, Rz, _) where R is the resulting vector.
FloatRegister temp = ToFloatRegister(ins->temp());
masm.vpshufd(MacroAssembler::ComputeShuffleMask(LaneY, LaneY, LaneW, LaneW), lhs, lhs);
masm.vpshufd(MacroAssembler::ComputeShuffleMask(LaneY, LaneY, LaneW, LaneW), rhs, temp);
masm.vpshufd(MacroAssembler::ComputeShuffleMask(1, 1, 3, 3), lhs, lhs);
masm.vpshufd(MacroAssembler::ComputeShuffleMask(1, 1, 3, 3), rhs, temp);
masm.vpmuludq(temp, lhs, lhs);
// lhs contains (Ry, _, Rw, _) where R is the resulting vector.
masm.vshufps(MacroAssembler::ComputeShuffleMask(LaneX, LaneZ, LaneX, LaneZ), scratch, lhs, lhs);
masm.vshufps(MacroAssembler::ComputeShuffleMask(0, 2, 0, 2), scratch, lhs, lhs);
// lhs contains (Ry, Rw, Rx, Rz)
masm.vshufps(MacroAssembler::ComputeShuffleMask(LaneZ, LaneX, LaneW, LaneY), lhs, lhs, lhs);
masm.vshufps(MacroAssembler::ComputeShuffleMask(2, 0, 3, 1), lhs, lhs, lhs);
return;
}
case MSimdBinaryArith::Op_div:

View File

@ -1085,8 +1085,8 @@ class MacroAssemblerX86Shared : public Assembler
vdivps(src, dest, dest);
}
static uint32_t ComputeShuffleMask(uint32_t x = LaneX, uint32_t y = LaneY,
uint32_t z = LaneZ, uint32_t w = LaneW)
static uint32_t ComputeShuffleMask(uint32_t x = 0, uint32_t y = 1,
uint32_t z = 2, uint32_t w = 3)
{
MOZ_ASSERT(x < 4 && y < 4 && z < 4 && w < 4);
uint32_t r = (w << 6) | (z << 4) | (y << 2) | (x << 0);