translate_arm/coprocessor: Minor tidying up

This commit is contained in:
Lioncash 2019-03-01 03:14:29 -05:00 committed by MerryMage
parent 1e32a09c03
commit 05a6ab691d

View file

@ -8,36 +8,40 @@
namespace Dynarmic::A32 { namespace Dynarmic::A32 {
// CDP{2} <coproc_no>, #<opc1>, <CRd>, <CRn>, <CRm>, #<opc2>
bool ArmTranslatorVisitor::arm_CDP(Cond cond, size_t opc1, CoprocReg CRn, CoprocReg CRd, size_t coproc_no, size_t opc2, CoprocReg CRm) { 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(); return arm_UDF();
}
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
// CDP{2} <coproc_no>, #<opc1>, <CRd>, <CRn>, <CRm>, #<opc2>
if (two || ConditionPassed(cond)) { if (two || ConditionPassed(cond)) {
ir.CoprocInternalOperation(coproc_no, two, opc1, CRd, CRn, CRm, opc2); ir.CoprocInternalOperation(coproc_no, two, opc1, CRd, CRn, CRm, opc2);
} }
return true; return true;
} }
// LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>, #+/-<imm32>]{!}
// LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>], #+/-<imm32>
// LDC{2}{L}<c> <coproc_no>, <CRd>, [<Rn>], <imm8>
bool ArmTranslatorVisitor::arm_LDC(Cond cond, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm8 imm8) { 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(); return arm_UDF();
if ((coproc_no & 0b1110) == 0b1010) }
if ((coproc_no & 0b1110) == 0b1010) {
return arm_UDF(); return arm_UDF();
}
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
const u32 imm32 = static_cast<u8>(imm8) << 2;
const bool index = p;
const bool add = u;
const bool wback = w;
const bool has_option = !p && !w && u;
// LDC{2}{L} <coproc_no>, <CRd>, [<Rn>, #+/-<imm32>]{!}
// LDC{2}{L} <coproc_no>, <CRd>, [<Rn>], #+/-<imm32>
// LDC{2}{L} <coproc_no>, <CRd>, [<Rn>], <imm8>
if (two || ConditionPassed(cond)) { if (two || ConditionPassed(cond)) {
const u32 imm32 = static_cast<u8>(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 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 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; 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; return true;
} }
// MCR{2}<c> <coproc_no>, #<opc1>, <Rt>, <CRn>, <CRm>, #<opc2>
bool ArmTranslatorVisitor::arm_MCR(Cond cond, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) { 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(); return arm_UDF();
if (t == Reg::PC) }
if (t == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
}
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
// MCR{2} <coproc_no>, #<opc1>, <Rt>, <CRn>, <CRm>, #<opc2>
if (two || ConditionPassed(cond)) { if (two || ConditionPassed(cond)) {
ir.CoprocSendOneWord(coproc_no, two, opc1, CRn, CRm, opc2, ir.GetRegister(t)); ir.CoprocSendOneWord(coproc_no, two, opc1, CRn, CRm, opc2, ir.GetRegister(t));
} }
return true; return true;
} }
// MCRR{2}<c> <coproc_no>, #<opc>, <Rt>, <Rt2>, <CRm>
bool ArmTranslatorVisitor::arm_MCRR(Cond cond, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) { 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(); return arm_UDF();
if (t == Reg::PC || t2 == Reg::PC) }
if (t == Reg::PC || t2 == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
}
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
// MCRR{2} <coproc_no>, #<opc>, <Rt>, <Rt2>, <CRm>
if (two || ConditionPassed(cond)) { if (two || ConditionPassed(cond)) {
ir.CoprocSendTwoWords(coproc_no, two, opc, CRm, ir.GetRegister(t), ir.GetRegister(t2)); ir.CoprocSendTwoWords(coproc_no, two, opc, CRm, ir.GetRegister(t), ir.GetRegister(t2));
} }
return true; return true;
} }
// MRC{2}<c> <coproc_no>, #<opc1>, <Rt>, <CRn>, <CRm>, #<opc2>
bool ArmTranslatorVisitor::arm_MRC(Cond cond, size_t opc1, CoprocReg CRn, Reg t, size_t coproc_no, size_t opc2, CoprocReg CRm) { 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(); return arm_UDF();
}
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
// MRC{2} <coproc_no>, #<opc1>, <Rt>, <CRn>, <CRm>, #<opc2>
if (two || ConditionPassed(cond)) { 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) { if (t != Reg::PC) {
ir.SetRegister(t, word); ir.SetRegister(t, word);
} else { } 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); ir.SetCpsrNZCV(new_cpsr_nzcv);
} }
} }
return true; return true;
} }
// MRRC{2}<c> <coproc_no>, #<opc>, <Rt>, <Rt2>, <CRm>
bool ArmTranslatorVisitor::arm_MRRC(Cond cond, Reg t2, Reg t, size_t coproc_no, size_t opc, CoprocReg CRm) { 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(); return arm_UDF();
if (t == Reg::PC || t2 == Reg::PC || t == t2) }
if (t == Reg::PC || t2 == Reg::PC || t == t2) {
return UnpredictableInstruction(); return UnpredictableInstruction();
}
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
// MRRC{2} <coproc_no>, #<opc>, <Rt>, <Rt2>, <CRm>
if (two || ConditionPassed(cond)) { 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(t, ir.LeastSignificantWord(two_words));
ir.SetRegister(t2, ir.MostSignificantWord(two_words).result); ir.SetRegister(t2, ir.MostSignificantWord(two_words).result);
} }
return true; return true;
} }
// STC{2}{L}<c> <coproc>, <CRd>, [<Rn>, #+/-<imm32>]{!}
// STC{2}{L}<c> <coproc>, <CRd>, [<Rn>], #+/-<imm32>
// STC{2}{L}<c> <coproc>, <CRd>, [<Rn>], <imm8>
bool ArmTranslatorVisitor::arm_STC(Cond cond, bool p, bool u, bool d, bool w, Reg n, CoprocReg CRd, size_t coproc_no, Imm8 imm8) { 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(); return arm_UDF();
if (!p && !u && !d && !w) }
if (!p && !u && !d && !w) {
return arm_UDF(); return arm_UDF();
if (n == Reg::PC && w) }
if (n == Reg::PC && w) {
return UnpredictableInstruction(); return UnpredictableInstruction();
}
const bool two = cond == Cond::NV; const bool two = cond == Cond::NV;
const u32 imm32 = static_cast<u8>(imm8) << 2;
const bool index = p;
const bool add = u;
const bool wback = w;
const bool has_option = !p && !w && u;
// STC{2}{L} <coproc>, <CRd>, [<Rn>, #+/-<imm32>]{!}
// STC{2}{L} <coproc>, <CRd>, [<Rn>], #+/-<imm32>
// STC{2}{L} <coproc>, <CRd>, [<Rn>], <imm8>
if (two || ConditionPassed(cond)) { if (two || ConditionPassed(cond)) {
const u32 imm32 = static_cast<u8>(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 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 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; const IR::U32 address = index ? offset_address : reg_n;