зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1069956: SIMD: Add support for int32x4.fromFloat32x4 and float32x4.fromInt32x4 in Odin; r=luke
This commit is contained in:
Родитель
900c9c8c75
Коммит
50c6f26e9d
|
@ -364,6 +364,7 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
|
||||||
case AsmJSSimdOperation_withY: native = simd_int32x4_withY; break;
|
case AsmJSSimdOperation_withY: native = simd_int32x4_withY; break;
|
||||||
case AsmJSSimdOperation_withZ: native = simd_int32x4_withZ; break;
|
case AsmJSSimdOperation_withZ: native = simd_int32x4_withZ; break;
|
||||||
case AsmJSSimdOperation_withW: native = simd_int32x4_withW; break;
|
case AsmJSSimdOperation_withW: native = simd_int32x4_withW; break;
|
||||||
|
case AsmJSSimdOperation_fromFloat32x4: native = simd_int32x4_fromFloat32x4; break;
|
||||||
case AsmJSSimdOperation_lessThanOrEqual:
|
case AsmJSSimdOperation_lessThanOrEqual:
|
||||||
case AsmJSSimdOperation_greaterThanOrEqual:
|
case AsmJSSimdOperation_greaterThanOrEqual:
|
||||||
case AsmJSSimdOperation_notEqual:
|
case AsmJSSimdOperation_notEqual:
|
||||||
|
@ -371,6 +372,7 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
|
||||||
case AsmJSSimdOperation_div:
|
case AsmJSSimdOperation_div:
|
||||||
case AsmJSSimdOperation_max:
|
case AsmJSSimdOperation_max:
|
||||||
case AsmJSSimdOperation_min:
|
case AsmJSSimdOperation_min:
|
||||||
|
case AsmJSSimdOperation_fromInt32x4:
|
||||||
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
|
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
|
||||||
"place");
|
"place");
|
||||||
}
|
}
|
||||||
|
@ -398,6 +400,10 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
|
||||||
case AsmJSSimdOperation_withY: native = simd_float32x4_withY; break;
|
case AsmJSSimdOperation_withY: native = simd_float32x4_withY; break;
|
||||||
case AsmJSSimdOperation_withZ: native = simd_float32x4_withZ; break;
|
case AsmJSSimdOperation_withZ: native = simd_float32x4_withZ; break;
|
||||||
case AsmJSSimdOperation_withW: native = simd_float32x4_withW; break;
|
case AsmJSSimdOperation_withW: native = simd_float32x4_withW; break;
|
||||||
|
case AsmJSSimdOperation_fromInt32x4: native = simd_float32x4_fromInt32x4; break;
|
||||||
|
case AsmJSSimdOperation_fromFloat32x4:
|
||||||
|
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
|
||||||
|
"place");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,9 @@ enum AsmJSSimdOperation
|
||||||
AsmJSSimdOperation_withX,
|
AsmJSSimdOperation_withX,
|
||||||
AsmJSSimdOperation_withY,
|
AsmJSSimdOperation_withY,
|
||||||
AsmJSSimdOperation_withZ,
|
AsmJSSimdOperation_withZ,
|
||||||
AsmJSSimdOperation_withW
|
AsmJSSimdOperation_withW,
|
||||||
|
AsmJSSimdOperation_fromInt32x4,
|
||||||
|
AsmJSSimdOperation_fromFloat32x4
|
||||||
};
|
};
|
||||||
|
|
||||||
// These labels describe positions in the prologue/epilogue of functions while
|
// These labels describe positions in the prologue/epilogue of functions while
|
||||||
|
|
|
@ -1427,7 +1427,9 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||||
!addStandardLibrarySimdOpName("withX", AsmJSSimdOperation_withX) ||
|
!addStandardLibrarySimdOpName("withX", AsmJSSimdOperation_withX) ||
|
||||||
!addStandardLibrarySimdOpName("withY", AsmJSSimdOperation_withY) ||
|
!addStandardLibrarySimdOpName("withY", AsmJSSimdOperation_withY) ||
|
||||||
!addStandardLibrarySimdOpName("withZ", AsmJSSimdOperation_withZ) ||
|
!addStandardLibrarySimdOpName("withZ", AsmJSSimdOperation_withZ) ||
|
||||||
!addStandardLibrarySimdOpName("withW", AsmJSSimdOperation_withW))
|
!addStandardLibrarySimdOpName("withW", AsmJSSimdOperation_withW) ||
|
||||||
|
!addStandardLibrarySimdOpName("fromFloat32x4", AsmJSSimdOperation_fromFloat32x4) ||
|
||||||
|
!addStandardLibrarySimdOpName("fromInt32x4", AsmJSSimdOperation_fromInt32x4))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2509,6 +2511,17 @@ class FunctionCompiler
|
||||||
return ins;
|
return ins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MDefinition *convertSimd(MDefinition *vec, MIRType from, MIRType to)
|
||||||
|
{
|
||||||
|
if (inDeadCode())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
MOZ_ASSERT(IsSimdType(from) && IsSimdType(to) && from != to);
|
||||||
|
MSimdConvert *ins = MSimdConvert::NewAsmJS(alloc(), vec, from, to);
|
||||||
|
curBlock_->add(ins);
|
||||||
|
return ins;
|
||||||
|
}
|
||||||
|
|
||||||
MDefinition *splatSimd(MDefinition *v, MIRType type)
|
MDefinition *splatSimd(MDefinition *v, MIRType type)
|
||||||
{
|
{
|
||||||
if (inDeadCode())
|
if (inDeadCode())
|
||||||
|
@ -3588,6 +3601,8 @@ IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
|
||||||
case AsmJSSimdOperation_withZ:
|
case AsmJSSimdOperation_withZ:
|
||||||
case AsmJSSimdOperation_withW:
|
case AsmJSSimdOperation_withW:
|
||||||
return true;
|
return true;
|
||||||
|
case AsmJSSimdOperation_fromFloat32x4:
|
||||||
|
return type == AsmJSSimdType_int32x4;
|
||||||
case AsmJSSimdOperation_mul:
|
case AsmJSSimdOperation_mul:
|
||||||
case AsmJSSimdOperation_div:
|
case AsmJSSimdOperation_div:
|
||||||
case AsmJSSimdOperation_max:
|
case AsmJSSimdOperation_max:
|
||||||
|
@ -3595,6 +3610,7 @@ IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
|
||||||
case AsmJSSimdOperation_lessThanOrEqual:
|
case AsmJSSimdOperation_lessThanOrEqual:
|
||||||
case AsmJSSimdOperation_notEqual:
|
case AsmJSSimdOperation_notEqual:
|
||||||
case AsmJSSimdOperation_greaterThanOrEqual:
|
case AsmJSSimdOperation_greaterThanOrEqual:
|
||||||
|
case AsmJSSimdOperation_fromInt32x4:
|
||||||
return type == AsmJSSimdType_float32x4;
|
return type == AsmJSSimdType_float32x4;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -4964,6 +4980,23 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
|
||||||
case AsmJSSimdOperation_withW:
|
case AsmJSSimdOperation_withW:
|
||||||
return CheckSimdWith(f, call, retType, SimdLane::LaneW, def, type);
|
return CheckSimdWith(f, call, retType, SimdLane::LaneW, def, type);
|
||||||
|
|
||||||
|
case AsmJSSimdOperation_fromInt32x4: {
|
||||||
|
DefinitionVector defs;
|
||||||
|
if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(Type::Int32x4), &defs))
|
||||||
|
return false;
|
||||||
|
*def = f.convertSimd(defs[0], MIRType_Int32x4, retType.toMIRType());
|
||||||
|
*type = retType;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case AsmJSSimdOperation_fromFloat32x4: {
|
||||||
|
DefinitionVector defs;
|
||||||
|
if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(Type::Float32x4), &defs))
|
||||||
|
return false;
|
||||||
|
*def = f.convertSimd(defs[0], MIRType_Float32x4, retType.toMIRType());
|
||||||
|
*type = retType;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
case AsmJSSimdOperation_splat: {
|
case AsmJSSimdOperation_splat: {
|
||||||
DefinitionVector defs;
|
DefinitionVector defs;
|
||||||
Type formalType = retType.simdToCoercedScalarType();
|
Type formalType = retType.simdToCoercedScalarType();
|
||||||
|
|
|
@ -564,6 +564,28 @@ CheckF4Comp(GEF32, 'var y=f4(1,2,3,4); var z=f4(-1,1,0,2); var x=i4(0,0,0,0); x
|
||||||
CheckF4Comp(GEF32, 'var y=f4(-1,1,0,2); var z=f4(1,2,3,4); var x=i4(0,0,0,0); x=ge(y,z)', [F, F, F, F]);
|
CheckF4Comp(GEF32, 'var y=f4(-1,1,0,2); var z=f4(1,2,3,4); var x=i4(0,0,0,0); x=ge(y,z)', [F, F, F, F]);
|
||||||
CheckF4Comp(GEF32, 'var y=f4(1,0,3,4); var z=f4(1,1,7,0); var x=i4(0,0,0,0); x=ge(y,z)', [T, F, F, T]);
|
CheckF4Comp(GEF32, 'var y=f4(1,0,3,4); var z=f4(1,1,7,0); var x=i4(0,0,0,0); x=ge(y,z)', [T, F, F, T]);
|
||||||
|
|
||||||
|
// Conversions operators
|
||||||
|
const CVTIF = 'var cvt=f4.fromInt32x4;';
|
||||||
|
const CVTFI = 'var cvt=i4.fromFloat32x4;';
|
||||||
|
|
||||||
|
assertAsmTypeFail('glob', USE_ASM + I32 + "var cvt=i4.fromInt32x4; return {}");
|
||||||
|
assertAsmTypeFail('glob', USE_ASM + F32 + "var cvt=f4.fromFloat32x4; return {}");
|
||||||
|
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIF + "function f() {var x=i4(1,2,3,4); x=cvt(x);} return f");
|
||||||
|
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIF + "function f() {var x=f4(1,2,3,4); x=cvt(x);} return f");
|
||||||
|
|
||||||
|
var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTIF + 'function f(x){x=i4(x); var y=f4(0,0,0,0); y=cvt(x); return f4(y);} return f'), this);
|
||||||
|
assertEqX4(f(SIMD.int32x4(1,2,3,4)), [1, 2, 3, 4]);
|
||||||
|
assertEqX4(f(SIMD.int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, Math.fround(INT32_MIN), Math.fround(INT32_MAX), -1]);
|
||||||
|
|
||||||
|
// TODO amend tests once int32x4.fromFloat32x4 is fully specified, when float
|
||||||
|
// values can't be converted into an int32 without overflowing. In these
|
||||||
|
// tests, we assume x86/x64, so a conversion which failed will return the
|
||||||
|
// undefined int32 value. See also bug 1068028.
|
||||||
|
const UNDEFINED_INT32 = 0x80000000 | 0;
|
||||||
|
var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTFI + 'function f(x){x=f4(x); var y=i4(0,0,0,0); y=cvt(x); return i4(y);} return f'), this);
|
||||||
|
assertEqX4(f(SIMD.float32x4(1,2,3,4)), [1, 2, 3, 4]);
|
||||||
|
assertEqX4(f(SIMD.float32x4(NaN,Infinity,-Infinity,-0)), [UNDEFINED_INT32, UNDEFINED_INT32, UNDEFINED_INT32, 0]);
|
||||||
|
|
||||||
// Bitwise ops
|
// Bitwise ops
|
||||||
const ANDI32 = 'var andd=i4.and;';
|
const ANDI32 = 'var andd=i4.and;';
|
||||||
const ORI32 = 'var orr=i4.or;';
|
const ORI32 = 'var orr=i4.or;';
|
||||||
|
|
Загрузка…
Ссылка в новой задаче