macro_interpreter.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright 2020 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <optional>
  7. #include <vector>
  8. #include "common/bit_field.h"
  9. #include "common/common_types.h"
  10. #include "video_core/macro/macro.h"
  11. namespace Tegra {
  12. namespace Engines {
  13. class Maxwell3D;
  14. }
  15. class MacroInterpreter final : public MacroEngine {
  16. public:
  17. explicit MacroInterpreter(Engines::Maxwell3D& maxwell3d_);
  18. protected:
  19. std::unique_ptr<CachedMacro> Compile(const std::vector<u32>& code) override;
  20. private:
  21. Engines::Maxwell3D& maxwell3d;
  22. };
  23. class MacroInterpreterImpl : public CachedMacro {
  24. public:
  25. explicit MacroInterpreterImpl(Engines::Maxwell3D& maxwell3d_, const std::vector<u32>& code_);
  26. void Execute(const std::vector<u32>& params, u32 method) override;
  27. private:
  28. /// Resets the execution engine state, zeroing registers, etc.
  29. void Reset();
  30. /**
  31. * Executes a single macro instruction located at the current program counter. Returns whether
  32. * the interpreter should keep running.
  33. *
  34. * @param is_delay_slot Whether the current step is being executed due to a delay slot in a
  35. * previous instruction.
  36. */
  37. bool Step(bool is_delay_slot);
  38. /// Calculates the result of an ALU operation. src_a OP src_b;
  39. u32 GetALUResult(Macro::ALUOperation operation, u32 src_a, u32 src_b);
  40. /// Performs the result operation on the input result and stores it in the specified register
  41. /// (if necessary).
  42. void ProcessResult(Macro::ResultOperation operation, u32 reg, u32 result);
  43. /// Evaluates the branch condition and returns whether the branch should be taken or not.
  44. bool EvaluateBranchCondition(Macro::BranchCondition cond, u32 value) const;
  45. /// Reads an opcode at the current program counter location.
  46. Macro::Opcode GetOpcode() const;
  47. /// Returns the specified register's value. Register 0 is hardcoded to always return 0.
  48. u32 GetRegister(u32 register_id) const;
  49. /// Sets the register to the input value.
  50. void SetRegister(u32 register_id, u32 value);
  51. /// Sets the method address to use for the next Send instruction.
  52. void SetMethodAddress(u32 address);
  53. /// Calls a GPU Engine method with the input parameter.
  54. void Send(u32 value);
  55. /// Reads a GPU register located at the method address.
  56. u32 Read(u32 method) const;
  57. /// Returns the next parameter in the parameter queue.
  58. u32 FetchParameter();
  59. Engines::Maxwell3D& maxwell3d;
  60. /// Current program counter
  61. u32 pc;
  62. /// Program counter to execute at after the delay slot is executed.
  63. std::optional<u32> delayed_pc;
  64. /// General purpose macro registers.
  65. std::array<u32, Macro::NUM_MACRO_REGISTERS> registers = {};
  66. /// Method address to use for the next Send instruction.
  67. Macro::MethodAddress method_address = {};
  68. /// Input parameters of the current macro.
  69. std::unique_ptr<u32[]> parameters;
  70. std::size_t num_parameters = 0;
  71. std::size_t parameters_capacity = 0;
  72. /// Index of the next parameter that will be fetched by the 'parm' instruction.
  73. u32 next_parameter_index = 0;
  74. bool carry_flag = false;
  75. const std::vector<u32>& code;
  76. };
  77. } // namespace Tegra