mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-04 05:34:42 +01:00
IR: Implement Conditional Select
This commit is contained in:
parent
7992a319ba
commit
6395f09f94
9 changed files with 126 additions and 0 deletions
|
|
@ -91,6 +91,23 @@ U1 IREmitter::TestBit(const U32U64& value, const U8& bit) {
|
|||
}
|
||||
}
|
||||
|
||||
U32 IREmitter::ConditionalSelect(Cond cond, const U32& a, const U32& b) {
|
||||
return Inst<U32>(Opcode::ConditionalSelect32, Value{cond}, a, b);
|
||||
}
|
||||
|
||||
U64 IREmitter::ConditionalSelect(Cond cond, const U64& a, const U64& b) {
|
||||
return Inst<U64>(Opcode::ConditionalSelect64, Value{cond}, a, b);
|
||||
}
|
||||
|
||||
U32U64 IREmitter::ConditionalSelect(Cond cond, const U32U64& a, const U32U64& b) {
|
||||
ASSERT(a.GetType() == b.GetType());
|
||||
if (a.GetType() == Type::U32) {
|
||||
return Inst<U32>(Opcode::ConditionalSelect32, Value{cond}, a, b);
|
||||
} else {
|
||||
return Inst<U64>(Opcode::ConditionalSelect64, Value{cond}, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
NZCV IREmitter::NZCVFrom(const Value& value) {
|
||||
return Inst<NZCV>(Opcode::GetNZCVFromOp, value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ public:
|
|||
U1 IsZero(const U64& value);
|
||||
U1 IsZero(const U32U64& value);
|
||||
U1 TestBit(const U32U64& value, const U8& bit);
|
||||
U32 ConditionalSelect(Cond cond, const U32& a, const U32& b);
|
||||
U64 ConditionalSelect(Cond cond, const U64& a, const U64& b);
|
||||
U32U64 ConditionalSelect(Cond cond, const U32U64& a, const U32U64& b);
|
||||
|
||||
// This pseudo-instruction may only be added to instructions that support it.
|
||||
NZCV NZCVFrom(const Value& value);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ enum class Type {
|
|||
F128 = 1 << 12,
|
||||
CoprocInfo = 1 << 13,
|
||||
NZCVFlags = 1 << 14,
|
||||
Cond = 1 << 15,
|
||||
};
|
||||
|
||||
constexpr Type operator|(Type a, Type b) {
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ OPCODE(MostSignificantBit, T::U1, T::U32
|
|||
OPCODE(IsZero32, T::U1, T::U32 )
|
||||
OPCODE(IsZero64, T::U1, T::U64 )
|
||||
OPCODE(TestBit, T::U1, T::U64, T::U8 )
|
||||
OPCODE(ConditionalSelect32, T::U32, T::Cond, T::U32, T::U32 )
|
||||
OPCODE(ConditionalSelect64, T::U64, T::Cond, T::U64, T::U64 )
|
||||
OPCODE(LogicalShiftLeft32, T::U32, T::U32, T::U8, T::U1 )
|
||||
OPCODE(LogicalShiftLeft64, T::U64, T::U64, T::U8 )
|
||||
OPCODE(LogicalShiftRight32, T::U32, T::U32, T::U8, T::U1 )
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ Value::Value(std::array<u8, 8> value) : type(Type::CoprocInfo) {
|
|||
inner.imm_coproc = value;
|
||||
}
|
||||
|
||||
Value::Value(Cond value) : type(Type::Cond) {
|
||||
inner.imm_cond = value;
|
||||
}
|
||||
|
||||
bool Value::IsImmediate() const {
|
||||
if (type == Type::Opaque)
|
||||
return inner.inst->GetOpcode() == Opcode::Identity ? inner.inst->GetArg(0).IsImmediate() : false;
|
||||
|
|
@ -143,5 +147,12 @@ std::array<u8, 8> Value::GetCoprocInfo() const {
|
|||
return inner.imm_coproc;
|
||||
}
|
||||
|
||||
Cond Value::GetCond() const {
|
||||
if (type == Type::Opaque && inner.inst->GetOpcode() == Opcode::Identity)
|
||||
return inner.inst->GetArg(0).GetCond();
|
||||
ASSERT(type == Type::Cond);
|
||||
return inner.imm_cond;
|
||||
}
|
||||
|
||||
} // namespace IR
|
||||
} // namespace Dynarmic
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "common/common_types.h"
|
||||
#include "frontend/A32/types.h"
|
||||
#include "frontend/A64/types.h"
|
||||
#include "frontend/ir/cond.h"
|
||||
#include "frontend/ir/opcodes.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
|
|
@ -37,6 +38,7 @@ public:
|
|||
explicit Value(u32 value);
|
||||
explicit Value(u64 value);
|
||||
explicit Value(std::array<u8, 8> value);
|
||||
explicit Value(Cond value);
|
||||
|
||||
bool IsEmpty() const;
|
||||
bool IsImmediate() const;
|
||||
|
|
@ -53,6 +55,7 @@ public:
|
|||
u32 GetU32() const;
|
||||
u64 GetU64() const;
|
||||
std::array<u8, 8> GetCoprocInfo() const;
|
||||
Cond GetCond() const;
|
||||
|
||||
private:
|
||||
Type type;
|
||||
|
|
@ -69,6 +72,7 @@ private:
|
|||
u32 imm_u32;
|
||||
u64 imm_u64;
|
||||
std::array<u8, 8> imm_coproc;
|
||||
Cond imm_cond;
|
||||
} inner;
|
||||
};
|
||||
static_assert(sizeof(Value) <= 2 * sizeof(u64), "IR::Value should be kept small in size");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue