2016-08-02 21:59:33 +01:00
|
|
|
/* This file is part of the dynarmic project.
|
|
|
|
* Copyright (c) 2016 MerryMage
|
|
|
|
* This software may be used and distributed according to the terms of the GNU
|
|
|
|
* General Public License version 2 or any later version.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "translate_arm.h"
|
|
|
|
|
|
|
|
namespace Dynarmic {
|
|
|
|
namespace Arm {
|
|
|
|
|
|
|
|
// Parallel Add/Subtract (Modulo arithmetic) instructions
|
|
|
|
bool ArmTranslatorVisitor::arm_SADD8(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SADD16(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SASX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SSAX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SSUB16(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UADD8(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UADD16(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UASX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_USAX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_USUB8(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_USUB16(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Parallel Add/Subtract (Saturating) instructions
|
|
|
|
bool ArmTranslatorVisitor::arm_QADD8(Cond cond, Reg n, Reg d, Reg m) {
|
2016-08-19 00:40:18 +01:00
|
|
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
|
|
|
return UnpredictableInstruction();
|
2016-08-12 18:26:14 +01:00
|
|
|
if (ConditionPassed(cond)) {
|
|
|
|
auto result = ir.PackedSaturatedAddS8(ir.GetRegister(n), ir.GetRegister(m));
|
|
|
|
ir.SetRegister(d, result);
|
|
|
|
}
|
|
|
|
return true;
|
2016-08-02 21:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_QADD16(Cond cond, Reg n, Reg d, Reg m) {
|
2016-08-19 00:40:18 +01:00
|
|
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
|
|
|
return UnpredictableInstruction();
|
2016-08-12 18:42:16 +01:00
|
|
|
if (ConditionPassed(cond)) {
|
|
|
|
auto result = ir.PackedSaturatedAddS16(ir.GetRegister(n), ir.GetRegister(m));
|
|
|
|
ir.SetRegister(d, result);
|
|
|
|
}
|
|
|
|
return true;
|
2016-08-02 21:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_QASX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_QSAX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
2016-08-19 00:40:18 +01:00
|
|
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
|
|
|
return UnpredictableInstruction();
|
2016-08-12 18:18:38 +01:00
|
|
|
if (ConditionPassed(cond)) {
|
|
|
|
auto result = ir.PackedSaturatedSubS8(ir.GetRegister(n), ir.GetRegister(m));
|
|
|
|
ir.SetRegister(d, result);
|
|
|
|
}
|
|
|
|
return true;
|
2016-08-02 21:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_QSUB16(Cond cond, Reg n, Reg d, Reg m) {
|
2016-08-19 00:40:18 +01:00
|
|
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
|
|
|
return UnpredictableInstruction();
|
2016-08-12 18:42:16 +01:00
|
|
|
if (ConditionPassed(cond)) {
|
|
|
|
auto result = ir.PackedSaturatedSubS16(ir.GetRegister(n), ir.GetRegister(m));
|
|
|
|
ir.SetRegister(d, result);
|
|
|
|
}
|
|
|
|
return true;
|
2016-08-02 21:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UQADD8(Cond cond, Reg n, Reg d, Reg m) {
|
2016-08-12 18:26:14 +01:00
|
|
|
if (ConditionPassed(cond)) {
|
|
|
|
auto result = ir.PackedSaturatedAddU8(ir.GetRegister(n), ir.GetRegister(m));
|
|
|
|
ir.SetRegister(d, result);
|
|
|
|
}
|
|
|
|
return true;
|
2016-08-02 21:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UQADD16(Cond cond, Reg n, Reg d, Reg m) {
|
2016-08-12 18:42:16 +01:00
|
|
|
if (ConditionPassed(cond)) {
|
|
|
|
auto result = ir.PackedSaturatedAddU16(ir.GetRegister(n), ir.GetRegister(m));
|
|
|
|
ir.SetRegister(d, result);
|
|
|
|
}
|
|
|
|
return true;
|
2016-08-02 21:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UQASX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UQSAX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UQSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
2016-08-19 00:40:18 +01:00
|
|
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
|
|
|
return UnpredictableInstruction();
|
2016-08-12 16:53:16 +01:00
|
|
|
if (ConditionPassed(cond)) {
|
|
|
|
auto result = ir.PackedSaturatedSubU8(ir.GetRegister(n), ir.GetRegister(m));
|
|
|
|
ir.SetRegister(d, result);
|
|
|
|
}
|
|
|
|
return true;
|
2016-08-02 21:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UQSUB16(Cond cond, Reg n, Reg d, Reg m) {
|
2016-08-19 00:40:18 +01:00
|
|
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC)
|
|
|
|
return UnpredictableInstruction();
|
2016-08-12 18:42:16 +01:00
|
|
|
if (ConditionPassed(cond)) {
|
|
|
|
auto result = ir.PackedSaturatedSubU16(ir.GetRegister(n), ir.GetRegister(m));
|
|
|
|
ir.SetRegister(d, result);
|
|
|
|
}
|
|
|
|
return true;
|
2016-08-02 21:59:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Parallel Add/Subtract (Halving) instructions
|
|
|
|
bool ArmTranslatorVisitor::arm_SHADD8(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SHADD16(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SHASX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SHSAX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SHSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_SHSUB16(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UHADD8(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UHADD16(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UHASX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UHSAX(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UHSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ArmTranslatorVisitor::arm_UHSUB16(Cond cond, Reg n, Reg d, Reg m) {
|
|
|
|
return InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Arm
|
|
|
|
} // namespace Dynarmic
|