Browse Source

replace weird asserts with unreachables

Signed-off-by: lizzie <lizzie@eden-emu.dev>
pull/2890/head
lizzie 3 months ago
parent
commit
89c0c29c77
No known key found for this signature in database GPG Key ID: 287378CADCAB13
  1. 3
      src/dynarmic/src/dynarmic/backend/arm64/emit_arm64.cpp
  2. 3
      src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64.cpp
  3. 3
      src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_a32.cpp
  4. 3
      src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp
  5. 6
      src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp
  6. 3
      src/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp
  7. 2
      src/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp
  8. 2
      src/dynarmic/src/dynarmic/backend/x64/emit_x64_data_processing.cpp
  9. 23
      src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp
  10. 6
      src/dynarmic/src/dynarmic/common/assert.cpp
  11. 51
      src/dynarmic/src/dynarmic/common/assert.h
  12. 18
      src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp
  13. 6
      src/dynarmic/src/dynarmic/ir/microinstruction.cpp
  14. 6
      src/dynarmic/src/dynarmic/ir/microinstruction.h
  15. 2
      src/dynarmic/src/dynarmic/ir/opt_passes.cpp

3
src/dynarmic/src/dynarmic/backend/arm64/emit_arm64.cpp

@ -241,8 +241,7 @@ EmittedBlockInfo EmitArm64(oaknut::CodeGenerator& code, IR::Block block, const E
#undef A32OPC
#undef A64OPC
default:
ASSERT(false && "Invalid opcode: {:x}", std::size_t(inst->GetOpcode()));
break;
UNREACHABLE();
}
reg_alloc.UpdateAllUses();

3
src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64.cpp

@ -143,8 +143,7 @@ EmittedBlockInfo EmitRV64(biscuit::Assembler& as, IR::Block block, const EmitCon
#undef A32OPC
#undef A64OPC
default:
ASSERT(false && "Invalid opcode: {:x}", std::size_t(inst->GetOpcode()));
break;
UNREACHABLE();
}
}

3
src/dynarmic/src/dynarmic/backend/riscv64/emit_riscv64_a32.cpp

@ -105,8 +105,7 @@ void EmitA32Cond(biscuit::Assembler& as, EmitContext&, IR::Cond cond, biscuit::L
as.BNEZ(Xscratch0, label);
break;
default:
ASSERT(false && "Unknown cond {}", static_cast<size_t>(cond));
break;
UNREACHABLE();
}
}

3
src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.cpp

@ -144,7 +144,8 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
#undef OPCODE
#undef A32OPC
#undef A64OPC
default: [[unlikely]] ASSERT(false && "Invalid opcode: {:x}", std::size_t(inst->GetOpcode()));
default:
UNREACHABLE();
}
reg_alloc.EndOfAllocScope();
func(reg_alloc);

6
src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.cpp

@ -129,10 +129,8 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) noexcept {
#undef OPCODE
#undef A32OPC
#undef A64OPC
default: [[unlikely]] {
ASSERT(false && "Invalid opcode: {:x}", std::size_t(opcode));
goto finish_this_inst;
}
default:
UNREACHABLE();
}
opcode_branch:
(this->*opcode_handlers[size_t(opcode)])(ctx, &inst);

3
src/dynarmic/src/dynarmic/backend/x64/block_of_code.cpp

@ -507,8 +507,7 @@ void BlockOfCode::LoadRequiredFlagsForCondFromRax(IR::Cond cond) {
case IR::Cond::NV:
break;
default:
ASSERT(false && "Unknown cond {}", static_cast<size_t>(cond));
break;
UNREACHABLE();
}
}

2
src/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp

@ -59,7 +59,7 @@ std::optional<EmitX64::BlockDescriptor> EmitX64::GetBasicBlock(IR::LocationDescr
}
void EmitX64::EmitInvalid(EmitContext&, IR::Inst* inst) {
ASSERT(false && "Invalid opcode: {:x}", std::size_t(inst->GetOpcode()));
UNREACHABLE();
}
void EmitX64::EmitVoid(EmitContext&, IR::Inst*) {

2
src/dynarmic/src/dynarmic/backend/x64/emit_x64_data_processing.cpp

@ -195,7 +195,7 @@ static void EmitConditionalSelect(BlockOfCode& code, EmitContext& ctx, IR::Inst*
code.mov(else_, then_);
break;
default:
ASSERT(false && "Invalid cond {}", static_cast<size_t>(args[0].GetImmediateCond()));
UNREACHABLE();
}
ctx.reg_alloc.DefineValue(inst, else_);

23
src/dynarmic/src/dynarmic/backend/x64/reg_alloc.cpp

@ -40,18 +40,6 @@ static inline bool CanExchange(const HostLoc a, const HostLoc b) noexcept {
// Minimum number of bits required to represent a type
static inline size_t GetBitWidth(const IR::Type type) noexcept {
switch (type) {
case IR::Type::A32Reg:
case IR::Type::A32ExtReg:
case IR::Type::A64Reg:
case IR::Type::A64Vec:
case IR::Type::CoprocInfo:
case IR::Type::Cond:
case IR::Type::Void:
case IR::Type::Table:
case IR::Type::AccType:
ASSERT(false && "Type {} cannot be represented at runtime", type);
case IR::Type::Opaque:
ASSERT(false && "Not a concrete type");
case IR::Type::U1:
return 8;
case IR::Type::U8:
@ -66,17 +54,14 @@ static inline size_t GetBitWidth(const IR::Type type) noexcept {
return 128;
case IR::Type::NZCVFlags:
return 32; // TODO: Update to 16 when flags optimization is done
default:
// A32REG A32EXTREG A64REG A64VEC COPROCINFO COND VOID TABLE ACCTYPE OPAQUE
UNREACHABLE();
}
UNREACHABLE();
}
static inline bool IsValuelessType(const IR::Type type) noexcept {
switch (type) {
case IR::Type::Table:
return true;
default:
return false;
}
return type == IR::Type::Table;
}
void HostLocInfo::ReleaseOne() noexcept {

6
src/dynarmic/src/dynarmic/common/assert.cpp

@ -3,13 +3,11 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <fmt/format.h>
#include <cstdio>
#include <exception>
[[noreturn]] void assert_terminate_impl(const char* expr_str, fmt::string_view msg, fmt::format_args args) {
fmt::print(stderr, "assertion failed: {}\n", expr_str);
fmt::vprint(stderr, msg, args);
[[noreturn]] void assert_terminate_impl(const char* s) {
std::puts(s);
std::fflush(stderr);
std::terminate();
}

51
src/dynarmic/src/dynarmic/common/assert.h

@ -6,48 +6,21 @@
#pragma once
#include <fmt/format.h>
[[noreturn]] void assert_terminate_impl(const char* expr_str, fmt::string_view msg, fmt::format_args args);
template<typename... Ts>
[[noreturn]] void assert_terminate(const char* expr_str, fmt::string_view msg, Ts... args) {
assert_terminate_impl(expr_str, msg, fmt::make_format_args(args...));
}
// Temporary until MCL is fully removed
#ifndef ASSERT_MSG
#define ASSERT_MSG(_a_, ...) \
([&]() { \
if (!(_a_)) [[unlikely]] { \
assert_terminate(#_a_, __VA_ARGS__); \
} \
}())
#endif
#ifndef ASSERT_FALSE
#define ASSERT_FALSE(...) \
([&]() { \
assert_terminate("false", __VA_ARGS__); \
}())
#endif
[[noreturn]] void assert_terminate_impl(const char* s);
#ifndef ASSERT
#define ASSERT(_a_) ASSERT(_a_ && "")
# define ASSERT(expr) do if(!(expr)) [[unlikely]] assert_terminate_impl(#expr); while(0)
#endif
#ifndef UNREACHABLE
#define UNREACHABLE() ASSERT(false && "unreachable")
# ifdef _MSC_VER
# define UNREACHABLE() ASSERT_FALSE("unreachable")
# else
# define UNREACHABLE() __builtin_unreachable();
# endif
#endif
#ifdef _DEBUG
#ifndef DEBUG_ASSERT
#define DEBUG_ASSERT(_a_) ASSERT(_a_)
#endif
#ifndef DEBUG_ASSERT_MSG
#define DEBUG_ASSERT_MSG(_a_, ...) ASSERT_MSG(_a_, __VA_ARGS__)
#endif
#else // not debug
#ifndef DEBUG_ASSERT
#define DEBUG_ASSERT(_a_)
#endif
#ifndef DEBUG_ASSERT_MSG
#define DEBUG_ASSERT_MSG(_a_, _desc_, ...)
#endif
# ifdef _DEBUG
# define DEBUG_ASSERT(_a_) ASSERT(_a_)
# else
# define DEBUG_ASSERT(_a_)
# endif
#endif

18
src/dynarmic/src/dynarmic/frontend/A64/translate/impl/impl.cpp

@ -232,9 +232,8 @@ IR::UAnyU128 TranslatorVisitor::Mem(IR::U64 address, size_t bytesize, IR::AccTyp
return ir.ReadMemory64(address, acc_type);
case 16:
return ir.ReadMemory128(address, acc_type);
default:
ASSERT(false && "Invalid bytesize parameter {}", bytesize);
}
UNREACHABLE();
}
void TranslatorVisitor::Mem(IR::U64 address, size_t bytesize, IR::AccType acc_type, IR::UAnyU128 value) {
@ -254,9 +253,8 @@ void TranslatorVisitor::Mem(IR::U64 address, size_t bytesize, IR::AccType acc_ty
case 16:
ir.WriteMemory128(address, value, acc_type);
return;
default:
ASSERT(false && "Invalid bytesize parameter {}", bytesize);
}
UNREACHABLE();
}
IR::UAnyU128 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccType acc_type) {
@ -271,9 +269,8 @@ IR::UAnyU128 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, I
return ir.ExclusiveReadMemory64(address, acc_type);
case 16:
return ir.ExclusiveReadMemory128(address, acc_type);
default:
ASSERT(false && "Invalid bytesize parameter {}", bytesize);
}
UNREACHABLE();
}
IR::U32 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::AccType acc_type, IR::UAnyU128 value) {
@ -288,9 +285,8 @@ IR::U32 TranslatorVisitor::ExclusiveMem(IR::U64 address, size_t bytesize, IR::Ac
return ir.ExclusiveWriteMemory64(address, value, acc_type);
case 16:
return ir.ExclusiveWriteMemory128(address, value, acc_type);
default:
ASSERT(false && "Invalid bytesize parameter {}", bytesize);
}
UNREACHABLE();
}
IR::U32U64 TranslatorVisitor::SignExtend(IR::UAny value, size_t to_size) {
@ -299,9 +295,8 @@ IR::U32U64 TranslatorVisitor::SignExtend(IR::UAny value, size_t to_size) {
return ir.SignExtendToWord(value);
case 64:
return ir.SignExtendToLong(value);
default:
ASSERT(false && "Invalid size parameter {}", to_size);
}
UNREACHABLE();
}
IR::U32U64 TranslatorVisitor::ZeroExtend(IR::UAny value, size_t to_size) {
@ -310,9 +305,8 @@ IR::U32U64 TranslatorVisitor::ZeroExtend(IR::UAny value, size_t to_size) {
return ir.ZeroExtendToWord(value);
case 64:
return ir.ZeroExtendToLong(value);
default:
ASSERT(false && "Invalid size parameter {}", to_size);
}
UNREACHABLE();
}
IR::U32U64 TranslatorVisitor::ShiftReg(size_t bitsize, Reg reg, Imm<2> shift, IR::U8 amount) {

6
src/dynarmic/src/dynarmic/ir/microinstruction.cpp

@ -42,8 +42,10 @@ Type Inst::GetType() const {
}
void Inst::SetArg(size_t index, Value value) noexcept {
DEBUG_ASSERT(index < GetNumArgsOf(op) && "Inst::SetArg: index {} >= number of arguments of {} ({})", index, op, GetNumArgsOf(op));
DEBUG_ASSERT(AreTypesCompatible(value.GetType(), GetArgTypeOf(op, index)) && "Inst::SetArg: type {} of argument {} not compatible with operation {} ({})", value.GetType(), index, op, GetArgTypeOf(op, index));
DEBUG_ASSERT(index < GetNumArgsOf(op));
DEBUG_ASSERT(AreTypesCompatible(value.GetType(), GetArgTypeOf(op, index)));
//DEBUG_ASSERT(index < GetNumArgsOf(op) && "Inst::SetArg: index {} >= number of arguments of {} ({})", index, op, GetNumArgsOf(op));
//DEBUG_ASSERT(AreTypesCompatible(value.GetType(), GetArgTypeOf(op, index)) && "Inst::SetArg: type {} of argument {} not compatible with operation {} ({})", value.GetType(), index, op, GetArgTypeOf(op, index));
if (!args[index].IsImmediate()) {
UndoUse(args[index]);
}

6
src/dynarmic/src/dynarmic/ir/microinstruction.h

@ -53,8 +53,10 @@ public:
}
inline Value GetArg(size_t index) const noexcept {
DEBUG_ASSERT(index < GetNumArgsOf(op) && "Inst::GetArg: index {} >= number of arguments of {} ({})", index, op, GetNumArgsOf(op));
DEBUG_ASSERT(!args[index].IsEmpty() || GetArgTypeOf(op, index) == IR::Type::Opaque && "Inst::GetArg: index {} is empty", index, args[index].GetType());
DEBUG_ASSERT(index < GetNumArgsOf(op));
DEBUG_ASSERT(!args[index].IsEmpty() || GetArgTypeOf(op, index) == IR::Type::Opaque);
//DEBUG_ASSERT(index < GetNumArgsOf(op) && "Inst::GetArg: index {} >= number of arguments of {} ({})", index, op, GetNumArgsOf(op));
//DEBUG_ASSERT(!args[index].IsEmpty() || GetArgTypeOf(op, index) == IR::Type::Opaque && "Inst::GetArg: index {} is empty", index, args[index].GetType());
return args[index];
}
void SetArg(size_t index, Value value) noexcept;

2
src/dynarmic/src/dynarmic/ir/opt_passes.cpp

@ -1466,7 +1466,7 @@ static void VerificationPass(const IR::Block& block) {
for (size_t i = 0; i < inst.NumArgs(); i++) {
const IR::Type t1 = inst.GetArg(i).GetType();
const IR::Type t2 = IR::GetArgTypeOf(inst.GetOpcode(), i);
ASSERT(IR::AreTypesCompatible(t1, t2) && "Block failed:\n{}", IR::DumpBlock(block));
ASSERT(IR::AreTypesCompatible(t1, t2));
}
}
ankerl::unordered_dense::map<IR::Inst*, size_t> actual_uses;

Loading…
Cancel
Save