mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1072368 - Implement the remaining SIMD integer compares in the interpreter and asm.js; a=sunfish,bbouvier, r=sunfish
--HG-- extra : histedit_source : c9a772af119b0d8d01ba5ef01653bc3a356826dc
This commit is contained in:
parent
4b9965e1ed
commit
5cc08e7f89
@ -94,12 +94,15 @@
|
||||
V(and, (BinaryFunc<Int32x4, And, Int32x4>), 2, 0) \
|
||||
V(equal, (CompareFunc<Int32x4, Equal>), 2, 0) \
|
||||
V(greaterThan, (CompareFunc<Int32x4, GreaterThan>), 2, 0) \
|
||||
V(greaterThanOrEqual, (CompareFunc<Int32x4, GreaterThanOrEqual>), 2, 0) \
|
||||
V(lessThan, (CompareFunc<Int32x4, LessThan>), 2, 0) \
|
||||
V(lessThanOrEqual, (CompareFunc<Int32x4, LessThanOrEqual>), 2, 0) \
|
||||
V(load, (Load<Int32x4, 4>), 2, 0) \
|
||||
V(loadXYZ, (Load<Int32x4, 3>), 2, 0) \
|
||||
V(loadXY, (Load<Int32x4, 2>), 2, 0) \
|
||||
V(loadX, (Load<Int32x4, 1>), 2, 0) \
|
||||
V(mul, (BinaryFunc<Int32x4, Mul, Int32x4>), 2, 0) \
|
||||
V(notEqual, (CompareFunc<Int32x4, NotEqual>), 2, 0) \
|
||||
V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2, 0) \
|
||||
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2, 0) \
|
||||
V(shiftLeft, (Int32x4BinaryScalar<ShiftLeft>), 2, 0) \
|
||||
@ -155,16 +158,16 @@
|
||||
_(max) \
|
||||
_(min) \
|
||||
_(maxNum) \
|
||||
_(minNum) \
|
||||
_(lessThanOrEqual) \
|
||||
_(notEqual) \
|
||||
_(greaterThanOrEqual)
|
||||
_(minNum)
|
||||
#define FOREACH_COMMONX4_SIMD_OP(_) \
|
||||
_(add) \
|
||||
_(sub) \
|
||||
_(lessThan) \
|
||||
_(lessThanOrEqual) \
|
||||
_(equal) \
|
||||
_(notEqual) \
|
||||
_(greaterThan) \
|
||||
_(greaterThanOrEqual) \
|
||||
_(and) \
|
||||
_(or) \
|
||||
_(xor) \
|
||||
|
@ -590,26 +590,38 @@ CheckI4(WWI, 'var x = i4(1,2,3,4); x = w(x, 42);', [1, 2, 3, 42]);
|
||||
// yields all bits set to 0 (i.e 0).
|
||||
const T = -1;
|
||||
const F = 0;
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + "var lt=i4.lessThanOrEqual; function f() {} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + "var ge=i4.greaterThanOrEqual; function f() {} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + "var ne=i4.notEqual; function f() {} return f");
|
||||
|
||||
const EQI32 = 'var eq = i4.equal';
|
||||
const NEI32 = 'var ne = i4.notEqual';
|
||||
const LTI32 = 'var lt = i4.lessThan;';
|
||||
const LEI32 = 'var le = i4.lessThanOrEqual';
|
||||
const GTI32 = 'var gt = i4.greaterThan;';
|
||||
const EQI32 = 'var eq = i4.equal;';
|
||||
|
||||
CheckI4(LTI32, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=lt(x,y)', [F, F, F, F]);
|
||||
CheckI4(LTI32, 'var x=i4(-1,1,0,2); var y=i4(1,2,3,4); x=lt(x,y)', [T, T, T, T]);
|
||||
CheckI4(LTI32, 'var x=i4(1,0,3,4); var y=i4(1,1,7,0); x=lt(x,y)', [F, T, T, F]);
|
||||
const GEI32 = 'var ge = i4.greaterThanOrEqual';
|
||||
|
||||
CheckI4(EQI32, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=eq(x,y)', [F, F, F, F]);
|
||||
CheckI4(EQI32, 'var x=i4(-1,1,0,2); var y=i4(1,2,3,4); x=eq(x,y)', [F, F, F, F]);
|
||||
CheckI4(EQI32, 'var x=i4(1,0,3,4); var y=i4(1,1,7,0); x=eq(x,y)', [T, F, F, F]);
|
||||
|
||||
CheckI4(NEI32, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=ne(x,y)', [T, T, T, T]);
|
||||
CheckI4(NEI32, 'var x=i4(-1,1,0,2); var y=i4(1,2,3,4); x=ne(x,y)', [T, T, T, T]);
|
||||
CheckI4(NEI32, 'var x=i4(1,0,3,4); var y=i4(1,1,7,0); x=ne(x,y)', [F, T, T, T]);
|
||||
|
||||
CheckI4(LTI32, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=lt(x,y)', [F, F, F, F]);
|
||||
CheckI4(LTI32, 'var x=i4(-1,1,0,2); var y=i4(1,2,3,4); x=lt(x,y)', [T, T, T, T]);
|
||||
CheckI4(LTI32, 'var x=i4(1,0,3,4); var y=i4(1,1,7,0); x=lt(x,y)', [F, T, T, F]);
|
||||
|
||||
CheckI4(LEI32, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=le(x,y)', [F, F, F, F]);
|
||||
CheckI4(LEI32, 'var x=i4(-1,1,0,2); var y=i4(1,2,3,4); x=le(x,y)', [T, T, T, T]);
|
||||
CheckI4(LEI32, 'var x=i4(1,0,3,4); var y=i4(1,1,7,0); x=le(x,y)', [T, T, T, F]);
|
||||
|
||||
CheckI4(GTI32, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=gt(x,y)', [T, T, T, T]);
|
||||
CheckI4(GTI32, 'var x=i4(-1,1,0,2); var y=i4(1,2,3,4); x=gt(x,y)', [F, F, F, F]);
|
||||
CheckI4(GTI32, 'var x=i4(1,0,3,4); var y=i4(1,1,7,0); x=gt(x,y)', [F, F, F, T]);
|
||||
|
||||
CheckI4(GEI32, 'var x=i4(1,2,3,4); var y=i4(-1,1,0,2); x=ge(x,y)', [T, T, T, T]);
|
||||
CheckI4(GEI32, 'var x=i4(-1,1,0,2); var y=i4(1,2,3,4); x=ge(x,y)', [F, F, F, F]);
|
||||
CheckI4(GEI32, 'var x=i4(1,0,3,4); var y=i4(1,1,7,0); x=ge(x,y)', [T, F, F, T]);
|
||||
|
||||
const LTF32 = 'var lt=f4.lessThan;';
|
||||
const LEF32 = 'var le=f4.lessThanOrEqual;';
|
||||
const GTF32 = 'var gt=f4.greaterThan;';
|
||||
|
@ -2677,6 +2677,8 @@ CodeGeneratorX86Shared::visitSimdShuffle(LSimdShuffle *ins)
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *ins)
|
||||
{
|
||||
static const SimdConstant allOnes = SimdConstant::SplatX4(-1);
|
||||
|
||||
FloatRegister lhs = ToFloatRegister(ins->lhs());
|
||||
Operand rhs = ToOperand(ins->rhs());
|
||||
MOZ_ASSERT(ToFloatRegister(ins->output()) == lhs);
|
||||
@ -2690,22 +2692,41 @@ CodeGeneratorX86Shared::visitSimdBinaryCompIx4(LSimdBinaryCompIx4 *ins)
|
||||
masm.packedEqualInt32x4(rhs, lhs);
|
||||
return true;
|
||||
case MSimdBinaryComp::lessThan:
|
||||
// scr := rhs
|
||||
// src := rhs
|
||||
if (rhs.kind() == Operand::FPREG)
|
||||
masm.moveAlignedInt32x4(ToFloatRegister(ins->rhs()), ScratchSimdReg);
|
||||
else
|
||||
masm.loadAlignedInt32x4(rhs, ScratchSimdReg);
|
||||
|
||||
// scr := scr > lhs (i.e. lhs < rhs)
|
||||
// src := src > lhs (i.e. lhs < rhs)
|
||||
// Improve by doing custom lowering (rhs is tied to the output register)
|
||||
masm.packedGreaterThanInt32x4(ToOperand(ins->lhs()), ScratchSimdReg);
|
||||
masm.moveAlignedInt32x4(ScratchSimdReg, lhs);
|
||||
return true;
|
||||
case MSimdBinaryComp::notEqual:
|
||||
// Ideally for notEqual, greaterThanOrEqual, and lessThanOrEqual, we
|
||||
// should invert the comparison by, e.g. swapping the arms of a select
|
||||
// if that's what it's used in.
|
||||
masm.loadConstantInt32x4(allOnes, ScratchSimdReg);
|
||||
masm.packedEqualInt32x4(rhs, lhs);
|
||||
masm.bitwiseXorX4(Operand(ScratchSimdReg), lhs);
|
||||
return true;
|
||||
case MSimdBinaryComp::greaterThanOrEqual:
|
||||
// src := rhs
|
||||
if (rhs.kind() == Operand::FPREG)
|
||||
masm.moveAlignedInt32x4(ToFloatRegister(ins->rhs()), ScratchSimdReg);
|
||||
else
|
||||
masm.loadAlignedInt32x4(rhs, ScratchSimdReg);
|
||||
masm.packedGreaterThanInt32x4(ToOperand(ins->lhs()), ScratchSimdReg);
|
||||
masm.loadConstantInt32x4(allOnes, lhs);
|
||||
masm.bitwiseXorX4(Operand(ScratchSimdReg), lhs);
|
||||
return true;
|
||||
case MSimdBinaryComp::lessThanOrEqual:
|
||||
// These operations are not part of the spec. so are not implemented.
|
||||
break;
|
||||
// lhs <= rhs is equivalent to !(rhs < lhs), which we compute here.
|
||||
masm.loadConstantInt32x4(allOnes, ScratchSimdReg);
|
||||
masm.packedGreaterThanInt32x4(rhs, lhs);
|
||||
masm.bitwiseXorX4(Operand(ScratchSimdReg), lhs);
|
||||
return true;
|
||||
}
|
||||
MOZ_CRASH("unexpected SIMD op");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user