aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorMerry <[email protected]>2023-01-20 11:47:49 +0000
committerMerry <[email protected]>2023-01-20 11:47:49 +0000
commitf0ebdf278cf59eb90a56a159c374028eef059253 (patch)
treef68a9980b35a8bc38800e06bfa497213c0662d13 /src
parentc0813cf2a50a71e372b6782141e777335ac801d9 (diff)
downloaddynarmic-f0ebdf278cf59eb90a56a159c374028eef059253.tar.gz
dynarmic-f0ebdf278cf59eb90a56a159c374028eef059253.zip
backend/x64: Improve verbose debugging output
Diffstat (limited to 'src')
-rw-r--r--src/dynarmic/backend/x64/a32_emit_x64.cpp2
-rw-r--r--src/dynarmic/backend/x64/a32_interface.cpp1
-rw-r--r--src/dynarmic/backend/x64/a64_emit_x64.cpp2
-rw-r--r--src/dynarmic/backend/x64/emit_x64.cpp34
-rw-r--r--src/dynarmic/backend/x64/emit_x64.h2
-rw-r--r--src/dynarmic/backend/x64/emit_x64_data_processing.cpp16
-rw-r--r--src/dynarmic/backend/x64/emit_x64_packed.cpp11
-rw-r--r--src/dynarmic/backend/x64/emit_x64_saturation.cpp3
-rw-r--r--src/dynarmic/backend/x64/emit_x64_vector.cpp14
-rw-r--r--src/dynarmic/backend/x64/reg_alloc.cpp29
-rw-r--r--src/dynarmic/backend/x64/reg_alloc.h7
-rw-r--r--src/dynarmic/backend/x64/verbose_debugging_output.cpp51
-rw-r--r--src/dynarmic/backend/x64/verbose_debugging_output.h2
13 files changed, 96 insertions, 78 deletions
diff --git a/src/dynarmic/backend/x64/a32_emit_x64.cpp b/src/dynarmic/backend/x64/a32_emit_x64.cpp
index 52c4a15c..0a08e7ef 100644
--- a/src/dynarmic/backend/x64/a32_emit_x64.cpp
+++ b/src/dynarmic/backend/x64/a32_emit_x64.cpp
@@ -148,7 +148,7 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
reg_alloc.EndOfAllocScope();
if (conf.very_verbose_debugging_output) {
- EmitVerboseDebuggingOutput(reg_alloc);
+ EmitVerboseDebuggingOutput(reg_alloc, block);
}
}
diff --git a/src/dynarmic/backend/x64/a32_interface.cpp b/src/dynarmic/backend/x64/a32_interface.cpp
index e671c192..e428672f 100644
--- a/src/dynarmic/backend/x64/a32_interface.cpp
+++ b/src/dynarmic/backend/x64/a32_interface.cpp
@@ -183,6 +183,7 @@ private:
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
}
+ Optimization::IdentityRemovalPass(ir_block);
Optimization::VerificationPass(ir_block);
return emitter.Emit(ir_block);
}
diff --git a/src/dynarmic/backend/x64/a64_emit_x64.cpp b/src/dynarmic/backend/x64/a64_emit_x64.cpp
index dd45049a..3cadcf8c 100644
--- a/src/dynarmic/backend/x64/a64_emit_x64.cpp
+++ b/src/dynarmic/backend/x64/a64_emit_x64.cpp
@@ -119,7 +119,7 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) {
ctx.reg_alloc.EndOfAllocScope();
if (conf.very_verbose_debugging_output) {
- EmitVerboseDebuggingOutput(reg_alloc);
+ EmitVerboseDebuggingOutput(reg_alloc, block);
}
}
diff --git a/src/dynarmic/backend/x64/emit_x64.cpp b/src/dynarmic/backend/x64/emit_x64.cpp
index 22ed7e3d..229c4f18 100644
--- a/src/dynarmic/backend/x64/emit_x64.cpp
+++ b/src/dynarmic/backend/x64/emit_x64.cpp
@@ -103,7 +103,7 @@ void EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, I
code.mov(dword[r15 + code.GetJitStateInfo().offsetof_rsb_ptr], index_reg.cvt32());
}
-void EmitX64::EmitVerboseDebuggingOutput(RegAlloc& reg_alloc) {
+void EmitX64::EmitVerboseDebuggingOutput(RegAlloc& reg_alloc, const IR::Block& block) {
code.sub(rsp, sizeof(RegisterData));
for (int i = 0; i < 16; i++) {
if (rsp.getIdx() == i) {
@@ -117,7 +117,7 @@ void EmitX64::EmitVerboseDebuggingOutput(RegAlloc& reg_alloc) {
code.lea(rax, ptr[rsp + sizeof(RegisterData) + offsetof(StackLayout, spill)]);
code.mov(xword[rsp + offsetof(RegisterData, spill)], rax);
- reg_alloc.EmitVerboseDebuggingOutput();
+ reg_alloc.EmitVerboseDebuggingOutput(block);
for (int i = 0; i < 16; i++) {
if (rsp.getIdx() == i) {
@@ -143,27 +143,32 @@ void EmitX64::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
PushRSBHelper(loc_desc_reg, index_reg, IR::LocationDescriptor{unique_hash_of_target});
}
-void EmitX64::EmitGetCarryFromOp(EmitContext&, IR::Inst*) {
- ASSERT_MSG(false, "should never happen");
+void EmitX64::EmitGetCarryFromOp(EmitContext& ctx, IR::Inst* inst) {
+ ctx.reg_alloc.RegisterPseudoOperation(inst);
}
-void EmitX64::EmitGetOverflowFromOp(EmitContext&, IR::Inst*) {
- ASSERT_MSG(false, "should never happen");
+void EmitX64::EmitGetOverflowFromOp(EmitContext& ctx, IR::Inst* inst) {
+ ctx.reg_alloc.RegisterPseudoOperation(inst);
}
-void EmitX64::EmitGetGEFromOp(EmitContext&, IR::Inst*) {
- ASSERT_MSG(false, "should never happen");
+void EmitX64::EmitGetGEFromOp(EmitContext& ctx, IR::Inst* inst) {
+ ctx.reg_alloc.RegisterPseudoOperation(inst);
}
-void EmitX64::EmitGetUpperFromOp(EmitContext&, IR::Inst*) {
- ASSERT_MSG(false, "should never happen");
+void EmitX64::EmitGetUpperFromOp(EmitContext& ctx, IR::Inst* inst) {
+ ctx.reg_alloc.RegisterPseudoOperation(inst);
}
-void EmitX64::EmitGetLowerFromOp(EmitContext&, IR::Inst*) {
- ASSERT_MSG(false, "should never happen");
+void EmitX64::EmitGetLowerFromOp(EmitContext& ctx, IR::Inst* inst) {
+ ctx.reg_alloc.RegisterPseudoOperation(inst);
}
void EmitX64::EmitGetNZFromOp(EmitContext& ctx, IR::Inst* inst) {
+ if (ctx.reg_alloc.IsValueLive(inst)) {
+ ctx.reg_alloc.RegisterPseudoOperation(inst);
+ return;
+ }
+
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const int bitsize = [&] {
@@ -190,6 +195,11 @@ void EmitX64::EmitGetNZFromOp(EmitContext& ctx, IR::Inst* inst) {
}
void EmitX64::EmitGetNZCVFromOp(EmitContext& ctx, IR::Inst* inst) {
+ if (ctx.reg_alloc.IsValueLive(inst)) {
+ ctx.reg_alloc.RegisterPseudoOperation(inst);
+ return;
+ }
+
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const int bitsize = [&] {
diff --git a/src/dynarmic/backend/x64/emit_x64.h b/src/dynarmic/backend/x64/emit_x64.h
index fcf51a6c..c1921a9a 100644
--- a/src/dynarmic/backend/x64/emit_x64.h
+++ b/src/dynarmic/backend/x64/emit_x64.h
@@ -108,7 +108,7 @@ protected:
BlockDescriptor RegisterBlock(const IR::LocationDescriptor& location_descriptor, CodePtr entrypoint, size_t size);
void PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, IR::LocationDescriptor target);
- void EmitVerboseDebuggingOutput(RegAlloc& reg_alloc);
+ void EmitVerboseDebuggingOutput(RegAlloc& reg_alloc, const IR::Block& block);
// Terminal instruction emitters
void EmitTerminal(IR::Terminal terminal, IR::LocationDescriptor initial_location, bool is_single_step);
diff --git a/src/dynarmic/backend/x64/emit_x64_data_processing.cpp b/src/dynarmic/backend/x64/emit_x64_data_processing.cpp
index 97bbdf52..396d3118 100644
--- a/src/dynarmic/backend/x64/emit_x64_data_processing.cpp
+++ b/src/dynarmic/backend/x64/emit_x64_data_processing.cpp
@@ -71,7 +71,6 @@ void EmitX64::EmitMostSignificantWord(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Reg64 carry = ctx.reg_alloc.ScratchGpr();
code.setc(carry.cvt8());
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
}
ctx.reg_alloc.DefineValue(inst, result);
@@ -332,7 +331,6 @@ void EmitX64::EmitLogicalShiftLeft32(EmitContext& ctx, IR::Inst* inst) {
}
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
ctx.reg_alloc.DefineValue(inst, result);
} else {
ctx.reg_alloc.UseScratch(shift_arg, HostLoc::RCX);
@@ -350,7 +348,6 @@ void EmitX64::EmitLogicalShiftLeft32(EmitContext& ctx, IR::Inst* inst) {
code.shr(result.cvt64(), 32);
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
ctx.reg_alloc.DefineValue(inst, result);
}
}
@@ -469,7 +466,6 @@ void EmitX64::EmitLogicalShiftRight32(EmitContext& ctx, IR::Inst* inst) {
}
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
ctx.reg_alloc.DefineValue(inst, result);
} else {
ctx.reg_alloc.UseScratch(shift_arg, HostLoc::RCX);
@@ -486,7 +482,6 @@ void EmitX64::EmitLogicalShiftRight32(EmitContext& ctx, IR::Inst* inst) {
code.setc(carry.cvt8());
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
ctx.reg_alloc.DefineValue(inst, result);
}
}
@@ -603,7 +598,6 @@ void EmitX64::EmitArithmeticShiftRight32(EmitContext& ctx, IR::Inst* inst) {
}
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
ctx.reg_alloc.DefineValue(inst, result);
} else {
ctx.reg_alloc.UseScratch(shift_arg, HostLoc::RCX);
@@ -620,7 +614,6 @@ void EmitX64::EmitArithmeticShiftRight32(EmitContext& ctx, IR::Inst* inst) {
code.setc(carry.cvt8());
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
ctx.reg_alloc.DefineValue(inst, result);
}
}
@@ -718,7 +711,6 @@ void EmitX64::EmitRotateRight32(EmitContext& ctx, IR::Inst* inst) {
}
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
ctx.reg_alloc.DefineValue(inst, result);
} else {
ctx.reg_alloc.UseScratch(shift_arg, HostLoc::RCX);
@@ -737,7 +729,6 @@ void EmitX64::EmitRotateRight32(EmitContext& ctx, IR::Inst* inst) {
code.L(end);
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
ctx.reg_alloc.DefineValue(inst, result);
}
}
@@ -788,7 +779,6 @@ void EmitX64::EmitRotateRightExtended(EmitContext& ctx, IR::Inst* inst) {
code.setc(carry);
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
}
ctx.reg_alloc.DefineValue(inst, result);
@@ -974,17 +964,14 @@ static void EmitAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bit
code.lahf();
code.seto(code.al);
ctx.reg_alloc.DefineValue(nzcv_inst, nzcv);
- ctx.EraseInstruction(nzcv_inst);
}
if (carry_inst) {
code.setc(carry);
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
}
if (overflow_inst) {
code.seto(overflow);
ctx.reg_alloc.DefineValue(overflow_inst, overflow);
- ctx.EraseInstruction(overflow_inst);
}
ctx.reg_alloc.DefineValue(inst, result);
@@ -1064,7 +1051,6 @@ static void EmitSub(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bit
code.lahf();
code.seto(code.al);
ctx.reg_alloc.DefineValue(nzcv_inst, nzcv);
- ctx.EraseInstruction(nzcv_inst);
}
if (carry_inst) {
if (invert_output_carry) {
@@ -1073,12 +1059,10 @@ static void EmitSub(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bit
code.setc(carry);
}
ctx.reg_alloc.DefineValue(carry_inst, carry);
- ctx.EraseInstruction(carry_inst);
}
if (overflow_inst) {
code.seto(overflow);
ctx.reg_alloc.DefineValue(overflow_inst, overflow);
- ctx.EraseInstruction(overflow_inst);
}
if (!is_cmp) {
ctx.reg_alloc.DefineValue(inst, result);
diff --git a/src/dynarmic/backend/x64/emit_x64_packed.cpp b/src/dynarmic/backend/x64/emit_x64_packed.cpp
index 7a710cd0..4cfad5ff 100644
--- a/src/dynarmic/backend/x64/emit_x64_packed.cpp
+++ b/src/dynarmic/backend/x64/emit_x64_packed.cpp
@@ -33,7 +33,6 @@ void EmitX64::EmitPackedAddU8(EmitContext& ctx, IR::Inst* inst) {
code.pxor(xmm_ge, ones);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
}
ctx.reg_alloc.DefineValue(inst, xmm_a);
@@ -56,7 +55,6 @@ void EmitX64::EmitPackedAddS8(EmitContext& ctx, IR::Inst* inst) {
code.pcmpgtb(xmm_ge, xmm0);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
}
code.paddb(xmm_a, xmm_b);
@@ -86,7 +84,6 @@ void EmitX64::EmitPackedAddU16(EmitContext& ctx, IR::Inst* inst) {
code.pxor(xmm_ge, ones);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
} else {
const Xbyak::Xmm tmp_a = ctx.reg_alloc.ScratchXmm();
const Xbyak::Xmm tmp_b = ctx.reg_alloc.ScratchXmm();
@@ -99,7 +96,6 @@ void EmitX64::EmitPackedAddU16(EmitContext& ctx, IR::Inst* inst) {
code.pcmpgtw(tmp_b, tmp_a); // *Signed* comparison!
ctx.reg_alloc.DefineValue(ge_inst, tmp_b);
- ctx.EraseInstruction(ge_inst);
}
}
@@ -123,7 +119,6 @@ void EmitX64::EmitPackedAddS16(EmitContext& ctx, IR::Inst* inst) {
code.pcmpgtw(xmm_ge, xmm0);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
}
code.paddw(xmm_a, xmm_b);
@@ -146,7 +141,6 @@ void EmitX64::EmitPackedSubU8(EmitContext& ctx, IR::Inst* inst) {
code.pcmpeqb(xmm_ge, xmm_a);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
}
code.psubb(xmm_a, xmm_b);
@@ -171,7 +165,6 @@ void EmitX64::EmitPackedSubS8(EmitContext& ctx, IR::Inst* inst) {
code.pcmpgtb(xmm_ge, xmm0);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
}
code.psubb(xmm_a, xmm_b);
@@ -205,7 +198,6 @@ void EmitX64::EmitPackedSubU16(EmitContext& ctx, IR::Inst* inst) {
code.psubw(xmm_a, xmm_b);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
ctx.reg_alloc.DefineValue(inst, xmm_a);
return;
}
@@ -226,7 +218,6 @@ void EmitX64::EmitPackedSubU16(EmitContext& ctx, IR::Inst* inst) {
code.psubw(xmm_a, xmm_b);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
ctx.reg_alloc.DefineValue(inst, xmm_a);
}
@@ -247,7 +238,6 @@ void EmitX64::EmitPackedSubS16(EmitContext& ctx, IR::Inst* inst) {
code.pcmpgtw(xmm_ge, xmm0);
ctx.reg_alloc.DefineValue(ge_inst, xmm_ge);
- ctx.EraseInstruction(ge_inst);
}
code.psubw(xmm_a, xmm_b);
@@ -554,7 +544,6 @@ static void EmitPackedSubAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst
code.or_(ge_sum, ge_diff);
ctx.reg_alloc.DefineValue(ge_inst, ge_sum);
- ctx.EraseInstruction(ge_inst);
}
if (is_halving) {
diff --git a/src/dynarmic/backend/x64/emit_x64_saturation.cpp b/src/dynarmic/backend/x64/emit_x64_saturation.cpp
index 707d99eb..24fb895b 100644
--- a/src/dynarmic/backend/x64/emit_x64_saturation.cpp
+++ b/src/dynarmic/backend/x64/emit_x64_saturation.cpp
@@ -64,7 +64,6 @@ void EmitSignedSaturatedOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst)
if constexpr (has_overflow_inst) {
if (const auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)) {
ctx.reg_alloc.DefineValue(overflow_inst, overflow);
- ctx.EraseInstruction(overflow_inst);
}
} else {
code.or_(code.byte[code.r15 + code.GetJitStateInfo().offsetof_fpsr_qc], overflow.cvt8());
@@ -155,7 +154,6 @@ void EmitX64::EmitSignedSaturation(EmitContext& ctx, IR::Inst* inst) {
code.seta(overflow.cvt8());
ctx.reg_alloc.DefineValue(overflow_inst, overflow);
- ctx.EraseInstruction(overflow_inst);
}
ctx.reg_alloc.DefineValue(inst, result);
@@ -185,7 +183,6 @@ void EmitX64::EmitUnsignedSaturation(EmitContext& ctx, IR::Inst* inst) {
code.seta(overflow.cvt8());
ctx.reg_alloc.DefineValue(overflow_inst, overflow);
- ctx.EraseInstruction(overflow_inst);
}
ctx.reg_alloc.DefineValue(inst, result);
diff --git a/src/dynarmic/backend/x64/emit_x64_vector.cpp b/src/dynarmic/backend/x64/emit_x64_vector.cpp
index 852ac742..4191f73c 100644
--- a/src/dynarmic/backend/x64/emit_x64_vector.cpp
+++ b/src/dynarmic/backend/x64/emit_x64_vector.cpp
@@ -3633,7 +3633,6 @@ void EmitX64::EmitVectorSignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
}
ctx.reg_alloc.DefineValue(upper_inst, result);
- ctx.EraseInstruction(upper_inst);
}
if (lower_inst) {
@@ -3645,7 +3644,6 @@ void EmitX64::EmitVectorSignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
code.pmullw(result, y);
}
ctx.reg_alloc.DefineValue(lower_inst, result);
- ctx.EraseInstruction(lower_inst);
}
}
@@ -3663,7 +3661,6 @@ void EmitX64::EmitVectorSignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
code.vpmulld(result, x, y);
ctx.reg_alloc.DefineValue(lower_inst, result);
- ctx.EraseInstruction(lower_inst);
return;
}
@@ -3675,7 +3672,6 @@ void EmitX64::EmitVectorSignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm lower_result = ctx.reg_alloc.ScratchXmm();
code.vpmulld(lower_result, x, y);
ctx.reg_alloc.DefineValue(lower_inst, lower_result);
- ctx.EraseInstruction(lower_inst);
}
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
@@ -3687,7 +3683,6 @@ void EmitX64::EmitVectorSignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
code.shufps(result, x, 0b11011101);
ctx.reg_alloc.DefineValue(upper_inst, result);
- ctx.EraseInstruction(upper_inst);
return;
}
@@ -3730,11 +3725,9 @@ void EmitX64::EmitVectorSignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
if (upper_inst) {
ctx.reg_alloc.DefineValue(upper_inst, upper_result);
- ctx.EraseInstruction(upper_inst);
}
if (lower_inst) {
ctx.reg_alloc.DefineValue(lower_inst, lower_result);
- ctx.EraseInstruction(lower_inst);
}
}
@@ -5139,7 +5132,6 @@ void EmitX64::EmitVectorUnsignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
}
ctx.reg_alloc.DefineValue(upper_inst, result);
- ctx.EraseInstruction(upper_inst);
}
if (lower_inst) {
@@ -5151,7 +5143,6 @@ void EmitX64::EmitVectorUnsignedMultiply16(EmitContext& ctx, IR::Inst* inst) {
code.pmullw(result, y);
}
ctx.reg_alloc.DefineValue(lower_inst, result);
- ctx.EraseInstruction(lower_inst);
}
}
@@ -5169,7 +5160,6 @@ void EmitX64::EmitVectorUnsignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
code.vpmulld(result, x, y);
ctx.reg_alloc.DefineValue(lower_inst, result);
- ctx.EraseInstruction(lower_inst);
return;
}
@@ -5181,7 +5171,6 @@ void EmitX64::EmitVectorUnsignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
const Xbyak::Xmm lower_result = ctx.reg_alloc.ScratchXmm();
code.vpmulld(lower_result, x, y);
ctx.reg_alloc.DefineValue(lower_inst, lower_result);
- ctx.EraseInstruction(lower_inst);
}
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
@@ -5193,7 +5182,6 @@ void EmitX64::EmitVectorUnsignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
code.shufps(result, x, 0b11011101);
ctx.reg_alloc.DefineValue(upper_inst, result);
- ctx.EraseInstruction(upper_inst);
return;
}
@@ -5224,11 +5212,9 @@ void EmitX64::EmitVectorUnsignedMultiply32(EmitContext& ctx, IR::Inst* inst) {
if (upper_inst) {
ctx.reg_alloc.DefineValue(upper_inst, upper_result);
- ctx.EraseInstruction(upper_inst);
}
if (lower_inst) {
ctx.reg_alloc.DefineValue(lower_inst, lower_result);
- ctx.EraseInstruction(lower_inst);
}
}
diff --git a/src/dynarmic/backend/x64/reg_alloc.cpp b/src/dynarmic/backend/x64/reg_alloc.cpp
index d37269a3..31764398 100644
--- a/src/dynarmic/backend/x64/reg_alloc.cpp
+++ b/src/dynarmic/backend/x64/reg_alloc.cpp
@@ -17,6 +17,7 @@
#include "dynarmic/backend/x64/abi.h"
#include "dynarmic/backend/x64/stack_layout.h"
#include "dynarmic/backend/x64/verbose_debugging_output.h"
+#include "dynarmic/ir/basic_block.h"
namespace Dynarmic::Backend::X64 {
@@ -157,12 +158,14 @@ void HostLocInfo::AddValue(IR::Inst* inst) {
max_bit_width = std::max(max_bit_width, GetBitWidth(inst->GetType()));
}
-void HostLocInfo::EmitVerboseDebuggingOutput(BlockOfCode& code, size_t host_loc_index) const {
+void HostLocInfo::EmitVerboseDebuggingOutput(BlockOfCode& code, size_t host_loc_index, const IR::Block& block) const {
using namespace Xbyak::util;
for (IR::Inst* value : values) {
+ const auto inst_offset = std::distance(block.begin(), IR::Block::const_iterator(value));
code.mov(code.ABI_PARAM1, rsp);
code.mov(code.ABI_PARAM2, host_loc_index);
- code.mov(code.ABI_PARAM3, mcl::bit_cast<u64>(value));
+ code.mov(code.ABI_PARAM3, mcl::bit_cast<u64>(inst_offset));
+ code.mov(code.ABI_PARAM4, GetBitWidth(value->GetType()));
code.CallFunction(PrintVerboseDebuggingOutputLine);
}
}
@@ -271,6 +274,24 @@ RegAlloc::ArgumentInfo RegAlloc::GetArgumentInfo(IR::Inst* inst) {
return ret;
}
+void RegAlloc::RegisterPseudoOperation(IR::Inst* inst) {
+ ASSERT(IsValueLive(inst));
+
+ for (size_t i = 0; i < inst->NumArgs(); i++) {
+ const IR::Value arg = inst->GetArg(i);
+ if (!arg.IsImmediate() && !IsValuelessType(arg.GetType())) {
+ if (const auto loc = ValueLocation(arg.GetInst())) {
+ // May not necessarily have a value (e.g. CMP variant of Sub32).
+ LocInfo(*loc).AddArgReference();
+ }
+ }
+ }
+}
+
+bool RegAlloc::IsValueLive(IR::Inst* inst) const {
+ return !!ValueLocation(inst);
+}
+
Xbyak::Reg64 RegAlloc::UseGpr(Argument& arg) {
ASSERT(!arg.allocated);
arg.allocated = true;
@@ -494,9 +515,9 @@ void RegAlloc::AssertNoMoreUses() {
ASSERT(std::all_of(hostloc_info.begin(), hostloc_info.end(), [](const auto& i) { return i.IsEmpty(); }));
}
-void RegAlloc::EmitVerboseDebuggingOutput() {
+void RegAlloc::EmitVerboseDebuggingOutput(const IR::Block& block) {
for (size_t i = 0; i < hostloc_info.size(); i++) {
- hostloc_info[i].EmitVerboseDebuggingOutput(code, i);
+ hostloc_info[i].EmitVerboseDebuggingOutput(code, i, block);
}
}
diff --git a/src/dynarmic/backend/x64/reg_alloc.h b/src/dynarmic/backend/x64/reg_alloc.h
index b6cdf796..957c2b2a 100644
--- a/src/dynarmic/backend/x64/reg_alloc.h
+++ b/src/dynarmic/backend/x64/reg_alloc.h
@@ -23,6 +23,7 @@
namespace Dynarmic::IR {
enum class AccType;
+class Block;
} // namespace Dynarmic::IR
namespace Dynarmic::Backend::X64 {
@@ -48,7 +49,7 @@ public:
void AddValue(IR::Inst* inst);
- void EmitVerboseDebuggingOutput(BlockOfCode& code, size_t host_loc_index) const;
+ void EmitVerboseDebuggingOutput(BlockOfCode& code, size_t host_loc_index, const IR::Block& block) const;
private:
// Current instruction state
@@ -110,6 +111,8 @@ public:
explicit RegAlloc(BlockOfCode& code, std::vector<HostLoc> gpr_order, std::vector<HostLoc> xmm_order);
ArgumentInfo GetArgumentInfo(IR::Inst* inst);
+ void RegisterPseudoOperation(IR::Inst* inst);
+ bool IsValueLive(IR::Inst* inst) const;
Xbyak::Reg64 UseGpr(Argument& arg);
Xbyak::Xmm UseXmm(Argument& arg);
@@ -145,7 +148,7 @@ public:
void AssertNoMoreUses();
- void EmitVerboseDebuggingOutput();
+ void EmitVerboseDebuggingOutput(const IR::Block& block);
private:
friend struct Argument;
diff --git a/src/dynarmic/backend/x64/verbose_debugging_output.cpp b/src/dynarmic/backend/x64/verbose_debugging_output.cpp
index 7c862783..3378786c 100644
--- a/src/dynarmic/backend/x64/verbose_debugging_output.cpp
+++ b/src/dynarmic/backend/x64/verbose_debugging_output.cpp
@@ -5,25 +5,52 @@
#include "dynarmic/backend/x64/verbose_debugging_output.h"
+#include <iterator>
+
#include <fmt/format.h>
#include "dynarmic/backend/x64/hostloc.h"
namespace Dynarmic::Backend::X64 {
-void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLoc hostloc, u64 inst_addr) {
- if (HostLocIsGPR(hostloc)) {
- const u64 value = reg_data.gprs[HostLocToReg64(hostloc).getIdx()];
- fmt::print("dynarmic debug: {:016x} = {:016x}{:016x}\n", inst_addr, 0, value);
- } else if (HostLocIsXMM(hostloc)) {
- const Vector value = reg_data.xmms[HostLocToXmm(hostloc).getIdx()];
- fmt::print("dynarmic debug: {:016x} = {:016x}{:016x}\n", inst_addr, value[1], value[0]);
- } else if (HostLocIsSpill(hostloc)) {
- const Vector value = (*reg_data.spill)[static_cast<size_t>(hostloc) - static_cast<size_t>(HostLoc::FirstSpill)];
- fmt::print("dynarmic debug: {:016x} = {:016x}{:016x}\n", inst_addr, value[1], value[0]);
- } else {
- fmt::print("dynarmic debug: Invalid hostloc\n");
+void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLoc hostloc, size_t inst_index, size_t bitsize) {
+ fmt::print("dynarmic debug: %{:05} = ", inst_index);
+
+ Vector value = [&]() -> Vector {
+ if (HostLocIsGPR(hostloc)) {
+ return {reg_data.gprs[HostLocToReg64(hostloc).getIdx()], 0};
+ } else if (HostLocIsXMM(hostloc)) {
+ return reg_data.xmms[HostLocToXmm(hostloc).getIdx()];
+ } else if (HostLocIsSpill(hostloc)) {
+ return (*reg_data.spill)[static_cast<size_t>(hostloc) - static_cast<size_t>(HostLoc::FirstSpill)];
+ } else {
+ fmt::print("invalid hostloc! ");
+ return {0, 0};
+ }
+ }();
+
+ switch (bitsize) {
+ case 8:
+ fmt::print("{:02x}", value[0] & 0xff);
+ break;
+ case 16:
+ fmt::print("{:04x}", value[0] & 0xffff);
+ break;
+ case 32:
+ fmt::print("{:08x}", value[0] & 0xffffffff);
+ break;
+ case 64:
+ fmt::print("{:016x}", value[0]);
+ break;
+ case 128:
+ fmt::print("{:016x}{:016x}", value[1], value[0]);
+ break;
+ default:
+ fmt::print("invalid bitsize!");
+ break;
}
+
+ fmt::print("\n");
}
} // namespace Dynarmic::Backend::X64
diff --git a/src/dynarmic/backend/x64/verbose_debugging_output.h b/src/dynarmic/backend/x64/verbose_debugging_output.h
index 95be7edf..412ce061 100644
--- a/src/dynarmic/backend/x64/verbose_debugging_output.h
+++ b/src/dynarmic/backend/x64/verbose_debugging_output.h
@@ -31,6 +31,6 @@ struct alignas(16) RegisterData {
# pragma warning(pop)
#endif
-void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLoc hostloc, u64 inst_addr);
+void PrintVerboseDebuggingOutputLine(RegisterData& reg_data, HostLoc hostloc, size_t inst_index, size_t bitsize);
} // namespace Dynarmic::Backend::X64