diff --git a/src/frontend/A32/translate/translate_arm/coprocessor.cpp b/src/frontend/A32/translate/translate_arm/coprocessor.cpp index e3044aae..67cbf992 100644 --- a/src/frontend/A32/translate/translate_arm/coprocessor.cpp +++ b/src/frontend/A32/translate/translate_arm/coprocessor.cpp @@ -8,36 +8,40 @@ namespace Dynarmic::A32 { +// CDP{2} , #, , , , # bool ArmTranslatorVisitor::arm_CDP(Cond cond, size_t opc1, CoprocReg CRn, CoprocReg CRd, size_t coproc_no, size_t opc2, CoprocReg CRm) { - if ((coproc_no & 0b1110) == 0b1010) + if ((coproc_no & 0b1110) == 0b1010) { return arm_UDF(); + } const bool two = cond == Cond::NV; - // CDP{2} , #, , , , # if (two || ConditionPassed(cond)) { ir.CoprocInternalOperation(coproc_no, two, opc1, CRd, CRn, CRm, opc2); } return true; } +// LDC{2}{L} , , [, #+/-]{!} +// LDC{2}{L} , , [], #+/- +// LDC{2}{L} , , [], bool ArmTranslatorVisitor::arm_LDC(Cond cond, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm8 imm8) { - if (!p && !u && !d && !w) + if (!p && !u && !d && !w) { return arm_UDF(); - if ((coproc_no & 0b1110) == 0b1010) + } + + if ((coproc_no & 0b1110) == 0b1010) { return arm_UDF(); + } const bool two = cond == Cond::NV; - const u32 imm32 = static_cast(imm8) << 2; - const bool index = p; - const bool add = u; - const bool wback = w; - const bool has_option = !p && !w && u; - // LDC{2}{L} , , [, #+/-]{!} - // LDC{2}{L} , , [], #+/- - // LDC{2}{L} , , [], if (two || ConditionPassed(cond)) { + const u32 imm32 = static_cast(imm8) << 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; @@ -49,91 +53,106 @@ bool ArmTranslatorVisitor::arm_LDC(Cond cond, bool p, bool u, bool d, bool w, Re return true; } +// MCR{2} , #, , , , # bool ArmTranslatorVisitor::arm_MCR(Cond cond, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) { - if ((coproc_no & 0b1110) == 0b1010) + if ((coproc_no & 0b1110) == 0b1010) { return arm_UDF(); - if (t == Reg::PC) + } + + if (t == Reg::PC) { return UnpredictableInstruction(); + } const bool two = cond == Cond::NV; - // MCR{2} , #, , , , # if (two || ConditionPassed(cond)) { ir.CoprocSendOneWord(coproc_no, two, opc1, CRn, CRm, opc2, ir.GetRegister(t)); } return true; } +// MCRR{2} , #, , , bool ArmTranslatorVisitor::arm_MCRR(Cond cond, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) { - if ((coproc_no & 0b1110) == 0b1010) + if ((coproc_no & 0b1110) == 0b1010) { return arm_UDF(); - if (t == Reg::PC || t2 == Reg::PC) + } + + if (t == Reg::PC || t2 == Reg::PC) { return UnpredictableInstruction(); + } const bool two = cond == Cond::NV; - // MCRR{2} , #, , , if (two || ConditionPassed(cond)) { ir.CoprocSendTwoWords(coproc_no, two, opc, CRm, ir.GetRegister(t), ir.GetRegister(t2)); } return true; } +// MRC{2} , #, , , , # bool ArmTranslatorVisitor::arm_MRC(Cond cond, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) { - if ((coproc_no & 0b1110) == 0b1010) + if ((coproc_no & 0b1110) == 0b1010) { return arm_UDF(); + } const bool two = cond == Cond::NV; - // MRC{2} , #, , , , # if (two || ConditionPassed(cond)) { - auto word = ir.CoprocGetOneWord(coproc_no, two, opc1, CRn, CRm, opc2); + const auto word = ir.CoprocGetOneWord(coproc_no, two, opc1, CRn, CRm, opc2); if (t != Reg::PC) { ir.SetRegister(t, word); } else { - auto new_cpsr_nzcv = ir.And(word, ir.Imm32(0xF0000000)); + const auto new_cpsr_nzcv = ir.And(word, ir.Imm32(0xF0000000)); ir.SetCpsrNZCV(new_cpsr_nzcv); } } return true; } +// MRRC{2} , #, , , bool ArmTranslatorVisitor::arm_MRRC(Cond cond, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) { - if ((coproc_no & 0b1110) == 0b1010) + if ((coproc_no & 0b1110) == 0b1010) { return arm_UDF(); - if (t == Reg::PC || t2 == Reg::PC || t == t2) + } + + if (t == Reg::PC || t2 == Reg::PC || t == t2) { return UnpredictableInstruction(); + } const bool two = cond == Cond::NV; - // MRRC{2} , #, , , if (two || ConditionPassed(cond)) { - auto two_words = ir.CoprocGetTwoWords(coproc_no, two, opc, 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; } +// STC{2}{L} , , [, #+/-]{!} +// STC{2}{L} , , [], #+/- +// STC{2}{L} , , [], bool ArmTranslatorVisitor::arm_STC(Cond cond, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm8 imm8) { - if ((coproc_no & 0b1110) == 0b1010) + if ((coproc_no & 0b1110) == 0b1010) { return arm_UDF(); - if (!p && !u && !d && !w) + } + + if (!p && !u && !d && !w) { return arm_UDF(); - if (n == Reg::PC && w) + } + + if (n == Reg::PC && w) { return UnpredictableInstruction(); + } const bool two = cond == Cond::NV; - const u32 imm32 = static_cast(imm8) << 2; - const bool index = p; - const bool add = u; - const bool wback = w; - const bool has_option = !p && !w && u; - // STC{2}{L} , , [, #+/-]{!} - // STC{2}{L} , , [], #+/- - // STC{2}{L} , , [], if (two || ConditionPassed(cond)) { + const u32 imm32 = static_cast(imm8) << 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;