diff --git a/src/dynarmic/backend/riscv64/emit_riscv64.cpp b/src/dynarmic/backend/riscv64/emit_riscv64.cpp index 1ac24b3e..54eb73c1 100644 --- a/src/dynarmic/backend/riscv64/emit_riscv64.cpp +++ b/src/dynarmic/backend/riscv64/emit_riscv64.cpp @@ -23,12 +23,18 @@ namespace Dynarmic::Backend::RV64 { template void EmitIR(biscuit::Assembler&, EmitContext&, IR::Inst*) { - ASSERT_FALSE("Unimplemented opcode {}", op); + ASSERT_FALSE("Unimplemented opcode {} ", op); } template<> void EmitIR(biscuit::Assembler&, EmitContext&, IR::Inst*) {} +template<> +void EmitIR(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + ctx.reg_alloc.DefineAsExisting(inst, args[0]); +} + template<> void EmitIR(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst); template<> diff --git a/src/dynarmic/backend/riscv64/reg_alloc.cpp b/src/dynarmic/backend/riscv64/reg_alloc.cpp index 245c961f..1451b430 100644 --- a/src/dynarmic/backend/riscv64/reg_alloc.cpp +++ b/src/dynarmic/backend/riscv64/reg_alloc.cpp @@ -125,6 +125,19 @@ void RegAlloc::UpdateAllUses() { } } +void RegAlloc::DefineAsExisting(IR::Inst* inst, Argument& arg) { + ASSERT(!ValueLocation(inst)); + + if (arg.value.IsImmediate()) { + inst->ReplaceUsesWith(arg.value); + return; + } + + auto& info = ValueInfo(arg.value.GetInst()); + info.values.emplace_back(inst); + info.expected_uses += inst->UseCount(); +} + void RegAlloc::AssertNoMoreUses() const { const auto is_empty = [](const auto& i) { return i.IsCompletelyEmpty(); }; ASSERT(std::all_of(gprs.begin(), gprs.end(), is_empty)); diff --git a/src/dynarmic/backend/riscv64/reg_alloc.h b/src/dynarmic/backend/riscv64/reg_alloc.h index e457bc84..d80f588b 100644 --- a/src/dynarmic/backend/riscv64/reg_alloc.h +++ b/src/dynarmic/backend/riscv64/reg_alloc.h @@ -118,6 +118,8 @@ public: auto WriteX(IR::Inst* inst) { return RAReg{*this, true, IR::Value{inst}}; } auto WriteD(IR::Inst* inst) { return RAReg{*this, true, IR::Value{inst}}; } + void DefineAsExisting(IR::Inst* inst, Argument& arg); + void SpillAll(); template