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.
This commit is contained in:
Lioncash 2019-03-02 17:03:08 -05:00 committed by MerryMage
parent 20fabc5083
commit bfaeb08d3c
4 changed files with 28 additions and 8 deletions

View file

@ -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

View file

@ -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")

View file

@ -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);

View file

@ -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