diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a2ad95bd..09438116 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,6 +66,7 @@ add_library(dynarmic frontend/A64/translate/impl/data_processing_logical.cpp frontend/A64/translate/impl/data_processing_pcrel.cpp frontend/A64/translate/impl/data_processing_register.cpp + frontend/A64/translate/impl/data_processing_shift.cpp frontend/A64/translate/impl/exception_generating.cpp frontend/A64/translate/impl/impl.cpp frontend/A64/translate/impl/impl.h diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 9cb0886f..be0f0cb7 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -276,10 +276,10 @@ INST(UnallocatedEncoding, "", "10111 // Data Processing - Register - 2 source //INST(UDIV, "UDIV", "z0011010110mmmmm000010nnnnnddddd") //INST(SDIV, "SDIV", "z0011010110mmmmm000011nnnnnddddd") -//INST(LSLV, "LSLV", "z0011010110mmmmm001000nnnnnddddd") -//INST(LSRV, "LSRV", "z0011010110mmmmm001001nnnnnddddd") -//INST(ASRV, "ASRV", "z0011010110mmmmm001010nnnnnddddd") -//INST(RORV, "RORV", "z0011010110mmmmm001011nnnnnddddd") +INST(LSLV, "LSLV", "z0011010110mmmmm001000nnnnnddddd") +INST(LSRV, "LSRV", "z0011010110mmmmm001001nnnnnddddd") +INST(ASRV, "ASRV", "z0011010110mmmmm001010nnnnnddddd") +INST(RORV, "RORV", "z0011010110mmmmm001011nnnnnddddd") //INST(CRC32, "CRC32B, CRC32H, CRC32W, CRC32X", "z0011010110mmmmm0100zznnnnnddddd") //INST(CRC32C, "CRC32CB, CRC32CH, CRC32CW, CRC32CX", "z0011010110mmmmm0101zznnnnnddddd") //INST(PACGA, "PACGA", "10011010110mmmmm001100nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/data_processing_shift.cpp b/src/frontend/A64/translate/impl/data_processing_shift.cpp new file mode 100644 index 00000000..1425d2ea --- /dev/null +++ b/src/frontend/A64/translate/impl/data_processing_shift.cpp @@ -0,0 +1,66 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 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 "frontend/A64/translate/impl/impl.h" + +namespace Dynarmic { +namespace A64 { + +static IR::U8 SanitizeShiftAmount(TranslatorVisitor& tv, IREmitter& ir, size_t datasize, + const IR::U32U64& amount) { + return ir.LeastSignificantByte(ir.And(amount, tv.I(datasize, datasize - 1))); +} + +bool TranslatorVisitor::LSLV(bool sf, Reg Rm, Reg Rn, Reg Rd) { + const size_t datasize = sf ? 64 : 32; + + const IR::U32U64 operand = X(datasize, Rn); + const IR::U32U64 shift_amount = X(datasize, Rm); + + const IR::U32U64 result = ir.LogicalShiftLeft(operand, SanitizeShiftAmount(*this, ir, datasize, shift_amount)); + + X(datasize, Rd, result); + return true; +} + +bool TranslatorVisitor::LSRV(bool sf, Reg Rm, Reg Rn, Reg Rd) { + const size_t datasize = sf ? 64 : 32; + + const IR::U32U64 operand = X(datasize, Rn); + const IR::U32U64 shift_amount = X(datasize, Rm); + + const IR::U32U64 result = ir.LogicalShiftRight(operand, SanitizeShiftAmount(*this, ir, datasize, shift_amount)); + + X(datasize, Rd, result); + return true; +} + +bool TranslatorVisitor::ASRV(bool sf, Reg Rm, Reg Rn, Reg Rd) { + const size_t datasize = sf ? 64 : 32; + + const IR::U32U64 operand = X(datasize, Rn); + const IR::U32U64 shift_amount = X(datasize, Rm); + + const IR::U32U64 result = ir.ArithmeticShiftRight(operand, SanitizeShiftAmount(*this, ir, datasize, shift_amount)); + + X(datasize, Rd, result); + return true; +} + +bool TranslatorVisitor::RORV(bool sf, Reg Rm, Reg Rn, Reg Rd) { + const size_t datasize = sf ? 64 : 32; + + const IR::U32U64 operand = X(datasize, Rn); + const IR::U32U64 shift_amount = X(datasize, Rm); + + const IR::U32U64 result = ir.RotateRight(operand, SanitizeShiftAmount(*this, ir, datasize, shift_amount)); + + X(datasize, Rd, result); + return true; +} + +} // namespace A64 +} // namespace Dynarmic