value.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "shader_recompiler/frontend/ir/microinstruction.h"
  5. #include "shader_recompiler/frontend/ir/opcodes.h"
  6. #include "shader_recompiler/frontend/ir/value.h"
  7. namespace Shader::IR {
  8. Value::Value(IR::Inst* value) noexcept : type{Type::Opaque}, inst{value} {}
  9. Value::Value(IR::Block* value) noexcept : type{Type::Label}, label{value} {}
  10. Value::Value(IR::Reg value) noexcept : type{Type::Reg}, reg{value} {}
  11. Value::Value(IR::Pred value) noexcept : type{Type::Pred}, pred{value} {}
  12. Value::Value(IR::Attribute value) noexcept : type{Type::Attribute}, attribute{value} {}
  13. Value::Value(bool value) noexcept : type{Type::U1}, imm_u1{value} {}
  14. Value::Value(u8 value) noexcept : type{Type::U8}, imm_u8{value} {}
  15. Value::Value(u16 value) noexcept : type{Type::U16}, imm_u16{value} {}
  16. Value::Value(u32 value) noexcept : type{Type::U32}, imm_u32{value} {}
  17. Value::Value(f32 value) noexcept : type{Type::F32}, imm_f32{value} {}
  18. Value::Value(u64 value) noexcept : type{Type::U64}, imm_u64{value} {}
  19. Value::Value(f64 value) noexcept : type{Type::F64}, imm_f64{value} {}
  20. bool Value::IsIdentity() const noexcept {
  21. return type == Type::Opaque && inst->Opcode() == Opcode::Identity;
  22. }
  23. bool Value::IsPhi() const noexcept {
  24. return type == Type::Opaque && inst->Opcode() == Opcode::Phi;
  25. }
  26. bool Value::IsEmpty() const noexcept {
  27. return type == Type::Void;
  28. }
  29. bool Value::IsImmediate() const noexcept {
  30. if (IsIdentity()) {
  31. return inst->Arg(0).IsImmediate();
  32. }
  33. return type != Type::Opaque;
  34. }
  35. bool Value::IsLabel() const noexcept {
  36. return type == Type::Label;
  37. }
  38. IR::Type Value::Type() const noexcept {
  39. if (IsIdentity() || IsPhi()) {
  40. return inst->Arg(0).Type();
  41. }
  42. if (type == Type::Opaque) {
  43. return inst->Type();
  44. }
  45. return type;
  46. }
  47. IR::Inst* Value::Inst() const {
  48. ValidateAccess(Type::Opaque);
  49. return inst;
  50. }
  51. IR::Block* Value::Label() const {
  52. ValidateAccess(Type::Label);
  53. return label;
  54. }
  55. IR::Inst* Value::InstRecursive() const {
  56. ValidateAccess(Type::Opaque);
  57. if (IsIdentity()) {
  58. return inst->Arg(0).InstRecursive();
  59. }
  60. return inst;
  61. }
  62. IR::Value Value::Resolve() const {
  63. if (IsIdentity()) {
  64. return inst->Arg(0).Resolve();
  65. }
  66. return *this;
  67. }
  68. IR::Reg Value::Reg() const {
  69. ValidateAccess(Type::Reg);
  70. return reg;
  71. }
  72. IR::Pred Value::Pred() const {
  73. ValidateAccess(Type::Pred);
  74. return pred;
  75. }
  76. IR::Attribute Value::Attribute() const {
  77. ValidateAccess(Type::Attribute);
  78. return attribute;
  79. }
  80. bool Value::U1() const {
  81. if (IsIdentity()) {
  82. return inst->Arg(0).U1();
  83. }
  84. ValidateAccess(Type::U1);
  85. return imm_u1;
  86. }
  87. u8 Value::U8() const {
  88. if (IsIdentity()) {
  89. return inst->Arg(0).U8();
  90. }
  91. ValidateAccess(Type::U8);
  92. return imm_u8;
  93. }
  94. u16 Value::U16() const {
  95. if (IsIdentity()) {
  96. return inst->Arg(0).U16();
  97. }
  98. ValidateAccess(Type::U16);
  99. return imm_u16;
  100. }
  101. u32 Value::U32() const {
  102. if (IsIdentity()) {
  103. return inst->Arg(0).U32();
  104. }
  105. ValidateAccess(Type::U32);
  106. return imm_u32;
  107. }
  108. f32 Value::F32() const {
  109. if (IsIdentity()) {
  110. return inst->Arg(0).F32();
  111. }
  112. ValidateAccess(Type::F32);
  113. return imm_f32;
  114. }
  115. u64 Value::U64() const {
  116. if (IsIdentity()) {
  117. return inst->Arg(0).U64();
  118. }
  119. ValidateAccess(Type::U64);
  120. return imm_u64;
  121. }
  122. f64 Value::F64() const {
  123. if (IsIdentity()) {
  124. return inst->Arg(0).F64();
  125. }
  126. ValidateAccess(Type::F64);
  127. return imm_f64;
  128. }
  129. bool Value::operator==(const Value& other) const {
  130. if (type != other.type) {
  131. return false;
  132. }
  133. switch (type) {
  134. case Type::Void:
  135. return true;
  136. case Type::Opaque:
  137. return inst == other.inst;
  138. case Type::Label:
  139. return label == other.label;
  140. case Type::Reg:
  141. return reg == other.reg;
  142. case Type::Pred:
  143. return pred == other.pred;
  144. case Type::Attribute:
  145. return attribute == other.attribute;
  146. case Type::U1:
  147. return imm_u1 == other.imm_u1;
  148. case Type::U8:
  149. return imm_u8 == other.imm_u8;
  150. case Type::U16:
  151. case Type::F16:
  152. return imm_u16 == other.imm_u16;
  153. case Type::U32:
  154. case Type::F32:
  155. return imm_u32 == other.imm_u32;
  156. case Type::U64:
  157. case Type::F64:
  158. return imm_u64 == other.imm_u64;
  159. case Type::U32x2:
  160. case Type::U32x3:
  161. case Type::U32x4:
  162. case Type::F16x2:
  163. case Type::F16x3:
  164. case Type::F16x4:
  165. case Type::F32x2:
  166. case Type::F32x3:
  167. case Type::F32x4:
  168. case Type::F64x2:
  169. case Type::F64x3:
  170. case Type::F64x4:
  171. break;
  172. }
  173. throw LogicError("Invalid type {}", type);
  174. }
  175. bool Value::operator!=(const Value& other) const {
  176. return !operator==(other);
  177. }
  178. void Value::ValidateAccess(IR::Type expected) const {
  179. if (type != expected) {
  180. throw LogicError("Reading {} out of {}", expected, type);
  181. }
  182. }
  183. } // namespace Shader::IR