macro.h 3.2 KB

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