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/ARM64/Arm64RegCache.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 "Core/MIPS/MIPS.h"20#include "Common/Arm64Emitter.h"2122namespace Arm64JitConstants {2324const Arm64Gen::ARM64Reg DOWNCOUNTREG = Arm64Gen::W24;25const Arm64Gen::ARM64Reg FLAGTEMPREG = Arm64Gen::X25;26const Arm64Gen::ARM64Reg JITBASEREG = Arm64Gen::X26;27const Arm64Gen::ARM64Reg CTXREG = Arm64Gen::X27;28const Arm64Gen::ARM64Reg MEMBASEREG = Arm64Gen::X28;29const Arm64Gen::ARM64Reg SCRATCH1_64 = Arm64Gen::X16;30const Arm64Gen::ARM64Reg SCRATCH2_64 = Arm64Gen::X17;31const Arm64Gen::ARM64Reg SCRATCH1 = Arm64Gen::W16;32const Arm64Gen::ARM64Reg SCRATCH2 = Arm64Gen::W17;3334enum {35TOTAL_MAPPABLE_MIPSREGS = 36,36};3738enum RegMIPSLoc {39ML_IMM,40ML_ARMREG,41// In an arm reg, but an adjusted pointer (not pointerified - unaligned.)42ML_ARMREG_AS_PTR,43// In an arm reg, but also has a known immediate value.44ML_ARMREG_IMM,45ML_MEM,46};4748// Initing is the default so the flag is reversed.49enum {50MAP_DIRTY = 1,51MAP_NOINIT = 2 | MAP_DIRTY,52};5354} // namespace5556namespace MIPSAnalyst {57struct AnalysisResults;58};5960typedef int MIPSReg;6162struct RegARM64 {63MIPSGPReg mipsReg; // if -1, no mipsreg attached.64bool isDirty; // Should the register be written back?65bool pointerified; // Has used movk to move the memory base into the top part of the reg. Note - still usable as 32-bit reg!66bool tempLocked; // Reserved for a temp register.67};6869struct RegMIPS {70// Where is this MIPS register?71Arm64JitConstants::RegMIPSLoc loc;72// Data (both or only one may be used, depending on loc.)73u64 imm;74Arm64Gen::ARM64Reg reg; // reg index75bool spillLock; // if true, this register cannot be spilled.76bool isStatic; // if true, this register will not be written back to ram by the regcache77// If loc == ML_MEM, it's back in its location in the CPU context struct.78};7980namespace MIPSComp {81struct JitOptions;82struct JitState;83}8485class Arm64RegCache {86public:87Arm64RegCache(MIPSState *mipsState, MIPSComp::JitState *js, MIPSComp::JitOptions *jo);88~Arm64RegCache() {}8990void Init(Arm64Gen::ARM64XEmitter *emitter);91void Start(MIPSAnalyst::AnalysisResults &stats);9293// Protect the arm register containing a MIPS register from spilling, to ensure that94// it's being kept allocated.95void SpillLock(MIPSGPReg reg, MIPSGPReg reg2 = MIPS_REG_INVALID, MIPSGPReg reg3 = MIPS_REG_INVALID, MIPSGPReg reg4 = MIPS_REG_INVALID);96void ReleaseSpillLock(MIPSGPReg reg, MIPSGPReg reg2 = MIPS_REG_INVALID, MIPSGPReg reg3 = MIPS_REG_INVALID, MIPSGPReg reg4 = MIPS_REG_INVALID);97void ReleaseSpillLocksAndDiscardTemps();9899void SetImm(MIPSGPReg reg, u64 immVal);100bool IsImm(MIPSGPReg reg) const;101bool IsPureImm(MIPSGPReg reg) const;102u64 GetImm(MIPSGPReg reg) const;103// Optimally set a register to an imm value (possibly using another register.)104void SetRegImm(Arm64Gen::ARM64Reg reg, u64 imm);105106// May fail and return INVALID_REG if it needs flushing.107Arm64Gen::ARM64Reg TryMapTempImm(MIPSGPReg);108109// Returns an ARM register containing the requested MIPS register.110Arm64Gen::ARM64Reg MapReg(MIPSGPReg reg, int mapFlags = 0);111Arm64Gen::ARM64Reg MapRegAsPointer(MIPSGPReg reg);112113bool IsMapped(MIPSGPReg reg);114bool IsMappedAsPointer(MIPSGPReg reg);115bool IsInRAM(MIPSGPReg reg);116117void MarkDirty(Arm64Gen::ARM64Reg reg);118void MapIn(MIPSGPReg rs);119void MapInIn(MIPSGPReg rd, MIPSGPReg rs);120void MapDirtyIn(MIPSGPReg rd, MIPSGPReg rs, bool avoidLoad = true);121void MapDirtyInIn(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, bool avoidLoad = true);122void MapDirtyDirtyIn(MIPSGPReg rd1, MIPSGPReg rd2, MIPSGPReg rs, bool avoidLoad = true);123void MapDirtyDirtyInIn(MIPSGPReg rd1, MIPSGPReg rd2, MIPSGPReg rs, MIPSGPReg rt, bool avoidLoad = true);124void FlushArmReg(Arm64Gen::ARM64Reg r);125void FlushBeforeCall();126void FlushAll();127void FlushR(MIPSGPReg r);128void DiscardR(MIPSGPReg r);129130Arm64Gen::ARM64Reg GetAndLockTempR();131132Arm64Gen::ARM64Reg R(MIPSGPReg preg); // Returns a cached register, while checking that it's NOT mapped as a pointer133Arm64Gen::ARM64Reg RPtr(MIPSGPReg preg); // Returns a cached register, if it has been mapped as a pointer134135void SetEmitter(Arm64Gen::ARM64XEmitter *emitter) { emit_ = emitter; }136137// For better log output only.138void SetCompilerPC(u32 compilerPC) { compilerPC_ = compilerPC; }139140int GetMipsRegOffset(MIPSGPReg r);141142// These are called once on startup to generate functions, that you should then call.143void EmitLoadStaticRegisters();144void EmitSaveStaticRegisters();145146private:147struct StaticAllocation {148MIPSGPReg mr;149Arm64Gen::ARM64Reg ar;150bool pointerified;151};152const StaticAllocation *GetStaticAllocations(int &count);153const Arm64Gen::ARM64Reg *GetMIPSAllocationOrder(int &count);154void MapRegTo(Arm64Gen::ARM64Reg reg, MIPSGPReg mipsReg, int mapFlags);155Arm64Gen::ARM64Reg AllocateReg();156Arm64Gen::ARM64Reg FindBestToSpill(bool unusedOnly, bool *clobbered);157Arm64Gen::ARM64Reg ARM64RegForFlush(MIPSGPReg r);158159MIPSState *mips_;160Arm64Gen::ARM64XEmitter *emit_;161MIPSComp::JitState *js_;162MIPSComp::JitOptions *jo_;163u32 compilerPC_;164165enum {166NUM_ARMREG = 32, // 31 actual registers, plus the zero/sp register which is not mappable.167NUM_MIPSREG = Arm64JitConstants::TOTAL_MAPPABLE_MIPSREGS,168};169170RegARM64 ar[NUM_ARMREG];171RegMIPS mr[NUM_MIPSREG];172};173174175