thumb32: Implement TST (reg)
This commit is contained in:
parent
ea5d8a3047
commit
c253b8fc51
4 changed files with 51 additions and 2 deletions
|
@ -157,9 +157,10 @@ if ("A32" IN_LIST DYNARMIC_FRONTENDS)
|
||||||
frontend/A32/translate/impl/thumb16.cpp
|
frontend/A32/translate/impl/thumb16.cpp
|
||||||
frontend/A32/translate/impl/thumb32_branch.cpp
|
frontend/A32/translate/impl/thumb32_branch.cpp
|
||||||
frontend/A32/translate/impl/thumb32_control.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_modified_immediate.cpp
|
||||||
frontend/A32/translate/impl/thumb32_data_processing_plain_binary_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_byte.cpp
|
||||||
frontend/A32/translate/impl/thumb32_load_halfword.cpp
|
frontend/A32/translate/impl/thumb32_load_halfword.cpp
|
||||||
frontend/A32/translate/impl/thumb32_load_word.cpp
|
frontend/A32/translate/impl/thumb32_load_word.cpp
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
//INST(thumb32_LDREXD, "LDREXD", "111010001101------------0111----")
|
//INST(thumb32_LDREXD, "LDREXD", "111010001101------------0111----")
|
||||||
|
|
||||||
// Data Processing (Shifted Register)
|
// 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_AND_reg, "AND (reg)", "11101010000---------------------")
|
||||||
//INST(thumb32_BIC_reg, "BIC (reg)", "11101010001---------------------")
|
//INST(thumb32_BIC_reg, "BIC (reg)", "11101010001---------------------")
|
||||||
//INST(thumb32_MOV_reg, "MOV (reg)", "11101010010-1111-000----0000----")
|
//INST(thumb32_MOV_reg, "MOV (reg)", "11101010010-1111-000----0000----")
|
||||||
|
|
|
@ -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
|
|
@ -56,6 +56,27 @@ struct ThumbTranslatorVisitor final {
|
||||||
return ThumbExpandImm_C(i, imm3, imm8, ir.Imm1(0)).imm32;
|
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;
|
A32::IREmitter ir;
|
||||||
ConditionalState cond_state = ConditionalState::None;
|
ConditionalState cond_state = ConditionalState::None;
|
||||||
TranslationOptions options;
|
TranslationOptions options;
|
||||||
|
@ -150,6 +171,9 @@ struct ThumbTranslatorVisitor final {
|
||||||
bool thumb16_B_t1(Cond cond, Imm<8> imm8);
|
bool thumb16_B_t1(Cond cond, Imm<8> imm8);
|
||||||
bool thumb16_B_t2(Imm<11> imm11);
|
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
|
// thumb32 data processing (modified immediate) instructions
|
||||||
bool thumb32_TST_imm(Imm<1> i, Reg n, Imm<3> imm3, Imm<8> imm8);
|
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);
|
bool thumb32_AND_imm(Imm<1> i, bool S, Reg n, Imm<3> imm3, Reg d, Imm<8> imm8);
|
||||||
|
|
Loading…
Reference in a new issue