translate_thumb: VFP/ASIMD conflict with coprocessor instructions

This commit is contained in:
MerryMage 2021-05-15 20:54:35 +01:00
parent 105b464bc1
commit 1643e8f3c6

View file

@ -79,6 +79,10 @@ u32 ConvertASIMDInstruction(u32 thumb_instruction) {
return 0xF7F0A000; // UDF return 0xF7F0A000; // UDF
} }
bool MaybeVFPOrASIMDInstruction(u32 thumb_instruction) {
return (thumb_instruction & 0xEC000000) == 0xEC000000 || (thumb_instruction & 0xFF100000) == 0xF9000000;
}
} // local namespace } // local namespace
IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, const TranslationOptions& options) { IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, const TranslationOptions& options) {
@ -102,16 +106,18 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
should_continue = visitor.thumb16_UDF(); should_continue = visitor.thumb16_UDF();
} }
} else { } else {
if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) { if (MaybeVFPOrASIMDInstruction(thumb_instruction)) {
should_continue = decoder->get().call(visitor, thumb_instruction);
} else if ((thumb_instruction & 0xEC000000) == 0xEC000000 || (thumb_instruction & 0xFF100000) == 0xF9000000) {
if (const auto vfp_decoder = DecodeVFP<TranslatorVisitor>(thumb_instruction)) { if (const auto vfp_decoder = DecodeVFP<TranslatorVisitor>(thumb_instruction)) {
should_continue = vfp_decoder->get().call(visitor, thumb_instruction); should_continue = vfp_decoder->get().call(visitor, thumb_instruction);
} else if (const auto asimd_decoder = DecodeASIMD<TranslatorVisitor>(ConvertASIMDInstruction(thumb_instruction))) { } else if (const auto asimd_decoder = DecodeASIMD<TranslatorVisitor>(ConvertASIMDInstruction(thumb_instruction))) {
should_continue = asimd_decoder->get().call(visitor, ConvertASIMDInstruction(thumb_instruction)); should_continue = asimd_decoder->get().call(visitor, ConvertASIMDInstruction(thumb_instruction));
} else if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
should_continue = decoder->get().call(visitor, thumb_instruction);
} else { } else {
should_continue = visitor.thumb32_UDF(); should_continue = visitor.thumb32_UDF();
} }
} else if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
should_continue = decoder->get().call(visitor, thumb_instruction);
} else { } else {
should_continue = visitor.thumb32_UDF(); should_continue = visitor.thumb32_UDF();
} }
@ -156,16 +162,18 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri
} }
} else { } else {
thumb_instruction = Common::SwapHalves32(thumb_instruction); thumb_instruction = Common::SwapHalves32(thumb_instruction);
if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) { if (MaybeVFPOrASIMDInstruction(thumb_instruction)) {
should_continue = decoder->get().call(visitor, thumb_instruction);
} else if ((thumb_instruction & 0xEC000000) == 0xEC000000 || (thumb_instruction & 0xFF100000) == 0xF9000000) {
if (const auto vfp_decoder = DecodeVFP<TranslatorVisitor>(thumb_instruction)) { if (const auto vfp_decoder = DecodeVFP<TranslatorVisitor>(thumb_instruction)) {
should_continue = vfp_decoder->get().call(visitor, thumb_instruction); should_continue = vfp_decoder->get().call(visitor, thumb_instruction);
} else if (const auto asimd_decoder = DecodeASIMD<TranslatorVisitor>(ConvertASIMDInstruction(thumb_instruction))) { } else if (const auto asimd_decoder = DecodeASIMD<TranslatorVisitor>(ConvertASIMDInstruction(thumb_instruction))) {
should_continue = asimd_decoder->get().call(visitor, ConvertASIMDInstruction(thumb_instruction)); should_continue = asimd_decoder->get().call(visitor, ConvertASIMDInstruction(thumb_instruction));
} else if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
should_continue = decoder->get().call(visitor, thumb_instruction);
} else { } else {
should_continue = visitor.thumb32_UDF(); should_continue = visitor.thumb32_UDF();
} }
} else if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
should_continue = decoder->get().call(visitor, thumb_instruction);
} else { } else {
should_continue = visitor.thumb32_UDF(); should_continue = visitor.thumb32_UDF();
} }