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

This commit is contained in:
Benjamin Bouvier 2014-09-25 13:18:21 +02:00
parent dbfbf336f5
commit a6004515f4
4 changed files with 77 additions and 5 deletions

View File

@ -365,6 +365,7 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
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_fromFloat32x4Bits: native = simd_int32x4_fromFloat32x4Bits; break;
case AsmJSSimdOperation_lessThanOrEqual:
case AsmJSSimdOperation_greaterThanOrEqual:
case AsmJSSimdOperation_notEqual:
@ -373,6 +374,7 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
case AsmJSSimdOperation_max:
case AsmJSSimdOperation_min:
case AsmJSSimdOperation_fromInt32x4:
case AsmJSSimdOperation_fromInt32x4Bits:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
"place");
}
@ -401,7 +403,9 @@ ValidateSimdOperation(JSContext *cx, AsmJSModule::Global &global, HandleValue gl
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_fromInt32x4Bits: native = simd_float32x4_fromInt32x4Bits; break;
case AsmJSSimdOperation_fromFloat32x4:
case AsmJSSimdOperation_fromFloat32x4Bits:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("shouldn't have been validated in the first "
"place");
}

View File

@ -98,7 +98,9 @@ enum AsmJSSimdOperation
AsmJSSimdOperation_withZ,
AsmJSSimdOperation_withW,
AsmJSSimdOperation_fromInt32x4,
AsmJSSimdOperation_fromFloat32x4
AsmJSSimdOperation_fromFloat32x4,
AsmJSSimdOperation_fromInt32x4Bits,
AsmJSSimdOperation_fromFloat32x4Bits
};
// These labels describe positions in the prologue/epilogue of functions while

View File

@ -1429,7 +1429,9 @@ class MOZ_STACK_CLASS ModuleCompiler
!addStandardLibrarySimdOpName("withZ", AsmJSSimdOperation_withZ) ||
!addStandardLibrarySimdOpName("withW", AsmJSSimdOperation_withW) ||
!addStandardLibrarySimdOpName("fromFloat32x4", AsmJSSimdOperation_fromFloat32x4) ||
!addStandardLibrarySimdOpName("fromInt32x4", AsmJSSimdOperation_fromInt32x4))
!addStandardLibrarySimdOpName("fromInt32x4", AsmJSSimdOperation_fromInt32x4) ||
!addStandardLibrarySimdOpName("fromFloat32x4Bits", AsmJSSimdOperation_fromFloat32x4Bits) ||
!addStandardLibrarySimdOpName("fromInt32x4Bits", AsmJSSimdOperation_fromInt32x4Bits))
{
return false;
}
@ -2511,13 +2513,14 @@ class FunctionCompiler
return ins;
}
template<class T>
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);
T *ins = T::NewAsmJS(alloc(), vec, from, to);
curBlock_->add(ins);
return ins;
}
@ -3602,6 +3605,7 @@ IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
case AsmJSSimdOperation_withW:
return true;
case AsmJSSimdOperation_fromFloat32x4:
case AsmJSSimdOperation_fromFloat32x4Bits:
return type == AsmJSSimdType_int32x4;
case AsmJSSimdOperation_mul:
case AsmJSSimdOperation_div:
@ -3611,6 +3615,7 @@ IsSimdValidOperationType(AsmJSSimdType type, AsmJSSimdOperation op)
case AsmJSSimdOperation_notEqual:
case AsmJSSimdOperation_greaterThanOrEqual:
case AsmJSSimdOperation_fromInt32x4:
case AsmJSSimdOperation_fromInt32x4Bits:
return type == AsmJSSimdType_float32x4;
}
return false;
@ -4984,7 +4989,15 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
DefinitionVector defs;
if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(Type::Int32x4), &defs))
return false;
*def = f.convertSimd(defs[0], MIRType_Int32x4, retType.toMIRType());
*def = f.convertSimd<MSimdConvert>(defs[0], MIRType_Int32x4, retType.toMIRType());
*type = retType;
return true;
}
case AsmJSSimdOperation_fromInt32x4Bits: {
DefinitionVector defs;
if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(Type::Int32x4), &defs))
return false;
*def = f.convertSimd<MSimdReinterpretCast>(defs[0], MIRType_Int32x4, retType.toMIRType());
*type = retType;
return true;
}
@ -4992,7 +5005,15 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
DefinitionVector defs;
if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(Type::Float32x4), &defs))
return false;
*def = f.convertSimd(defs[0], MIRType_Float32x4, retType.toMIRType());
*def = f.convertSimd<MSimdConvert>(defs[0], MIRType_Float32x4, retType.toMIRType());
*type = retType;
return true;
}
case AsmJSSimdOperation_fromFloat32x4Bits: {
DefinitionVector defs;
if (!CheckSimdCallArgs(f, call, 1, CheckArgIsSubtypeOf(Type::Float32x4), &defs))
return false;
*def = f.convertSimd<MSimdReinterpretCast>(defs[0], MIRType_Float32x4, retType.toMIRType());
*type = retType;
return true;
}

View File

@ -586,6 +586,51 @@ var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTFI + 'function f(x){
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]);
// Cast operators
const CVTIFB = 'var cvt=f4.fromInt32x4Bits;';
const CVTFIB = 'var cvt=i4.fromFloat32x4Bits;';
var cast = (function() {
var i32 = new Int32Array(1);
var f32 = new Float32Array(i32.buffer);
function fromInt32Bits(x) {
i32[0] = x;
return f32[0];
}
function fromFloat32Bits(x) {
f32[0] = x;
return i32[0];
}
return {
fromInt32Bits,
fromFloat32Bits
}
})();
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 + CVTIFB + "function f() {var x=i4(1,2,3,4); x=cvt(x);} return f");
assertAsmTypeFail('glob', USE_ASM + I32 + F32 + CVTIFB + "function f() {var x=f4(1,2,3,4); x=cvt(x);} return f");
var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTIFB + '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].map(cast.fromInt32Bits));
assertEqX4(f(SIMD.int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, INT32_MIN, INT32_MAX, -1].map(cast.fromInt32Bits));
var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32A + CVTIFB + 'function f(x){x=i4(x); var y=f4(0,0,0,0); var z=f4(1,1,1,1); y=cvt(x); y=f4a(y, z); return f4(y)} return f'), this);
assertEqX4(f(SIMD.int32x4(1,2,3,4)), [1, 2, 3, 4].map(cast.fromInt32Bits).map((x) => x+1));
assertEqX4(f(SIMD.int32x4(0,INT32_MIN,INT32_MAX,-1)), [0, INT32_MIN, INT32_MAX, -1].map(cast.fromInt32Bits).map((x) => x+1));
var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + CVTFIB + '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].map(cast.fromFloat32Bits));
assertEqX4(f(SIMD.float32x4(-0,NaN,+Infinity,-Infinity)), [-0, NaN, +Infinity, -Infinity].map(cast.fromFloat32Bits));
var f = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + I32A + CVTFIB + 'function f(x){x=f4(x); var y=i4(0,0,0,0); var z=i4(1,1,1,1); y=cvt(x); y=i4a(y,z); return i4(y);} return f'), this);
assertEqX4(f(SIMD.float32x4(1,2,3,4)), [1, 2, 3, 4].map(cast.fromFloat32Bits).map((x) => x+1));
assertEqX4(f(SIMD.float32x4(-0,NaN,+Infinity,-Infinity)), [-0, NaN, +Infinity, -Infinity].map(cast.fromFloat32Bits).map((x) => x+1));
// Bitwise ops
const ANDI32 = 'var andd=i4.and;';
const ORI32 = 'var orr=i4.or;';