thumb32: Implement SBFX/UBFX

This commit is contained in:
Lioncash 2021-02-25 09:32:01 -05:00
parent 7334914047
commit 68885fdb3c
3 changed files with 51 additions and 4 deletions

View file

@ -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-----")

View file

@ -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);
}

View file

@ -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