2021-01-09 01:30:07 -05:00
|
|
|
// Copyright 2021 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <compare>
|
|
|
|
#include <iterator>
|
|
|
|
|
|
|
|
#include <fmt/format.h>
|
|
|
|
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "shader_recompiler/exception.h"
|
|
|
|
|
|
|
|
namespace Shader::Maxwell {
|
|
|
|
|
|
|
|
class Location {
|
2021-02-11 14:39:06 -05:00
|
|
|
static constexpr u32 VIRTUAL_BIAS{4};
|
2021-01-09 01:30:07 -05:00
|
|
|
|
|
|
|
public:
|
|
|
|
constexpr Location() = default;
|
|
|
|
|
|
|
|
constexpr Location(u32 initial_offset) : offset{initial_offset} {
|
|
|
|
if (initial_offset % 8 != 0) {
|
|
|
|
throw InvalidArgument("initial_offset={} is not a multiple of 8", initial_offset);
|
|
|
|
}
|
|
|
|
Align();
|
|
|
|
}
|
|
|
|
|
2021-02-11 14:39:06 -05:00
|
|
|
constexpr Location Virtual() const noexcept {
|
|
|
|
Location virtual_location;
|
|
|
|
virtual_location.offset = offset - VIRTUAL_BIAS;
|
|
|
|
return virtual_location;
|
|
|
|
}
|
|
|
|
|
2021-01-09 01:30:07 -05:00
|
|
|
[[nodiscard]] constexpr u32 Offset() const noexcept {
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]] constexpr bool IsVirtual() const {
|
2021-02-11 14:39:06 -05:00
|
|
|
return offset % 8 == VIRTUAL_BIAS;
|
2021-01-09 01:30:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
constexpr auto operator<=>(const Location&) const noexcept = default;
|
|
|
|
|
|
|
|
constexpr Location operator++() noexcept {
|
|
|
|
const Location copy{*this};
|
|
|
|
Step();
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr Location operator++(int) noexcept {
|
|
|
|
Step();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr Location operator--() noexcept {
|
|
|
|
const Location copy{*this};
|
|
|
|
Back();
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr Location operator--(int) noexcept {
|
|
|
|
Back();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr Location operator+(int number) const {
|
|
|
|
Location new_pc{*this};
|
|
|
|
while (number > 0) {
|
|
|
|
--number;
|
|
|
|
++new_pc;
|
|
|
|
}
|
|
|
|
while (number < 0) {
|
|
|
|
++number;
|
|
|
|
--new_pc;
|
|
|
|
}
|
|
|
|
return new_pc;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr Location operator-(int number) const {
|
|
|
|
return operator+(-number);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
constexpr void Align() {
|
|
|
|
offset += offset % 32 == 0 ? 8 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr void Step() {
|
|
|
|
offset += 8 + (offset % 32 == 24 ? 8 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr void Back() {
|
|
|
|
offset -= 8 + (offset % 32 == 8 ? 8 : 0);
|
|
|
|
}
|
|
|
|
|
2021-02-11 14:39:06 -05:00
|
|
|
u32 offset{0xcccccccc};
|
2021-01-09 01:30:07 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Shader::Maxwell
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct fmt::formatter<Shader::Maxwell::Location> {
|
|
|
|
constexpr auto parse(format_parse_context& ctx) {
|
|
|
|
return ctx.begin();
|
|
|
|
}
|
|
|
|
template <typename FormatContext>
|
|
|
|
auto format(const Shader::Maxwell::Location& location, FormatContext& ctx) {
|
|
|
|
return fmt::format_to(ctx.out(), "{:04x}", location.Offset());
|
|
|
|
}
|
|
|
|
};
|