translate.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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/environment.h"
  5. #include "shader_recompiler/frontend/ir/basic_block.h"
  6. #include "shader_recompiler/frontend/maxwell/decode.h"
  7. #include "shader_recompiler/frontend/maxwell/location.h"
  8. #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
  9. #include "shader_recompiler/frontend/maxwell/translate/translate.h"
  10. namespace Shader::Maxwell {
  11. template <auto visitor_method>
  12. static void Invoke(TranslatorVisitor& visitor, Location pc, u64 insn) {
  13. using MethodType = decltype(visitor_method);
  14. if constexpr (std::is_invocable_r_v<void, MethodType, TranslatorVisitor&, Location, u64>) {
  15. (visitor.*visitor_method)(pc, insn);
  16. } else if constexpr (std::is_invocable_r_v<void, MethodType, TranslatorVisitor&, u64>) {
  17. (visitor.*visitor_method)(insn);
  18. } else {
  19. (visitor.*visitor_method)();
  20. }
  21. }
  22. IR::Block Translate(Environment& env, const Flow::Block& flow_block) {
  23. IR::Block block{flow_block.begin.Offset(), flow_block.end.Offset()};
  24. TranslatorVisitor visitor{env, block};
  25. const Location pc_end{flow_block.end};
  26. Location pc{flow_block.begin};
  27. while (pc != pc_end) {
  28. const u64 insn{env.ReadInstruction(pc.Offset())};
  29. const Opcode opcode{Decode(insn)};
  30. switch (opcode) {
  31. #define INST(name, cute, mask) \
  32. case Opcode::name: \
  33. Invoke<&TranslatorVisitor::name>(visitor, pc, insn); \
  34. break;
  35. #include "shader_recompiler/frontend/maxwell/maxwell.inc"
  36. #undef OPCODE
  37. default:
  38. throw LogicError("Invalid opcode {}", opcode);
  39. }
  40. ++pc;
  41. }
  42. return block;
  43. }
  44. } // namespace Shader::Maxwell