saturated: Implement QASX, QSAX, UQASX, UQSAX
This commit is contained in:
parent
01abb65960
commit
1c21ae6bcd
2 changed files with 81 additions and 20 deletions
|
@ -184,16 +184,6 @@ bool ArmTranslatorVisitor::arm_QADD16(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_QASX(Cond cond, Reg n, Reg d, Reg m) {
|
|
||||||
UNUSED(cond, n, d, m);
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_QSAX(Cond cond, Reg n, Reg d, Reg m) {
|
|
||||||
UNUSED(cond, n, d, m);
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
bool ArmTranslatorVisitor::arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
|
@ -230,16 +220,6 @@ bool ArmTranslatorVisitor::arm_UQADD16(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_UQASX(Cond cond, Reg n, Reg d, Reg m) {
|
|
||||||
UNUSED(cond, n, d, m);
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_UQSAX(Cond cond, Reg n, Reg d, Reg m) {
|
|
||||||
UNUSED(cond, n, d, m);
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_UQSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
bool ArmTranslatorVisitor::arm_UQSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
|
|
|
@ -158,6 +158,87 @@ bool ArmTranslatorVisitor::arm_QDSUB(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parallel saturated instructions
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_QASX(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
// QASX <Rd>, <Rn>, <Rm>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto Rn = ir.GetRegister(n);
|
||||||
|
auto Rm = ir.GetRegister(m);
|
||||||
|
auto Rn_lo = ir.SignExtendHalfToWord(ir.LeastSignificantHalf(Rn));
|
||||||
|
auto Rn_hi = ir.SignExtendHalfToWord(MostSignificantHalf(ir, Rn));
|
||||||
|
auto Rm_lo = ir.SignExtendHalfToWord(ir.LeastSignificantHalf(Rm));
|
||||||
|
auto Rm_hi = ir.SignExtendHalfToWord(MostSignificantHalf(ir, Rm));
|
||||||
|
auto diff = ir.SignedSaturation(ir.Sub(Rn_lo, Rm_hi), 16).result;
|
||||||
|
auto sum = ir.SignedSaturation(ir.Add(Rn_hi, Rm_lo), 16).result;
|
||||||
|
auto result = Pack2x16To1x32(ir, diff, sum);
|
||||||
|
ir.SetRegister(d, result);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_QSAX(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
// QSAX <Rd>, <Rn>, <Rm>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto Rn = ir.GetRegister(n);
|
||||||
|
auto Rm = ir.GetRegister(m);
|
||||||
|
auto Rn_lo = ir.SignExtendHalfToWord(ir.LeastSignificantHalf(Rn));
|
||||||
|
auto Rn_hi = ir.SignExtendHalfToWord(MostSignificantHalf(ir, Rn));
|
||||||
|
auto Rm_lo = ir.SignExtendHalfToWord(ir.LeastSignificantHalf(Rm));
|
||||||
|
auto Rm_hi = ir.SignExtendHalfToWord(MostSignificantHalf(ir, Rm));
|
||||||
|
auto sum = ir.SignedSaturation(ir.Add(Rn_lo, Rm_hi), 16).result;
|
||||||
|
auto diff = ir.SignedSaturation(ir.Sub(Rn_hi, Rm_lo), 16).result;
|
||||||
|
auto result = Pack2x16To1x32(ir, sum, diff);
|
||||||
|
ir.SetRegister(d, result);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_UQASX(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
// UQASX <Rd>, <Rn>, <Rm>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto Rn = ir.GetRegister(n);
|
||||||
|
auto Rm = ir.GetRegister(m);
|
||||||
|
auto Rn_lo = ir.ZeroExtendHalfToWord(ir.LeastSignificantHalf(Rn));
|
||||||
|
auto Rn_hi = ir.ZeroExtendHalfToWord(MostSignificantHalf(ir, Rn));
|
||||||
|
auto Rm_lo = ir.ZeroExtendHalfToWord(ir.LeastSignificantHalf(Rm));
|
||||||
|
auto Rm_hi = ir.ZeroExtendHalfToWord(MostSignificantHalf(ir, Rm));
|
||||||
|
auto diff = ir.UnsignedSaturation(ir.Sub(Rn_lo, Rm_hi), 16).result;
|
||||||
|
auto sum = ir.UnsignedSaturation(ir.Add(Rn_hi, Rm_lo), 16).result;
|
||||||
|
auto result = Pack2x16To1x32(ir, diff, sum);
|
||||||
|
ir.SetRegister(d, result);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_UQSAX(Cond cond, Reg n, Reg d, Reg m) {
|
||||||
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
// UQSAX <Rd>, <Rn>, <Rm>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto Rn = ir.GetRegister(n);
|
||||||
|
auto Rm = ir.GetRegister(m);
|
||||||
|
auto Rn_lo = ir.ZeroExtendHalfToWord(ir.LeastSignificantHalf(Rn));
|
||||||
|
auto Rn_hi = ir.ZeroExtendHalfToWord(MostSignificantHalf(ir, Rn));
|
||||||
|
auto Rm_lo = ir.ZeroExtendHalfToWord(ir.LeastSignificantHalf(Rm));
|
||||||
|
auto Rm_hi = ir.ZeroExtendHalfToWord(MostSignificantHalf(ir, Rm));
|
||||||
|
auto sum = ir.UnsignedSaturation(ir.Add(Rn_lo, Rm_hi), 16).result;
|
||||||
|
auto diff = ir.UnsignedSaturation(ir.Sub(Rn_hi, Rm_lo), 16).result;
|
||||||
|
auto result = Pack2x16To1x32(ir, sum, diff);
|
||||||
|
ir.SetRegister(d, result);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Arm
|
} // namespace Arm
|
||||||
} // namespace Dynarmic
|
} // namespace Dynarmic
|
||||||
|
|
Loading…
Reference in a new issue