From bfaeb08d3ca4ee26707a5d53b96e2c681f5d9593 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 2 Mar 2019 17:03:08 -0500 Subject: [PATCH] A64: Implement LDNP/STNP LDNP and STNP indicate that a memory access is non-temporal/streaming (i.e. unlikely to be repeated), allowing data caching to not be performed. However, given this is only a hint, we can treat these two instructions as regular LDP and STP instructions for the time being. --- src/CMakeLists.txt | 1 + src/frontend/A64/decoder/a64.inc | 6 ++--- src/frontend/A64/translate/impl/impl.h | 6 ++--- .../impl/load_store_no_allocate_pair.cpp | 23 +++++++++++++++++++ 4 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 src/frontend/A64/translate/impl/load_store_no_allocate_pair.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c6a51f87..0887b4eb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,6 +142,7 @@ add_library(dynarmic frontend/A64/translate/impl/load_store_exclusive.cpp frontend/A64/translate/impl/load_store_load_literal.cpp frontend/A64/translate/impl/load_store_multiple_structures.cpp + frontend/A64/translate/impl/load_store_no_allocate_pair.cpp frontend/A64/translate/impl/load_store_register_immediate.cpp frontend/A64/translate/impl/load_store_register_pair.cpp frontend/A64/translate/impl/load_store_register_register_offset.cpp diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 9400bdf0..7c9145c6 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -181,10 +181,8 @@ INST(PRFM_lit, "PRFM (literal)", "11011 INST(LDR_lit_fpsimd, "LDR (literal, SIMD&FP)", "oo011100iiiiiiiiiiiiiiiiiiittttt") // Loads and stores - Load/Store no-allocate pair -//INST(STNP_gen, "STNP", "-010100000iiiiiiiuuuuunnnnnttttt") -//INST(LDNP_gen, "LDNP", "-010100001iiiiiiiuuuuunnnnnttttt") -//INST(STNP_fpsimd, "STNP (SIMD&FP)", "oo10110000iiiiiiiuuuuunnnnnttttt") -//INST(LDNP_fpsimd, "LDNP (SIMD&FP)", "oo10110001iiiiiiiuuuuunnnnnttttt") +INST(STNP_LDNP_gen, "STNP/LDNP", "o01010000Liiiiiiiuuuuunnnnnttttt") +INST(STNP_LDNP_fpsimd, "STNP/LDNP (SIMD&FP)", "oo1011000Liiiiiiiuuuuunnnnnttttt") // Loads and stores - Load/Store register pair INST(STP_LDP_gen, "STP/LDP", "oo10100pwLiiiiiiiuuuuunnnnnttttt") diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index 6fc859ef..d65318ed 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -256,10 +256,8 @@ struct TranslatorVisitor final { bool PRFM_lit(Imm<19> imm19, Imm<5> prfop); // Loads and stores - Load/Store no-allocate pair - bool STNP_gen(Imm<7> imm7, Reg Rt2, Reg Rn, Reg Rt); - bool LDNP_gen(Imm<7> imm7, Reg Rt2, Reg Rn, Reg Rt); - bool STNP_fpsimd(Imm<2> opc, Imm<7> imm7, Vec Vt2, Reg Rn, Vec Vt); - bool LDNP_fpsimd(Imm<2> opc, Imm<7> imm7, Vec Vt2, Reg Rn, Vec Vt); + bool STNP_LDNP_gen(Imm<1> upper_opc, Imm<1> L, Imm<7> imm7, Reg Rt2, Reg Rn, Reg Rt); + bool STNP_LDNP_fpsimd(Imm<2> opc, Imm<1> L, Imm<7> imm7, Vec Vt2, Reg Rn, Vec Vt); // Loads and stores - Load/Store register pair bool STP_LDP_gen(Imm<2> opc, bool not_postindex, bool wback, Imm<1> L, Imm<7> imm7, Reg Rt2, Reg Rn, Reg Rt); diff --git a/src/frontend/A64/translate/impl/load_store_no_allocate_pair.cpp b/src/frontend/A64/translate/impl/load_store_no_allocate_pair.cpp new file mode 100644 index 00000000..a8ce489b --- /dev/null +++ b/src/frontend/A64/translate/impl/load_store_no_allocate_pair.cpp @@ -0,0 +1,23 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2019 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include "frontend/A64/translate/impl/impl.h" + +namespace Dynarmic::A64 { + +// Given the LDNP and STNP instructions are simply hinting at non-temporal +// accesses, we can treat them as regular LDP and STP instructions for the +// time being since we don't perform data caching. + +bool TranslatorVisitor::STNP_LDNP_gen(Imm<1> upper_opc, Imm<1> L, Imm<7> imm7, Reg Rt2, Reg Rn, Reg Rt) { + return STP_LDP_gen(Imm<2>{upper_opc.ZeroExtend() << 1}, true, false, L, imm7, Rt2, Rn, Rt); +} + +bool TranslatorVisitor::STNP_LDNP_fpsimd(Imm<2> opc, Imm<1> L, Imm<7> imm7, Vec Vt2, Reg Rn, Vec Vt) { + return STP_LDP_fpsimd(opc, true, false, L, imm7, Vt2, Rn, Vt); +} + +} // namespace Dynarmic::A64