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:
Dan Gohman 2014-11-24 16:07:43 +01:00
parent 4b9965e1ed
commit 5cc08e7f89
3 changed files with 52 additions and 16 deletions

View File

@ -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) \

View File

@ -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;';

View File

@ -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");
}