2016-07-01 14:01:06 +01:00
|
|
|
/* This file is part of the dynarmic project.
|
|
|
|
* Copyright (c) 2016 MerryMage
|
2020-04-23 15:25:11 +01:00
|
|
|
* SPDX-License-Identifier: 0BSD
|
2016-07-01 14:01:06 +01:00
|
|
|
*/
|
2016-08-05 18:54:19 +01:00
|
|
|
|
2016-07-01 14:01:06 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
|
2018-01-04 21:12:02 +00:00
|
|
|
#include <xbyak.h>
|
|
|
|
|
2016-07-01 14:01:06 +01:00
|
|
|
#include "common/common_types.h"
|
|
|
|
|
2020-04-08 11:46:36 +01:00
|
|
|
namespace Dynarmic::Backend::X64 {
|
2016-07-01 14:01:06 +01:00
|
|
|
|
2016-08-13 00:10:23 +01:00
|
|
|
class BlockOfCode;
|
|
|
|
|
2016-12-15 21:31:58 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#pragma warning(push)
|
|
|
|
#pragma warning(disable:4324) // Structure was padded due to alignment specifier
|
|
|
|
#endif
|
|
|
|
|
2018-01-01 22:49:17 +00:00
|
|
|
struct A32JitState {
|
2018-01-02 17:45:39 +00:00
|
|
|
using ProgramCounterType = u32;
|
|
|
|
|
2018-01-01 22:49:17 +00:00
|
|
|
A32JitState() { ResetRSB(); }
|
2016-08-13 00:10:23 +01:00
|
|
|
|
2016-07-01 14:01:06 +01:00
|
|
|
std::array<u32, 16> Reg{}; // Current register file.
|
|
|
|
// TODO: Mode-specific register sets unimplemented.
|
|
|
|
|
2019-07-25 11:40:40 +01:00
|
|
|
u32 upper_location_descriptor = 0;
|
2019-05-05 23:17:15 +01:00
|
|
|
|
2019-05-05 19:49:54 +01:00
|
|
|
u32 cpsr_ge = 0;
|
|
|
|
u32 cpsr_q = 0;
|
|
|
|
u32 cpsr_nzcv = 0;
|
|
|
|
u32 cpsr_jaifm = 0;
|
2017-12-02 13:55:04 +00:00
|
|
|
u32 Cpsr() const;
|
|
|
|
void SetCpsr(u32 cpsr);
|
|
|
|
|
2020-05-28 20:39:19 +01:00
|
|
|
alignas(16) std::array<u32, 64> ExtReg{}; // Extension registers.
|
2016-08-01 20:03:13 +01:00
|
|
|
|
2018-01-04 21:12:02 +00:00
|
|
|
static constexpr size_t SpillCount = 64;
|
2020-05-28 20:39:19 +01:00
|
|
|
alignas(16) std::array<std::array<u64, 2>, SpillCount> spill{}; // Spill.
|
2018-01-04 21:12:02 +00:00
|
|
|
static Xbyak::Address GetSpillLocationFromIndex(size_t i) {
|
|
|
|
using namespace Xbyak::util;
|
2020-05-28 20:39:19 +01:00
|
|
|
return xword[r15 + offsetof(A32JitState, spill) + i * sizeof(u64) * 2];
|
2018-01-04 21:12:02 +00:00
|
|
|
}
|
2016-07-01 14:01:06 +01:00
|
|
|
|
2016-08-07 18:08:48 +01:00
|
|
|
// For internal use (See: BlockOfCode::RunCode)
|
2016-08-07 00:40:29 +01:00
|
|
|
u32 guest_MXCSR = 0x00001f80;
|
2020-06-20 00:01:10 +01:00
|
|
|
u32 asimd_MXCSR = 0x00009fc0;
|
2016-08-05 18:54:19 +01:00
|
|
|
u32 save_host_MXCSR = 0;
|
2017-12-03 02:42:22 +00:00
|
|
|
s64 cycles_to_run = 0;
|
2016-07-04 10:22:11 +01:00
|
|
|
s64 cycles_remaining = 0;
|
2016-08-15 15:02:08 +01:00
|
|
|
bool halt_requested = false;
|
2019-05-03 23:28:02 +01:00
|
|
|
bool check_bit = false;
|
2016-08-05 18:54:19 +01:00
|
|
|
|
TranslateArm: Implement CLREX, LDREX, LDREXB, LDREXD, LDREXH, STREX, STREXB, STREXD, STREXH, SWP, SWPB
2016-08-09 22:48:20 +01:00
|
|
|
// Exclusive state
|
|
|
|
u32 exclusive_state = 0;
|
|
|
|
|
2016-08-15 15:48:22 +01:00
|
|
|
static constexpr size_t RSBSize = 8; // MUST be a power of 2.
|
2017-11-27 20:29:19 +00:00
|
|
|
static constexpr size_t RSBPtrMask = RSBSize - 1;
|
2016-08-13 00:10:23 +01:00
|
|
|
u32 rsb_ptr = 0;
|
|
|
|
std::array<u64, RSBSize> rsb_location_descriptors;
|
|
|
|
std::array<u64, RSBSize> rsb_codeptrs;
|
2016-08-31 21:57:33 +01:00
|
|
|
void ResetRSB();
|
2016-08-13 00:10:23 +01:00
|
|
|
|
2018-06-30 10:49:47 +01:00
|
|
|
u32 fpsr_exc = 0;
|
2018-07-15 23:19:35 +01:00
|
|
|
u32 fpsr_qc = 0; // Dummy value
|
2019-05-05 19:46:57 +01:00
|
|
|
u32 fpsr_nzcv = 0;
|
2016-08-05 18:54:19 +01:00
|
|
|
u32 Fpscr() const;
|
|
|
|
void SetFpscr(u32 FPSCR);
|
2019-07-25 11:40:40 +01:00
|
|
|
|
|
|
|
u64 GetUniqueHash() const noexcept {
|
|
|
|
return (static_cast<u64>(upper_location_descriptor) << 32) | (static_cast<u64>(Reg[15]));
|
|
|
|
}
|
2019-07-28 18:59:44 +01:00
|
|
|
|
|
|
|
void TransferJitState(const A32JitState& src, bool reset_rsb) {
|
|
|
|
Reg = src.Reg;
|
|
|
|
upper_location_descriptor = src.upper_location_descriptor;
|
|
|
|
cpsr_ge = src.cpsr_ge;
|
|
|
|
cpsr_q = src.cpsr_q;
|
|
|
|
cpsr_nzcv = src.cpsr_nzcv;
|
|
|
|
cpsr_jaifm = src.cpsr_jaifm;
|
|
|
|
ExtReg = src.ExtReg;
|
|
|
|
guest_MXCSR = src.guest_MXCSR;
|
2020-06-20 00:00:36 +01:00
|
|
|
asimd_MXCSR = src.asimd_MXCSR;
|
2019-07-28 18:59:44 +01:00
|
|
|
fpsr_exc = src.fpsr_exc;
|
|
|
|
fpsr_qc = src.fpsr_qc;
|
|
|
|
fpsr_nzcv = src.fpsr_nzcv;
|
|
|
|
|
|
|
|
exclusive_state = 0;
|
|
|
|
|
|
|
|
if (reset_rsb) {
|
|
|
|
ResetRSB();
|
|
|
|
} else {
|
|
|
|
rsb_ptr = src.rsb_ptr;
|
|
|
|
rsb_location_descriptors = src.rsb_location_descriptors;
|
|
|
|
rsb_codeptrs = src.rsb_codeptrs;
|
|
|
|
}
|
|
|
|
}
|
2016-07-01 14:01:06 +01:00
|
|
|
};
|
|
|
|
|
2016-12-15 21:31:58 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#pragma warning(pop)
|
|
|
|
#endif
|
|
|
|
|
2016-08-24 20:07:08 +01:00
|
|
|
using CodePtr = const void*;
|
2016-07-01 14:01:06 +01:00
|
|
|
|
2020-04-08 11:46:36 +01:00
|
|
|
} // namespace Dynarmic::Backend::X64
|