macro_jit_x64.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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 <bitset>
  7. #include <xbyak.h>
  8. #include "common/bit_field.h"
  9. #include "common/common_types.h"
  10. #include "common/x64/xbyak_abi.h"
  11. #include "video_core/macro/macro.h"
  12. namespace Tegra {
  13. namespace Engines {
  14. class Maxwell3D;
  15. }
  16. /// MAX_CODE_SIZE is arbitrarily chosen based on current booting games
  17. constexpr size_t MAX_CODE_SIZE = 0x10000;
  18. class MacroJITx64 final : public MacroEngine {
  19. public:
  20. explicit MacroJITx64(Engines::Maxwell3D& maxwell3d_);
  21. protected:
  22. std::unique_ptr<CachedMacro> Compile(const std::vector<u32>& code) override;
  23. private:
  24. Engines::Maxwell3D& maxwell3d;
  25. };
  26. class MacroJITx64Impl : public Xbyak::CodeGenerator, public CachedMacro {
  27. public:
  28. explicit MacroJITx64Impl(Engines::Maxwell3D& maxwell3d_, const std::vector<u32>& code_);
  29. ~MacroJITx64Impl();
  30. void Execute(const std::vector<u32>& parameters, u32 method) override;
  31. void Compile_ALU(Macro::Opcode opcode);
  32. void Compile_AddImmediate(Macro::Opcode opcode);
  33. void Compile_ExtractInsert(Macro::Opcode opcode);
  34. void Compile_ExtractShiftLeftImmediate(Macro::Opcode opcode);
  35. void Compile_ExtractShiftLeftRegister(Macro::Opcode opcode);
  36. void Compile_Read(Macro::Opcode opcode);
  37. void Compile_Branch(Macro::Opcode opcode);
  38. private:
  39. void Optimizer_ScanFlags();
  40. void Compile();
  41. bool Compile_NextInstruction();
  42. Xbyak::Reg32 Compile_FetchParameter();
  43. Xbyak::Reg32 Compile_GetRegister(u32 index, Xbyak::Reg32 dst);
  44. void Compile_ProcessResult(Macro::ResultOperation operation, u32 reg);
  45. void Compile_Send(Xbyak::Reg32 value);
  46. Macro::Opcode GetOpCode() const;
  47. std::bitset<32> PersistentCallerSavedRegs() const;
  48. struct JITState {
  49. Engines::Maxwell3D* maxwell3d{};
  50. std::array<u32, Macro::NUM_MACRO_REGISTERS> registers{};
  51. u32 carry_flag{};
  52. };
  53. static_assert(offsetof(JITState, maxwell3d) == 0, "Maxwell3D is not at 0x0");
  54. using ProgramType = void (*)(JITState*, const u32*);
  55. struct OptimizerState {
  56. bool can_skip_carry{};
  57. bool has_delayed_pc{};
  58. bool zero_reg_skip{};
  59. bool skip_dummy_addimmediate{};
  60. bool optimize_for_method_move{};
  61. bool enable_asserts{};
  62. };
  63. OptimizerState optimizer{};
  64. std::optional<Macro::Opcode> next_opcode{};
  65. ProgramType program{nullptr};
  66. std::array<Xbyak::Label, MAX_CODE_SIZE> labels;
  67. std::array<Xbyak::Label, MAX_CODE_SIZE> delay_skip;
  68. Xbyak::Label end_of_code{};
  69. bool is_delay_slot{};
  70. u32 pc{};
  71. std::optional<u32> delayed_pc;
  72. const std::vector<u32>& code;
  73. Engines::Maxwell3D& maxwell3d;
  74. };
  75. } // namespace Tegra