verification_pass: show type errors

This commit is contained in:
Tillmann Karras 2016-08-17 13:29:05 +01:00 committed by MerryMage
parent dad7724b86
commit 9782e7da3f
4 changed files with 35 additions and 13 deletions

View file

@ -70,8 +70,16 @@ std::string DumpBlock(const IR::Block& block) {
const size_t arg_count = GetNumArgsOf(op); const size_t arg_count = GetNumArgsOf(op);
for (size_t arg_index = 0; arg_index < arg_count; arg_index++) { for (size_t arg_index = 0; arg_index < arg_count; arg_index++) {
const Value arg = inst->GetArg(arg_index);
ret += arg_index != 0 ? ", " : " "; ret += arg_index != 0 ? ", " : " ";
ret += arg_to_string(inst->GetArg(arg_index)); ret += arg_to_string(arg);
Type actual_type = arg.GetType();
Type expected_type = GetArgTypeOf(op, arg_index);
if (actual_type != expected_type && actual_type != Type::Opaque && expected_type != Type::Opaque) {
ret += Common::StringFromFormat("<type error: %s != %s>", GetNameOf(actual_type), GetNameOf(expected_type));
}
} }
ret += "\n"; ret += "\n";

View file

@ -4,6 +4,7 @@
* General Public License version 2 or any later version. * General Public License version 2 or any later version.
*/ */
#include <array>
#include <map> #include <map>
#include <vector> #include <vector>
@ -48,5 +49,12 @@ const char* GetNameOf(Opcode op) {
return OpcodeInfo::opcode_info.at(op).name; return OpcodeInfo::opcode_info.at(op).name;
} }
const char* GetNameOf(Type type) {
const static std::array<const char*, 11> names = {
"Void", "RegRef", "ExtRegRef", "Opaque", "U1", "U8", "U16", "U32", "U64", "F32", "F64"
};
return names.at(static_cast<size_t>(type));
}
} // namespace IR } // namespace IR
} // namespace Dynarmic } // namespace Dynarmic

View file

@ -28,17 +28,17 @@ constexpr size_t OpcodeCount = static_cast<size_t>(Opcode::NUM_OPCODE);
* The intermediate representation is typed. These are the used by our IR. * The intermediate representation is typed. These are the used by our IR.
*/ */
enum class Type { enum class Type {
Void = 1 << 0, Void,
RegRef = 1 << 1, RegRef,
ExtRegRef = 1 << 2, ExtRegRef,
Opaque = 1 << 3, Opaque,
U1 = 1 << 4, U1,
U8 = 1 << 5, U8,
U16 = 1 << 6, U16,
U32 = 1 << 7, U32,
U64 = 1 << 8, U64,
F32 = 1 << 9, F32,
F64 = 1 << 10, F64,
}; };
/// Get return type of an opcode /// Get return type of an opcode
@ -53,5 +53,8 @@ Type GetArgTypeOf(Opcode op, size_t arg_index);
/// Get the name of an opcode. /// Get the name of an opcode.
const char* GetNameOf(Opcode op); const char* GetNameOf(Opcode op);
/// Get the name of a type.
const char* GetNameOf(Type type);
} // namespace Arm } // namespace Arm
} // namespace Dynarmic } // namespace Dynarmic

View file

@ -20,7 +20,10 @@ void VerificationPass(const IR::Block& block) {
for (size_t i = 0; i < inst.NumArgs(); i++) { for (size_t i = 0; i < inst.NumArgs(); i++) {
IR::Type t1 = inst.GetArg(i).GetType(); IR::Type t1 = inst.GetArg(i).GetType();
IR::Type t2 = IR::GetArgTypeOf(inst.GetOpcode(), i); IR::Type t2 = IR::GetArgTypeOf(inst.GetOpcode(), i);
ASSERT(t1 == t2 || t1 == IR::Type::Opaque || t2 == IR::Type::Opaque); if (t1 != t2 && t1 != IR::Type::Opaque && t2 != IR::Type::Opaque) {
puts(IR::DumpBlock(block).c_str());
ASSERT(false);
}
} }
} }