thumb32: Implement SBFX/UBFX
This commit is contained in:
parent
7334914047
commit
68885fdb3c
3 changed files with 51 additions and 4 deletions
|
@ -78,15 +78,15 @@ INST(thumb32_MOVW_imm, "MOVW (imm)", "11110i100100iiii0iiidd
|
|||
//INST(thumb32_SUB_imm_2, "SUB (imm)", "11110-101010----0---------------")
|
||||
INST(thumb32_MOVT, "MOVT", "11110i101100iiii0iiiddddiiiiiiii")
|
||||
//INST(thumb32_SSAT, "SSAT", "11110-110000----0---------------")
|
||||
INST(thumb32_SSAT16, "SSAT16", "111100110010nnnn0000dddd0000iiii")
|
||||
//INST(thumb32_SSAT, "SSAT", "11110-110010----0---------------")
|
||||
//INST(thumb32_SBFX, "SBFX", "11110-110100----0---------------")
|
||||
INST(thumb32_SSAT16, "SSAT16", "111100110010nnnn0000dddd0000iiii")
|
||||
INST(thumb32_SBFX, "SBFX", "111100110100nnnn0iiiddddii0wwwww")
|
||||
INST(thumb32_BFC, "BFC", "11110011011011110iiiddddii0bbbbb")
|
||||
INST(thumb32_BFI, "BFI", "111100110110nnnn0iiiddddii0bbbbb")
|
||||
//INST(thumb32_USAT, "USAT", "11110-111000----0---------------")
|
||||
INST(thumb32_USAT16, "USAT16", "111100111010nnnn0000dddd0000iiii")
|
||||
//INST(thumb32_USAT, "USAT", "11110-111010----0---------------")
|
||||
//INST(thumb32_UBFX, "UBFX", "11110-111100----0---------------")
|
||||
INST(thumb32_USAT16, "USAT16", "111100111010nnnn0000dddd0000iiii")
|
||||
INST(thumb32_UBFX, "UBFX", "111100111100nnnn0iiiddddii0wwwww")
|
||||
|
||||
// Branches and Miscellaneous Control
|
||||
//INST(thumb32_MSR_banked, "MSR (banked)", "11110011100-----10-0------1-----")
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "common/bit_util.h"
|
||||
#include "frontend/A32/translate/impl/translate_thumb.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
@ -100,10 +101,54 @@ bool ThumbTranslatorVisitor::thumb32_MOVW_imm(Imm<1> imm1, Imm<4> imm4, Imm<3> i
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ThumbTranslatorVisitor::thumb32_SBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1) {
|
||||
if (d == Reg::PC || n == Reg::PC) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
const u32 lsbit = concatenate(imm3, imm2).ZeroExtend();
|
||||
const u32 widthm1_value = widthm1.ZeroExtend();
|
||||
const u32 msb = lsbit + widthm1_value;
|
||||
if (msb >= Common::BitSize<u32>()) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
constexpr size_t max_width = Common::BitSize<u32>();
|
||||
const auto width = widthm1_value + 1;
|
||||
const auto left_shift_amount = static_cast<u8>(max_width - width - lsbit);
|
||||
const auto right_shift_amount = static_cast<u8>(max_width - width);
|
||||
const auto operand = ir.GetRegister(n);
|
||||
const auto tmp = ir.LogicalShiftLeft(operand, ir.Imm8(left_shift_amount));
|
||||
const auto result = ir.ArithmeticShiftRight(tmp, ir.Imm8(right_shift_amount));
|
||||
|
||||
ir.SetRegister(d, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ThumbTranslatorVisitor::thumb32_SSAT16(Reg n, Reg d, Imm<4> sat_imm) {
|
||||
return Saturation16(*this, n, d, sat_imm.ZeroExtend() + 1, &IREmitter::SignedSaturation);
|
||||
}
|
||||
|
||||
bool ThumbTranslatorVisitor::thumb32_UBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1) {
|
||||
if (d == Reg::PC || n == Reg::PC) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
const u32 lsbit = concatenate(imm3, imm2).ZeroExtend();
|
||||
const u32 widthm1_value = widthm1.ZeroExtend();
|
||||
const u32 msb = lsbit + widthm1_value;
|
||||
if (msb >= Common::BitSize<u32>()) {
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
const auto operand = ir.GetRegister(n);
|
||||
const auto mask = ir.Imm32(Common::Ones<u32>(widthm1_value + 1));
|
||||
const auto result = ir.And(ir.LogicalShiftRight(operand, ir.Imm8(u8(lsbit))), mask);
|
||||
|
||||
ir.SetRegister(d, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ThumbTranslatorVisitor::thumb32_USAT16(Reg n, Reg d, Imm<4> sat_imm) {
|
||||
return Saturation16(*this, n, d, sat_imm.ZeroExtend(), &IREmitter::UnsignedSaturation);
|
||||
}
|
||||
|
|
|
@ -164,7 +164,9 @@ struct ThumbTranslatorVisitor final {
|
|||
bool thumb32_BFI(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> msb);
|
||||
bool thumb32_MOVT(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8);
|
||||
bool thumb32_MOVW_imm(Imm<1> imm1, Imm<4> imm4, Imm<3> imm3, Reg d, Imm<8> imm8);
|
||||
bool thumb32_SBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1);
|
||||
bool thumb32_SSAT16(Reg n, Reg d, Imm<4> sat_imm);
|
||||
bool thumb32_UBFX(Reg n, Imm<3> imm3, Reg d, Imm<2> imm2, Imm<5> widthm1);
|
||||
bool thumb32_USAT16(Reg n, Reg d, Imm<4> sat_imm);
|
||||
|
||||
// thumb32 miscellaneous control instructions
|
||||
|
|
Loading…
Reference in a new issue