macro.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <memory>
  5. #include <unordered_map>
  6. #include <vector>
  7. #include "common/bit_field.h"
  8. #include "common/common_types.h"
  9. namespace Tegra {
  10. namespace Engines {
  11. class Maxwell3D;
  12. }
  13. namespace Macro {
  14. constexpr std::size_t NUM_MACRO_REGISTERS = 8;
  15. enum class Operation : u32 {
  16. ALU = 0,
  17. AddImmediate = 1,
  18. ExtractInsert = 2,
  19. ExtractShiftLeftImmediate = 3,
  20. ExtractShiftLeftRegister = 4,
  21. Read = 5,
  22. Unused = 6, // This operation doesn't seem to be a valid encoding.
  23. Branch = 7,
  24. };
  25. enum class ALUOperation : u32 {
  26. Add = 0,
  27. AddWithCarry = 1,
  28. Subtract = 2,
  29. SubtractWithBorrow = 3,
  30. // Operations 4-7 don't seem to be valid encodings.
  31. Xor = 8,
  32. Or = 9,
  33. And = 10,
  34. AndNot = 11,
  35. Nand = 12
  36. };
  37. enum class ResultOperation : u32 {
  38. IgnoreAndFetch = 0,
  39. Move = 1,
  40. MoveAndSetMethod = 2,
  41. FetchAndSend = 3,
  42. MoveAndSend = 4,
  43. FetchAndSetMethod = 5,
  44. MoveAndSetMethodFetchAndSend = 6,
  45. MoveAndSetMethodSend = 7
  46. };
  47. enum class BranchCondition : u32 {
  48. Zero = 0,
  49. NotZero = 1,
  50. };
  51. union Opcode {
  52. u32 raw;
  53. BitField<0, 3, Operation> operation;
  54. BitField<4, 3, ResultOperation> result_operation;
  55. BitField<4, 1, BranchCondition> branch_condition;
  56. // If set on a branch, then the branch doesn't have a delay slot.
  57. BitField<5, 1, u32> branch_annul;
  58. BitField<7, 1, u32> is_exit;
  59. BitField<8, 3, u32> dst;
  60. BitField<11, 3, u32> src_a;
  61. BitField<14, 3, u32> src_b;
  62. // The signed immediate overlaps the second source operand and the alu operation.
  63. BitField<14, 18, s32> immediate;
  64. BitField<17, 5, ALUOperation> alu_operation;
  65. // Bitfield instructions data
  66. BitField<17, 5, u32> bf_src_bit;
  67. BitField<22, 5, u32> bf_size;
  68. BitField<27, 5, u32> bf_dst_bit;
  69. u32 GetBitfieldMask() const {
  70. return (1 << bf_size) - 1;
  71. }
  72. s32 GetBranchTarget() const {
  73. return static_cast<s32>(immediate * sizeof(u32));
  74. }
  75. };
  76. union MethodAddress {
  77. u32 raw;
  78. BitField<0, 12, u32> address;
  79. BitField<12, 6, u32> increment;
  80. };
  81. } // namespace Macro
  82. class HLEMacro;
  83. class CachedMacro {
  84. public:
  85. virtual ~CachedMacro() = default;
  86. /**
  87. * Executes the macro code with the specified input parameters.
  88. *
  89. * @param parameters The parameters of the macro
  90. * @param method The method to execute
  91. */
  92. virtual void Execute(const std::vector<u32>& parameters, u32 method) = 0;
  93. };
  94. class MacroEngine {
  95. public:
  96. explicit MacroEngine(Engines::Maxwell3D& maxwell3d);
  97. virtual ~MacroEngine();
  98. // Store the uploaded macro code to compile them when they're called.
  99. void AddCode(u32 method, u32 data);
  100. // Clear the code associated with a method.
  101. void ClearCode(u32 method);
  102. // Compiles the macro if its not in the cache, and executes the compiled macro
  103. void Execute(u32 method, const std::vector<u32>& parameters);
  104. protected:
  105. virtual std::unique_ptr<CachedMacro> Compile(const std::vector<u32>& code) = 0;
  106. private:
  107. struct CacheInfo {
  108. std::unique_ptr<CachedMacro> lle_program{};
  109. std::unique_ptr<CachedMacro> hle_program{};
  110. u64 hash{};
  111. bool has_hle_program{};
  112. };
  113. std::unordered_map<u32, CacheInfo> macro_cache;
  114. std::unordered_map<u32, std::vector<u32>> uploaded_macro_code;
  115. std::unique_ptr<HLEMacro> hle_macros;
  116. };
  117. std::unique_ptr<MacroEngine> GetMacroEngine(Engines::Maxwell3D& maxwell3d);
  118. } // namespace Tegra