Fix size_t errors

Signed-off-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
crueter 2026-04-01 01:46:27 -04:00 committed by lizzie
parent aabee19226
commit d9d0a10c03
25 changed files with 156 additions and 150 deletions

View file

@ -227,7 +227,7 @@ void A32AddressSpace::EmitPrelude() {
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) { if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
code.LDR(Xscratch0, l_return_to_dispatcher); code.LDR(Xscratch0, l_return_to_dispatcher);
for (size_t i = 0; i < RSBCount; i++) { for (std::size_t i = 0; i < RSBCount; i++) {
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry)); code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
} }
} }
@ -266,7 +266,7 @@ void A32AddressSpace::EmitPrelude() {
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) { if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
code.LDR(Xscratch0, l_return_to_dispatcher); code.LDR(Xscratch0, l_return_to_dispatcher);
for (size_t i = 0; i < RSBCount; i++) { for (std::size_t i = 0; i < RSBCount; i++) {
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry)); code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
} }
} }

View file

@ -403,7 +403,7 @@ void A64AddressSpace::EmitPrelude() {
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) { if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
code.LDR(Xscratch0, l_return_to_dispatcher); code.LDR(Xscratch0, l_return_to_dispatcher);
for (size_t i = 0; i < RSBCount; i++) { for (std::size_t i = 0; i < RSBCount; i++) {
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry)); code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
} }
} }
@ -441,7 +441,7 @@ void A64AddressSpace::EmitPrelude() {
if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) { if (conf.HasOptimization(OptimizationFlag::ReturnStackBuffer)) {
code.LDR(Xscratch0, l_return_to_dispatcher); code.LDR(Xscratch0, l_return_to_dispatcher);
for (size_t i = 0; i < RSBCount; i++) { for (std::size_t i = 0; i < RSBCount; i++) {
code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry)); code.STR(Xscratch0, SP, offsetof(StackLayout, rsb) + offsetof(RSBEntry, code_ptr) + i * sizeof(RSBEntry));
} }
} }

View file

@ -18,15 +18,15 @@ namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util; using namespace oaknut::util;
static constexpr size_t gpr_size = 8; static constexpr std::size_t gpr_size = 8;
static constexpr size_t fpr_size = 16; static constexpr std::size_t fpr_size = 16;
struct FrameInfo { struct FrameInfo {
std::vector<int> gprs; std::vector<int> gprs;
std::vector<int> fprs; std::vector<int> fprs;
size_t frame_size; std::size_t frame_size;
size_t gprs_size; std::size_t gprs_size;
size_t fprs_size; std::size_t fprs_size;
}; };
static std::vector<int> ListToIndexes(u32 list) { static std::vector<int> ListToIndexes(u32 list) {
@ -39,15 +39,15 @@ static std::vector<int> ListToIndexes(u32 list) {
return indexes; return indexes;
} }
static FrameInfo CalculateFrameInfo(RegisterList rl, size_t frame_size) { static FrameInfo CalculateFrameInfo(RegisterList rl, std::size_t frame_size) {
const auto gprs = ListToIndexes(static_cast<u32>(rl)); const auto gprs = ListToIndexes(static_cast<u32>(rl));
const auto fprs = ListToIndexes(static_cast<u32>(rl >> 32)); const auto fprs = ListToIndexes(static_cast<u32>(rl >> 32));
const size_t num_gprs = gprs.size(); const std::size_t num_gprs = gprs.size();
const size_t num_fprs = fprs.size(); const std::size_t num_fprs = fprs.size();
const size_t gprs_size = (num_gprs + 1) / 2 * 16; const std::size_t gprs_size = (num_gprs + 1) / 2 * 16;
const size_t fprs_size = num_fprs * 16; const std::size_t fprs_size = num_fprs * 16;
return { return {
gprs, gprs,
@ -60,16 +60,16 @@ static FrameInfo CalculateFrameInfo(RegisterList rl, size_t frame_size) {
#define DO_IT(TYPE, REG_TYPE, PAIR_OP, SINGLE_OP, OFFSET) \ #define DO_IT(TYPE, REG_TYPE, PAIR_OP, SINGLE_OP, OFFSET) \
if (frame_info.TYPE##s.size() > 0) { \ if (frame_info.TYPE##s.size() > 0) { \
for (size_t i = 0; i < frame_info.TYPE##s.size() - 1; i += 2) { \ for (std::size_t i = 0; i < frame_info.TYPE##s.size() - 1; i += 2) { \
code.PAIR_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, oaknut::REG_TYPE{frame_info.TYPE##s[i + 1]}, SP, (OFFSET) + i * TYPE##_size); \ code.PAIR_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, oaknut::REG_TYPE{frame_info.TYPE##s[i + 1]}, SP, (OFFSET) + i * TYPE##_size); \
} \ } \
if (frame_info.TYPE##s.size() % 2 == 1) { \ if (frame_info.TYPE##s.size() % 2 == 1) { \
const size_t i = frame_info.TYPE##s.size() - 1; \ const std::size_t i = frame_info.TYPE##s.size() - 1; \
code.SINGLE_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, SP, (OFFSET) + i * TYPE##_size); \ code.SINGLE_OP(oaknut::REG_TYPE{frame_info.TYPE##s[i]}, SP, (OFFSET) + i * TYPE##_size); \
} \ } \
} }
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame_size) { void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t frame_size) {
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size); const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
code.SUB(SP, SP, frame_info.gprs_size + frame_info.fprs_size); code.SUB(SP, SP, frame_info.gprs_size + frame_info.fprs_size);
@ -80,7 +80,7 @@ void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t fram
code.SUB(SP, SP, frame_info.frame_size); code.SUB(SP, SP, frame_info.frame_size);
} }
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t frame_size) { void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t frame_size) {
const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size); const FrameInfo frame_info = CalculateFrameInfo(rl, frame_size);
code.ADD(SP, SP, frame_info.frame_size); code.ADD(SP, SP, frame_info.frame_size);

View file

@ -67,7 +67,7 @@ constexpr RegisterList ToRegList(oaknut::Reg reg) {
constexpr RegisterList ABI_CALLEE_SAVE = 0x0000ff00'7ff80000; constexpr RegisterList ABI_CALLEE_SAVE = 0x0000ff00'7ff80000;
constexpr RegisterList ABI_CALLER_SAVE = 0xffffffff'4000ffff; constexpr RegisterList ABI_CALLER_SAVE = 0xffffffff'4000ffff;
void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t stack_space); void ABI_PushRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t stack_space);
void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, size_t stack_space); void ABI_PopRegisters(oaknut::CodeGenerator& code, RegisterList rl, std::size_t stack_space);
} // namespace Dynarmic::Backend::Arm64 } // namespace Dynarmic::Backend::Arm64

View file

@ -24,7 +24,7 @@
namespace Dynarmic::Backend::Arm64 { namespace Dynarmic::Backend::Arm64 {
AddressSpace::AddressSpace(size_t code_cache_size) AddressSpace::AddressSpace(std::size_t code_cache_size)
: ir_block{IR::LocationDescriptor{0}} : ir_block{IR::LocationDescriptor{0}}
, code_cache_size(code_cache_size) , code_cache_size(code_cache_size)
, mem(code_cache_size) , mem(code_cache_size)
@ -102,8 +102,8 @@ void AddressSpace::ClearCache() {
code.set_offset(prelude_info.end_of_prelude); code.set_offset(prelude_info.end_of_prelude);
} }
size_t AddressSpace::GetRemainingSize() { std::size_t AddressSpace::GetRemainingSize() {
return code_cache_size - static_cast<size_t>(code.offset()); return code_cache_size - static_cast<std::size_t>(code.offset());
} }
EmittedBlockInfo AddressSpace::Emit(IR::Block block) { EmittedBlockInfo AddressSpace::Emit(IR::Block block) {

View file

@ -26,7 +26,7 @@ namespace Dynarmic::Backend::Arm64 {
class AddressSpace { class AddressSpace {
public: public:
explicit AddressSpace(size_t code_cache_size); explicit AddressSpace(std::size_t code_cache_size);
virtual ~AddressSpace(); virtual ~AddressSpace();
virtual void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const = 0; virtual void GenerateIR(IR::Block& ir_block, IR::LocationDescriptor) const = 0;
@ -60,7 +60,7 @@ protected:
#endif #endif
} }
size_t GetRemainingSize(); std::size_t GetRemainingSize();
EmittedBlockInfo Emit(IR::Block ir_block); EmittedBlockInfo Emit(IR::Block ir_block);
void Link(EmittedBlockInfo& block); void Link(EmittedBlockInfo& block);
void LinkBlockLinks(const CodePtr entry_point, const CodePtr target_ptr, const std::vector<BlockRelocation>& block_relocations_list); void LinkBlockLinks(const CodePtr entry_point, const CodePtr target_ptr, const std::vector<BlockRelocation>& block_relocations_list);
@ -69,7 +69,7 @@ protected:
FakeCall FastmemCallback(u64 host_pc); FakeCall FastmemCallback(u64 host_pc);
IR::Block ir_block; IR::Block ir_block;
const size_t code_cache_size; const std::size_t code_cache_size;
oaknut::CodeBlock mem; oaknut::CodeBlock mem;
oaknut::CodeGenerator code; oaknut::CodeGenerator code;

View file

@ -176,7 +176,7 @@ void EmitIR<IR::Opcode::NZCVFromPackedFlags>(oaknut::CodeGenerator&, EmitContext
ctx.reg_alloc.DefineAsExisting(inst, args[0]); ctx.reg_alloc.DefineAsExisting(inst, args[0]);
} }
static void EmitAddCycles(oaknut::CodeGenerator& code, EmitContext& ctx, size_t cycles_to_add) { static void EmitAddCycles(oaknut::CodeGenerator& code, EmitContext& ctx, std::size_t cycles_to_add) {
if (!ctx.conf.enable_cycle_counting) { if (!ctx.conf.enable_cycle_counting) {
return; return;
} }

View file

@ -103,7 +103,7 @@ struct BlockRelocation {
struct EmittedBlockInfo { struct EmittedBlockInfo {
CodePtr entry_point; CodePtr entry_point;
size_t size; std::size_t size;
std::vector<Relocation> relocations; std::vector<Relocation> relocations;
ankerl::unordered_dense::map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations; ankerl::unordered_dense::map<IR::LocationDescriptor, std::vector<BlockRelocation>> block_relocations;
ankerl::unordered_dense::map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info; ankerl::unordered_dense::map<std::ptrdiff_t, FastmemPatchInfo> fastmem_patch_info;
@ -127,9 +127,9 @@ struct EmitConfig {
// Page table // Page table
u64 page_table_pointer; u64 page_table_pointer;
size_t page_table_address_space_bits; std::size_t page_table_address_space_bits;
int page_table_pointer_mask_bits; int page_table_pointer_mask_bits;
size_t page_table_log2_stride; std::size_t page_table_log2_stride;
bool silently_mirror_page_table; bool silently_mirror_page_table;
bool absolute_offset_page_table; bool absolute_offset_page_table;
u8 detect_misaligned_access_via_page_table; u8 detect_misaligned_access_via_page_table;
@ -138,7 +138,7 @@ struct EmitConfig {
// Fastmem // Fastmem
std::optional<u64> fastmem_pointer; std::optional<u64> fastmem_pointer;
bool recompile_on_fastmem_failure; bool recompile_on_fastmem_failure;
size_t fastmem_address_space_bits; std::size_t fastmem_address_space_bits;
bool silently_mirror_fastmem; bool silently_mirror_fastmem;
// Timing // Timing
@ -156,9 +156,9 @@ struct EmitConfig {
void (*emit_check_memory_abort)(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, oaknut::Label& end); void (*emit_check_memory_abort)(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, oaknut::Label& end);
// State offsets // State offsets
size_t state_nzcv_offset; std::size_t state_nzcv_offset;
size_t state_fpsr_offset; std::size_t state_fpsr_offset;
size_t state_exclusive_state_offset; std::size_t state_exclusive_state_offset;
// A32 specific // A32 specific
std::array<std::shared_ptr<A32::Coprocessor>, 16> coprocessors{}; std::array<std::shared_ptr<A32::Coprocessor>, 16> coprocessors{};

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
@ -45,7 +45,7 @@ static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A3
template<> template<>
void EmitIR<IR::Opcode::A32CoprocInternalOperation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { void EmitIR<IR::Opcode::A32CoprocInternalOperation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const auto coproc_info = inst->GetArg(0).GetCoprocInfo(); const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
const size_t coproc_num = coproc_info[0]; const std::size_t coproc_num = coproc_info[0];
const bool two = coproc_info[1] != 0; const bool two = coproc_info[1] != 0;
const auto opc1 = static_cast<unsigned>(coproc_info[2]); const auto opc1 = static_cast<unsigned>(coproc_info[2]);
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]); const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
@ -72,7 +72,7 @@ template<>
void EmitIR<IR::Opcode::A32CoprocSendOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { void EmitIR<IR::Opcode::A32CoprocSendOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const auto coproc_info = inst->GetArg(0).GetCoprocInfo(); const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
const size_t coproc_num = coproc_info[0]; const std::size_t coproc_num = coproc_info[0];
const bool two = coproc_info[1] != 0; const bool two = coproc_info[1] != 0;
const auto opc1 = static_cast<unsigned>(coproc_info[2]); const auto opc1 = static_cast<unsigned>(coproc_info[2]);
const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]); const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]);
@ -115,7 +115,7 @@ void EmitIR<IR::Opcode::A32CoprocSendTwoWords>(oaknut::CodeGenerator& code, Emit
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const auto coproc_info = inst->GetArg(0).GetCoprocInfo(); const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
const size_t coproc_num = coproc_info[0]; const std::size_t coproc_num = coproc_info[0];
const bool two = coproc_info[1] != 0; const bool two = coproc_info[1] != 0;
const auto opc = static_cast<unsigned>(coproc_info[2]); const auto opc = static_cast<unsigned>(coproc_info[2]);
const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]); const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]);
@ -158,7 +158,7 @@ template<>
void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const auto coproc_info = inst->GetArg(0).GetCoprocInfo(); const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
const size_t coproc_num = coproc_info[0]; const std::size_t coproc_num = coproc_info[0];
const bool two = coproc_info[1] != 0; const bool two = coproc_info[1] != 0;
const auto opc1 = static_cast<unsigned>(coproc_info[2]); const auto opc1 = static_cast<unsigned>(coproc_info[2]);
const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]); const auto CRn = static_cast<A32::CoprocReg>(coproc_info[3]);
@ -199,7 +199,7 @@ void EmitIR<IR::Opcode::A32CoprocGetOneWord>(oaknut::CodeGenerator& code, EmitCo
template<> template<>
void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { void EmitIR<IR::Opcode::A32CoprocGetTwoWords>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const auto coproc_info = inst->GetArg(0).GetCoprocInfo(); const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
const size_t coproc_num = coproc_info[0]; const std::size_t coproc_num = coproc_info[0];
const bool two = coproc_info[1] != 0; const bool two = coproc_info[1] != 0;
const unsigned opc = coproc_info[2]; const unsigned opc = coproc_info[2];
const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]); const auto CRm = static_cast<A32::CoprocReg>(coproc_info[3]);
@ -243,7 +243,7 @@ void EmitIR<IR::Opcode::A32CoprocLoadWords>(oaknut::CodeGenerator& code, EmitCon
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const auto coproc_info = inst->GetArg(0).GetCoprocInfo(); const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
const size_t coproc_num = coproc_info[0]; const std::size_t coproc_num = coproc_info[0];
const bool two = coproc_info[1] != 0; const bool two = coproc_info[1] != 0;
const bool long_transfer = coproc_info[2] != 0; const bool long_transfer = coproc_info[2] != 0;
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]); const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);
@ -274,7 +274,7 @@ void EmitIR<IR::Opcode::A32CoprocStoreWords>(oaknut::CodeGenerator& code, EmitCo
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const auto coproc_info = inst->GetArg(0).GetCoprocInfo(); const auto coproc_info = inst->GetArg(0).GetCoprocInfo();
const size_t coproc_num = coproc_info[0]; const std::size_t coproc_num = coproc_info[0];
const bool two = coproc_info[1] != 0; const bool two = coproc_info[1] != 0;
const bool long_transfer = coproc_info[2] != 0; const bool long_transfer = coproc_info[2] != 0;
const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]); const auto CRd = static_cast<A32::CoprocReg>(coproc_info[3]);

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
@ -21,7 +21,7 @@ namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util; using namespace oaknut::util;
template<size_t bitsize, typename EmitFn> template<std::size_t bitsize, typename EmitFn>
static void EmitCRC(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit_fn) { static void EmitCRC(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit_fn) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);

View file

@ -23,7 +23,7 @@ namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util; using namespace oaknut::util;
template<size_t bitsize, typename EmitFn> template<std::size_t bitsize, typename EmitFn>
static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -34,7 +34,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
emit(Rresult, Roperand); emit(Rresult, Roperand);
} }
template<size_t bitsize, typename EmitFn> template<std::size_t bitsize, typename EmitFn>
static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
@ -867,7 +867,7 @@ void EmitIR<IR::Opcode::RotateRightMasked64>(oaknut::CodeGenerator& code, EmitCo
[&](auto& Xresult, auto& Xoperand, auto& Xshift) { code.ROR(Xresult, Xoperand, Xshift); }); [&](auto& Xresult, auto& Xoperand, auto& Xshift) { code.ROR(Xresult, Xoperand, Xshift); });
} }
template<size_t bitsize, typename EmitFn> template<std::size_t bitsize, typename EmitFn>
static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) { static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
static_assert(bitsize == 32 || bitsize == 64); static_assert(bitsize == 32 || bitsize == 64);
if constexpr (bitsize == 32) { if constexpr (bitsize == 32) {
@ -881,7 +881,7 @@ static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn)
} }
} }
template<size_t bitsize, bool sub> template<std::size_t bitsize, bool sub>
static void EmitAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { static void EmitAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp); const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
@ -1125,7 +1125,7 @@ static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
} }
} }
template<size_t bitsize, typename EmitFn1, typename EmitFn2 = std::nullptr_t> template<std::size_t bitsize, typename EmitFn1, typename EmitFn2 = std::nullptr_t>
static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn1 emit_without_flags, EmitFn2 emit_with_flags = nullptr) { static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn1 emit_without_flags, EmitFn2 emit_with_flags = nullptr) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Rresult = ctx.reg_alloc.WriteReg<bitsize>(inst); auto Rresult = ctx.reg_alloc.WriteReg<bitsize>(inst);
@ -1167,7 +1167,7 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
} }
} }
template<size_t bitsize> template<std::size_t bitsize>
static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp); const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp);
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp); const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
@ -23,7 +23,7 @@ namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util; using namespace oaknut::util;
template<size_t bitsize, typename EmitFn> template<std::size_t bitsize, typename EmitFn>
static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst); auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
@ -34,7 +34,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
emit(Vresult, Voperand); emit(Vresult, Voperand);
} }
template<size_t bitsize, typename EmitFn> template<std::size_t bitsize, typename EmitFn>
static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst); auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
@ -46,7 +46,7 @@ static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
emit(Vresult, Va, Vb); emit(Vresult, Va, Vb);
} }
template<size_t bitsize, typename EmitFn> template<std::size_t bitsize, typename EmitFn>
static void EmitFourOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitFourOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst); auto Vresult = ctx.reg_alloc.WriteVec<bitsize>(inst);
@ -59,10 +59,10 @@ static void EmitFourOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
emit(Vresult, Va, Vb, Vc); emit(Vresult, Va, Vb, Vc);
} }
template<size_t bitsize_from, size_t bitsize_to, typename EmitFn> template<std::size_t bitsize_from, std::size_t bitstd::size_to, typename EmitFn>
static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Vto = ctx.reg_alloc.WriteVec<bitsize_to>(inst); auto Vto = ctx.reg_alloc.WriteVec<bitstd::size_to>(inst);
auto Vfrom = ctx.reg_alloc.ReadVec<bitsize_from>(args[0]); auto Vfrom = ctx.reg_alloc.ReadVec<bitsize_from>(args[0]);
const auto rounding_mode = static_cast<FP::RoundingMode>(args[1].GetImmediateU8()); const auto rounding_mode = static_cast<FP::RoundingMode>(args[1].GetImmediateU8());
RegAlloc::Realize(Vto, Vfrom); RegAlloc::Realize(Vto, Vfrom);
@ -73,19 +73,19 @@ static void EmitConvert(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
emit(Vto, Vfrom); emit(Vto, Vfrom);
} }
template<size_t bitsize_from, size_t bitsize_to, bool is_signed> template<std::size_t bitsize_from, std::size_t bitstd::size_to, bool is_signed>
static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Rto = ctx.reg_alloc.WriteReg<std::max<size_t>(bitsize_to, 32)>(inst); auto Rto = ctx.reg_alloc.WriteReg<std::max<std::size_t>(bitstd::size_to, 32)>(inst);
auto Vfrom = ctx.reg_alloc.ReadVec<bitsize_from>(args[0]); auto Vfrom = ctx.reg_alloc.ReadVec<bitsize_from>(args[0]);
const size_t fbits = args[1].GetImmediateU8(); const std::size_t fbits = args[1].GetImmediateU8();
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8()); const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
RegAlloc::Realize(Rto, Vfrom); RegAlloc::Realize(Rto, Vfrom);
ctx.fpsr.Load(); ctx.fpsr.Load();
if (rounding_mode == FP::RoundingMode::TowardsZero) { if (rounding_mode == FP::RoundingMode::TowardsZero) {
if constexpr (is_signed) { if constexpr (is_signed) {
if constexpr (bitsize_to == 16) { if constexpr (bitstd::size_to == 16) {
code.FCVTZS(Rto, Vfrom, fbits + 16); code.FCVTZS(Rto, Vfrom, fbits + 16);
code.ASR(Wscratch0, Rto, 31); code.ASR(Wscratch0, Rto, 31);
code.ADD(Rto, Rto, Wscratch0, LSR, 16); // Round towards zero when truncating code.ADD(Rto, Rto, Wscratch0, LSR, 16); // Round towards zero when truncating
@ -96,7 +96,7 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
code.FCVTZS(Rto, Vfrom); code.FCVTZS(Rto, Vfrom);
} }
} else { } else {
if constexpr (bitsize_to == 16) { if constexpr (bitstd::size_to == 16) {
code.FCVTZU(Rto, Vfrom, fbits + 16); code.FCVTZU(Rto, Vfrom, fbits + 16);
code.LSR(Rto, Rto, 16); code.LSR(Rto, Rto, 16);
} else if (fbits) { } else if (fbits) {
@ -107,7 +107,7 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
} }
} else { } else {
ASSERT(fbits == 0); ASSERT(fbits == 0);
ASSERT(bitsize_to != 16); ASSERT(bitstd::size_to != 16);
if constexpr (is_signed) { if constexpr (is_signed) {
switch (rounding_mode) { switch (rounding_mode) {
case FP::RoundingMode::ToNearest_TieEven: case FP::RoundingMode::ToNearest_TieEven:
@ -158,12 +158,12 @@ static void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
} }
} }
template<size_t bitsize_from, size_t bitsize_to, typename EmitFn> template<std::size_t bitsize_from, std::size_t bitstd::size_to, typename EmitFn>
static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Vto = ctx.reg_alloc.WriteVec<bitsize_to>(inst); auto Vto = ctx.reg_alloc.WriteVec<bitstd::size_to>(inst);
auto Rfrom = ctx.reg_alloc.ReadReg<std::max<size_t>(bitsize_from, 32)>(args[0]); auto Rfrom = ctx.reg_alloc.ReadReg<std::max<std::size_t>(bitsize_from, 32)>(args[0]);
const size_t fbits = args[1].GetImmediateU8(); const std::size_t fbits = args[1].GetImmediateU8();
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8()); const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
RegAlloc::Realize(Vto, Rfrom); RegAlloc::Realize(Vto, Rfrom);
ctx.fpsr.Load(); ctx.fpsr.Load();
@ -212,7 +212,7 @@ void EmitIR<IR::Opcode::FPAdd64>(oaknut::CodeGenerator& code, EmitContext& ctx,
EmitThreeOp<64>(code, ctx, inst, [&](auto& Dresult, auto& Da, auto& Db) { code.FADD(Dresult, Da, Db); }); EmitThreeOp<64>(code, ctx, inst, [&](auto& Dresult, auto& Da, auto& Db) { code.FADD(Dresult, Da, Db); });
} }
template<size_t size> template<std::size_t size>
void EmitCompare(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { void EmitCompare(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto flags = ctx.reg_alloc.WriteFlags(inst); auto flags = ctx.reg_alloc.WriteFlags(inst);

View file

@ -35,7 +35,7 @@ bool IsOrdered(IR::AccType acctype) {
return acctype == IR::AccType::ORDERED || acctype == IR::AccType::ORDEREDRW || acctype == IR::AccType::LIMITEDORDERED; return acctype == IR::AccType::ORDERED || acctype == IR::AccType::ORDEREDRW || acctype == IR::AccType::LIMITEDORDERED;
} }
LinkTarget ReadMemoryLinkTarget(size_t bitsize) { LinkTarget ReadMemoryLinkTarget(std::size_t bitsize) {
switch (bitsize) { switch (bitsize) {
case 8: case 8:
return LinkTarget::ReadMemory8; return LinkTarget::ReadMemory8;
@ -51,7 +51,7 @@ LinkTarget ReadMemoryLinkTarget(size_t bitsize) {
UNREACHABLE(); UNREACHABLE();
} }
LinkTarget WriteMemoryLinkTarget(size_t bitsize) { LinkTarget WriteMemoryLinkTarget(std::size_t bitsize) {
switch (bitsize) { switch (bitsize) {
case 8: case 8:
return LinkTarget::WriteMemory8; return LinkTarget::WriteMemory8;
@ -67,7 +67,7 @@ LinkTarget WriteMemoryLinkTarget(size_t bitsize) {
UNREACHABLE(); UNREACHABLE();
} }
LinkTarget WrappedReadMemoryLinkTarget(size_t bitsize) { LinkTarget WrappedReadMemoryLinkTarget(std::size_t bitsize) {
switch (bitsize) { switch (bitsize) {
case 8: case 8:
return LinkTarget::WrappedReadMemory8; return LinkTarget::WrappedReadMemory8;
@ -83,7 +83,7 @@ LinkTarget WrappedReadMemoryLinkTarget(size_t bitsize) {
UNREACHABLE(); UNREACHABLE();
} }
LinkTarget WrappedWriteMemoryLinkTarget(size_t bitsize) { LinkTarget WrappedWriteMemoryLinkTarget(std::size_t bitsize) {
switch (bitsize) { switch (bitsize) {
case 8: case 8:
return LinkTarget::WrappedWriteMemory8; return LinkTarget::WrappedWriteMemory8;
@ -99,7 +99,7 @@ LinkTarget WrappedWriteMemoryLinkTarget(size_t bitsize) {
UNREACHABLE(); UNREACHABLE();
} }
LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) { LinkTarget ExclusiveReadMemoryLinkTarget(std::size_t bitsize) {
switch (bitsize) { switch (bitsize) {
case 8: case 8:
return LinkTarget::ExclusiveReadMemory8; return LinkTarget::ExclusiveReadMemory8;
@ -115,7 +115,7 @@ LinkTarget ExclusiveReadMemoryLinkTarget(size_t bitsize) {
UNREACHABLE(); UNREACHABLE();
} }
LinkTarget ExclusiveWriteMemoryLinkTarget(size_t bitsize) { LinkTarget ExclusiveWriteMemoryLinkTarget(std::size_t bitsize) {
switch (bitsize) { switch (bitsize) {
case 8: case 8:
return LinkTarget::ExclusiveWriteMemory8; return LinkTarget::ExclusiveWriteMemory8;
@ -209,9 +209,9 @@ void CallbackOnlyEmitExclusiveWriteMemory(oaknut::CodeGenerator& code, EmitConte
ctx.reg_alloc.DefineAsRegister(inst, X0); ctx.reg_alloc.DefineAsRegister(inst, X0);
} }
constexpr size_t page_table_const_bits = 12; constexpr std::size_t page_table_const_bits = 12;
constexpr size_t page_table_const_size = 1 << page_table_const_bits; constexpr std::size_t page_table_const_size = 1 << page_table_const_bits;
constexpr size_t page_table_const_mask = (1 << page_table_const_bits) - 1; constexpr std::size_t page_table_const_mask = (1 << page_table_const_bits) - 1;
// This function may use Xscratch0 as a scratch register // This function may use Xscratch0 as a scratch register
// Trashes NZCV // Trashes NZCV
@ -255,8 +255,8 @@ void EmitDetectMisalignedVAddr(oaknut::CodeGenerator& code, EmitContext& ctx, oa
// Trashes NZCV // Trashes NZCV
template<std::size_t bitsize> template<std::size_t bitsize>
std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) { std::pair<oaknut::XReg, oaknut::XReg> InlinePageTableEmitVAddrLookup(oaknut::CodeGenerator& code, EmitContext& ctx, oaknut::XReg Xaddr, const SharedLabel& fallback) {
const size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_table_const_bits; const std::size_t valid_page_index_bits = ctx.conf.page_table_address_space_bits - page_table_const_bits;
const size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits; const std::size_t unused_top_bits = 64 - ctx.conf.page_table_address_space_bits;
EmitDetectMisalignedVAddr<bitsize>(code, ctx, Xaddr, fallback); EmitDetectMisalignedVAddr<bitsize>(code, ctx, Xaddr, fallback);

View file

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
@ -66,7 +66,7 @@ void EmitIR<IR::Opcode::SignedSaturation>(oaknut::CodeGenerator& code, EmitConte
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const size_t N = args[1].GetImmediateU8(); const std::size_t N = args[1].GetImmediateU8();
ASSERT(N >= 1 && N <= 32); ASSERT(N >= 1 && N <= 32);
if (N == 32) { if (N == 32) {
@ -112,7 +112,7 @@ void EmitIR<IR::Opcode::UnsignedSaturation>(oaknut::CodeGenerator& code, EmitCon
RegAlloc::Realize(Wresult, Woperand); RegAlloc::Realize(Wresult, Woperand);
ctx.reg_alloc.SpillFlags(); ctx.reg_alloc.SpillFlags();
const size_t N = args[1].GetImmediateU8(); const std::size_t N = args[1].GetImmediateU8();
ASSERT(N <= 31); ASSERT(N <= 31);
const u32 saturated_value = (1u << N) - 1; const u32 saturated_value = (1u << N) - 1;

View file

@ -33,7 +33,7 @@ static void EmitTwoOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
emit(Qresult, Qoperand); emit(Qresult, Qoperand);
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) { EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
if constexpr (size == 8) { if constexpr (size == 8) {
@ -50,7 +50,7 @@ static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR:
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitTwoOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitTwoOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) { EmitTwoOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) {
ctx.fpsr.Load(); ctx.fpsr.Load();
@ -58,7 +58,7 @@ static void EmitTwoOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext&
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) { EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
if constexpr (size == 8) { if constexpr (size == 8) {
@ -73,7 +73,7 @@ static void EmitTwoOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) { EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
if constexpr (size == 16) { if constexpr (size == 16) {
@ -88,7 +88,7 @@ static void EmitTwoOpArrangedNarrow(oaknut::CodeGenerator& code, EmitContext& ct
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitTwoOpArrangedSaturatedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOpArrangedSaturatedNarrow(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitTwoOpArrangedNarrow<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) { EmitTwoOpArrangedNarrow<size>(code, ctx, inst, [&](auto Vresult, auto Voperand) {
ctx.fpsr.Load(); ctx.fpsr.Load();
@ -96,7 +96,7 @@ static void EmitTwoOpArrangedSaturatedNarrow(oaknut::CodeGenerator& code, EmitCo
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) { EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
if constexpr (size == 8) { if constexpr (size == 8) {
@ -111,7 +111,7 @@ static void EmitTwoOpArrangedPairWiden(oaknut::CodeGenerator& code, EmitContext&
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitTwoOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) { EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qoperand) {
if constexpr (size == 8) { if constexpr (size == 8) {
@ -137,7 +137,7 @@ static void EmitThreeOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst
emit(Qresult, Qa, Qb); emit(Qresult, Qa, Qb);
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) { EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
if constexpr (size == 8) { if constexpr (size == 8) {
@ -154,7 +154,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitThreeOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitThreeOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitThreeOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) { EmitThreeOpArranged<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) {
ctx.fpsr.Load(); ctx.fpsr.Load();
@ -162,7 +162,7 @@ static void EmitThreeOpArrangedSaturated(oaknut::CodeGenerator& code, EmitContex
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) { EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
if constexpr (size == 8) { if constexpr (size == 8) {
@ -179,7 +179,7 @@ static void EmitThreeOpArrangedWiden(oaknut::CodeGenerator& code, EmitContext& c
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitThreeOpArrangedSaturatedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitThreeOpArrangedSaturatedWiden(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitThreeOpArrangedWiden<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) { EmitThreeOpArrangedWiden<size>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) {
ctx.fpsr.Load(); ctx.fpsr.Load();
@ -187,7 +187,7 @@ static void EmitThreeOpArrangedSaturatedWiden(oaknut::CodeGenerator& code, EmitC
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) { EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
if constexpr (size == 8) { if constexpr (size == 8) {
@ -202,7 +202,7 @@ static void EmitThreeOpArrangedLower(oaknut::CodeGenerator& code, EmitContext& c
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qaccumulator = ctx.reg_alloc.ReadWriteQ(args[1], inst); // NB: Swapped auto Qaccumulator = ctx.reg_alloc.ReadWriteQ(args[1], inst); // NB: Swapped
@ -223,7 +223,7 @@ static void EmitSaturatedAccumulate(oaknut::CodeGenerator&, EmitContext& ctx, IR
} }
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qresult = ctx.reg_alloc.WriteQ(inst); auto Qresult = ctx.reg_alloc.WriteQ(inst);
@ -244,7 +244,7 @@ static void EmitImmShift(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* ins
} }
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitImmShiftSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitImmShiftSaturated(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitImmShift<size>(code, ctx, inst, [&](auto Vresult, auto Voperand, u8 shift_amount) { EmitImmShift<size>(code, ctx, inst, [&](auto Vresult, auto Voperand, u8 shift_amount) {
ctx.fpsr.Load(); ctx.fpsr.Load();
@ -252,7 +252,7 @@ static void EmitImmShiftSaturated(oaknut::CodeGenerator& code, EmitContext& ctx,
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Vresult = ctx.reg_alloc.WriteVec<size>(inst); auto Vresult = ctx.reg_alloc.WriteVec<size>(inst);
@ -272,13 +272,13 @@ static void EmitReduce(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst,
} }
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitGetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitGetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate()); ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8(); const u8 index = args[1].GetImmediateU8();
auto Rresult = ctx.reg_alloc.WriteReg<std::max<size_t>(32, size)>(inst); auto Rresult = ctx.reg_alloc.WriteReg<std::max<std::size_t>(32, size)>(inst);
auto Qvalue = ctx.reg_alloc.ReadQ(args[0]); auto Qvalue = ctx.reg_alloc.ReadQ(args[0]);
RegAlloc::Realize(Rresult, Qvalue); RegAlloc::Realize(Rresult, Qvalue);
@ -307,14 +307,14 @@ void EmitIR<IR::Opcode::VectorGetElement64>(oaknut::CodeGenerator& code, EmitCon
EmitGetElement<64>(code, ctx, inst, [&](auto& Xresult, auto& Qvalue, u8 index) { code.UMOV(Xresult, Qvalue->Delem()[index]); }); EmitGetElement<64>(code, ctx, inst, [&](auto& Xresult, auto& Qvalue, u8 index) { code.UMOV(Xresult, Qvalue->Delem()[index]); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitSetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitSetElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ASSERT(args[1].IsImmediate()); ASSERT(args[1].IsImmediate());
const u8 index = args[1].GetImmediateU8(); const u8 index = args[1].GetImmediateU8();
auto Qvector = ctx.reg_alloc.ReadWriteQ(args[0], inst); auto Qvector = ctx.reg_alloc.ReadWriteQ(args[0], inst);
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<size_t>(32, size)>(args[2]); auto Rvalue = ctx.reg_alloc.ReadReg<std::max<std::size_t>(32, size)>(args[2]);
RegAlloc::Realize(Qvector, Rvalue); RegAlloc::Realize(Qvector, Rvalue);
// TODO: fpr source // TODO: fpr source
@ -432,11 +432,11 @@ void EmitIR<IR::Opcode::VectorArithmeticVShift64>(oaknut::CodeGenerator& code, E
EmitThreeOpArranged<64>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) { code.SSHL(Vresult, Va, Vb); }); EmitThreeOpArranged<64>(code, ctx, inst, [&](auto Vresult, auto Va, auto Vb) { code.SSHL(Vresult, Va, Vb); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitBroadcast(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitBroadcast(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qvector = ctx.reg_alloc.WriteQ(inst); auto Qvector = ctx.reg_alloc.WriteQ(inst);
auto Rvalue = ctx.reg_alloc.ReadReg<std::max<size_t>(32, size)>(args[0]); auto Rvalue = ctx.reg_alloc.ReadReg<std::max<std::size_t>(32, size)>(args[0]);
RegAlloc::Realize(Qvector, Rvalue); RegAlloc::Realize(Qvector, Rvalue);
// TODO: fpr source // TODO: fpr source
@ -479,7 +479,7 @@ void EmitIR<IR::Opcode::VectorBroadcast64>(oaknut::CodeGenerator& code, EmitCont
EmitBroadcast<64>(code, ctx, inst, [&](auto& Qvector, auto& Xvalue) { code.DUP(Qvector->D2(), Xvalue); }); EmitBroadcast<64>(code, ctx, inst, [&](auto& Qvector, auto& Xvalue) { code.DUP(Qvector->D2(), Xvalue); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitBroadcastElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitBroadcastElement(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qvector = ctx.reg_alloc.WriteQ(inst); auto Qvector = ctx.reg_alloc.WriteQ(inst);
@ -1612,17 +1612,17 @@ void EmitIR<IR::Opcode::VectorTableLookup64>(oaknut::CodeGenerator& code, EmitCo
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst()); auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
const size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); }); const std::size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
const bool is_defaults_zero = inst->GetArg(0).IsZero(); const bool is_defaults_zero = inst->GetArg(0).IsZero();
auto Dresult = is_defaults_zero ? ctx.reg_alloc.WriteD(inst) : ctx.reg_alloc.ReadWriteD(args[0], inst); auto Dresult = is_defaults_zero ? ctx.reg_alloc.WriteD(inst) : ctx.reg_alloc.ReadWriteD(args[0], inst);
auto Dindices = ctx.reg_alloc.ReadD(args[2]); auto Dindices = ctx.reg_alloc.ReadD(args[2]);
std::vector<RAReg<oaknut::DReg>> Dtable; std::vector<RAReg<oaknut::DReg>> Dtable;
for (size_t i = 0; i < table_size; i++) { for (std::size_t i = 0; i < table_size; i++) {
Dtable.emplace_back(ctx.reg_alloc.ReadD(table[i])); Dtable.emplace_back(ctx.reg_alloc.ReadD(table[i]));
} }
RegAlloc::Realize(Dresult, Dindices); RegAlloc::Realize(Dresult, Dindices);
for (size_t i = 0; i < table_size; i++) { for (std::size_t i = 0; i < table_size; i++) {
RegAlloc::Realize(Dtable[i]); RegAlloc::Realize(Dtable[i]);
} }
@ -1679,17 +1679,17 @@ void EmitIR<IR::Opcode::VectorTableLookup128>(oaknut::CodeGenerator& code, EmitC
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst()); auto table = ctx.reg_alloc.GetArgumentInfo(inst->GetArg(1).GetInst());
const size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); }); const std::size_t table_size = std::count_if(table.begin(), table.end(), [](const auto& elem) { return !elem.IsVoid(); });
const bool is_defaults_zero = inst->GetArg(0).IsZero(); const bool is_defaults_zero = inst->GetArg(0).IsZero();
auto Qresult = is_defaults_zero ? ctx.reg_alloc.WriteQ(inst) : ctx.reg_alloc.ReadWriteQ(args[0], inst); auto Qresult = is_defaults_zero ? ctx.reg_alloc.WriteQ(inst) : ctx.reg_alloc.ReadWriteQ(args[0], inst);
auto Qindices = ctx.reg_alloc.ReadQ(args[2]); auto Qindices = ctx.reg_alloc.ReadQ(args[2]);
std::vector<RAReg<oaknut::QReg>> Qtable; std::vector<RAReg<oaknut::QReg>> Qtable;
for (size_t i = 0; i < table_size; i++) { for (std::size_t i = 0; i < table_size; i++) {
Qtable.emplace_back(ctx.reg_alloc.ReadQ(table[i])); Qtable.emplace_back(ctx.reg_alloc.ReadQ(table[i]));
} }
RegAlloc::Realize(Qresult, Qindices); RegAlloc::Realize(Qresult, Qindices);
for (size_t i = 0; i < table_size; i++) { for (std::size_t i = 0; i < table_size; i++) {
RegAlloc::Realize(Qtable[i]); RegAlloc::Realize(Qtable[i]);
} }

View file

@ -32,7 +32,7 @@
namespace Dynarmic::Backend::Arm64 { namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util; using namespace oaknut::util;
using A64FullVectorWidth = std::integral_constant<size_t, 128>; using A64FullVectorWidth = std::integral_constant<std::size_t, 128>;
// Array alias that always sizes itself according to the given type T // Array alias that always sizes itself according to the given type T
// relative to the size of a vector register. e.g. T = u32 would result // relative to the size of a vector register. e.g. T = u32 would result
@ -65,7 +65,7 @@ static void EmitTwoOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa); }); MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitTwoOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qa) { EmitTwoOp(code, ctx, inst, [&](auto& Qresult, auto& Qa) {
if constexpr (size == 16) { if constexpr (size == 16) {
@ -93,7 +93,7 @@ static void EmitThreeOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa, Qb); }); MaybeStandardFPSCRValue(code, ctx, fpcr_controlled, [&] { emit(Qresult, Qa, Qb); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) { EmitThreeOp(code, ctx, inst, [&](auto& Qresult, auto& Qa, auto& Qb) {
if constexpr (size == 16) { if constexpr (size == 16) {
@ -108,7 +108,7 @@ static void EmitThreeOpArranged(oaknut::CodeGenerator& code, EmitContext& ctx, I
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qresult = ctx.reg_alloc.ReadWriteQ(args[0], inst); auto Qresult = ctx.reg_alloc.ReadWriteQ(args[0], inst);
@ -131,7 +131,7 @@ static void EmitFMA(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* ins
}); });
} }
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qto = ctx.reg_alloc.WriteQ(inst); auto Qto = ctx.reg_alloc.WriteQ(inst);
@ -153,12 +153,12 @@ static void EmitFromFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Ins
}); });
} }
template<size_t fsize, bool is_signed> template<std::size_t fsize, bool is_signed>
void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { void EmitToFixed(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qto = ctx.reg_alloc.WriteQ(inst); auto Qto = ctx.reg_alloc.WriteQ(inst);
auto Qfrom = ctx.reg_alloc.ReadQ(args[0]); auto Qfrom = ctx.reg_alloc.ReadQ(args[0]);
const size_t fbits = args[1].GetImmediateU8(); const std::size_t fbits = args[1].GetImmediateU8();
const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8()); const auto rounding_mode = static_cast<FP::RoundingMode>(args[2].GetImmediateU8());
const bool fpcr_controlled = inst->GetArg(3).GetU1(); const bool fpcr_controlled = inst->GetArg(3).GetU1();
RegAlloc::Realize(Qto, Qfrom); RegAlloc::Realize(Qto, Qfrom);
@ -272,7 +272,7 @@ static void EmitTwoOpFallbackWithoutRegAlloc(oaknut::CodeGenerator& code, EmitCo
ABI_PopRegisters(code, ABI_CALLER_SAVE & ~(1ull << Qresult.index()), stack_size); ABI_PopRegisters(code, ABI_CALLER_SAVE & ~(1ull << Qresult.index()), stack_size);
} }
template<size_t fpcr_controlled_arg_index = 1, typename Lambda> template<std::size_t fpcr_controlled_arg_index = 1, typename Lambda>
static void EmitTwoOpFallback(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) { static void EmitTwoOpFallback(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst, Lambda lambda) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qarg1 = ctx.reg_alloc.ReadQ(args[0]); auto Qarg1 = ctx.reg_alloc.ReadQ(args[0]);
@ -562,7 +562,7 @@ void EmitIR<IR::Opcode::FPVectorRecipStepFused64>(oaknut::CodeGenerator& code, E
/// TODO: we have space for a 5th parameter? :) /// TODO: we have space for a 5th parameter? :)
template<typename FPT, FP::RoundingMode rounding_mode, bool exact> template<typename FPT, FP::RoundingMode rounding_mode, bool exact>
static void EmitIRVectorRoundInt16Thunk(VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) { static void EmitIRVectorRoundInt16Thunk(VectorArray<FPT>& output, const VectorArray<FPT>& input, FP::FPCR fpcr, FP::FPSR& fpsr) {
for (size_t i = 0; i < output.size(); ++i) for (std::size_t i = 0; i < output.size(); ++i)
output[i] = FPT(FP::FPRoundInt<FPT>(input[i], fpcr, rounding_mode, exact, fpsr)); output[i] = FPT(FP::FPRoundInt<FPT>(input[i], fpcr, rounding_mode, exact, fpsr));
} }

View file

@ -23,7 +23,7 @@ namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util; using namespace oaknut::util;
template<size_t size, typename EmitFn> template<std::size_t size, typename EmitFn>
static void Emit(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) { static void Emit(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst, EmitFn emit) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto Qresult = ctx.reg_alloc.WriteQ(inst); auto Qresult = ctx.reg_alloc.WriteQ(inst);

View file

@ -29,7 +29,7 @@ void ExclusiveMonitor::Unlock() {
lock.Unlock(); lock.Unlock();
} }
bool ExclusiveMonitor::CheckAndClear(size_t processor_id, VAddr address) { bool ExclusiveMonitor::CheckAndClear(std::size_t processor_id, VAddr address) {
const VAddr masked_address = address & RESERVATION_GRANULE_MASK; const VAddr masked_address = address & RESERVATION_GRANULE_MASK;
Lock(); Lock();
@ -52,7 +52,7 @@ void ExclusiveMonitor::Clear() {
Unlock(); Unlock();
} }
void ExclusiveMonitor::ClearProcessor(size_t processor_id) { void ExclusiveMonitor::ClearProcessor(std::size_t processor_id) {
Lock(); Lock();
exclusive_addresses[processor_id] = INVALID_EXCLUSIVE_ADDRESS; exclusive_addresses[processor_id] = INVALID_EXCLUSIVE_ADDRESS;
Unlock(); Unlock();

View file

@ -21,7 +21,7 @@ namespace Dynarmic::Backend::Arm64 {
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>; using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
constexpr size_t xmrx(size_t x) noexcept { constexpr std::size_t xmrx(std::size_t x) noexcept {
x ^= x >> 32; x ^= x >> 32;
x *= 0xff51afd7ed558ccd; x *= 0xff51afd7ed558ccd;
x ^= mcl::bit::rotate_right(x, 47) ^ mcl::bit::rotate_right(x, 23); x ^= mcl::bit::rotate_right(x, 47) ^ mcl::bit::rotate_right(x, 23);
@ -29,7 +29,7 @@ constexpr size_t xmrx(size_t x) noexcept {
} }
struct DoNotFastmemMarkerHash { struct DoNotFastmemMarkerHash {
[[nodiscard]] size_t operator()(const DoNotFastmemMarker& value) const noexcept { [[nodiscard]] std::size_t operator()(const DoNotFastmemMarker& value) const noexcept {
return xmrx(std::get<0>(value).Value() ^ u64(std::get<1>(value))); return xmrx(std::get<0>(value).Value() ^ u64(std::get<1>(value)));
} }
}; };

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage * Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
@ -13,7 +16,7 @@ namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util; using namespace oaknut::util;
FpsrManager::FpsrManager(oaknut::CodeGenerator& code, size_t state_fpsr_offset) FpsrManager::FpsrManager(oaknut::CodeGenerator& code, std::size_t state_fpsr_offset)
: code{code}, state_fpsr_offset{state_fpsr_offset} {} : code{code}, state_fpsr_offset{state_fpsr_offset} {}
void FpsrManager::Spill() { void FpsrManager::Spill() {

View file

@ -27,8 +27,8 @@ namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util; using namespace oaknut::util;
constexpr size_t spill_offset = offsetof(StackLayout, spill); constexpr std::size_t spill_offset = offsetof(StackLayout, spill);
constexpr size_t spill_slot_size = sizeof(decltype(StackLayout::spill)::value_type); constexpr std::size_t spill_slot_size = sizeof(decltype(StackLayout::spill)::value_type);
static bool IsValuelessType(IR::Type type) { static bool IsValuelessType(IR::Type type) {
switch (type) { switch (type) {
@ -131,7 +131,7 @@ void HostLocInfo::UpdateUses() {
RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) { RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
ArgumentInfo ret = {Argument{}, Argument{}, Argument{}, Argument{}}; ArgumentInfo ret = {Argument{}, Argument{}, Argument{}, Argument{}};
for (size_t i = 0; i < inst->NumArgs(); i++) { for (std::size_t i = 0; i < inst->NumArgs(); i++) {
const IR::Value arg = inst->GetArg(i); const IR::Value arg = inst->GetArg(i);
ret[i].value = arg; ret[i].value = arg;
if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) { if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
@ -245,7 +245,7 @@ void RegAlloc::AssertNoMoreUses() const {
void RegAlloc::EmitVerboseDebuggingOutput() { void RegAlloc::EmitVerboseDebuggingOutput() {
code.MOV(X19, std::bit_cast<u64>(&PrintVerboseDebuggingOutputLine)); // Non-volatile register code.MOV(X19, std::bit_cast<u64>(&PrintVerboseDebuggingOutputLine)); // Non-volatile register
const auto do_location = [&](HostLocInfo& info, HostLocType type, size_t index) { const auto do_location = [&](HostLocInfo& info, HostLocType type, std::size_t index) {
using namespace oaknut::util; using namespace oaknut::util;
for (const IR::Inst* value : info.values) { for (const IR::Inst* value : info.values) {
code.MOV(X0, SP); code.MOV(X0, SP);
@ -257,14 +257,14 @@ void RegAlloc::EmitVerboseDebuggingOutput() {
} }
}; };
for (size_t i = 0; i < gprs.size(); i++) { for (std::size_t i = 0; i < gprs.size(); i++) {
do_location(gprs[i], HostLocType::X, i); do_location(gprs[i], HostLocType::X, i);
} }
for (size_t i = 0; i < fprs.size(); i++) { for (std::size_t i = 0; i < fprs.size(); i++) {
do_location(fprs[i], HostLocType::Q, i); do_location(fprs[i], HostLocType::Q, i);
} }
do_location(flags, HostLocType::Nzcv, 0); do_location(flags, HostLocType::Nzcv, 0);
for (size_t i = 0; i < spills.size(); i++) { for (std::size_t i = 0; i < spills.size(); i++) {
do_location(spills[i], HostLocType::Spill, i); do_location(spills[i], HostLocType::Spill, i);
} }
} }
@ -576,13 +576,13 @@ std::optional<HostLoc> RegAlloc::ValueLocation(const IR::Inst* value) const {
HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) { HostLocInfo& RegAlloc::ValueInfo(HostLoc host_loc) {
switch (host_loc.kind) { switch (host_loc.kind) {
case HostLoc::Kind::Gpr: case HostLoc::Kind::Gpr:
return gprs[static_cast<size_t>(host_loc.index)]; return gprs[static_cast<std::size_t>(host_loc.index)];
case HostLoc::Kind::Fpr: case HostLoc::Kind::Fpr:
return fprs[static_cast<size_t>(host_loc.index)]; return fprs[static_cast<std::size_t>(host_loc.index)];
case HostLoc::Kind::Flags: case HostLoc::Kind::Flags:
return flags; return flags;
case HostLoc::Kind::Spill: case HostLoc::Kind::Spill:
return spills[static_cast<size_t>(host_loc.index)]; return spills[static_cast<std::size_t>(host_loc.index)];
} }
UNREACHABLE(); UNREACHABLE();
} }

View file

@ -141,11 +141,11 @@ private:
struct HostLocInfo final { struct HostLocInfo final {
std::vector<const IR::Inst*> values; std::vector<const IR::Inst*> values;
size_t locked = 0; std::size_t locked = 0;
bool realized = false; bool realized = false;
size_t uses_this_inst = 0; std::size_t uses_this_inst = 0;
size_t accumulated_uses = 0; std::size_t accumulated_uses = 0;
size_t expected_uses = 0; std::size_t expected_uses = 0;
bool Contains(const IR::Inst*) const; bool Contains(const IR::Inst*) const;
void SetupScratchLocation(); void SetupScratchLocation();
@ -179,7 +179,7 @@ public:
auto ReadH(Argument& arg) { return RAReg<oaknut::HReg>{*this, RWType::Read, arg.value, nullptr}; } auto ReadH(Argument& arg) { return RAReg<oaknut::HReg>{*this, RWType::Read, arg.value, nullptr}; }
auto ReadB(Argument& arg) { return RAReg<oaknut::BReg>{*this, RWType::Read, arg.value, nullptr}; } auto ReadB(Argument& arg) { return RAReg<oaknut::BReg>{*this, RWType::Read, arg.value, nullptr}; }
template<size_t size> template<std::size_t size>
auto ReadReg(Argument& arg) { auto ReadReg(Argument& arg) {
if constexpr (size == 64) { if constexpr (size == 64) {
return ReadX(arg); return ReadX(arg);
@ -190,7 +190,7 @@ public:
} }
} }
template<size_t size> template<std::size_t size>
auto ReadVec(Argument& arg) { auto ReadVec(Argument& arg) {
if constexpr (size == 128) { if constexpr (size == 128) {
return ReadQ(arg); return ReadQ(arg);
@ -218,7 +218,7 @@ public:
auto WriteFlags(IR::Inst* inst) { return RAReg<FlagsTag>{*this, RWType::Write, {}, inst}; } auto WriteFlags(IR::Inst* inst) { return RAReg<FlagsTag>{*this, RWType::Write, {}, inst}; }
template<size_t size> template<std::size_t size>
auto WriteReg(IR::Inst* inst) { auto WriteReg(IR::Inst* inst) {
if constexpr (size == 64) { if constexpr (size == 64) {
return WriteX(inst); return WriteX(inst);
@ -229,7 +229,7 @@ public:
} }
} }
template<size_t size> template<std::size_t size>
auto WriteVec(IR::Inst* inst) { auto WriteVec(IR::Inst* inst) {
if constexpr (size == 128) { if constexpr (size == 128) {
return WriteQ(inst); return WriteQ(inst);
@ -255,7 +255,7 @@ public:
auto ReadWriteH(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::HReg>{*this, RWType::ReadWrite, arg.value, inst}; } auto ReadWriteH(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::HReg>{*this, RWType::ReadWrite, arg.value, inst}; }
auto ReadWriteB(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::BReg>{*this, RWType::ReadWrite, arg.value, inst}; } auto ReadWriteB(Argument& arg, const IR::Inst* inst) { return RAReg<oaknut::BReg>{*this, RWType::ReadWrite, arg.value, inst}; }
template<size_t size> template<std::size_t size>
auto ReadWriteReg(Argument& arg, const IR::Inst* inst) { auto ReadWriteReg(Argument& arg, const IR::Inst* inst) {
if constexpr (size == 64) { if constexpr (size == 64) {
return ReadWriteX(arg, inst); return ReadWriteX(arg, inst);
@ -266,7 +266,7 @@ public:
} }
} }
template<size_t size> template<std::size_t size>
auto ReadWriteVec(Argument& arg, const IR::Inst* inst) { auto ReadWriteVec(Argument& arg, const IR::Inst* inst) {
if constexpr (size == 128) { if constexpr (size == 128) {
return ReadWriteQ(arg, inst); return ReadWriteQ(arg, inst);
@ -335,7 +335,7 @@ private:
HostLocInfo flags; HostLocInfo flags;
std::array<HostLocInfo, SpillCount> spills; std::array<HostLocInfo, SpillCount> spills;
mutable size_t alloc_candidate_index = 0; mutable std::size_t alloc_candidate_index = 0;
ankerl::unordered_dense::set<const IR::Inst*> defined_insts; ankerl::unordered_dense::set<const IR::Inst*> defined_insts;
}; };

View file

@ -19,14 +19,14 @@ namespace Dynarmic::Backend::Arm64 {
# pragma warning(disable : 4324) // Structure was padded due to alignment specifier # pragma warning(disable : 4324) // Structure was padded due to alignment specifier
#endif #endif
constexpr size_t SpillCount = 64; constexpr std::size_t SpillCount = 64;
struct alignas(16) RSBEntry { struct alignas(16) RSBEntry {
u64 target; u64 target;
u64 code_ptr; u64 code_ptr;
}; };
constexpr size_t RSBCount = 8; constexpr std::size_t RSBCount = 8;
constexpr u64 RSBIndexMask = (RSBCount - 1) * sizeof(RSBEntry); constexpr u64 RSBIndexMask = (RSBCount - 1) * sizeof(RSBEntry);
struct alignas(16) StackLayout { struct alignas(16) StackLayout {

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
* Copyright (c) 2023 MerryMage * Copyright (c) 2023 MerryMage
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
@ -51,7 +54,7 @@ void EmitVerboseDebuggingOutput(oaknut::CodeGenerator& code, EmitContext& ctx) {
code.ADD(SP, SP, sizeof(RegisterData)); code.ADD(SP, SP, sizeof(RegisterData));
} }
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, size_t reg_index, size_t inst_index, IR::Type inst_type) { void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, std::size_t reg_index, std::size_t inst_index, IR::Type inst_type) {
fmt::print("dynarmic debug: %{:05} = ", inst_index); fmt::print("dynarmic debug: %{:05} = ", inst_index);
Vector value = [&]() -> Vector { Vector value = [&]() -> Vector {

View file

@ -54,6 +54,6 @@ struct alignas(16) RegisterData {
#endif #endif
void EmitVerboseDebuggingOutput(oaknut::CodeGenerator& code, EmitContext& ctx); void EmitVerboseDebuggingOutput(oaknut::CodeGenerator& code, EmitContext& ctx);
void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, size_t reg_index, size_t inst_index, IR::Type inst_type); void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLocType reg_type, std::size_t reg_index, std::size_t inst_index, IR::Type inst_type);
} // namespace Dynarmic::Backend::Arm64 } // namespace Dynarmic::Backend::Arm64