Skip to content

Commit

Permalink
PowerPC: Raise alignment exceptions in more situations
Browse files Browse the repository at this point in the history
To avoid affecting performance, the JITs will most of the time not raise
alignment exceptions unless you enable the new INI-only setting
AlignmentExceptions.
  • Loading branch information
JosJuice committed Jan 21, 2024
1 parent 517952e commit a15476f
Show file tree
Hide file tree
Showing 15 changed files with 240 additions and 205 deletions.
9 changes: 7 additions & 2 deletions Source/Core/Common/Arm64Emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,14 +693,19 @@ static constexpr u32 MaskImm26(s64 distance)
}

// FixupBranch branching
void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch)
void ARM64XEmitter::SetJumpTarget(const FixupBranch& branch)
{
SetJumpTarget(branch, m_code);
}

void ARM64XEmitter::SetJumpTarget(const FixupBranch& branch, const u8* target)
{
if (!branch.ptr)
return;

bool Not = false;
u32 inst = 0;
s64 distance = (s64)(m_code - branch.ptr);
s64 distance = static_cast<s64>(target - branch.ptr);
distance >>= 2;

switch (branch.type)
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Common/Arm64Emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,8 @@ class ARM64XEmitter
bool HasWriteFailed() const { return m_write_failed; }

// FixupBranch branching
void SetJumpTarget(FixupBranch const& branch);
void SetJumpTarget(const FixupBranch& branch);
void SetJumpTarget(const FixupBranch& branch, const u8* target);
[[nodiscard]] FixupBranch CBZ(ARM64Reg Rt);
[[nodiscard]] FixupBranch CBNZ(ARM64Reg Rt);
[[nodiscard]] FixupBranch B(CCFlags cond);
Expand Down
12 changes: 10 additions & 2 deletions Source/Core/Core/PowerPC/Interpreter/ExceptionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@ enum class ProgramExceptionCause : u32
Trap = 1 << (31 - 14),
};

inline void GenerateAlignmentException(PowerPC::PowerPCState& ppc_state, u32 address)
inline void GenerateAlignmentException(PowerPC::PowerPCState& ppc_state, u32 effective_address,
UGeckoInstruction inst)
{
ppc_state.Exceptions |= EXCEPTION_ALIGNMENT;
ppc_state.spr[SPR_DAR] = address;
ppc_state.spr[SPR_DAR] = effective_address;

// It has not been hardware tested what gets used instead of RD and RA in
// the cases documented as undefined. For now, simply use RD and RA
const bool x = inst.OPCD >= 32;
const u32 op = x ? inst.SUBOP10 : (inst.OPCD >> 1);
const u32 dsisr = ((op >> 8) << 15) | ((op & 0b11111) << 10) | (inst.RD << 5) | (inst.RA);
ppc_state.spr[SPR_DSISR] = dsisr;
}

inline void GenerateDSIException(PowerPC::PowerPCState& ppc_state, u32 address)
Expand Down
Loading

0 comments on commit a15476f

Please sign in to comment.