saturated: Implement SSAT and USAT
This commit is contained in:
parent
6a269a6ebd
commit
56ea2386d3
2 changed files with 52 additions and 16 deletions
|
@ -9,6 +9,54 @@
|
||||||
namespace Dynarmic {
|
namespace Dynarmic {
|
||||||
namespace Arm {
|
namespace Arm {
|
||||||
|
|
||||||
|
// Saturation instructions
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_SSAT(Cond cond, Imm5 sat_imm, Reg d, Imm5 imm5, bool sh, Reg n) {
|
||||||
|
if (d == Reg::PC || n == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
size_t saturate_to = static_cast<size_t>(sat_imm) + 1;
|
||||||
|
ShiftType shift = !sh ? ShiftType::LSL : ShiftType::ASR;
|
||||||
|
|
||||||
|
// SSAT <Rd>, #<saturate_to>, <Rn>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto operand = EmitImmShift(ir.GetRegister(n), shift, imm5, ir.GetCFlag());
|
||||||
|
auto result = ir.SignedSaturation(operand.result, saturate_to);
|
||||||
|
ir.SetRegister(d, result.result);
|
||||||
|
ir.OrQFlag(result.overflow);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_SSAT16(Cond cond, Imm4 sat_imm, Reg d, Reg n) {
|
||||||
|
UNUSED(cond, sat_imm, d, n);
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_USAT(Cond cond, Imm5 sat_imm, Reg d, Imm5 imm5, bool sh, Reg n) {
|
||||||
|
if (d == Reg::PC || n == Reg::PC)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
|
||||||
|
size_t saturate_to = static_cast<size_t>(sat_imm);
|
||||||
|
ShiftType shift = !sh ? ShiftType::LSL : ShiftType::ASR;
|
||||||
|
|
||||||
|
// USAT <Rd>, #<saturate_to>, <Rn>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto operand = EmitImmShift(ir.GetRegister(n), shift, imm5, ir.GetCFlag());
|
||||||
|
auto result = ir.UnsignedSaturation(operand.result, saturate_to);
|
||||||
|
ir.SetRegister(d, result.result);
|
||||||
|
ir.OrQFlag(result.overflow);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_USAT16(Cond cond, Imm4 sat_imm, Reg d, Reg n) {
|
||||||
|
UNUSED(cond, sat_imm, d, n);
|
||||||
|
return InterpretThisInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saturated Add/Subtract instructions
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_QADD(Cond cond, Reg n, Reg d, Reg m) {
|
bool ArmTranslatorVisitor::arm_QADD(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();
|
||||||
|
|
|
@ -227,22 +227,10 @@ struct ArmTranslatorVisitor final {
|
||||||
bool arm_REVSH(Cond cond, Reg d, Reg m);
|
bool arm_REVSH(Cond cond, Reg d, Reg m);
|
||||||
|
|
||||||
// Saturation instructions
|
// Saturation instructions
|
||||||
bool arm_SSAT(Cond cond, Imm5 sat_imm, Reg d, Imm5 imm5, bool sh, Reg n) {
|
bool arm_SSAT(Cond cond, Imm5 sat_imm, Reg d, Imm5 imm5, bool sh, Reg n);
|
||||||
UNUSED(cond, sat_imm, d, imm5, sh, n);
|
bool arm_SSAT16(Cond cond, Imm4 sat_imm, Reg d, Reg n);
|
||||||
return InterpretThisInstruction();
|
bool arm_USAT(Cond cond, Imm5 sat_imm, Reg d, Imm5 imm5, bool sh, Reg n);
|
||||||
}
|
bool arm_USAT16(Cond cond, Imm4 sat_imm, Reg d, Reg n);
|
||||||
bool arm_SSAT16(Cond cond, Imm4 sat_imm, Reg d, Reg n) {
|
|
||||||
UNUSED(cond, sat_imm, d, n);
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_USAT(Cond cond, Imm5 sat_imm, Reg d, Imm5 imm5, bool sh, Reg n) {
|
|
||||||
UNUSED(cond, sat_imm, d, imm5, sh, n);
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
bool arm_USAT16(Cond cond, Imm4 sat_imm, Reg d, Reg n) {
|
|
||||||
UNUSED(cond, sat_imm, d, n);
|
|
||||||
return InterpretThisInstruction();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiply (Normal) instructions
|
// Multiply (Normal) instructions
|
||||||
bool arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n);
|
bool arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n);
|
||||||
|
|
Loading…
Reference in a new issue