externals: Remove mp and replace uses with mcl

This commit is contained in:
Merry 2022-04-19 12:12:19 +01:00
parent f642637971
commit de4154aa18
60 changed files with 90 additions and 1502 deletions

View file

@ -19,10 +19,11 @@ if (NOT TARGET fmt AND NOT TARGET fmt::fmt)
add_subdirectory(fmt) add_subdirectory(fmt)
endif() endif()
# mp # mcl
add_library(mp INTERFACE) if (NOT TARGET merry::mcl)
target_include_directories(mp INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mp/include>) add_subdirectory(mcl)
endif()
# robin-map # robin-map

6
externals/README.md vendored
View file

@ -4,7 +4,7 @@ This repository uses subtrees to manage some of its externals.
``` ```
git remote add externals-fmt https://github.com/fmtlib/fmt.git --no-tags git remote add externals-fmt https://github.com/fmtlib/fmt.git --no-tags
git remote add externals-mp https://github.com/MerryMage/mp.git --no-tags git remote add externals-mcl https://github.com/merryhime/mcl.git --no-tags
git remote add externals-robin-map https://github.com/Tessil/robin-map.git --no-tags git remote add externals-robin-map https://github.com/Tessil/robin-map.git --no-tags
git remote add externals-vixl https://git.linaro.org/arm/vixl.git --no-tags git remote add externals-vixl https://git.linaro.org/arm/vixl.git --no-tags
git remote add externals-xbyak https://github.com/herumi/xbyak.git --no-tags git remote add externals-xbyak https://github.com/herumi/xbyak.git --no-tags
@ -18,14 +18,14 @@ Change `<ref>` to refer to the appropriate git reference.
``` ```
git fetch externals-fmt git fetch externals-fmt
git fetch externals-mp git fetch externals-mcl
git fetch externals-robin-map git fetch externals-robin-map
git fetch externals-vixl git fetch externals-vixl
git fetch externals-xbyak git fetch externals-xbyak
git fetch externals-zycore git fetch externals-zycore
git fetch externals-zydis git fetch externals-zydis
git subtree pull --squash --prefix=externals/fmt externals-fmt <ref> git subtree pull --squash --prefix=externals/fmt externals-fmt <ref>
git subtree pull --squash --prefix=externals/mp externals-mp <ref> git subtree pull --squash --prefix=externals/mcl externals-mcl <ref>
git subtree pull --squash --prefix=externals/robin-map externals-robin-map <ref> git subtree pull --squash --prefix=externals/robin-map externals-robin-map <ref>
git subtree pull --squash --prefix=externals/vixl/vixl externals-vixl <ref> git subtree pull --squash --prefix=externals/vixl/vixl externals-vixl <ref>
git subtree pull --squash --prefix=externals/xbyak externals-xbyak <ref> git subtree pull --squash --prefix=externals/xbyak externals-xbyak <ref>

View file

@ -1,19 +0,0 @@
language: cpp
os: linux
matrix:
- compiler: clang
env: CXX=clang
dist: bionic
- compiler: g++-8
env: CXX=g++-8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-8
script:
- $CXX --version
- $CXX -I./include -std=c++17 -Wall -Wextra -Wcast-qual -pedantic -pedantic-errors -Werror tests/all_tests.cpp

View file

@ -1,12 +0,0 @@
Copyright (C) 2017 MerryMage
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

122
externals/mp/README.md vendored
View file

@ -1,122 +0,0 @@
mp
===
A small, 0BSD-licensed metaprogramming library for C++17.
This is intended to be a lightweight and easy to understand implementation of a subset of useful metaprogramming utilities.
Usage
-----
Just add the `include` directory to your include path. That's it.
`typelist`
----------
A `mp::list` is a list of types. This set of headers provide metafunctions for manipulating lists of types.
### Constructor
* `mp::list`: Constructs a list.
* `mp::lift_sequence`: Lifts a value sequence into a list. Intended for use on `std::integral_sequence`.
### Element access
* `mp::get`: Gets a numbered element of a list.
* `mp::head`: Gets the first element of a list.
* `mp::tail`: Gets all-but-the-first-element as a list.
### Properties
* `mp::length`: Gets the length of a list.
* `mp::contains`: Determines if this list contains a specified element.
### Modifiers
* `mp::append`: Constructs a list with the provided elements appended to it.
* `mp::prepend`: Constructs a list with the provided elements prepended to it.
### Operations
* `mp::concat`: Concantenates multiple lists together.
* `mp::cartesian_product`: Construct a list containing the [cartesian product](https://en.wikipedia.org/wiki/Cartesian_product) of the provided lists.
### Conversions
* `mp::lower_to_tuple`: This operation only works on a list solely containing metavalues. Results in a `std::tuple` with equivalent values.
`metavalue`
-----------
A metavalue is a type of template `std::integral_constant`.
### Constants
* mp::true_type: Aliases to [`std::true_type`](https://en.cppreference.com/w/cpp/types/integral_constant)
* mp::false_type: Aliases to [`mp::false_type`](https://en.cppreference.com/w/cpp/types/integral_constant)
### Constructor
* mp::value: Aliases to [`std::integral_constant`](https://en.cppreference.com/w/cpp/types/integral_constant)
* mp::bool_value: Aliases to [`std::bool_constant`](https://en.cppreference.com/w/cpp/types/integral_constant)
* mp::size_value: Constructs a metavalue with value of type std::size_t
* `mp::lift_value`: Lifts a value of any arbitrary type to become a metavalue
### Conversions
* `mp::value_cast`
### Operations
* `mp::value_equal`: Compares value equality, ignores type. Use `std::is_same` for strict comparison.
* `mp::logic_if`: Like std::conditional but has a bool metavalue as first argument.
* `mp::bit_not`: Bitwise not
* `mp::bit_and`: Bitwise and
* `mp::bit_or`: Bitwise or
* `mp::bit_xor`: Bitwise xor
* `mp::logic_not`: Logical not
* `mp::logic_and`: Logical conjunction (no short circuiting, always results in a mp:bool_value)
* `mp::logic_or`: Logical disjunction (no short circuiting, always results in a mp:bool_value)
* `mp::conjunction`: Logical conjunction (with short circuiting, preserves type)
* `mp::disjunction`: Logical disjunction (with short circuiting, preserves type)
* `mp::sum`: Sum of values
* `mp::product`: Product of values
`metafunction`
--------------
* `std::void_t`: Always returns `void`.
* `mp::identity`: Identity metafunction. Can be used to establish a non-deduced context. See also C++20 `std::type_identity`.
* `mp::apply`: Invoke a provided metafunction with arguments specified in a list.
* `mp::map`: Apply a provided metafunction to each element of a list.
* `mp::bind`: Curry a metafunction. A macro `MM_MP_BIND` is provided to make this a little prettier.
`traits`
--------
Type traits not in the standard library.
### `function_info`
* `mp::parameter_count_v`: Number of parameters a function has
* `mp::parameter_list`: Get a typelist of the parameter types
* `mp::get_parameter`: Get the type of a parameter by index
* `mp::equivalent_function_type`: Get an equivalent function type (for MFPs this does not include the class)
* `mp::equivalent_function_type_with_class`: Get an equivalent function type with explicit `this` argument (MFPs only)
* `mp::return_type`: Return type of the function
* `mp::class_type`: Only valid for member function pointer types. Gets the class the member function is associated with.
### `integer_of_size`
* `mp::signed_integer_of_size`: Gets a signed integer of the specified bit-size (if it exists)
* `mp::unsigned_integer_of_size`: Gets an unsigned integer of the specified bit-size (if it exists)
### Misc
* `mp::is_instance_of_template`: Checks if a type is an instance of a template class.
License
-------
Please see [LICENSE-0BSD](LICENSE-0BSD).

View file

@ -1,26 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
namespace detail {
template<template<class...> class F, class L>
struct apply_impl;
template<template<class...> class F, template<class...> class LT, class... Es>
struct apply_impl<F, LT<Es...>> {
using type = F<Es...>;
};
} // namespace detail
/// Invokes metafunction F where the arguments are all the members of list L
template<template<class...> class F, class L>
using apply = typename detail::apply_impl<F, L>::type;
} // namespace mp

View file

@ -1,19 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
/// Binds the first sizeof...(A) arguments of metafunction F with arguments A
template<template<class...> class F, class... As>
struct bind {
template<class... Rs>
using type = F<As..., Rs...>;
};
} // namespace mp
#define MM_MP_BIND(...) ::mp::bind<__VA_ARGS__>::template type

View file

@ -1,23 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
namespace detail {
template<class T>
struct identity_impl {
using type = T;
};
} // namespace detail
/// Identity metafunction
template<class T>
using identity = typename identity_impl<T>::type;
} // namespace mp

View file

@ -1,26 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
namespace detail {
template<template<class...> class F, class L>
struct map_impl;
template<template<class...> class F, template<class...> class LT, class... Es>
struct map_impl<F, LT<Es...>> {
using type = LT<F<Es>...>;
};
} // namespace detail
/// Applies each element of list L to metafunction F
template<template<class...> class F, class L>
using map = typename detail::map_impl<F, L>::type;
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/lift_value.h>
namespace mp {
/// Bitwise and of metavalues Vs
template<class... Vs>
using bit_and = lift_value<(Vs::value & ...)>;
/// Bitwise and of metavalues Vs
template<class... Vs>
constexpr auto bit_and_v = (Vs::value & ...);
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/lift_value.h>
namespace mp {
/// Bitwise not of metavalue V
template<class V>
using bit_not = lift_value<~V::value>;
/// Bitwise not of metavalue V
template<class V>
constexpr auto bit_not_v = ~V::value;
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/lift_value.h>
namespace mp {
/// Bitwise or of metavalues Vs
template<class... Vs>
using bit_or = lift_value<(Vs::value | ...)>;
/// Bitwise or of metavalues Vs
template<class... Vs>
constexpr auto bit_or_v = (Vs::value | ...);
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/lift_value.h>
namespace mp {
/// Bitwise xor of metavalues Vs
template<class... Vs>
using bit_xor = lift_value<(Vs::value ^ ...)>;
/// Bitwise xor of metavalues Vs
template<class... Vs>
constexpr auto bit_xor_v = (Vs::value ^ ...);
} // namespace mp

View file

@ -1,43 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/value.h>
#include <mp/metavalue/logic_if.h>
namespace mp {
namespace detail {
template<class...>
struct conjunction_impl;
template<>
struct conjunction_impl<> {
using type = false_type;
};
template<class V>
struct conjunction_impl<V> {
using type = V;
};
template<class V1, class... Vs>
struct conjunction_impl<V1, Vs...> {
using type = logic_if<V1, typename conjunction_impl<Vs...>::type, V1>;
};
} // namespace detail
/// Conjunction of metavalues Vs with short-circuiting and type preservation.
template<class... Vs>
using conjunction = typename detail::conjunction_impl<Vs...>::type;
/// Conjunction of metavalues Vs with short-circuiting and type preservation.
template<class... Vs>
constexpr auto conjunction_v = conjunction<Vs...>::value;
} // namespace mp

View file

@ -1,43 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/value.h>
#include <mp/metavalue/logic_if.h>
namespace mp {
namespace detail {
template<class...>
struct disjunction_impl;
template<>
struct disjunction_impl<> {
using type = false_type;
};
template<class V>
struct disjunction_impl<V> {
using type = V;
};
template<class V1, class... Vs>
struct disjunction_impl<V1, Vs...> {
using type = logic_if<V1, V1, typename disjunction_impl<Vs...>::type>;
};
} // namespace detail
/// Disjunction of metavalues Vs with short-circuiting and type preservation.
template<class... Vs>
using disjunction = typename detail::disjunction_impl<Vs...>::type;
/// Disjunction of metavalues Vs with short-circuiting and type preservation.
template<class... Vs>
constexpr auto disjunction_v = disjunction<Vs...>::value;
} // namespace mp

View file

@ -1,16 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <type_traits>
namespace mp {
/// Lifts a value into a type (a metavalue)
template<auto V>
using lift_value = std::integral_constant<decltype(V), V>;
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/value.h>
namespace mp {
/// Logical conjunction of metavalues Vs without short-circuiting or type presevation.
template<class... Vs>
using logic_and = bool_value<(true && ... && Vs::value)>;
/// Logical conjunction of metavalues Vs without short-circuiting or type presevation.
template<class... Vs>
constexpr bool logic_and_v = (true && ... && Vs::value);
} // namespace mp

View file

@ -1,21 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <type_traits>
#include <mp/metavalue/value.h>
namespace mp {
/// Conditionally select between types T and F based on boolean metavalue V
template<class V, class T, class F>
using logic_if = std::conditional_t<bool(V::value), T, F>;
/// Conditionally select between metavalues T and F based on boolean metavalue V
template<class V, class TV, class FV>
constexpr auto logic_if_v = logic_if<V, TV, FV>::value;
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/value.h>
namespace mp {
/// Logical negation of metavalue V.
template<class V>
using logic_not = bool_value<!bool(V::value)>;
/// Logical negation of metavalue V.
template<class V>
constexpr bool logic_not_v = !bool(V::value);
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/value.h>
namespace mp {
/// Logical disjunction of metavalues Vs without short-circuiting or type presevation.
template<class... Vs>
using logic_or = bool_value<(false || ... || Vs::value)>;
/// Logical disjunction of metavalues Vs without short-circuiting or type presevation.
template<class... Vs>
constexpr bool logic_or_v = (false || ... || Vs::value);
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/lift_value.h>
namespace mp {
/// Product of metavalues Vs
template<class... Vs>
using product = lift_value<(Vs::value * ...)>;
/// Product of metavalues Vs
template<class... Vs>
constexpr auto product_v = (Vs::value * ...);
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/lift_value.h>
namespace mp {
/// Sum of metavalues Vs
template<class... Vs>
using sum = lift_value<(Vs::value + ...)>;
/// Sum of metavalues Vs
template<class... Vs>
constexpr auto sum_v = (Vs::value + ...);
} // namespace mp

View file

@ -1,31 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <cstddef>
#include <type_traits>
namespace mp {
/// A metavalue (of type VT and value v).
template<class VT, VT v>
using value = std::integral_constant<VT, v>;
/// A metavalue of type std::size_t (and value v).
template<std::size_t v>
using size_value = value<std::size_t, v>;
/// A metavalue of type bool (and value v). (Aliases to std::bool_constant.)
template<bool v>
using bool_value = value<bool, v>;
/// true metavalue (Aliases to std::true_type).
using true_type = bool_value<true>;
/// false metavalue (Aliases to std::false_type).
using false_type = bool_value<false>;
} // namespace mp

View file

@ -1,16 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <type_traits>
namespace mp {
/// Casts a metavalue from one type to another
template<class T, class V>
using value_cast = std::integral_constant<T, static_cast<T>(V::value)>;
} // namespace mp

View file

@ -1,16 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <type_traits>
namespace mp {
/// Do two metavalues contain the same value?
template<class V1, class V2>
using value_equal = std::bool_constant<V1::value == V2::value>;
} // namespace mp

View file

@ -1,20 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/lift_value.h>
namespace mp {
/// Metafunction that returns the number of arguments it has
template<typename... Ts>
using argument_count = lift_value<sizeof...(Ts)>;
/// Metafunction that returns the number of arguments it has
template<typename... Ts>
constexpr auto argument_count_v = sizeof...(Ts);
} // namespace mp

View file

@ -1,71 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <cstddef>
#include <tuple>
#include <mp/typelist/list.h>
namespace mp {
template<class F>
struct function_info : function_info<decltype(&F::operator())> {};
template<class R, class... As>
struct function_info<R(As...)> {
using return_type = R;
using parameter_list = list<As...>;
static constexpr std::size_t parameter_count = sizeof...(As);
using equivalent_function_type = R(As...);
template<std::size_t I>
struct parameter {
static_assert(I < parameter_count, "Non-existent parameter");
using type = std::tuple_element_t<I, std::tuple<As...>>;
};
};
template<class R, class... As>
struct function_info<R(*)(As...)> : function_info<R(As...)> {};
template<class C, class R, class... As>
struct function_info<R(C::*)(As...)> : function_info<R(As...)> {
using class_type = C;
using equivalent_function_type_with_class = R(C*, As...);
};
template<class C, class R, class... As>
struct function_info<R(C::*)(As...) const> : function_info<R(As...)> {
using class_type = C;
using equivalent_function_type_with_class = R(C*, As...);
};
template<class F>
constexpr size_t parameter_count_v = function_info<F>::parameter_count;
template<class F>
using parameter_list = typename function_info<F>::parameter_list;
template<class F, std::size_t I>
using get_parameter = typename function_info<F>::template parameter<I>::type;
template<class F>
using equivalent_function_type = typename function_info<F>::equivalent_function_type;
template<class F>
using equivalent_function_type_with_class = typename function_info<F>::equivalent_function_type_with_class;
template<class F>
using return_type = typename function_info<F>::return_type;
template<class F>
using class_type = typename function_info<F>::class_type;
} // namespace mp

View file

@ -1,50 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2018 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <cstddef>
#include <cstdint>
namespace mp {
namespace detail {
template<std::size_t size>
struct integer_of_size_impl{};
template<>
struct integer_of_size_impl<8> {
using unsigned_type = std::uint8_t;
using signed_type = std::int8_t;
};
template<>
struct integer_of_size_impl<16> {
using unsigned_type = std::uint16_t;
using signed_type = std::int16_t;
};
template<>
struct integer_of_size_impl<32> {
using unsigned_type = std::uint32_t;
using signed_type = std::int32_t;
};
template<>
struct integer_of_size_impl<64> {
using unsigned_type = std::uint64_t;
using signed_type = std::int64_t;
};
} // namespace detail
template<std::size_t size>
using unsigned_integer_of_size = typename detail::integer_of_size_impl<size>::unsigned_type;
template<std::size_t size>
using signed_integer_of_size = typename detail::integer_of_size_impl<size>::signed_type;
} // namespace mp

View file

@ -1,23 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/value.h>
namespace mp {
/// Is type T an instance of template class C?
template <template <class...> class, class>
struct is_instance_of_template : false_type {};
template <template <class...> class C, class... As>
struct is_instance_of_template<C, C<As...>> : true_type {};
/// Is type T an instance of template class C?
template<template <class...> class C, class T>
constexpr bool is_instance_of_template_v = is_instance_of_template<C, T>::value;
} // namespace mp

View file

@ -1,26 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
namespace detail {
template<class... L>
struct append_impl;
template<template<class...> class LT, class... E1s, class... E2s>
struct append_impl<LT<E1s...>, E2s...> {
using type = LT<E1s..., E2s...>;
};
} // namespace detail
/// Append items E to list L
template<class L, class... Es>
using append = typename detail::append_impl<L, Es...>::type;
} // namespace mp

View file

@ -1,50 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2018 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metafunction/bind.h>
#include <mp/metafunction/map.h>
#include <mp/typelist/append.h>
#include <mp/typelist/concat.h>
#include <mp/typelist/list.h>
namespace mp {
namespace detail {
template<class... Ls>
struct cartesian_product_impl;
template<class RL>
struct cartesian_product_impl<RL> {
using type = RL;
};
template<template<class...> class LT, class... REs, class... E2s>
struct cartesian_product_impl<LT<REs...>, LT<E2s...>> {
using type = concat<
map<MM_MP_BIND(append, REs), list<E2s...>>...
>;
};
template<class RL, class L2, class L3, class... Ls>
struct cartesian_product_impl<RL, L2, L3, Ls...> {
using type = typename cartesian_product_impl<
typename cartesian_product_impl<RL, L2>::type,
L3,
Ls...
>::type;
};
} // namespace detail
/// Produces the cartesian product of a set of lists
/// For example:
/// cartesian_product<list<A, B>, list<D, E>> == list<list<A, D>, list<A, E>, list<B, D>, list<B, E>
template<typename L1, typename... Ls>
using cartesian_product = typename detail::cartesian_product_impl<map<list, L1>, Ls...>::type;
} // namespace mp

View file

@ -1,56 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/typelist/list.h>
namespace mp {
namespace detail {
template<class... Ls>
struct concat_impl;
template<>
struct concat_impl<> {
using type = list<>;
};
template<class L>
struct concat_impl<L> {
using type = L;
};
template<template<class...> class LT, class... E1s, class... E2s, class... Ls>
struct concat_impl<LT<E1s...>, LT<E2s...>, Ls...> {
using type = typename concat_impl<LT<E1s..., E2s...>, Ls...>::type;
};
template<template<class...> class LT,
class... E1s, class... E2s, class... E3s, class... E4s, class... E5s, class... E6s, class... E7s, class... E8s,
class... E9s, class... E10s, class... E11s, class... E12s, class... E13s, class... E14s, class... E15s, class... E16s,
class... Ls>
struct concat_impl<
LT<E1s...>, LT<E2s...>, LT<E3s...>, LT<E4s...>, LT<E5s...>, LT<E6s...>, LT<E7s...>, LT<E8s...>,
LT<E9s...>, LT<E10s...>, LT<E11s...>, LT<E12s...>, LT<E13s...>, LT<E14s...>, LT<E15s...>, LT<E16s...>,
Ls...>
{
using type = typename concat_impl<
LT<
E1s..., E2s..., E3s..., E4s..., E5s..., E6s..., E7s..., E8s...,
E9s..., E10s..., E11s..., E12s..., E13s..., E14s..., E15s..., E16s...
>,
Ls...
>::type;
};
} // namespace detail
/// Concatenate lists together
template<class... Ls>
using concat = typename detail::concat_impl<Ls...>::type;
} // namespace mp

View file

@ -1,25 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metavalue/value.h>
namespace mp {
/// Does list L contain an element which is same as type T?
template<class L, class T>
struct contains;
template<template<class...> class LT, class... Ts, class T>
struct contains<LT<Ts...>, T>
: bool_value<(false || ... || std::is_same_v<Ts, T>)>
{};
/// Does list L contain an element which is same as type T?
template<class L, class T>
constexpr bool contains_v = contains<L, T>::value;
} // namespace mp

View file

@ -1,34 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <cstddef>
#include <type_traits>
namespace mp {
namespace detail {
template<size_t N, class L>
struct drop_impl;
template<size_t N, template<class...> class LT>
struct drop_impl<N, LT<>> {
using type = LT<>;
};
template<size_t N, template<class...> class LT, class E1, class... Es>
struct drop_impl<N, LT<E1, Es...>> {
using type = std::conditional_t<N == 0, LT<E1, Es...>, typename drop_impl<N - 1, LT<Es...>>::type>;
};
} // namespace detail
/// Drops the first N elements of list L
template<std::size_t N, class L>
using drop = typename detail::drop_impl<N, L>::type;
} // namespace mp

View file

@ -1,19 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <cstddef>
#include <tuple>
#include <mp/metafunction/apply.h>
namespace mp {
/// Get element I from list L
template<std::size_t I, class L>
using get = std::tuple_element_t<I, apply<std::tuple, L>>;
} // namespace mp

View file

@ -1,26 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
namespace detail {
template<class L>
struct head_impl;
template<template<class...> class LT, class E1, class... Es>
struct head_impl<LT<E1, Es...>> {
using type = E1;
};
} // namespace detail
/// Gets the tail/cdr/all-but-the-first-element of list L
template<class L>
using head = typename detail::head_impl<L>::type;
} // namespace mp

View file

@ -1,21 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mp/metafunction/apply.h>
#include <mp/misc/argument_count.h>
namespace mp {
/// Length of list L
template<class L>
using length = apply<argument_count, L>;
/// Length of list L
template<class L>
constexpr auto length_v = length<L>::value;
} // namespace mp

View file

@ -1,30 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <type_traits>
#include <mp/typelist/list.h>
namespace mp {
namespace detail {
template<class VL>
struct lift_sequence_impl;
template<class T, template <class, T...> class VLT, T... values>
struct lift_sequence_impl<VLT<T, values...>> {
using type = list<std::integral_constant<T, values>...>;
};
} // namespace detail
/// Lifts values in value list VL to create a type list.
template<class VL>
using lift_sequence = typename detail::lift_sequence_impl<VL>::type;
} // namespace mp

View file

@ -1,14 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
/// Contains a list of types
template<class... E>
struct list {};
} // namespace mp

View file

@ -1,25 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <tuple>
namespace mp {
/// Converts a list of metavalues to a tuple.
template<class L>
struct lower_to_tuple;
template<template<class...> class LT, class... Es>
struct lower_to_tuple<LT<Es...>> {
static constexpr auto value = std::make_tuple(static_cast<typename Es::value_type>(Es::value)...);
};
/// Converts a list of metavalues to a tuple.
template<class L>
constexpr auto lower_to_tuple_v = lower_to_tuple<L>::value;
} // namespace mp

View file

@ -1,26 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
namespace detail {
template<class... L>
struct prepend_impl;
template<template<class...> class LT, class... E1s, class... E2s>
struct prepend_impl<LT<E1s...>, E2s...> {
using type = LT<E2s..., E1s...>;
};
} // namespace detail
/// Prepend items E to list L
template<class L, class... Es>
using prepend = typename detail::prepend_impl<L, Es...>::type;
} // namespace mp

View file

@ -1,26 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2017 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
namespace mp {
namespace detail {
template<class L>
struct tail_impl;
template<template<class...> class LT, class E1, class... Es>
struct tail_impl<LT<E1, Es...>> {
using type = LT<Es...>;
};
} // namespace detail
/// Gets the first type of list L
template<class L>
using tail = typename detail::tail_impl<L>::type;
} // namespace mp

View file

@ -1,12 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#include "metavalue_tests.h"
#include "traits_tests.h"
#include "typelist_tests.h"
int main() {
return 0;
}

View file

@ -1,93 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <type_traits>
#include <mp/metavalue/bit_and.h>
#include <mp/metavalue/bit_not.h>
#include <mp/metavalue/bit_or.h>
#include <mp/metavalue/bit_xor.h>
#include <mp/metavalue/conjunction.h>
#include <mp/metavalue/disjunction.h>
#include <mp/metavalue/lift_value.h>
#include <mp/metavalue/logic_and.h>
#include <mp/metavalue/logic_not.h>
#include <mp/metavalue/logic_or.h>
#include <mp/metavalue/product.h>
#include <mp/metavalue/sum.h>
#include <mp/metavalue/value.h>
#include <mp/metavalue/value_cast.h>
#include <mp/metavalue/value_equal.h>
using namespace mp;
// bit_and
static_assert(bit_and<lift_value<3>, lift_value<1>>::value == 1);
// bit_not
static_assert(bit_not<lift_value<0>>::value == ~0);
// bit_or
static_assert(bit_or<lift_value<1>, lift_value<3>>::value == 3);
// bit_xor
static_assert(bit_xor<lift_value<1>, lift_value<3>>::value == 2);
// conjunction
static_assert(std::is_same_v<conjunction<std::true_type>, std::true_type>);
static_assert(std::is_same_v<conjunction<std::true_type, lift_value<0>>, lift_value<0>>);
static_assert(std::is_same_v<conjunction<std::true_type, lift_value<42>, std::true_type>, std::true_type>);
// disjunction
static_assert(std::is_same_v<disjunction<std::true_type>, std::true_type>);
static_assert(std::is_same_v<disjunction<std::false_type, lift_value<0>>, lift_value<0>>);
static_assert(std::is_same_v<disjunction<std::false_type, lift_value<42>, std::true_type>, lift_value<42>>);
// lift_value
static_assert(std::is_same_v<lift_value<3>, std::integral_constant<int, 3>>);
static_assert(std::is_same_v<lift_value<false>, std::false_type>);
// logic_and
static_assert(std::is_same_v<logic_and<>, std::true_type>);
static_assert(std::is_same_v<logic_and<std::true_type>, std::true_type>);
static_assert(std::is_same_v<logic_and<lift_value<1>>, std::true_type>);
static_assert(std::is_same_v<logic_and<std::true_type, std::false_type>, std::false_type>);
// logic_not
static_assert(std::is_same_v<logic_not<std::false_type>, std::true_type>);
// logic_or
static_assert(std::is_same_v<logic_or<>, std::false_type>);
static_assert(std::is_same_v<logic_or<std::true_type>, std::true_type>);
static_assert(std::is_same_v<logic_or<lift_value<0>>, std::false_type>);
static_assert(std::is_same_v<logic_or<std::true_type, std::false_type>, std::true_type>);
// product
static_assert(product<lift_value<1>, lift_value<2>, lift_value<3>, lift_value<4>>::value == 24);
// sum
static_assert(sum<lift_value<1>, lift_value<2>, lift_value<3>, lift_value<4>>::value == 10);
// value_cast
static_assert(std::is_same_v<value_cast<int, std::true_type>, std::integral_constant<int, 1>>);
// value_equal
static_assert(std::is_same_v<value_equal<std::true_type, std::integral_constant<int, 1>>, std::true_type>);

View file

@ -1,42 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <tuple>
#include <type_traits>
#include <mp/traits/function_info.h>
#include <mp/traits/is_instance_of_template.h>
using namespace mp;
// function_info
struct Bar {
int frob(double a) { return a; }
};
static_assert(parameter_count_v<void()> == 0);
static_assert(parameter_count_v<void(int, int, int)> == 3);
static_assert(std::is_same_v<get_parameter<void(*)(bool, int, double), 2>, double>);
static_assert(std::is_same_v<equivalent_function_type<void(*)(bool, int, double)>, void(bool, int, double)>);
static_assert(std::is_same_v<return_type<void(*)(bool, int, double)>, void>);
static_assert(std::is_same_v<equivalent_function_type<decltype(&Bar::frob)>, int(double)>);
static_assert(std::is_same_v<class_type<decltype(&Bar::frob)>, Bar>);
// is_instance_of_template
template<class, class...>
class Foo {};
template<class, class>
class Pair {};
static_assert(is_instance_of_template_v<std::tuple, std::tuple<int, bool>>);
static_assert(!is_instance_of_template_v<std::tuple, bool>);
static_assert(is_instance_of_template_v<Foo, Foo<bool>>);
static_assert(is_instance_of_template_v<Pair, Pair<bool, int>>);
static_assert(!is_instance_of_template_v<Pair, Foo<bool, int>>);

View file

@ -1,113 +0,0 @@
/* This file is part of the mp project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>
#include <mp/metavalue/value.h>
#include <mp/typelist/append.h>
#include <mp/typelist/cartesian_product.h>
#include <mp/typelist/concat.h>
#include <mp/typelist/contains.h>
#include <mp/typelist/drop.h>
#include <mp/typelist/get.h>
#include <mp/typelist/head.h>
#include <mp/typelist/length.h>
#include <mp/typelist/lift_sequence.h>
#include <mp/typelist/list.h>
#include <mp/typelist/lower_to_tuple.h>
#include <mp/typelist/prepend.h>
#include <mp/typelist/tail.h>
using namespace mp;
// append
static_assert(std::is_same_v<append<list<int, bool>, double>, list<int, bool, double>>);
static_assert(std::is_same_v<append<list<>, int, int>, list<int, int>>);
// cartesian_product
static_assert(
std::is_same_v<
cartesian_product<list<int, bool>, list<double, float>, list<char, unsigned>>,
list<
list<int, double, char>,
list<int, double, unsigned>,
list<int, float, char>,
list<int, float, unsigned>,
list<bool, double, char>,
list<bool, double, unsigned>,
list<bool, float, char>,
list<bool, float, unsigned>
>
>
);
// concat
static_assert(std::is_same_v<concat<list<int, bool>, list<double>>, list<int, bool, double>>);
static_assert(std::is_same_v<concat<list<>, list<int>, list<int>>, list<int, int>>);
// contains
static_assert(contains_v<list<int>, int>);
static_assert(!contains_v<list<>, int>);
static_assert(!contains_v<list<double>, int>);
static_assert(contains_v<list<double, int>, int>);
// drop
static_assert(std::is_same_v<list<>, drop<3, list<int, int>>>);
static_assert(std::is_same_v<list<>, drop<3, list<int, int, int>>>);
static_assert(std::is_same_v<list<int>, drop<3, list<int, int, int, int>>>);
static_assert(std::is_same_v<list<double>, drop<3, list<int, int, int, double>>>);
static_assert(std::is_same_v<list<int, double, bool>, drop<0, list<int, double, bool>>>);
// get
static_assert(std::is_same_v<get<0, list<int, double>>, int>);
static_assert(std::is_same_v<get<1, list<int, double>>, double>);
// head
static_assert(std::is_same_v<head<list<int, double>>, int>);
static_assert(std::is_same_v<head<list<int>>, int>);
// length
static_assert(length_v<list<>> == 0);
static_assert(length_v<list<int>> == 1);
static_assert(length_v<list<int, int, int>> == 3);
// lift_sequence
static_assert(
std::is_same_v<
lift_sequence<std::make_index_sequence<3>>,
list<size_value<0>, size_value<1>, size_value<2>>
>
);
// lower_to_tuple
static_assert(lower_to_tuple_v<list<size_value<0>, size_value<1>, size_value<2>>> == std::tuple<std::size_t, std::size_t, std::size_t>(0, 1, 2));
static_assert(lower_to_tuple_v<list<std::true_type, std::false_type>> == std::make_tuple(true, false));
// prepend
static_assert(std::is_same_v<prepend<list<int, int>, double>, list<double, int, int>>);
static_assert(std::is_same_v<prepend<list<>, double>, list<double>>);
static_assert(std::is_same_v<prepend<list<int>, double, bool>, list<double, bool, int>>);
// tail
static_assert(std::is_same_v<tail<list<int, double>>, list<double>>);
static_assert(std::is_same_v<tail<list<int>>, list<>>);

View file

@ -388,7 +388,7 @@ target_link_libraries(dynarmic
PRIVATE PRIVATE
$<BUILD_INTERFACE:boost> $<BUILD_INTERFACE:boost>
$<BUILD_INTERFACE:fmt::fmt> $<BUILD_INTERFACE:fmt::fmt>
$<BUILD_INTERFACE:mp> $<BUILD_INTERFACE:merry::mcl>
tsl::robin_map tsl::robin_map
$<BUILD_INTERFACE:xbyak> $<BUILD_INTERFACE:xbyak>
$<BUILD_INTERFACE:Zydis> $<BUILD_INTERFACE:Zydis>
@ -401,7 +401,7 @@ if (DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT)
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1) target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
endif() endif()
if (DYNARMIC_IGNORE_ASSERTS) if (DYNARMIC_IGNORE_ASSERTS)
target_compile_definitions(dynarmic PRIVATE DYNARMIC_IGNORE_ASSERTS=1) target_compile_definitions(dynarmic PRIVATE MCL_IGNORE_ASSERTS=1)
endif() endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Windows") if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0) target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)

View file

@ -10,7 +10,7 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <fmt/ostream.h> #include <fmt/ostream.h>
#include <mp/traits/integer_of_size.h> #include <mcl/type_traits/integer_of_size.hpp>
#include <xbyak/xbyak.h> #include <xbyak/xbyak.h>
#include "dynarmic/backend/x64/a32_emit_x64.h" #include "dynarmic/backend/x64/a32_emit_x64.h"

View file

@ -7,7 +7,7 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <fmt/ostream.h> #include <fmt/ostream.h>
#include <mp/traits/integer_of_size.h> #include <mcl/type_traits/integer_of_size.hpp>
#include "dynarmic/backend/x64/a64_jitstate.h" #include "dynarmic/backend/x64/a64_jitstate.h"
#include "dynarmic/backend/x64/abi.h" #include "dynarmic/backend/x64/abi.h"

View file

@ -10,7 +10,7 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <fmt/ostream.h> #include <fmt/ostream.h>
#include <mp/traits/integer_of_size.h> #include <mcl/type_traits/integer_of_size.hpp>
#include <xbyak/xbyak.h> #include <xbyak/xbyak.h>
#include "dynarmic/backend/x64/a64_emit_x64.h" #include "dynarmic/backend/x64/a64_emit_x64.h"

View file

@ -8,7 +8,7 @@
#include <cstring> #include <cstring>
#include <utility> #include <utility>
#include <mp/traits/function_info.h> #include <mcl/type_traits/function_info.hpp>
#include "dynarmic/backend/x64/callback.h" #include "dynarmic/backend/x64/callback.h"
#include "dynarmic/common/cast_util.h" #include "dynarmic/common/cast_util.h"
@ -32,18 +32,18 @@ struct ThunkBuilder<R (C::*)(Args...), mfp> {
} // namespace impl } // namespace impl
template<auto mfp> template<auto mfp>
ArgCallback DevirtualizeGeneric(mp::class_type<decltype(mfp)>* this_) { ArgCallback DevirtualizeGeneric(mcl::class_type<decltype(mfp)>* this_) {
return ArgCallback{&impl::ThunkBuilder<decltype(mfp), mfp>::Thunk, reinterpret_cast<u64>(this_)}; return ArgCallback{&impl::ThunkBuilder<decltype(mfp), mfp>::Thunk, reinterpret_cast<u64>(this_)};
} }
template<auto mfp> template<auto mfp>
ArgCallback DevirtualizeWindows(mp::class_type<decltype(mfp)>* this_) { ArgCallback DevirtualizeWindows(mcl::class_type<decltype(mfp)>* this_) {
static_assert(sizeof(mfp) == 8); static_assert(sizeof(mfp) == 8);
return ArgCallback{Common::BitCast<u64>(mfp), reinterpret_cast<u64>(this_)}; return ArgCallback{Common::BitCast<u64>(mfp), reinterpret_cast<u64>(this_)};
} }
template<auto mfp> template<auto mfp>
ArgCallback DevirtualizeItanium(mp::class_type<decltype(mfp)>* this_) { ArgCallback DevirtualizeItanium(mcl::class_type<decltype(mfp)>* this_) {
struct MemberFunctionPointer { struct MemberFunctionPointer {
/// For a non-virtual function, this is a simple function pointer. /// For a non-virtual function, this is a simple function pointer.
/// For a virtual function, it is (1 + virtual table offset in bytes). /// For a virtual function, it is (1 + virtual table offset in bytes).
@ -65,7 +65,7 @@ ArgCallback DevirtualizeItanium(mp::class_type<decltype(mfp)>* this_) {
} }
template<auto mfp> template<auto mfp>
ArgCallback Devirtualize(mp::class_type<decltype(mfp)>* this_) { ArgCallback Devirtualize(mcl::class_type<decltype(mfp)>* this_) {
#if defined(__APPLE__) || defined(linux) || defined(__linux) || defined(__linux__) #if defined(__APPLE__) || defined(linux) || defined(__linux) || defined(__linux__)
return DevirtualizeItanium<mfp>(this_); return DevirtualizeItanium<mfp>(this_);
#elif defined(__MINGW64__) #elif defined(__MINGW64__)

View file

@ -7,12 +7,12 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <mp/metavalue/lift_value.h> #include <mcl/mp/metavalue/lift_value.hpp>
#include <mp/traits/integer_of_size.h> #include <mcl/mp/typelist/cartesian_product.hpp>
#include <mp/typelist/cartesian_product.h> #include <mcl/mp/typelist/lift_sequence.hpp>
#include <mp/typelist/lift_sequence.h> #include <mcl/mp/typelist/list.hpp>
#include <mp/typelist/list.h> #include <mcl/mp/typelist/lower_to_tuple.hpp>
#include <mp/typelist/lower_to_tuple.h> #include <mcl/type_traits/integer_of_size.hpp>
#include "dynarmic/backend/x64/abi.h" #include "dynarmic/backend/x64/abi.h"
#include "dynarmic/backend/x64/block_of_code.h" #include "dynarmic/backend/x64/block_of_code.h"
@ -34,6 +34,7 @@
namespace Dynarmic::Backend::X64 { namespace Dynarmic::Backend::X64 {
using namespace Xbyak::util; using namespace Xbyak::util;
namespace mp = mcl::mp;
namespace { namespace {
@ -173,7 +174,7 @@ void PostProcessNaN(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm tmp) {
// We allow for the case where op1 and result are the same register. We do not read from op1 once result is written to. // We allow for the case where op1 and result are the same register. We do not read from op1 once result is written to.
template<size_t fsize> template<size_t fsize>
void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, Xbyak::Xmm op2, Xbyak::Reg64 tmp, Xbyak::Label end) { void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, Xbyak::Xmm op2, Xbyak::Reg64 tmp, Xbyak::Label end) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
constexpr FPT exponent_mask = FP::FPInfo<FPT>::exponent_mask; constexpr FPT exponent_mask = FP::FPInfo<FPT>::exponent_mask;
constexpr FPT mantissa_msb = FP::FPInfo<FPT>::mantissa_msb; constexpr FPT mantissa_msb = FP::FPInfo<FPT>::mantissa_msb;
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1); constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
@ -267,7 +268,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
template<size_t fsize, typename Function> template<size_t fsize, typename Function>
void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) { void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -324,7 +325,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn)
template<size_t fsize> template<size_t fsize>
void FPAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { void FPAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u); constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -350,7 +351,7 @@ void EmitX64::EmitFPAbs64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
void FPNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { void FPNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask; constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -440,7 +441,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize, bool is_max> template<size_t fsize, bool is_max>
static void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
constexpr FPT default_nan = FP::FPInfo<FPT>::DefaultNaN(); constexpr FPT default_nan = FP::FPInfo<FPT>::DefaultNaN();
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1); constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
@ -592,7 +593,7 @@ void EmitX64::EmitFPMul64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -697,7 +698,7 @@ void EmitX64::EmitFPMulAdd64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -755,7 +756,7 @@ void EmitX64::EmitFPMulX64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
if constexpr (fsize != 16) { if constexpr (fsize != 16) {
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) { if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
@ -801,7 +802,7 @@ void EmitX64::EmitFPRecipEstimate64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ctx.reg_alloc.HostCall(inst, args[0]); ctx.reg_alloc.HostCall(inst, args[0]);
@ -824,7 +825,7 @@ void EmitX64::EmitFPRecipExponent64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -949,7 +950,7 @@ static void EmitFPRound(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, siz
constexpr size_t fsize = std::get<0>(t); constexpr size_t fsize = std::get<0>(t);
constexpr FP::RoundingMode rounding_mode = std::get<1>(t); constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
constexpr bool exact = std::get<2>(t); constexpr bool exact = std::get<2>(t);
using InputSize = mp::unsigned_integer_of_size<fsize>; using InputSize = mcl::unsigned_integer_of_size<fsize>;
return FP::FPRoundInt<InputSize>(static_cast<InputSize>(input), fpcr, rounding_mode, exact, fpsr); return FP::FPRoundInt<InputSize>(static_cast<InputSize>(input), fpcr, rounding_mode, exact, fpsr);
})}; })};
@ -977,7 +978,7 @@ void EmitX64::EmitFPRoundInt64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
if constexpr (fsize != 16) { if constexpr (fsize != 16) {
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) { if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
@ -1156,7 +1157,7 @@ void EmitX64::EmitFPRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -1589,7 +1590,7 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
constexpr auto t = mp::lower_to_tuple_v<decltype(args)>; constexpr auto t = mp::lower_to_tuple_v<decltype(args)>;
constexpr size_t fbits = std::get<0>(t); constexpr size_t fbits = std::get<0>(t);
constexpr FP::RoundingMode rounding_mode = std::get<1>(t); constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
return FP::FPToFixed<FPT>(isize, static_cast<FPT>(input), fbits, unsigned_, fpcr, rounding_mode, fpsr); return FP::FPToFixed<FPT>(isize, static_cast<FPT>(input), fbits, unsigned_, fpcr, rounding_mode, fpsr);
})}; })};

View file

@ -210,7 +210,7 @@ void AxxEmitX64::EmitExclusiveReadMemory(AxxEmitContext& ctx, IR::Inst* inst) {
const bool ordered = IsOrdered(args[1].GetImmediateAccType()); const bool ordered = IsOrdered(args[1].GetImmediateAccType());
if constexpr (bitsize != 128) { if constexpr (bitsize != 128) {
using T = mp::unsigned_integer_of_size<bitsize>; using T = mcl::unsigned_integer_of_size<bitsize>;
ctx.reg_alloc.HostCall(inst, {}, args[0]); ctx.reg_alloc.HostCall(inst, {}, args[0]);
@ -275,7 +275,7 @@ void AxxEmitX64::EmitExclusiveWriteMemory(AxxEmitContext& ctx, IR::Inst* inst) {
code.mov(code.byte[r15 + offsetof(AxxJitState, exclusive_state)], u8(0)); code.mov(code.byte[r15 + offsetof(AxxJitState, exclusive_state)], u8(0));
code.mov(code.ABI_PARAM1, reinterpret_cast<u64>(&conf)); code.mov(code.ABI_PARAM1, reinterpret_cast<u64>(&conf));
if constexpr (bitsize != 128) { if constexpr (bitsize != 128) {
using T = mp::unsigned_integer_of_size<bitsize>; using T = mcl::unsigned_integer_of_size<bitsize>;
code.CallLambda( code.CallLambda(
[](AxxUserConfig& conf, Axx::VAddr vaddr, T value) -> u32 { [](AxxUserConfig& conf, Axx::VAddr vaddr, T value) -> u32 {

View file

@ -5,7 +5,7 @@
#include <limits> #include <limits>
#include <mp/traits/integer_of_size.h> #include <mcl/type_traits/integer_of_size.hpp>
#include "dynarmic/backend/x64/block_of_code.h" #include "dynarmic/backend/x64/block_of_code.h"
#include "dynarmic/backend/x64/emit_x64.h" #include "dynarmic/backend/x64/emit_x64.h"
@ -37,7 +37,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
Xbyak::Reg addend = ctx.reg_alloc.UseGpr(args[1]).changeBit(size); Xbyak::Reg addend = ctx.reg_alloc.UseGpr(args[1]).changeBit(size);
Xbyak::Reg overflow = ctx.reg_alloc.ScratchGpr().changeBit(size); Xbyak::Reg overflow = ctx.reg_alloc.ScratchGpr().changeBit(size);
constexpr u64 int_max = static_cast<u64>(std::numeric_limits<mp::signed_integer_of_size<size>>::max()); constexpr u64 int_max = static_cast<u64>(std::numeric_limits<mcl::signed_integer_of_size<size>>::max());
if constexpr (size < 64) { if constexpr (size < 64) {
code.xor_(overflow.cvt32(), overflow.cvt32()); code.xor_(overflow.cvt32(), overflow.cvt32());
code.bt(result.cvt32(), size - 1); code.bt(result.cvt32(), size - 1);
@ -81,7 +81,7 @@ void EmitUnsignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst
Xbyak::Reg op_result = ctx.reg_alloc.UseScratchGpr(args[0]).changeBit(size); Xbyak::Reg op_result = ctx.reg_alloc.UseScratchGpr(args[0]).changeBit(size);
Xbyak::Reg addend = ctx.reg_alloc.UseScratchGpr(args[1]).changeBit(size); Xbyak::Reg addend = ctx.reg_alloc.UseScratchGpr(args[1]).changeBit(size);
constexpr u64 boundary = op == Op::Add ? std::numeric_limits<mp::unsigned_integer_of_size<size>>::max() : 0; constexpr u64 boundary = op == Op::Add ? std::numeric_limits<mcl::unsigned_integer_of_size<size>>::max() : 0;
if constexpr (op == Op::Add) { if constexpr (op == Op::Add) {
code.add(op_result, addend); code.add(op_result, addend);

View file

@ -8,7 +8,7 @@
#include <cstdlib> #include <cstdlib>
#include <type_traits> #include <type_traits>
#include <mp/traits/function_info.h> #include <mcl/type_traits/function_info.hpp>
#include <xbyak/xbyak.h> #include <xbyak/xbyak.h>
#include "dynarmic/backend/x64/abi.h" #include "dynarmic/backend/x64/abi.h"
@ -53,7 +53,7 @@ static void EmitAVXVectorOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst
template<typename Lambda> template<typename Lambda>
static void EmitOneArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) { static void EmitOneArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda); const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
constexpr u32 stack_space = 2 * 16; constexpr u32 stack_space = 2 * 16;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
@ -76,7 +76,7 @@ static void EmitOneArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Ins
template<typename Lambda> template<typename Lambda>
static void EmitOneArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) { static void EmitOneArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda); const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
constexpr u32 stack_space = 2 * 16; constexpr u32 stack_space = 2 * 16;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
@ -101,7 +101,7 @@ static void EmitOneArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext
template<typename Lambda> template<typename Lambda>
static void EmitTwoArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) { static void EmitTwoArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda); const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
constexpr u32 stack_space = 3 * 16; constexpr u32 stack_space = 3 * 16;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);
@ -129,7 +129,7 @@ static void EmitTwoArgumentFallbackWithSaturation(BlockOfCode& code, EmitContext
template<typename Lambda> template<typename Lambda>
static void EmitTwoArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) { static void EmitTwoArgumentFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda); const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
constexpr u32 stack_space = 3 * 16; constexpr u32 stack_space = 3 * 16;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]); const Xbyak::Xmm arg1 = ctx.reg_alloc.UseXmm(args[0]);

View file

@ -9,13 +9,13 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <mp/metavalue/lift_value.h> #include <mcl/mp/metavalue/lift_value.hpp>
#include <mp/traits/function_info.h> #include <mcl/mp/typelist/cartesian_product.hpp>
#include <mp/traits/integer_of_size.h> #include <mcl/mp/typelist/lift_sequence.hpp>
#include <mp/typelist/cartesian_product.h> #include <mcl/mp/typelist/list.hpp>
#include <mp/typelist/lift_sequence.h> #include <mcl/mp/typelist/lower_to_tuple.hpp>
#include <mp/typelist/list.h> #include <mcl/type_traits/function_info.hpp>
#include <mp/typelist/lower_to_tuple.h> #include <mcl/type_traits/integer_of_size.hpp>
#include "dynarmic/backend/x64/abi.h" #include "dynarmic/backend/x64/abi.h"
#include "dynarmic/backend/x64/block_of_code.h" #include "dynarmic/backend/x64/block_of_code.h"
@ -34,6 +34,7 @@
namespace Dynarmic::Backend::X64 { namespace Dynarmic::Backend::X64 {
using namespace Xbyak::util; using namespace Xbyak::util;
namespace mp = mcl::mp;
namespace { namespace {
@ -70,7 +71,7 @@ void MaybeStandardFPSCRValue(BlockOfCode& code, EmitContext& ctx, bool fpcr_cont
template<size_t fsize, template<typename> class Indexer, size_t narg> template<size_t fsize, template<typename> class Indexer, size_t narg>
struct NaNHandler { struct NaNHandler {
public: public:
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
using function_type = void (*)(std::array<VectorArray<FPT>, narg>&, FP::FPCR); using function_type = void (*)(std::array<VectorArray<FPT>, narg>&, FP::FPCR);
@ -161,26 +162,26 @@ Xbyak::Address GetVectorOf(BlockOfCode& code) {
template<size_t fsize> template<size_t fsize>
Xbyak::Address GetNaNVector(BlockOfCode& code) { Xbyak::Address GetNaNVector(BlockOfCode& code) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
return GetVectorOf<fsize, FP::FPInfo<FPT>::DefaultNaN()>(code); return GetVectorOf<fsize, FP::FPInfo<FPT>::DefaultNaN()>(code);
} }
template<size_t fsize> template<size_t fsize>
Xbyak::Address GetNegativeZeroVector(BlockOfCode& code) { Xbyak::Address GetNegativeZeroVector(BlockOfCode& code) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
return GetVectorOf<fsize, FP::FPInfo<FPT>::Zero(true)>(code); return GetVectorOf<fsize, FP::FPInfo<FPT>::Zero(true)>(code);
} }
template<size_t fsize> template<size_t fsize>
Xbyak::Address GetSmallestNormalVector(BlockOfCode& code) { Xbyak::Address GetSmallestNormalVector(BlockOfCode& code) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
constexpr FPT smallest_normal_number = FP::FPValue<FPT, false, FP::FPInfo<FPT>::exponent_min, 1>(); constexpr FPT smallest_normal_number = FP::FPValue<FPT, false, FP::FPInfo<FPT>::exponent_min, 1>();
return GetVectorOf<fsize, smallest_normal_number>(code); return GetVectorOf<fsize, smallest_normal_number>(code);
} }
template<size_t fsize, bool sign, int exponent, mp::unsigned_integer_of_size<fsize> value> template<size_t fsize, bool sign, int exponent, mcl::unsigned_integer_of_size<fsize> value>
Xbyak::Address GetVectorOf(BlockOfCode& code) { Xbyak::Address GetVectorOf(BlockOfCode& code) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
return GetVectorOf<fsize, FP::FPValue<FPT, sign, exponent, value>()>(code); return GetVectorOf<fsize, FP::FPValue<FPT, sign, exponent, value>()>(code);
} }
@ -413,7 +414,7 @@ void EmitThreeOpVectorOperation(BlockOfCode& code, EmitContext& ctx, IR::Inst* i
template<typename Lambda> template<typename Lambda>
void EmitTwoOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Lambda lambda, bool fpcr_controlled) { void EmitTwoOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Lambda lambda, bool fpcr_controlled) {
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda); const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
const u32 fpcr = ctx.FPCR(fpcr_controlled).Value(); const u32 fpcr = ctx.FPCR(fpcr_controlled).Value();
@ -448,7 +449,7 @@ void EmitTwoOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lamb
template<typename Lambda> template<typename Lambda>
void EmitThreeOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Xbyak::Xmm arg2, Lambda lambda, bool fpcr_controlled) { void EmitThreeOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Xbyak::Xmm arg2, Lambda lambda, bool fpcr_controlled) {
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda); const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
const u32 fpcr = ctx.FPCR(fpcr_controlled).Value(); const u32 fpcr = ctx.FPCR(fpcr_controlled).Value();
@ -502,7 +503,7 @@ void EmitThreeOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, La
template<typename Lambda> template<typename Lambda>
void EmitFourOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Xbyak::Xmm arg2, Xbyak::Xmm arg3, Lambda lambda, bool fpcr_controlled) { void EmitFourOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak::Xmm result, Xbyak::Xmm arg1, Xbyak::Xmm arg2, Xbyak::Xmm arg3, Lambda lambda, bool fpcr_controlled) {
const auto fn = static_cast<mp::equivalent_function_type<Lambda>*>(lambda); const auto fn = static_cast<mcl::equivalent_function_type<Lambda>*>(lambda);
#ifdef _WIN32 #ifdef _WIN32
constexpr u32 stack_space = 5 * 16; constexpr u32 stack_space = 5 * 16;
@ -559,7 +560,7 @@ void EmitFourOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lam
template<size_t fsize> template<size_t fsize>
void FPVectorAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { void FPVectorAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u); constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
constexpr u64 non_sign_mask64 = Common::Replicate<u64>(non_sign_mask, fsize); constexpr u64 non_sign_mask64 = Common::Replicate<u64>(non_sign_mask, fsize);
@ -1065,7 +1066,7 @@ void EmitX64::EmitFPVectorMul64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
void EmitFPVectorMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { void EmitFPVectorMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& addend, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) { const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& addend, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
for (size_t i = 0; i < result.size(); i++) { for (size_t i = 0; i < result.size(); i++) {
@ -1160,7 +1161,7 @@ void EmitX64::EmitFPVectorMulAdd64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitFPVectorMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitFPVectorMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool fpcr_controlled = args[2].GetImmediateU1(); const bool fpcr_controlled = args[2].GetImmediateU1();
@ -1226,7 +1227,7 @@ void EmitX64::EmitFPVectorMulX64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
void FPVectorNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { void FPVectorNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask; constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
constexpr u64 sign_mask64 = Common::Replicate<u64>(sign_mask, fsize); constexpr u64 sign_mask64 = Common::Replicate<u64>(sign_mask, fsize);
@ -1280,7 +1281,7 @@ void EmitX64::EmitFPVectorPairedAddLower64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
if constexpr (fsize != 16) { if constexpr (fsize != 16) {
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) { if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
@ -1326,7 +1327,7 @@ void EmitX64::EmitFPVectorRecipEstimate64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) { const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
for (size_t i = 0; i < result.size(); i++) { for (size_t i = 0; i < result.size(); i++) {
@ -1420,7 +1421,7 @@ void EmitX64::EmitFPVectorRecipStepFused64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { void EmitFPVectorRoundInt(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
const auto rounding = static_cast<FP::RoundingMode>(inst->GetArg(1).GetU8()); const auto rounding = static_cast<FP::RoundingMode>(inst->GetArg(1).GetU8());
const bool exact = inst->GetArg(2).GetU1(); const bool exact = inst->GetArg(2).GetU1();
@ -1492,7 +1493,7 @@ void EmitX64::EmitFPVectorRoundInt64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& operand, FP::FPCR fpcr, FP::FPSR& fpsr) { const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& operand, FP::FPCR fpcr, FP::FPSR& fpsr) {
for (size_t i = 0; i < result.size(); i++) { for (size_t i = 0; i < result.size(); i++) {
@ -1540,7 +1541,7 @@ void EmitX64::EmitFPVectorRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize> template<size_t fsize>
static void EmitRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { static void EmitRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) { const auto fallback_fn = [](VectorArray<FPT>& result, const VectorArray<FPT>& op1, const VectorArray<FPT>& op2, FP::FPCR fpcr, FP::FPSR& fpsr) {
for (size_t i = 0; i < result.size(); i++) { for (size_t i = 0; i < result.size(); i++) {
@ -1709,7 +1710,7 @@ void EmitX64::EmitFPVectorToHalf32(EmitContext& ctx, IR::Inst* inst) {
template<size_t fsize, bool unsigned_> template<size_t fsize, bool unsigned_>
void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
using FPT = mp::unsigned_integer_of_size<fsize>; using FPT = mcl::unsigned_integer_of_size<fsize>;
const size_t fbits = inst->GetArg(1).GetU8(); const size_t fbits = inst->GetArg(1).GetU8();
const auto rounding = static_cast<FP::RoundingMode>(inst->GetArg(2).GetU8()); const auto rounding = static_cast<FP::RoundingMode>(inst->GetArg(2).GetU8());

View file

@ -8,7 +8,7 @@
#include <cstring> #include <cstring>
#include <type_traits> #include <type_traits>
#include <mp/traits/function_info.h> #include <mcl/type_traits/function_info.hpp>
namespace Dynarmic::Common { namespace Dynarmic::Common {
@ -39,7 +39,7 @@ inline Dest BitCastPointee(const SourcePtr source) noexcept {
/// Cast a lambda into an equivalent function pointer. /// Cast a lambda into an equivalent function pointer.
template<class Function> template<class Function>
inline auto FptrCast(Function f) noexcept { inline auto FptrCast(Function f) noexcept {
return static_cast<mp::equivalent_function_type<Function>*>(f); return static_cast<mcl::equivalent_function_type<Function>*>(f);
} }
} // namespace Dynarmic::Common } // namespace Dynarmic::Common

View file

@ -9,26 +9,26 @@
#include <map> #include <map>
#include <type_traits> #include <type_traits>
#include <mp/metafunction/apply.h> #include <mcl/mp/metafunction/apply.hpp>
#include <mp/traits/is_instance_of_template.h> #include <mcl/mp/typelist/list.hpp>
#include <mp/typelist/list.h> #include <mcl/type_traits/is_instance_of_template.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
# include <mp/typelist/head.h> # include <mcl/mp/typelist/head.hpp>
#endif #endif
namespace Dynarmic::Common { namespace Dynarmic::Common {
template<typename Function, typename... Values> template<typename Function, typename... Values>
inline auto GenerateLookupTableFromList(Function f, mp::list<Values...>) { inline auto GenerateLookupTableFromList(Function f, mcl::mp::list<Values...>) {
#ifdef _MSC_VER #ifdef _MSC_VER
using PairT = std::invoke_result_t<Function, mp::head<mp::list<Values...>>>; using PairT = std::invoke_result_t<Function, mcl::mp::head<mcl::mp::list<Values...>>>;
#else #else
using PairT = std::common_type_t<std::invoke_result_t<Function, Values>...>; using PairT = std::common_type_t<std::invoke_result_t<Function, Values>...>;
#endif #endif
using MapT = mp::apply<std::map, PairT>; using MapT = mcl::mp::apply<std::map, PairT>;
static_assert(mp::is_instance_of_template_v<std::pair, PairT>); static_assert(mcl::is_instance_of_template_v<std::pair, PairT>);
const std::initializer_list<PairT> pair_array{f(Values{})...}; const std::initializer_list<PairT> pair_array{f(Values{})...};
return MapT(pair_array.begin(), pair_array.end()); return MapT(pair_array.begin(), pair_array.end());

View file

@ -9,7 +9,7 @@
#include <array> #include <array>
#include <tuple> #include <tuple>
#include <mp/traits/function_info.h> #include <mcl/type_traits/function_info.hpp>
#include "dynarmic/common/assert.h" #include "dynarmic/common/assert.h"
#include "dynarmic/common/bit_util.h" #include "dynarmic/common/bit_util.h"
@ -165,7 +165,7 @@ struct detail {
* Creates a matcher that can match and parse instructions based on bitstring. * Creates a matcher that can match and parse instructions based on bitstring.
* See also: GetMaskAndExpect and GetArgInfo for format of bitstring. * See also: GetMaskAndExpect and GetArgInfo for format of bitstring.
*/ */
template<typename FnT, size_t args_count = mp::parameter_count_v<FnT>> template<typename FnT, size_t args_count = mcl::parameter_count_v<FnT>>
static auto GetMatcher(FnT fn, const char* const name, std::tuple<opcode_type, opcode_type> mask_and_expect, std::tuple<std::array<opcode_type, args_count>, std::array<size_t, args_count>> masks_and_shifts) { static auto GetMatcher(FnT fn, const char* const name, std::tuple<opcode_type, opcode_type> mask_and_expect, std::tuple<std::array<opcode_type, args_count>, std::array<size_t, args_count>> masks_and_shifts) {
using Iota = std::make_index_sequence<args_count>; using Iota = std::make_index_sequence<args_count>;
@ -177,7 +177,7 @@ struct detail {
} }
}; };
#define DYNARMIC_DECODER_GET_MATCHER(MatcherT, fn, name, bitstring) Decoder::detail::detail<MatcherT<V>>::GetMatcher(&V::fn, name, Decoder::detail::detail<MatcherT<V>>::GetMaskAndExpect(bitstring), Decoder::detail::detail<MatcherT<V>>::template GetArgInfo<mp::parameter_count_v<decltype(&V::fn)>>(bitstring)) #define DYNARMIC_DECODER_GET_MATCHER(MatcherT, fn, name, bitstring) Decoder::detail::detail<MatcherT<V>>::GetMatcher(&V::fn, name, Decoder::detail::detail<MatcherT<V>>::GetMaskAndExpect(bitstring), Decoder::detail::detail<MatcherT<V>>::template GetArgInfo<mcl::parameter_count_v<decltype(&V::fn)>>(bitstring))
} // namespace detail } // namespace detail
} // namespace Dynarmic::Decoder } // namespace Dynarmic::Decoder

View file

@ -51,12 +51,12 @@ include(CreateDirectoryGroups)
create_target_directory_groups(dynarmic_tests) create_target_directory_groups(dynarmic_tests)
create_target_directory_groups(dynarmic_print_info) create_target_directory_groups(dynarmic_print_info)
target_link_libraries(dynarmic_tests PRIVATE dynarmic boost catch fmt mp xbyak) target_link_libraries(dynarmic_tests PRIVATE dynarmic boost catch fmt mcl xbyak)
target_include_directories(dynarmic_tests PRIVATE . ../src) target_include_directories(dynarmic_tests PRIVATE . ../src)
target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS}) target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS})
target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1 CATCH_CONFIG_ENABLE_BENCHMARKING=1) target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1 CATCH_CONFIG_ENABLE_BENCHMARKING=1)
target_link_libraries(dynarmic_print_info PRIVATE dynarmic boost catch fmt mp) target_link_libraries(dynarmic_print_info PRIVATE dynarmic boost catch fmt mcl)
target_include_directories(dynarmic_print_info PRIVATE . ../src) target_include_directories(dynarmic_print_info PRIVATE . ../src)
target_compile_options(dynarmic_print_info PRIVATE ${DYNARMIC_CXX_FLAGS}) target_compile_options(dynarmic_print_info PRIVATE ${DYNARMIC_CXX_FLAGS})
target_compile_definitions(dynarmic_print_info PRIVATE FMT_USE_USER_DEFINED_LITERALS=1) target_compile_definitions(dynarmic_print_info PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)