value.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include "common/common_types.h"
  6. #include "shader_recompiler/exception.h"
  7. #include "shader_recompiler/frontend/ir/attribute.h"
  8. #include "shader_recompiler/frontend/ir/pred.h"
  9. #include "shader_recompiler/frontend/ir/reg.h"
  10. #include "shader_recompiler/frontend/ir/patch.h"
  11. #include "shader_recompiler/frontend/ir/type.h"
  12. namespace Shader::IR {
  13. class Block;
  14. class Inst;
  15. class Value {
  16. public:
  17. Value() noexcept : type{IR::Type::Void}, inst{nullptr} {}
  18. explicit Value(IR::Inst* value) noexcept;
  19. explicit Value(IR::Block* value) noexcept;
  20. explicit Value(IR::Reg value) noexcept;
  21. explicit Value(IR::Pred value) noexcept;
  22. explicit Value(IR::Attribute value) noexcept;
  23. explicit Value(IR::Patch value) noexcept;
  24. explicit Value(bool value) noexcept;
  25. explicit Value(u8 value) noexcept;
  26. explicit Value(u16 value) noexcept;
  27. explicit Value(u32 value) noexcept;
  28. explicit Value(f32 value) noexcept;
  29. explicit Value(u64 value) noexcept;
  30. explicit Value(f64 value) noexcept;
  31. [[nodiscard]] bool IsIdentity() const noexcept;
  32. [[nodiscard]] bool IsPhi() const noexcept;
  33. [[nodiscard]] bool IsEmpty() const noexcept;
  34. [[nodiscard]] bool IsImmediate() const noexcept;
  35. [[nodiscard]] bool IsLabel() const noexcept;
  36. [[nodiscard]] IR::Type Type() const noexcept;
  37. [[nodiscard]] IR::Inst* Inst() const;
  38. [[nodiscard]] IR::Block* Label() const;
  39. [[nodiscard]] IR::Inst* InstRecursive() const;
  40. [[nodiscard]] IR::Value Resolve() const;
  41. [[nodiscard]] IR::Reg Reg() const;
  42. [[nodiscard]] IR::Pred Pred() const;
  43. [[nodiscard]] IR::Attribute Attribute() const;
  44. [[nodiscard]] IR::Patch Patch() const;
  45. [[nodiscard]] bool U1() const;
  46. [[nodiscard]] u8 U8() const;
  47. [[nodiscard]] u16 U16() const;
  48. [[nodiscard]] u32 U32() const;
  49. [[nodiscard]] f32 F32() const;
  50. [[nodiscard]] u64 U64() const;
  51. [[nodiscard]] f64 F64() const;
  52. [[nodiscard]] bool operator==(const Value& other) const;
  53. [[nodiscard]] bool operator!=(const Value& other) const;
  54. private:
  55. void ValidateAccess(IR::Type expected) const;
  56. IR::Type type;
  57. union {
  58. IR::Inst* inst;
  59. IR::Block* label;
  60. IR::Reg reg;
  61. IR::Pred pred;
  62. IR::Attribute attribute;
  63. IR::Patch patch;
  64. bool imm_u1;
  65. u8 imm_u8;
  66. u16 imm_u16;
  67. u32 imm_u32;
  68. f32 imm_f32;
  69. u64 imm_u64;
  70. f64 imm_f64;
  71. };
  72. };
  73. static_assert(std::is_trivially_copyable_v<Value>);
  74. template <IR::Type type_>
  75. class TypedValue : public Value {
  76. public:
  77. TypedValue() = default;
  78. template <IR::Type other_type>
  79. requires((other_type & type_) != IR::Type::Void) explicit(false)
  80. TypedValue(const TypedValue<other_type>& value)
  81. : Value(value) {}
  82. explicit TypedValue(const Value& value) : Value(value) {
  83. if ((value.Type() & type_) == IR::Type::Void) {
  84. throw InvalidArgument("Incompatible types {} and {}", type_, value.Type());
  85. }
  86. }
  87. explicit TypedValue(IR::Inst* inst_) : TypedValue(Value(inst_)) {}
  88. };
  89. using U1 = TypedValue<Type::U1>;
  90. using U8 = TypedValue<Type::U8>;
  91. using U16 = TypedValue<Type::U16>;
  92. using U32 = TypedValue<Type::U32>;
  93. using U64 = TypedValue<Type::U64>;
  94. using F16 = TypedValue<Type::F16>;
  95. using F32 = TypedValue<Type::F32>;
  96. using F64 = TypedValue<Type::F64>;
  97. using U32U64 = TypedValue<Type::U32 | Type::U64>;
  98. using F32F64 = TypedValue<Type::F32 | Type::F64>;
  99. using U16U32U64 = TypedValue<Type::U16 | Type::U32 | Type::U64>;
  100. using F16F32F64 = TypedValue<Type::F16 | Type::F32 | Type::F64>;
  101. using UAny = TypedValue<Type::U8 | Type::U16 | Type::U32 | Type::U64>;
  102. } // namespace Shader::IR