A64: Implement STLRB, STLRH, STLR, LDARB, LDARH, LDAR

This commit is contained in:
MerryMage 2018-02-05 01:10:52 +00:00
parent 5a65313236
commit b02b861242
4 changed files with 91 additions and 58 deletions

View file

@ -82,6 +82,7 @@ add_library(dynarmic
frontend/A64/translate/impl/floating_point_data_processing_two_register.cpp frontend/A64/translate/impl/floating_point_data_processing_two_register.cpp
frontend/A64/translate/impl/impl.cpp frontend/A64/translate/impl/impl.cpp
frontend/A64/translate/impl/impl.h 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_load_literal.cpp
frontend/A64/translate/impl/load_store_multiple_structures.cpp frontend/A64/translate/impl/load_store_multiple_structures.cpp
frontend/A64/translate/impl/load_store_register_immediate.cpp frontend/A64/translate/impl/load_store_register_immediate.cpp

View file

@ -124,38 +124,22 @@ INST(LDx_mult_2, "LDx (multiple structures)", "0Q001
//INST(LD4R_2, "LD4R", "0Q001101111mmmmm1110zznnnnnttttt") //INST(LD4R_2, "LD4R", "0Q001101111mmmmm1110zznnnnnttttt")
// Loads and stores - Load/Store Exclusive // Loads and stores - Load/Store Exclusive
//INST(STXRB, "STXRB", "00001000000sssss011111nnnnnttttt") //INST(STXR, "STXRB, STXRH, STXR", "zz001000000sssss011111nnnnnttttt")
//INST(STLXRB, "STLXRB", "00001000000sssss111111nnnnnttttt") //INST(STLXR, "STLXRB, STLXRH, STLXR", "zz001000000sssss111111nnnnnttttt")
//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(STXP, "STXP", "1z001000001sssss0uuuuunnnnnttttt") //INST(STXP, "STXP", "1z001000001sssss0uuuuunnnnnttttt")
//INST(STLXP, "STLXP", "1z001000001sssss1uuuuunnnnnttttt") //INST(STLXP, "STLXP", "1z001000001sssss1uuuuunnnnnttttt")
//INST(LDXR, "LDXR", "1-00100001011111011111nnnnnttttt") //INST(LDXR, "LDXRB, LDXRH, LDXR", "zz00100001011111011111nnnnnttttt")
//INST(LDAXR, "LDAXR", "1-00100001011111111111nnnnnttttt") //INST(LDAXRB, "LDAXRB", "zz00100001011111111111nnnnnttttt")
//INST(LDXP, "LDXP", "1z001000011111110uuuuunnnnnttttt") //INST(LDXP, "LDXP", "1z001000011111110uuuuunnnnnttttt")
//INST(LDAXP, "LDAXP", "1z001000011111111uuuuunnnnnttttt") //INST(LDAXP, "LDAXP", "1z001000011111111uuuuunnnnnttttt")
//INST(STLLR, "STLLR", "1-00100010011111011111nnnnnttttt") //INST(STLLR, "STLLRB, STLLRH, STLLR", "zz00100010011111011111nnnnnttttt")
//INST(STLR, "STLR", "1-00100010011111111111nnnnnttttt") INST(STLR, "STLRB, STLRH, STLR", "zz00100010011111111111nnnnnttttt")
//INST(CAS, "CAS, CASA, CASAL, CASL", "1-0010001L1sssssp11111nnnnnttttt") //INST(LDLAR, "LDLARB, LDLARH, LDLAR", "zz00100011011111011111nnnnnttttt")
//INST(LDLAR, "LDLAR", "1-00100011011111011111nnnnnttttt") INST(LDAR, "LDARB, LDARH, LDAR", "zz00100011011111111111nnnnnttttt")
//INST(LDAR, "LDAR", "1-00100011011111111111nnnnnttttt") //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) // Loads and stores - Load register (literal)
INST(LDR_lit_gen, "LDR (literal)", "0z011000iiiiiiiiiiiiiiiiiiittttt") INST(LDR_lit_gen, "LDR (literal)", "0z011000iiiiiiiiiiiiiiiiiiittttt")

View file

@ -16,7 +16,7 @@
namespace Dynarmic::A64 { namespace Dynarmic::A64 {
enum class AccType { 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 { enum class MemOp {
@ -187,38 +187,22 @@ struct TranslatorVisitor final {
bool LD4R_2(bool Q, Reg Rm, Imm<2> size, Reg Rn, Vec Vt); bool LD4R_2(bool Q, Reg Rm, Imm<2> size, Reg Rn, Vec Vt);
// Loads and stores - Load/Store Exclusive // Loads and stores - Load/Store Exclusive
bool STXRB(Reg Rs, Reg Rn, Reg Rt); bool STXR(Imm<2> size, Reg Rs, Reg Rn, Reg Rt);
bool STLXRB(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 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 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 CASH(bool L, Reg Rs, bool o0, Reg Rn, Reg Rt);
bool LDLARH(Reg Rn, Reg Rt); bool CAS(bool sz, bool L, Reg Rs, bool o0, 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);
// Loads and stores - Load register (literal) // Loads and stores - Load register (literal)
bool LDR_lit_gen(bool opc_0, Imm<19> imm19, Reg Rt); bool LDR_lit_gen(bool opc_0, Imm<19> imm19, Reg Rt);

View file

@ -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<size_t>();
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<size_t>();
const bool L = 1;
const bool o0 = 1;
return OrderedSharedDecodeAndOperation(*this, size, L, o0, Rn, Rt);
}
} // namespace Dynarmic::A64