mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-02-19 14:52:57 +00:00
microinstruction: Introduce convenience informational functions
Whenever more rigorous optimizations are attempted (or even basic ones), it's usually helpful to know what overall kind of instruction is being dealt with, in the event certain classes of instructions may be eligible for optimization.
This commit is contained in:
@@ -10,6 +10,210 @@
|
||||
namespace Dynarmic {
|
||||
namespace IR {
|
||||
|
||||
bool Inst::IsArithmeticShift() const {
|
||||
return op == Opcode::ArithmeticShiftRight;
|
||||
}
|
||||
|
||||
bool Inst::IsCircularShift() const {
|
||||
return op == Opcode::RotateRight ||
|
||||
op == Opcode::RotateRightExtended;
|
||||
}
|
||||
|
||||
bool Inst::IsLogicalShift() const {
|
||||
switch (op) {
|
||||
case Opcode::LogicalShiftLeft:
|
||||
case Opcode::LogicalShiftRight:
|
||||
case Opcode::LogicalShiftRight64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::IsShift() const {
|
||||
return IsArithmeticShift() ||
|
||||
IsCircularShift() ||
|
||||
IsLogicalShift();
|
||||
}
|
||||
|
||||
bool Inst::IsSharedMemoryRead() const {
|
||||
switch (op) {
|
||||
case Opcode::ReadMemory8:
|
||||
case Opcode::ReadMemory16:
|
||||
case Opcode::ReadMemory32:
|
||||
case Opcode::ReadMemory64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::IsSharedMemoryWrite() const {
|
||||
switch (op) {
|
||||
case Opcode::WriteMemory8:
|
||||
case Opcode::WriteMemory16:
|
||||
case Opcode::WriteMemory32:
|
||||
case Opcode::WriteMemory64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::IsSharedMemoryReadOrWrite() const {
|
||||
return IsSharedMemoryRead() || IsSharedMemoryWrite();
|
||||
}
|
||||
|
||||
bool Inst::IsExclusiveMemoryWrite() const {
|
||||
switch (op) {
|
||||
case Opcode::ExclusiveWriteMemory8:
|
||||
case Opcode::ExclusiveWriteMemory16:
|
||||
case Opcode::ExclusiveWriteMemory32:
|
||||
case Opcode::ExclusiveWriteMemory64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::IsMemoryRead() const {
|
||||
return IsSharedMemoryRead();
|
||||
}
|
||||
|
||||
bool Inst::IsMemoryWrite() const {
|
||||
return IsSharedMemoryWrite() || IsExclusiveMemoryWrite();
|
||||
}
|
||||
|
||||
bool Inst::IsMemoryReadOrWrite() const {
|
||||
return IsMemoryRead() || IsMemoryWrite();
|
||||
}
|
||||
|
||||
bool Inst::ReadsFromCPSR() const {
|
||||
switch (op) {
|
||||
case Opcode::GetCpsr:
|
||||
case Opcode::GetNFlag:
|
||||
case Opcode::GetZFlag:
|
||||
case Opcode::GetCFlag:
|
||||
case Opcode::GetVFlag:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::WritesToCPSR() const {
|
||||
switch (op) {
|
||||
case Opcode::SetCpsr:
|
||||
case Opcode::SetNFlag:
|
||||
case Opcode::SetZFlag:
|
||||
case Opcode::SetCFlag:
|
||||
case Opcode::SetVFlag:
|
||||
case Opcode::OrQFlag:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::ReadsFromCoreRegister() const {
|
||||
switch (op) {
|
||||
case Opcode::GetRegister:
|
||||
case Opcode::GetExtendedRegister32:
|
||||
case Opcode::GetExtendedRegister64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::WritesToCoreRegister() const {
|
||||
switch (op) {
|
||||
case Opcode::SetRegister:
|
||||
case Opcode::SetExtendedRegister32:
|
||||
case Opcode::SetExtendedRegister64:
|
||||
case Opcode::BXWritePC:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::ReadsFromFPSCR() const {
|
||||
switch (op) {
|
||||
case Opcode::FPAbs32:
|
||||
case Opcode::FPAbs64:
|
||||
case Opcode::FPAdd32:
|
||||
case Opcode::FPAdd64:
|
||||
case Opcode::FPDiv32:
|
||||
case Opcode::FPDiv64:
|
||||
case Opcode::FPMul32:
|
||||
case Opcode::FPMul64:
|
||||
case Opcode::FPNeg32:
|
||||
case Opcode::FPNeg64:
|
||||
case Opcode::FPSqrt32:
|
||||
case Opcode::FPSqrt64:
|
||||
case Opcode::FPSub32:
|
||||
case Opcode::FPSub64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::WritesToFPSCR() const {
|
||||
switch (op) {
|
||||
case Opcode::FPAbs32:
|
||||
case Opcode::FPAbs64:
|
||||
case Opcode::FPAdd32:
|
||||
case Opcode::FPAdd64:
|
||||
case Opcode::FPDiv32:
|
||||
case Opcode::FPDiv64:
|
||||
case Opcode::FPMul32:
|
||||
case Opcode::FPMul64:
|
||||
case Opcode::FPNeg32:
|
||||
case Opcode::FPNeg64:
|
||||
case Opcode::FPSqrt32:
|
||||
case Opcode::FPSqrt64:
|
||||
case Opcode::FPSub32:
|
||||
case Opcode::FPSub64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Inst::CausesCPUException() const {
|
||||
return op == Opcode::Breakpoint ||
|
||||
op == Opcode::CallSupervisor;
|
||||
}
|
||||
|
||||
bool Inst::AltersExclusiveState() const {
|
||||
return op == Opcode::ClearExclusive ||
|
||||
op == Opcode::SetExclusive ||
|
||||
IsExclusiveMemoryWrite();
|
||||
}
|
||||
|
||||
bool Inst::MayHaveSideEffects() const {
|
||||
return op == Opcode::PushRSB ||
|
||||
CausesCPUException() ||
|
||||
WritesToCoreRegister() ||
|
||||
WritesToCPSR() ||
|
||||
WritesToFPSCR() ||
|
||||
AltersExclusiveState() ||
|
||||
IsMemoryWrite();
|
||||
|
||||
}
|
||||
|
||||
Value Inst::GetArg(size_t index) const {
|
||||
DEBUG_ASSERT(index < GetNumArgsOf(op));
|
||||
DEBUG_ASSERT(!args[index].IsEmpty());
|
||||
|
||||
Reference in New Issue
Block a user