2018-01-06 21:15:25 +00: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
|
2018-01-06 21:15:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
|
|
|
|
#include <xbyak.h>
|
|
|
|
|
2020-05-06 22:08:38 +01:00
|
|
|
#include "backend/x64/nzcv_util.h"
|
2018-01-06 21:15:25 +00:00
|
|
|
#include "common/common_types.h"
|
2020-04-06 15:05:50 +01:00
|
|
|
#include "frontend/A64/location_descriptor.h"
|
2018-01-06 21:15:25 +00:00
|
|
|
|
2020-04-08 11:46:36 +01:00
|
|
|
namespace Dynarmic::Backend::X64 {
|
2018-01-06 21:15:25 +00:00
|
|
|
|
|
|
|
class BlockOfCode;
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#pragma warning(push)
|
|
|
|
#pragma warning(disable:4324) // Structure was padded due to alignment specifier
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct A64JitState {
|
|
|
|
using ProgramCounterType = u64;
|
|
|
|
|
|
|
|
A64JitState() { ResetRSB(); }
|
|
|
|
|
|
|
|
std::array<u64, 31> reg{};
|
2018-05-01 14:02:42 +01:00
|
|
|
u64 sp = 0;
|
|
|
|
u64 pc = 0;
|
2018-01-06 21:15:25 +00:00
|
|
|
|
2019-05-05 19:49:54 +01:00
|
|
|
u32 cpsr_nzcv = 0;
|
2018-02-05 12:23:51 +00:00
|
|
|
|
2018-01-07 14:46:35 +00:00
|
|
|
u32 GetPstate() const {
|
2020-05-06 22:08:38 +01:00
|
|
|
return NZCV::FromX64(cpsr_nzcv);
|
2018-01-07 14:46:35 +00:00
|
|
|
}
|
|
|
|
void SetPstate(u32 new_pstate) {
|
2020-05-06 22:08:38 +01:00
|
|
|
cpsr_nzcv = NZCV::ToX64(new_pstate);
|
2018-01-07 14:46:35 +00:00
|
|
|
}
|
2018-01-06 21:15:25 +00:00
|
|
|
|
|
|
|
alignas(16) std::array<u64, 64> vec{}; // Extension registers.
|
|
|
|
|
|
|
|
static constexpr size_t SpillCount = 64;
|
2018-01-26 18:35:46 +00:00
|
|
|
alignas(16) std::array<std::array<u64, 2>, SpillCount> spill{}; // Spill.
|
2018-01-06 21:15:25 +00:00
|
|
|
static Xbyak::Address GetSpillLocationFromIndex(size_t i) {
|
|
|
|
using namespace Xbyak::util;
|
2018-01-26 18:35:46 +00:00
|
|
|
return xword[r15 + offsetof(A64JitState, spill) + i * sizeof(u64) * 2];
|
2018-01-06 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// For internal use (See: BlockOfCode::RunCode)
|
|
|
|
u32 guest_MXCSR = 0x00001f80;
|
|
|
|
u32 save_host_MXCSR = 0;
|
|
|
|
s64 cycles_to_run = 0;
|
|
|
|
s64 cycles_remaining = 0;
|
|
|
|
bool halt_requested = false;
|
2018-01-07 16:33:02 +00:00
|
|
|
bool check_bit = false;
|
2018-01-06 21:15:25 +00:00
|
|
|
|
A64: Implement STXRB, STXRH, STXR, STLXRB, STLXRH, STLXR, LDXRB, LDXRH, LDXR, LDAXRB, LDAXRH, LDAXR
2018-02-13 00:19:04 +00:00
|
|
|
// Exclusive state
|
2018-02-13 14:02:59 +00:00
|
|
|
static constexpr u64 RESERVATION_GRANULE_MASK = 0xFFFF'FFFF'FFFF'FFF0ull;
|
|
|
|
u8 exclusive_state = 0;
|
A64: Implement STXRB, STXRH, STXR, STLXRB, STLXRH, STLXR, LDXRB, LDXRH, LDXR, LDAXRB, LDAXRH, LDAXR
2018-02-13 00:19:04 +00:00
|
|
|
|
2018-01-06 21:15:25 +00:00
|
|
|
static constexpr size_t RSBSize = 8; // MUST be a power of 2.
|
|
|
|
static constexpr size_t RSBPtrMask = RSBSize - 1;
|
|
|
|
u32 rsb_ptr = 0;
|
|
|
|
std::array<u64, RSBSize> rsb_location_descriptors;
|
|
|
|
std::array<u64, RSBSize> rsb_codeptrs;
|
|
|
|
void ResetRSB() {
|
|
|
|
rsb_location_descriptors.fill(0xFFFFFFFFFFFFFFFFull);
|
|
|
|
rsb_codeptrs.fill(0);
|
|
|
|
}
|
|
|
|
|
2018-06-30 10:49:47 +01:00
|
|
|
u32 fpsr_exc = 0;
|
2018-07-15 23:19:35 +01:00
|
|
|
u32 fpsr_qc = 0;
|
2018-01-06 21:15:25 +00:00
|
|
|
u32 fpcr = 0;
|
2018-02-20 17:38:29 +00:00
|
|
|
u32 GetFpcr() const;
|
|
|
|
u32 GetFpsr() const;
|
2019-05-24 06:59:04 +01:00
|
|
|
void SetFpcr(u32 value);
|
|
|
|
void SetFpsr(u32 value);
|
2018-01-06 21:15:25 +00:00
|
|
|
|
2020-04-06 15:05:50 +01:00
|
|
|
u64 GetUniqueHash() const noexcept {
|
|
|
|
const u64 fpcr_u64 = static_cast<u64>(fpcr & A64::LocationDescriptor::fpcr_mask) << A64::LocationDescriptor::fpcr_shift;
|
|
|
|
const u64 pc_u64 = pc & A64::LocationDescriptor::pc_mask;
|
|
|
|
return pc_u64 | fpcr_u64;
|
|
|
|
}
|
2018-01-06 21:15:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#pragma warning(pop)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
using CodePtr = const void*;
|
|
|
|
|
2020-04-08 11:46:36 +01:00
|
|
|
} // namespace Dynarmic::Backend::X64
|