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/Arm64Jit.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 "Common/CPUDetect.h"20#include "Common/ArmCommon.h"21#include "Common/Arm64Emitter.h"22#include "Core/MIPS/JitCommon/JitState.h"23#include "Core/MIPS/JitCommon/JitBlockCache.h"24#include "Core/MIPS/JitCommon/JitCommon.h"25#include "Core/MIPS/ARM64/Arm64RegCache.h"26#include "Core/MIPS/ARM64/Arm64RegCacheFPU.h"27#include "Core/MIPS/MIPSVFPUUtils.h"2829#ifndef offsetof30#include "stddef.h"31#endif3233namespace MIPSComp {3435class Arm64Jit : public Arm64Gen::ARM64CodeBlock, public JitInterface, public MIPSFrontendInterface {36public:37Arm64Jit(MIPSState *mipsState);38virtual ~Arm64Jit();3940void DoState(PointerWrap &p) override;4142const JitOptions &GetJitOptions() { return jo; }4344// Compiled ops should ignore delay slots45// the compiler will take care of them by itself46// OR NOT47void Comp_Generic(MIPSOpcode op) override;4849void RunLoopUntil(u64 globalticks) override;5051void Compile(u32 em_address) override; // Compiles a block at current MIPS PC52const u8 *DoJit(u32 em_address, JitBlock *b);5354const u8 *GetCrashHandler() const override { return crashHandler; }55bool CodeInRange(const u8 *ptr) const override { return IsInSpace(ptr); }56bool DescribeCodePtr(const u8 *ptr, std::string &name) override;57MIPSOpcode GetOriginalOp(MIPSOpcode op) override;5859void Comp_RunBlock(MIPSOpcode op) override;60void Comp_ReplacementFunc(MIPSOpcode op) override;6162// Ops63void Comp_ITypeMem(MIPSOpcode op) override;64void Comp_StoreSync(MIPSOpcode op) override;65void Comp_Cache(MIPSOpcode op) override;6667void Comp_RelBranch(MIPSOpcode op) override;68void Comp_RelBranchRI(MIPSOpcode op) override;69void Comp_FPUBranch(MIPSOpcode op) override;70void Comp_FPULS(MIPSOpcode op) override;71void Comp_FPUComp(MIPSOpcode op) override;72void Comp_Jump(MIPSOpcode op) override;73void Comp_JumpReg(MIPSOpcode op) override;74void Comp_Syscall(MIPSOpcode op) override;75void Comp_Break(MIPSOpcode op) override;7677void Comp_IType(MIPSOpcode op) override;78void Comp_RType2(MIPSOpcode op) override;79void Comp_RType3(MIPSOpcode op) override;80void Comp_ShiftType(MIPSOpcode op) override;81void Comp_Allegrex(MIPSOpcode op) override;82void Comp_Allegrex2(MIPSOpcode op) override;83void Comp_VBranch(MIPSOpcode op) override;84void Comp_MulDivType(MIPSOpcode op) override;85void Comp_Special3(MIPSOpcode op) override;8687void Comp_FPU3op(MIPSOpcode op) override;88void Comp_FPU2op(MIPSOpcode op) override;89void Comp_mxc1(MIPSOpcode op) override;9091void Comp_DoNothing(MIPSOpcode op) override;9293void Comp_SV(MIPSOpcode op) override;94void Comp_SVQ(MIPSOpcode op) override;95void Comp_VPFX(MIPSOpcode op) override;96void Comp_VVectorInit(MIPSOpcode op) override;97void Comp_VMatrixInit(MIPSOpcode op) override;98void Comp_VDot(MIPSOpcode op) override;99void Comp_VecDo3(MIPSOpcode op) override;100void Comp_VV2Op(MIPSOpcode op) override;101void Comp_Mftv(MIPSOpcode op) override;102void Comp_Vmfvc(MIPSOpcode op) override;103void Comp_Vmtvc(MIPSOpcode op) override;104void Comp_Vmmov(MIPSOpcode op) override;105void Comp_VScl(MIPSOpcode op) override;106void Comp_Vmmul(MIPSOpcode op) override;107void Comp_Vmscl(MIPSOpcode op) override;108void Comp_Vtfm(MIPSOpcode op) override;109void Comp_VHdp(MIPSOpcode op) override;110void Comp_VCrs(MIPSOpcode op) override;111void Comp_VDet(MIPSOpcode op) override;112void Comp_Vi2x(MIPSOpcode op) override;113void Comp_Vx2i(MIPSOpcode op) override;114void Comp_Vf2i(MIPSOpcode op) override;115void Comp_Vi2f(MIPSOpcode op) override;116void Comp_Vh2f(MIPSOpcode op) override;117void Comp_Vcst(MIPSOpcode op) override;118void Comp_Vhoriz(MIPSOpcode op) override;119void Comp_VRot(MIPSOpcode op) override;120void Comp_VIdt(MIPSOpcode op) override;121void Comp_Vcmp(MIPSOpcode op) override;122void Comp_Vcmov(MIPSOpcode op) override;123void Comp_Viim(MIPSOpcode op) override;124void Comp_Vfim(MIPSOpcode op) override;125void Comp_VCrossQuat(MIPSOpcode op) override;126void Comp_Vsgn(MIPSOpcode op) override;127void Comp_Vocp(MIPSOpcode op) override;128void Comp_ColorConv(MIPSOpcode op) override;129void Comp_Vbfy(MIPSOpcode op) override;130131// Non-NEON: VPFX132133// NEON implementations of the VFPU ops.134void CompNEON_SV(MIPSOpcode op);135void CompNEON_SVQ(MIPSOpcode op);136void CompNEON_VVectorInit(MIPSOpcode op);137void CompNEON_VMatrixInit(MIPSOpcode op);138void CompNEON_VDot(MIPSOpcode op);139void CompNEON_VecDo3(MIPSOpcode op);140void CompNEON_VV2Op(MIPSOpcode op);141void CompNEON_Mftv(MIPSOpcode op);142void CompNEON_Vmfvc(MIPSOpcode op);143void CompNEON_Vmtvc(MIPSOpcode op);144void CompNEON_Vmmov(MIPSOpcode op);145void CompNEON_VScl(MIPSOpcode op);146void CompNEON_Vmmul(MIPSOpcode op);147void CompNEON_Vmscl(MIPSOpcode op);148void CompNEON_Vtfm(MIPSOpcode op);149void CompNEON_VHdp(MIPSOpcode op);150void CompNEON_VCrs(MIPSOpcode op);151void CompNEON_VDet(MIPSOpcode op);152void CompNEON_Vi2x(MIPSOpcode op);153void CompNEON_Vx2i(MIPSOpcode op);154void CompNEON_Vf2i(MIPSOpcode op);155void CompNEON_Vi2f(MIPSOpcode op);156void CompNEON_Vh2f(MIPSOpcode op);157void CompNEON_Vcst(MIPSOpcode op);158void CompNEON_Vhoriz(MIPSOpcode op);159void CompNEON_VRot(MIPSOpcode op);160void CompNEON_VIdt(MIPSOpcode op);161void CompNEON_Vcmp(MIPSOpcode op);162void CompNEON_Vcmov(MIPSOpcode op);163void CompNEON_Viim(MIPSOpcode op);164void CompNEON_Vfim(MIPSOpcode op);165void CompNEON_VCrossQuat(MIPSOpcode op);166void CompNEON_Vsgn(MIPSOpcode op);167void CompNEON_Vocp(MIPSOpcode op);168void CompNEON_ColorConv(MIPSOpcode op);169void CompNEON_Vbfy(MIPSOpcode op);170171int Replace_fabsf() override;172173JitBlockCache *GetBlockCache() override { return &blocks; }174JitBlockCacheDebugInterface *GetBlockCacheDebugInterface() override { return &blocks; }175176std::vector<u32> SaveAndClearEmuHackOps() override { return blocks.SaveAndClearEmuHackOps(); }177void RestoreSavedEmuHackOps(std::vector<u32> saved) override { blocks.RestoreSavedEmuHackOps(saved); }178179void ClearCache() override;180void InvalidateCacheAt(u32 em_address, int length = 4) override;181void UpdateFCR31() override;182183void EatPrefix() override { js.EatPrefix(); }184185const u8 *GetDispatcher() const override {186return dispatcher;187}188bool IsAtDispatchFetch(const u8 *ptr) const override {189return ptr == dispatcherFetch;190}191192void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override;193void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override;194195private:196void GenerateFixedCode(const JitOptions &jo);197void FlushAll();198void FlushPrefixV();199200u32 GetCompilerPC();201void CompileDelaySlot(int flags);202void EatInstruction(MIPSOpcode op);203void AddContinuedBlock(u32 dest);204MIPSOpcode GetOffsetInstruction(int offset);205206void WriteDownCount(int offset = 0, bool updateFlags = true);207void WriteDownCountR(Arm64Gen::ARM64Reg reg, bool updateFlags = true);208void RestoreRoundingMode(bool force = false);209void ApplyRoundingMode(bool force = false);210void UpdateRoundingMode(u32 fcr31 = -1);211void MovFromPC(Arm64Gen::ARM64Reg r);212void MovToPC(Arm64Gen::ARM64Reg r);213214bool ReplaceJalTo(u32 dest);215216// Clobbers SCRATCH2.217void SaveStaticRegisters();218// Clobbers SCRATCH2.219void LoadStaticRegisters();220221void WriteExit(u32 destination, int exit_num);222void WriteExitDestInR(Arm64Gen::ARM64Reg Reg);223void WriteSyscallExit();224bool CheckJitBreakpoint(u32 addr, int downcountOffset);225bool CheckMemoryBreakpoint(int instructionOffset = 0);226227// Utility compilation functions228void BranchFPFlag(MIPSOpcode op, CCFlags cc, bool likely);229void BranchVFPUFlag(MIPSOpcode op, CCFlags cc, bool likely);230void BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool likely);231void BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely);232233// Utilities to reduce duplicated code234void CompImmLogic(MIPSGPReg rs, MIPSGPReg rt, u32 uimm, void (ARM64XEmitter::*arith)(Arm64Gen::ARM64Reg dst, Arm64Gen::ARM64Reg src, Arm64Gen::ARM64Reg src2), bool (ARM64XEmitter::*tryArithI2R)(Arm64Gen::ARM64Reg dst, Arm64Gen::ARM64Reg src, u64 val), u32 (*eval)(u32 a, u32 b));235void CompType3(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, void (ARM64XEmitter::*arithOp2)(Arm64Gen::ARM64Reg dst, Arm64Gen::ARM64Reg rm, Arm64Gen::ARM64Reg rn), bool (ARM64XEmitter::*tryArithI2R)(Arm64Gen::ARM64Reg dst, Arm64Gen::ARM64Reg rm, u64 val), u32 (*eval)(u32 a, u32 b), bool symmetric = false);236void CompShiftImm(MIPSOpcode op, Arm64Gen::ShiftType shiftType, int sa);237void CompShiftVar(MIPSOpcode op, Arm64Gen::ShiftType shiftType);238void CompVrotShuffle(u8 *dregs, int imm, VectorSize sz, bool negSin);239240void ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz);241void ApplyPrefixD(const u8 *vregs, VectorSize sz);242void GetVectorRegsPrefixS(u8 *regs, VectorSize sz, int vectorReg) {243_assert_(js.prefixSFlag & JitState::PREFIX_KNOWN);244GetVectorRegs(regs, sz, vectorReg);245ApplyPrefixST(regs, js.prefixS, sz);246}247void GetVectorRegsPrefixT(u8 *regs, VectorSize sz, int vectorReg) {248_assert_(js.prefixTFlag & JitState::PREFIX_KNOWN);249GetVectorRegs(regs, sz, vectorReg);250ApplyPrefixST(regs, js.prefixT, sz);251}252void GetVectorRegsPrefixD(u8 *regs, VectorSize sz, int vectorReg);253254// Utils255void SetScratch1ToEffectiveAddress(MIPSGPReg rs, s16 offset);256std::vector<Arm64Gen::FixupBranch> SetScratch1ForSafeAddress(MIPSGPReg rs, s16 offset, Arm64Gen::ARM64Reg tempReg);257void Comp_ITypeMemLR(MIPSOpcode op, bool load);258259JitBlockCache blocks;260JitOptions jo;261JitState js;262263Arm64RegCache gpr;264Arm64RegCacheFPU fpr;265266Arm64Gen::ARM64FloatEmitter fp;267268MIPSState *mips_;269270int dontLogBlocks;271int logBlocks;272273public:274// Code pointers275const u8 *enterDispatcher;276277const u8 *outerLoop;278const u8 *outerLoopPCInSCRATCH1;279const u8 *dispatcherCheckCoreState;280const u8 *dispatcherPCInSCRATCH1;281const u8 *dispatcher;282const u8 *dispatcherNoCheck;283const u8 *dispatcherFetch;284285const u8 *saveStaticRegisters;286const u8 *loadStaticRegisters;287288const u8 *restoreRoundingMode;289const u8 *applyRoundingMode;290const u8 *updateRoundingMode;291292const u8 *crashHandler;293294int jitStartOffset;295296// Indexed by FPCR FZ:RN bits for convenience. Uses SCRATCH2.297const u8 *convertS0ToSCRATCH1[8];298};299300} // namespace MIPSComp301302303304