aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYang Liu <[email protected]>2024-02-17 14:38:31 +0800
committerMerry <[email protected]>2024-03-02 19:38:46 +0000
commitb485553ed855ae4fc5b96f4753e8e66f89d21abd (patch)
tree367e138dee2573e2ebdb2d050cc8ba5b16f1de50
parent1de237bf24c1c755ffedec23442f681bdf4f8560 (diff)
downloaddynarmic-b485553ed855ae4fc5b96f4753e8e66f89d21abd.tar.gz
dynarmic-b485553ed855ae4fc5b96f4753e8e66f89d21abd.zip
backend/rv64: Implement Identity
-rw-r--r--src/dynarmic/backend/riscv64/emit_riscv64.cpp8
-rw-r--r--src/dynarmic/backend/riscv64/reg_alloc.cpp13
-rw-r--r--src/dynarmic/backend/riscv64/reg_alloc.h2
3 files changed, 22 insertions, 1 deletions
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,13 +23,19 @@ namespace Dynarmic::Backend::RV64 {
template<IR::Opcode op>
void EmitIR(biscuit::Assembler&, EmitContext&, IR::Inst*) {
- ASSERT_FALSE("Unimplemented opcode {}", op);
+ ASSERT_FALSE("Unimplemented opcode {} ", op);
}
template<>
void EmitIR<IR::Opcode::Void>(biscuit::Assembler&, EmitContext&, IR::Inst*) {}
template<>
+void EmitIR<IR::Opcode::Identity>(biscuit::Assembler&, EmitContext& ctx, IR::Inst* inst) {
+ auto args = ctx.reg_alloc.GetArgumentInfo(inst);
+ ctx.reg_alloc.DefineAsExisting(inst, args[0]);
+}
+
+template<>
void EmitIR<IR::Opcode::A32GetRegister>(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst);
template<>
void EmitIR<IR::Opcode::A32SetRegister>(biscuit::Assembler& as, EmitContext& ctx, IR::Inst* inst);
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<biscuit::GPR>{*this, true, IR::Value{inst}}; }
auto WriteD(IR::Inst* inst) { return RAReg<biscuit::FPR>{*this, true, IR::Value{inst}}; }
+ void DefineAsExisting(IR::Inst* inst, Argument& arg);
+
void SpillAll();
template<typename... Ts>