mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
mips: Initial structure for a MIPS emitter.
This commit is contained in:
parent
07ec247864
commit
6407e4a32a
4 changed files with 202 additions and 1 deletions
|
@ -189,6 +189,7 @@
|
|||
<ClInclude Include="LogManager.h" />
|
||||
<ClInclude Include="MemArena.h" />
|
||||
<ClInclude Include="MemoryUtil.h" />
|
||||
<ClInclude Include="MipsEmitter.h" />
|
||||
<ClInclude Include="MsgHandler.h" />
|
||||
<ClInclude Include="ppcEmitter.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
|
@ -226,6 +227,7 @@
|
|||
<ClCompile Include="LogManager.cpp" />
|
||||
<ClCompile Include="MemArena.cpp" />
|
||||
<ClCompile Include="MemoryUtil.cpp" />
|
||||
<ClCompile Include="MipsEmitter.cpp" />
|
||||
<ClCompile Include="Misc.cpp" />
|
||||
<ClCompile Include="MsgHandler.cpp" />
|
||||
<ClCompile Include="ppcEmitter.cpp">
|
||||
|
@ -258,4 +260,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -37,6 +37,7 @@
|
|||
<Filter>Crypto</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ppcEmitter.h" />
|
||||
<ClInclude Include="MipsEmitter.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
|
@ -67,6 +68,7 @@
|
|||
<ClCompile Include="ChunkFile.cpp" />
|
||||
<ClCompile Include="ArmThunk.cpp" />
|
||||
<ClCompile Include="ppcEmitter.cpp" />
|
||||
<ClCompile Include="MipsEmitter.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
|
|
83
Common/MipsEmitter.cpp
Normal file
83
Common/MipsEmitter.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) 2014- 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 "base/logging.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MemoryUtil.h"
|
||||
#include "MipsEmitter.h"
|
||||
#include "CPUDetect.h"
|
||||
|
||||
namespace MIPSGen {
|
||||
void MIPSXEmitter::SetCodePtr(u8 *ptr) {
|
||||
code_ = ptr;
|
||||
lastCacheFlushEnd_ = ptr;
|
||||
}
|
||||
|
||||
void MIPSXEmitter::ReserveCodeSpace(u32 bytes) {
|
||||
for (u32 i = 0; i < bytes / 4; ++i) {
|
||||
BREAK(0);
|
||||
}
|
||||
}
|
||||
|
||||
const u8 *MIPSXEmitter::AlignCode16() {
|
||||
ReserveCodeSpace((-(intptr_t)code_) & 15);
|
||||
return code_;
|
||||
}
|
||||
|
||||
const u8 *MIPSXEmitter::AlignCodePage() {
|
||||
// TODO: Assuming code pages ought to be 4K?
|
||||
ReserveCodeSpace((-(intptr_t)code_) & 4095);
|
||||
return code_;
|
||||
}
|
||||
|
||||
const u8 *MIPSXEmitter::GetCodePtr() const {
|
||||
return code_;
|
||||
}
|
||||
|
||||
u8 *MIPSXEmitter::GetWritableCodePtr() {
|
||||
return code_;
|
||||
}
|
||||
|
||||
void MIPSXEmitter::FlushIcache() {
|
||||
FlushIcacheSection(lastCacheFlushEnd_, code_);
|
||||
lastCacheFlushEnd_ = code_;
|
||||
}
|
||||
|
||||
void MIPSXEmitter::FlushIcacheSection(u8 *start, u8 *end) {
|
||||
#if defined(MIPS)
|
||||
// TODO: Completely untested.
|
||||
#ifdef __clang__
|
||||
__clear_cache(start, end);
|
||||
#else
|
||||
__builtin___clear_cache(start, end);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void MIPSXEmitter::BREAK(u32 code) {
|
||||
// 000000 iiiiiiiiiiiiiiiiiiii 001101
|
||||
Write32Fields(26, 0x00000000, 6, code & 0xFFFFF, 0, 0x0000000d);
|
||||
}
|
||||
|
||||
}
|
114
Common/MipsEmitter.h
Normal file
114
Common/MipsEmitter.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
// Copyright (c) 2014- 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/.
|
||||
|
||||
// WARNING - THIS LIBRARY IS NOT THREAD SAFE!!! (cargo culted but probably true)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Common.h"
|
||||
#include "MsgHandler.h"
|
||||
|
||||
namespace MIPSGen {
|
||||
|
||||
enum MIPSReg {
|
||||
R_ZERO = 0,
|
||||
R_AT,
|
||||
V0, V1,
|
||||
|
||||
A0 = 4, A1 = 5, A2 = 6, A3 = 7, A4 = 8, A5 = 9, A6 = 10, A7 = 11,
|
||||
// Alternate names depending on ABI.
|
||||
T0 = 8, T1 = 9, T2 = 10, T3 = 11,
|
||||
|
||||
T4, T5, T6, T7,
|
||||
S0, S1, S2, S3, S4, S5, S6, S7,
|
||||
T8, T9,
|
||||
K0, K1,
|
||||
R_GP, R_SP, R_FP,
|
||||
R_RA,
|
||||
|
||||
F_BASE = 32,
|
||||
F0 = 32, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,
|
||||
F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31,
|
||||
|
||||
INVALID_REG = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
enum {
|
||||
// All 32 except: ZERO, K0/K1 (kernel), RA. The rest are only convention.
|
||||
NUMGPRs = 32 - 1 - 2 - 1,
|
||||
NUMFPRs = 32,
|
||||
};
|
||||
|
||||
enum FixupBranchType {
|
||||
// 16-bit immediate jump/branch (to pc + (simm16 + 1 ops).)
|
||||
BRANCH_16,
|
||||
// 26-bit immediate jump/branch (to pc's 4 high bits + imm * 4.)
|
||||
BRANCH_26,
|
||||
};
|
||||
|
||||
// Beware of delay slots.
|
||||
struct FixupBranch {
|
||||
u8 *ptr;
|
||||
FixupBranchType type;
|
||||
};
|
||||
|
||||
class MIPSXEmitter {
|
||||
public:
|
||||
MIPSXEmitter() : code_(0), lastCacheFlushEnd_(0) {
|
||||
}
|
||||
MIPSXEmitter(u8 *code_ptr) : code_(code_ptr), lastCacheFlushEnd_(code_ptr) {
|
||||
SetCodePtr(code_ptr);
|
||||
}
|
||||
virtual ~MIPSXEmitter() {
|
||||
}
|
||||
|
||||
void SetCodePtr(u8 *ptr);
|
||||
void ReserveCodeSpace(u32 bytes);
|
||||
const u8 *AlignCode16();
|
||||
const u8 *AlignCodePage();
|
||||
const u8 *GetCodePtr() const;
|
||||
u8 *GetWritableCodePtr();
|
||||
void FlushIcache();
|
||||
void FlushIcacheSection(u8 *start, u8 *end);
|
||||
|
||||
// 20 bits valid in code.
|
||||
void BREAK(u32 code);
|
||||
|
||||
protected:
|
||||
inline void Write32(u32 value) {
|
||||
*code32_++ = value;
|
||||
}
|
||||
// Less parenthesis.
|
||||
inline void Write32Fields(u8 pos1, u32 v1, u8 pos2, u32 v2) {
|
||||
*code32_++ = (v1 << pos1) | (v2 << pos2);
|
||||
}
|
||||
inline void Write32Fields(u8 pos1, u32 v1, u8 pos2, u32 v2, u8 pos3, u32 v3) {
|
||||
*code32_++ = (v1 << pos1) | (v2 << pos2) | (v3 << pos3);
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
u8 *code_;
|
||||
u32 *code32_;
|
||||
};
|
||||
u8 *lastCacheFlushEnd_;
|
||||
};
|
||||
|
||||
};
|
Loading…
Add table
Reference in a new issue