value.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. ValidateAccess(Type::U1);
  71. return imm_u1;
  72. }
  73. u8 Value::U8() const {
  74. ValidateAccess(Type::U8);
  75. return imm_u8;
  76. }
  77. u16 Value::U16() const {
  78. ValidateAccess(Type::U16);
  79. return imm_u16;
  80. }
  81. u32 Value::U32() const {
  82. ValidateAccess(Type::U32);
  83. return imm_u32;
  84. }
  85. u64 Value::U64() const {
  86. ValidateAccess(Type::U64);
  87. return imm_u64;
  88. }
  89. bool Value::operator==(const Value& other) const {
  90. if (type != other.type) {
  91. return false;
  92. }
  93. switch (type) {
  94. case Type::Void:
  95. return true;
  96. case Type::Opaque:
  97. return inst == other.inst;
  98. case Type::Label:
  99. return label == other.label;
  100. case Type::Reg:
  101. return reg == other.reg;
  102. case Type::Pred:
  103. return pred == other.pred;
  104. case Type::Attribute:
  105. return attribute == other.attribute;
  106. case Type::U1:
  107. return imm_u1 == other.imm_u1;
  108. case Type::U8:
  109. return imm_u8 == other.imm_u8;
  110. case Type::U16:
  111. return imm_u16 == other.imm_u16;
  112. case Type::U32:
  113. return imm_u32 == other.imm_u32;
  114. case Type::U64:
  115. return imm_u64 == other.imm_u64;
  116. case Type::ZSCO:
  117. throw NotImplementedException("ZSCO comparison");
  118. }
  119. throw LogicError("Invalid type {}", type);
  120. }
  121. bool Value::operator!=(const Value& other) const {
  122. return !operator==(other);
  123. }
  124. void Value::ValidateAccess(IR::Type expected) const {
  125. if (type != expected) {
  126. throw LogicError("Reading {} out of {}", expected, type);
  127. }
  128. }
  129. } // namespace Shader::IR