From bb1c5bd3b210f697dff65c9eca9851f0baafb9a7 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Tue, 23 Jan 2018 10:24:53 -0500 Subject: [PATCH] A64: Implement SMADDL, SMSUBL, UMADDL, and UMSUBL --- src/frontend/A64/decoder/a64.inc | 8 ++-- .../impl/data_processing_multiply.cpp | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 9458fe95..57d3547b 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -339,11 +339,11 @@ INST(CSNEG, "CSNEG", "z1011 // Data Processing - Register - 3 source INST(MADD, "MADD", "z0011011000mmmmm0aaaaannnnnddddd") INST(MSUB, "MSUB", "z0011011000mmmmm1aaaaannnnnddddd") -//INST(SMADDL, "SMADDL", "10011011001mmmmm0aaaaannnnnddddd") -//INST(SMSUBL, "SMSUBL", "10011011001mmmmm1aaaaannnnnddddd") +INST(SMADDL, "SMADDL", "10011011001mmmmm0aaaaannnnnddddd") +INST(SMSUBL, "SMSUBL", "10011011001mmmmm1aaaaannnnnddddd") //INST(SMULH, "SMULH", "10011011010mmmmm011111nnnnnddddd") -//INST(UMADDL, "UMADDL", "10011011101mmmmm0aaaaannnnnddddd") -//INST(UMSUBL, "UMSUBL", "10011011101mmmmm1aaaaannnnnddddd") +INST(UMADDL, "UMADDL", "10011011101mmmmm0aaaaannnnnddddd") +INST(UMSUBL, "UMSUBL", "10011011101mmmmm1aaaaannnnnddddd") //INST(UMULH, "UMULH", "10011011110mmmmm011111nnnnnddddd") // Data Processing - FP and SIMD - AES diff --git a/src/frontend/A64/translate/impl/data_processing_multiply.cpp b/src/frontend/A64/translate/impl/data_processing_multiply.cpp index fd5b080d..b7d26516 100644 --- a/src/frontend/A64/translate/impl/data_processing_multiply.cpp +++ b/src/frontend/A64/translate/impl/data_processing_multiply.cpp @@ -35,5 +35,49 @@ bool TranslatorVisitor::MSUB(bool sf, Reg Rm, Reg Ra, Reg Rn, Reg Rd) { return true; } +bool TranslatorVisitor::SMADDL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) { + const IR::U64 a = X(64, Ra); + const IR::U64 m = ir.SignExtendToLong(X(32, Rm)); + const IR::U64 n = ir.SignExtendToLong(X(32, Rn)); + + const IR::U64 result = ir.Add(a, ir.Mul(n, m)); + + X(64, Rd, result); + return true; +} + +bool TranslatorVisitor::SMSUBL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) { + const IR::U64 a = X(64, Ra); + const IR::U64 m = ir.SignExtendToLong(X(32, Rm)); + const IR::U64 n = ir.SignExtendToLong(X(32, Rn)); + + const IR::U64 result = ir.Sub(a, ir.Mul(n, m)); + + X(64, Rd, result); + return true; +} + +bool TranslatorVisitor::UMADDL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) { + const IR::U64 a = X(64, Ra); + const IR::U64 m = ir.ZeroExtendToLong(X(32, Rm)); + const IR::U64 n = ir.ZeroExtendToLong(X(32, Rn)); + + const IR::U64 result = ir.Add(a, ir.Mul(n, m)); + + X(64, Rd, result); + return true; +} + +bool TranslatorVisitor::UMSUBL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) { + const IR::U64 a = X(64, Ra); + const IR::U64 m = ir.ZeroExtendToLong(X(32, Rm)); + const IR::U64 n = ir.ZeroExtendToLong(X(32, Rn)); + + const IR::U64 result = ir.Sub(a, ir.Mul(n, m)); + + X(64, Rd, result); + return true; +} + } // namespace A64 } // namespace Dynarmic