dynarmic/src/backend_x64/block_of_code.h

133 lines
3.9 KiB
C
Raw Normal View History

2016-07-01 15:01:06 +02:00
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* This software may be used and distributed according to the terms of the GNU
* General Public License version 2 or any later version.
*/
#pragma once
#include <array>
2016-08-24 21:07:08 +02:00
#include <vector>
#include <xbyak.h>
2016-07-01 15:01:06 +02:00
#include "backend_x64/jitstate.h"
#include "common/common_types.h"
namespace Dynarmic {
namespace BackendX64 {
2016-08-24 21:07:08 +02:00
class BlockOfCode final : public Xbyak::CodeGenerator {
2016-07-01 15:01:06 +02:00
public:
BlockOfCode();
2016-08-12 19:17:31 +02:00
/// Clears this block of code and resets code pointer to beginning.
void ClearCache(bool poison_memory);
2016-07-01 15:01:06 +02:00
2016-08-12 19:17:31 +02:00
/// Runs emulated code for approximately `cycles_to_run` cycles.
2016-07-01 15:01:06 +02:00
size_t RunCode(JitState* jit_state, CodePtr basic_block, size_t cycles_to_run) const;
2016-08-12 19:17:31 +02:00
/// Code emitter: Returns to host
void ReturnFromRunCode(bool MXCSR_switch = true);
2016-08-12 19:17:31 +02:00
/// Code emitter: Makes guest MXCSR the current MXCSR
void SwitchMxcsrOnEntry();
2016-08-12 19:17:31 +02:00
/// Code emitter: Makes saved host MXCSR the current MXCSR
void SwitchMxcsrOnExit();
2016-08-24 21:07:08 +02:00
/// Code emitter: Calls the function
void CallFunction(const void* fn);
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatPositiveZero32() {
return xword[rip + const_FloatPositiveZero32];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatNegativeZero32() {
return xword[rip + const_FloatNegativeZero32];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatNaN32() {
return xword[rip + const_FloatNaN32];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatNonSignMask32() {
return xword[rip + const_FloatNonSignMask32];
2016-08-07 02:27:18 +02:00
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatPositiveZero64() {
return xword[rip + const_FloatPositiveZero64];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatNegativeZero64() {
return xword[rip + const_FloatNegativeZero64];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatNaN64() {
return xword[rip + const_FloatNaN64];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatNonSignMask64() {
return xword[rip + const_FloatNonSignMask64];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatPenultimatePositiveDenormal64() {
return xword[rip + const_FloatPenultimatePositiveDenormal64];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatMinS32() {
return xword[rip + const_FloatMinS32];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatMaxS32() {
return xword[rip + const_FloatMaxS32];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatMinU32() {
return xword[rip + const_FloatMinU32];
}
2016-08-24 21:07:08 +02:00
Xbyak::Address MFloatMaxU32() {
return xword[rip + const_FloatMaxU32];
}
2016-07-01 15:01:06 +02:00
2016-08-24 21:07:08 +02:00
const void* GetReturnFromRunCodeAddress() const {
return return_from_run_code;
}
2016-08-24 21:07:08 +02:00
void int3() { db(0xCC); }
void nop(size_t size = 0) {
for (size_t i = 0; i < size; i++) {
db(0x90);
}
}
void SetCodePtr(CodePtr ptr);
void EnsurePatchLocationSize(CodePtr begin, size_t size);
#ifdef _WIN32
Xbyak::Reg64 ABI_RETURN = rax;
Xbyak::Reg64 ABI_PARAM1 = rcx;
Xbyak::Reg64 ABI_PARAM2 = rdx;
Xbyak::Reg64 ABI_PARAM3 = r8;
Xbyak::Reg64 ABI_PARAM4 = r9;
#else
Xbyak::Reg64 ABI_RETURN = rax;
Xbyak::Reg64 ABI_PARAM1 = rdi;
Xbyak::Reg64 ABI_PARAM2 = rsi;
Xbyak::Reg64 ABI_PARAM3 = rdx;
Xbyak::Reg64 ABI_PARAM4 = rcx;
#endif
2016-07-01 15:01:06 +02:00
private:
2016-08-24 21:07:08 +02:00
Xbyak::Label const_FloatPositiveZero32;
Xbyak::Label const_FloatNegativeZero32;
Xbyak::Label const_FloatNaN32;
Xbyak::Label const_FloatNonSignMask32;
Xbyak::Label const_FloatPositiveZero64;
Xbyak::Label const_FloatNegativeZero64;
Xbyak::Label const_FloatNaN64;
Xbyak::Label const_FloatNonSignMask64;
Xbyak::Label const_FloatPenultimatePositiveDenormal64;
Xbyak::Label const_FloatMinS32;
Xbyak::Label const_FloatMaxS32;
Xbyak::Label const_FloatMinU32;
Xbyak::Label const_FloatMaxU32;
void GenConstants();
2016-07-01 15:01:06 +02:00
using RunCodeFuncType = void(*)(JitState*, CodePtr);
RunCodeFuncType run_code = nullptr;
2016-07-01 15:01:06 +02:00
void GenRunCode();
2016-08-24 21:07:08 +02:00
const void* return_from_run_code = nullptr;
const void* return_from_run_code_without_mxcsr_switch = nullptr;
void GenReturnFromRunCode();
2016-07-01 15:01:06 +02:00
};
} // namespace BackendX64
} // namespace Dynarmic