thumb32: Implement TST (reg)

This commit is contained in:
MerryMage 2021-03-06 18:39:48 +00:00
parent ea5d8a3047
commit c253b8fc51
4 changed files with 51 additions and 2 deletions

View file

@ -157,9 +157,10 @@ if ("A32" IN_LIST DYNARMIC_FRONTENDS)
frontend/A32/translate/impl/thumb16.cpp
frontend/A32/translate/impl/thumb32_branch.cpp
frontend/A32/translate/impl/thumb32_control.cpp
frontend/A32/translate/impl/thumb32_data_processing_register.cpp
frontend/A32/translate/impl/thumb32_data_processing_modified_immediate.cpp
frontend/A32/translate/impl/thumb32_data_processing_plain_binary_immediate.cpp
frontend/A32/translate/impl/thumb32_data_processing_register.cpp
frontend/A32/translate/impl/thumb32_data_processing_shifted_register.cpp
frontend/A32/translate/impl/thumb32_load_byte.cpp
frontend/A32/translate/impl/thumb32_load_halfword.cpp
frontend/A32/translate/impl/thumb32_load_word.cpp

View file

@ -29,7 +29,7 @@
//INST(thumb32_LDREXD, "LDREXD", "111010001101------------0111----")
// Data Processing (Shifted Register)
//INST(thumb32_TST_reg, "TST (reg)", "111010100001--------1111--------")
INST(thumb32_TST_reg, "TST (reg)", "111010100001nnnn0vvv1111vvttmmmm")
//INST(thumb32_AND_reg, "AND (reg)", "11101010000---------------------")
//INST(thumb32_BIC_reg, "BIC (reg)", "11101010001---------------------")
//INST(thumb32_MOV_reg, "MOV (reg)", "11101010010-1111-000----0000----")

View file

@ -0,0 +1,24 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#include "frontend/A32/translate/impl/translate_thumb.h"
namespace Dynarmic::A32 {
bool ThumbTranslatorVisitor::thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m) {
if (n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
const auto shifted = EmitImmShift(ir.GetRegister(m), type, imm3, imm2, ir.GetCFlag());
const auto result = ir.And(ir.GetRegister(n), shifted.result);
ir.SetNFlag(ir.MostSignificantBit(result));
ir.SetZFlag(ir.IsZero(result));
ir.SetCFlag(shifted.carry);
return true;
}
} // namespace Dynarmic::A32

View file

@ -56,6 +56,27 @@ struct ThumbTranslatorVisitor final {
return ThumbExpandImm_C(i, imm3, imm8, ir.Imm1(0)).imm32;
}
IR::ResultAndCarry<IR::U32> EmitImmShift(IR::U32 value, ShiftType type, Imm<3> imm3, Imm<2> imm2, IR::U1 carry_in) {
u8 imm5_value = concatenate(imm3, imm2).ZeroExtend<u8>();
switch (type) {
case ShiftType::LSL:
return ir.LogicalShiftLeft(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::LSR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.LogicalShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ASR:
imm5_value = imm5_value ? imm5_value : 32;
return ir.ArithmeticShiftRight(value, ir.Imm8(imm5_value), carry_in);
case ShiftType::ROR:
if (imm5_value) {
return ir.RotateRight(value, ir.Imm8(imm5_value), carry_in);
} else {
return ir.RotateRightExtended(value, carry_in);
}
}
UNREACHABLE();
}
A32::IREmitter ir;
ConditionalState cond_state = ConditionalState::None;
TranslationOptions options;
@ -150,6 +171,9 @@ struct ThumbTranslatorVisitor final {
bool thumb16_B_t1(Cond cond, Imm<8> imm8);
bool thumb16_B_t2(Imm<11> imm11);
// thumb32 data processing (shifted register) instructions
bool thumb32_TST_reg(Reg n, Imm<3> imm3, Imm<2> imm2, ShiftType type, Reg m);
// thumb32 data processing (modified immediate) instructions
bool thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
bool thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);