From 1643e8f3c643cd280ecf881d43e4acacc0401499 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 15 May 2021 20:54:35 +0100 Subject: [PATCH] translate_thumb: VFP/ASIMD conflict with coprocessor instructions --- .../A32/translate/translate_thumb.cpp | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index e4d62c0b..69e9b7ba 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -79,6 +79,10 @@ u32 ConvertASIMDInstruction(u32 thumb_instruction) { return 0xF7F0A000; // UDF } +bool MaybeVFPOrASIMDInstruction(u32 thumb_instruction) { + return (thumb_instruction & 0xEC000000) == 0xEC000000 || (thumb_instruction & 0xFF100000) == 0xF9000000; +} + } // local namespace 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(); } } else { - if (const auto decoder = DecodeThumb32(thumb_instruction)) { - should_continue = decoder->get().call(visitor, thumb_instruction); - } else if ((thumb_instruction & 0xEC000000) == 0xEC000000 || (thumb_instruction & 0xFF100000) == 0xF9000000) { + if (MaybeVFPOrASIMDInstruction(thumb_instruction)) { if (const auto vfp_decoder = DecodeVFP(thumb_instruction)) { should_continue = vfp_decoder->get().call(visitor, thumb_instruction); } else if (const auto asimd_decoder = DecodeASIMD(ConvertASIMDInstruction(thumb_instruction))) { should_continue = asimd_decoder->get().call(visitor, ConvertASIMDInstruction(thumb_instruction)); + } else if (const auto decoder = DecodeThumb32(thumb_instruction)) { + should_continue = decoder->get().call(visitor, thumb_instruction); } else { should_continue = visitor.thumb32_UDF(); } + } else if (const auto decoder = DecodeThumb32(thumb_instruction)) { + should_continue = decoder->get().call(visitor, thumb_instruction); } else { should_continue = visitor.thumb32_UDF(); } @@ -156,16 +162,18 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri } } else { thumb_instruction = Common::SwapHalves32(thumb_instruction); - if (const auto decoder = DecodeThumb32(thumb_instruction)) { - should_continue = decoder->get().call(visitor, thumb_instruction); - } else if ((thumb_instruction & 0xEC000000) == 0xEC000000 || (thumb_instruction & 0xFF100000) == 0xF9000000) { + if (MaybeVFPOrASIMDInstruction(thumb_instruction)) { if (const auto vfp_decoder = DecodeVFP(thumb_instruction)) { should_continue = vfp_decoder->get().call(visitor, thumb_instruction); } else if (const auto asimd_decoder = DecodeASIMD(ConvertASIMDInstruction(thumb_instruction))) { should_continue = asimd_decoder->get().call(visitor, ConvertASIMDInstruction(thumb_instruction)); + } else if (const auto decoder = DecodeThumb32(thumb_instruction)) { + should_continue = decoder->get().call(visitor, thumb_instruction); } else { should_continue = visitor.thumb32_UDF(); } + } else if (const auto decoder = DecodeThumb32(thumb_instruction)) { + should_continue = decoder->get().call(visitor, thumb_instruction); } else { should_continue = visitor.thumb32_UDF(); }