Bug 1069956: SIMD: Add support for int32x4.fromFloat32x4 and float32x4.fromInt32x4 in Odin; r=luke

This commit is contained in:
Benjamin Bouvier 2014-09-25 13:18:08 +02:00
Родитель 900c9c8c75
Коммит 50c6f26e9d
4 изменённых файлов: 65 добавлений и 2 удалений

Просмотреть файл

@ -364,6 +364,7 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
case AsmJSSimdOperation_withY: native = simd_int32x4_withY; break;
case AsmJSSimdOperation_withZ: native = simd_int32x4_withZ; break;
case AsmJSSimdOperation_withW: native = simd_int32x4_withW; break;
case AsmJSSimdOperation_fromFloat32x4: native = simd_int32x4_fromFloat32x4; break;
case AsmJSSimdOperation_lessThanOrEqual:
case AsmJSSimdOperation_greaterThanOrEqual:
case AsmJSSimdOperation_notEqual:
@ -371,6 +372,7 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
case AsmJSSimdOperation_div:
case AsmJSSimdOperation_max:
case AsmJSSimdOperation_min:
case AsmJSSimdOperation_fromInt32x4:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
"place");
}
@ -398,6 +400,10 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
case AsmJSSimdOperation_withY: native = simd_float32x4_withY; break;
case AsmJSSimdOperation_withZ: native = simd_float32x4_withZ; 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;
}

Просмотреть файл

@ -96,7 +96,9 @@ enum AsmJSSimdOperation
AsmJSSimdOperation_withX,
AsmJSSimdOperation_withY,
AsmJSSimdOperation_withZ,
AsmJSSimdOperation_withW
AsmJSSimdOperation_withW,
AsmJSSimdOperation_fromInt32x4,
AsmJSSimdOperation_fromFloat32x4
};
// 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("withY", AsmJSSimdOperation_withY) ||
!addStandardLibrarySimdOpName("withZ", AsmJSSimdOperation_withZ) ||
!addStandardLibrarySimdOpName("withW", AsmJSSimdOperation_withW))
!addStandardLibrarySimdOpName("withW", AsmJSSimdOperation_withW) ||
!addStandardLibrarySimdOpName("fromFloat32x4", AsmJSSimdOperation_fromFloat32x4) ||
!addStandardLibrarySimdOpName("fromInt32x4", AsmJSSimdOperation_fromInt32x4))
{
return false;
}
@ -2509,6 +2511,17 @@ class FunctionCompiler
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)
{
if (inDeadCode())
@ -3588,6 +3601,8 @@ IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
case AsmJSSimdOperation_withZ:
case AsmJSSimdOperation_withW:
return true;
case AsmJSSimdOperation_fromFloat32x4:
return type == AsmJSSimdType_int32x4;
case AsmJSSimdOperation_mul:
case AsmJSSimdOperation_div:
case AsmJSSimdOperation_max:
@ -3595,6 +3610,7 @@ IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
case AsmJSSimdOperation_lessThanOrEqual:
case AsmJSSimdOperation_notEqual:
case AsmJSSimdOperation_greaterThanOrEqual:
case AsmJSSimdOperation_fromInt32x4:
return type == AsmJSSimdType_float32x4;
}
return false;
@ -4964,6 +4980,23 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
case AsmJSSimdOperation_withW:
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: {
DefinitionVector defs;
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,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
const ANDI32 = 'var andd=i4.and;';
const ORI32 = 'var orr=i4.or;';