verification_pass: show type errors
This commit is contained in:
parent
dad7724b86
commit
9782e7da3f
4 changed files with 35 additions and 13 deletions
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue