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.h112
1 files changed, 112 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..26d29eae2
--- /dev/null
+++ b/src/shader_recompiler/frontend/maxwell/location.h
@@ -0,0 +1,112 @@
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_BIAS{4};
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 constexpr Location Virtual() const noexcept {
31 Location virtual_location;
32 virtual_location.offset = offset - VIRTUAL_BIAS;
33 return virtual_location;
34 }
35
36 [[nodiscard]] constexpr u32 Offset() const noexcept {
37 return offset;
38 }
39
40 [[nodiscard]] constexpr bool IsVirtual() const {
41 return offset % 8 == VIRTUAL_BIAS;
42 }
43
44 constexpr auto operator<=>(const Location&) const noexcept = default;
45
46 constexpr Location operator++() noexcept {
47 const Location copy{*this};
48 Step();
49 return copy;
50 }
51
52 constexpr Location operator++(int) noexcept {
53 Step();
54 return *this;
55 }
56
57 constexpr Location operator--() noexcept {
58 const Location copy{*this};
59 Back();
60 return copy;
61 }
62
63 constexpr Location operator--(int) noexcept {
64 Back();
65 return *this;
66 }
67
68 constexpr Location operator+(int number) const {
69 Location new_pc{*this};
70 while (number > 0) {
71 --number;
72 ++new_pc;
73 }
74 while (number < 0) {
75 ++number;
76 --new_pc;
77 }
78 return new_pc;
79 }
80
81 constexpr Location operator-(int number) const {
82 return operator+(-number);
83 }
84
85private:
86 constexpr void Align() {
87 offset += offset % 32 == 0 ? 8 : 0;
88 }
89
90 constexpr void Step() {
91 offset += 8 + (offset % 32 == 24 ? 8 : 0);
92 }
93
94 constexpr void Back() {
95 offset -= 8 + (offset % 32 == 8 ? 8 : 0);
96 }
97
98 u32 offset{0xcccccccc};
99};
100
101} // namespace Shader::Maxwell
102
103template <>
104struct fmt::formatter<Shader::Maxwell::Location> {
105 constexpr auto parse(format_parse_context& ctx) {
106 return ctx.begin();
107 }
108 template <typename FormatContext>
109 auto format(const Shader::Maxwell::Location& location, FormatContext& ctx) {
110 return fmt::format_to(ctx.out(), "{:04x}", location.Offset());
111 }
112};