A32/location_descriptor: Add CPSR.IT to A32::LocationDescriptor
This commit is contained in:
parent
13f65f55eb
commit
5f8eb7c51c
4 changed files with 42 additions and 23 deletions
|
@ -222,7 +222,7 @@ void A32EmitX64::GenTerminalHandlers() {
|
||||||
// This calculation has to match up with IREmitter::PushRSB
|
// This calculation has to match up with IREmitter::PushRSB
|
||||||
constexpr size_t offsetof_pc = offsetof(A32JitState, Reg) + 15 * sizeof(u32);
|
constexpr size_t offsetof_pc = offsetof(A32JitState, Reg) + 15 * sizeof(u32);
|
||||||
static_assert(offsetof_pc + 4 == offsetof(A32JitState, cpsr_et));
|
static_assert(offsetof_pc + 4 == offsetof(A32JitState, cpsr_et));
|
||||||
static_assert(offsetof_pc + 5 == offsetof(A32JitState, padding));
|
static_assert(offsetof_pc + 5 == offsetof(A32JitState, cpsr_it));
|
||||||
static_assert(offsetof_pc + 6 == offsetof(A32JitState, fpcr_mode));
|
static_assert(offsetof_pc + 6 == offsetof(A32JitState, fpcr_mode));
|
||||||
code.mov(rbx, qword[r15 + offsetof_pc]);
|
code.mov(rbx, qword[r15 + offsetof_pc]);
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,19 +19,21 @@ namespace Dynarmic::BackendX64 {
|
||||||
*
|
*
|
||||||
* ARM CPSR flags
|
* ARM CPSR flags
|
||||||
* --------------
|
* --------------
|
||||||
* N bit 31 Negative flag
|
* N bit 31 Negative flag
|
||||||
* Z bit 30 Zero flag
|
* Z bit 30 Zero flag
|
||||||
* C bit 29 Carry flag
|
* C bit 29 Carry flag
|
||||||
* V bit 28 oVerflow flag
|
* V bit 28 oVerflow flag
|
||||||
* Q bit 27 Saturation flag
|
* Q bit 27 Saturation flag
|
||||||
* J bit 24 Jazelle instruction set flag
|
* IT[1:0] bits 25-26 If-Then execution state (lower 2 bits)
|
||||||
* GE bits 16-19 Greater than or Equal flags
|
* J bit 24 Jazelle instruction set flag
|
||||||
* E bit 9 Data Endianness flag
|
* GE bits 16-19 Greater than or Equal flags
|
||||||
* A bit 8 Disable imprecise Aborts
|
* IT[7:2] bits 10-15 If-Then execution state (upper 6 bits)
|
||||||
* I bit 7 Disable IRQ interrupts
|
* E bit 9 Data Endianness flag
|
||||||
* F bit 6 Disable FIQ interrupts
|
* A bit 8 Disable imprecise Aborts
|
||||||
* T bit 5 Thumb instruction set flag
|
* I bit 7 Disable IRQ interrupts
|
||||||
* M bits 0-4 Processor Mode bits
|
* F bit 6 Disable FIQ interrupts
|
||||||
|
* T bit 5 Thumb instruction set flag
|
||||||
|
* M bits 0-4 Processor Mode bits
|
||||||
*
|
*
|
||||||
* x64 LAHF+SETO flags
|
* x64 LAHF+SETO flags
|
||||||
* -------------------
|
* -------------------
|
||||||
|
@ -62,6 +64,9 @@ u32 A32JitState::Cpsr() const {
|
||||||
cpsr |= Common::Bit<7>(cpsr_ge) ? 1 << 16 : 0;
|
cpsr |= Common::Bit<7>(cpsr_ge) ? 1 << 16 : 0;
|
||||||
// E flag, T flag
|
// E flag, T flag
|
||||||
cpsr |= static_cast<u32>(cpsr_et) << 5;
|
cpsr |= static_cast<u32>(cpsr_et) << 5;
|
||||||
|
// IT state
|
||||||
|
cpsr |= static_cast<u32>(cpsr_it & 0b11111100) << 8;
|
||||||
|
cpsr |= static_cast<u32>(cpsr_it & 0b00000011) << 25;
|
||||||
// Other flags
|
// Other flags
|
||||||
cpsr |= cpsr_jaifm;
|
cpsr |= cpsr_jaifm;
|
||||||
|
|
||||||
|
@ -81,8 +86,12 @@ void A32JitState::SetCpsr(u32 cpsr) {
|
||||||
cpsr_ge |= Common::Bit<16>(cpsr) ? 0x000000FF : 0;
|
cpsr_ge |= Common::Bit<16>(cpsr) ? 0x000000FF : 0;
|
||||||
// E flag, T flag
|
// E flag, T flag
|
||||||
cpsr_et = static_cast<u8>((cpsr >> 5) & 0x11);
|
cpsr_et = static_cast<u8>((cpsr >> 5) & 0x11);
|
||||||
|
// IT state
|
||||||
|
cpsr_it = 0;
|
||||||
|
cpsr_it |= static_cast<u8>((cpsr >> 8) & 0b11111100);
|
||||||
|
cpsr_it |= static_cast<u8>((cpsr >> 25) & 0b00000011);
|
||||||
// Other flags
|
// Other flags
|
||||||
cpsr_jaifm = cpsr & 0x07F0FDDF;
|
cpsr_jaifm = cpsr & 0x010001DF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void A32JitState::ResetRSB() {
|
void A32JitState::ResetRSB() {
|
||||||
|
@ -186,8 +195,4 @@ void A32JitState::SetFpscr(u32 FPSCR) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 A32JitState::GetUniqueHash() const noexcept {
|
|
||||||
return (static_cast<u64>(cpsr_et) << 32) | (static_cast<u64>(fpcr_mode) << 48) | Reg[15];
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Dynarmic::BackendX64
|
} // namespace Dynarmic::BackendX64
|
||||||
|
|
|
@ -31,9 +31,12 @@ struct A32JitState {
|
||||||
|
|
||||||
// Location Descriptor related (the order of fields is important)
|
// Location Descriptor related (the order of fields is important)
|
||||||
u8 cpsr_et = 0; ///< Format: 000E000T
|
u8 cpsr_et = 0; ///< Format: 000E000T
|
||||||
u8 padding = 0;
|
u8 cpsr_it = 0; ///< Format: ccccmmmm
|
||||||
u16 fpcr_mode = 0; ///< Top 16 bits of FPCR
|
u16 fpcr_mode = 0; ///< Top 16 bits of FPCR
|
||||||
u64 GetUniqueHash() const noexcept;
|
u64 GetUniqueHash() const noexcept {
|
||||||
|
const u64 upper_half = u64(cpsr_et) | (u64(cpsr_it) << 8) | (u64(fpcr_mode) << 16);
|
||||||
|
return (upper_half << 32) | Reg[15];
|
||||||
|
}
|
||||||
|
|
||||||
// CPSR fields
|
// CPSR fields
|
||||||
u32 cpsr_ge = 0;
|
u32 cpsr_ge = 0;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "frontend/A32/FPSCR.h"
|
#include "frontend/A32/FPSCR.h"
|
||||||
#include "frontend/A32/PSR.h"
|
#include "frontend/A32/PSR.h"
|
||||||
|
#include "frontend/A32/ITState.h"
|
||||||
#include "frontend/ir/location_descriptor.h"
|
#include "frontend/ir/location_descriptor.h"
|
||||||
|
|
||||||
namespace Dynarmic::A32 {
|
namespace Dynarmic::A32 {
|
||||||
|
@ -25,7 +26,7 @@ namespace Dynarmic::A32 {
|
||||||
class LocationDescriptor {
|
class LocationDescriptor {
|
||||||
public:
|
public:
|
||||||
// Indicates bits that should be preserved within descriptors.
|
// Indicates bits that should be preserved within descriptors.
|
||||||
static constexpr u32 CPSR_MODE_MASK = 0x00000220;
|
static constexpr u32 CPSR_MODE_MASK = 0x0600FE20;
|
||||||
static constexpr u32 FPSCR_MODE_MASK = 0x07F70000;
|
static constexpr u32 FPSCR_MODE_MASK = 0x07F70000;
|
||||||
|
|
||||||
LocationDescriptor(u32 arm_pc, PSR cpsr, FPSCR fpscr)
|
LocationDescriptor(u32 arm_pc, PSR cpsr, FPSCR fpscr)
|
||||||
|
@ -35,12 +36,14 @@ public:
|
||||||
arm_pc = static_cast<u32>(o.Value());
|
arm_pc = static_cast<u32>(o.Value());
|
||||||
cpsr.T(o.Value() & (u64(0x01) << 32));
|
cpsr.T(o.Value() & (u64(0x01) << 32));
|
||||||
cpsr.E(o.Value() & (u64(0x10) << 32));
|
cpsr.E(o.Value() & (u64(0x10) << 32));
|
||||||
|
cpsr.IT(ITState{static_cast<u8>(o.Value() >> 40)});
|
||||||
fpscr = static_cast<u32>(o.Value() >> 32) & FPSCR_MODE_MASK;
|
fpscr = static_cast<u32>(o.Value() >> 32) & FPSCR_MODE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 PC() const { return arm_pc; }
|
u32 PC() const { return arm_pc; }
|
||||||
bool TFlag() const { return cpsr.T(); }
|
bool TFlag() const { return cpsr.T(); }
|
||||||
bool EFlag() const { return cpsr.E(); }
|
bool EFlag() const { return cpsr.E(); }
|
||||||
|
ITState IT() const { return cpsr.IT(); }
|
||||||
|
|
||||||
A32::PSR CPSR() const { return cpsr; }
|
A32::PSR CPSR() const { return cpsr; }
|
||||||
A32::FPSCR FPSCR() const { return fpscr; }
|
A32::FPSCR FPSCR() const { return fpscr; }
|
||||||
|
@ -79,14 +82,22 @@ public:
|
||||||
return LocationDescriptor(arm_pc, cpsr, A32::FPSCR{new_fpscr & FPSCR_MODE_MASK});
|
return LocationDescriptor(arm_pc, cpsr, A32::FPSCR{new_fpscr & FPSCR_MODE_MASK});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocationDescriptor AdvanceIT() const {
|
||||||
|
PSR new_cpsr = cpsr;
|
||||||
|
new_cpsr.IT(new_cpsr.IT().Advance());
|
||||||
|
|
||||||
|
return LocationDescriptor(arm_pc, new_cpsr, fpscr);
|
||||||
|
}
|
||||||
|
|
||||||
u64 UniqueHash() const noexcept {
|
u64 UniqueHash() const noexcept {
|
||||||
// This value MUST BE UNIQUE.
|
// This value MUST BE UNIQUE.
|
||||||
// This calculation has to match up with EmitX64::EmitTerminalPopRSBHint
|
// This calculation has to match up with EmitX64::EmitTerminalPopRSBHint
|
||||||
const u64 pc_u64 = u64(arm_pc);
|
const u64 pc_u64 = u64(arm_pc);
|
||||||
const u64 fpscr_u64 = u64(fpscr.Value()) << 32;
|
const u64 fpscr_u64 = u64(fpscr.Value()) << 32;
|
||||||
|
const u64 it_u64 = u64(cpsr.IT().Value()) << 40;
|
||||||
const u64 t_u64 = cpsr.T() ? u64(0x01) << 32 : 0;
|
const u64 t_u64 = cpsr.T() ? u64(0x01) << 32 : 0;
|
||||||
const u64 e_u64 = cpsr.E() ? u64(0x10) << 32 : 0;
|
const u64 e_u64 = cpsr.E() ? u64(0x10) << 32 : 0;
|
||||||
return pc_u64 | fpscr_u64 | t_u64 | e_u64;
|
return pc_u64 | fpscr_u64 | it_u64 | t_u64 | e_u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator IR::LocationDescriptor() const {
|
operator IR::LocationDescriptor() const {
|
||||||
|
|
Loading…
Reference in a new issue