emit_glasm_special.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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/backend/glasm/emit_glasm_instructions.h"
  5. #include "shader_recompiler/backend/glasm/glasm_emit_context.h"
  6. #include "shader_recompiler/frontend/ir/value.h"
  7. namespace Shader::Backend::GLASM {
  8. static void DefinePhi(EmitContext& ctx, IR::Inst& phi) {
  9. switch (phi.Type()) {
  10. case IR::Type::U1:
  11. case IR::Type::U32:
  12. case IR::Type::F32:
  13. ctx.reg_alloc.Define(phi);
  14. break;
  15. case IR::Type::U64:
  16. case IR::Type::F64:
  17. ctx.reg_alloc.LongDefine(phi);
  18. break;
  19. default:
  20. throw NotImplementedException("Phi node type {}", phi.Type());
  21. }
  22. }
  23. void EmitPhi(EmitContext& ctx, IR::Inst& phi) {
  24. const size_t num_args{phi.NumArgs()};
  25. for (size_t i = 0; i < num_args; ++i) {
  26. ctx.reg_alloc.Consume(phi.Arg(i));
  27. }
  28. if (!phi.Definition<Id>().is_valid) {
  29. // The phi node wasn't forward defined
  30. DefinePhi(ctx, phi);
  31. }
  32. }
  33. void EmitVoid(EmitContext&) {}
  34. void EmitReference(EmitContext& ctx, const IR::Value& value) {
  35. ctx.reg_alloc.Consume(value);
  36. }
  37. void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) {
  38. IR::Inst& phi{RegAlloc::AliasInst(*phi_value.Inst())};
  39. if (!phi.Definition<Id>().is_valid) {
  40. // The phi node wasn't forward defined
  41. DefinePhi(ctx, phi);
  42. }
  43. const Register phi_reg{ctx.reg_alloc.Consume(IR::Value{&phi})};
  44. const Value eval_value{ctx.reg_alloc.Consume(value)};
  45. if (phi_reg == eval_value) {
  46. return;
  47. }
  48. switch (phi.Flags<IR::Type>()) {
  49. case IR::Type::U1:
  50. case IR::Type::U32:
  51. case IR::Type::F32:
  52. ctx.Add("MOV.S {}.x,{};", phi_reg, ScalarS32{eval_value});
  53. break;
  54. case IR::Type::U64:
  55. case IR::Type::F64:
  56. ctx.Add("MOV.U64 {}.x,{};", phi_reg, ScalarRegister{eval_value});
  57. break;
  58. default:
  59. throw NotImplementedException("Phi node type {}", phi.Type());
  60. }
  61. }
  62. void EmitPrologue(EmitContext&) {
  63. // TODO
  64. }
  65. void EmitEpilogue(EmitContext&) {
  66. // TODO
  67. }
  68. void EmitEmitVertex(EmitContext& ctx, ScalarS32 stream) {
  69. if (stream.type == Type::U32 && stream.imm_u32 == 0) {
  70. ctx.Add("EMIT;");
  71. } else {
  72. ctx.Add("EMITS {};", stream);
  73. }
  74. }
  75. void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) {
  76. if (!stream.IsImmediate()) {
  77. LOG_WARNING(Shader_GLASM, "Stream is not immediate");
  78. }
  79. ctx.reg_alloc.Consume(stream);
  80. ctx.Add("ENDPRIM;");
  81. }
  82. } // namespace Shader::Backend::GLASM