diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/location.h')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/location.h | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/location.h b/src/shader_recompiler/frontend/maxwell/location.h new file mode 100644 index 000000000..66b51a19e --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/location.h | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <compare> | ||
| 8 | #include <iterator> | ||
| 9 | |||
| 10 | #include <fmt/format.h> | ||
| 11 | |||
| 12 | #include "common/common_types.h" | ||
| 13 | #include "shader_recompiler/exception.h" | ||
| 14 | |||
| 15 | namespace Shader::Maxwell { | ||
| 16 | |||
| 17 | class Location { | ||
| 18 | static constexpr u32 VIRTUAL_OFFSET{std::numeric_limits<u32>::max()}; | ||
| 19 | |||
| 20 | public: | ||
| 21 | constexpr Location() = default; | ||
| 22 | |||
| 23 | constexpr Location(u32 initial_offset) : offset{initial_offset} { | ||
| 24 | if (initial_offset % 8 != 0) { | ||
| 25 | throw InvalidArgument("initial_offset={} is not a multiple of 8", initial_offset); | ||
| 26 | } | ||
| 27 | Align(); | ||
| 28 | } | ||
| 29 | |||
| 30 | [[nodiscard]] constexpr u32 Offset() const noexcept { | ||
| 31 | return offset; | ||
| 32 | } | ||
| 33 | |||
| 34 | [[nodiscard]] constexpr bool IsVirtual() const { | ||
| 35 | return offset == VIRTUAL_OFFSET; | ||
| 36 | } | ||
| 37 | |||
| 38 | constexpr auto operator<=>(const Location&) const noexcept = default; | ||
| 39 | |||
| 40 | constexpr Location operator++() noexcept { | ||
| 41 | const Location copy{*this}; | ||
| 42 | Step(); | ||
| 43 | return copy; | ||
| 44 | } | ||
| 45 | |||
| 46 | constexpr Location operator++(int) noexcept { | ||
| 47 | Step(); | ||
| 48 | return *this; | ||
| 49 | } | ||
| 50 | |||
| 51 | constexpr Location operator--() noexcept { | ||
| 52 | const Location copy{*this}; | ||
| 53 | Back(); | ||
| 54 | return copy; | ||
| 55 | } | ||
| 56 | |||
| 57 | constexpr Location operator--(int) noexcept { | ||
| 58 | Back(); | ||
| 59 | return *this; | ||
| 60 | } | ||
| 61 | |||
| 62 | constexpr Location operator+(int number) const { | ||
| 63 | Location new_pc{*this}; | ||
| 64 | while (number > 0) { | ||
| 65 | --number; | ||
| 66 | ++new_pc; | ||
| 67 | } | ||
| 68 | while (number < 0) { | ||
| 69 | ++number; | ||
| 70 | --new_pc; | ||
| 71 | } | ||
| 72 | return new_pc; | ||
| 73 | } | ||
| 74 | |||
| 75 | constexpr Location operator-(int number) const { | ||
| 76 | return operator+(-number); | ||
| 77 | } | ||
| 78 | |||
| 79 | private: | ||
| 80 | constexpr void Align() { | ||
| 81 | offset += offset % 32 == 0 ? 8 : 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | constexpr void Step() { | ||
| 85 | offset += 8 + (offset % 32 == 24 ? 8 : 0); | ||
| 86 | } | ||
| 87 | |||
| 88 | constexpr void Back() { | ||
| 89 | offset -= 8 + (offset % 32 == 8 ? 8 : 0); | ||
| 90 | } | ||
| 91 | |||
| 92 | u32 offset{VIRTUAL_OFFSET}; | ||
| 93 | }; | ||
| 94 | |||
| 95 | } // namespace Shader::Maxwell | ||
| 96 | |||
| 97 | template <> | ||
| 98 | struct fmt::formatter<Shader::Maxwell::Location> { | ||
| 99 | constexpr auto parse(format_parse_context& ctx) { | ||
| 100 | return ctx.begin(); | ||
| 101 | } | ||
| 102 | template <typename FormatContext> | ||
| 103 | auto format(const Shader::Maxwell::Location& location, FormatContext& ctx) { | ||
| 104 | return fmt::format_to(ctx.out(), "{:04x}", location.Offset()); | ||
| 105 | } | ||
| 106 | }; | ||