value.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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/opcode.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(u64 value) noexcept : type{Type::U64}, imm_u64{value} {}
  18. bool Value::IsIdentity() const noexcept {
  19. return type == Type::Opaque && inst->Opcode() == Opcode::Identity;
  20. }
  21. bool Value::IsEmpty() const noexcept {
  22. return type == Type::Void;
  23. }
  24. bool Value::IsImmediate() const noexcept {
  25. if (IsIdentity()) {
  26. return inst->Arg(0).IsImmediate();
  27. }
  28. return type != Type::Opaque;
  29. }
  30. bool Value::IsLabel() const noexcept {
  31. return type == Type::Label;
  32. }
  33. IR::Type Value::Type() const noexcept {
  34. if (IsIdentity()) {
  35. return inst->Arg(0).Type();
  36. }
  37. if (type == Type::Opaque) {
  38. return inst->Type();
  39. }
  40. return type;
  41. }
  42. IR::Inst* Value::Inst() const {
  43. ValidateAccess(Type::Opaque);
  44. return inst;
  45. }
  46. IR::Block* Value::Label() const {
  47. ValidateAccess(Type::Label);
  48. return label;
  49. }
  50. IR::Inst* Value::InstRecursive() const {
  51. ValidateAccess(Type::Opaque);
  52. if (IsIdentity()) {
  53. return inst->Arg(0).InstRecursive();
  54. }
  55. return inst;
  56. }
  57. IR::Reg Value::Reg() const {
  58. ValidateAccess(Type::Reg);
  59. return reg;
  60. }
  61. IR::Pred Value::Pred() const {
  62. ValidateAccess(Type::Pred);
  63. return pred;
  64. }
  65. IR::Attribute Value::Attribute() const {
  66. ValidateAccess(Type::Attribute);
  67. return attribute;
  68. }
  69. bool Value::U1() const {
  70. if (IsIdentity()) {
  71. return inst->Arg(0).U1();
  72. }
  73. ValidateAccess(Type::U1);
  74. return imm_u1;
  75. }
  76. u8 Value::U8() const {
  77. if (IsIdentity()) {
  78. return inst->Arg(0).U8();
  79. }
  80. ValidateAccess(Type::U8);
  81. return imm_u8;
  82. }
  83. u16 Value::U16() const {
  84. if (IsIdentity()) {
  85. return inst->Arg(0).U16();
  86. }
  87. ValidateAccess(Type::U16);
  88. return imm_u16;
  89. }
  90. u32 Value::U32() const {
  91. if (IsIdentity()) {
  92. return inst->Arg(0).U32();
  93. }
  94. ValidateAccess(Type::U32);
  95. return imm_u32;
  96. }
  97. u64 Value::U64() const {
  98. if (IsIdentity()) {
  99. return inst->Arg(0).U64();
  100. }
  101. ValidateAccess(Type::U64);
  102. return imm_u64;
  103. }
  104. bool Value::operator==(const Value& other) const {
  105. if (type != other.type) {
  106. return false;
  107. }
  108. switch (type) {
  109. case Type::Void:
  110. return true;
  111. case Type::Opaque:
  112. return inst == other.inst;
  113. case Type::Label:
  114. return label == other.label;
  115. case Type::Reg:
  116. return reg == other.reg;
  117. case Type::Pred:
  118. return pred == other.pred;
  119. case Type::Attribute:
  120. return attribute == other.attribute;
  121. case Type::U1:
  122. return imm_u1 == other.imm_u1;
  123. case Type::U8:
  124. return imm_u8 == other.imm_u8;
  125. case Type::U16:
  126. return imm_u16 == other.imm_u16;
  127. case Type::U32:
  128. return imm_u32 == other.imm_u32;
  129. case Type::U64:
  130. return imm_u64 == other.imm_u64;
  131. }
  132. throw LogicError("Invalid type {}", type);
  133. }
  134. bool Value::operator!=(const Value& other) const {
  135. return !operator==(other);
  136. }
  137. void Value::ValidateAccess(IR::Type expected) const {
  138. if (type != expected) {
  139. throw LogicError("Reading {} out of {}", expected, type);
  140. }
  141. }
  142. } // namespace Shader::IR