diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index be6d24f8..5b4949d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,6 +82,7 @@ add_library(dynarmic frontend/A64/translate/impl/floating_point_data_processing_two_register.cpp frontend/A64/translate/impl/impl.cpp frontend/A64/translate/impl/impl.h + 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_register_immediate.cpp diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 38b3311f..81afdd67 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -124,38 +124,22 @@ INST(LDx_mult_2, "LDx (multiple structures)", "0Q001 //INST(LD4R_2, "LD4R", "0Q001101111mmmmm1110zznnnnnttttt") // Loads and stores - Load/Store Exclusive -//INST(STXRB, "STXRB", "00001000000sssss011111nnnnnttttt") -//INST(STLXRB, "STLXRB", "00001000000sssss111111nnnnnttttt") -//INST(CASP, "CASP, CASPA, CASPAL, CASPL", "0z0010000L1sssssp11111nnnnnttttt") -//INST(LDXRB, "LDXRB", "0000100001011111011111nnnnnttttt") -//INST(LDAXRB, "LDAXRB", "0000100001011111111111nnnnnttttt") -//INST(STLLRB, "STLLRB", "0000100010011111011111nnnnnttttt") -//INST(STLRB, "STLRB", "0000100010011111111111nnnnnttttt") -//INST(CASB, "CASB, CASAB, CASALB, CASLB", "000010001L1sssssp11111nnnnnttttt") -//INST(LDLARB, "LDLARB", "0000100011011111011111nnnnnttttt") -//INST(LDARB, "LDARB", "0000100011011111111111nnnnnttttt") -//INST(STXRH, "STXRH", "01001000000sssss011111nnnnnttttt") -//INST(STLXRH, "STLXRH", "01001000000sssss111111nnnnnttttt") -//INST(LDXRH, "LDXRH", "0100100001011111011111nnnnnttttt") -//INST(LDAXRH, "LDAXRH", "0100100001011111111111nnnnnttttt") -//INST(STLLRH, "STLLRH", "0100100010011111011111nnnnnttttt") -//INST(STLRH, "STLRH", "0100100010011111111111nnnnnttttt") -//INST(CASH, "CASH, CASAH, CASALH, CASLH", "010010001L1sssssp11111nnnnnttttt") -//INST(LDLARH, "LDLARH", "0100100011011111011111nnnnnttttt") -//INST(LDARH, "LDARH", "0100100011011111111111nnnnnttttt") -//INST(STXR, "STXR", "1-001000000sssss011111nnnnnttttt") -//INST(STLXR, "STLXR", "1-001000000sssss111111nnnnnttttt") +//INST(STXR, "STXRB, STXRH, STXR", "zz001000000sssss011111nnnnnttttt") +//INST(STLXR, "STLXRB, STLXRH, STLXR", "zz001000000sssss111111nnnnnttttt") //INST(STXP, "STXP", "1z001000001sssss0uuuuunnnnnttttt") //INST(STLXP, "STLXP", "1z001000001sssss1uuuuunnnnnttttt") -//INST(LDXR, "LDXR", "1-00100001011111011111nnnnnttttt") -//INST(LDAXR, "LDAXR", "1-00100001011111111111nnnnnttttt") +//INST(LDXR, "LDXRB, LDXRH, LDXR", "zz00100001011111011111nnnnnttttt") +//INST(LDAXRB, "LDAXRB", "zz00100001011111111111nnnnnttttt") //INST(LDXP, "LDXP", "1z001000011111110uuuuunnnnnttttt") //INST(LDAXP, "LDAXP", "1z001000011111111uuuuunnnnnttttt") -//INST(STLLR, "STLLR", "1-00100010011111011111nnnnnttttt") -//INST(STLR, "STLR", "1-00100010011111111111nnnnnttttt") -//INST(CAS, "CAS, CASA, CASAL, CASL", "1-0010001L1sssssp11111nnnnnttttt") -//INST(LDLAR, "LDLAR", "1-00100011011111011111nnnnnttttt") -//INST(LDAR, "LDAR", "1-00100011011111111111nnnnnttttt") +//INST(STLLR, "STLLRB, STLLRH, STLLR", "zz00100010011111011111nnnnnttttt") +INST(STLR, "STLRB, STLRH, STLR", "zz00100010011111111111nnnnnttttt") +//INST(LDLAR, "LDLARB, LDLARH, LDLAR", "zz00100011011111011111nnnnnttttt") +INST(LDAR, "LDARB, LDARH, LDAR", "zz00100011011111111111nnnnnttttt") +//INST(CASP, "CASP, CASPA, CASPAL, CASPL", "0z0010000L1sssssp11111nnnnnttttt") // ARMv8.1 +//INST(CASB, "CASB, CASAB, CASALB, CASLB", "000010001L1sssssp11111nnnnnttttt") // ARMv8.1 +//INST(CASH, "CASH, CASAH, CASALH, CASLH", "010010001L1sssssp11111nnnnnttttt") // ARMv8.1 +//INST(CAS, "CAS, CASA, CASAL, CASL", "1z0010001L1sssssp11111nnnnnttttt") // ARMv8.1 // Loads and stores - Load register (literal) INST(LDR_lit_gen, "LDR (literal)", "0z011000iiiiiiiiiiiiiiiiiiittttt") diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index 43dc4d82..aaa29dc3 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -16,7 +16,7 @@ namespace Dynarmic::A64 { enum class AccType { - NORMAL, VEC, STREAM, VECSTREAM, ATOMIC, ORDERED, UNPRIV, IFETCH, PTW, DC, IC, AT, + NORMAL, VEC, STREAM, VECSTREAM, ATOMIC, ORDERED, ORDEREDRW, LIMITEDORDERED, UNPRIV, IFETCH, PTW, DC, IC, DCZVA, AT, }; enum class MemOp { @@ -187,38 +187,22 @@ struct TranslatorVisitor final { bool LD4R_2(bool Q, Reg Rm, Imm<2> size, Reg Rn, Vec Vt); // Loads and stores - Load/Store Exclusive - bool STXRB(Reg Rs, Reg Rn, Reg Rt); - bool STLXRB(Reg Rs, Reg Rn, Reg Rt); + bool STXR(Imm<2> size, Reg Rs, Reg Rn, Reg Rt); + bool STLXR(Imm<2> size, Reg Rs, Reg Rn, Reg Rt); + bool STXP(Imm<1> size, Reg Rs, Reg Rt2, Reg Rn, Reg Rt); + bool STLXP(Imm<1> size, Reg Rs, Reg Rt2, Reg Rn, Reg Rt); + bool LDXR(Imm<2> size, Reg Rn, Reg Rt); + bool LDAXRB(Imm<2> size, Reg Rn, Reg Rt); + bool LDXP(Imm<1> size, Reg Rt2, Reg Rn, Reg Rt); + bool LDAXP(Imm<1> size, Reg Rt2, Reg Rn, Reg Rt); + bool STLLR(Imm<2> size, Reg Rn, Reg Rt); + bool STLR(Imm<2> size, Reg Rn, Reg Rt); + bool LDLAR(Imm<2> size, Reg Rn, Reg Rt); + bool LDAR(Imm<2> size, Reg Rn, Reg Rt); bool CASP(bool sz, bool L, Reg Rs, bool o0, Reg Rn, Reg Rt); - bool LDXRB(Reg Rn, Reg Rt); - bool LDAXRB(Reg Rn, Reg Rt); - bool STLLRB(Reg Rn, Reg Rt); - bool STLRB(Reg Rn, Reg Rt); bool CASB(bool L, Reg Rs, bool o0, Reg Rn, Reg Rt); - bool LDLARB(Reg Rn, Reg Rt); - bool LDARB(Reg Rn, Reg Rt); - bool STXRH(Reg Rs, Reg Rn, Reg Rt); - bool STLXRH(Reg Rs, Reg Rn, Reg Rt); - bool LDXRH(Reg Rn, Reg Rt); - bool LDAXRH(Reg Rn, Reg Rt); - bool STLLRH(Reg Rn, Reg Rt); - bool STLRH(Reg Rn, Reg Rt); bool CASH(bool L, Reg Rs, bool o0, Reg Rn, Reg Rt); - bool LDLARH(Reg Rn, Reg Rt); - bool LDARH(Reg Rn, Reg Rt); - bool STXR(Reg Rs, Reg Rn, Reg Rt); - bool STLXR(Reg Rs, Reg Rn, Reg Rt); - bool STXP(bool sz, Reg Rs, Reg Rt2, Reg Rn, Reg Rt); - bool STLXP(bool sz, Reg Rs, Reg Rt2, Reg Rn, Reg Rt); - bool LDXR(Reg Rn, Reg Rt); - bool LDAXR(Reg Rn, Reg Rt); - bool LDXP(bool sz, Reg Rt2, Reg Rn, Reg Rt); - bool LDAXP(bool sz, Reg Rt2, Reg Rn, Reg Rt); - bool STLLR(Reg Rn, Reg Rt); - bool STLR(Reg Rn, Reg Rt); - bool CAS(bool L, Reg Rs, bool o0, Reg Rn, Reg Rt); - bool LDLAR(Reg Rn, Reg Rt); - bool LDAR(Reg Rn, Reg Rt); + bool CAS(bool sz, bool L, Reg Rs, bool o0, Reg Rn, Reg Rt); // Loads and stores - Load register (literal) bool LDR_lit_gen(bool opc_0, Imm<19> imm19, Reg Rt); diff --git a/src/frontend/A64/translate/impl/load_store_exclusive.cpp b/src/frontend/A64/translate/impl/load_store_exclusive.cpp new file mode 100644 index 00000000..e5bb3705 --- /dev/null +++ b/src/frontend/A64/translate/impl/load_store_exclusive.cpp @@ -0,0 +1,64 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 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 { + +static bool OrderedSharedDecodeAndOperation(TranslatorVisitor& tv, size_t size, bool L, bool o0, Reg Rn, Reg Rt) { + // Shared Decode + + const AccType acctype = !o0 ? AccType::LIMITEDORDERED : AccType::ORDERED; + const MemOp memop = L ? MemOp::LOAD : MemOp::STORE; + const size_t elsize = 8 << size; + const size_t regsize = elsize == 64 ? 64 : 32; + const size_t datasize = elsize; + + // Operation + + const size_t dbytes = datasize / 8; + + IR::U64 address; + if (Rn == Reg::SP) { + // TODO: Check SP Alignment + address = tv.SP(64); + } else { + address = tv.X(64, Rn); + } + + switch (memop) { + case MemOp::STORE: { + IR::UAny data = tv.X(datasize, Rt); + tv.Mem(address, dbytes, acctype, data); + break; + } + case MemOp::LOAD: { + IR::UAny data = tv.Mem(address, dbytes, acctype); + tv.X(regsize, Rt, tv.ZeroExtend(data, regsize)); + break; + } + default: + UNREACHABLE(); + } + + return true; +} + +bool TranslatorVisitor::STLR(Imm<2> sz, Reg Rn, Reg Rt) { + const size_t size = sz.ZeroExtend(); + const bool L = 0; + const bool o0 = 1; + return OrderedSharedDecodeAndOperation(*this, size, L, o0, Rn, Rt); +} + +bool TranslatorVisitor::LDAR(Imm<2> sz, Reg Rn, Reg Rt) { + const size_t size = sz.ZeroExtend(); + const bool L = 1; + const bool o0 = 1; + return OrderedSharedDecodeAndOperation(*this, size, L, o0, Rn, Rt); +} + +} // namespace Dynarmic::A64