1 // Copyright 2010 Dolphin Emulator Project 2 // Licensed under GPLv2+ 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <cstddef> 8 #include <map> 9 #include <unordered_set> 10 11 #include "Common/CommonTypes.h" 12 #include "Common/x64Emitter.h" 13 #include "Core/ConfigManager.h" 14 #include "Core/MachineContext.h" 15 #include "Core/PowerPC/CPUCoreBase.h" 16 #include "Core/PowerPC/JitCommon/JitAsmCommon.h" 17 #include "Core/PowerPC/JitCommon/JitCache.h" 18 #include "Core/PowerPC/PPCAnalyst.h" 19 20 //#define JIT_LOG_GENERATED_CODE // Enables logging of generated code 21 //#define JIT_LOG_GPR // Enables logging of the PPC general purpose regs 22 //#define JIT_LOG_FPR // Enables logging of the PPC floating point regs 23 24 // Use these to control the instruction selection 25 // #define INSTRUCTION_START FallBackToInterpreter(inst); return; 26 // #define INSTRUCTION_START PPCTables::CountInstruction(inst); 27 #define INSTRUCTION_START 28 29 #define FALLBACK_IF(cond) \ 30 do \ 31 { \ 32 if (cond) \ 33 { \ 34 FallBackToInterpreter(inst); \ 35 return; \ 36 } \ 37 } while (0) 38 39 #define JITDISABLE(setting) \ 40 FALLBACK_IF(SConfig::GetInstance().bJITOff || SConfig::GetInstance().setting) 41 42 class JitBase : public CPUCoreBase 43 { 44 protected: 45 struct JitOptions 46 { 47 bool enableBlocklink; 48 bool optimizeGatherPipe; 49 bool accurateSinglePrecision; 50 bool fastmem; 51 bool fastmem_arena; 52 bool memcheck; 53 bool profile_blocks; 54 }; 55 struct JitState 56 { 57 u32 compilerPC; 58 u32 blockStart; 59 int instructionNumber; 60 int instructionsLeft; 61 int downcountAmount; 62 u32 numLoadStoreInst; 63 u32 numFloatingPointInst; 64 // If this is set, we need to generate an exception handler for the fastmem load. 65 u8* fastmemLoadStore; 66 // If this is set, a load or store already prepared a jump to the exception handler for us, 67 // so just fixup that branch instead of testing for a DSI again. 68 bool fixupExceptionHandler; 69 Gen::FixupBranch exceptionHandler; 70 71 bool assumeNoPairedQuantize; 72 std::map<u8, u32> constantGqr; 73 bool firstFPInstructionFound; 74 bool isLastInstruction; 75 int skipInstructions; 76 bool carryFlagSet; 77 bool carryFlagInverted; 78 79 bool generatingTrampoline = false; 80 u8* trampolineExceptionHandler; 81 82 bool mustCheckFifo; 83 int fifoBytesSinceCheck; 84 85 PPCAnalyst::BlockStats st; 86 PPCAnalyst::BlockRegStats gpa; 87 PPCAnalyst::BlockRegStats fpa; 88 PPCAnalyst::CodeOp* op; 89 90 JitBlock* curBlock; 91 92 std::unordered_set<u32> fifoWriteAddresses; 93 std::unordered_set<u32> pairedQuantizeAddresses; 94 std::unordered_set<u32> noSpeculativeConstantsAddresses; 95 }; 96 97 PPCAnalyst::CodeBlock code_block; 98 PPCAnalyst::CodeBuffer m_code_buffer; 99 PPCAnalyst::PPCAnalyzer analyzer; 100 101 bool CanMergeNextInstructions(int count) const; 102 103 void UpdateMemoryOptions(); 104 105 public: 106 JitBase(); 107 ~JitBase() override; 108 109 static const u8* Dispatch(JitBase& jit); 110 virtual JitBaseBlockCache* GetBlockCache() = 0; 111 112 virtual void Jit(u32 em_address) = 0; 113 114 virtual const CommonAsmRoutinesBase* GetAsmRoutines() = 0; 115 116 virtual bool HandleFault(uintptr_t access_address, SContext* ctx) = 0; HandleStackFault()117 virtual bool HandleStackFault() { return false; } 118 119 static constexpr std::size_t code_buffer_size = 32000; 120 121 // This should probably be removed from public: 122 JitOptions jo{}; 123 JitState js{}; 124 }; 125 126 void JitTrampoline(JitBase& jit, u32 em_address); 127