// Copyright Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #include #include #include namespace rocRoller::Expression::EvaluateDetail { CAN_OPERATE_CONCEPT(Add, +); static_assert(CCanAdd); static_assert(CCanAdd); static_assert(!CCanAdd); /** * Custom declared so that we can check for null pointers where appropriate. */ template <> struct OperationEvaluatorVisitor : public BinaryEvaluatorVisitor { template requires CCanAdd auto evaluate(LHS const& lhs, RHS const& rhs) const { assertNonNullPointer(lhs); assertNonNullPointer(rhs); return lhs + rhs; } }; CAN_OPERATE_CONCEPT(Subtract, -); /** * Custom declared so that we can check for null pointers where appropriate. */ template <> struct OperationEvaluatorVisitor : public BinaryEvaluatorVisitor { template requires CCanSubtract auto evaluate(LHS const& lhs, RHS const& rhs) const { assertNonNullPointer(lhs); assertNonNullPointer(rhs); return lhs - rhs; } }; SIMPLE_BINARY_OP(Multiply, *); SIMPLE_BINARY_OP(Divide, /); SIMPLE_BINARY_OP(Modulo, %); template <> struct OperationEvaluatorVisitor : public BinaryEvaluatorVisitor { int evaluate(int const& lhs, int const& rhs) const { assertNonNullPointer(lhs); assertNonNullPointer(rhs); return (lhs * (int64_t)rhs) >> 32; } int evaluate(int const& lhs, unsigned int const& rhs) const { assertNonNullPointer(lhs); assertNonNullPointer(rhs); return (lhs * (int64_t)rhs) >> 32; } int evaluate(unsigned int const& lhs, int const& rhs) const { assertNonNullPointer(lhs); assertNonNullPointer(rhs); return (lhs * (int64_t)rhs) >> 32; } unsigned int evaluate(unsigned int const& lhs, unsigned int const& rhs) const { assertNonNullPointer(lhs); assertNonNullPointer(rhs); return (lhs * (uint64_t)rhs) >> 32; } int64_t evaluate(int const& lhs, int64_t const& rhs) const { return evaluate((int64_t)lhs, rhs); } int64_t evaluate(int64_t const& lhs, int64_t const& rhs) const { assertNonNullPointer(lhs); assertNonNullPointer(rhs); return ((__int128_t)lhs * (__int128_t)rhs) >> 64; } uint64_t evaluate(uint64_t const& lhs, uint64_t const& rhs) const { assertNonNullPointer(lhs); assertNonNullPointer(rhs); return ((__uint128_t)lhs * (__uint128_t)rhs) >> 64; } }; INSTANTIATE_BINARY_OP(Add); INSTANTIATE_BINARY_OP(Subtract); INSTANTIATE_BINARY_OP(Multiply); INSTANTIATE_BINARY_OP(MultiplyHigh); INSTANTIATE_BINARY_OP(Divide); INSTANTIATE_BINARY_OP(Modulo); static_assert(CCanEvaluateBinary, double, double>); static_assert(!CCanEvaluateBinary, double, int*>); static_assert(CCanEvaluateBinary, float*, int>); static_assert(CCanEvaluateBinary, double, double>); static_assert(!CCanEvaluateBinary, double, int*>); static_assert(CCanEvaluateBinary, float*, int>); static_assert(CCanEvaluateBinary, double, double>); static_assert(!CCanEvaluateBinary, double, int*>); static_assert(!CCanEvaluateBinary, float*, int>); }