From a8a65beb2be31413e95262f51161221e310e1043 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 21 Jan 2018 14:24:44 -0500 Subject: [PATCH] data_processsing_conditional_select: Implement CSINC, CSINV and CSNEG --- src/frontend/A64/decoder/a64.inc | 6 ++-- .../data_processing_conditional_select.cpp | 36 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 80f76a79..9cb0886f 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -332,9 +332,9 @@ INST(SBCS, "SBCS", "z1111 // Data Processing - Register - Conditional select INST(CSEL, "CSEL", "z0011010100mmmmmcccc00nnnnnddddd") -//INST(CSINC, "CSINC", "z0011010100mmmmmcccc01nnnnnddddd") -//INST(CSINV, "CSINV", "z1011010100mmmmmcccc00nnnnnddddd") -//INST(CSNEG, "CSNEG", "z1011010100mmmmmcccc01nnnnnddddd") +INST(CSINC, "CSINC", "z0011010100mmmmmcccc01nnnnnddddd") +INST(CSINV, "CSINV", "z1011010100mmmmmcccc00nnnnnddddd") +INST(CSNEG, "CSNEG", "z1011010100mmmmmcccc01nnnnnddddd") // Data Processing - Register - 3 source //INST(MADD, "MADD", "z0011011000mmmmm0aaaaannnnnddddd") diff --git a/src/frontend/A64/translate/impl/data_processing_conditional_select.cpp b/src/frontend/A64/translate/impl/data_processing_conditional_select.cpp index 9179ea58..5b319b5f 100644 --- a/src/frontend/A64/translate/impl/data_processing_conditional_select.cpp +++ b/src/frontend/A64/translate/impl/data_processing_conditional_select.cpp @@ -22,5 +22,41 @@ bool TranslatorVisitor::CSEL(bool sf, Reg Rm, Cond cond, Reg Rn, Reg Rd) { return true; } +bool TranslatorVisitor::CSINC(bool sf, Reg Rm, Cond cond, Reg Rn, Reg Rd) { + const size_t datasize = sf ? 64 : 32; + + const IR::U32U64 operand1 = X(datasize, Rn); + const IR::U32U64 operand2 = X(datasize, Rm); + + const IR::U32U64 result = ir.ConditionalSelect(cond, operand1, ir.Add(operand2, I(datasize, 1))); + + X(datasize, Rd, result); + return true; +} + +bool TranslatorVisitor::CSINV(bool sf, Reg Rm, Cond cond, Reg Rn, Reg Rd) { + const size_t datasize = sf ? 64 : 32; + + const IR::U32U64 operand1 = X(datasize, Rn); + const IR::U32U64 operand2 = X(datasize, Rm); + + const IR::U32U64 result = ir.ConditionalSelect(cond, operand1, ir.Not(operand2)); + + X(datasize, Rd, result); + return true; +} + +bool TranslatorVisitor::CSNEG(bool sf, Reg Rm, Cond cond, Reg Rn, Reg Rd) { + const size_t datasize = sf ? 64 : 32; + + const IR::U32U64 operand1 = X(datasize, Rn); + const IR::U32U64 operand2 = X(datasize, Rm); + + const IR::U32U64 result = ir.ConditionalSelect(cond, operand1, ir.Add(ir.Not(operand2), I(datasize, 1))); + + X(datasize, Rd, result); + return true; +} + } // namespace A64 } // namespace Dynarmic