IR: Add VectorTable and VectorTableLookup IR instructions

This commit is contained in:
MerryMage 2018-08-18 21:08:34 +01:00
parent 0288974512
commit 89d08c7d61
12 changed files with 133 additions and 39 deletions

View file

@ -1537,6 +1537,16 @@ U128 IREmitter::VectorSub(size_t esize, const U128& a, const U128& b) {
return {};
}
Table IREmitter::VectorTable(std::vector<U128> values) {
ASSERT(values.size() >= 1 && values.size() <= 4);
values.resize(4);
return Inst<Table>(Opcode::VectorTable, values[0], values[1], values[2], values[3]);
}
U128 IREmitter::VectorTableLookup(const U128& defaults, const Table& table, const U128& indices) {
return Inst<U128>(Opcode::VectorTableLookup, defaults, table, indices);
}
U128 IREmitter::VectorUnsignedAbsoluteDifference(size_t esize, const U128& a, const U128& b) {
switch (esize) {
case 8:

View file

@ -266,6 +266,8 @@ public:
U128 VectorSignedSaturatedNarrowToSigned(size_t original_esize, const U128& a);
U128 VectorSignedSaturatedNarrowToUnsigned(size_t original_esize, const U128& a);
U128 VectorSub(size_t esize, const U128& a, const U128& b);
Table VectorTable(std::vector<U128> values);
U128 VectorTableLookup(const U128& defaults, const Table& table, const U128& indices);
U128 VectorUnsignedAbsoluteDifference(size_t esize, const U128& a, const U128& b);
U128 VectorUnsignedSaturatedNarrow(size_t esize, const U128& a);
U128 VectorZeroExtend(size_t original_esize, const U128& a);

View file

@ -489,7 +489,7 @@ size_t Inst::NumArgs() const {
Value Inst::GetArg(size_t index) const {
ASSERT_MSG(index < GetNumArgsOf(op), "Inst::GetArg: index {} >= number of arguments of {} ({})", index, op, GetNumArgsOf(op));
ASSERT_MSG(!args[index].IsEmpty(), "Inst::GetArg: index {} is empty", index);
ASSERT_MSG(!args[index].IsEmpty() || GetArgTypeOf(op, index) == IR::Type::Opaque, "Inst::GetArg: index {} is empty", index, args[index].GetType());
return args[index];
}

View file

@ -17,6 +17,8 @@ namespace Dynarmic::IR {
enum class Opcode;
enum class Type;
constexpr size_t max_arg_count = 4;
/**
* A representation of a microinstruction. A single ARM/Thumb instruction may be
* converted into zero or more microinstructions.
@ -136,7 +138,7 @@ private:
Opcode op;
size_t use_count = 0;
std::array<Value, 3> args;
std::array<Value, max_arg_count> args;
// Pointers to related pseudooperations:
// Since not all combinations are possible, we use a union to save space

View file

@ -43,6 +43,7 @@ constexpr Type U128 = Type::U128;
constexpr Type CoprocInfo = Type::CoprocInfo;
constexpr Type NZCV = Type::NZCVFlags;
constexpr Type Cond = Type::Cond;
constexpr Type Table = Type::Table;
static const std::map<Opcode, Meta> opcode_info {{
#define OPCODE(name, type, ...) { Opcode::name, { #name, type, { __VA_ARGS__ } } },

View file

@ -401,6 +401,8 @@ OPCODE(VectorSub8, U128, U128,
OPCODE(VectorSub16, U128, U128, U128 )
OPCODE(VectorSub32, U128, U128, U128 )
OPCODE(VectorSub64, U128, U128, U128 )
OPCODE(VectorTable, Table, U128, Opaque, Opaque, Opaque )
OPCODE(VectorTableLookup, U128, U128, Table, U128 )
OPCODE(VectorUnsignedAbsoluteDifference8, U128, U128, U128 )
OPCODE(VectorUnsignedAbsoluteDifference16, U128, U128, U128 )
OPCODE(VectorUnsignedAbsoluteDifference32, U128, U128, U128 )

View file

@ -16,13 +16,23 @@
namespace Dynarmic::IR {
std::string GetNameOf(Type type) {
static const std::array<const char*, 16> names = {
"Void", "A32Reg", "A32ExtReg", "A64Reg", "A64Vec", "Opaque", "U1", "U8", "U16", "U32", "U64", "F32", "F64", "CoprocInfo", "NZCVFlags", "Cond"
};
const size_t index = static_cast<size_t>(type);
if (index > names.size())
return fmt::format("Unknown Type {}", index);
return names.at(index);
static const std::array<const char*, 15> names{"A32Reg", "A32ExtReg", "A64Reg", "A64Vec", "Opaque", "U1", "U8", "U16", "U32", "U64", "U128", "CoprocInfo", "NZCVFlags", "Cond", "Table"};
const size_t bits = static_cast<size_t>(type);
if (bits == 0) {
return "Void";
}
std::string result;
for (size_t i = 0; i < names.size(); i++) {
if ((bits & (size_t(1) << i)) != 0) {
if (!result.empty()) {
result += '|';
}
result += names[i];
}
}
return result;
}
bool AreTypesCompatible(Type t1, Type t2) {

View file

@ -32,6 +32,7 @@ enum class Type {
CoprocInfo = 1 << 11,
NZCVFlags = 1 << 12,
Cond = 1 << 13,
Table = 1 << 14,
};
constexpr Type operator|(Type a, Type b) {

View file

@ -103,5 +103,6 @@ using U32U64 = TypedValue<Type::U32 | Type::U64>;
using UAny = TypedValue<Type::U8 | Type::U16 | Type::U32 | Type::U64>;
using UAnyU128 = TypedValue<Type::U8 | Type::U16 | Type::U32 | Type::U64 | Type::U128>;
using NZCV = TypedValue<Type::NZCVFlags>;
using Table = TypedValue<Type::Table>;
} // namespace Dynarmic::IR