thumb32: Add coprocessor instructions
This commit is contained in:
parent
5ebe11c329
commit
b93ae62acf
5 changed files with 95 additions and 16 deletions
|
@ -157,6 +157,7 @@ if ("A32" IN_LIST DYNARMIC_FRONTENDS)
|
|||
frontend/A32/translate/impl/thumb16.cpp
|
||||
frontend/A32/translate/impl/thumb32_branch.cpp
|
||||
frontend/A32/translate/impl/thumb32_control.cpp
|
||||
frontend/A32/translate/impl/thumb32_coprocessor.cpp
|
||||
frontend/A32/translate/impl/thumb32_data_processing_modified_immediate.cpp
|
||||
frontend/A32/translate/impl/thumb32_data_processing_plain_binary_immediate.cpp
|
||||
frontend/A32/translate/impl/thumb32_data_processing_register.cpp
|
||||
|
|
|
@ -281,19 +281,10 @@ INST(thumb32_UMLAL, "UMLAL", "111110111110nnnnllllhh
|
|||
INST(thumb32_UMAAL, "UMAAL", "111110111110nnnnllllhhhh0110mmmm")
|
||||
|
||||
// Coprocessor
|
||||
//INST(thumb32_MCRR2, "MCRR2", "111111000100--------------------")
|
||||
//INST(thumb32_MCRR, "MCRR", "111011000100--------------------")
|
||||
//INST(thumb32_STC2, "STC2", "1111110----0--------------------")
|
||||
//INST(thumb32_STC, "STC", "1110110----0--------------------")
|
||||
//INST(thumb32_MRRC2, "MRRC2", "111111000101--------------------")
|
||||
//INST(thumb32_MRRC, "MRRC", "111011000101--------------------")
|
||||
//INST(thumb32_LDC2_lit, "LDC2 (lit)", "1111110----11111----------------")
|
||||
//INST(thumb32_LDC_lit, "LDC (lit)", "1110110----11111----------------")
|
||||
//INST(thumb32_LDC2_imm, "LDC2 (imm)", "1111110----1--------------------")
|
||||
//INST(thumb32_LDC_imm, "LDC (imm)", "1110110----1--------------------")
|
||||
//INST(thumb32_CDP2, "CDP2", "11111110-------------------0----")
|
||||
//INST(thumb32_CDP, "CDP", "11101110-------------------0----")
|
||||
//INST(thumb32_MCR2, "MCR2", "11111110---0---------------1----")
|
||||
//INST(thumb32_MCR, "MCR", "11101110---0---------------1----")
|
||||
//INST(thumb32_MRC2, "MRC2", "11111110---1---------------1----")
|
||||
//INST(thumb32_MRC, "MRC", "11101110---1---------------1----")
|
||||
INST(thumb32_MCRR, "MCRR", "111o11000100uuuuttttppppooooMMMM")
|
||||
INST(thumb32_MRRC, "MRRC", "111o11000101uuuuttttppppooooMMMM")
|
||||
INST(thumb32_STC, "STC", "111o110pudw0nnnnDDDDppppvvvvvvvv")
|
||||
INST(thumb32_LDC, "LDC", "111o110pudw1nnnnDDDDppppvvvvvvvv")
|
||||
INST(thumb32_CDP, "CDP", "111o1110ooooNNNNDDDDppppooo0MMMM")
|
||||
INST(thumb32_MCR, "MCR", "111o1110ooo0NNNNttttppppooo1MMMM")
|
||||
INST(thumb32_MRC, "MRC", "111o1110ooo1NNNNttttppppooo1MMMM")
|
||||
|
|
75
src/frontend/A32/translate/impl/thumb32_coprocessor.cpp
Normal file
75
src/frontend/A32/translate/impl/thumb32_coprocessor.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2021 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "frontend/A32/translate/impl/translate.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
bool TranslatorVisitor::thumb32_MCRR(bool two, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) {
|
||||
ir.CoprocSendTwoWords(coproc_no, two, opc, CRm, ir.GetRegister(t), ir.GetRegister(t2));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::thumb32_MRRC(bool two, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) {
|
||||
const auto two_words = ir.CoprocGetTwoWords(coproc_no, two, opc, CRm);
|
||||
ir.SetRegister(t, ir.LeastSignificantWord(two_words));
|
||||
ir.SetRegister(t2, ir.MostSignificantWord(two_words).result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::thumb32_STC(bool two, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm<8> imm8) {
|
||||
const u32 imm32 = imm8.ZeroExtend() << 2;
|
||||
const bool index = p;
|
||||
const bool add = u;
|
||||
const bool wback = w;
|
||||
const bool has_option = !p && !w && u;
|
||||
const IR::U32 reg_n = ir.GetRegister(n);
|
||||
const IR::U32 offset_address = add ? ir.Add(reg_n, ir.Imm32(imm32)) : ir.Sub(reg_n, ir.Imm32(imm32));
|
||||
const IR::U32 address = index ? offset_address : reg_n;
|
||||
ir.CoprocStoreWords(coproc_no, two, d, CRd, address, has_option, imm8.ZeroExtend<u8>());
|
||||
if (wback) {
|
||||
ir.SetRegister(n, offset_address);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::thumb32_LDC(bool two, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm<8> imm8) {
|
||||
const u32 imm32 = imm8.ZeroExtend() << 2;
|
||||
const bool index = p;
|
||||
const bool add = u;
|
||||
const bool wback = w;
|
||||
const bool has_option = !p && !w && u;
|
||||
const IR::U32 reg_n = ir.GetRegister(n);
|
||||
const IR::U32 offset_address = add ? ir.Add(reg_n, ir.Imm32(imm32)) : ir.Sub(reg_n, ir.Imm32(imm32));
|
||||
const IR::U32 address = index ? offset_address : reg_n;
|
||||
ir.CoprocLoadWords(coproc_no, two, d, CRd, address, has_option, imm8.ZeroExtend<u8>());
|
||||
if (wback) {
|
||||
ir.SetRegister(n, offset_address);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::thumb32_CDP(bool two, size_t opc1, CoprocReg CRn, CoprocReg CRd, size_t coproc_no, size_t opc2, CoprocReg CRm) {
|
||||
ir.CoprocInternalOperation(coproc_no, two, opc1, CRd, CRn, CRm, opc2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::thumb32_MCR(bool two, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) {
|
||||
ir.CoprocSendOneWord(coproc_no, two, opc1, CRn, CRm, opc2, ir.GetRegister(t));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::thumb32_MRC(bool two, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) {
|
||||
const auto word = ir.CoprocGetOneWord(coproc_no, two, opc1, CRn, CRm, opc2);
|
||||
if (t != Reg::PC) {
|
||||
ir.SetRegister(t, word);
|
||||
} else {
|
||||
const auto new_cpsr_nzcv = ir.And(word, ir.Imm32(0xF0000000));
|
||||
ir.SetCpsrNZCV(new_cpsr_nzcv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
|
@ -740,6 +740,15 @@ struct TranslatorVisitor final {
|
|||
bool thumb32_UHSUB8(Reg n, Reg d, Reg m);
|
||||
bool thumb32_UHSUB16(Reg n, Reg d, Reg m);
|
||||
|
||||
// thumb32 coprocessor insturctions
|
||||
bool thumb32_MCRR(bool two, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm);
|
||||
bool thumb32_MRRC(bool two, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm);
|
||||
bool thumb32_STC(bool two, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm<8> imm8);
|
||||
bool thumb32_LDC(bool two, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm<8> imm8);
|
||||
bool thumb32_CDP(bool two, size_t opc1, CoprocReg CRn, CoprocReg CRd, size_t coproc_no, size_t opc2, CoprocReg CRm);
|
||||
bool thumb32_MCR(bool two, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm);
|
||||
bool thumb32_MRC(bool two, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm);
|
||||
|
||||
// Floating-point three-register data processing instructions
|
||||
bool vfp_VADD(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
|
||||
bool vfp_VSUB(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
|
||||
|
|
|
@ -200,6 +200,9 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
|
|||
"vfp_VCVT_from_fixed",
|
||||
"asimd_VRECPS", // Unicorn does not fuse the multiply and subtraction, resulting in being off by 1ULP.
|
||||
"asimd_VRSQRTS", // Unicorn does not fuse the multiply and subtraction, resulting in being off by 1ULP.
|
||||
|
||||
// Coprocessor
|
||||
"thumb32_CDP", "thumb32_LDC", "thumb32_MCR", "thumb32_MCRR", "thumb32_MRC", "thumb32_MRRC", "thumb32_STC",
|
||||
};
|
||||
|
||||
for (const auto& [fn, bitstring] : list) {
|
||||
|
|
Loading…
Reference in a new issue