2019-06-21 23:28:32 +00:00
|
|
|
#include "ARMJIT.h"
|
|
|
|
|
2019-06-25 15:09:27 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2019-07-14 02:33:36 +00:00
|
|
|
#include "Config.h"
|
|
|
|
|
2019-06-21 23:28:32 +00:00
|
|
|
#include "ARMJIT_x64/ARMJIT_Compiler.h"
|
|
|
|
|
|
|
|
namespace ARMJIT
|
|
|
|
{
|
|
|
|
|
|
|
|
Compiler* compiler;
|
|
|
|
BlockCache cache;
|
|
|
|
|
|
|
|
#define DUP2(x) x, x
|
|
|
|
|
|
|
|
static ptrdiff_t JIT_MEM[2][32] = {
|
|
|
|
//arm9
|
|
|
|
{
|
|
|
|
/* 0X*/ DUP2(offsetof(BlockCache, ARM9_ITCM)),
|
|
|
|
/* 1X*/ DUP2(offsetof(BlockCache, ARM9_ITCM)), // mirror
|
|
|
|
/* 2X*/ DUP2(offsetof(BlockCache, MainRAM)),
|
|
|
|
/* 3X*/ DUP2(offsetof(BlockCache, SWRAM)),
|
|
|
|
/* 4X*/ DUP2(-1),
|
|
|
|
/* 5X*/ DUP2(-1),
|
|
|
|
/* 6X*/ -1,
|
|
|
|
offsetof(BlockCache, ARM9_LCDC), // Plain ARM9-CPU Access (LCDC mode) (max 656KB)
|
|
|
|
/* 7X*/ DUP2(-1),
|
|
|
|
/* 8X*/ DUP2(-1),
|
|
|
|
/* 9X*/ DUP2(-1),
|
|
|
|
/* AX*/ DUP2(-1),
|
|
|
|
/* BX*/ DUP2(-1),
|
|
|
|
/* CX*/ DUP2(-1),
|
|
|
|
/* DX*/ DUP2(-1),
|
|
|
|
/* EX*/ DUP2(-1),
|
|
|
|
/* FX*/ DUP2(offsetof(BlockCache, ARM9_BIOS))
|
|
|
|
},
|
|
|
|
//arm7
|
|
|
|
{
|
|
|
|
/* 0X*/ DUP2(offsetof(BlockCache, ARM7_BIOS)),
|
|
|
|
/* 1X*/ DUP2(-1),
|
|
|
|
/* 2X*/ DUP2(offsetof(BlockCache, MainRAM)),
|
|
|
|
/* 3X*/ offsetof(BlockCache, SWRAM),
|
|
|
|
offsetof(BlockCache, ARM7_WRAM),
|
2019-06-30 11:35:03 +00:00
|
|
|
/* 4X*/ DUP2(-1),
|
2019-06-21 23:28:32 +00:00
|
|
|
/* 5X*/ DUP2(-1),
|
|
|
|
/* 6X*/ DUP2(offsetof(BlockCache, ARM7_WVRAM)), /* contrary to Gbatek, melonDS and itself,
|
|
|
|
DeSmuME doesn't mirror the 64 MB region at 0x6800000 */
|
|
|
|
/* 7X*/ DUP2(-1),
|
|
|
|
/* 8X*/ DUP2(-1),
|
|
|
|
/* 9X*/ DUP2(-1),
|
|
|
|
/* AX*/ DUP2(-1),
|
|
|
|
/* BX*/ DUP2(-1),
|
|
|
|
/* CX*/ DUP2(-1),
|
|
|
|
/* DX*/ DUP2(-1),
|
|
|
|
/* EX*/ DUP2(-1),
|
|
|
|
/* FX*/ DUP2(-1)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static u32 JIT_MASK[2][32] = {
|
|
|
|
//arm9
|
|
|
|
{
|
|
|
|
/* 0X*/ DUP2(0x00007FFF),
|
|
|
|
/* 1X*/ DUP2(0x00007FFF),
|
|
|
|
/* 2X*/ DUP2(0x003FFFFF),
|
|
|
|
/* 3X*/ DUP2(0x00007FFF),
|
|
|
|
/* 4X*/ DUP2(0x00000000),
|
|
|
|
/* 5X*/ DUP2(0x00000000),
|
|
|
|
/* 6X*/ 0x00000000,
|
|
|
|
0x000FFFFF,
|
|
|
|
/* 7X*/ DUP2(0x00000000),
|
|
|
|
/* 8X*/ DUP2(0x00000000),
|
|
|
|
/* 9X*/ DUP2(0x00000000),
|
|
|
|
/* AX*/ DUP2(0x00000000),
|
|
|
|
/* BX*/ DUP2(0x00000000),
|
|
|
|
/* CX*/ DUP2(0x00000000),
|
|
|
|
/* DX*/ DUP2(0x00000000),
|
|
|
|
/* EX*/ DUP2(0x00000000),
|
|
|
|
/* FX*/ DUP2(0x00007FFF)
|
|
|
|
},
|
|
|
|
//arm7
|
|
|
|
{
|
|
|
|
/* 0X*/ DUP2(0x00003FFF),
|
|
|
|
/* 1X*/ DUP2(0x00000000),
|
|
|
|
/* 2X*/ DUP2(0x003FFFFF),
|
|
|
|
/* 3X*/ 0x00007FFF,
|
|
|
|
0x0000FFFF,
|
|
|
|
/* 4X*/ 0x00000000,
|
|
|
|
0x0000FFFF,
|
|
|
|
/* 5X*/ DUP2(0x00000000),
|
|
|
|
/* 6X*/ DUP2(0x0003FFFF),
|
|
|
|
/* 7X*/ DUP2(0x00000000),
|
|
|
|
/* 8X*/ DUP2(0x00000000),
|
|
|
|
/* 9X*/ DUP2(0x00000000),
|
|
|
|
/* AX*/ DUP2(0x00000000),
|
|
|
|
/* BX*/ DUP2(0x00000000),
|
|
|
|
/* CX*/ DUP2(0x00000000),
|
|
|
|
/* DX*/ DUP2(0x00000000),
|
|
|
|
/* EX*/ DUP2(0x00000000),
|
|
|
|
/* FX*/ DUP2(0x00000000)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#undef DUP2
|
|
|
|
|
|
|
|
|
|
|
|
void Init()
|
|
|
|
{
|
|
|
|
memset(&cache, 0, sizeof(BlockCache));
|
|
|
|
|
2019-07-21 11:36:48 +00:00
|
|
|
for (int i = 0; i < 0x2000; i++)
|
|
|
|
cache.AddrMapping9[i] = JIT_MEM[0][i >> 8] == -1 ? NULL :
|
|
|
|
(CompiledBlock*)((u8*)&cache + JIT_MEM[0][i >> 8])
|
|
|
|
+ (((i << 15) & JIT_MASK[0][i >> 8]) >> 1);
|
|
|
|
for (int i = 0; i < 0x4000; i++)
|
|
|
|
cache.AddrMapping7[i] = JIT_MEM[1][i >> 9] == -1 ? NULL :
|
|
|
|
(CompiledBlock*)((u8*)&cache + JIT_MEM[1][i >> 9])
|
|
|
|
+ (((i << 14) & JIT_MASK[1][i >> 9]) >> 1);
|
2019-06-21 23:28:32 +00:00
|
|
|
|
|
|
|
compiler = new Compiler();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DeInit()
|
|
|
|
{
|
|
|
|
delete compiler;
|
|
|
|
}
|
|
|
|
|
2019-07-11 14:22:47 +00:00
|
|
|
CompiledBlock CompileBlock(ARM* cpu)
|
2019-06-21 23:28:32 +00:00
|
|
|
{
|
|
|
|
bool thumb = cpu->CPSR & 0x20;
|
|
|
|
|
2019-07-14 02:33:36 +00:00
|
|
|
if (Config::JIT_MaxBlockSize < 1)
|
|
|
|
Config::JIT_MaxBlockSize = 1;
|
|
|
|
if (Config::JIT_MaxBlockSize > 32)
|
|
|
|
Config::JIT_MaxBlockSize = 32;
|
|
|
|
|
|
|
|
FetchedInstr instrs[Config::JIT_MaxBlockSize];
|
2019-06-21 23:28:32 +00:00
|
|
|
int i = 0;
|
2019-07-14 02:33:36 +00:00
|
|
|
u32 blockAddr = cpu->R[15] - (thumb ? 2 : 4);
|
2019-06-21 23:28:32 +00:00
|
|
|
u32 r15 = cpu->R[15];
|
|
|
|
u32 nextInstr[2] = {cpu->NextInstr[0], cpu->NextInstr[1]};
|
|
|
|
do
|
|
|
|
{
|
|
|
|
r15 += thumb ? 2 : 4;
|
|
|
|
|
|
|
|
instrs[i].Instr = nextInstr[0];
|
|
|
|
instrs[i].NextInstr[0] = nextInstr[0] = nextInstr[1];
|
|
|
|
|
|
|
|
if (cpu->Num == 0)
|
|
|
|
{
|
|
|
|
ARMv5* cpuv5 = (ARMv5*)cpu;
|
|
|
|
if (thumb && r15 & 0x2)
|
|
|
|
{
|
|
|
|
nextInstr[1] >>= 16;
|
|
|
|
instrs[i].CodeCycles = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nextInstr[1] = cpuv5->CodeRead32(r15, false);
|
|
|
|
instrs[i].CodeCycles = cpu->CodeCycles;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ARMv4* cpuv4 = (ARMv4*)cpu;
|
|
|
|
if (thumb)
|
|
|
|
nextInstr[1] = cpuv4->CodeRead16(r15);
|
|
|
|
else
|
|
|
|
nextInstr[1] = cpuv4->CodeRead32(r15);
|
|
|
|
instrs[i].CodeCycles = cpu->CodeCycles;
|
|
|
|
}
|
|
|
|
instrs[i].NextInstr[1] = nextInstr[1];
|
|
|
|
instrs[i].Info = ARMInstrInfo::Decode(thumb, cpu->Num, instrs[i].Instr);
|
|
|
|
|
|
|
|
i++;
|
2019-07-14 02:33:36 +00:00
|
|
|
} while(!instrs[i - 1].Info.Branches() && i < Config::JIT_MaxBlockSize);
|
2019-06-21 23:28:32 +00:00
|
|
|
|
|
|
|
CompiledBlock block = compiler->CompileBlock(cpu, instrs, i);
|
|
|
|
|
2019-07-21 11:36:48 +00:00
|
|
|
if (cpu->Num == 0)
|
|
|
|
InsertBlock<0>(blockAddr, block);
|
|
|
|
else
|
|
|
|
InsertBlock<1>(blockAddr, block);
|
2019-07-11 14:22:47 +00:00
|
|
|
|
|
|
|
return block;
|
2019-06-21 23:28:32 +00:00
|
|
|
}
|
|
|
|
|
2019-07-14 02:33:36 +00:00
|
|
|
void InvalidateBlockCache()
|
2019-06-25 15:09:27 +00:00
|
|
|
{
|
|
|
|
memset(cache.MainRAM, 0, sizeof(cache.MainRAM));
|
|
|
|
memset(cache.SWRAM, 0, sizeof(cache.SWRAM));
|
|
|
|
memset(cache.ARM9_BIOS, 0, sizeof(cache.ARM9_BIOS));
|
|
|
|
memset(cache.ARM9_ITCM, 0, sizeof(cache.ARM9_ITCM));
|
|
|
|
memset(cache.ARM9_LCDC, 0, sizeof(cache.ARM9_LCDC));
|
|
|
|
memset(cache.ARM7_BIOS, 0, sizeof(cache.ARM7_BIOS));
|
|
|
|
memset(cache.ARM7_WRAM, 0, sizeof(cache.ARM7_WRAM));
|
|
|
|
memset(cache.ARM7_WVRAM, 0, sizeof(cache.ARM7_WVRAM));
|
2019-07-14 02:33:36 +00:00
|
|
|
|
|
|
|
compiler->Reset();
|
2019-06-25 15:09:27 +00:00
|
|
|
}
|
|
|
|
|
2019-06-21 23:28:32 +00:00
|
|
|
}
|