From 599a613feaa328a227045e70565dc373582e87da Mon Sep 17 00:00:00 2001 From: MerryMage Date: Tue, 25 Apr 2017 13:57:27 +0100 Subject: [PATCH] Move SEL from status_register_access to misc --- src/frontend/translate/translate_arm/misc.cpp | 27 +++++++++++++++++++ .../translate_arm/status_register_access.cpp | 27 ------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/frontend/translate/translate_arm/misc.cpp b/src/frontend/translate/translate_arm/misc.cpp index 1892458d..e6e806a0 100644 --- a/src/frontend/translate/translate_arm/misc.cpp +++ b/src/frontend/translate/translate_arm/misc.cpp @@ -18,5 +18,32 @@ bool ArmTranslatorVisitor::arm_CLZ(Cond cond, Reg d, Reg m) { return true; } +bool ArmTranslatorVisitor::arm_SEL(Cond cond, Reg n, Reg d, Reg m) { + if (n == Reg::PC || d == Reg::PC || m == Reg::PC) + return UnpredictableInstruction(); + + if (ConditionPassed(cond)) { + auto ge = ir.GetGEFlags(); + + // Perform some arithmetic to expand 0bXYZW into 0bXXXXXXXXYYYYYYYYZZZZZZZZWWWWWWWW => 0xXXYYZZWW + // The logic behind this is as follows: + // 0000 0000 0000 0000 | 0000 0000 0000 xyzw + // 0000 000x yzw0 00xy | zw00 0xyz w000 xyzw (x * 0x00204081) + // 0000 000x 0000 000y | 0000 000z 0000 000w (x & 0x01010101) + // xxxx xxxx yyyy yyyy | zzzz zzzz wwww wwww (x * 0xff) + + auto x2 = ir.Mul(ge, ir.Imm32(0x00204081)); + auto x3 = ir.And(x2, ir.Imm32(0x01010101)); + auto mask = ir.Mul(x3, ir.Imm32(0xFF)); + + auto to = ir.GetRegister(m); + auto from = ir.GetRegister(n); + auto result = ir.Or(ir.And(from, mask), ir.And(to, ir.Not(mask))); + ir.SetRegister(d, result); + } + + return true; +} + } // namespace Arm } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/status_register_access.cpp b/src/frontend/translate/translate_arm/status_register_access.cpp index a8e52089..f737f5eb 100644 --- a/src/frontend/translate/translate_arm/status_register_access.cpp +++ b/src/frontend/translate/translate_arm/status_register_access.cpp @@ -77,32 +77,5 @@ bool ArmTranslatorVisitor::arm_SRS() { return InterpretThisInstruction(); } -bool ArmTranslatorVisitor::arm_SEL(Cond cond, Reg n, Reg d, Reg m) { - if (n == Reg::PC || d == Reg::PC || m == Reg::PC) - return UnpredictableInstruction(); - - if (ConditionPassed(cond)) { - auto ge = ir.GetGEFlags(); - - // Perform some arithmetic to expand 0bXYZW into 0bXXXXXXXXYYYYYYYYZZZZZZZZWWWWWWWW => 0xXXYYZZWW - // The logic behind this is as follows: - // 0000 0000 0000 0000 | 0000 0000 0000 xyzw - // 0000 000x yzw0 00xy | zw00 0xyz w000 xyzw (x * 0x00204081) - // 0000 000x 0000 000y | 0000 000z 0000 000w (x & 0x01010101) - // xxxx xxxx yyyy yyyy | zzzz zzzz wwww wwww (x * 0xff) - - auto x2 = ir.Mul(ge, ir.Imm32(0x00204081)); - auto x3 = ir.And(x2, ir.Imm32(0x01010101)); - auto mask = ir.Mul(x3, ir.Imm32(0xFF)); - - auto to = ir.GetRegister(m); - auto from = ir.GetRegister(n); - auto result = ir.Or(ir.And(from, mask), ir.And(to, ir.Not(mask))); - ir.SetRegister(d, result); - } - - return true; -} - } // namespace Arm } // namespace Dynarmic