mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1073064: SIMD: Add int32x4.shift{left,right,rightLogical} to asm.js; r=luke
This commit is contained in:
parent
99d2d28c3d
commit
1b86dbcbb4
@ -2453,13 +2453,13 @@ class FunctionCompiler
|
||||
return ins;
|
||||
}
|
||||
|
||||
MDefinition *binarySimd(MDefinition *lhs, MDefinition *rhs, MSimdBinaryComp::Operation op)
|
||||
template<class T>
|
||||
MDefinition *binarySimd(MDefinition *lhs, MDefinition *rhs, typename T::Operation op)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
|
||||
JS_ASSERT(IsSimdType(lhs->type()) && rhs->type() == lhs->type());
|
||||
MSimdBinaryComp *ins = MSimdBinaryComp::NewAsmJS(alloc(), lhs, rhs, op);
|
||||
T *ins = T::NewAsmJS(alloc(), lhs, rhs, op);
|
||||
curBlock_->add(ins);
|
||||
return ins;
|
||||
}
|
||||
@ -4875,7 +4875,20 @@ CheckSimdBinary<MSimdBinaryComp::Operation>(FunctionCompiler &f, ParseNode *call
|
||||
DefinitionVector argDefs;
|
||||
if (!CheckSimdCallArgs(f, call, 2, CheckArgIsSubtypeOf(retType), &argDefs))
|
||||
return false;
|
||||
*def = f.binarySimd(argDefs[0], argDefs[1], op);
|
||||
*def = f.binarySimd<MSimdBinaryComp>(argDefs[0], argDefs[1], op);
|
||||
*type = Type::Int32x4;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool
|
||||
CheckSimdBinary<MSimdShift::Operation>(FunctionCompiler &f, ParseNode *call, Type retType,
|
||||
MSimdShift::Operation op, MDefinition **def, Type *type)
|
||||
{
|
||||
DefinitionVector argDefs;
|
||||
if (!CheckSimdCallArgs(f, call, 2, CheckSimdVectorScalarArgs(retType), &argDefs))
|
||||
return false;
|
||||
*def = f.binarySimd<MSimdShift>(argDefs[0], argDefs[1], op);
|
||||
*type = Type::Int32x4;
|
||||
return true;
|
||||
}
|
||||
@ -4965,6 +4978,13 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
|
||||
case AsmJSSimdOperation_fromFloat32x4Bits:
|
||||
return CheckSimdCast<MSimdReinterpretCast>(f, call, Type::Float32x4, retType, def, type);
|
||||
|
||||
case AsmJSSimdOperation_shiftLeft:
|
||||
return CheckSimdBinary(f, call, Type::Int32x4, MSimdShift::lsh, def, type);
|
||||
case AsmJSSimdOperation_shiftRight:
|
||||
return CheckSimdBinary(f, call, Type::Int32x4, MSimdShift::rsh, def, type);
|
||||
case AsmJSSimdOperation_shiftRightLogical:
|
||||
return CheckSimdBinary(f, call, Type::Int32x4, MSimdShift::ursh, def, type);
|
||||
|
||||
case AsmJSSimdOperation_splat: {
|
||||
DefinitionVector defs;
|
||||
Type formalType = retType.simdToCoercedScalarType();
|
||||
|
@ -115,7 +115,10 @@
|
||||
|
||||
#define FOREACH_INT32X4_SIMD_OP(_) \
|
||||
_(fromFloat32x4) \
|
||||
_(fromFloat32x4Bits)
|
||||
_(fromFloat32x4Bits) \
|
||||
_(shiftLeft) \
|
||||
_(shiftRight) \
|
||||
_(shiftRightLogical)
|
||||
#define FOREACH_FLOAT32X4_SIMD_OP(_) \
|
||||
_(fromInt32x4) \
|
||||
_(fromInt32x4Bits) \
|
||||
|
@ -665,11 +665,45 @@ CheckF4(ANDF32, 'var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16
|
||||
CheckF4(ORF32, 'var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16.36); x=orr(x,y)', bitwise.or( [42, 13.37, -1.42, 23.10], [19.89, 2.4, 8.15, 16.36]));
|
||||
CheckF4(XORF32, 'var x=f4(42, 13.37,-1.42, 23.10); var y=f4(19.89, 2.4, 8.15, 16.36); x=xorr(x,y)', bitwise.xor([42, 13.37, -1.42, 23.10], [19.89, 2.4, 8.15, 16.36]));
|
||||
|
||||
// Logical ops
|
||||
const LSHI = 'var lsh=i4.shiftLeft;'
|
||||
const RSHI = 'var rsh=i4.shiftRight;'
|
||||
const URSHI = 'var ursh=i4.shiftRightLogical;'
|
||||
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return i4(lsh(x,f32(42)));} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + FROUND + LSHI + "function f() {var x=f4(1,2,3,4); return i4(lsh(x,42));} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + LSHI + "function f() {var x=i4(1,2,3,4); return i4(lsh(x,42.0));} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + FROUND + LSHI + "function f() {var x=i4(1,2,3,4); return i4(lsh(x,f32(42)));} return f");
|
||||
|
||||
var input = 'i4(0, 1, ' + INT32_MIN + ', ' + INT32_MAX + ')';
|
||||
var vinput = [0, 1, INT32_MIN, INT32_MAX];
|
||||
|
||||
// TODO: What to do for masks > 31? Should we keep only the five low bits of
|
||||
// the mask (JS) or not (x86)?
|
||||
// Behave as x86 for now, fix when more broadly specified. See also bug 1068028
|
||||
function Lsh(i) { if (i > 31) return () => 0; return function(x) { return (x << i) | 0 } }
|
||||
function Rsh(i) { if (i > 31) return (x) => (x<0)?-1:0; return function(x) { return (x >> i) | 0 } }
|
||||
function Ursh(i) { if (i > 31) return () => 0; return function(x) { return (x >>> i) | 0 } }
|
||||
|
||||
var asmLsh = asmLink(asmCompile('glob', USE_ASM + I32 + LSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return i4(lsh(v, x+y))} return f;'), this)
|
||||
var asmRsh = asmLink(asmCompile('glob', USE_ASM + I32 + RSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return i4(rsh(v, x+y))} return f;'), this)
|
||||
var asmUrsh = asmLink(asmCompile('glob', USE_ASM + I32 + URSHI + 'function f(x, y){x=x|0;y=y|0; var v=' + input + ';return i4(ursh(v, x+y))} return f;'), this)
|
||||
|
||||
for (var i = 1; i < 64; i++) {
|
||||
CheckI4(LSHI, 'var x=' + input + '; x=lsh(x, ' + i + ')', vinput.map(Lsh(i)));
|
||||
CheckI4(RSHI, 'var x=' + input + '; x=rsh(x, ' + i + ')', vinput.map(Rsh(i)));
|
||||
CheckI4(URSHI, 'var x=' + input + '; x=ursh(x, ' + i + ')', vinput.map(Ursh(i)));
|
||||
|
||||
assertEqX4(asmLsh(i, 3), vinput.map(Lsh(i + 3)));
|
||||
assertEqX4(asmRsh(i, 3), vinput.map(Rsh(i + 3)));
|
||||
assertEqX4(asmUrsh(i, 3), vinput.map(Ursh(i + 3)));
|
||||
}
|
||||
|
||||
// Select
|
||||
const I32SEL = 'var i4sel = i4.select;'
|
||||
const F32SEL = 'var f4sel = f4.select;'
|
||||
|
||||
assertAsmTypeFail('glob', USE_ASM + F32 + I32SEL + "function f() {var m=f4(1,2,3,4); return i4(i4sel(x,x,x));} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + F32 + I32SEL + "function f() {var x=f4(1,2,3,4); return i4(i4sel(x,x,x));} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=f4(1,2,3,4); var x=i4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=f4(1,2,3,4); var x=f4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
|
||||
|
Loading…
Reference in New Issue
Block a user