summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/frontend/maxwell/location.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/location.h')
-rw-r--r--src/shader_recompiler/frontend/maxwell/location.h106
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
15namespace Shader::Maxwell {
16
17class Location {
18 static constexpr u32 VIRTUAL_OFFSET{std::numeric_limits<u32>::max()};
19
20public:
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
79private:
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
97template <>
98struct 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};