Merge pull request #580 from lioncash/shift

thumb32: Implement ASR, LSL, LSR, and ROR register variants
This commit is contained in:
merry 2021-02-26 19:07:12 +00:00 committed by GitHub
commit bf7d1a17ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 5 deletions

View file

@ -189,10 +189,10 @@ INST(thumb32_BLX_imm, "BLX (imm)", "11110Svvvvvvvvvv11j0jv
//INST(thumb32_LDR_imm12, "LDR (imm12)", "111110001101--------------------")
// Data Processing (register)
//INST(thumb32_LSL_reg, "LSL (reg)", "11111010000-----1111----0000----")
//INST(thumb32_LSR_reg, "LSR (reg)", "11111010001-----1111----0000----")
//INST(thumb32_ASR_reg, "ASR (reg)", "11111010010-----1111----0000----")
//INST(thumb32_ROR_reg, "ROR (reg)", "11111010011-----1111----0000----")
INST(thumb32_LSL_reg, "LSL (reg)", "111110100000mmmm1111dddd0000ssss")
INST(thumb32_LSR_reg, "LSR (reg)", "111110100010mmmm1111dddd0000ssss")
INST(thumb32_ASR_reg, "ASR (reg)", "111110100100mmmm1111dddd0000ssss")
INST(thumb32_ROR_reg, "ROR (reg)", "111110100110mmmm1111dddd0000ssss")
INST(thumb32_SXTH, "SXTH", "11111010000011111111dddd10rrmmmm")
INST(thumb32_SXTAH, "SXTAH", "111110100000nnnn1111dddd10rrmmmm")
INST(thumb32_UXTH, "UXTH", "11111010000111111111dddd10rrmmmm")

View file

@ -6,11 +6,44 @@
#include "frontend/A32/translate/impl/translate_thumb.h"
namespace Dynarmic::A32 {
static IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) {
namespace {
IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) {
const u8 rotate_by = static_cast<u8>(static_cast<size_t>(rotate) * 8);
return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result;
}
using ShiftFunction = IR::ResultAndCarry<IR::U32> (IREmitter::*)(const IR::U32&, const IR::U8&, const IR::U1&);
bool ShiftInstruction(ThumbTranslatorVisitor& v, Reg m, Reg d, Reg s, ShiftFunction shift_fn) {
if (d == Reg::PC || m == Reg::PC || s == Reg::PC) {
return v.UnpredictableInstruction();
}
const auto shift_s = v.ir.LeastSignificantByte(v.ir.GetRegister(s));
const auto apsr_c = v.ir.GetCFlag();
const auto result_carry = (v.ir.*shift_fn)(v.ir.GetRegister(m), shift_s, apsr_c);
v.ir.SetRegister(d, result_carry.result);
return true;
}
} // Anonymous namespace
bool ThumbTranslatorVisitor::thumb32_ASR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::ArithmeticShiftRight);
}
bool ThumbTranslatorVisitor::thumb32_LSL_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftLeft);
}
bool ThumbTranslatorVisitor::thumb32_LSR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::LogicalShiftRight);
}
bool ThumbTranslatorVisitor::thumb32_ROR_reg(Reg m, Reg d, Reg s) {
return ShiftInstruction(*this, m, d, s, &IREmitter::RotateRight);
}
bool ThumbTranslatorVisitor::thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m) {
if (d == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();

View file

@ -182,6 +182,10 @@ struct ThumbTranslatorVisitor final {
bool thumb32_BLX_imm(Imm<1> S, Imm<10> hi, Imm<1> j1, Imm<1> j2, Imm<11> lo);
// thumb32 data processing (register) instructions
bool thumb32_ASR_reg(Reg m, Reg d, Reg s);
bool thumb32_LSL_reg(Reg m, Reg d, Reg s);
bool thumb32_LSR_reg(Reg m, Reg d, Reg s);
bool thumb32_ROR_reg(Reg m, Reg d, Reg s);
bool thumb32_SXTB(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTB16(Reg d, SignExtendRotation rotate, Reg m);
bool thumb32_SXTAB(Reg n, Reg d, SignExtendRotation rotate, Reg m);