Skip to content

Commit

Permalink
Implement f{32,64}.copysign instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Aug 11, 2020
1 parent c0d88e1 commit 219777c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
17 changes: 15 additions & 2 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,16 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, span<const Value>
binary_op(stack, std::divides<float>{});
break;
}
case Instr::f32_copysign:
{
// TODO: This is not optimal implementation. The std::copysign() is inlined, but
// it afects the compiler to still use SSE vectors (probably due to C++ABI)
// while this can be implemented with just generic registers and integer
// instructions: (a & ABS_MASK) | (b & SIGN_MASK).
// https://godbolt.org/z/aPqvfo
binary_op(stack, std::copysign<float, float>);
break;
}

case Instr::f64_add:
{
Expand All @@ -1481,6 +1491,11 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, span<const Value>
binary_op(stack, std::divides<double>{});
break;
}
case Instr::f64_copysign:
{
binary_op(stack, std::copysign<double, double>);
break;
}

case Instr::i32_wrap_i64:
{
Expand Down Expand Up @@ -1586,7 +1601,6 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, span<const Value>
case Instr::f32_mul:
case Instr::f32_min:
case Instr::f32_max:
case Instr::f32_copysign:
case Instr::f64_abs:
case Instr::f64_neg:
case Instr::f64_ceil:
Expand All @@ -1598,7 +1612,6 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, span<const Value>
case Instr::f64_mul:
case Instr::f64_min:
case Instr::f64_max:
case Instr::f64_copysign:
case Instr::f32_convert_i32_s:
case Instr::f32_convert_i32_u:
case Instr::f32_convert_i64_s:
Expand Down
28 changes: 28 additions & 0 deletions test/unittests/execute_floating_point_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,34 @@ TYPED_TEST(execute_floating_point_types, div)
EXPECT_THAT(exec(TypeParam{0xABCD.01p7}, TypeParam{4}), Result(TypeParam{0x1.579A02p20}));
}

TYPED_TEST(execute_floating_point_types, copysign)
{
using FP = FP<TypeParam>;
using Limits = typename FP::Limits;

auto instance = instantiate(parse(this->get_binop_code(Instr::f32_copysign)));
const auto exec = [&](auto arg1, auto arg2) { return execute(*instance, 0, {arg1, arg2}); };

std::vector p_values(std::begin(this->q_values), std::end(this->q_values));
for (const auto x :
{TypeParam{0}, Limits::infinity(), FP::nan(FP::canon), FP::nan(FP::canon + 1), FP::nan(1)})
p_values.push_back(x);

for (const auto p1 : p_values)
{
for (const auto p2 : p_values)
{
// fcopysign(+-p1, +-p2) = +-p1
EXPECT_THAT(exec(p1, p2), Result(p1));
EXPECT_THAT(exec(-p1, -p2), Result(-p1));

// fcopysign(+-p1, -+p2) = -+p1
EXPECT_THAT(exec(p1, -p2), Result(-p1));
EXPECT_THAT(exec(-p1, p2), Result(p1));
}
}
}


template <typename SrcT, typename DstT>
struct ConversionPairWasmTraits;
Expand Down

0 comments on commit 219777c

Please sign in to comment.