diff --git a/src/common/math_util.h b/src/common/math_util.h new file mode 100644 index 00000000..eed8c275 --- /dev/null +++ b/src/common/math_util.h @@ -0,0 +1,28 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#pragma once + +#include + +namespace Dynarmic { +namespace Common { + +/** + * This function is a workaround for a bug in MSVC 19.12 where fold expressions + * do not work when the /permissive- flag is enabled. + */ +template +constexpr T Sum(T first, Ts ...rest) { + if constexpr (sizeof...(rest) == 0) { + return first; + } else { + return first + Sum(std::forward(rest)...); + } +} + +} // namespace Common +} // namespace Dynarmic diff --git a/src/frontend/A64/imm.h b/src/frontend/A64/imm.h index edc3d456..609afc5d 100644 --- a/src/frontend/A64/imm.h +++ b/src/frontend/A64/imm.h @@ -9,6 +9,7 @@ #include "common/assert.h" #include "common/bit_util.h" #include "common/common_types.h" +#include "common/math_util.h" namespace Dynarmic { namespace A64 { @@ -85,13 +86,13 @@ bool operator!=(const Imm& a, u32 b) { * This is equivalent to a:b:...:z in ASL. */ template -auto concatenate(Imm first, Imm ...rest) -> Imm<(first_bit_size + ... + rest_bit_sizes)> { +auto concatenate(Imm first, Imm ...rest) { if constexpr (sizeof...(rest) == 0) { return first; } else { const auto concat_rest = concatenate(rest...); const u32 value = (first.ZeroExtend() << concat_rest.bit_size) | concat_rest.ZeroExtend(); - return Imm<(first_bit_size + ... + rest_bit_sizes)>{value}; + return Imm{value}; } }