[wasm] Int64Lowering of I64XConvertFXX instructions.
On 32-bit systems I64XConvertFXX instructions are compiled to calls to C functions. The TF node for the function call is already generated in the wasm compiler, the lowering of the I64 parameter is done in the Int64Lowering. We use the return value of the C function to determine whether the conversion should trap or not. R=titzer@chromium.org Review URL: https://codereview.chromium.org/1775903002 Cr-Commit-Position: refs/heads/master@{#34738}
This commit is contained in:
parent
5fceb67049
commit
d57d14b978
@ -1209,6 +1209,26 @@ ExternalReference ExternalReference::wasm_uint64_to_float64(Isolate* isolate) {
|
||||
Redirect(isolate, FUNCTION_ADDR(wasm::uint64_to_float64_wrapper)));
|
||||
}
|
||||
|
||||
ExternalReference ExternalReference::wasm_float32_to_int64(Isolate* isolate) {
|
||||
return ExternalReference(
|
||||
Redirect(isolate, FUNCTION_ADDR(wasm::float32_to_int64_wrapper)));
|
||||
}
|
||||
|
||||
ExternalReference ExternalReference::wasm_float32_to_uint64(Isolate* isolate) {
|
||||
return ExternalReference(
|
||||
Redirect(isolate, FUNCTION_ADDR(wasm::float32_to_uint64_wrapper)));
|
||||
}
|
||||
|
||||
ExternalReference ExternalReference::wasm_float64_to_int64(Isolate* isolate) {
|
||||
return ExternalReference(
|
||||
Redirect(isolate, FUNCTION_ADDR(wasm::float64_to_int64_wrapper)));
|
||||
}
|
||||
|
||||
ExternalReference ExternalReference::wasm_float64_to_uint64(Isolate* isolate) {
|
||||
return ExternalReference(
|
||||
Redirect(isolate, FUNCTION_ADDR(wasm::float64_to_uint64_wrapper)));
|
||||
}
|
||||
|
||||
static void f64_acos_wrapper(double* param) { *param = std::acos(*param); }
|
||||
|
||||
ExternalReference ExternalReference::f64_acos_wrapper_function(
|
||||
|
@ -926,6 +926,10 @@ class ExternalReference BASE_EMBEDDED {
|
||||
static ExternalReference wasm_uint64_to_float32(Isolate* isolate);
|
||||
static ExternalReference wasm_int64_to_float64(Isolate* isolate);
|
||||
static ExternalReference wasm_uint64_to_float64(Isolate* isolate);
|
||||
static ExternalReference wasm_float32_to_int64(Isolate* isolate);
|
||||
static ExternalReference wasm_float32_to_uint64(Isolate* isolate);
|
||||
static ExternalReference wasm_float64_to_int64(Isolate* isolate);
|
||||
static ExternalReference wasm_float64_to_uint64(Isolate* isolate);
|
||||
|
||||
static ExternalReference f64_acos_wrapper_function(Isolate* isolate);
|
||||
static ExternalReference f64_asin_wrapper_function(Isolate* isolate);
|
||||
|
@ -893,48 +893,24 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
|
||||
op = m->RoundUint64ToFloat64();
|
||||
break;
|
||||
// kExprI64SConvertF32:
|
||||
// kExprI64SConvertF64:
|
||||
// kExprI64UConvertF32:
|
||||
// kExprI64UConvertF64:
|
||||
case wasm::kExprI64SConvertF32: {
|
||||
return BuildI64SConvertF32(input);
|
||||
}
|
||||
// kExprI64SConvertF64:
|
||||
case wasm::kExprI64SConvertF64: {
|
||||
return BuildI64SConvertF64(input);
|
||||
}
|
||||
// kExprI64UConvertF32:
|
||||
case wasm::kExprI64UConvertF32: {
|
||||
return BuildI64UConvertF32(input);
|
||||
}
|
||||
// kExprI64UConvertF64:
|
||||
case wasm::kExprI64UConvertF64: {
|
||||
return BuildI64UConvertF64(input);
|
||||
}
|
||||
#if WASM_64
|
||||
// Opcodes only supported on 64-bit platforms.
|
||||
// TODO(titzer): query the machine operator builder here instead of #ifdef.
|
||||
case wasm::kExprI64SConvertF32: {
|
||||
Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToInt64(), input);
|
||||
Node* result =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
|
||||
Node* overflow =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
|
||||
trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
|
||||
return result;
|
||||
}
|
||||
case wasm::kExprI64SConvertF64: {
|
||||
Node* trunc = graph()->NewNode(m->TryTruncateFloat64ToInt64(), input);
|
||||
Node* result =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
|
||||
Node* overflow =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
|
||||
trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
|
||||
return result;
|
||||
}
|
||||
case wasm::kExprI64UConvertF32: {
|
||||
Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToUint64(), input);
|
||||
Node* result =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
|
||||
Node* overflow =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
|
||||
trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
|
||||
return result;
|
||||
}
|
||||
case wasm::kExprI64UConvertF64: {
|
||||
Node* trunc = graph()->NewNode(m->TryTruncateFloat64ToUint64(), input);
|
||||
Node* result =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
|
||||
Node* overflow =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
|
||||
trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
|
||||
return result;
|
||||
}
|
||||
case wasm::kExprF64ReinterpretI64:
|
||||
op = m->BitcastInt64ToFloat64();
|
||||
break;
|
||||
@ -1655,26 +1631,27 @@ Node* WasmGraphBuilder::BuildCFuncInstruction(ExternalReference ref,
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildF32SConvertI64(Node* input) {
|
||||
return BuildConversionInstruction(
|
||||
return BuildIntToFloatConversionInstruction(
|
||||
input, ExternalReference::wasm_int64_to_float32(jsgraph()->isolate()),
|
||||
MachineRepresentation::kWord64, MachineType::Float32());
|
||||
}
|
||||
Node* WasmGraphBuilder::BuildF32UConvertI64(Node* input) {
|
||||
return BuildConversionInstruction(
|
||||
return BuildIntToFloatConversionInstruction(
|
||||
input, ExternalReference::wasm_uint64_to_float32(jsgraph()->isolate()),
|
||||
MachineRepresentation::kWord64, MachineType::Float32());
|
||||
}
|
||||
Node* WasmGraphBuilder::BuildF64SConvertI64(Node* input) {
|
||||
return BuildConversionInstruction(
|
||||
return BuildIntToFloatConversionInstruction(
|
||||
input, ExternalReference::wasm_int64_to_float64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kWord64, MachineType::Float64());
|
||||
}
|
||||
Node* WasmGraphBuilder::BuildF64UConvertI64(Node* input) {
|
||||
return BuildConversionInstruction(
|
||||
return BuildIntToFloatConversionInstruction(
|
||||
input, ExternalReference::wasm_uint64_to_float64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kWord64, MachineType::Float64());
|
||||
}
|
||||
Node* WasmGraphBuilder::BuildConversionInstruction(
|
||||
|
||||
Node* WasmGraphBuilder::BuildIntToFloatConversionInstruction(
|
||||
Node* input, ExternalReference ref,
|
||||
MachineRepresentation parameter_representation,
|
||||
const MachineType result_type) {
|
||||
@ -1701,6 +1678,99 @@ Node* WasmGraphBuilder::BuildConversionInstruction(
|
||||
return load;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildI64SConvertF32(Node* input) {
|
||||
if (jsgraph()->machine()->Is32()) {
|
||||
return BuildFloatToIntConversionInstruction(
|
||||
input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kFloat32, MachineType::Int64());
|
||||
} else {
|
||||
Node* trunc = graph()->NewNode(
|
||||
jsgraph()->machine()->TryTruncateFloat32ToInt64(), input);
|
||||
Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
|
||||
Node* overflow =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
|
||||
trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input) {
|
||||
if (jsgraph()->machine()->Is32()) {
|
||||
return BuildFloatToIntConversionInstruction(
|
||||
input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kFloat32, MachineType::Int64());
|
||||
} else {
|
||||
Node* trunc = graph()->NewNode(
|
||||
jsgraph()->machine()->TryTruncateFloat32ToUint64(), input);
|
||||
Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
|
||||
Node* overflow =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
|
||||
trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input) {
|
||||
if (jsgraph()->machine()->Is32()) {
|
||||
return BuildFloatToIntConversionInstruction(
|
||||
input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kFloat64, MachineType::Int64());
|
||||
} else {
|
||||
Node* trunc = graph()->NewNode(
|
||||
jsgraph()->machine()->TryTruncateFloat64ToInt64(), input);
|
||||
Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
|
||||
Node* overflow =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
|
||||
trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input) {
|
||||
if (jsgraph()->machine()->Is32()) {
|
||||
return BuildFloatToIntConversionInstruction(
|
||||
input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kFloat64, MachineType::Int64());
|
||||
} else {
|
||||
Node* trunc = graph()->NewNode(
|
||||
jsgraph()->machine()->TryTruncateFloat64ToUint64(), input);
|
||||
Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
|
||||
Node* overflow =
|
||||
graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
|
||||
trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction(
|
||||
Node* input, ExternalReference ref,
|
||||
MachineRepresentation parameter_representation,
|
||||
const MachineType result_type) {
|
||||
Node* stack_slot_param = graph()->NewNode(
|
||||
jsgraph()->machine()->StackSlot(parameter_representation));
|
||||
Node* stack_slot_result = graph()->NewNode(
|
||||
jsgraph()->machine()->StackSlot(result_type.representation()));
|
||||
const Operator* store_op = jsgraph()->machine()->Store(
|
||||
StoreRepresentation(parameter_representation, kNoWriteBarrier));
|
||||
*effect_ =
|
||||
graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
|
||||
input, *effect_, *control_);
|
||||
MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
|
||||
sig_builder.AddReturn(MachineType::Int32());
|
||||
sig_builder.AddParam(MachineType::Pointer());
|
||||
sig_builder.AddParam(MachineType::Pointer());
|
||||
Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
|
||||
Node* args[] = {function, stack_slot_param, stack_slot_result};
|
||||
trap_->ZeroCheck32(kTrapFloatUnrepresentable,
|
||||
BuildCCall(sig_builder.Build(), args));
|
||||
const Operator* load_op = jsgraph()->machine()->Load(result_type);
|
||||
Node* load =
|
||||
graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0),
|
||||
*effect_, *control_);
|
||||
*effect_ = load;
|
||||
return load;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
|
||||
const size_t params = sig->parameter_count();
|
||||
const size_t extra = 2; // effect and control inputs.
|
||||
|
@ -207,7 +207,7 @@ class WasmGraphBuilder {
|
||||
Node* BuildF64Atan2(Node* left, Node* right);
|
||||
Node* BuildF64Mod(Node* left, Node* right);
|
||||
|
||||
Node* BuildConversionInstruction(
|
||||
Node* BuildIntToFloatConversionInstruction(
|
||||
Node* input, ExternalReference ref,
|
||||
MachineRepresentation parameter_representation,
|
||||
const MachineType result_type);
|
||||
@ -216,6 +216,15 @@ class WasmGraphBuilder {
|
||||
Node* BuildF64SConvertI64(Node* input);
|
||||
Node* BuildF64UConvertI64(Node* input);
|
||||
|
||||
Node* BuildFloatToIntConversionInstruction(
|
||||
Node* input, ExternalReference ref,
|
||||
MachineRepresentation parameter_representation,
|
||||
const MachineType result_type);
|
||||
Node* BuildI64SConvertF32(Node* input);
|
||||
Node* BuildI64UConvertF32(Node* input);
|
||||
Node* BuildI64SConvertF64(Node* input);
|
||||
Node* BuildI64UConvertF64(Node* input);
|
||||
|
||||
Node** Realloc(Node** buffer, size_t count) {
|
||||
Node** buf = Buffer(count);
|
||||
if (buf != buffer) memcpy(buf, buffer, count * sizeof(Node*));
|
||||
|
@ -123,6 +123,14 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
|
||||
"wasm::int64_to_float64_wrapper");
|
||||
Add(ExternalReference::wasm_uint64_to_float64(isolate).address(),
|
||||
"wasm::uint64_to_float64_wrapper");
|
||||
Add(ExternalReference::wasm_float32_to_int64(isolate).address(),
|
||||
"wasm::float32_to_int64_wrapper");
|
||||
Add(ExternalReference::wasm_float32_to_uint64(isolate).address(),
|
||||
"wasm::float32_to_uint64_wrapper");
|
||||
Add(ExternalReference::wasm_float64_to_int64(isolate).address(),
|
||||
"wasm::float64_to_int64_wrapper");
|
||||
Add(ExternalReference::wasm_float64_to_uint64(isolate).address(),
|
||||
"wasm::float64_to_uint64_wrapper");
|
||||
Add(ExternalReference::f64_acos_wrapper_function(isolate).address(),
|
||||
"f64_acos_wrapper");
|
||||
Add(ExternalReference::f64_asin_wrapper_function(isolate).address(),
|
||||
|
@ -92,6 +92,53 @@ static void uint64_to_float64_wrapper(uint64_t* input, double* output) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t float32_to_int64_wrapper(float* input, int64_t* output) {
|
||||
// We use "<" here to check the upper bound because of rounding problems: With
|
||||
// "<=" some inputs would be considered within int64 range which are actually
|
||||
// not within int64 range.
|
||||
if (*input >= static_cast<float>(std::numeric_limits<int64_t>::min()) &&
|
||||
*input < static_cast<float>(std::numeric_limits<int64_t>::max())) {
|
||||
*output = static_cast<int64_t>(*input);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t float32_to_uint64_wrapper(float* input, uint64_t* output) {
|
||||
// We use "<" here to check the upper bound because of rounding problems: With
|
||||
// "<=" some inputs would be considered within uint64 range which are actually
|
||||
// not within uint64 range.
|
||||
if (*input > -1.0 &&
|
||||
*input < static_cast<float>(std::numeric_limits<uint64_t>::max())) {
|
||||
*output = static_cast<uint64_t>(*input);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t float64_to_int64_wrapper(double* input, int64_t* output) {
|
||||
// We use "<" here to check the upper bound because of rounding problems: With
|
||||
// "<=" some inputs would be considered within int64 range which are actually
|
||||
// not within int64 range.
|
||||
if (*input >= static_cast<double>(std::numeric_limits<int64_t>::min()) &&
|
||||
*input < static_cast<double>(std::numeric_limits<int64_t>::max())) {
|
||||
*output = static_cast<int64_t>(*input);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t float64_to_uint64_wrapper(double* input, uint64_t* output) {
|
||||
// We use "<" here to check the upper bound because of rounding problems: With
|
||||
// "<=" some inputs would be considered within uint64 range which are actually
|
||||
// not within uint64 range.
|
||||
if (*input > -1.0 &&
|
||||
*input < static_cast<double>(std::numeric_limits<uint64_t>::max())) {
|
||||
*output = static_cast<uint64_t>(*input);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} // namespace wasm
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -331,6 +331,99 @@ TEST(RunCallUint64ToFloat64) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RunCallFloat32ToInt64) {
|
||||
BufferedRawMachineAssemblerTester<int32_t> m;
|
||||
ExternalReference ref = ExternalReference::wasm_float32_to_int64(m.isolate());
|
||||
|
||||
float input;
|
||||
int64_t output;
|
||||
|
||||
Node* function = m.ExternalConstant(ref);
|
||||
m.Return(m.CallCFunction2(
|
||||
MachineType::Int32(), MachineType::Pointer(), MachineType::Pointer(),
|
||||
function, m.PointerConstant(&input), m.PointerConstant(&output)));
|
||||
FOR_FLOAT32_INPUTS(i) {
|
||||
input = *i;
|
||||
if (*i >= static_cast<float>(std::numeric_limits<int64_t>::min()) &&
|
||||
*i < static_cast<float>(std::numeric_limits<int64_t>::max())) {
|
||||
CHECK_EQ(1, m.Call());
|
||||
CHECK_EQ(static_cast<int64_t>(*i), output);
|
||||
} else {
|
||||
CHECK_EQ(0, m.Call());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RunCallFloat32ToUint64) {
|
||||
BufferedRawMachineAssemblerTester<int32_t> m;
|
||||
ExternalReference ref =
|
||||
ExternalReference::wasm_float32_to_uint64(m.isolate());
|
||||
|
||||
float input;
|
||||
uint64_t output;
|
||||
|
||||
Node* function = m.ExternalConstant(ref);
|
||||
m.Return(m.CallCFunction2(
|
||||
MachineType::Int32(), MachineType::Pointer(), MachineType::Pointer(),
|
||||
function, m.PointerConstant(&input), m.PointerConstant(&output)));
|
||||
FOR_FLOAT32_INPUTS(i) {
|
||||
input = *i;
|
||||
if (*i > -1.0 &&
|
||||
*i < static_cast<float>(std::numeric_limits<uint64_t>::max())) {
|
||||
CHECK_EQ(1, m.Call());
|
||||
CHECK_EQ(static_cast<uint64_t>(*i), output);
|
||||
} else {
|
||||
CHECK_EQ(0, m.Call());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RunCallFloat64ToInt64) {
|
||||
BufferedRawMachineAssemblerTester<int32_t> m;
|
||||
ExternalReference ref = ExternalReference::wasm_float64_to_int64(m.isolate());
|
||||
|
||||
double input;
|
||||
int64_t output;
|
||||
|
||||
Node* function = m.ExternalConstant(ref);
|
||||
m.Return(m.CallCFunction2(
|
||||
MachineType::Int32(), MachineType::Pointer(), MachineType::Pointer(),
|
||||
function, m.PointerConstant(&input), m.PointerConstant(&output)));
|
||||
FOR_FLOAT64_INPUTS(i) {
|
||||
input = *i;
|
||||
if (*i >= static_cast<double>(std::numeric_limits<int64_t>::min()) &&
|
||||
*i < static_cast<double>(std::numeric_limits<int64_t>::max())) {
|
||||
CHECK_EQ(1, m.Call());
|
||||
CHECK_EQ(static_cast<int64_t>(*i), output);
|
||||
} else {
|
||||
CHECK_EQ(0, m.Call());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RunCallFloat64ToUint64) {
|
||||
BufferedRawMachineAssemblerTester<int32_t> m;
|
||||
ExternalReference ref =
|
||||
ExternalReference::wasm_float64_to_uint64(m.isolate());
|
||||
|
||||
double input;
|
||||
uint64_t output;
|
||||
|
||||
Node* function = m.ExternalConstant(ref);
|
||||
m.Return(m.CallCFunction2(
|
||||
MachineType::Int32(), MachineType::Pointer(), MachineType::Pointer(),
|
||||
function, m.PointerConstant(&input), m.PointerConstant(&output)));
|
||||
FOR_FLOAT64_INPUTS(i) {
|
||||
input = *i;
|
||||
if (*i > -1.0 &&
|
||||
*i < static_cast<double>(std::numeric_limits<uint64_t>::max())) {
|
||||
CHECK_EQ(1, m.Call());
|
||||
CHECK_EQ(static_cast<uint64_t>(*i), output);
|
||||
} else {
|
||||
CHECK_EQ(0, m.Call());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -442,9 +442,64 @@ TEST(Run_Wasm_F64UConvertI64) {
|
||||
}
|
||||
}
|
||||
// kExprI64SConvertF32:
|
||||
|
||||
TEST(Run_Wasm_I64SConvertF32) {
|
||||
WasmRunner<int64_t> r(MachineType::Float32());
|
||||
BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT32_INPUTS(i) {
|
||||
if (*i < static_cast<float>(std::numeric_limits<int64_t>::max()) &&
|
||||
*i >= static_cast<float>(std::numeric_limits<int64_t>::min())) {
|
||||
CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
|
||||
} else {
|
||||
CHECK_TRAP64(r.Call(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
// kExprI64SConvertF64:
|
||||
TEST(Run_Wasm_I64SConvertF64) {
|
||||
WasmRunner<int64_t> r(MachineType::Float64());
|
||||
BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT64_INPUTS(i) {
|
||||
if (*i < static_cast<double>(std::numeric_limits<int64_t>::max()) &&
|
||||
*i >= static_cast<double>(std::numeric_limits<int64_t>::min())) {
|
||||
CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
|
||||
} else {
|
||||
CHECK_TRAP64(r.Call(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// kExprI64UConvertF32:
|
||||
TEST(Run_Wasm_I64UConvertF32) {
|
||||
WasmRunner<uint64_t> r(MachineType::Float32());
|
||||
BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT32_INPUTS(i) {
|
||||
if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) &&
|
||||
*i > -1) {
|
||||
CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
|
||||
} else {
|
||||
CHECK_TRAP64(r.Call(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// kExprI64UConvertF64:
|
||||
TEST(Run_Wasm_I64UConvertF64) {
|
||||
WasmRunner<uint64_t> r(MachineType::Float64());
|
||||
BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT64_INPUTS(i) {
|
||||
if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) &&
|
||||
*i > -1) {
|
||||
CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
|
||||
} else {
|
||||
CHECK_TRAP64(r.Call(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Run_WasmCallI64Parameter) {
|
||||
// Build the target function.
|
||||
|
@ -3129,66 +3129,6 @@ TEST(Run_Wasm_F64Max_Snan) {
|
||||
|
||||
#endif
|
||||
|
||||
#if WASM_64
|
||||
TEST(Run_Wasm_I64SConvertF32) {
|
||||
WasmRunner<int64_t> r(MachineType::Float32());
|
||||
BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT32_INPUTS(i) {
|
||||
if (*i < static_cast<float>(INT64_MAX) &&
|
||||
*i >= static_cast<float>(INT64_MIN)) {
|
||||
CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
|
||||
} else {
|
||||
CHECK_TRAP64(r.Call(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(Run_Wasm_I64SConvertF64) {
|
||||
WasmRunner<int64_t> r(MachineType::Float64());
|
||||
BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT64_INPUTS(i) {
|
||||
if (*i < static_cast<double>(INT64_MAX) &&
|
||||
*i >= static_cast<double>(INT64_MIN)) {
|
||||
CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i));
|
||||
} else {
|
||||
CHECK_TRAP64(r.Call(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(Run_Wasm_I64UConvertF32) {
|
||||
WasmRunner<uint64_t> r(MachineType::Float32());
|
||||
BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT32_INPUTS(i) {
|
||||
if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
|
||||
CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
|
||||
} else {
|
||||
CHECK_TRAP64(r.Call(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(Run_Wasm_I64UConvertF64) {
|
||||
WasmRunner<uint64_t> r(MachineType::Float64());
|
||||
BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
|
||||
|
||||
FOR_FLOAT64_INPUTS(i) {
|
||||
if (*i < static_cast<float>(UINT64_MAX) && *i > -1) {
|
||||
CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i));
|
||||
} else {
|
||||
CHECK_TRAP64(r.Call(*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// TODO(titzer): Fix and re-enable.
|
||||
#if 0
|
||||
TEST(Run_Wasm_I32SConvertF32) {
|
||||
|
Loading…
Reference in New Issue
Block a user