mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 05:28:56 +02:00
boost::stable_Vector evil
This commit is contained in:
parent
f4fa122eab
commit
87ed964b6f
12 changed files with 91 additions and 84 deletions
|
|
@ -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.
|
||||||
|
|
@ -133,7 +133,7 @@ void EmitIR<IR::Opcode::LeastSignificantByte>(oaknut::CodeGenerator& code, EmitC
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::MostSignificantWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::MostSignificantWord>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
|
@ -242,7 +242,7 @@ void EmitIR<IR::Opcode::ConditionalSelectNZCV>(oaknut::CodeGenerator& code, Emit
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftLeft32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::LogicalShiftLeft32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -379,7 +379,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft64>(oaknut::CodeGenerator& code, EmitCon
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::LogicalShiftRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -517,7 +517,7 @@ void EmitIR<IR::Opcode::LogicalShiftRight64>(oaknut::CodeGenerator& code, EmitCo
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::ArithmeticShiftRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::ArithmeticShiftRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -643,7 +643,7 @@ void EmitIR<IR::Opcode::ArithmeticShiftRight64>(oaknut::CodeGenerator& code, Emi
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::RotateRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::RotateRight32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -730,7 +730,7 @@ void EmitIR<IR::Opcode::RotateRight64>(oaknut::CodeGenerator& code, EmitContext&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::RotateRightExtended>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::RotateRightExtended>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Wresult = ctx.reg_alloc.WriteW(inst);
|
auto Wresult = ctx.reg_alloc.WriteW(inst);
|
||||||
|
|
@ -884,8 +884,8 @@ static void MaybeAddSubImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn)
|
||||||
|
|
||||||
template<size_t bitsize, bool sub>
|
template<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(ctx.block, IR::Opcode::GetNZCVFromOp);
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
|
@ -1133,8 +1133,8 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
|
||||||
auto Ra = ctx.reg_alloc.ReadReg<bitsize>(args[0]);
|
auto Ra = ctx.reg_alloc.ReadReg<bitsize>(args[0]);
|
||||||
|
|
||||||
if constexpr (!std::is_same_v<EmitFn2, std::nullptr_t>) {
|
if constexpr (!std::is_same_v<EmitFn2, std::nullptr_t>) {
|
||||||
const auto nz_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZFromOp);
|
const auto nz_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZFromOp);
|
||||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp);
|
||||||
ASSERT(!(nz_inst && nzcv_inst));
|
ASSERT(!(nz_inst && nzcv_inst));
|
||||||
const auto flag_inst = nz_inst ? nz_inst : nzcv_inst;
|
const auto flag_inst = nz_inst ? nz_inst : nzcv_inst;
|
||||||
|
|
||||||
|
|
@ -1170,8 +1170,8 @@ static void EmitBitOp(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* i
|
||||||
|
|
||||||
template<size_t bitsize>
|
template<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(ctx.block, IR::Opcode::GetNZFromOp);
|
||||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp);
|
||||||
ASSERT(!(nz_inst && nzcv_inst));
|
ASSERT(!(nz_inst && nzcv_inst));
|
||||||
const auto flag_inst = nz_inst ? nz_inst : nzcv_inst;
|
const auto flag_inst = nz_inst ? nz_inst : nzcv_inst;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -46,7 +49,7 @@ static void EmitSaturatedPackedOp(oaknut::CodeGenerator&, EmitContext& ctx, IR::
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddU8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::PackedAddU8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
@ -66,7 +69,7 @@ void EmitIR<IR::Opcode::PackedAddU8>(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddS8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::PackedAddS8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
@ -87,7 +90,7 @@ void EmitIR<IR::Opcode::PackedAddS8>(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubU8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::PackedSubU8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
@ -108,7 +111,7 @@ void EmitIR<IR::Opcode::PackedSubU8>(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubS8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::PackedSubS8>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
@ -129,7 +132,7 @@ void EmitIR<IR::Opcode::PackedSubS8>(oaknut::CodeGenerator& code, EmitContext& c
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddU16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::PackedAddU16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
@ -149,7 +152,7 @@ void EmitIR<IR::Opcode::PackedAddU16>(oaknut::CodeGenerator& code, EmitContext&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedAddS16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::PackedAddS16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
@ -170,7 +173,7 @@ void EmitIR<IR::Opcode::PackedAddS16>(oaknut::CodeGenerator& code, EmitContext&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubU16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::PackedSubU16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
@ -191,7 +194,7 @@ void EmitIR<IR::Opcode::PackedSubU16>(oaknut::CodeGenerator& code, EmitContext&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::PackedSubS16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::PackedSubS16>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
@ -212,7 +215,7 @@ void EmitIR<IR::Opcode::PackedSubS16>(oaknut::CodeGenerator& code, EmitContext&
|
||||||
|
|
||||||
template<bool add_is_hi, bool is_signed, bool is_halving>
|
template<bool add_is_hi, bool is_signed, bool is_halving>
|
||||||
static void EmitPackedAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitPackedAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
auto Vresult = ctx.reg_alloc.WriteD(inst);
|
||||||
|
|
|
||||||
|
|
@ -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 @@ using namespace oaknut::util;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp);
|
||||||
ASSERT(overflow_inst);
|
ASSERT(overflow_inst);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
@ -43,7 +43,7 @@ void EmitIR<IR::Opcode::SignedSaturatedAddWithFlag32>(oaknut::CodeGenerator& cod
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp);
|
||||||
ASSERT(overflow_inst);
|
ASSERT(overflow_inst);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
@ -63,7 +63,7 @@ void EmitIR<IR::Opcode::SignedSaturatedSubWithFlag32>(oaknut::CodeGenerator& cod
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::SignedSaturation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::SignedSaturation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, 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 size_t N = args[1].GetImmediateU8();
|
||||||
|
|
@ -104,7 +104,7 @@ void EmitIR<IR::Opcode::SignedSaturation>(oaknut::CodeGenerator& code, EmitConte
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::UnsignedSaturation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::UnsignedSaturation>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto Wresult = ctx.reg_alloc.WriteW(inst);
|
auto Wresult = ctx.reg_alloc.WriteW(inst);
|
||||||
|
|
|
||||||
|
|
@ -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) 2024 MerryMage
|
* Copyright (c) 2024 MerryMage
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
|
@ -84,7 +87,7 @@ void EmitIR<IR::Opcode::ConditionalSelectNZCV>(biscuit::Assembler&, EmitContext&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::LogicalShiftLeft32>(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -126,7 +129,7 @@ void EmitIR<IR::Opcode::LogicalShiftLeft64>(biscuit::Assembler&, EmitContext&, I
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::LogicalShiftRight32>(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::LogicalShiftRight32>(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -267,8 +270,8 @@ static void AddImmWithFlags(biscuit::Assembler& as, biscuit::GPR rd, biscuit::GP
|
||||||
|
|
||||||
template<size_t bitsize, bool sub>
|
template<size_t bitsize, bool sub>
|
||||||
static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitAddSub(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp);
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ void EmitX64::EmitLeastSignificantWord(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitMostSignificantWord(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitMostSignificantWord(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Reg64 result = ctx.reg_alloc.UseScratchGpr(code, args[0]);
|
const Xbyak::Reg64 result = ctx.reg_alloc.UseScratchGpr(code, args[0]);
|
||||||
|
|
@ -265,7 +265,7 @@ void EmitX64::EmitReplicateBit64(Dynarmic::Backend::X64::EmitContext& ctx, IR::I
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitLogicalShiftLeft32(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitLogicalShiftLeft32(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -401,7 +401,7 @@ void EmitX64::EmitLogicalShiftLeft64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitLogicalShiftRight32(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitLogicalShiftRight32(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -535,7 +535,7 @@ void EmitX64::EmitLogicalShiftRight64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitArithmeticShiftRight32(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitArithmeticShiftRight32(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -664,7 +664,7 @@ void EmitX64::EmitArithmeticShiftRight64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitRotateRight32(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitRotateRight32(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& operand_arg = args[0];
|
auto& operand_arg = args[0];
|
||||||
|
|
@ -768,7 +768,7 @@ void EmitX64::EmitRotateRight64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitRotateRightExtended(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitRotateRightExtended(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Reg32 result = ctx.reg_alloc.UseScratchGpr(code, args[0]).cvt32();
|
const Xbyak::Reg32 result = ctx.reg_alloc.UseScratchGpr(code, args[0]).cvt32();
|
||||||
|
|
@ -919,9 +919,9 @@ static Xbyak::Reg64 DoNZCV(BlockOfCode& code, RegAlloc& reg_alloc, IR::Inst* nzc
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, size_t bitsize) {
|
static void EmitAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, size_t bitsize) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp);
|
||||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& carry_in = args[2];
|
auto& carry_in = args[2];
|
||||||
|
|
@ -1006,9 +1006,9 @@ void EmitX64::EmitAdd64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitSub(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bitsize) {
|
static void EmitSub(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bitsize) {
|
||||||
const auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp);
|
const auto carry_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetCarryFromOp);
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp);
|
||||||
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp);
|
const auto nzcv_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetNZCVFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto& carry_in = args[2];
|
auto& carry_in = args[2];
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -17,7 +17,7 @@ using namespace Xbyak::util;
|
||||||
|
|
||||||
void EmitX64::EmitPackedAddU8(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitPackedAddU8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||||
|
|
@ -43,7 +43,7 @@ void EmitX64::EmitPackedAddU8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
void EmitX64::EmitPackedAddS8(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitPackedAddS8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||||
|
|
@ -67,7 +67,7 @@ void EmitX64::EmitPackedAddS8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
void EmitX64::EmitPackedAddU16(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitPackedAddU16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||||
|
|
@ -107,7 +107,7 @@ void EmitX64::EmitPackedAddU16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
void EmitX64::EmitPackedAddS16(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitPackedAddS16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||||
|
|
@ -131,7 +131,7 @@ void EmitX64::EmitPackedAddS16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
void EmitX64::EmitPackedSubU8(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitPackedSubU8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||||
|
|
@ -153,7 +153,7 @@ void EmitX64::EmitPackedSubU8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
void EmitX64::EmitPackedSubS8(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitPackedSubS8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||||
|
|
@ -177,7 +177,7 @@ void EmitX64::EmitPackedSubS8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
void EmitX64::EmitPackedSubU16(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitPackedSubU16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
if (!ge_inst) {
|
if (!ge_inst) {
|
||||||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
|
|
@ -226,7 +226,7 @@ void EmitX64::EmitPackedSubU16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
void EmitX64::EmitPackedSubS16(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitPackedSubS16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
const Xbyak::Xmm xmm_a = ctx.reg_alloc.UseScratchXmm(code, args[0]);
|
||||||
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
const Xbyak::Xmm xmm_b = ctx.reg_alloc.UseXmm(code, args[1]);
|
||||||
|
|
@ -493,7 +493,7 @@ void EmitX64::EmitPackedHalvingSubS16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
static void EmitPackedSubAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, bool hi_is_sum, bool is_signed, bool is_halving) {
|
static void EmitPackedSubAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, bool hi_is_sum, bool is_signed, bool is_halving) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp);
|
const auto ge_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetGEFromOp);
|
||||||
|
|
||||||
const Xbyak::Reg32 reg_a_hi = ctx.reg_alloc.UseScratchGpr(code, args[0]).cvt32();
|
const Xbyak::Reg32 reg_a_hi = ctx.reg_alloc.UseScratchGpr(code, args[0]).cvt32();
|
||||||
const Xbyak::Reg32 reg_b_hi = ctx.reg_alloc.UseScratchGpr(code, args[1]).cvt32();
|
const Xbyak::Reg32 reg_b_hi = ctx.reg_alloc.UseScratchGpr(code, args[1]).cvt32();
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
|
||||||
|
|
||||||
code.seto(overflow.cvt8());
|
code.seto(overflow.cvt8());
|
||||||
if constexpr (has_overflow_inst) {
|
if constexpr (has_overflow_inst) {
|
||||||
if (const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)) {
|
if (const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetOverflowFromOp)) {
|
||||||
ctx.reg_alloc.DefineValue(code, overflow_inst, overflow);
|
ctx.reg_alloc.DefineValue(code, overflow_inst, overflow);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -114,7 +114,7 @@ void EmitX64::EmitSignedSaturatedSubWithFlag32(EmitContext& ctx, IR::Inst* inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, 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 size_t N = args[1].GetImmediateU8();
|
||||||
|
|
@ -163,7 +163,7 @@ void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitUnsignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitUnsignedSaturation(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
const auto overflow_inst = inst->GetAssociatedPseudoOperation(ctx.block, 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 size_t N = args[1].GetImmediateU8();
|
||||||
|
|
|
||||||
|
|
@ -3910,8 +3910,8 @@ void EmitX64::EmitVectorSignedAbsoluteDifference32(EmitContext& ctx, IR::Inst* i
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorSignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorSignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto upper_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetUpperFromOp);
|
const auto upper_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetUpperFromOp);
|
||||||
const auto lower_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetLowerFromOp);
|
const auto lower_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetLowerFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm x = ctx.reg_alloc.UseXmm(code, args[0]);
|
const Xbyak::Xmm x = ctx.reg_alloc.UseXmm(code, args[0]);
|
||||||
|
|
@ -3942,8 +3942,8 @@ void EmitX64::EmitVectorSignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorSignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorSignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto upper_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetUpperFromOp);
|
const auto upper_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetUpperFromOp);
|
||||||
const auto lower_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetLowerFromOp);
|
const auto lower_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetLowerFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
|
@ -5508,8 +5508,8 @@ void EmitX64::EmitVectorUnsignedAbsoluteDifference32(EmitContext& ctx, IR::Inst*
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorUnsignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorUnsignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto upper_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetUpperFromOp);
|
const auto upper_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetUpperFromOp);
|
||||||
const auto lower_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetLowerFromOp);
|
const auto lower_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetLowerFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const Xbyak::Xmm x = ctx.reg_alloc.UseXmm(code, args[0]);
|
const Xbyak::Xmm x = ctx.reg_alloc.UseXmm(code, args[0]);
|
||||||
|
|
@ -5540,8 +5540,8 @@ void EmitX64::EmitVectorUnsignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorUnsignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorUnsignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
|
||||||
const auto upper_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetUpperFromOp);
|
const auto upper_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetUpperFromOp);
|
||||||
const auto lower_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetLowerFromOp);
|
const auto lower_inst = inst->GetAssociatedPseudoOperation(ctx.block, IR::Opcode::GetLowerFromOp);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ enum class Opcode;
|
||||||
/// order memory accesses.
|
/// order memory accesses.
|
||||||
class Block final {
|
class Block final {
|
||||||
public:
|
public:
|
||||||
using instruction_list_type = std::list<Inst>;
|
using instruction_list_type = boost::container::stable_vector<Inst>;
|
||||||
using iterator = instruction_list_type::iterator;
|
using iterator = instruction_list_type::iterator;
|
||||||
using const_iterator = instruction_list_type::const_iterator;
|
using const_iterator = instruction_list_type::const_iterator;
|
||||||
using reverse_iterator = instruction_list_type::reverse_iterator;
|
using reverse_iterator = instruction_list_type::reverse_iterator;
|
||||||
|
|
|
||||||
|
|
@ -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 @@ bool Inst::AreAllArgsImmediates() const {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Inst* Inst::GetAssociatedPseudoOperation(Opcode opcode) {
|
Inst* Inst::GetAssociatedPseudoOperation(Block& block, Opcode opcode) {
|
||||||
Inst* pseudoop = next_pseudoop;
|
Inst* pseudoop = next_pseudoop;
|
||||||
while (pseudoop) {
|
while (pseudoop) {
|
||||||
if (pseudoop->GetOpcode() == opcode) {
|
if (pseudoop->GetOpcode() == opcode) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ namespace Dynarmic::IR {
|
||||||
|
|
||||||
enum class Opcode;
|
enum class Opcode;
|
||||||
enum class Type : u16;
|
enum class Type : u16;
|
||||||
|
class Block;
|
||||||
|
|
||||||
constexpr size_t max_arg_count = 4;
|
constexpr size_t max_arg_count = 4;
|
||||||
|
|
||||||
|
|
@ -38,7 +39,7 @@ public:
|
||||||
return next_pseudoop && !IsAPseudoOperation(op);
|
return next_pseudoop && !IsAPseudoOperation(op);
|
||||||
}
|
}
|
||||||
/// Gets a pseudo-operation associated with this instruction.
|
/// Gets a pseudo-operation associated with this instruction.
|
||||||
Inst* GetAssociatedPseudoOperation(Opcode opcode);
|
Inst* GetAssociatedPseudoOperation(Block& block, Opcode opcode);
|
||||||
|
|
||||||
/// Get the microop this microinstruction represents.
|
/// Get the microop this microinstruction represents.
|
||||||
Opcode GetOpcode() const { return op; }
|
Opcode GetOpcode() const { return op; }
|
||||||
|
|
@ -76,12 +77,12 @@ public:
|
||||||
|
|
||||||
// TODO: so much padding wasted with mcl::intrusive_node
|
// TODO: so much padding wasted with mcl::intrusive_node
|
||||||
// 16 + 1, 24
|
// 16 + 1, 24
|
||||||
Opcode op; //2 (6)
|
std::array<Value, max_arg_count> args; //16 * 4 = 64 (1 cache line)
|
||||||
// Linked list of pseudooperations associated with this instruction.
|
// Linked list of pseudooperations associated with this instruction.
|
||||||
Inst* next_pseudoop = nullptr; //8 (14)
|
Inst* next_pseudoop = nullptr; //8 (14)
|
||||||
unsigned use_count = 0; //4 (0)
|
unsigned use_count = 0; //4 (0)
|
||||||
unsigned name = 0; //4 (4)
|
unsigned name = 0; //4 (4)
|
||||||
alignas(64) std::array<Value, max_arg_count> args; //16 * 4 = 64 (1 cache line)
|
Opcode op; //2 (6)
|
||||||
};
|
};
|
||||||
//static_assert(sizeof(Inst) == 128);
|
//static_assert(sizeof(Inst) == 128);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -868,8 +868,8 @@ static void FoldMostSignificantBit(IR::Inst& inst) {
|
||||||
inst.ReplaceUsesWith(IR::Value{(operand.GetImmediateAsU64() >> 31) != 0});
|
inst.ReplaceUsesWith(IR::Value{(operand.GetImmediateAsU64() >> 31) != 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FoldMostSignificantWord(IR::Inst& inst) {
|
static void FoldMostSignificantWord(IR::Block& block, IR::Inst& inst) {
|
||||||
IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(Op::GetCarryFromOp);
|
IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(block, Op::GetCarryFromOp);
|
||||||
|
|
||||||
if (!inst.AreAllArgsImmediates()) {
|
if (!inst.AreAllArgsImmediates()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -928,8 +928,8 @@ static void FoldOR(IR::Inst& inst, bool is_32_bit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool FoldShifts(IR::Inst& inst) {
|
static bool FoldShifts(IR::Block& block, IR::Inst& inst) {
|
||||||
IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(Op::GetCarryFromOp);
|
IR::Inst* carry_inst = inst.GetAssociatedPseudoOperation(block, Op::GetCarryFromOp);
|
||||||
|
|
||||||
// The 32-bit variants can contain 3 arguments, while the
|
// The 32-bit variants can contain 3 arguments, while the
|
||||||
// 64-bit variants only contain 2.
|
// 64-bit variants only contain 2.
|
||||||
|
|
@ -1013,14 +1013,14 @@ static void ConstantPropagation(IR::Block& block) {
|
||||||
// skip NZCV so we dont end up discarding side effects :)
|
// skip NZCV so we dont end up discarding side effects :)
|
||||||
// TODO(lizzie): hey stupid maybe fix the A64 codegen for folded constants AND
|
// TODO(lizzie): hey stupid maybe fix the A64 codegen for folded constants AND
|
||||||
// redirect the mfer properly?!??! just saying :)
|
// redirect the mfer properly?!??! just saying :)
|
||||||
if (IR::MayGetNZCVFromOp(opcode) && inst.GetAssociatedPseudoOperation(IR::Opcode::GetNZCVFromOp))
|
if (IR::MayGetNZCVFromOp(opcode) && inst.GetAssociatedPseudoOperation(block, IR::Opcode::GetNZCVFromOp))
|
||||||
continue;
|
continue;
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case Op::LeastSignificantWord:
|
case Op::LeastSignificantWord:
|
||||||
FoldLeastSignificantWord(inst);
|
FoldLeastSignificantWord(inst);
|
||||||
break;
|
break;
|
||||||
case Op::MostSignificantWord:
|
case Op::MostSignificantWord:
|
||||||
FoldMostSignificantWord(inst);
|
FoldMostSignificantWord(block, inst);
|
||||||
break;
|
break;
|
||||||
case Op::LeastSignificantHalf:
|
case Op::LeastSignificantHalf:
|
||||||
FoldLeastSignificantHalf(inst);
|
FoldLeastSignificantHalf(inst);
|
||||||
|
|
@ -1042,42 +1042,42 @@ static void ConstantPropagation(IR::Block& block) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Op::LogicalShiftLeft32:
|
case Op::LogicalShiftLeft32:
|
||||||
if (FoldShifts(inst)) {
|
if (FoldShifts(block, inst)) {
|
||||||
ReplaceUsesWith(inst, true, Safe::LogicalShiftLeft<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
ReplaceUsesWith(inst, true, Safe::LogicalShiftLeft<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Op::LogicalShiftLeft64:
|
case Op::LogicalShiftLeft64:
|
||||||
if (FoldShifts(inst)) {
|
if (FoldShifts(block, inst)) {
|
||||||
ReplaceUsesWith(inst, false, Safe::LogicalShiftLeft<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
ReplaceUsesWith(inst, false, Safe::LogicalShiftLeft<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Op::LogicalShiftRight32:
|
case Op::LogicalShiftRight32:
|
||||||
if (FoldShifts(inst)) {
|
if (FoldShifts(block, inst)) {
|
||||||
ReplaceUsesWith(inst, true, Safe::LogicalShiftRight<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
ReplaceUsesWith(inst, true, Safe::LogicalShiftRight<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Op::LogicalShiftRight64:
|
case Op::LogicalShiftRight64:
|
||||||
if (FoldShifts(inst)) {
|
if (FoldShifts(block, inst)) {
|
||||||
ReplaceUsesWith(inst, false, Safe::LogicalShiftRight<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
ReplaceUsesWith(inst, false, Safe::LogicalShiftRight<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Op::ArithmeticShiftRight32:
|
case Op::ArithmeticShiftRight32:
|
||||||
if (FoldShifts(inst)) {
|
if (FoldShifts(block, inst)) {
|
||||||
ReplaceUsesWith(inst, true, Safe::ArithmeticShiftRight<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
ReplaceUsesWith(inst, true, Safe::ArithmeticShiftRight<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Op::ArithmeticShiftRight64:
|
case Op::ArithmeticShiftRight64:
|
||||||
if (FoldShifts(inst)) {
|
if (FoldShifts(block, inst)) {
|
||||||
ReplaceUsesWith(inst, false, Safe::ArithmeticShiftRight<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
ReplaceUsesWith(inst, false, Safe::ArithmeticShiftRight<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Op::RotateRight32:
|
case Op::RotateRight32:
|
||||||
if (FoldShifts(inst)) {
|
if (FoldShifts(block, inst)) {
|
||||||
ReplaceUsesWith(inst, true, mcl::bit::rotate_right<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
ReplaceUsesWith(inst, true, mcl::bit::rotate_right<u32>(inst.GetArg(0).GetU32(), inst.GetArg(1).GetU8()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Op::RotateRight64:
|
case Op::RotateRight64:
|
||||||
if (FoldShifts(inst)) {
|
if (FoldShifts(block, inst)) {
|
||||||
ReplaceUsesWith(inst, false, mcl::bit::rotate_right<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
ReplaceUsesWith(inst, false, mcl::bit::rotate_right<u64>(inst.GetArg(0).GetU64(), inst.GetArg(1).GetU8()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue