mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Now builds on Playbook and Dev Alpha Make emulator more compatible with other OS (case sensitivity, defines, includes) Uses Android's code paths and backend
195 lines
5.5 KiB
C++
195 lines
5.5 KiB
C++
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official git repository and contact information can be found at
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
#include "ABI.h"
|
|
#include <ArmEmitter.h>
|
|
|
|
#include "../../MemMap.h"
|
|
|
|
#include "../MIPS.h"
|
|
#include "../../CoreTiming.h"
|
|
#include "MemoryUtil.h"
|
|
|
|
#include "ABI.h"
|
|
#include "Jit.h"
|
|
#include "../JitCommon/JitCommon.h"
|
|
#include "../../Core.h"
|
|
#include "Asm.h"
|
|
|
|
using namespace ArmGen;
|
|
|
|
//static int temp32; // unused?
|
|
|
|
//TODO - make an option
|
|
//#if _DEBUG
|
|
static bool enableDebug = false;
|
|
//#else
|
|
// bool enableDebug = false;
|
|
//#endif
|
|
|
|
//static bool enableStatistics = false; //unused?
|
|
|
|
//The standard ARM calling convention allocates the 16 ARM registers as:
|
|
|
|
// r15 is the program counter.
|
|
// r14 is the link register. (The BL instruction, used in a subroutine call, stores the return address in this register).
|
|
// r13 is the stack pointer. (The Push/Pop instructions in "Thumb" operating mode use this register only).
|
|
// r12 is the Intra-Procedure-call scratch register.
|
|
// r4 to r11: used to hold local variables.
|
|
// r0 to r3: used to hold argument values passed to a subroutine, and also hold results returned from a subroutine.
|
|
|
|
// R2, R3, R4, R5, R6, R7, R8, R10, R11 // omitting R9?
|
|
|
|
|
|
// STATIC ALLOCATION ARM:
|
|
// R11 : Memory base pointer.
|
|
|
|
extern volatile CoreState coreState;
|
|
|
|
void Jit()
|
|
{
|
|
MIPSComp::jit->Compile(currentMIPS->pc);
|
|
}
|
|
|
|
// PLAN: no more block numbers - crazy opcodes just contain offset within
|
|
// dynarec buffer
|
|
// At this offset - 4, there is an int specifying the block number.
|
|
|
|
void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit)
|
|
{
|
|
enterCode = AlignCode16();
|
|
//ARMABI_PushAllCalleeSavedRegsAndAdjustStack();
|
|
/*
|
|
#ifndef _M_IX86
|
|
// Two statically allocated registers.
|
|
MOV(64, R(RBX), Imm64((u64)Memory::base));
|
|
MOV(64, R(R15), Imm64((u64)jit->GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough
|
|
#endif
|
|
*/
|
|
|
|
SetCC(CC_AL);
|
|
//ARMABI_MOVIMM32(R11, (u32)Memory::base);
|
|
//ARMABI_MOVIMM32(R10, (u32)jit->GetBlockCache()->GetCodePointers());
|
|
|
|
outerLoop = GetCodePtr();
|
|
//ARMABI_CallFunction(reinterpret_cast<void *>(&CoreTiming::Advance));
|
|
FixupBranch skipToRealDispatch = B(); //skip the sync and compare first time
|
|
|
|
dispatcher = GetCodePtr();
|
|
// The result of slice decrementation should be in flags if somebody jumped here
|
|
// IMPORTANT - We jump on negative, not carry!!!
|
|
SetCC(CC_LT);
|
|
FixupBranch bail = B();
|
|
|
|
SetCC(CC_AL);
|
|
SetJumpTarget(skipToRealDispatch);
|
|
//INT3();
|
|
|
|
dispatcherNoCheck = GetCodePtr();
|
|
// LDR(R0, R11, R0, M(&mips->pc));
|
|
dispatcherPcInR0 = GetCodePtr();
|
|
|
|
_assert_msg_(CPU, Memory::base != 0, "Memory base bogus");
|
|
//ARMABI_MOVIMM32(R1, Memory::MEMVIEW32_MASK + 1);
|
|
AND(R0, R0, R1);
|
|
LDR(R0, R11, R0);
|
|
MOV(R1, R0);
|
|
//AND(R1, R1, Imm32(MIPS_EMUHACK_MASK));
|
|
//AND(R0, R0, Imm32(MIPS_EMUHACK_VALUE_MASK));
|
|
//CMP(R0, Imm32(MIPS_EMUHACK_OPCODE));
|
|
SetCC(CC_NEQ);
|
|
FixupBranch notfound = B();
|
|
SetCC(CC_AL);
|
|
// IDEA - we have 24 bits, why not just use offsets from base of code?
|
|
if (enableDebug)
|
|
{
|
|
// ADD(32, M(&mips->debugCount), Imm8(1));
|
|
}
|
|
//grab from list and jump to it
|
|
// ADD(R0, R10, LSL(R0, 2));
|
|
B(R0);
|
|
SetJumpTarget(notfound);
|
|
|
|
//BL(&Jit);
|
|
|
|
//B(dispatcherNoCheck); // no point in special casing this
|
|
|
|
SetJumpTarget(bail);
|
|
doTiming = GetCodePtr();
|
|
|
|
testExternalExceptions = GetCodePtr();
|
|
//TEST(32, M((void *)&mips->exceptions), Imm32(MIPSState::BREAKING_EXCEPTIONS));
|
|
//FixupBranch noExtException = J_CC(CC_Z);
|
|
//MOV(32, R(EAX), M(&mips->pc));
|
|
// MOV(32, M(&NPC), R(EAX));
|
|
// ABI_CallFunction(reinterpret_cast<void *>(&MIPSState::CheckExternalExceptions));
|
|
//SetJumpTarget(noExtException);
|
|
|
|
//CMP(M((void*)&coreState), Imm8(0));
|
|
SetCC(CC_EQ);
|
|
//B(outerLoop);
|
|
SetCC(CC_AL);
|
|
|
|
//Landing pad for drec space
|
|
//ARMABI_PopAllCalleeSavedRegsAndAdjustStack();
|
|
B(_LR);
|
|
|
|
breakpointBailout = GetCodePtr();
|
|
|
|
//Landing pad for drec space
|
|
//ARMABI_PopAllCalleeSavedRegsAndAdjustStack();
|
|
//RET();
|
|
|
|
GenerateCommon();
|
|
}
|
|
|
|
void AsmRoutineManager::GenerateCommon()
|
|
{
|
|
/*
|
|
fifoDirectWrite8 = AlignCode4();
|
|
GenFifoWrite(8);
|
|
fifoDirectWrite16 = AlignCode4();
|
|
GenFifoWrite(16);
|
|
fifoDirectWrite32 = AlignCode4();
|
|
GenFifoWrite(32);
|
|
fifoDirectWriteFloat = AlignCode4();
|
|
GenFifoFloatWrite();
|
|
fifoDirectWriteXmm64 = AlignCode4();
|
|
GenFifoXmm64Write();
|
|
|
|
GenQuantizedLoads();
|
|
GenQuantizedStores();
|
|
GenQuantizedSingleStores();
|
|
*/
|
|
|
|
//CMPSD(R(XMM0), M(&zero),
|
|
// TODO
|
|
|
|
// Fast write routines - special case the most common hardware write
|
|
// TODO: use this.
|
|
// Even in x86, the param values will be in the right registers.
|
|
/*
|
|
const u8 *fastMemWrite8 = AlignCode16();
|
|
CMP(32, R(ABI_PARAM2), Imm32(0xCC008000));
|
|
FixupBranch skip_fast_write = J_CC(CC_NE, false);
|
|
MOV(32, EAX, M(&m_gatherPipeCount));
|
|
MOV(8, MDisp(EAX, (u32)&m_gatherPipe), ABI_PARAM1);
|
|
ADD(32, 1, M(&m_gatherPipeCount));
|
|
RET();
|
|
SetJumpTarget(skip_fast_write);
|
|
CALL((void *)&Memory::Write_U8);*/
|
|
}
|