impl.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "common/bit_field.h"
  5. #include "shader_recompiler/frontend/ir/ir_emitter.h"
  6. #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
  7. namespace Shader::Maxwell {
  8. IR::U32 TranslatorVisitor::X(IR::Reg reg) {
  9. return ir.GetReg(reg);
  10. }
  11. IR::F32 TranslatorVisitor::F(IR::Reg reg) {
  12. return ir.BitCast<IR::F32>(X(reg));
  13. }
  14. void TranslatorVisitor::X(IR::Reg dest_reg, const IR::U32& value) {
  15. ir.SetReg(dest_reg, value);
  16. }
  17. void TranslatorVisitor::F(IR::Reg dest_reg, const IR::F32& value) {
  18. X(dest_reg, ir.BitCast<IR::U32>(value));
  19. }
  20. IR::U32 TranslatorVisitor::GetReg8(u64 insn) {
  21. union {
  22. u64 raw;
  23. BitField<8, 8, IR::Reg> index;
  24. } const reg{insn};
  25. return X(reg.index);
  26. }
  27. IR::U32 TranslatorVisitor::GetReg20(u64 insn) {
  28. union {
  29. u64 raw;
  30. BitField<20, 8, IR::Reg> index;
  31. } const reg{insn};
  32. return X(reg.index);
  33. }
  34. IR::U32 TranslatorVisitor::GetReg39(u64 insn) {
  35. union {
  36. u64 raw;
  37. BitField<39, 8, IR::Reg> index;
  38. } const reg{insn};
  39. return X(reg.index);
  40. }
  41. IR::F32 TranslatorVisitor::GetRegFloat20(u64 insn) {
  42. return ir.BitCast<IR::F32>(GetReg20(insn));
  43. }
  44. IR::F32 TranslatorVisitor::GetRegFloat39(u64 insn) {
  45. return ir.BitCast<IR::F32>(GetReg39(insn));
  46. }
  47. IR::U32 TranslatorVisitor::GetCbuf(u64 insn) {
  48. union {
  49. u64 raw;
  50. BitField<20, 14, s64> offset;
  51. BitField<34, 5, u64> binding;
  52. } const cbuf{insn};
  53. if (cbuf.binding >= 18) {
  54. throw NotImplementedException("Out of bounds constant buffer binding {}", cbuf.binding);
  55. }
  56. if (cbuf.offset >= 0x10'000 || cbuf.offset < 0) {
  57. throw NotImplementedException("Out of bounds constant buffer offset {}", cbuf.offset);
  58. }
  59. const IR::U32 binding{ir.Imm32(static_cast<u32>(cbuf.binding))};
  60. const IR::U32 byte_offset{ir.Imm32(static_cast<u32>(cbuf.offset) * 4)};
  61. return ir.GetCbuf(binding, byte_offset);
  62. }
  63. IR::F32 TranslatorVisitor::GetFloatCbuf(u64 insn) {
  64. return ir.BitCast<IR::F32>(GetCbuf(insn));
  65. }
  66. IR::U32 TranslatorVisitor::GetImm20(u64 insn) {
  67. union {
  68. u64 raw;
  69. BitField<20, 19, u64> value;
  70. BitField<56, 1, u64> is_negative;
  71. } const imm{insn};
  72. if (imm.is_negative != 0) {
  73. const s64 raw{static_cast<s64>(imm.value)};
  74. return ir.Imm32(static_cast<s32>(-(1LL << 19) + raw));
  75. } else {
  76. return ir.Imm32(static_cast<u32>(imm.value));
  77. }
  78. }
  79. IR::F32 TranslatorVisitor::GetFloatImm20(u64 insn) {
  80. union {
  81. u64 raw;
  82. BitField<20, 19, u64> value;
  83. BitField<56, 1, u64> is_negative;
  84. } const imm{insn};
  85. const u32 sign_bit{imm.is_negative != 0 ? (1ULL << 31) : 0};
  86. const u32 value{static_cast<u32>(imm.value) << 12};
  87. return ir.Imm32(Common::BitCast<f32>(value | sign_bit));
  88. }
  89. IR::U32 TranslatorVisitor::GetImm32(u64 insn) {
  90. union {
  91. u64 raw;
  92. BitField<20, 32, u64> value;
  93. } const imm{insn};
  94. return ir.Imm32(static_cast<u32>(imm.value));
  95. }
  96. void TranslatorVisitor::SetZFlag(const IR::U1& value) {
  97. ir.SetZFlag(value);
  98. }
  99. void TranslatorVisitor::SetSFlag(const IR::U1& value) {
  100. ir.SetSFlag(value);
  101. }
  102. void TranslatorVisitor::SetCFlag(const IR::U1& value) {
  103. ir.SetCFlag(value);
  104. }
  105. void TranslatorVisitor::SetOFlag(const IR::U1& value) {
  106. ir.SetOFlag(value);
  107. }
  108. void TranslatorVisitor::ResetZero() {
  109. SetZFlag(ir.Imm1(false));
  110. }
  111. void TranslatorVisitor::ResetSFlag() {
  112. SetSFlag(ir.Imm1(false));
  113. }
  114. void TranslatorVisitor::ResetCFlag() {
  115. SetCFlag(ir.Imm1(false));
  116. }
  117. void TranslatorVisitor::ResetOFlag() {
  118. SetOFlag(ir.Imm1(false));
  119. }
  120. } // namespace Shader::Maxwell