mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1060789: OdinMonkey SIMD: Add support for splat; r=luke
This commit is contained in:
parent
c4f557a7b3
commit
e177470d58
@ -352,6 +352,7 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
|
||||
case AsmJSSimdOperation_or: native = simd_int32x4_or; break;
|
||||
case AsmJSSimdOperation_xor: native = simd_int32x4_xor; break;
|
||||
case AsmJSSimdOperation_select: native = simd_int32x4_select; break;
|
||||
case AsmJSSimdOperation_splat: native = simd_int32x4_splat; break;
|
||||
case AsmJSSimdOperation_lessThanOrEqual:
|
||||
case AsmJSSimdOperation_greaterThanOrEqual:
|
||||
case AsmJSSimdOperation_notEqual:
|
||||
@ -377,6 +378,7 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
|
||||
case AsmJSSimdOperation_or: native = simd_float32x4_or; break;
|
||||
case AsmJSSimdOperation_xor: native = simd_float32x4_xor; break;
|
||||
case AsmJSSimdOperation_select: native = simd_float32x4_select; break;
|
||||
case AsmJSSimdOperation_splat: native = simd_float32x4_splat; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ enum AsmJSSimdOperation
|
||||
AsmJSSimdOperation_or,
|
||||
AsmJSSimdOperation_xor,
|
||||
AsmJSSimdOperation_select,
|
||||
AsmJSSimdOperation_splat
|
||||
};
|
||||
|
||||
// These labels describe positions in the prologue/epilogue of functions while
|
||||
|
@ -1378,7 +1378,8 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
!addStandardLibrarySimdOpName("and", AsmJSSimdOperation_and) ||
|
||||
!addStandardLibrarySimdOpName("or", AsmJSSimdOperation_or) ||
|
||||
!addStandardLibrarySimdOpName("xor", AsmJSSimdOperation_xor) ||
|
||||
!addStandardLibrarySimdOpName("select", AsmJSSimdOperation_select))
|
||||
!addStandardLibrarySimdOpName("select", AsmJSSimdOperation_select) ||
|
||||
!addStandardLibrarySimdOpName("splat", AsmJSSimdOperation_splat))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -3524,6 +3525,7 @@ IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
|
||||
case AsmJSSimdOperation_or:
|
||||
case AsmJSSimdOperation_xor:
|
||||
case AsmJSSimdOperation_select:
|
||||
case AsmJSSimdOperation_splat:
|
||||
return true;
|
||||
case AsmJSSimdOperation_mul:
|
||||
case AsmJSSimdOperation_div:
|
||||
@ -4692,6 +4694,38 @@ CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltinF
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckUnarySimd(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
|
||||
MDefinition **def, Type *type)
|
||||
{
|
||||
unsigned numArgs = CallArgListLength(call);
|
||||
if (numArgs != 1)
|
||||
return f.failf(call, "expected 1 argument to unary arithmetic SIMD operation, got %u", numArgs);
|
||||
|
||||
ParseNode *arg = CallArgList(call);
|
||||
MDefinition *argDef;
|
||||
Type argType;
|
||||
if (!CheckExpr(f, arg, &argDef, &argType))
|
||||
return false;
|
||||
|
||||
// For now, the only unary SIMD operation is splat(scalar).
|
||||
MOZ_ASSERT(global->simdOperation() == AsmJSSimdOperation_splat);
|
||||
switch (global->simdOperationType()) {
|
||||
case AsmJSSimdType_int32x4:
|
||||
if (!argType.isIntish())
|
||||
return f.failf(arg, "%s is not a subtype of intish", argType.toChars());
|
||||
break;
|
||||
case AsmJSSimdType_float32x4:
|
||||
if (!CheckFloatCoercionArg(f, arg, argType, argDef, &argDef))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
*type = global->simdOperationType();
|
||||
*def = f.simdSplat<MSimdSplatX4>(argDef, type->toMIRType());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckBinarySimd(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
|
||||
MDefinition **def, Type *type)
|
||||
@ -4714,7 +4748,6 @@ CheckBinarySimd(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Glob
|
||||
if (lhsType != retType || rhsType != retType)
|
||||
return f.failf(lhs, "arguments to SIMD binary op should both be %s", retType.toChars());
|
||||
|
||||
|
||||
MIRType opType = retType.toMIRType();
|
||||
switch (global->simdOperation()) {
|
||||
case AsmJSSimdOperation_add:
|
||||
@ -4774,6 +4807,7 @@ CheckBinarySimd(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Glob
|
||||
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryBitwise::xor_, opType);
|
||||
*type = retType;
|
||||
break;
|
||||
case AsmJSSimdOperation_splat:
|
||||
case AsmJSSimdOperation_select:
|
||||
MOZ_CRASH("unexpected SIMD binary operation");
|
||||
}
|
||||
@ -4824,6 +4858,8 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
|
||||
{
|
||||
JS_ASSERT(global->isSimdOperation());
|
||||
switch (global->simdOperation()) {
|
||||
case AsmJSSimdOperation_splat:
|
||||
return CheckUnarySimd(f, call, global, def, type);
|
||||
case AsmJSSimdOperation_add:
|
||||
case AsmJSSimdOperation_sub:
|
||||
case AsmJSSimdOperation_mul:
|
||||
|
@ -1,5 +1,5 @@
|
||||
load(libdir + "asm.js");
|
||||
var heap = new ArrayBuffer(4096);
|
||||
var heap = new ArrayBuffer(0x10000);
|
||||
|
||||
// Set to true to see more JS debugging spew
|
||||
const DEBUG = false;
|
||||
@ -553,6 +553,34 @@ assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
|
||||
|
||||
// Splat
|
||||
const I32SPLAT = 'var splat=i4.splat;'
|
||||
const F32SPLAT = 'var splat=f4.splat;'
|
||||
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SPLAT + "function f() {var m=i4(1,2,3,4); var p=f4(1.,2.,3.,4.); p=splat(1);} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + "function f() {var m=i4(1,2,3,4); m=splat(1, 2)} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + "function f() {var m=i4(1,2,3,4); m=splat()} return f");
|
||||
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + "function f() {var m=i4(1,2,3,4); m=splat(m);} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + "function f() {var m=i4(1,2,3,4); m=splat(1.0);} return f");
|
||||
assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + FROUND + "function f() {var m=i4(1,2,3,4); m=splat(f32(1.0));} return f");
|
||||
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SPLAT + 'function f(){return i4(splat(42));} return f'), this)(), [42, 42, 42, 42]);
|
||||
|
||||
const l33t = Math.fround(13.37);
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + F32SPLAT + FROUND + 'function f(){return f4(splat(1));} return f'), this)(), [1, 1, 1, 1]);
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + F32SPLAT + FROUND + 'function f(){return f4(splat(1 >>> 0));} return f'), this)(), [1, 1, 1, 1]);
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + F32SPLAT + FROUND + 'function f(){return f4(splat(13.37));} return f'), this)(), [l33t, l33t, l33t, l33t]);
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + F32 + F32SPLAT + FROUND + 'function f(){return f4(splat(f32(13.37)));} return f'), this)(), [l33t, l33t, l33t, l33t]);
|
||||
|
||||
var i32view = new Int32Array(heap);
|
||||
var f32view = new Float32Array(heap);
|
||||
i32view[0] = 42;
|
||||
assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + I32 + I32SPLAT + 'var i32=new glob.Int32Array(heap); function f(){return i4(splat(i32[0]));} return f'), this, {}, heap)(), [42, 42, 42, 42]);
|
||||
f32view[0] = 42;
|
||||
assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + F32 + F32SPLAT + 'var f32=new glob.Float32Array(heap); function f(){return f4(splat(f32[0]));} return f'), this, {}, heap)(), [42, 42, 42, 42]);
|
||||
assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + F32 + F32SPLAT + FROUND + 'function f(){return f4(splat(f32(1) + f32(2)));} return f'), this, {}, heap)(), [3, 3, 3, 3]);
|
||||
|
||||
// Dead code
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + 'function f(){var x=i4(1,2,3,4); return i4(x); x=i4(5,6,7,8); return i4(x);} return f'), this)(), [1, 2, 3, 4]);
|
||||
assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + 'function f(){var x=i4(1,2,3,4); var c=0; return i4(x); c=x.x|0; return i4(x);} return f'), this)(), [1, 2, 3, 4]);
|
||||
|
Loading…
Reference in New Issue
Block a user