[dynarmic] simplify assert macro usage (Only ASSERT/DEBUG_ASSERT are needed) (#2890)

- replace instances of ASSERT() with those where UNREACHABLE() should be used instead
- debuggers exist for a reason, you can't just debug an issue in dynarmic with just printing fancy text... you need to inspect values and alldat - while yes the asserts are "useful"; there is this beautiful thing called backtraces
- this will indirectly speedup the main decoder loop because of the added UNREACHABLE()
- this also removes a bunch of macros that were redundant
- the weird trick of [&](){}() is really funky, just do what everyone has done for the past 30 years and use a `do { <thing> } while(0)` :)

I may or may not have missed one assert or messed up my regex substitutions...

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2890
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2025-10-31 17:22:06 +01:00 committed by crueter
parent 2dc6d773ee
commit f9773fa908
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
65 changed files with 385 additions and 429 deletions

View File

@ -257,7 +257,7 @@ pacman -Syu --needed --noconfirm $packages
<summary>HaikuOS</summary>
```sh
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt6_devel qt6_5compat_devel libusb1_devel libz_devel glslang mbedtls3
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt6_devel qt6_5compat_devel libusb1_devel libz_devel mbedtls3_devel glslang
```
[Caveats](./Caveats.md#haikuos).

View File

@ -61,11 +61,7 @@ constexpr RegisterList ToRegList(oaknut::Reg reg) {
if (reg.is_vector()) {
return RegisterList{1} << (reg.index() + 32);
}
if (reg.index() == 31) {
ASSERT_FALSE("ZR not allowed in reg list");
}
ASSERT(reg.index() != 31 && "ZR not allowed in reg list");
if (reg.index() == -1) {
return RegisterList{1} << 31;
}

View File

@ -28,7 +28,7 @@ AddressSpace::AddressSpace(size_t code_cache_size)
, mem(code_cache_size)
, code(mem.ptr(), mem.ptr())
, fastmem_manager(exception_handler) {
ASSERT_MSG(code_cache_size <= 128 * 1024 * 1024, "code_cache_size > 128 MiB not currently supported");
ASSERT(code_cache_size <= 128 * 1024 * 1024 && "code_cache_size > 128 MiB not currently supported");
exception_handler.Register(mem, code_cache_size);
exception_handler.SetFastmemCallback([this](u64 host_pc) {
@ -258,7 +258,7 @@ void AddressSpace::Link(EmittedBlockInfo& block_info) {
c.BL(prelude_info.get_ticks_remaining);
break;
default:
ASSERT_FALSE("Invalid relocation target");
UNREACHABLE();
}
}
@ -292,7 +292,7 @@ void AddressSpace::LinkBlockLinks(const CodePtr entry_point, const CodePtr targe
}
break;
default:
ASSERT_FALSE("Invalid BlockRelocationType");
UNREACHABLE();
}
}
}
@ -342,9 +342,9 @@ FakeCall AddressSpace::FastmemCallback(u64 host_pc) {
}
fail:
fmt::print("dynarmic: Segfault happened within JITted code at host_pc = {:016x}\n", host_pc);
fmt::print("Segfault wasn't at a fastmem patch location!\n");
ASSERT_FALSE("segfault");
fmt::print("dynarmic: Segfault happened within JITted code at host_pc = {:016x}\n"
"Segfault wasn't at a fastmem patch location!\n", host_pc);
UNREACHABLE();
}
} // namespace Dynarmic::Backend::Arm64

View File

@ -112,8 +112,7 @@ void EmitIR<IR::Opcode::GetNZCVFromOp>(oaknut::CodeGenerator& code, EmitContext&
break;
}
default:
ASSERT_FALSE("Invalid type for GetNZCVFromOp");
break;
UNREACHABLE();
}
}
@ -143,8 +142,7 @@ void EmitIR<IR::Opcode::GetNZFromOp>(oaknut::CodeGenerator& code, EmitContext& c
break;
}
default:
ASSERT_FALSE("Invalid type for GetNZFromOp");
break;
UNREACHABLE();
}
}
@ -241,8 +239,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();

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@ -34,7 +37,7 @@ oaknut::Label EmitA32Cond(oaknut::CodeGenerator& code, EmitContext&, IR::Cond co
void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Terminal terminal, IR::LocationDescriptor initial_location, bool is_single_step);
void EmitA32Terminal(oaknut::CodeGenerator&, EmitContext&, IR::Term::Interpret, IR::LocationDescriptor, bool) {
ASSERT_FALSE("Interpret should never be emitted.");
UNREACHABLE();
}
void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) {

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@ -20,7 +23,8 @@ namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util;
static void EmitCoprocessorException() {
ASSERT_FALSE("Should raise coproc exception here");
// TODO: Raise coproc except
UNREACHABLE();
}
static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr, std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}) {

View File

@ -36,7 +36,7 @@ oaknut::Label EmitA64Cond(oaknut::CodeGenerator& code, EmitContext&, IR::Cond co
void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Terminal terminal, IR::LocationDescriptor initial_location, bool is_single_step);
void EmitA64Terminal(oaknut::CodeGenerator&, EmitContext&, IR::Term::Interpret, IR::LocationDescriptor, bool) {
ASSERT_FALSE("Interpret should never be emitted.");
UNREACHABLE();
}
void EmitA64Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) {

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@ -117,7 +120,7 @@ void EmitIR<IR::Opcode::SM4AccessSubstitutionBox>(oaknut::CodeGenerator& code, E
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@ -123,11 +126,10 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
code.FCVTAS(Rto, Vfrom);
break;
case FP::RoundingMode::ToOdd:
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
break;
default:
ASSERT_FALSE("Invalid RoundingMode");
break;
UNREACHABLE();
}
} else {
switch (rounding_mode) {
@ -147,11 +149,10 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
code.FCVTAU(Rto, Vfrom);
break;
case FP::RoundingMode::ToOdd:
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
break;
default:
ASSERT_FALSE("Invalid RoundingMode");
break;
UNREACHABLE();
}
}
}
@ -188,7 +189,7 @@ void EmitIR<IR::Opcode::FPAbs16>(oaknut::CodeGenerator& code, EmitContext& ctx,
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -315,7 +316,7 @@ void EmitIR<IR::Opcode::FPMulAdd16>(oaknut::CodeGenerator& code, EmitContext& ct
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -333,7 +334,7 @@ void EmitIR<IR::Opcode::FPMulSub16>(oaknut::CodeGenerator& code, EmitContext& ct
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -361,7 +362,7 @@ void EmitIR<IR::Opcode::FPNeg16>(oaknut::CodeGenerator& code, EmitContext& ctx,
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -379,7 +380,7 @@ void EmitIR<IR::Opcode::FPRecipEstimate16>(oaknut::CodeGenerator& code, EmitCont
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -397,7 +398,7 @@ void EmitIR<IR::Opcode::FPRecipExponent16>(oaknut::CodeGenerator& code, EmitCont
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -415,7 +416,7 @@ void EmitIR<IR::Opcode::FPRecipStepFused16>(oaknut::CodeGenerator& code, EmitCon
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -433,7 +434,7 @@ void EmitIR<IR::Opcode::FPRoundInt16>(oaknut::CodeGenerator& code, EmitContext&
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -467,9 +468,8 @@ void EmitIR<IR::Opcode::FPRoundInt32>(oaknut::CodeGenerator& code, EmitContext&
case FP::RoundingMode::ToNearest_TieAwayFromZero:
code.FRINTA(Sresult, Soperand);
break;
default:
ASSERT_FALSE("Invalid RoundingMode");
}
UNREACHABLE();
}
}
@ -505,7 +505,7 @@ void EmitIR<IR::Opcode::FPRoundInt64>(oaknut::CodeGenerator& code, EmitContext&
code.FRINTA(Dresult, Doperand);
break;
default:
ASSERT_FALSE("Invalid RoundingMode");
UNREACHABLE();
}
}
}
@ -515,7 +515,7 @@ void EmitIR<IR::Opcode::FPRSqrtEstimate16>(oaknut::CodeGenerator& code, EmitCont
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -533,7 +533,7 @@ void EmitIR<IR::Opcode::FPRSqrtStepFused16>(oaknut::CodeGenerator& code, EmitCon
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -647,7 +647,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedS16>(oaknut::CodeGenerator& code, EmitConte
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -655,7 +655,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedS32>(oaknut::CodeGenerator& code, EmitConte
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -663,7 +663,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedS64>(oaknut::CodeGenerator& code, EmitConte
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -671,7 +671,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedU16>(oaknut::CodeGenerator& code, EmitConte
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -679,7 +679,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedU32>(oaknut::CodeGenerator& code, EmitConte
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -687,7 +687,7 @@ void EmitIR<IR::Opcode::FPHalfToFixedU64>(oaknut::CodeGenerator& code, EmitConte
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>

View File

@ -315,7 +315,7 @@ CodePtr EmitMemoryLdr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
code.DMB(oaknut::BarrierOp::ISH);
break;
default:
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
} else {
fastmem_location = code.xptr<CodePtr>();
@ -337,7 +337,7 @@ CodePtr EmitMemoryLdr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
code.LDR(oaknut::QReg{value_idx}, Xbase, Roffset, index_ext);
break;
default:
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
}
@ -376,7 +376,7 @@ CodePtr EmitMemoryStr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
code.DMB(oaknut::BarrierOp::ISH);
break;
default:
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
} else {
fastmem_location = code.xptr<CodePtr>();
@ -398,7 +398,7 @@ CodePtr EmitMemoryStr(oaknut::CodeGenerator& code, int value_idx, oaknut::XReg X
code.STR(oaknut::QReg{value_idx}, Xbase, Roffset, index_ext);
break;
default:
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
}

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@ -131,7 +134,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAdd8>(oaknut::CodeGenerator& code, EmitCo
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -139,7 +142,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAdd16>(oaknut::CodeGenerator& code, EmitC
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -147,7 +150,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAdd32>(oaknut::CodeGenerator& code, EmitC
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -155,7 +158,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAdd64>(oaknut::CodeGenerator& code, EmitC
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -163,7 +166,7 @@ void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh16>(oaknut::Cod
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -171,7 +174,7 @@ void EmitIR<IR::Opcode::SignedSaturatedDoublingMultiplyReturnHigh32>(oaknut::Cod
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -179,7 +182,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSub8>(oaknut::CodeGenerator& code, EmitCo
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -187,7 +190,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSub16>(oaknut::CodeGenerator& code, EmitC
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -195,7 +198,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSub32>(oaknut::CodeGenerator& code, EmitC
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -203,7 +206,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSub64>(oaknut::CodeGenerator& code, EmitC
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -211,7 +214,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedAdd8>(oaknut::CodeGenerator& code, Emit
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -219,7 +222,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedAdd16>(oaknut::CodeGenerator& code, Emi
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -227,7 +230,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedAdd32>(oaknut::CodeGenerator& code, Emi
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -235,7 +238,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedAdd64>(oaknut::CodeGenerator& code, Emi
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -243,7 +246,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedSub8>(oaknut::CodeGenerator& code, Emit
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -251,7 +254,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedSub16>(oaknut::CodeGenerator& code, Emi
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -259,7 +262,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedSub32>(oaknut::CodeGenerator& code, Emi
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -267,7 +270,7 @@ void EmitIR<IR::Opcode::UnsignedSaturatedSub64>(oaknut::CodeGenerator& code, Emi
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
} // namespace Dynarmic::Backend::Arm64

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
@ -638,7 +641,7 @@ void EmitIR<IR::Opcode::VectorEqual128>(oaknut::CodeGenerator& code, EmitContext
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -867,7 +870,7 @@ void EmitIR<IR::Opcode::VectorMaxS64>(oaknut::CodeGenerator& code, EmitContext&
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -890,7 +893,7 @@ void EmitIR<IR::Opcode::VectorMaxU64>(oaknut::CodeGenerator& code, EmitContext&
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -913,7 +916,7 @@ void EmitIR<IR::Opcode::VectorMinS64>(oaknut::CodeGenerator& code, EmitContext&
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -936,7 +939,7 @@ void EmitIR<IR::Opcode::VectorMinU64>(oaknut::CodeGenerator& code, EmitContext&
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -956,7 +959,7 @@ void EmitIR<IR::Opcode::VectorMultiply32>(oaknut::CodeGenerator& code, EmitConte
template<>
void EmitIR<IR::Opcode::VectorMultiply64>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
ASSERT_MSG(ctx.conf.very_verbose_debugging_output, "VectorMultiply64 is for debugging only");
ASSERT(ctx.conf.very_verbose_debugging_output && "VectorMultiply64 is for debugging only");
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
code.FMOV(Xscratch0, Qa->toD());
code.FMOV(Xscratch1, Qb->toD());
@ -1383,7 +1386,7 @@ void EmitIR<IR::Opcode::VectorSignExtend64>(oaknut::CodeGenerator& code, EmitCon
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -1406,7 +1409,7 @@ void EmitIR<IR::Opcode::VectorSignedMultiply16>(oaknut::CodeGenerator& code, Emi
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -1414,7 +1417,7 @@ void EmitIR<IR::Opcode::VectorSignedMultiply32>(oaknut::CodeGenerator& code, Emi
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -1600,7 +1603,7 @@ void EmitIR<IR::Opcode::VectorSub64>(oaknut::CodeGenerator& code, EmitContext& c
template<>
void EmitIR<IR::Opcode::VectorTable>(oaknut::CodeGenerator&, EmitContext&, IR::Inst* inst) {
// Do nothing. We *want* to hold on to the refcount for our arguments, so VectorTableLookup can use our arguments.
ASSERT_MSG(inst->UseCount() == 1, "Table cannot be used multiple times");
ASSERT(inst->UseCount() == 1 && "Table cannot be used multiple times");
}
template<>
@ -1665,9 +1668,8 @@ void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitCo
code.TBX(Dresult->B8(), oaknut::List{V0.B16(), V1.B16()}, Dindices->B8());
}
break;
default:
ASSERT_FALSE("Unsupported table_size");
}
UNREACHABLE();
}
template<>
@ -1729,9 +1731,8 @@ void EmitIR<IR::Opcode::VectorTableLookup128>(oaknut::CodeGenerator& code, EmitC
code.TBX(Qresult->B16(), oaknut::List{V0.B16(), V1.B16(), V2.B16(), V3.B16()}, Qindices->B16());
}
break;
default:
ASSERT_FALSE("Unsupported table_size");
}
UNREACHABLE();
}
template<>
@ -1778,7 +1779,7 @@ void EmitIR<IR::Opcode::VectorUnsignedMultiply16>(oaknut::CodeGenerator& code, E
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -1786,7 +1787,7 @@ void EmitIR<IR::Opcode::VectorUnsignedMultiply32>(oaknut::CodeGenerator& code, E
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>

View File

@ -227,11 +227,10 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
code.FCVTAS(Vto, Vfrom);
break;
case FP::RoundingMode::ToOdd:
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
break;
default:
ASSERT_FALSE("Invalid RoundingMode");
break;
UNREACHABLE();
}
} else {
switch (rounding_mode) {
@ -251,11 +250,10 @@ void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst)
code.FCVTAU(Vto, Vfrom);
break;
case FP::RoundingMode::ToOdd:
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
break;
default:
ASSERT_FALSE("Invalid RoundingMode");
break;
UNREACHABLE();
}
}
}
@ -340,7 +338,7 @@ void EmitIR<IR::Opcode::FPVectorEqual16>(oaknut::CodeGenerator& code, EmitContex
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -465,7 +463,7 @@ void EmitIR<IR::Opcode::FPVectorMulAdd16>(oaknut::CodeGenerator& code, EmitConte
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -493,7 +491,7 @@ void EmitIR<IR::Opcode::FPVectorNeg16>(oaknut::CodeGenerator& code, EmitContext&
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -538,7 +536,7 @@ void EmitIR<IR::Opcode::FPVectorRecipEstimate16>(oaknut::CodeGenerator& code, Em
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -556,7 +554,7 @@ void EmitIR<IR::Opcode::FPVectorRecipStepFused16>(oaknut::CodeGenerator& code, E
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -647,9 +645,8 @@ void EmitIR<IR::Opcode::FPVectorRoundInt32>(oaknut::CodeGenerator& code, EmitCon
case FP::RoundingMode::ToNearest_TieAwayFromZero:
code.FRINTA(Qresult->S4(), Qoperand->S4());
break;
default:
ASSERT_FALSE("Invalid RoundingMode");
}
UNREACHABLE();
}
});
}
@ -687,9 +684,8 @@ void EmitIR<IR::Opcode::FPVectorRoundInt64>(oaknut::CodeGenerator& code, EmitCon
case FP::RoundingMode::ToNearest_TieAwayFromZero:
code.FRINTA(Qresult->D2(), Qoperand->D2());
break;
default:
ASSERT_FALSE("Invalid RoundingMode");
}
UNREACHABLE();
}
});
}
@ -699,7 +695,7 @@ void EmitIR<IR::Opcode::FPVectorRSqrtEstimate16>(oaknut::CodeGenerator& code, Em
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -717,7 +713,7 @@ void EmitIR<IR::Opcode::FPVectorRSqrtStepFused16>(oaknut::CodeGenerator& code, E
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -772,7 +768,7 @@ void EmitIR<IR::Opcode::FPVectorToSignedFixed16>(oaknut::CodeGenerator& code, Em
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>
@ -790,7 +786,7 @@ void EmitIR<IR::Opcode::FPVectorToUnsignedFixed16>(oaknut::CodeGenerator& code,
(void)code;
(void)ctx;
(void)inst;
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
}
template<>

View File

@ -136,7 +136,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
const IR::Value arg = inst->GetArg(i);
ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
ASSERT_MSG(ValueLocation(arg.GetInst()), "argument must already been defined");
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
ValueInfo(arg.GetInst()).uses_this_inst++;
}
}
@ -328,8 +328,7 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
switch (current_location->kind) {
case HostLoc::Kind::Gpr:
ASSERT_FALSE("Logic error");
break;
UNREACHABLE(); //logic error
case HostLoc::Kind::Fpr:
code.FMOV(oaknut::XReg{new_location_index}, oaknut::DReg{current_location->index});
// ASSERT size fits
@ -354,13 +353,12 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
code.FMOV(oaknut::DReg{new_location_index}, oaknut::XReg{current_location->index});
break;
case HostLoc::Kind::Fpr:
ASSERT_FALSE("Logic error");
break;
UNREACHABLE(); //logic error
case HostLoc::Kind::Spill:
code.LDR(oaknut::QReg{new_location_index}, SP, spill_offset + current_location->index * spill_slot_size);
break;
case HostLoc::Kind::Flags:
ASSERT_FALSE("Moving from flags into fprs is not currently supported");
ASSERT(false && "Moving from flags into fprs is not currently supported");
break;
}
@ -368,7 +366,7 @@ int RegAlloc::RealizeReadImpl(const IR::Value& value) {
fprs[new_location_index].realized = true;
return new_location_index;
} else if constexpr (required_kind == HostLoc::Kind::Flags) {
ASSERT_FALSE("A simple read from flags is likely a logic error.");
UNREACHABLE(); //A simple read from flags is likely a logic error
} else {
static_assert(Common::always_false_v<mcl::mp::lift_value<required_kind>>);
}
@ -414,7 +412,7 @@ int RegAlloc::RealizeReadWriteImpl(const IR::Value& read_value, const IR::Inst*
LoadCopyInto(read_value, oaknut::QReg{write_loc});
return write_loc;
} else if constexpr (kind == HostLoc::Kind::Flags) {
ASSERT_FALSE("Incorrect function for ReadWrite of flags");
ASSERT(false && "Incorrect function for ReadWrite of flags");
} else {
static_assert(Common::always_false_v<mcl::mp::lift_value<kind>>);
}
@ -486,7 +484,7 @@ void RegAlloc::ReadWriteFlags(Argument& read, IR::Inst* write) {
code.LDR(Wscratch0, SP, spill_offset + current_location->index * spill_slot_size);
code.MSR(oaknut::SystemReg::NZCV, Xscratch0);
} else {
ASSERT_FALSE("Invalid current location for flags");
UNREACHABLE(); //ASSERT(false && "Invalid current location for flags");
}
if (write) {
@ -508,7 +506,7 @@ void RegAlloc::SpillFlags() {
int RegAlloc::FindFreeSpill() const {
const auto iter = std::find_if(spills.begin(), spills.end(), [](const HostLocInfo& info) { return info.values.empty(); });
ASSERT_MSG(iter != spills.end(), "All spill locations are full");
ASSERT(iter != spills.end() && "All spill locations are full");
return static_cast<int>(iter - spills.begin());
}
@ -558,8 +556,7 @@ void RegAlloc::LoadCopyInto(const IR::Value& value, oaknut::QReg reg) {
code.LDR(reg, SP, spill_offset + current_location->index * spill_slot_size);
break;
case HostLoc::Kind::Flags:
ASSERT_FALSE("Moving from flags into fprs is not currently supported");
break;
UNREACHABLE(); //ASSERT(false && "Moving from flags into fprs is not currently supported");
}
}
@ -592,7 +589,7 @@ HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) {
case HostLoc::Kind::Spill:
return spills[static_cast<size_t>(host_loc.index)];
}
ASSERT_FALSE("RegAlloc::ValueInfo: Invalid HostLoc::Kind");
UNREACHABLE();
}
HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
@ -600,17 +597,14 @@ HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value); iter != gprs.end()) {
return *iter;
}
if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value); iter != fprs.end()) {
} else if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value); iter != fprs.end()) {
return *iter;
}
if (contains_value(flags)) {
} else if (contains_value(flags)) {
return flags;
}
if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != spills.end()) {
} else if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != spills.end()) {
return *iter;
}
ASSERT_FALSE("RegAlloc::ValueInfo: Value not found");
UNREACHABLE();
}
} // namespace Dynarmic::Backend::Arm64

View File

@ -182,7 +182,7 @@ public:
} else if constexpr (size == 32) {
return ReadW(arg);
} else {
ASSERT_FALSE("Invalid size to ReadReg {}", size);
UNREACHABLE();
}
}
@ -199,7 +199,7 @@ public:
} else if constexpr (size == 8) {
return ReadB(arg);
} else {
ASSERT_FALSE("Invalid size to ReadVec {}", size);
UNREACHABLE();
}
}
@ -221,7 +221,7 @@ public:
} else if constexpr (size == 32) {
return WriteW(inst);
} else {
ASSERT_FALSE("Invalid size to WriteReg {}", size);
UNREACHABLE();
}
}
@ -238,7 +238,7 @@ public:
} else if constexpr (size == 8) {
return WriteB(inst);
} else {
ASSERT_FALSE("Invalid size to WriteVec {}", size);
UNREACHABLE();
}
}
@ -258,7 +258,7 @@ public:
} else if constexpr (size == 32) {
return ReadWriteW(arg, inst);
} else {
ASSERT_FALSE("Invalid size to ReadWriteReg {}", size);
UNREACHABLE();
}
}
@ -275,7 +275,7 @@ public:
} else if constexpr (size == 8) {
return ReadWriteB(arg, inst);
} else {
ASSERT_FALSE("Invalid size to ReadWriteVec {}", size);
UNREACHABLE();
}
}
@ -371,9 +371,8 @@ void RAReg<T>::Realize() {
case RWType::ReadWrite:
reg = T{reg_alloc.RealizeReadWriteImpl<kind>(read_value, write_value)};
break;
default:
ASSERT_FALSE("Invalid RWType");
}
UNREACHABLE();
}
} // namespace Dynarmic::Backend::Arm64

View File

@ -88,16 +88,14 @@ private:
};
MachHandler::MachHandler() {
#define KCHECK(x) ASSERT_MSG((x) == KERN_SUCCESS, "dynarmic: macOS MachHandler: init failure at {}", #x)
#define KCHECK(x) ASSERT((x) == KERN_SUCCESS && "init failure at " #x)
KCHECK(mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server_port));
KCHECK(mach_port_insert_right(mach_task_self(), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND));
KCHECK(task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, server_port, EXCEPTION_STATE | MACH_EXCEPTION_CODES, THREAD_STATE));
// The below doesn't actually work, and I'm not sure why; since this doesn't work we'll have a spurious error message upon shutdown.
// The below doesn't actually work, and I'm not sure why; since this doesn't work we'll have a spurious
// error message upon shutdown.
mach_port_t prev;
KCHECK(mach_port_request_notification(mach_task_self(), server_port, MACH_NOTIFY_PORT_DESTROYED, 0, server_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev));
#undef KCHECK
thread = std::thread(&MachHandler::MessagePump, this);

View File

@ -12,6 +12,8 @@
#include <mutex>
#include <shared_mutex>
#include <optional>
#include <bit>
#include <fmt/format.h>
#include <ankerl/unordered_dense.h>
#include "dynarmic/backend/exception_handler.h"
#include "dynarmic/common/assert.h"
@ -27,7 +29,6 @@
#else
# error "Invalid architecture"
#endif
#include <bit>
namespace Dynarmic::Backend {
@ -139,7 +140,7 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
}
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
#elif defined(ARCHITECTURE_riscv64)
ASSERT_FALSE("Unimplemented");
UNREACHABLE();
#else
# error "Invalid architecture"
#endif

View File

@ -128,7 +128,7 @@ void A32AddressSpace::Link(EmittedBlockInfo& block_info) {
break;
}
default:
ASSERT_FALSE("Invalid relocation target");
UNREACHABLE();
}
}
}

View File

@ -121,7 +121,7 @@ struct Jit::Impl final {
private:
void RequestCacheInvalidation() {
// ASSERT_FALSE("Unimplemented");
// UNREACHABLE();
invalidate_entire_cache = false;
invalid_cache_ranges.clear();

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2024 MerryMage
* SPDX-License-Identifier: 0BSD
@ -16,8 +19,7 @@ class CodeBlock {
public:
explicit CodeBlock(std::size_t size) noexcept : memsize(size) {
mem = (u8*)mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
if (mem == nullptr)
ASSERT_FALSE("out of memory");
ASSERT(mem != nullptr);
}
~CodeBlock() noexcept {

View File

@ -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();
}
}

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2024 MerryMage
* SPDX-License-Identifier: 0BSD
@ -105,15 +108,14 @@ void EmitA32Cond(biscuit::Assembler& as, EmitContext&, IR::Cond cond, biscuit::L
as.BNEZ(Xscratch0, label);
break;
default:
ASSERT_MSG(false, "Unknown cond {}", static_cast<size_t>(cond));
break;
UNREACHABLE();
}
}
void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx, IR::Term::Terminal terminal, IR::LocationDescriptor initial_location, bool is_single_step);
void EmitA32Terminal(biscuit::Assembler&, EmitContext&, IR::Term::Interpret, IR::LocationDescriptor, bool) {
ASSERT_FALSE("Interpret should never be emitted.");
UNREACHABLE();
}
void EmitA32Terminal(biscuit::Assembler& as, EmitContext& ctx, IR::Term::ReturnToDispatch, IR::LocationDescriptor, bool) {

View File

@ -105,7 +105,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
const IR::Value arg = inst->GetArg(i);
ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
ASSERT_MSG(ValueLocation(arg.GetInst()), "argument must already been defined");
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
ValueInfo(arg.GetInst()).uses_this_inst++;
}
}
@ -193,8 +193,7 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
switch (current_location->kind) {
case HostLoc::Kind::Gpr:
ASSERT_FALSE("Logic error");
break;
UNREACHABLE(); //logic error
case HostLoc::Kind::Fpr:
as.FMV_X_D(biscuit::GPR(new_location_index), biscuit::FPR{current_location->index});
// ASSERT size fits
@ -216,8 +215,7 @@ u32 RegAlloc::RealizeReadImpl(const IR::Value& value) {
as.FMV_D_X(biscuit::FPR{new_location_index}, biscuit::GPR(current_location->index));
break;
case HostLoc::Kind::Fpr:
ASSERT_FALSE("Logic error");
break;
UNREACHABLE(); //logic error
case HostLoc::Kind::Spill:
as.FLD(biscuit::FPR{new_location_index}, spill_offset + current_location->index * spill_slot_size, biscuit::sp);
break;
@ -299,7 +297,7 @@ void RegAlloc::SpillFpr(u32 index) {
u32 RegAlloc::FindFreeSpill() const {
const auto iter = std::find_if(spills.begin(), spills.end(), [](const HostLocInfo& info) { return info.values.empty(); });
ASSERT_MSG(iter != spills.end(), "All spill locations are full");
ASSERT(iter != spills.end() && "All spill locations are full");
return static_cast<u32>(iter - spills.begin());
}
@ -307,14 +305,11 @@ std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
const auto contains_value = [value](const HostLocInfo& info) {
return info.Contains(value);
};
if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value); iter != gprs.end()) {
return HostLoc{HostLoc::Kind::Gpr, static_cast<u32>(iter - gprs.begin())};
}
if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value); iter != fprs.end()) {
} else if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value); iter != fprs.end()) {
return HostLoc{HostLoc::Kind::Fpr, static_cast<u32>(iter - fprs.begin())};
}
if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != spills.end()) {
} else if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != spills.end()) {
return HostLoc{HostLoc::Kind::Spill, static_cast<u32>(iter - spills.begin())};
}
return std::nullopt;
@ -323,30 +318,27 @@ std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) {
switch (host_loc.kind) {
case HostLoc::Kind::Gpr:
return gprs[static_cast<size_t>(host_loc.index)];
return gprs[size_t(host_loc.index)];
case HostLoc::Kind::Fpr:
return fprs[static_cast<size_t>(host_loc.index)];
return fprs[size_t(host_loc.index)];
case HostLoc::Kind::Spill:
return spills[static_cast<size_t>(host_loc.index)];
return spills[size_t(host_loc.index)];
}
ASSERT_FALSE("RegAlloc::ValueInfo: Invalid HostLoc::Kind");
UNREACHABLE();
}
HostLocInfo& RegAlloc::ValueInfo(const IR::Inst* value) {
const auto contains_value = [value](const HostLocInfo& info) {
return info.Contains(value);
};
if (const auto iter = std::find_if(gprs.begin(), gprs.end(), contains_value); iter != gprs.end()) {
return *iter;
}
if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value); iter != gprs.end()) {
} else if (const auto iter = std::find_if(fprs.begin(), fprs.end(), contains_value); iter != gprs.end()) {
return *iter;
} else if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != gprs.end()) {
return *iter;
}
if (const auto iter = std::find_if(spills.begin(), spills.end(), contains_value); iter != gprs.end()) {
return *iter;
}
ASSERT_FALSE("RegAlloc::ValueInfo: Value not found");
UNREACHABLE();
}
} // namespace Dynarmic::Backend::RV64

View File

@ -48,18 +48,16 @@ static Xbyak::Address MJitStateReg(A32::Reg reg) {
static Xbyak::Address MJitStateExtReg(A32::ExtReg reg) {
if (A32::IsSingleExtReg(reg)) {
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::S0);
const size_t index = size_t(reg) - size_t(A32::ExtReg::S0);
return dword[BlockOfCode::ABI_JIT_PTR + offsetof(A32JitState, ExtReg) + sizeof(u32) * index];
}
if (A32::IsDoubleExtReg(reg)) {
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
} else if (A32::IsDoubleExtReg(reg)) {
const size_t index = size_t(reg) - size_t(A32::ExtReg::D0);
return qword[BlockOfCode::ABI_JIT_PTR + offsetof(A32JitState, ExtReg) + sizeof(u64) * index];
}
if (A32::IsQuadExtReg(reg)) {
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::Q0);
} else if (A32::IsQuadExtReg(reg)) {
const size_t index = size_t(reg) - size_t(A32::ExtReg::Q0);
return xword[BlockOfCode::ABI_JIT_PTR + offsetof(A32JitState, ExtReg) + 2 * sizeof(u64) * index];
}
ASSERT_FALSE("Should never happen.");
UNREACHABLE();
}
A32EmitContext::A32EmitContext(const A32::UserConfig& conf, RegAlloc& reg_alloc, IR::Block& block)
@ -144,7 +142,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);
@ -846,7 +845,7 @@ void A32EmitX64::EmitA32SetFpscrNZCV(A32EmitContext& ctx, IR::Inst* inst) {
}
static void EmitCoprocessorException() {
ASSERT_FALSE("Should raise coproc exception here");
UNREACHABLE();
}
static void CallCoprocCallback(BlockOfCode& code, RegAlloc& reg_alloc, A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr, std::optional<Argument::copyable_reference> arg0 = {}, std::optional<Argument::copyable_reference> arg1 = {}) {
@ -1126,9 +1125,9 @@ std::string A32EmitX64::LocationDescriptorToFriendlyName(const IR::LocationDescr
}
void A32EmitX64::EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDescriptor initial_location, bool) {
ASSERT_MSG(A32::LocationDescriptor{terminal.next}.TFlag() == A32::LocationDescriptor{initial_location}.TFlag(), "Unimplemented");
ASSERT_MSG(A32::LocationDescriptor{terminal.next}.EFlag() == A32::LocationDescriptor{initial_location}.EFlag(), "Unimplemented");
ASSERT_MSG(terminal.num_instructions == 1, "Unimplemented");
ASSERT(A32::LocationDescriptor{terminal.next}.TFlag() == A32::LocationDescriptor{initial_location}.TFlag() && "Unimplemented");
ASSERT(A32::LocationDescriptor{terminal.next}.EFlag() == A32::LocationDescriptor{initial_location}.EFlag() && "Unimplemented");
ASSERT(terminal.num_instructions == 1 && "Unimplemented");
code.mov(code.ABI_PARAM2.cvt32(), A32::LocationDescriptor{terminal.next}.PC());
code.mov(code.ABI_PARAM3.cvt32(), 1);

View File

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

View File

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

View File

@ -59,7 +59,7 @@ std::optional<EmitX64::BlockDescriptor> EmitX64::GetBasicBlock(IR::LocationDescr
}
void EmitX64::EmitInvalid(EmitContext&, IR::Inst* inst) {
ASSERT_MSG(false, "Invalid opcode: {:x}", std::size_t(inst->GetOpcode()));
UNREACHABLE();
}
void EmitX64::EmitVoid(EmitContext&, IR::Inst*) {
@ -352,7 +352,7 @@ void EmitX64::EmitTerminal(IR::Terminal terminal, IR::LocationDescriptor initial
if constexpr (!std::is_same_v<T, IR::Term::Invalid>) {
this->EmitTerminalImpl(x, initial_location, is_single_step);
} else {
ASSERT_MSG(false, "Invalid terminal");
ASSERT(false && "Invalid terminal");
}
}, terminal);
}

View File

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

View File

@ -39,12 +39,11 @@ FakeCall AxxEmitX64::FastmemCallback(u64 rip_) {
InvalidateBasicBlocks({std::get<0>(marker)});
}
return result;
} else {
}
fmt::print("dynarmic: Segfault happened within JITted code at rip = {:016x}\n"
"Segfault wasn't at a fastmem patch location!\n", rip_);
UNREACHABLE(); //("iter != fastmem_patch_info.end()");
}
}
template<std::size_t bitsize, auto callback>
void AxxEmitX64::EmitMemoryRead(AxxEmitContext& ctx, IR::Inst* inst) {

View File

@ -243,7 +243,7 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
}
break;
default:
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
return fastmem_location;
} else {
@ -265,7 +265,7 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
code.movups(Xbyak::Xmm(value_idx), xword[addr]);
break;
default:
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
return fastmem_location;
}
@ -311,7 +311,7 @@ const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int
break;
}
default:
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
return fastmem_location;
} else {
@ -333,7 +333,7 @@ const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int
code.movups(xword[addr], Xbyak::Xmm(value_idx));
break;
default:
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
return fastmem_location;
}

View File

@ -2425,27 +2425,27 @@ void EmitX64::EmitVectorMultiply64(EmitContext& ctx, IR::Inst* inst) {
}
void EmitX64::EmitVectorMultiplySignedWiden8(EmitContext&, IR::Inst*) {
ASSERT_FALSE("Unexpected VectorMultiplySignedWiden8");
UNREACHABLE();
}
void EmitX64::EmitVectorMultiplySignedWiden16(EmitContext&, IR::Inst*) {
ASSERT_FALSE("Unexpected VectorMultiplySignedWiden16");
UNREACHABLE();
}
void EmitX64::EmitVectorMultiplySignedWiden32(EmitContext&, IR::Inst*) {
ASSERT_FALSE("Unexpected VectorMultiplySignedWiden32");
UNREACHABLE();
}
void EmitX64::EmitVectorMultiplyUnsignedWiden8(EmitContext&, IR::Inst*) {
ASSERT_FALSE("Unexpected VectorMultiplyUnsignedWiden8");
UNREACHABLE();
}
void EmitX64::EmitVectorMultiplyUnsignedWiden16(EmitContext&, IR::Inst*) {
ASSERT_FALSE("Unexpected VectorMultiplyUnsignedWiden16");
UNREACHABLE();
}
void EmitX64::EmitVectorMultiplyUnsignedWiden32(EmitContext&, IR::Inst*) {
ASSERT_FALSE("Unexpected VectorMultiplyUnsignedWiden32");
UNREACHABLE();
}
void EmitX64::EmitVectorNarrow16(EmitContext& ctx, IR::Inst* inst) {
@ -5039,7 +5039,7 @@ void EmitX64::EmitVectorSub64(EmitContext& ctx, IR::Inst* inst) {
void EmitX64::EmitVectorTable(EmitContext&, IR::Inst* inst) {
// Do nothing. We *want* to hold on to the refcount for our arguments, so VectorTableLookup can use our arguments.
ASSERT_MSG(inst->UseCount() == 1, "Table cannot be used multiple times");
ASSERT(inst->UseCount() == 1 && "Table cannot be used multiple times");
}
void EmitX64::EmitVectorTableLookup64(EmitContext& ctx, IR::Inst* inst) {

View File

@ -55,9 +55,6 @@ struct OpArg {
case 64:
inner_reg = inner_reg.cvt64();
return;
default:
ASSERT_MSG(false, "Invalid bits");
return;
}
}
UNREACHABLE();

View File

@ -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();
}
}
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 {
@ -223,7 +208,7 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(const IR::Inst* inst) noexcept
const auto arg = inst->GetArg(i);
ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
ASSERT_MSG(ValueLocation(arg.GetInst()), "argument must already been defined");
ASSERT(ValueLocation(arg.GetInst()) && "argument must already been defined");
LocInfo(*ValueLocation(arg.GetInst())).AddArgReference();
}
}
@ -467,19 +452,19 @@ HostLoc RegAlloc::SelectARegister(const boost::container::static_vector<HostLoc,
auto const it_final = it_empty_candidate != desired_locations.cend()
? it_empty_candidate : it_candidate != desired_locations.cend()
? it_candidate : it_rex_candidate;
ASSERT_MSG(it_final != desired_locations.cend(), "All candidate registers have already been allocated");
ASSERT(it_final != desired_locations.cend() && "All candidate registers have already been allocated");
// Evil magic - increment LRU counter (will wrap at 256)
const_cast<RegAlloc*>(this)->LocInfo(*it_final).lru_counter++;
return *it_final;
}
void RegAlloc::DefineValueImpl(IR::Inst* def_inst, HostLoc host_loc) noexcept {
ASSERT_MSG(!ValueLocation(def_inst), "def_inst has already been defined");
ASSERT(!ValueLocation(def_inst) && "def_inst has already been defined");
LocInfo(host_loc).AddValue(def_inst);
}
void RegAlloc::DefineValueImpl(IR::Inst* def_inst, const IR::Value& use_inst) noexcept {
ASSERT_MSG(!ValueLocation(def_inst), "def_inst has already been defined");
ASSERT(!ValueLocation(def_inst) && "def_inst has already been defined");
if (use_inst.IsImmediate()) {
const HostLoc location = ScratchImpl(gpr_order);
@ -488,13 +473,13 @@ void RegAlloc::DefineValueImpl(IR::Inst* def_inst, const IR::Value& use_inst) no
return;
}
ASSERT_MSG(ValueLocation(use_inst.GetInst()), "use_inst must already be defined");
ASSERT(ValueLocation(use_inst.GetInst()) && "use_inst must already be defined");
const HostLoc location = *ValueLocation(use_inst.GetInst());
DefineValueImpl(def_inst, location);
}
HostLoc RegAlloc::LoadImmediate(IR::Value imm, HostLoc host_loc) noexcept {
ASSERT_MSG(imm.IsImmediate(), "imm is not an immediate");
ASSERT(imm.IsImmediate() && "imm is not an immediate");
if (HostLocIsGPR(host_loc)) {
const Xbyak::Reg64 reg = HostLocToReg64(host_loc);
const u64 imm_value = imm.GetImmediateAsU64();
@ -521,7 +506,7 @@ void RegAlloc::Move(HostLoc to, HostLoc from) noexcept {
const size_t bit_width = LocInfo(from).GetMaxBitWidth();
ASSERT(LocInfo(to).IsEmpty() && !LocInfo(from).IsLocked());
ASSERT(bit_width <= HostLocBitWidth(to));
ASSERT_MSG(!LocInfo(from).IsEmpty(), "Mov eliminated");
ASSERT(!LocInfo(from).IsEmpty() && "Mov eliminated");
EmitMove(bit_width, to, from);
LocInfo(to) = std::exchange(LocInfo(from), {});
}
@ -554,9 +539,9 @@ void RegAlloc::MoveOutOfTheWay(HostLoc reg) noexcept {
}
void RegAlloc::SpillRegister(HostLoc loc) noexcept {
ASSERT_MSG(HostLocIsRegister(loc), "Only registers can be spilled");
ASSERT_MSG(!LocInfo(loc).IsEmpty(), "There is no need to spill unoccupied registers");
ASSERT_MSG(!LocInfo(loc).IsLocked(), "Registers that have been allocated must not be spilt");
ASSERT(HostLocIsRegister(loc) && "Only registers can be spilled");
ASSERT(!LocInfo(loc).IsEmpty() && "There is no need to spill unoccupied registers");
ASSERT(!LocInfo(loc).IsLocked() && "Registers that have been allocated must not be spilt");
auto const new_loc = FindFreeSpill(HostLocIsXMM(loc));
Move(new_loc, loc);
}
@ -582,14 +567,14 @@ HostLoc RegAlloc::FindFreeSpill(bool is_xmm) const noexcept {
for (size_t i = size_t(HostLoc::FirstSpill); i < hostloc_info.size(); ++i)
if (const auto loc = HostLoc(i); LocInfo(loc).IsEmpty())
return loc;
ASSERT_FALSE("All spill locations are full");
UNREACHABLE();
};
void RegAlloc::EmitMove(const size_t bit_width, const HostLoc to, const HostLoc from) noexcept {
auto const spill_to_op_arg_helper = [&](HostLoc loc, size_t reserved_stack_space) {
ASSERT(HostLocIsSpill(loc));
size_t i = size_t(loc) - size_t(HostLoc::FirstSpill);
ASSERT_MSG(i < SpillCount, "Spill index greater than number of available spill locations");
ASSERT(i < SpillCount && "Spill index greater than number of available spill locations");
return Xbyak::util::rsp + reserved_stack_space + ABI_SHADOW_SPACE + offsetof(StackLayout, spill) + i * sizeof(StackLayout::spill[0]);
};
auto const spill_xmm_to_op = [&](const HostLoc loc) {
@ -669,18 +654,13 @@ void RegAlloc::EmitMove(const size_t bit_width, const HostLoc to, const HostLoc
code->mov(Xbyak::util::dword[spill_to_op_arg_helper(to, reserved_stack_space)], HostLocToReg64(from).cvt32());
}
} else {
ASSERT_FALSE("Invalid RegAlloc::EmitMove");
UNREACHABLE();
}
}
void RegAlloc::EmitExchange(const HostLoc a, const HostLoc b) noexcept {
if (HostLocIsGPR(a) && HostLocIsGPR(b)) {
ASSERT(HostLocIsGPR(a) && HostLocIsGPR(b) && "Exchanging XMM registers is uneeded OR invalid emit");
code->xchg(HostLocToReg64(a), HostLocToReg64(b));
} else if (HostLocIsXMM(a) && HostLocIsXMM(b)) {
ASSERT_FALSE("Check your code: Exchanging XMM registers is unnecessary");
} else {
ASSERT_FALSE("Invalid RegAlloc::EmitExchange");
}
}
} // namespace Dynarmic::Backend::X64

View File

@ -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();
}

View File

@ -6,48 +6,22 @@
#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
// TODO: Use source_info?
[[noreturn]] void assert_terminate_impl(const char* s);
#ifndef ASSERT
#define ASSERT(_a_) ASSERT_MSG(_a_, "")
# define ASSERT(expr) do if(!(expr)) [[unlikely]] assert_terminate_impl(__FILE__ ": " #expr); while(0)
#endif
#ifndef UNREACHABLE
#define UNREACHABLE() ASSERT_MSG(false, "unreachable")
# ifdef _MSC_VER
# define UNREACHABLE() ASSERT(false && __FILE__ ": unreachable")
# else
# define UNREACHABLE() __builtin_unreachable();
# endif
#endif
#ifdef _DEBUG
#ifndef DEBUG_ASSERT
# ifndef NDEBUG
# 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
# else
# define DEBUG_ASSERT(_a_)
# endif
#ifndef DEBUG_ASSERT_MSG
#define DEBUG_ASSERT_MSG(_a_, _desc_, ...)
#endif
#endif

View File

@ -73,7 +73,7 @@ public:
/// Set rounding mode control field.
void RMode(FP::RoundingMode rounding_mode) {
ASSERT_MSG(static_cast<u32>(rounding_mode) <= 0b11, "FPCR: Invalid rounding mode");
ASSERT(static_cast<u32>(rounding_mode) <= 0b11 && "FPCR: Invalid rounding mode");
value = mcl::bit::set_bits<22, 23>(value, static_cast<u32>(rounding_mode));
}
@ -93,7 +93,7 @@ public:
/// Set the stride of a vector when executing AArch32 VFP instructions.
/// This field has no function in AArch64 state.
void Stride(size_t stride) {
ASSERT_MSG(stride >= 1 && stride <= 2, "FPCR: Invalid stride");
ASSERT(stride >= 1 && stride <= 2 && "FPCR: Invalid stride");
value = mcl::bit::set_bits<20, 21>(value, stride == 1 ? 0b00u : 0b11u);
}
@ -116,7 +116,7 @@ public:
/// Sets the length of a vector when executing AArch32 VFP instructions.
/// This field has no function in AArch64 state.
void Len(size_t len) {
ASSERT_MSG(len >= 1 && len <= 8, "FPCR: Invalid len");
ASSERT(len >= 1 && len <= 8 && "FPCR: Invalid len");
value = mcl::bit::set_bits<16, 18>(value, static_cast<u32>(len - 1));
}

View File

@ -18,44 +18,31 @@ namespace Dynarmic::FP {
void FPProcessException(FPExc exception, FPCR fpcr, FPSR& fpsr) {
switch (exception) {
case FPExc::InvalidOp:
if (fpcr.IOE()) {
ASSERT_FALSE("Raising floating point exceptions unimplemented");
}
ASSERT(!fpcr.IOE() && "Raising floating point exceptions unimplemented");
fpsr.IOC(true);
break;
case FPExc::DivideByZero:
if (fpcr.DZE()) {
ASSERT_FALSE("Raising floating point exceptions unimplemented");
}
ASSERT(!fpcr.DZE() && "Raising floating point exceptions unimplemented");
fpsr.DZC(true);
break;
case FPExc::Overflow:
if (fpcr.OFE()) {
ASSERT_FALSE("Raising floating point exceptions unimplemented");
}
ASSERT(!fpcr.OFE() && "Raising floating point exceptions unimplemented");
fpsr.OFC(true);
break;
case FPExc::Underflow:
if (fpcr.UFE()) {
ASSERT_FALSE("Raising floating point exceptions unimplemented");
}
ASSERT(!fpcr.UFE() && "Raising floating point exceptions unimplemented");
fpsr.UFC(true);
break;
case FPExc::Inexact:
if (fpcr.IXE()) {
ASSERT_FALSE("Raising floating point exceptions unimplemented");
}
ASSERT(!fpcr.IXE() && "Raising floating point exceptions unimplemented");
fpsr.IXC(true);
break;
case FPExc::InputDenorm:
if (fpcr.IDE()) {
ASSERT_FALSE("Raising floating point exceptions unimplemented");
}
ASSERT(!fpcr.IDE() && "Raising floating point exceptions unimplemented");
fpsr.IDC(true);
break;
default:
UNREACHABLE();
break;
}
}

View File

@ -56,15 +56,11 @@ IR::U32 IREmitter::GetRegister(Reg reg) {
}
IR::U32U64 IREmitter::GetExtendedRegister(ExtReg reg) {
if (A32::IsSingleExtReg(reg)) {
if (A32::IsSingleExtReg(reg))
return Inst<IR::U32U64>(Opcode::A32GetExtendedRegister32, IR::Value(reg));
}
if (A32::IsDoubleExtReg(reg)) {
else if (A32::IsDoubleExtReg(reg))
return Inst<IR::U32U64>(Opcode::A32GetExtendedRegister64, IR::Value(reg));
}
ASSERT_FALSE("Invalid reg.");
UNREACHABLE();
}
IR::U128 IREmitter::GetVector(ExtReg reg) {
@ -83,7 +79,7 @@ void IREmitter::SetExtendedRegister(const ExtReg reg, const IR::U32U64& value) {
} else if (A32::IsDoubleExtReg(reg)) {
Inst(Opcode::A32SetExtendedRegister64, IR::Value(reg), value);
} else {
ASSERT_FALSE("Invalid reg.");
UNREACHABLE();
}
}
@ -240,7 +236,7 @@ IR::UAny IREmitter::ReadMemory(size_t bitsize, const IR::U32& vaddr, IR::AccType
case 64:
return ReadMemory64(vaddr, acc_type);
}
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
IR::U8 IREmitter::ReadMemory8(const IR::U32& vaddr, IR::AccType acc_type) {
@ -298,7 +294,7 @@ void IREmitter::WriteMemory(size_t bitsize, const IR::U32& vaddr, const IR::UAny
case 64:
return WriteMemory64(vaddr, value, acc_type);
}
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
void IREmitter::WriteMemory8(const IR::U32& vaddr, const IR::U8& value, IR::AccType acc_type) {

View File

@ -21,7 +21,7 @@
namespace Dynarmic::A32 {
bool CondCanContinue(const ConditionalState cond_state, const A32::IREmitter& ir) {
ASSERT_MSG(cond_state != ConditionalState::Break, "Should never happen.");
ASSERT(cond_state != ConditionalState::Break && "Should never happen.");
if (cond_state == ConditionalState::None)
return true;

View File

@ -71,7 +71,7 @@ IR::UAny TranslatorVisitor::I(size_t bitsize, u64 value) {
case 64:
return ir.Imm64(value);
default:
ASSERT_FALSE("Imm - get: Invalid bitsize");
UNREACHABLE();
}
}

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2020 MerryMage
* SPDX-License-Identifier: 0BSD
@ -69,7 +72,7 @@ std::optional<std::tuple<size_t, size_t, size_t>> DecodeType(Imm<4> type, size_t
}
return std::tuple<size_t, size_t, size_t>{4, 1, 2};
}
ASSERT_FALSE("Decode error");
UNREACHABLE();
}
} // namespace

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
@ -93,7 +96,7 @@ bool TranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n, Re
return UnpredictableInstruction();
}
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@ -124,7 +127,7 @@ bool TranslatorVisitor::arm_LDR_imm(Cond cond, bool P, bool U, bool W, Reg n, Re
// LDR <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDR <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDR_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (m == Reg::PC) {
return UnpredictableInstruction();
}
@ -182,7 +185,7 @@ bool TranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n, R
return UnpredictableInstruction();
}
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@ -207,7 +210,7 @@ bool TranslatorVisitor::arm_LDRB_imm(Cond cond, bool P, bool U, bool W, Reg n, R
// LDRB <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRB <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDRB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Imm<5> imm5, ShiftType shift, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
@ -350,7 +353,7 @@ bool TranslatorVisitor::arm_LDRD_reg(Cond cond, bool P, bool U, bool W, Reg n, R
// LDRH <Rt>, [PC, #-/+<imm>]
bool TranslatorVisitor::arm_LDRH_lit(Cond cond, bool P, bool U, bool W, Reg t, Imm<4> imm8a, Imm<4> imm8b) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (P == W) {
return UnpredictableInstruction();
}
@ -380,7 +383,7 @@ bool TranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, R
return UnpredictableInstruction();
}
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@ -405,7 +408,7 @@ bool TranslatorVisitor::arm_LDRH_imm(Cond cond, bool P, bool U, bool W, Reg n, R
// LDRH <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRH <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDRH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
@ -454,7 +457,7 @@ bool TranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction();
}
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@ -479,7 +482,7 @@ bool TranslatorVisitor::arm_LDRSB_imm(Cond cond, bool P, bool U, bool W, Reg n,
// LDRSB <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRSB <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDRSB_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
@ -527,7 +530,7 @@ bool TranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n,
return UnpredictableInstruction();
}
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if ((!P || W) && n == t) {
return UnpredictableInstruction();
}
@ -552,7 +555,7 @@ bool TranslatorVisitor::arm_LDRSH_imm(Cond cond, bool P, bool U, bool W, Reg n,
// LDRSH <Rt>, [<Rn>, #+/-<Rm>]{!}
// LDRSH <Rt>, [<Rn>], #+/-<Rm>
bool TranslatorVisitor::arm_LDRSH_reg(Cond cond, bool P, bool U, bool W, Reg n, Reg t, Reg m) {
ASSERT_MSG(!(!P && W), "T form of instruction unimplemented");
ASSERT(!(!P && W) && "T form of instruction unimplemented");
if (t == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
@ -31,7 +34,7 @@ bool TranslatorVisitor::arm_MRS(Cond cond, Reg d) {
// MSR<c> <spec_reg>, #<const>
bool TranslatorVisitor::arm_MSR_imm(Cond cond, unsigned mask, int rotate, Imm<8> imm8) {
ASSERT_MSG(mask != 0, "Decode error");
ASSERT(mask != 0 && "Decode error");
if (!ArmConditionPassed(cond)) {
return true;

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
@ -684,7 +687,7 @@ bool TranslatorVisitor::thumb16_NOP() {
// IT{<x>{<y>{<z>}}} <cond>
bool TranslatorVisitor::thumb16_IT(Imm<8> imm8) {
ASSERT_MSG((imm8.Bits<0, 3>() != 0b0000), "Decode Error");
ASSERT((imm8.Bits<0, 3>() != 0b0000) && "Decode Error");
if (imm8.Bits<4, 7>() == 0b1111 || (imm8.Bits<4, 7>() == 0b1110 && mcl::bit::count_ones(imm8.Bits<0, 3>()) != 1)) {
return UnpredictableInstruction();
}

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2021 MerryMage
* SPDX-License-Identifier: 0BSD
@ -20,7 +23,7 @@ bool TranslatorVisitor::thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
}
bool TranslatorVisitor::thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction();
}
@ -66,7 +69,7 @@ bool TranslatorVisitor::thumb32_MOV_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Im
}
bool TranslatorVisitor::thumb32_ORR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(n != Reg::PC, "Decode error");
ASSERT(n != Reg::PC && "Decode error");
if (d == Reg::PC) {
return UnpredictableInstruction();
}
@ -97,7 +100,7 @@ bool TranslatorVisitor::thumb32_MVN_imm(Imm<1> i, bool S, Imm<3> imm3, Reg d, Im
}
bool TranslatorVisitor::thumb32_ORN_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(n != Reg::PC, "Decode error");
ASSERT(n != Reg::PC && "Decode error");
if (d == Reg::PC) {
return UnpredictableInstruction();
}
@ -125,7 +128,7 @@ bool TranslatorVisitor::thumb32_TEQ_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
}
bool TranslatorVisitor::thumb32_EOR_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction();
}
@ -153,7 +156,7 @@ bool TranslatorVisitor::thumb32_CMN_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
}
bool TranslatorVisitor::thumb32_ADD_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction();
}
@ -211,7 +214,7 @@ bool TranslatorVisitor::thumb32_CMP_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm
}
bool TranslatorVisitor::thumb32_SUB_imm_1(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC) {
return UnpredictableInstruction();
}

View File

@ -17,7 +17,7 @@ namespace Dynarmic::A32 {
using SaturationFunction = IR::ResultAndOverflow<IR::U32> (IREmitter::*)(const IR::U32&, size_t);
static bool Saturation(TranslatorVisitor& v, bool sh, Reg n, Reg d, Imm<5> shift_amount, size_t saturate_to, SaturationFunction sat_fn) {
ASSERT_MSG(!(sh && shift_amount == 0), "Invalid decode");
ASSERT(!(sh && shift_amount == 0) && "Invalid decode");
if (d == Reg::PC || n == Reg::PC) {
return v.UnpredictableInstruction();

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
@ -20,7 +23,7 @@ bool TranslatorVisitor::thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
}
bool TranslatorVisitor::thumb32_AND_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -64,7 +67,7 @@ bool TranslatorVisitor::thumb32_MOV_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2,
}
bool TranslatorVisitor::thumb32_ORR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(n != Reg::PC, "Decode error");
ASSERT(n != Reg::PC && "Decode error");
if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -94,7 +97,7 @@ bool TranslatorVisitor::thumb32_MVN_reg(bool S, Imm<3> imm3, Reg d, Imm<2> imm2,
}
bool TranslatorVisitor::thumb32_ORN_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(n != Reg::PC, "Decode error");
ASSERT(n != Reg::PC && "Decode error");
if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -122,7 +125,7 @@ bool TranslatorVisitor::thumb32_TEQ_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
}
bool TranslatorVisitor::thumb32_EOR_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -165,7 +168,7 @@ bool TranslatorVisitor::thumb32_CMN_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
}
bool TranslatorVisitor::thumb32_ADD_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
@ -221,7 +224,7 @@ bool TranslatorVisitor::thumb32_CMP_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftTy
}
bool TranslatorVisitor::thumb32_SUB_reg(bool S, Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, ShiftType type, Reg m) {
ASSERT_MSG(!(d == Reg::PC && S), "Decode error");
ASSERT(!(d == Reg::PC && S) && "Decode error");
if ((d == Reg::PC && !S) || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
@ -1301,11 +1304,11 @@ bool TranslatorVisitor::vfp_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd, bo
// VSTM{mode}<c> <Rn>{!}, <list of double registers>
bool TranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) {
ASSERT_MSG(false, "Decode error");
ASSERT(false && "Decode error");
}
if (p && !w) {
ASSERT_MSG(false, "Decode error");
ASSERT(false && "Decode error");
}
if (p == u && w) {
@ -1353,11 +1356,11 @@ bool TranslatorVisitor::vfp_VSTM_a1(Cond cond, bool p, bool u, bool D, bool w, R
// VSTM{mode}<c> <Rn>{!}, <list of single registers>
bool TranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) {
ASSERT_MSG(false, "Decode error");
ASSERT(false && "Decode error");
}
if (p && !w) {
ASSERT_MSG(false, "Decode error");
ASSERT(false && "Decode error");
}
if (p == u && w) {
@ -1396,11 +1399,11 @@ bool TranslatorVisitor::vfp_VSTM_a2(Cond cond, bool p, bool u, bool D, bool w, R
// VLDM{mode}<c> <Rn>{!}, <list of double registers>
bool TranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) {
ASSERT_MSG(false, "Decode error");
ASSERT(false && "Decode error");
}
if (p && !w) {
ASSERT_MSG(false, "Decode error");
ASSERT(false && "Decode error");
}
if (p == u && w) {
@ -1446,11 +1449,11 @@ bool TranslatorVisitor::vfp_VLDM_a1(Cond cond, bool p, bool u, bool D, bool w, R
// VLDM{mode}<c> <Rn>{!}, <list of single registers>
bool TranslatorVisitor::vfp_VLDM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm<8> imm8) {
if (!p && !u && !w) {
ASSERT_MSG(false, "Decode error");
ASSERT(false && "Decode error");
}
if (p && !w) {
ASSERT_MSG(false, "Decode error");
ASSERT(false && "Decode error");
}
if (p == u && w) {

View File

@ -77,7 +77,7 @@ IR::Block TranslateArm(LocationDescriptor descriptor, TranslateCallbacks* tcb, c
}
}
ASSERT_MSG(block.HasTerminal(), "Terminal has not been set");
ASSERT(block.HasTerminal() && "Terminal has not been set");
block.SetEndLocation(visitor.ir.current_location);

View File

@ -176,7 +176,7 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, TranslateCallbacks* tcb,
}
}
ASSERT_MSG(block.HasTerminal(), "Terminal has not been set");
ASSERT(block.HasTerminal() && "Terminal has not been set");
block.SetEndLocation(visitor.ir.current_location);

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2018 MerryMage
* SPDX-License-Identifier: 0BSD
@ -41,7 +44,7 @@ IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory
visitor.ir.SetTerm(IR::Term::LinkBlock{*visitor.ir.current_location});
}
ASSERT_MSG(block.HasTerminal(), "Terminal has not been set");
ASSERT(block.HasTerminal() && "Terminal has not been set");
block.SetEndLocation(*visitor.ir.current_location);

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2018 MerryMage
* SPDX-License-Identifier: 0BSD
@ -75,9 +78,8 @@ IR::UAny TranslatorVisitor::I(size_t bitsize, u64 value) {
return ir.Imm32(static_cast<u32>(value));
case 64:
return ir.Imm64(value);
default:
ASSERT_FALSE("Imm - get: Invalid bitsize");
}
UNREACHABLE();
}
IR::UAny TranslatorVisitor::X(size_t bitsize, Reg reg) {
@ -90,9 +92,8 @@ IR::UAny TranslatorVisitor::X(size_t bitsize, Reg reg) {
return ir.GetW(reg);
case 64:
return ir.GetX(reg);
default:
ASSERT_FALSE("X - get: Invalid bitsize");
}
UNREACHABLE();
}
void TranslatorVisitor::X(size_t bitsize, Reg reg, IR::U32U64 value) {
@ -103,9 +104,8 @@ void TranslatorVisitor::X(size_t bitsize, Reg reg, IR::U32U64 value) {
case 64:
ir.SetX(reg, value);
return;
default:
ASSERT_FALSE("X - set: Invalid bitsize");
}
UNREACHABLE();
}
IR::U32U64 TranslatorVisitor::SP(size_t bitsize) {
@ -114,9 +114,8 @@ IR::U32U64 TranslatorVisitor::SP(size_t bitsize) {
return ir.LeastSignificantWord(ir.GetSP());
case 64:
return ir.GetSP();
default:
ASSERT_FALSE("SP - get : Invalid bitsize");
}
UNREACHABLE();
}
void TranslatorVisitor::SP(size_t bitsize, IR::U32U64 value) {
@ -128,7 +127,7 @@ void TranslatorVisitor::SP(size_t bitsize, IR::U32U64 value) {
ir.SetSP(value);
break;
default:
ASSERT_FALSE("SP - set : Invalid bitsize");
UNREACHABLE();
}
}
@ -140,9 +139,8 @@ IR::U128 TranslatorVisitor::V(size_t bitsize, Vec vec) {
return ir.GetD(vec);
case 128:
return ir.GetQ(vec);
default:
ASSERT_FALSE("V - get : Invalid bitsize");
}
UNREACHABLE();
}
void TranslatorVisitor::V(size_t bitsize, Vec vec, IR::U128 value) {
@ -157,9 +155,8 @@ void TranslatorVisitor::V(size_t bitsize, Vec vec, IR::U128 value) {
case 128:
ir.SetQ(vec, value);
return;
default:
ASSERT_FALSE("V - Set : Invalid bitsize");
}
UNREACHABLE();
}
IR::UAnyU128 TranslatorVisitor::V_scalar(size_t bitsize, Vec vec) {
@ -232,9 +229,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 +250,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 +266,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 +282,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 +292,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 +302,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) {

View File

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2018 MerryMage
* SPDX-License-Identifier: 0BSD
@ -70,15 +73,8 @@ bool MultiplyByElementHalfPrecision(TranslatorVisitor& v, Imm<1> L, Imm<1> M, Im
// TODO: Currently we don't implement half-precision paths
// for regular multiplication and extended multiplication.
if (extra_behavior == ExtraBehavior::None) {
ASSERT_FALSE("half-precision option unimplemented");
}
if (extra_behavior == ExtraBehavior::MultiplyExtended) {
ASSERT_FALSE("half-precision option unimplemented");
}
ASSERT(extra_behavior != ExtraBehavior::None
&& extra_behavior != ExtraBehavior::MultiplyExtended);
if (extra_behavior == ExtraBehavior::Subtract) {
operand1 = v.ir.FPNeg(operand1);
}

View File

@ -30,7 +30,7 @@ public:
explicit Imm(u32 value)
: value(value) {
ASSERT_MSG((mcl::bit::get_bits<0, bit_size - 1>(value) == value), "More bits in value than expected");
ASSERT((mcl::bit::get_bits<0, bit_size - 1>(value) == value) && "More bits in value than expected");
}
template<typename T = u32>

View File

@ -144,12 +144,12 @@ public:
}
/// Sets the terminal instruction for this basic block.
inline void SetTerminal(Terminal term) noexcept {
ASSERT_MSG(!HasTerminal(), "Terminal has already been set.");
ASSERT(!HasTerminal() && "Terminal has already been set.");
terminal = std::move(term);
}
/// Replaces the terminal instruction for this basic block.
inline void ReplaceTerminal(Terminal term) noexcept {
ASSERT_MSG(HasTerminal(), "Terminal has not been set.");
ASSERT(HasTerminal() && "Terminal has not been set.");
terminal = std::move(term);
}
/// Determines whether or not this basic block has a terminal instruction.

View File

@ -124,7 +124,7 @@ public:
ASSERT(value.GetType() == Type::U64);
return value;
}
ASSERT_FALSE("Invalid bitsize");
UNREACHABLE();
}
U32 LeastSignificantWord(const U64& value) {
@ -992,7 +992,7 @@ public:
}
UAny VectorGetElement(size_t esize, const U128& a, size_t index) {
ASSERT_MSG(esize * index < 128, "Invalid index");
ASSERT(esize * index < 128 && "Invalid index");
switch (esize) {
case 8:
return Inst<U8>(Opcode::VectorGetElement8, a, Imm8(static_cast<u8>(index)));
@ -1008,7 +1008,7 @@ public:
}
U128 VectorSetElement(size_t esize, const U128& a, size_t index, const IR::UAny& elem) {
ASSERT_MSG(esize * index < 128, "Invalid index");
ASSERT(esize * index < 128 && "Invalid index");
switch (esize) {
case 8:
return Inst<U128>(Opcode::VectorSetElement8, a, Imm8(static_cast<u8>(index)), elem);
@ -1114,7 +1114,7 @@ public:
}
U128 VectorBroadcastElementLower(size_t esize, const U128& a, size_t index) {
ASSERT_MSG(esize * index < 128, "Invalid index");
ASSERT(esize * index < 128 && "Invalid index");
switch (esize) {
case 8:
return Inst<U128>(Opcode::VectorBroadcastElementLower8, a, u8(index));
@ -1127,7 +1127,7 @@ public:
}
U128 VectorBroadcastElement(size_t esize, const U128& a, size_t index) {
ASSERT_MSG(esize * index < 128, "Invalid index");
ASSERT(esize * index < 128 && "Invalid index");
switch (esize) {
case 8:
return Inst<U128>(Opcode::VectorBroadcastElement8, a, u8(index));

View File

@ -42,8 +42,10 @@ Type Inst::GetType() const {
}
void Inst::SetArg(size_t index, Value value) noexcept {
DEBUG_ASSERT_MSG(index < GetNumArgsOf(op), "Inst::SetArg: index {} >= number of arguments of {} ({})", index, op, GetNumArgsOf(op));
DEBUG_ASSERT_MSG(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]);
}
@ -79,7 +81,7 @@ void Inst::Use(const Value& value) {
if (IsAPseudoOperation(op)) {
if (op == Opcode::GetNZCVFromOp) {
ASSERT_MSG(MayGetNZCVFromOp(value.GetInst()->GetOpcode()), "This value doesn't support the GetNZCVFromOp pseduo-op");
ASSERT(MayGetNZCVFromOp(value.GetInst()->GetOpcode()) && "This value doesn't support the GetNZCVFromOp pseduo-op");
}
Inst* insert_point = value.GetInst();

View File

@ -53,8 +53,10 @@ public:
}
inline Value GetArg(size_t index) const noexcept {
DEBUG_ASSERT_MSG(index < GetNumArgsOf(op), "Inst::GetArg: index {} >= number of arguments of {} ({})", index, op, GetNumArgsOf(op));
DEBUG_ASSERT_MSG(!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;

View File

@ -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_MSG(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;

View File

@ -70,7 +70,7 @@ bool AnyLocationDescriptorForTerminalHas(IR::Terminal terminal, Fn fn) {
} else if constexpr (std::is_same_v<T, IR::Term::CheckHalt>) {
return AnyLocationDescriptorForTerminalHas(t.else_, fn);
} else {
ASSERT_MSG(false, "Invalid terminal type");
ASSERT(false && "Invalid terminal type");
return false;
}
}, terminal);
@ -282,7 +282,7 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
} else if (bitstring.substr(0, 8) == "11110100") {
bitstring.replace(0, 8, "11111001");
} else {
ASSERT_FALSE("Unhandled ASIMD instruction: {} {}", fn, bs);
UNREACHABLE(); // "Unhandled ASIMD instruction: {} {}", fn, bs);
}
if (std::find(do_not_test.begin(), do_not_test.end(), fn) != do_not_test.end()) {
invalid.emplace_back(InstructionGenerator{bitstring.c_str()});

View File

@ -97,11 +97,17 @@ public:
MemoryWrite32(vaddr + 4, static_cast<u32>(value >> 32));
}
void InterpreterFallback(u32 pc, size_t num_instructions) override { ASSERT_MSG(false, "InterpreterFallback({:08x}, {}) code = {:08x}", pc, num_instructions, *MemoryReadCode(pc)); }
void InterpreterFallback(u32 pc, size_t num_instructions) override {
UNREACHABLE(); //ASSERT(false && "InterpreterFallback({:08x} && {}) code = {:08x}", pc, num_instructions, *MemoryReadCode(pc));
}
void CallSVC(std::uint32_t swi) override { ASSERT_MSG(false, "CallSVC({})", swi); }
void CallSVC(std::uint32_t swi) override {
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
}
void ExceptionRaised(u32 pc, Dynarmic::A32::Exception /*exception*/) override { ASSERT_MSG(false, "ExceptionRaised({:08x}) code = {:08x}", pc, *MemoryReadCode(pc)); }
void ExceptionRaised(u32 pc, Dynarmic::A32::Exception /*exception*/) override {
UNREACHABLE(); //ASSERT(false && "ExceptionRaised({:08x}) code = {:08x}", pc, *MemoryReadCode(pc));
}
void AddTicks(std::uint64_t ticks) override {
if (ticks > ticks_left) {
@ -184,11 +190,17 @@ public:
return true;
}
void InterpreterFallback(std::uint32_t pc, size_t num_instructions) override { ASSERT_MSG(false, "InterpreterFallback({:016x}, {})", pc, num_instructions); }
void InterpreterFallback(std::uint32_t pc, size_t num_instructions) override {
UNREACHABLE(); //ASSERT(false && "InterpreterFallback({:016x} && {})", pc, num_instructions);
}
void CallSVC(std::uint32_t swi) override { ASSERT_MSG(false, "CallSVC({})", swi); }
void CallSVC(std::uint32_t swi) override {
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
}
void ExceptionRaised(std::uint32_t pc, Dynarmic::A32::Exception) override { ASSERT_MSG(false, "ExceptionRaised({:016x})", pc); }
void ExceptionRaised(std::uint32_t pc, Dynarmic::A32::Exception) override {
UNREACHABLE(); //ASSERT(false && "ExceptionRaised({:016x})", pc);
}
void AddTicks(std::uint64_t ticks) override {
if (ticks > ticks_left) {

View File

@ -105,11 +105,17 @@ public:
return true;
}
void InterpreterFallback(u64 pc, size_t num_instructions) override { ASSERT_MSG(false, "InterpreterFallback({:016x}, {})", pc, num_instructions); }
void InterpreterFallback(u64 pc, size_t num_instructions) override {
UNREACHABLE(); // ASSERT(false&& "InterpreterFallback({:016x} && {})", pc, num_instructions);
}
void CallSVC(std::uint32_t swi) override { ASSERT_MSG(false, "CallSVC({})", swi); }
void CallSVC(std::uint32_t swi) override {
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
}
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception /*exception*/) override { ASSERT_MSG(false, "ExceptionRaised({:016x})", pc); }
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception /*exception*/) override {
UNREACHABLE(); //ASSERT(false && "ExceptionRaised({:016x})", pc);
}
void AddTicks(std::uint64_t ticks) override {
if (ticks > ticks_left) {
@ -202,11 +208,17 @@ public:
return true;
}
void InterpreterFallback(u64 pc, size_t num_instructions) override { ASSERT_MSG(ignore_invalid_insn, "InterpreterFallback({:016x}, {})", pc, num_instructions); }
void InterpreterFallback(u64 pc, size_t num_instructions) override {
ASSERT(ignore_invalid_insn && "InterpreterFallback");
}
void CallSVC(std::uint32_t swi) override { ASSERT_MSG(false, "CallSVC({})", swi); }
void CallSVC(std::uint32_t swi) override {
UNREACHABLE(); //ASSERT(false && "CallSVC({})", swi);
}
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception) override { ASSERT_MSG(false, "ExceptionRaised({:016x})", pc); }
void ExceptionRaised(u64 pc, Dynarmic::A64::Exception) override {
UNREACHABLE(); //ASSERT(false && "ExceptionRaised({:016x})", pc);
}
void AddTicks(std::uint64_t ticks) override {
if (ticks > ticks_left) {

View File

@ -306,7 +306,7 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
} else if (bitstring.substr(0, 8) == "11110100") {
bitstring.replace(0, 8, "11111001");
} else {
ASSERT_FALSE("Unhandled ASIMD instruction: {} {}", fn, bs);
UNREACHABLE(); // "Unhandled ASIMD instruction: {} {}", fn, bs);
}
if (std::find(do_not_test.begin(), do_not_test.end(), fn) != do_not_test.end()) {
invalid.emplace_back(InstructionGenerator{bitstring.c_str()});

View File

@ -18,7 +18,7 @@
#define CHECKED(expr) \
do { \
if (auto cerr_ = (expr)) { \
ASSERT_MSG(false, "Call " #expr " failed with error: {} ({})\n", static_cast<size_t>(cerr_), \
ASSERT(false && "Call " #expr " failed with error: {} ({})\n", static_cast<size_t>(cerr_), \
uc_strerror(cerr_)); \
} \
} while (0)

View File

@ -13,7 +13,7 @@
#define CHECKED(expr) \
do { \
if (auto cerr_ = (expr)) { \
ASSERT_MSG(false, "Call " #expr " failed with error: {} ({})\n", static_cast<size_t>(cerr_), \
ASSERT(false && "Call " #expr " failed with error: {} ({})\n", static_cast<size_t>(cerr_), \
uc_strerror(cerr_)); \
} \
} while (0)