CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Core/MIPS/MIPSAnalyst.h
Views: 1401
// Copyright (c) 2012- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#pragma once1819#include <string>20#include <vector>2122#include "Common/CommonTypes.h"23#include "Common/File/Path.h"24#include "Core/MIPS/MIPS.h"2526class DebugInterface;2728namespace MIPSAnalyst29{30const int MIPS_NUM_GPRS = 32;3132struct RegisterAnalysisResults {33bool used;34int firstRead;35int lastRead;36int firstWrite;37int lastWrite;38int firstReadAsAddr;39int lastReadAsAddr;4041int readCount;42int writeCount;43int readAsAddrCount;4445int TotalReadCount() const { return readCount + readAsAddrCount; }46int FirstRead() const { return firstReadAsAddr < firstRead ? firstReadAsAddr : firstRead; }47int LastRead() const { return lastReadAsAddr > lastRead ? lastReadAsAddr : lastRead; }4849void MarkRead(u32 addr) {50if (firstRead == -1)51firstRead = addr;52lastRead = addr;53readCount++;54used = true;55}5657void MarkReadAsAddr(u32 addr) {58if (firstReadAsAddr == -1)59firstReadAsAddr = addr;60lastReadAsAddr = addr;61readAsAddrCount++;62used = true;63}6465void MarkWrite(u32 addr) {66if (firstWrite == -1)67firstWrite = addr;68lastWrite = addr;69writeCount++;70used = true;71}72};7374struct AnalysisResults {75RegisterAnalysisResults r[MIPS_NUM_GPRS];76};7778AnalysisResults Analyze(u32 address);7980// This tells us if the reg is used within intrs of addr (also includes likely delay slots.)81bool IsRegisterUsed(MIPSGPReg reg, u32 addr, int instrs);82// This tells us if the reg is clobbered within intrs of addr (e.g. it is surely not used.)83bool IsRegisterClobbered(MIPSGPReg reg, u32 addr, int instrs);8485struct AnalyzedFunction {86u32 start;87u32 end;88u64 hash;89u32 size;90bool isStraightLeaf;91bool hasHash;92bool usesVFPU;93bool foundInSymbolMap;94char name[64];95};9697struct ReplacementTableEntry;9899void Reset();100101bool IsRegisterUsed(u32 reg, u32 addr);102// This will not only create a database of "AnalyzedFunction" structs, it also103// will insert all the functions it finds into the symbol map, if insertSymbols is true.104105// If we have loaded symbols from the elf, we'll register functions as they are touched106// so that we don't just dump them all in the cache.107void RegisterFunction(u32 startAddr, u32 size, const char *name);108// Returns new insertSymbols value for FinalizeScan().109bool ScanForFunctions(u32 startAddr, u32 endAddr, bool insertSymbols);110void FinalizeScan(bool insertSymbols);111void ForgetFunctions(u32 startAddr, u32 endAddr);112void PrecompileFunctions();113void PrecompileFunction(u32 startAddr, u32 length);114115void SetHashMapFilename(const std::string& filename = "");116void LoadBuiltinHashMap();117void LoadHashMap(const Path &filename);118void StoreHashMap(Path filename = Path());119120const char *LookupHash(u64 hash, u32 funcSize);121void ReplaceFunctions();122123void UpdateHashMap();124void ApplyHashMap();125126std::vector<MIPSGPReg> GetInputRegs(MIPSOpcode op);127std::vector<MIPSGPReg> GetOutputRegs(MIPSOpcode op);128129MIPSGPReg GetOutGPReg(MIPSOpcode op);130bool ReadsFromGPReg(MIPSOpcode op, MIPSGPReg reg);131bool IsDelaySlotNiceReg(MIPSOpcode branchOp, MIPSOpcode op, MIPSGPReg reg1, MIPSGPReg reg2 = MIPS_REG_ZERO);132bool IsDelaySlotNiceVFPU(MIPSOpcode branchOp, MIPSOpcode op);133bool IsDelaySlotNiceFPU(MIPSOpcode branchOp, MIPSOpcode op);134bool IsSyscall(MIPSOpcode op);135136bool OpWouldChangeMemory(u32 pc, u32 addr, u32 size);137int OpMemoryAccessSize(u32 pc);138bool IsOpMemoryWrite(u32 pc);139bool OpHasDelaySlot(u32 pc);140141typedef struct {142DebugInterface* cpu;143u32 opcodeAddress;144MIPSOpcode encodedOpcode;145146// shared between branches and conditional moves147bool isConditional;148bool conditionMet;149150// branches151u32 branchTarget;152bool isBranch;153bool isLinkedBranch;154bool isLikelyBranch;155bool isBranchToRegister;156int branchRegisterNum;157158// data access159bool isDataAccess;160int dataSize;161u32 dataAddress;162163bool hasRelevantAddress;164u32 relevantAddress;165} MipsOpcodeInfo;166167MipsOpcodeInfo GetOpcodeInfo(DebugInterface* cpu, u32 address);168169} // namespace MIPSAnalyst170171172