early-access version 1255
This commit is contained in:
53
externals/dynarmic/src/frontend/A32/decoder/arm.h
vendored
Executable file
53
externals/dynarmic/src/frontend/A32/decoder/arm.h
vendored
Executable file
@@ -0,0 +1,53 @@
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2016 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*
|
||||
* Original version of table by Lioncash.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "common/bit_util.h"
|
||||
#include "common/common_types.h"
|
||||
#include "frontend/decoder/decoder_detail.h"
|
||||
#include "frontend/decoder/matcher.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
template <typename Visitor>
|
||||
using ArmMatcher = Decoder::Matcher<Visitor, u32>;
|
||||
|
||||
template <typename V>
|
||||
std::vector<ArmMatcher<V>> GetArmDecodeTable() {
|
||||
std::vector<ArmMatcher<V>> table = {
|
||||
|
||||
#define INST(fn, name, bitstring) Decoder::detail::detail<ArmMatcher<V>>::GetMatcher(&V::fn, name, bitstring),
|
||||
#include "arm.inc"
|
||||
#undef INST
|
||||
|
||||
};
|
||||
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
std::stable_sort(table.begin(), table.end(), [](const auto& matcher1, const auto& matcher2) {
|
||||
return Common::BitCount(matcher1.GetMask()) > Common::BitCount(matcher2.GetMask());
|
||||
});
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
std::optional<std::reference_wrapper<const ArmMatcher<V>>> DecodeArm(u32 instruction) {
|
||||
static const auto table = GetArmDecodeTable<V>();
|
||||
|
||||
const auto matches_instruction = [instruction](const auto& matcher) { return matcher.Matches(instruction); };
|
||||
|
||||
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
|
||||
return iter != table.end() ? std::optional<std::reference_wrapper<const ArmMatcher<V>>>(*iter) : std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
316
externals/dynarmic/src/frontend/A32/decoder/arm.inc
vendored
Executable file
316
externals/dynarmic/src/frontend/A32/decoder/arm.inc
vendored
Executable file
@@ -0,0 +1,316 @@
|
||||
// Barrier instructions
|
||||
INST(arm_DMB, "DMB", "1111010101111111111100000101oooo") // v7
|
||||
INST(arm_DSB, "DSB", "1111010101111111111100000100oooo") // v7
|
||||
INST(arm_ISB, "ISB", "1111010101111111111100000110oooo") // v7
|
||||
|
||||
// Branch instructions
|
||||
INST(arm_BLX_imm, "BLX (imm)", "1111101hvvvvvvvvvvvvvvvvvvvvvvvv") // v5
|
||||
INST(arm_BLX_reg, "BLX (reg)", "cccc000100101111111111110011mmmm") // v5
|
||||
INST(arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv") // all
|
||||
INST(arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv") // all
|
||||
INST(arm_BX, "BX", "cccc000100101111111111110001mmmm") // v4T
|
||||
INST(arm_BXJ, "BXJ", "cccc000100101111111111110010mmmm") // v5J
|
||||
|
||||
// CRC32 instructions
|
||||
INST(arm_CRC32, "CRC32", "cccc00010zz0nnnndddd00000100mmmm") // v8
|
||||
INST(arm_CRC32C, "CRC32C", "cccc00010zz0nnnndddd00100100mmmm") // v8
|
||||
|
||||
// Coprocessor instructions
|
||||
INST(arm_CDP, "CDP", "cccc1110ooooNNNNDDDDppppooo0MMMM") // v2 (CDP2: v5)
|
||||
INST(arm_LDC, "LDC", "cccc110pudw1nnnnDDDDppppvvvvvvvv") // v2 (LDC2: v5)
|
||||
INST(arm_MCR, "MCR", "cccc1110ooo0NNNNttttppppooo1MMMM") // v2 (MCR2: v5)
|
||||
INST(arm_MCRR, "MCRR", "cccc11000100uuuuttttppppooooMMMM") // v5E (MCRR2: v6)
|
||||
INST(arm_MRC, "MRC", "cccc1110ooo1NNNNttttppppooo1MMMM") // v2 (MRC2: v5)
|
||||
INST(arm_MRRC, "MRRC", "cccc11000101uuuuttttppppooooMMMM") // v5E (MRRC2: v6)
|
||||
INST(arm_STC, "STC", "cccc110pudw0nnnnDDDDppppvvvvvvvv") // v2 (STC2: v5)
|
||||
|
||||
// Data Processing instructions
|
||||
INST(arm_ADC_imm, "ADC (imm)", "cccc0010101Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_ADC_reg, "ADC (reg)", "cccc0000101Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_ADC_rsr, "ADC (rsr)", "cccc0000101Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_ADD_imm, "ADD (imm)", "cccc0010100Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_ADD_reg, "ADD (reg)", "cccc0000100Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_ADD_rsr, "ADD (rsr)", "cccc0000100Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_AND_imm, "AND (imm)", "cccc0010000Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_AND_reg, "AND (reg)", "cccc0000000Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_AND_rsr, "AND (rsr)", "cccc0000000Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_BIC_imm, "BIC (imm)", "cccc0011110Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_BIC_reg, "BIC (reg)", "cccc0001110Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_BIC_rsr, "BIC (rsr)", "cccc0001110Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_CMN_imm, "CMN (imm)", "cccc00110111nnnn0000rrrrvvvvvvvv") // all
|
||||
INST(arm_CMN_reg, "CMN (reg)", "cccc00010111nnnn0000vvvvvrr0mmmm") // all
|
||||
INST(arm_CMN_rsr, "CMN (rsr)", "cccc00010111nnnn0000ssss0rr1mmmm") // all
|
||||
INST(arm_CMP_imm, "CMP (imm)", "cccc00110101nnnn0000rrrrvvvvvvvv") // all
|
||||
INST(arm_CMP_reg, "CMP (reg)", "cccc00010101nnnn0000vvvvvrr0mmmm") // all
|
||||
INST(arm_CMP_rsr, "CMP (rsr)", "cccc00010101nnnn0000ssss0rr1mmmm") // all
|
||||
INST(arm_EOR_imm, "EOR (imm)", "cccc0010001Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_EOR_reg, "EOR (reg)", "cccc0000001Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_EOR_rsr, "EOR (rsr)", "cccc0000001Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_MOV_imm, "MOV (imm)", "cccc0011101S0000ddddrrrrvvvvvvvv") // all
|
||||
INST(arm_MOV_reg, "MOV (reg)", "cccc0001101S0000ddddvvvvvrr0mmmm") // all
|
||||
INST(arm_MOV_rsr, "MOV (rsr)", "cccc0001101S0000ddddssss0rr1mmmm") // all
|
||||
INST(arm_MVN_imm, "MVN (imm)", "cccc0011111S0000ddddrrrrvvvvvvvv") // all
|
||||
INST(arm_MVN_reg, "MVN (reg)", "cccc0001111S0000ddddvvvvvrr0mmmm") // all
|
||||
INST(arm_MVN_rsr, "MVN (rsr)", "cccc0001111S0000ddddssss0rr1mmmm") // all
|
||||
INST(arm_ORR_imm, "ORR (imm)", "cccc0011100Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_ORR_reg, "ORR (reg)", "cccc0001100Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_ORR_rsr, "ORR (rsr)", "cccc0001100Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_RSB_imm, "RSB (imm)", "cccc0010011Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_RSB_reg, "RSB (reg)", "cccc0000011Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_RSB_rsr, "RSB (rsr)", "cccc0000011Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_RSC_imm, "RSC (imm)", "cccc0010111Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_RSC_reg, "RSC (reg)", "cccc0000111Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_RSC_rsr, "RSC (rsr)", "cccc0000111Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_SBC_imm, "SBC (imm)", "cccc0010110Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_SBC_reg, "SBC (reg)", "cccc0000110Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_SBC_rsr, "SBC (rsr)", "cccc0000110Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_SUB_imm, "SUB (imm)", "cccc0010010Snnnnddddrrrrvvvvvvvv") // all
|
||||
INST(arm_SUB_reg, "SUB (reg)", "cccc0000010Snnnnddddvvvvvrr0mmmm") // all
|
||||
INST(arm_SUB_rsr, "SUB (rsr)", "cccc0000010Snnnnddddssss0rr1mmmm") // all
|
||||
INST(arm_TEQ_imm, "TEQ (imm)", "cccc00110011nnnn0000rrrrvvvvvvvv") // all
|
||||
INST(arm_TEQ_reg, "TEQ (reg)", "cccc00010011nnnn0000vvvvvrr0mmmm") // all
|
||||
INST(arm_TEQ_rsr, "TEQ (rsr)", "cccc00010011nnnn0000ssss0rr1mmmm") // all
|
||||
INST(arm_TST_imm, "TST (imm)", "cccc00110001nnnn0000rrrrvvvvvvvv") // all
|
||||
INST(arm_TST_reg, "TST (reg)", "cccc00010001nnnn0000vvvvvrr0mmmm") // all
|
||||
INST(arm_TST_rsr, "TST (rsr)", "cccc00010001nnnn0000ssss0rr1mmmm") // all
|
||||
|
||||
// Exception Generating instructions
|
||||
INST(arm_BKPT, "BKPT", "cccc00010010vvvvvvvvvvvv0111vvvv") // v5
|
||||
INST(arm_SVC, "SVC", "cccc1111vvvvvvvvvvvvvvvvvvvvvvvv") // all
|
||||
INST(arm_UDF, "UDF", "111001111111------------1111----") // all
|
||||
|
||||
// Extension instructions
|
||||
INST(arm_SXTB, "SXTB", "cccc011010101111ddddrr000111mmmm") // v6
|
||||
INST(arm_SXTB16, "SXTB16", "cccc011010001111ddddrr000111mmmm") // v6
|
||||
INST(arm_SXTH, "SXTH", "cccc011010111111ddddrr000111mmmm") // v6
|
||||
INST(arm_SXTAB, "SXTAB", "cccc01101010nnnnddddrr000111mmmm") // v6
|
||||
INST(arm_SXTAB16, "SXTAB16", "cccc01101000nnnnddddrr000111mmmm") // v6
|
||||
INST(arm_SXTAH, "SXTAH", "cccc01101011nnnnddddrr000111mmmm") // v6
|
||||
INST(arm_UXTB, "UXTB", "cccc011011101111ddddrr000111mmmm") // v6
|
||||
INST(arm_UXTB16, "UXTB16", "cccc011011001111ddddrr000111mmmm") // v6
|
||||
INST(arm_UXTH, "UXTH", "cccc011011111111ddddrr000111mmmm") // v6
|
||||
INST(arm_UXTAB, "UXTAB", "cccc01101110nnnnddddrr000111mmmm") // v6
|
||||
INST(arm_UXTAB16, "UXTAB16", "cccc01101100nnnnddddrr000111mmmm") // v6
|
||||
INST(arm_UXTAH, "UXTAH", "cccc01101111nnnnddddrr000111mmmm") // v6
|
||||
|
||||
// Hint instructions
|
||||
INST(arm_PLD_imm, "PLD (imm)", "11110101uz01nnnn1111iiiiiiiiiiii") // v5E for PLD; v7 for PLDW
|
||||
INST(arm_PLD_reg, "PLD (reg)", "11110111uz01nnnn1111iiiiitt0mmmm") // v5E for PLD; v7 for PLDW
|
||||
INST(arm_SEV, "SEV", "----0011001000001111000000000100") // v6K
|
||||
INST(arm_SEVL, "SEVL", "----0011001000001111000000000101") // v8
|
||||
INST(arm_WFE, "WFE", "----0011001000001111000000000010") // v6K
|
||||
INST(arm_WFI, "WFI", "----0011001000001111000000000011") // v6K
|
||||
INST(arm_YIELD, "YIELD", "----0011001000001111000000000001") // v6K
|
||||
INST(arm_NOP, "Reserved Hint", "----0011001000001111------------")
|
||||
INST(arm_NOP, "Reserved Hint", "----001100100000111100000000----")
|
||||
|
||||
// Synchronization Primitive instructions
|
||||
INST(arm_CLREX, "CLREX", "11110101011111111111000000011111") // v6K
|
||||
INST(arm_SWP, "SWP", "cccc00010000nnnntttt00001001uuuu") // v2S (v6: Deprecated)
|
||||
INST(arm_SWPB, "SWPB", "cccc00010100nnnntttt00001001uuuu") // v2S (v6: Deprecated)
|
||||
INST(arm_STL, "STL", "cccc00011000nnnn111111001001tttt") // v8
|
||||
INST(arm_STLEX, "STLEX", "cccc00011000nnnndddd11101001tttt") // v8
|
||||
INST(arm_STREX, "STREX", "cccc00011000nnnndddd11111001mmmm") // v6
|
||||
INST(arm_LDA, "LDA", "cccc00011001nnnndddd110010011111") // v8
|
||||
INST(arm_LDAEX, "LDAEX", "cccc00011001nnnndddd111010011111") // v8
|
||||
INST(arm_LDREX, "LDREX", "cccc00011001nnnndddd111110011111") // v6
|
||||
INST(arm_STLEXD, "STLEXD", "cccc00011010nnnndddd11101001mmmm") // v8
|
||||
INST(arm_STREXD, "STREXD", "cccc00011010nnnndddd11111001mmmm") // v6K
|
||||
INST(arm_LDAEXD, "LDAEXD", "cccc00011011nnnndddd111010011111") // v8
|
||||
INST(arm_LDREXD, "LDREXD", "cccc00011011nnnndddd111110011111") // v6K
|
||||
INST(arm_STLB, "STLB", "cccc00011100nnnn111111001001tttt") // v8
|
||||
INST(arm_STLEXB, "STLEXB", "cccc00011100nnnndddd11101001mmmm") // v8
|
||||
INST(arm_STREXB, "STREXB", "cccc00011100nnnndddd11111001mmmm") // v6K
|
||||
INST(arm_LDAB, "LDAB", "cccc00011101nnnndddd110010011111") // v8
|
||||
INST(arm_LDAEXB, "LDAEXB", "cccc00011101nnnndddd111010011111") // v8
|
||||
INST(arm_LDREXB, "LDREXB", "cccc00011101nnnndddd111110011111") // v6K
|
||||
INST(arm_STLH, "STLH", "cccc00011110nnnn111111001001mmmm") // v8
|
||||
INST(arm_STLEXH, "STLEXH", "cccc00011110nnnndddd11101001mmmm") // v8
|
||||
INST(arm_STREXH, "STREXH", "cccc00011110nnnndddd11111001mmmm") // v6K
|
||||
INST(arm_LDAH, "LDAH", "cccc00011111nnnndddd110010011111") // v8
|
||||
INST(arm_LDAEXH, "LDAEXH", "cccc00011111nnnndddd111010011111") // v8
|
||||
INST(arm_LDREXH, "LDREXH", "cccc00011111nnnndddd111110011111") // v6K
|
||||
|
||||
// Load/Store instructions
|
||||
INST(arm_LDRBT, "LDRBT (A1)", "----0100-111--------------------")
|
||||
INST(arm_LDRBT, "LDRBT (A2)", "----0110-111---------------0----")
|
||||
INST(arm_LDRHT, "LDRHT (A1)", "----0000-111------------1011----")
|
||||
INST(arm_LDRHT, "LDRHT (A1)", "----0000-1111111--------1011----")
|
||||
INST(arm_LDRHT, "LDRHT (A2)", "----0000-011--------00001011----")
|
||||
INST(arm_LDRSBT, "LDRSBT (A1)", "----0000-111------------1101----")
|
||||
INST(arm_LDRSBT, "LDRSBT (A2)", "----0000-011--------00001101----")
|
||||
INST(arm_LDRSHT, "LDRSHT (A1)", "----0000-111------------1111----")
|
||||
INST(arm_LDRSHT, "LDRSHT (A2)", "----0000-011--------00001111----")
|
||||
INST(arm_LDRT, "LDRT (A1)", "----0100-011--------------------")
|
||||
INST(arm_LDRT, "LDRT (A2)", "----0110-011---------------0----")
|
||||
INST(arm_STRBT, "STRBT (A1)", "----0100-110--------------------")
|
||||
INST(arm_STRBT, "STRBT (A2)", "----0110-110---------------0----")
|
||||
INST(arm_STRHT, "STRHT (A1)", "----0000-110------------1011----")
|
||||
INST(arm_STRHT, "STRHT (A2)", "----0000-010--------00001011----")
|
||||
INST(arm_STRT, "STRT (A1)", "----0100-010--------------------")
|
||||
INST(arm_STRT, "STRT (A2)", "----0110-010---------------0----")
|
||||
INST(arm_LDR_lit, "LDR (lit)", "cccc0101u0011111ttttvvvvvvvvvvvv")
|
||||
INST(arm_LDR_imm, "LDR (imm)", "cccc010pu0w1nnnnttttvvvvvvvvvvvv")
|
||||
INST(arm_LDR_reg, "LDR (reg)", "cccc011pu0w1nnnnttttvvvvvrr0mmmm")
|
||||
INST(arm_LDRB_lit, "LDRB (lit)", "cccc0101u1011111ttttvvvvvvvvvvvv")
|
||||
INST(arm_LDRB_imm, "LDRB (imm)", "cccc010pu1w1nnnnttttvvvvvvvvvvvv")
|
||||
INST(arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnttttvvvvvrr0mmmm")
|
||||
INST(arm_LDRD_lit, "LDRD (lit)", "cccc0001u1001111ttttvvvv1101vvvv")
|
||||
INST(arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnttttvvvv1101vvvv") // v5E
|
||||
INST(arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnntttt00001101mmmm") // v5E
|
||||
INST(arm_LDRH_lit, "LDRH (lit)", "cccc000pu1w11111ttttvvvv1011vvvv")
|
||||
INST(arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnttttvvvv1011vvvv")
|
||||
INST(arm_LDRH_reg, "LDRH (reg)", "cccc000pu0w1nnnntttt00001011mmmm")
|
||||
INST(arm_LDRSB_lit, "LDRSB (lit)", "cccc0001u1011111ttttvvvv1101vvvv")
|
||||
INST(arm_LDRSB_imm, "LDRSB (imm)", "cccc000pu1w1nnnnttttvvvv1101vvvv")
|
||||
INST(arm_LDRSB_reg, "LDRSB (reg)", "cccc000pu0w1nnnntttt00001101mmmm")
|
||||
INST(arm_LDRSH_lit, "LDRSH (lit)", "cccc0001u1011111ttttvvvv1111vvvv")
|
||||
INST(arm_LDRSH_imm, "LDRSH (imm)", "cccc000pu1w1nnnnttttvvvv1111vvvv")
|
||||
INST(arm_LDRSH_reg, "LDRSH (reg)", "cccc000pu0w1nnnntttt00001111mmmm")
|
||||
INST(arm_STR_imm, "STR (imm)", "cccc010pu0w0nnnnttttvvvvvvvvvvvv")
|
||||
INST(arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnttttvvvvvrr0mmmm")
|
||||
INST(arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnttttvvvvvvvvvvvv")
|
||||
INST(arm_STRB_reg, "STRB (reg)", "cccc011pu1w0nnnnttttvvvvvrr0mmmm")
|
||||
INST(arm_STRD_imm, "STRD (imm)", "cccc000pu1w0nnnnttttvvvv1111vvvv") // v5E
|
||||
INST(arm_STRD_reg, "STRD (reg)", "cccc000pu0w0nnnntttt00001111mmmm") // v5E
|
||||
INST(arm_STRH_imm, "STRH (imm)", "cccc000pu1w0nnnnttttvvvv1011vvvv")
|
||||
INST(arm_STRH_reg, "STRH (reg)", "cccc000pu0w0nnnntttt00001011mmmm")
|
||||
|
||||
// Load/Store Multiple instructions
|
||||
INST(arm_LDM, "LDM", "cccc100010w1nnnnxxxxxxxxxxxxxxxx") // all
|
||||
INST(arm_LDMDA, "LDMDA", "cccc100000w1nnnnxxxxxxxxxxxxxxxx") // all
|
||||
INST(arm_LDMDB, "LDMDB", "cccc100100w1nnnnxxxxxxxxxxxxxxxx") // all
|
||||
INST(arm_LDMIB, "LDMIB", "cccc100110w1nnnnxxxxxxxxxxxxxxxx") // all
|
||||
INST(arm_LDM_usr, "LDM (usr reg)", "----100--101--------------------") // all
|
||||
INST(arm_LDM_eret, "LDM (exce ret)", "----100--1-1----1---------------") // all
|
||||
INST(arm_STM, "STM", "cccc100010w0nnnnxxxxxxxxxxxxxxxx") // all
|
||||
INST(arm_STMDA, "STMDA", "cccc100000w0nnnnxxxxxxxxxxxxxxxx") // all
|
||||
INST(arm_STMDB, "STMDB", "cccc100100w0nnnnxxxxxxxxxxxxxxxx") // all
|
||||
INST(arm_STMIB, "STMIB", "cccc100110w0nnnnxxxxxxxxxxxxxxxx") // all
|
||||
INST(arm_STM_usr, "STM (usr reg)", "----100--100--------------------") // all
|
||||
|
||||
// Miscellaneous instructions
|
||||
INST(arm_BFC, "BFC", "cccc0111110vvvvvddddvvvvv0011111") // v6T2
|
||||
INST(arm_BFI, "BFI", "cccc0111110vvvvvddddvvvvv001nnnn") // v6T2
|
||||
INST(arm_CLZ, "CLZ", "cccc000101101111dddd11110001mmmm") // v5
|
||||
INST(arm_MOVT, "MOVT", "cccc00110100vvvvddddvvvvvvvvvvvv") // v6T2
|
||||
INST(arm_MOVW, "MOVW", "cccc00110000vvvvddddvvvvvvvvvvvv") // v6T2
|
||||
INST(arm_NOP, "NOP", "----0011001000001111000000000000") // v6K
|
||||
INST(arm_SBFX, "SBFX", "cccc0111101wwwwwddddvvvvv101nnnn") // v6T2
|
||||
INST(arm_SEL, "SEL", "cccc01101000nnnndddd11111011mmmm") // v6
|
||||
INST(arm_UBFX, "UBFX", "cccc0111111wwwwwddddvvvvv101nnnn") // v6T2
|
||||
|
||||
// Unsigned Sum of Absolute Differences instructions
|
||||
INST(arm_USAD8, "USAD8", "cccc01111000dddd1111mmmm0001nnnn") // v6
|
||||
INST(arm_USADA8, "USADA8", "cccc01111000ddddaaaammmm0001nnnn") // v6
|
||||
|
||||
// Packing instructions
|
||||
INST(arm_PKHBT, "PKHBT", "cccc01101000nnnnddddvvvvv001mmmm") // v6K
|
||||
INST(arm_PKHTB, "PKHTB", "cccc01101000nnnnddddvvvvv101mmmm") // v6K
|
||||
|
||||
// Reversal instructions
|
||||
INST(arm_RBIT, "RBIT", "cccc011011111111dddd11110011mmmm") // v6T2
|
||||
INST(arm_REV, "REV", "cccc011010111111dddd11110011mmmm") // v6
|
||||
INST(arm_REV16, "REV16", "cccc011010111111dddd11111011mmmm") // v6
|
||||
INST(arm_REVSH, "REVSH", "cccc011011111111dddd11111011mmmm") // v6
|
||||
|
||||
// Saturation instructions
|
||||
INST(arm_SSAT, "SSAT", "cccc0110101vvvvvddddvvvvvr01nnnn") // v6
|
||||
INST(arm_SSAT16, "SSAT16", "cccc01101010vvvvdddd11110011nnnn") // v6
|
||||
INST(arm_USAT, "USAT", "cccc0110111vvvvvddddvvvvvr01nnnn") // v6
|
||||
INST(arm_USAT16, "USAT16", "cccc01101110vvvvdddd11110011nnnn") // v6
|
||||
|
||||
// Divide instructions
|
||||
INST(arm_SDIV, "SDIV", "cccc01110001dddd1111mmmm0001nnnn") // v7a
|
||||
INST(arm_UDIV, "UDIV", "cccc01110011dddd1111mmmm0001nnnn") // v7a
|
||||
|
||||
// Multiply (Normal) instructions
|
||||
INST(arm_MLA, "MLA", "cccc0000001Sddddaaaammmm1001nnnn") // v2
|
||||
INST(arm_MLS, "MLS", "cccc00000110ddddaaaammmm1001nnnn") // v6T2
|
||||
INST(arm_MUL, "MUL", "cccc0000000Sdddd0000mmmm1001nnnn") // v2
|
||||
|
||||
// Multiply (Long) instructions
|
||||
INST(arm_SMLAL, "SMLAL", "cccc0000111Sddddaaaammmm1001nnnn") // v3M
|
||||
INST(arm_SMULL, "SMULL", "cccc0000110Sddddaaaammmm1001nnnn") // v3M
|
||||
INST(arm_UMAAL, "UMAAL", "cccc00000100ddddaaaammmm1001nnnn") // v6
|
||||
INST(arm_UMLAL, "UMLAL", "cccc0000101Sddddaaaammmm1001nnnn") // v3M
|
||||
INST(arm_UMULL, "UMULL", "cccc0000100Sddddaaaammmm1001nnnn") // v3M
|
||||
|
||||
// Multiply (Halfword) instructions
|
||||
INST(arm_SMLALxy, "SMLALXY", "cccc00010100ddddaaaammmm1xy0nnnn") // v5xP
|
||||
INST(arm_SMLAxy, "SMLAXY", "cccc00010000ddddaaaammmm1xy0nnnn") // v5xP
|
||||
INST(arm_SMULxy, "SMULXY", "cccc00010110dddd0000mmmm1xy0nnnn") // v5xP
|
||||
|
||||
// Multiply (Word by Halfword) instructions
|
||||
INST(arm_SMLAWy, "SMLAWY", "cccc00010010ddddaaaammmm1y00nnnn") // v5xP
|
||||
INST(arm_SMULWy, "SMULWY", "cccc00010010dddd0000mmmm1y10nnnn") // v5xP
|
||||
|
||||
// Multiply (Most Significant Word) instructions
|
||||
INST(arm_SMMUL, "SMMUL", "cccc01110101dddd1111mmmm00R1nnnn") // v6
|
||||
INST(arm_SMMLA, "SMMLA", "cccc01110101ddddaaaammmm00R1nnnn") // v6
|
||||
INST(arm_SMMLS, "SMMLS", "cccc01110101ddddaaaammmm11R1nnnn") // v6
|
||||
|
||||
// Multiply (Dual) instructions
|
||||
INST(arm_SMLAD, "SMLAD", "cccc01110000ddddaaaammmm00M1nnnn") // v6
|
||||
INST(arm_SMLALD, "SMLALD", "cccc01110100ddddaaaammmm00M1nnnn") // v6
|
||||
INST(arm_SMLSD, "SMLSD", "cccc01110000ddddaaaammmm01M1nnnn") // v6
|
||||
INST(arm_SMLSLD, "SMLSLD", "cccc01110100ddddaaaammmm01M1nnnn") // v6
|
||||
INST(arm_SMUAD, "SMUAD", "cccc01110000dddd1111mmmm00M1nnnn") // v6
|
||||
INST(arm_SMUSD, "SMUSD", "cccc01110000dddd1111mmmm01M1nnnn") // v6
|
||||
|
||||
// Parallel Add/Subtract (Modulo) instructions
|
||||
INST(arm_SADD8, "SADD8", "cccc01100001nnnndddd11111001mmmm") // v6
|
||||
INST(arm_SADD16, "SADD16", "cccc01100001nnnndddd11110001mmmm") // v6
|
||||
INST(arm_SASX, "SASX", "cccc01100001nnnndddd11110011mmmm") // v6
|
||||
INST(arm_SSAX, "SSAX", "cccc01100001nnnndddd11110101mmmm") // v6
|
||||
INST(arm_SSUB8, "SSUB8", "cccc01100001nnnndddd11111111mmmm") // v6
|
||||
INST(arm_SSUB16, "SSUB16", "cccc01100001nnnndddd11110111mmmm") // v6
|
||||
INST(arm_UADD8, "UADD8", "cccc01100101nnnndddd11111001mmmm") // v6
|
||||
INST(arm_UADD16, "UADD16", "cccc01100101nnnndddd11110001mmmm") // v6
|
||||
INST(arm_UASX, "UASX", "cccc01100101nnnndddd11110011mmmm") // v6
|
||||
INST(arm_USAX, "USAX", "cccc01100101nnnndddd11110101mmmm") // v6
|
||||
INST(arm_USUB8, "USUB8", "cccc01100101nnnndddd11111111mmmm") // v6
|
||||
INST(arm_USUB16, "USUB16", "cccc01100101nnnndddd11110111mmmm") // v6
|
||||
|
||||
// Parallel Add/Subtract (Saturating) instructions
|
||||
INST(arm_QADD8, "QADD8", "cccc01100010nnnndddd11111001mmmm") // v6
|
||||
INST(arm_QADD16, "QADD16", "cccc01100010nnnndddd11110001mmmm") // v6
|
||||
INST(arm_QASX, "QASX", "cccc01100010nnnndddd11110011mmmm") // v6
|
||||
INST(arm_QSAX, "QSAX", "cccc01100010nnnndddd11110101mmmm") // v6
|
||||
INST(arm_QSUB8, "QSUB8", "cccc01100010nnnndddd11111111mmmm") // v6
|
||||
INST(arm_QSUB16, "QSUB16", "cccc01100010nnnndddd11110111mmmm") // v6
|
||||
INST(arm_UQADD8, "UQADD8", "cccc01100110nnnndddd11111001mmmm") // v6
|
||||
INST(arm_UQADD16, "UQADD16", "cccc01100110nnnndddd11110001mmmm") // v6
|
||||
INST(arm_UQASX, "UQASX", "cccc01100110nnnndddd11110011mmmm") // v6
|
||||
INST(arm_UQSAX, "UQSAX", "cccc01100110nnnndddd11110101mmmm") // v6
|
||||
INST(arm_UQSUB8, "UQSUB8", "cccc01100110nnnndddd11111111mmmm") // v6
|
||||
INST(arm_UQSUB16, "UQSUB16", "cccc01100110nnnndddd11110111mmmm") // v6
|
||||
|
||||
// Parallel Add/Subtract (Halving) instructions
|
||||
INST(arm_SHADD8, "SHADD8", "cccc01100011nnnndddd11111001mmmm") // v6
|
||||
INST(arm_SHADD16, "SHADD16", "cccc01100011nnnndddd11110001mmmm") // v6
|
||||
INST(arm_SHASX, "SHASX", "cccc01100011nnnndddd11110011mmmm") // v6
|
||||
INST(arm_SHSAX, "SHSAX", "cccc01100011nnnndddd11110101mmmm") // v6
|
||||
INST(arm_SHSUB8, "SHSUB8", "cccc01100011nnnndddd11111111mmmm") // v6
|
||||
INST(arm_SHSUB16, "SHSUB16", "cccc01100011nnnndddd11110111mmmm") // v6
|
||||
INST(arm_UHADD8, "UHADD8", "cccc01100111nnnndddd11111001mmmm") // v6
|
||||
INST(arm_UHADD16, "UHADD16", "cccc01100111nnnndddd11110001mmmm") // v6
|
||||
INST(arm_UHASX, "UHASX", "cccc01100111nnnndddd11110011mmmm") // v6
|
||||
INST(arm_UHSAX, "UHSAX", "cccc01100111nnnndddd11110101mmmm") // v6
|
||||
INST(arm_UHSUB8, "UHSUB8", "cccc01100111nnnndddd11111111mmmm") // v6
|
||||
INST(arm_UHSUB16, "UHSUB16", "cccc01100111nnnndddd11110111mmmm") // v6
|
||||
|
||||
// Saturated Add/Subtract instructions
|
||||
INST(arm_QADD, "QADD", "cccc00010000nnnndddd00000101mmmm") // v5xP
|
||||
INST(arm_QSUB, "QSUB", "cccc00010010nnnndddd00000101mmmm") // v5xP
|
||||
INST(arm_QDADD, "QDADD", "cccc00010100nnnndddd00000101mmmm") // v5xP
|
||||
INST(arm_QDSUB, "QDSUB", "cccc00010110nnnndddd00000101mmmm") // v5xP
|
||||
|
||||
// Status Register Access instructions
|
||||
INST(arm_CPS, "CPS", "111100010000---00000000---0-----") // v6
|
||||
INST(arm_SETEND, "SETEND", "1111000100000001000000e000000000") // v6
|
||||
INST(arm_MRS, "MRS", "cccc000100001111dddd000000000000") // v3
|
||||
INST(arm_MSR_imm, "MSR (imm)", "cccc00110010mmmm1111rrrrvvvvvvvv") // v3
|
||||
INST(arm_MSR_reg, "MSR (reg)", "cccc00010010mmmm111100000000nnnn") // v3
|
||||
INST(arm_RFE, "RFE", "1111100--0-1----0000101000000000") // v6
|
||||
INST(arm_SRS, "SRS", "1111100--1-0110100000101000-----") // v6
|
77
externals/dynarmic/src/frontend/A32/decoder/asimd.h
vendored
Executable file
77
externals/dynarmic/src/frontend/A32/decoder/asimd.h
vendored
Executable file
@@ -0,0 +1,77 @@
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2020 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "common/bit_util.h"
|
||||
#include "common/common_types.h"
|
||||
#include "frontend/decoder/decoder_detail.h"
|
||||
#include "frontend/decoder/matcher.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
template <typename Visitor>
|
||||
using ASIMDMatcher = Decoder::Matcher<Visitor, u32>;
|
||||
|
||||
template <typename V>
|
||||
std::vector<ASIMDMatcher<V>> GetASIMDDecodeTable() {
|
||||
std::vector<ASIMDMatcher<V>> table = {
|
||||
|
||||
#define INST(fn, name, bitstring) Decoder::detail::detail<ASIMDMatcher<V>>::GetMatcher(&V::fn, name, bitstring),
|
||||
#include "asimd.inc"
|
||||
#undef INST
|
||||
|
||||
};
|
||||
|
||||
// Exceptions to the rule of thumb.
|
||||
const std::set<std::string> comes_first{
|
||||
"VBIC, VMOV, VMVN, VORR (immediate)",
|
||||
"VEXT",
|
||||
"VTBL",
|
||||
"VTBX",
|
||||
"VDUP (scalar)",
|
||||
};
|
||||
const std::set<std::string> comes_last{
|
||||
"VMLA (scalar)",
|
||||
"VMLAL (scalar)",
|
||||
"VQDMLAL/VQDMLSL (scalar)",
|
||||
"VMUL (scalar)",
|
||||
"VMULL (scalar)",
|
||||
"VQDMULL (scalar)",
|
||||
"VQDMULH (scalar)",
|
||||
"VQRDMULH (scalar)",
|
||||
};
|
||||
const auto sort_begin = std::stable_partition(table.begin(), table.end(), [&](const auto& matcher) {
|
||||
return comes_first.count(matcher.GetName()) > 0;
|
||||
});
|
||||
const auto sort_end = std::stable_partition(table.begin(), table.end(), [&](const auto& matcher) {
|
||||
return comes_last.count(matcher.GetName()) == 0;
|
||||
});
|
||||
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
std::stable_sort(sort_begin, sort_end, [](const auto& matcher1, const auto& matcher2) {
|
||||
return Common::BitCount(matcher1.GetMask()) > Common::BitCount(matcher2.GetMask());
|
||||
});
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
std::optional<std::reference_wrapper<const ASIMDMatcher<V>>> DecodeASIMD(u32 instruction) {
|
||||
static const auto table = GetASIMDDecodeTable<V>();
|
||||
|
||||
const auto matches_instruction = [instruction](const auto& matcher) { return matcher.Matches(instruction); };
|
||||
|
||||
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
|
||||
return iter != table.end() ? std::optional<std::reference_wrapper<const ASIMDMatcher<V>>>(*iter) : std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
167
externals/dynarmic/src/frontend/A32/decoder/asimd.inc
vendored
Executable file
167
externals/dynarmic/src/frontend/A32/decoder/asimd.inc
vendored
Executable file
@@ -0,0 +1,167 @@
|
||||
// Three registers of the same length
|
||||
INST(asimd_VHADD, "VHADD", "1111001U0Dzznnnndddd0000NQM0mmmm") // ASIMD
|
||||
INST(asimd_VQADD, "VQADD", "1111001U0Dzznnnndddd0000NQM1mmmm") // ASIMD
|
||||
INST(asimd_VRHADD, "VRHADD", "1111001U0Dzznnnndddd0001NQM0mmmm") // ASIMD
|
||||
INST(asimd_VAND_reg, "VAND (register)", "111100100D00nnnndddd0001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VBIC_reg, "VBIC (register)", "111100100D01nnnndddd0001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VORR_reg, "VORR (register)", "111100100D10nnnndddd0001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VORN_reg, "VORN (register)", "111100100D11nnnndddd0001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VEOR_reg, "VEOR (register)", "111100110D00nnnndddd0001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VBSL, "VBSL", "111100110D01nnnndddd0001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VBIT, "VBIT", "111100110D10nnnndddd0001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VBIF, "VBIF", "111100110D11nnnndddd0001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VHSUB, "VHSUB", "1111001U0Dzznnnndddd0010NQM0mmmm") // ASIMD
|
||||
INST(asimd_VQSUB, "VQSUB", "1111001U0Dzznnnndddd0010NQM1mmmm") // ASIMD
|
||||
INST(asimd_VCGT_reg, "VCGT (register)", "1111001U0Dzznnnndddd0011NQM0mmmm") // ASIMD
|
||||
INST(asimd_VCGE_reg, "VCGE (register)", "1111001U0Dzznnnndddd0011NQM1mmmm") // ASIMD
|
||||
INST(asimd_VSHL_reg, "VSHL (register)", "1111001U0Dzznnnndddd0100NQM0mmmm") // ASIMD
|
||||
INST(asimd_VQSHL_reg, "VQSHL (register)", "1111001U0Dzznnnndddd0100NQM1mmmm") // ASIMD
|
||||
INST(asimd_VRSHL, "VRSHL", "1111001U0Dzznnnndddd0101NQM0mmmm") // ASIMD
|
||||
//INST(asimd_VQRSHL, "VQRSHL", "1111001U0-CC--------0101---1----") // ASIMD
|
||||
INST(asimd_VMAX, "VMAX/VMIN (integer)", "1111001U0Dzznnnnmmmm0110NQMommmm") // ASIMD
|
||||
INST(asimd_VABD, "VABD", "1111001U0Dzznnnndddd0111NQM0mmmm") // ASIMD
|
||||
INST(asimd_VABA, "VABA", "1111001U0Dzznnnndddd0111NQM1mmmm") // ASIMD
|
||||
INST(asimd_VADD_int, "VADD (integer)", "111100100Dzznnnndddd1000NQM0mmmm") // ASIMD
|
||||
INST(asimd_VSUB_int, "VSUB (integer)", "111100110Dzznnnndddd1000NQM0mmmm") // ASIMD
|
||||
INST(asimd_VTST, "VTST", "111100100Dzznnnndddd1000NQM1mmmm") // ASIMD
|
||||
INST(asimd_VCEQ_reg, "VCEG (register)", "111100110Dzznnnndddd1000NQM1mmmm") // ASIMD
|
||||
INST(asimd_VMLA, "VMLA/VMLS", "1111001o0Dzznnnndddd1001NQM0mmmm") // ASIMD
|
||||
INST(asimd_VMUL, "VMUL", "1111001P0Dzznnnndddd1001NQM1mmmm") // ASIMD
|
||||
INST(asimd_VPMAX_int, "VPMAX/VPMIN (integer)", "1111001U0Dzznnnndddd1010NQMommmm") // ASIMD
|
||||
INST(asimd_VQDMULH, "VQDMULH", "111100100Dzznnnndddd1011NQM0mmmm") // ASIMD
|
||||
INST(asimd_VQRDMULH, "VQRDMULH", "111100110Dzznnnndddd1011NQM0mmmm") // ASIMD
|
||||
INST(asimd_VPADD, "VPADD", "111100100Dzznnnndddd1011NQM1mmmm") // ASIMD
|
||||
INST(asimd_VFMA, "VFMA", "111100100D0znnnndddd1100NQM1mmmm") // ASIMD
|
||||
INST(asimd_VFMS, "VFMS", "111100100D1znnnndddd1100NQM1mmmm") // ASIMD
|
||||
INST(asimd_VADD_float, "VADD (floating-point)", "111100100D0znnnndddd1101NQM0mmmm") // ASIMD
|
||||
INST(asimd_VSUB_float, "VSUB (floating-point)", "111100100D1znnnndddd1101NQM0mmmm") // ASIMD
|
||||
INST(asimd_VPADD_float, "VPADD (floating-point)", "111100110D0znnnndddd1101NQM0mmmm") // ASIMD
|
||||
INST(asimd_VABD_float, "VABD (floating-point)", "111100110D1znnnndddd1101NQM0mmmm") // ASIMD
|
||||
INST(asimd_VMLA_float, "VMLA (floating-point)", "111100100D0znnnndddd1101NQM1mmmm") // ASIMD
|
||||
INST(asimd_VMLS_float, "VMLS (floating-point)", "111100100D1znnnndddd1101NQM1mmmm") // ASIMD
|
||||
INST(asimd_VMUL_float, "VMUL (floating-point)", "111100110D0znnnndddd1101NQM1mmmm") // ASIMD
|
||||
INST(asimd_VCEQ_reg_float, "VCEQ (register)", "111100100D0znnnndddd1110NQM0mmmm") // ASIMD
|
||||
INST(asimd_VCGE_reg_float, "VCGE (register)", "111100110D0znnnndddd1110NQM0mmmm") // ASIMD
|
||||
INST(asimd_VCGT_reg_float, "VCGT (register)", "111100110D1znnnndddd1110NQM0mmmm") // ASIMD
|
||||
INST(asimd_VACGE, "VACGE", "111100110Doznnnndddd1110NQM1mmmm") // ASIMD
|
||||
INST(asimd_VMAX_float, "VMAX (floating-point)", "111100100D0znnnndddd1111NQM0mmmm") // ASIMD
|
||||
INST(asimd_VMIN_float, "VMIN (floating-point)", "111100100D1znnnndddd1111NQM0mmmm") // ASIMD
|
||||
INST(asimd_VPMAX_float, "VPMAX (floating-point)", "111100110D0znnnndddd1111NQM0mmmm") // ASIMD
|
||||
INST(asimd_VPMIN_float, "VPMIN (floating-point)", "111100110D1znnnndddd1111NQM0mmmm") // ASIMD
|
||||
INST(asimd_VRECPS, "VRECPS", "111100100D0znnnndddd1111NQM1mmmm") // ASIMD
|
||||
INST(asimd_VRSQRTS, "VRSQRTS", "111100100D1znnnndddd1111NQM1mmmm") // ASIMD
|
||||
|
||||
// Three registers of different lengths
|
||||
INST(asimd_VADDL, "VADDL/VADDW", "1111001U1Dzznnnndddd000oN0M0mmmm") // ASIMD
|
||||
INST(asimd_VSUBL, "VSUBL/VSUBW", "1111001U1Dzznnnndddd001oN0M0mmmm") // ASIMD
|
||||
//INST(asimd_VADDHN, "VADDHN", "111100101-----------0100-0-0----") // ASIMD
|
||||
//INST(asimd_VRADDHN, "VRADDHN", "111100111-----------0100-0-0----") // ASIMD
|
||||
INST(asimd_VABAL, "VABAL", "1111001U1Dzznnnndddd0101N0M0mmmm") // ASIMD
|
||||
//INST(asimd_VSUBHN, "VSUBHN", "111100101-----------0110-0-0----") // ASIMD
|
||||
//INST(asimd_VRSUBHN, "VRSUBHN", "111100111-----------0110-0-0----") // ASIMD
|
||||
INST(asimd_VABDL, "VABDL", "1111001U1Dzznnnndddd0111N0M0mmmm") // ASIMD
|
||||
INST(asimd_VMLAL, "VMLAL/VMLSL", "1111001U1Dzznnnndddd10o0N0M0mmmm") // ASIMD
|
||||
//INST(asimd_VQDMLAL, "VQDMLAL", "111100101-----------10-1-0-0----") // ASIMD
|
||||
INST(asimd_VMULL, "VMULL", "1111001U1Dzznnnndddd11P0N0M0mmmm") // ASIMD
|
||||
//INST(asimd_VQDMULL, "VQDMULL", "111100101-----------1101-0-0----") // ASIMD
|
||||
|
||||
// Two registers and a scalar
|
||||
INST(asimd_VMLA_scalar, "VMLA (scalar)", "1111001Q1Dzznnnndddd0o0FN1M0mmmm") // ASIMD
|
||||
INST(asimd_VMLAL_scalar, "VMLAL (scalar)", "1111001U1dzznnnndddd0o10N1M0mmmm") // ASIMD
|
||||
//INST(asimd_VQDMLAL_scalar, "VQDMLAL/VQDMLSL (scalar)", "111100101-BB--------0x11-1-0----") // ASIMD
|
||||
INST(asimd_VMUL_scalar, "VMUL (scalar)", "1111001Q1Dzznnnndddd100FN1M0mmmm") // ASIMD
|
||||
INST(asimd_VMULL_scalar, "VMULL (scalar)", "1111001U1Dzznnnndddd1010N1M0mmmm") // ASIMD
|
||||
INST(asimd_VQDMULL_scalar, "VQDMULL (scalar)", "111100101Dzznnnndddd1011N1M0mmmm") // ASIMD
|
||||
INST(asimd_VQDMULH_scalar, "VQDMULH (scalar)", "1111001Q1Dzznnnndddd1100N1M0mmmm") // ASIMD
|
||||
INST(asimd_VQRDMULH_scalar, "VQRDMULH (scalar)", "1111001Q1Dzznnnndddd1101N1M0mmmm") // ASIMD
|
||||
|
||||
// Two registers and a shift amount
|
||||
INST(asimd_SHR, "SHR", "1111001U1Diiiiiidddd0000LQM1mmmm") // ASIMD
|
||||
INST(asimd_SRA, "SRA", "1111001U1Diiiiiidddd0001LQM1mmmm") // ASIMD
|
||||
INST(asimd_VRSHR, "VRSHR", "1111001U1Diiiiiidddd0010LQM1mmmm") // ASIMD
|
||||
INST(asimd_VRSRA, "VRSRA", "1111001U1Diiiiiidddd0011LQM1mmmm") // ASIMD
|
||||
INST(asimd_VSRI, "VSRI", "111100111Diiiiiidddd0100LQM1mmmm") // ASIMD
|
||||
INST(asimd_VSHL, "VSHL", "111100101Diiiiiidddd0101LQM1mmmm") // ASIMD
|
||||
INST(asimd_VSLI, "VSLI", "111100111Diiiiiidddd0101LQM1mmmm") // ASIMD
|
||||
INST(asimd_VQSHL, "VQSHL" , "1111001U1Diiiiiidddd011oLQM1mmmm") // ASIMD
|
||||
INST(asimd_VSHRN, "VSHRN", "111100101Diiiiiidddd100000M1mmmm") // ASIMD
|
||||
INST(asimd_VRSHRN, "VRSHRN", "111100101Diiiiiidddd100001M1mmmm") // ASIMD
|
||||
INST(asimd_VQSHRUN, "VQSHRUN", "111100111Diiiiiidddd100000M1mmmm") // ASIMD
|
||||
INST(asimd_VQRSHRUN, "VQRSHRUN", "111100111Diiiiiidddd100001M1mmmm") // ASIMD
|
||||
INST(asimd_VQSHRN, "VQSHRN", "1111001U1Diiiiiidddd100100M1mmmm") // ASIMD
|
||||
INST(asimd_VQRSHRN, "VQRSHRN", "1111001U1Diiiiiidddd100101M1mmmm") // ASIMD
|
||||
INST(asimd_VSHLL, "VSHLL", "1111001U1Diiiiiidddd101000M1mmmm") // ASIMD
|
||||
INST(asimd_VCVT_fixed, "VCVT (fixed-point)", "1111001U1Diiiiiidddd111o0QM1mmmm") // ASIMD
|
||||
|
||||
// Two registers, miscellaneous
|
||||
INST(asimd_VREV, "VREV{16,32,64}", "111100111D11zz00dddd000ooQM0mmmm") // ASIMD
|
||||
INST(asimd_VPADDL, "VPADDL", "111100111D11zz00dddd0010oQM0mmmm") // ASIMD
|
||||
INST(asimd_VCLS, "VCLS", "111100111D11zz00dddd01000QM0mmmm") // ASIMD
|
||||
INST(asimd_VCLZ, "VCLZ", "111100111D11zz00dddd01001QM0mmmm") // ASIMD
|
||||
INST(asimd_VCNT, "VCNT", "111100111D11zz00dddd01010QM0mmmm") // ASIMD
|
||||
INST(asimd_VMVN_reg, "VMVN_reg", "111100111D11zz00dddd01011QM0mmmm") // ASIMD
|
||||
INST(asimd_VPADAL, "VPADAL", "111100111D11zz00dddd0110oQM0mmmm") // ASIMD
|
||||
INST(asimd_VQABS, "VQABS", "111100111D11zz00dddd01110QM0mmmm") // ASIMD
|
||||
INST(asimd_VQNEG, "VQNEG", "111100111D11zz00dddd01111QM0mmmm") // ASIMD
|
||||
INST(asimd_VCGT_zero, "VCGT (zero)", "111100111D11zz01dddd0F000QM0mmmm") // ASIMD
|
||||
INST(asimd_VCGE_zero, "VCGE (zero)", "111100111D11zz01dddd0F001QM0mmmm") // ASIMD
|
||||
INST(asimd_VCEQ_zero, "VCEQ (zero)", "111100111D11zz01dddd0F010QM0mmmm") // ASIMD
|
||||
INST(asimd_VCLE_zero, "VCLE (zero)", "111100111D11zz01dddd0F011QM0mmmm") // ASIMD
|
||||
INST(asimd_VCLT_zero, "VCLT (zero)", "111100111D11zz01dddd0F100QM0mmmm") // ASIMD
|
||||
INST(arm_UDF, "UNALLOCATED", "111100111-11--01----01101--0----") // v8
|
||||
INST(asimd_VABS, "VABS", "111100111D11zz01dddd0F110QM0mmmm") // ASIMD
|
||||
INST(asimd_VNEG, "VNEG", "111100111D11zz01dddd0F111QM0mmmm") // ASIMD
|
||||
INST(asimd_VSWP, "VSWP", "111100111D110010dddd00000QM0mmmm") // ASIMD
|
||||
INST(arm_UDF, "UNALLOCATED", "111100111-11--10----00000--0----") // ASIMD
|
||||
INST(asimd_VTRN, "VTRN", "111100111D11zz10dddd00001QM0mmmm") // ASIMD
|
||||
INST(asimd_VUZP, "VUZP", "111100111D11zz10dddd00010QM0mmmm") // ASIMD
|
||||
INST(asimd_VZIP, "VZIP", "111100111D11zz10dddd00011QM0mmmm") // ASIMD
|
||||
INST(asimd_VMOVN, "VMOVN", "111100111D11zz10dddd001000M0mmmm") // ASIMD
|
||||
INST(asimd_VQMOVUN, "VQMOVUN", "111100111D11zz10dddd001001M0mmmm") // ASIMD
|
||||
INST(asimd_VQMOVN, "VQMOVN", "111100111D11zz10dddd00101oM0mmmm") // ASIMD
|
||||
INST(asimd_VSHLL_max, "VSHLL_max", "111100111D11zz10dddd001100M0mmmm") // ASIMD
|
||||
INST(arm_UDF, "UNALLOCATED (VRINTN)", "111100111-11--10----01000--0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VRINTX)", "111100111-11--10----01001--0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VRINTA)", "111100111-11--10----01010--0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VRINTZ)", "111100111-11--10----01011--0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VRINTM)", "111100111-11--10----01101--0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VRINTP)", "111100111-11--10----01111--0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VCVT half)", "111100111-11--10----011-00-0----") // ASIMD
|
||||
INST(arm_UDF, "UNALLOCATED", "111100111-11--10----011-01-0----") // ASIMD
|
||||
INST(arm_UDF, "UNALLOCATED (VCVTA)", "111100111-11--11----0000---0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VCVTN)", "111100111-11--11----0001---0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VCVTP)", "111100111-11--11----0010---0----")
|
||||
INST(arm_UDF, "UNALLOCATED (VCVTM)", "111100111-11--11----0011---0----")
|
||||
INST(asimd_VRECPE, "VRECPE", "111100111D11zz11dddd010F0QM0mmmm") // ASIMD
|
||||
INST(asimd_VRSQRTE, "VRSQRTE", "111100111D11zz11dddd010F1QM0mmmm") // ASIMD
|
||||
INST(asimd_VCVT_integer, "VCVT (integer)", "111100111D11zz11dddd011oUQM0mmmm") // ASIMD
|
||||
|
||||
// Two registers, cryptography
|
||||
INST(v8_AESE, "AESE", "111100111D11zz00dddd001100M0mmmm") // v8
|
||||
INST(v8_AESD, "AESD", "111100111D11zz00dddd001101M0mmmm") // v8
|
||||
INST(v8_AESMC, "AESMC", "111100111D11zz00dddd001110M0mmmm") // v8
|
||||
INST(v8_AESIMC, "AESIMC", "111100111D11zz00dddd001111M0mmmm") // v8
|
||||
INST(arm_UDF, "UNALLOCATED", "111100111-11--01----001010-0----") // v8
|
||||
INST(arm_UDF, "UNALLOCATED (SHA1H)", "111100111-11--01----001011-0----") // v8
|
||||
INST(arm_UDF, "UNALLOCATED (SHA1SU1)", "111100111-11--10----001110-0----") // v8
|
||||
INST(arm_UDF, "UNALLOCATED (SHA256SU0)", "111100111-11--10----001111-0----") // v8
|
||||
|
||||
// One register and modified immediate
|
||||
INST(asimd_VMOV_imm, "VBIC, VMOV, VMVN, VORR (immediate)", "1111001a1D000bcdVVVVmmmm0Qo1efgh") // ASIMD
|
||||
|
||||
// Miscellaneous
|
||||
INST(asimd_VEXT, "VEXT", "111100101D11nnnnddddiiiiNQM0mmmm") // ASIMD
|
||||
INST(asimd_VTBL, "VTBL", "111100111D11nnnndddd10zzN0M0mmmm") // ASIMD
|
||||
INST(asimd_VTBX, "VTBX", "111100111D11nnnndddd10zzN1M0mmmm") // ASIMD
|
||||
INST(asimd_VDUP_scalar, "VDUP (scalar)", "111100111D11iiiidddd11000QM0mmmm") // ASIMD
|
||||
INST(arm_UDF, "UNALLOCATED", "111100111-11--------11-----0----") // ASIMD
|
||||
|
||||
// Advanced SIMD load/store structures
|
||||
INST(v8_VST_multiple, "VST{1-4} (multiple)", "111101000D00nnnnddddxxxxzzaammmm") // v8
|
||||
INST(v8_VLD_multiple, "VLD{1-4} (multiple)", "111101000D10nnnnddddxxxxzzaammmm") // v8
|
||||
INST(arm_UDF, "UNALLOCATED", "111101000--0--------1011--------") // v8
|
||||
INST(arm_UDF, "UNALLOCATED", "111101000--0--------11----------") // v8
|
||||
INST(arm_UDF, "UNALLOCATED", "111101001-00--------11----------") // v8
|
||||
INST(v8_VLD_all_lanes, "VLD{1-4} (all lanes)", "111101001D10nnnndddd11nnzzTammmm") // v8
|
||||
INST(v8_VST_single, "VST{1-4} (single)", "111101001D00nnnnddddzzNNaaaammmm") // v8
|
||||
INST(v8_VLD_single, "VLD{1-4} (single)", "111101001D10nnnnddddzzNNaaaammmm") // v8
|
134
externals/dynarmic/src/frontend/A32/decoder/thumb16.h
vendored
Executable file
134
externals/dynarmic/src/frontend/A32/decoder/thumb16.h
vendored
Executable file
@@ -0,0 +1,134 @@
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2016 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "frontend/decoder/decoder_detail.h"
|
||||
#include "frontend/decoder/matcher.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
template <typename Visitor>
|
||||
using Thumb16Matcher = Decoder::Matcher<Visitor, u16>;
|
||||
|
||||
template<typename V>
|
||||
std::optional<std::reference_wrapper<const Thumb16Matcher<V>>> DecodeThumb16(u16 instruction) {
|
||||
static const std::vector<Thumb16Matcher<V>> table = {
|
||||
|
||||
#define INST(fn, name, bitstring) Decoder::detail::detail<Thumb16Matcher<V>>::GetMatcher(fn, name, bitstring)
|
||||
|
||||
// Shift (immediate), add, subtract, move and compare instructions
|
||||
INST(&V::thumb16_LSL_imm, "LSL (imm)", "00000vvvvvmmmddd"),
|
||||
INST(&V::thumb16_LSR_imm, "LSR (imm)", "00001vvvvvmmmddd"),
|
||||
INST(&V::thumb16_ASR_imm, "ASR (imm)", "00010vvvvvmmmddd"),
|
||||
INST(&V::thumb16_ADD_reg_t1, "ADD (reg, T1)", "0001100mmmnnnddd"),
|
||||
INST(&V::thumb16_SUB_reg, "SUB (reg)", "0001101mmmnnnddd"),
|
||||
INST(&V::thumb16_ADD_imm_t1, "ADD (imm, T1)", "0001110vvvnnnddd"),
|
||||
INST(&V::thumb16_SUB_imm_t1, "SUB (imm, T1)", "0001111vvvnnnddd"),
|
||||
INST(&V::thumb16_MOV_imm, "MOV (imm)", "00100dddvvvvvvvv"),
|
||||
INST(&V::thumb16_CMP_imm, "CMP (imm)", "00101nnnvvvvvvvv"),
|
||||
INST(&V::thumb16_ADD_imm_t2, "ADD (imm, T2)", "00110dddvvvvvvvv"),
|
||||
INST(&V::thumb16_SUB_imm_t2, "SUB (imm, T2)", "00111dddvvvvvvvv"),
|
||||
|
||||
// Data-processing instructions
|
||||
INST(&V::thumb16_AND_reg, "AND (reg)", "0100000000mmmddd"),
|
||||
INST(&V::thumb16_EOR_reg, "EOR (reg)", "0100000001mmmddd"),
|
||||
INST(&V::thumb16_LSL_reg, "LSL (reg)", "0100000010mmmddd"),
|
||||
INST(&V::thumb16_LSR_reg, "LSR (reg)", "0100000011mmmddd"),
|
||||
INST(&V::thumb16_ASR_reg, "ASR (reg)", "0100000100mmmddd"),
|
||||
INST(&V::thumb16_ADC_reg, "ADC (reg)", "0100000101mmmddd"),
|
||||
INST(&V::thumb16_SBC_reg, "SBC (reg)", "0100000110mmmddd"),
|
||||
INST(&V::thumb16_ROR_reg, "ROR (reg)", "0100000111sssddd"),
|
||||
INST(&V::thumb16_TST_reg, "TST (reg)", "0100001000mmmnnn"),
|
||||
INST(&V::thumb16_RSB_imm, "RSB (imm)", "0100001001nnnddd"),
|
||||
INST(&V::thumb16_CMP_reg_t1, "CMP (reg, T1)", "0100001010mmmnnn"),
|
||||
INST(&V::thumb16_CMN_reg, "CMN (reg)", "0100001011mmmnnn"),
|
||||
INST(&V::thumb16_ORR_reg, "ORR (reg)", "0100001100mmmddd"),
|
||||
INST(&V::thumb16_MUL_reg, "MUL (reg)", "0100001101nnnddd"),
|
||||
INST(&V::thumb16_BIC_reg, "BIC (reg)", "0100001110mmmddd"),
|
||||
INST(&V::thumb16_MVN_reg, "MVN (reg)", "0100001111mmmddd"),
|
||||
|
||||
// Special data instructions
|
||||
INST(&V::thumb16_ADD_reg_t2, "ADD (reg, T2)", "01000100Dmmmmddd"), // v4T, Low regs: v6T2
|
||||
INST(&V::thumb16_CMP_reg_t2, "CMP (reg, T2)", "01000101Nmmmmnnn"), // v4T
|
||||
INST(&V::thumb16_MOV_reg, "MOV (reg)", "01000110Dmmmmddd"), // v4T, Low regs: v6
|
||||
|
||||
// Store/Load single data item instructions
|
||||
INST(&V::thumb16_LDR_literal, "LDR (literal)", "01001tttvvvvvvvv"),
|
||||
INST(&V::thumb16_STR_reg, "STR (reg)", "0101000mmmnnnttt"),
|
||||
INST(&V::thumb16_STRH_reg, "STRH (reg)", "0101001mmmnnnttt"),
|
||||
INST(&V::thumb16_STRB_reg, "STRB (reg)", "0101010mmmnnnttt"),
|
||||
INST(&V::thumb16_LDRSB_reg, "LDRSB (reg)", "0101011mmmnnnttt"),
|
||||
INST(&V::thumb16_LDR_reg, "LDR (reg)", "0101100mmmnnnttt"),
|
||||
INST(&V::thumb16_LDRH_reg, "LDRH (reg)", "0101101mmmnnnttt"),
|
||||
INST(&V::thumb16_LDRB_reg, "LDRB (reg)", "0101110mmmnnnttt"),
|
||||
INST(&V::thumb16_LDRSH_reg, "LDRSH (reg)", "0101111mmmnnnttt"),
|
||||
INST(&V::thumb16_STR_imm_t1, "STR (imm, T1)", "01100vvvvvnnnttt"),
|
||||
INST(&V::thumb16_LDR_imm_t1, "LDR (imm, T1)", "01101vvvvvnnnttt"),
|
||||
INST(&V::thumb16_STRB_imm, "STRB (imm)", "01110vvvvvnnnttt"),
|
||||
INST(&V::thumb16_LDRB_imm, "LDRB (imm)", "01111vvvvvnnnttt"),
|
||||
INST(&V::thumb16_STRH_imm, "STRH (imm)", "10000vvvvvnnnttt"),
|
||||
INST(&V::thumb16_LDRH_imm, "LDRH (imm)", "10001vvvvvnnnttt"),
|
||||
INST(&V::thumb16_STR_imm_t2, "STR (imm, T2)", "10010tttvvvvvvvv"),
|
||||
INST(&V::thumb16_LDR_imm_t2, "LDR (imm, T2)", "10011tttvvvvvvvv"),
|
||||
|
||||
// Generate relative address instructions
|
||||
INST(&V::thumb16_ADR, "ADR", "10100dddvvvvvvvv"),
|
||||
INST(&V::thumb16_ADD_sp_t1, "ADD (SP plus imm, T1)", "10101dddvvvvvvvv"),
|
||||
INST(&V::thumb16_ADD_sp_t2, "ADD (SP plus imm, T2)", "101100000vvvvvvv"), // v4T
|
||||
INST(&V::thumb16_SUB_sp, "SUB (SP minus imm)", "101100001vvvvvvv"), // v4T
|
||||
|
||||
// Hint instructions
|
||||
INST(&V::thumb16_NOP, "NOP", "1011111100000000"), // v6T2
|
||||
INST(&V::thumb16_SEV, "SEV", "1011111101000000"), // v7
|
||||
INST(&V::thumb16_SEVL, "SEVL", "1011111101010000"), // v8
|
||||
INST(&V::thumb16_WFE, "WFE", "1011111100100000"), // v7
|
||||
INST(&V::thumb16_WFI, "WFI", "1011111100110000"), // v7
|
||||
INST(&V::thumb16_YIELD, "YIELD", "1011111100010000"), // v7
|
||||
|
||||
// Miscellaneous 16-bit instructions
|
||||
INST(&V::thumb16_SXTH, "SXTH", "1011001000mmmddd"), // v6
|
||||
INST(&V::thumb16_SXTB, "SXTB", "1011001001mmmddd"), // v6
|
||||
INST(&V::thumb16_UXTH, "UXTH", "1011001010mmmddd"), // v6
|
||||
INST(&V::thumb16_UXTB, "UXTB", "1011001011mmmddd"), // v6
|
||||
INST(&V::thumb16_PUSH, "PUSH", "1011010Mxxxxxxxx"), // v4T
|
||||
INST(&V::thumb16_POP, "POP", "1011110Pxxxxxxxx"), // v4T
|
||||
INST(&V::thumb16_SETEND, "SETEND", "101101100101x000"), // v6
|
||||
INST(&V::thumb16_CPS, "CPS", "10110110011m0aif"), // v6
|
||||
INST(&V::thumb16_REV, "REV", "1011101000mmmddd"), // v6
|
||||
INST(&V::thumb16_REV16, "REV16", "1011101001mmmddd"), // v6
|
||||
INST(&V::thumb16_REVSH, "REVSH", "1011101011mmmddd"), // v6
|
||||
INST(&V::thumb16_BKPT, "BKPT", "10111110xxxxxxxx"), // v5
|
||||
|
||||
// Store/Load multiple registers
|
||||
INST(&V::thumb16_STMIA, "STMIA", "11000nnnxxxxxxxx"),
|
||||
INST(&V::thumb16_LDMIA, "LDMIA", "11001nnnxxxxxxxx"),
|
||||
|
||||
// Branch instructions
|
||||
INST(&V::thumb16_BX, "BX", "010001110mmmm000"), // v4T
|
||||
INST(&V::thumb16_BLX_reg, "BLX (reg)", "010001111mmmm000"), // v5T
|
||||
INST(&V::thumb16_CBZ_CBNZ, "CBZ/CBNZ", "1011o0i1iiiiinnn"), // v6T2
|
||||
INST(&V::thumb16_UDF, "UDF", "11011110--------"),
|
||||
INST(&V::thumb16_SVC, "SVC", "11011111xxxxxxxx"),
|
||||
INST(&V::thumb16_B_t1, "B (T1)", "1101ccccvvvvvvvv"),
|
||||
INST(&V::thumb16_B_t2, "B (T2)", "11100vvvvvvvvvvv"),
|
||||
|
||||
#undef INST
|
||||
|
||||
};
|
||||
|
||||
const auto matches_instruction = [instruction](const auto& matcher){ return matcher.Matches(instruction); };
|
||||
|
||||
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
|
||||
return iter != table.end() ? std::optional<std::reference_wrapper<const Thumb16Matcher<V>>>(*iter) : std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
354
externals/dynarmic/src/frontend/A32/decoder/thumb32.h
vendored
Executable file
354
externals/dynarmic/src/frontend/A32/decoder/thumb32.h
vendored
Executable file
@@ -0,0 +1,354 @@
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2016 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "frontend/decoder/decoder_detail.h"
|
||||
#include "frontend/decoder/matcher.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
template <typename Visitor>
|
||||
using Thumb32Matcher = Decoder::Matcher<Visitor, u32>;
|
||||
|
||||
template<typename V>
|
||||
std::optional<std::reference_wrapper<const Thumb32Matcher<V>>> DecodeThumb32(u32 instruction) {
|
||||
static const std::vector<Thumb32Matcher<V>> table = {
|
||||
|
||||
#define INST(fn, name, bitstring) Decoder::detail::detail<Thumb32Matcher<V>>::GetMatcher(fn, name, bitstring)
|
||||
|
||||
// Load/Store Multiple
|
||||
//INST(&V::thumb32_SRS_1, "SRS", "1110100000-0--------------------"),
|
||||
//INST(&V::thumb32_RFE_2, "RFE", "1110100000-1--------------------"),
|
||||
//INST(&V::thumb32_STMIA, "STMIA/STMEA", "1110100010-0--------------------"),
|
||||
//INST(&V::thumb32_POP, "POP", "1110100010111101----------------"),
|
||||
//INST(&V::thumb32_LDMIA, "LDMIA/LDMFD", "1110100010-1--------------------"),
|
||||
//INST(&V::thumb32_PUSH, "PUSH", "1110100100101101----------------"),
|
||||
//INST(&V::thumb32_STMDB, "STMDB/STMFD", "1110100100-0--------------------"),
|
||||
//INST(&V::thumb32_LDMDB, "LDMDB/LDMEA", "1110100100-1--------------------"),
|
||||
//INST(&V::thumb32_SRS_1, "SRS", "1110100110-0--------------------"),
|
||||
//INST(&V::thumb32_RFE_2, "RFE", "1110100110-1--------------------"),
|
||||
|
||||
// Load/Store Dual, Load/Store Exclusive, Table Branch
|
||||
//INST(&V::thumb32_STREX, "STREX", "111010000100--------------------"),
|
||||
//INST(&V::thumb32_LDREX, "LDREX", "111010000101--------------------"),
|
||||
//INST(&V::thumb32_STRD_imm_1, "STRD (imm)", "11101000-110--------------------"),
|
||||
//INST(&V::thumb32_STRD_imm_2, "STRD (imm)", "11101001-1-0--------------------"),
|
||||
//INST(&V::thumb32_LDRD_imm_1, "LDRD (lit)", "11101000-1111111----------------"),
|
||||
//INST(&V::thumb32_LDRD_imm_2, "LDRD (lit)", "11101001-1-11111----------------"),
|
||||
//INST(&V::thumb32_LDRD_imm_1, "LDRD (imm)", "11101000-111--------------------"),
|
||||
//INST(&V::thumb32_LDRD_imm_2, "LDRD (imm)", "11101001-1-1--------------------"),
|
||||
//INST(&V::thumb32_STREXB, "STREXB", "111010001100------------0100----"),
|
||||
//INST(&V::thumb32_STREXH, "STREXH", "111010001100------------0101----"),
|
||||
//INST(&V::thumb32_STREXD, "STREXD", "111010001100------------0111----"),
|
||||
//INST(&V::thumb32_TBB, "TBB", "111010001101------------0000----"),
|
||||
//INST(&V::thumb32_TBH, "TBH", "111010001101------------0001----"),
|
||||
//INST(&V::thumb32_LDREXB, "LDREXB", "111010001101------------0100----"),
|
||||
//INST(&V::thumb32_LDREXH, "LDREXH", "111010001101------------0101----"),
|
||||
//INST(&V::thumb32_LDREXD, "LDREXD", "111010001101------------0111----"),
|
||||
|
||||
// Data Processing (Shifted Register)
|
||||
//INST(&V::thumb32_TST_reg, "TST (reg)", "111010100001--------1111--------"),
|
||||
//INST(&V::thumb32_AND_reg, "AND (reg)", "11101010000---------------------"),
|
||||
//INST(&V::thumb32_BIC_reg, "BIC (reg)", "11101010001---------------------"),
|
||||
//INST(&V::thumb32_MOV_reg, "MOV (reg)", "11101010010-1111-000----0000----"),
|
||||
//INST(&V::thumb32_LSL_imm, "LSL (imm)", "11101010010-1111----------00----"),
|
||||
//INST(&V::thumb32_LSR_imm, "LSR (imm)", "11101010010-1111----------01----"),
|
||||
//INST(&V::thumb32_ASR_imm, "ASR (imm)", "11101010010-1111----------10----"),
|
||||
//INST(&V::thumb32_RRX, "RRX", "11101010010-1111-000----0011----"),
|
||||
//INST(&V::thumb32_ROR_imm, "ROR (imm)", "11101010010-1111----------11----"),
|
||||
//INST(&V::thumb32_ORR_reg, "ORR (reg)", "11101010010---------------------"),
|
||||
//INST(&V::thumb32_MVN_reg, "MVN (reg)", "11101010011-1111----------------"),
|
||||
//INST(&V::thumb32_ORN_reg, "ORN (reg)", "11101010011---------------------"),
|
||||
//INST(&V::thumb32_TEQ_reg, "TEQ (reg)", "111010101001--------1111--------"),
|
||||
//INST(&V::thumb32_EOR_reg, "EOR (reg)", "11101010100---------------------"),
|
||||
//INST(&V::thumb32_PKH, "PKH", "11101010110---------------------"),
|
||||
//INST(&V::thumb32_CMN_reg, "CMN (reg)", "111010110001--------1111--------"),
|
||||
//INST(&V::thumb32_ADD_reg, "ADD (reg)", "11101011000---------------------"),
|
||||
//INST(&V::thumb32_ADC_reg, "ADC (reg)", "11101011010---------------------"),
|
||||
//INST(&V::thumb32_SBC_reg, "SBC (reg)", "11101011011---------------------"),
|
||||
//INST(&V::thumb32_CMP_reg, "CMP (reg)", "111010111011--------1111--------"),
|
||||
//INST(&V::thumb32_SUB_reg, "SUB (reg)", "11101011101---------------------"),
|
||||
//INST(&V::thumb32_RSB_reg, "RSB (reg)", "11101011110---------------------"),
|
||||
|
||||
// Data Processing (Modified Immediate)
|
||||
//INST(&V::thumb32_TST_imm, "TST (imm)", "11110-000001----0---1111--------"),
|
||||
//INST(&V::thumb32_AND_imm, "AND (imm)", "11110-00000-----0---------------"),
|
||||
//INST(&V::thumb32_BIC_imm, "BIC (imm)", "11110-00001-----0---------------"),
|
||||
//INST(&V::thumb32_MOV_imm, "MOV (imm)", "11110000010-11110---------------"),
|
||||
//INST(&V::thumb32_ORR_imm, "ORR (imm)", "11110-00010-----0---------------"),
|
||||
//INST(&V::thumb32_MVN_imm, "MVN (imm)", "11110000011-11110---------------"),
|
||||
//INST(&V::thumb32_ORN_imm, "ORN (imm)", "11110-00011-----0---------------"),
|
||||
//INST(&V::thumb32_TEQ_imm, "TEQ (imm)", "11110-001001----0---1111--------"),
|
||||
//INST(&V::thumb32_EOR_imm, "EOR (imm)", "11110-00100-----0---------------"),
|
||||
//INST(&V::thumb32_CMN_imm, "CMN (imm)", "11110-010001----0---1111--------"),
|
||||
//INST(&V::thumb32_ADD_imm_1, "ADD (imm)", "11110-01000-----0---------------"),
|
||||
//INST(&V::thumb32_ADC_imm, "ADC (imm)", "11110-01010-----0---------------"),
|
||||
//INST(&V::thumb32_SBC_imm, "SBC (imm)", "11110-01011-----0---------------"),
|
||||
//INST(&V::thumb32_CMP_imm, "CMP (imm)", "11110-011011----0---1111--------"),
|
||||
//INST(&V::thumb32_SUB_imm_1, "SUB (imm)", "11110-01101-----0---------------"),
|
||||
//INST(&V::thumb32_RSB_imm, "RSB (imm)", "11110-01110-----0---------------"),
|
||||
|
||||
// Data Processing (Plain Binary Immediate)
|
||||
//INST(&V::thumb32_ADR, "ADR", "11110-10000011110---------------"),
|
||||
//INST(&V::thumb32_ADD_imm_2, "ADD (imm)", "11110-100000----0---------------"),
|
||||
//INST(&V::thumb32_MOVW_imm, "MOVW (imm)", "11110-100100----0---------------"),
|
||||
//INST(&V::thumb32_ADR, "ADR", "11110-10101011110---------------"),
|
||||
//INST(&V::thumb32_SUB_imm_2, "SUB (imm)", "11110-101010----0---------------"),
|
||||
//INST(&V::thumb32_MOVT, "MOVT", "11110-101100----0---------------"),
|
||||
//INST(&V::thumb32_SSAT, "SSAT", "11110-110000----0---------------"),
|
||||
//INST(&V::thumb32_SSAT16, "SSAT16", "11110-110010----0000----00------"),
|
||||
//INST(&V::thumb32_SSAT, "SSAT", "11110-110010----0---------------"),
|
||||
//INST(&V::thumb32_SBFX, "SBFX", "11110-110100----0---------------"),
|
||||
//INST(&V::thumb32_BFC, "BFC", "11110-11011011110---------------"),
|
||||
//INST(&V::thumb32_BFI, "BFI", "11110-110110----0---------------"),
|
||||
//INST(&V::thumb32_USAT, "USAT", "11110-111000----0---------------"),
|
||||
//INST(&V::thumb32_USAT16, "USAT16", "11110-111010----0000----00------"),
|
||||
//INST(&V::thumb32_USAT, "USAT", "11110-111010----0---------------"),
|
||||
//INST(&V::thumb32_UBFX, "UBFX", "11110-111100----0---------------"),
|
||||
|
||||
// Branches and Miscellaneous Control
|
||||
//INST(&V::thumb32_MSR_banked, "MSR (banked)", "11110011100-----10-0------1-----"),
|
||||
//INST(&V::thumb32_MSR_reg_1, "MSR (reg)", "111100111001----10-0------0-----"),
|
||||
//INST(&V::thumb32_MSR_reg_2, "MSR (reg)", "111100111000----10-0--01--0-----"),
|
||||
//INST(&V::thumb32_MSR_reg_3, "MSR (reg)", "111100111000----10-0--1---0-----"),
|
||||
//INST(&V::thumb32_MSR_reg_4, "MSR (reg)", "111100111000----10-0--00--0-----"),
|
||||
|
||||
//INST(&V::thumb32_NOP, "NOP", "111100111010----10-0-00000000000"),
|
||||
//INST(&V::thumb32_YIELD, "YIELD", "111100111010----10-0-00000000001"),
|
||||
//INST(&V::thumb32_WFE, "WFE", "111100111010----10-0-00000000010"),
|
||||
//INST(&V::thumb32_WFI, "WFI", "111100111010----10-0-00000000011"),
|
||||
//INST(&V::thumb32_SEV, "SEV", "111100111010----10-0-00000000100"),
|
||||
//INST(&V::thumb32_SEVL, "SEVL", "111100111010----10-0-00000000101"),
|
||||
//INST(&V::thumb32_DBG, "DBG", "111100111010----10-0-0001111----"),
|
||||
//INST(&V::thumb32_CPS, "CPS", "111100111010----10-0------------"),
|
||||
|
||||
//INST(&V::thumb32_ENTERX, "ENTERX", "111100111011----10-0----0001----"),
|
||||
//INST(&V::thumb32_LEAVEX, "LEAVEX", "111100111011----10-0----0000----"),
|
||||
//INST(&V::thumb32_CLREX, "CLREX", "111100111011----10-0----0010----"),
|
||||
//INST(&V::thumb32_DSB, "DSB", "111100111011----10-0----0100----"),
|
||||
//INST(&V::thumb32_DMB, "DMB", "111100111011----10-0----0101----"),
|
||||
//INST(&V::thumb32_ISB, "ISB", "111100111011----10-0----0110----"),
|
||||
|
||||
//INST(&V::thumb32_BXJ, "BXJ", "111100111100----1000111100000000"),
|
||||
//INST(&V::thumb32_ERET, "ERET", "11110011110111101000111100000000"),
|
||||
//INST(&V::thumb32_SUBS_pc_lr, "SUBS PC, LR", "111100111101111010001111--------"),
|
||||
|
||||
//INST(&V::thumb32_MRS_banked, "MRS (banked)", "11110011111-----10-0------1-----"),
|
||||
//INST(&V::thumb32_MRS_reg_1, "MRS (reg)", "111100111111----10-0------0-----"),
|
||||
//INST(&V::thumb32_MRS_reg_2, "MRS (reg)", "111100111110----10-0------0-----"),
|
||||
//INST(&V::thumb32_HVC, "HVC", "111101111110----1000------------"),
|
||||
//INST(&V::thumb32_SMC, "SMC", "111101111111----1000000000000000"),
|
||||
//INST(&V::thumb32_UDF, "UDF", "111101111111----1010------------"),
|
||||
|
||||
//INST(&V::thumb32_BL, "BL", "11110-----------11-1------------"),
|
||||
//INST(&V::thumb32_BLX, "BLX", "11110-----------11-0------------"),
|
||||
//INST(&V::thumb32_B, "B", "11110-----------10-1------------"),
|
||||
//INST(&V::thumb32_B_cond, "B (cond)", "11110-----------10-0------------"),
|
||||
|
||||
// Store Single Data Item
|
||||
//INST(&V::thumb32_STRB_imm_1, "STRB (imm)", "111110000000--------1--1--------"),
|
||||
//INST(&V::thumb32_STRB_imm_2, "STRB (imm)", "111110000000--------1100--------"),
|
||||
//INST(&V::thumb32_STRB_imm_3, "STRB (imm)", "111110001000--------------------"),
|
||||
//INST(&V::thumb32_STRBT, "STRBT", "111110000000--------1110--------"),
|
||||
//INST(&V::thumb32_STRB, "STRB (reg)", "111110000000--------000000------"),
|
||||
//INST(&V::thumb32_STRH_imm_1, "STRH (imm)", "111110000010--------1--1--------"),
|
||||
//INST(&V::thumb32_STRH_imm_2, "STRH (imm)", "111110000010--------1100--------"),
|
||||
//INST(&V::thumb32_STRH_imm_3, "STRH (imm)", "111110001010--------------------"),
|
||||
//INST(&V::thumb32_STRHT, "STRHT", "111110000010--------1110--------"),
|
||||
//INST(&V::thumb32_STRH, "STRH (reg)", "111110000010--------000000------"),
|
||||
//INST(&V::thumb32_STR_imm_1, "STR (imm)", "111110000100--------1--1--------"),
|
||||
//INST(&V::thumb32_STR_imm_2, "STR (imm)", "111110000100--------1100--------"),
|
||||
//INST(&V::thumb32_STR_imm_3, "STR (imm)", "111110001100--------------------"),
|
||||
//INST(&V::thumb32_STRT, "STRT", "111110000100--------1110--------"),
|
||||
//INST(&V::thumb32_STR_reg, "STR (reg)", "111110000100--------000000------"),
|
||||
|
||||
// Load Byte and Memory Hints
|
||||
//INST(&V::thumb32_PLD_lit, "PLD (lit)", "11111000-00111111111------------"),
|
||||
//INST(&V::thumb32_PLD_reg, "PLD (reg)", "111110000001----1111000000------"),
|
||||
//INST(&V::thumb32_PLD_imm8, "PLD (imm8)", "1111100000-1----11111100--------"),
|
||||
//INST(&V::thumb32_PLD_imm12, "PLD (imm12)", "111110001001----1111------------"),
|
||||
//INST(&V::thumb32_PLI_lit, "PLI (lit)", "11111001-00111111111------------"),
|
||||
//INST(&V::thumb32_PLI_reg, "PLI (reg)", "111110010001----1111000000------"),
|
||||
//INST(&V::thumb32_PLI_imm8, "PLI (imm8)", "111110010001----11111100--------"),
|
||||
//INST(&V::thumb32_PLI_imm12, "PLI (imm12)", "111110011001----1111------------"),
|
||||
//INST(&V::thumb32_LDRB_lit, "LDRB (lit)", "11111000-0011111----------------"),
|
||||
//INST(&V::thumb32_LDRB_reg, "LDRB (reg)", "111110000001--------000000------"),
|
||||
//INST(&V::thumb32_LDRBT, "LDRBT", "111110000001--------1110--------"),
|
||||
//INST(&V::thumb32_LDRB_imm8, "LDRB (imm8)", "111110000001--------1-----------"),
|
||||
//INST(&V::thumb32_LDRB_imm12, "LDRB (imm12)", "111110001001--------------------"),
|
||||
//INST(&V::thumb32_LDRSB_lit, "LDRSB (lit)", "11111001-0011111----------------"),
|
||||
//INST(&V::thumb32_LDRSB_reg, "LDRSB (reg)", "111110010001--------000000------"),
|
||||
//INST(&V::thumb32_LDRSBT, "LDRSBT", "111110010001--------1110--------"),
|
||||
//INST(&V::thumb32_LDRSB_imm8, "LDRSB (imm8)", "111110010001--------1-----------"),
|
||||
//INST(&V::thumb32_LDRSB_imm12, "LDRSB (imm12)", "111110011001--------------------"),
|
||||
|
||||
// Load Halfword and Memory Hints
|
||||
//INST(&V::thumb32_LDRH_lit, "LDRH (lit)", "11111000-0111111----------------"),
|
||||
//INST(&V::thumb32_LDRH_reg, "LDRH (reg)", "111110000011--------000000------"),
|
||||
//INST(&V::thumb32_LDRHT, "LDRHT", "111110000011--------1110--------"),
|
||||
//INST(&V::thumb32_LDRH_imm8, "LDRH (imm8)", "111110000011--------1-----------"),
|
||||
//INST(&V::thumb32_LDRH_imm12, "LDRH (imm12)", "111110001011--------------------"),
|
||||
//INST(&V::thumb32_LDRSH_lit, "LDRSH (lit)", "11111001-0111111----------------"),
|
||||
//INST(&V::thumb32_LDRSH_reg, "LDRSH (reg)", "111110010011--------000000------"),
|
||||
//INST(&V::thumb32_LDRSHT, "LDRSHT", "111110010011--------1110--------"),
|
||||
//INST(&V::thumb32_LDRSH_imm8, "LDRSH (imm8)", "111110010011--------1-----------"),
|
||||
//INST(&V::thumb32_LDRSH_imm12, "LDRSH (imm12)", "111110011011--------------------"),
|
||||
//INST(&V::thumb32_NOP, "NOP", "111110010011----1111000000------"),
|
||||
//INST(&V::thumb32_NOP, "NOP", "111110010011----11111100--------"),
|
||||
//INST(&V::thumb32_NOP, "NOP", "11111001-01111111111------------"),
|
||||
//INST(&V::thumb32_NOP, "NOP", "111110011011----1111------------"),
|
||||
|
||||
// Load Word
|
||||
//INST(&V::thumb32_LDR_lit, "LDR (lit)", "11111000-1011111----------------"),
|
||||
//INST(&V::thumb32_LDRT, "LDRT", "111110000101--------1110--------"),
|
||||
//INST(&V::thumb32_LDR_reg, "LDR (reg)", "111110000101--------000000------"),
|
||||
//INST(&V::thumb32_LDR_imm8, "LDR (imm8)", "111110000101--------1-----------"),
|
||||
//INST(&V::thumb32_LDR_imm12, "LDR (imm12)", "111110001101--------------------"),
|
||||
|
||||
// Undefined
|
||||
//INST(&V::thumb32_UDF, "UDF", "1111100--111--------------------"),
|
||||
|
||||
// Data Processing (register)
|
||||
//INST(&V::thumb32_LSL_reg, "LSL (reg)", "11111010000-----1111----0000----"),
|
||||
//INST(&V::thumb32_LSR_reg, "LSR (reg)", "11111010001-----1111----0000----"),
|
||||
//INST(&V::thumb32_ASR_reg, "ASR (reg)", "11111010010-----1111----0000----"),
|
||||
//INST(&V::thumb32_ROR_reg, "ROR (reg)", "11111010011-----1111----0000----"),
|
||||
//INST(&V::thumb32_SXTH, "SXTH", "11111010000011111111----1-------"),
|
||||
//INST(&V::thumb32_SXTAH, "SXTAH", "111110100000----1111----1-------"),
|
||||
//INST(&V::thumb32_UXTH, "UXTH", "11111010000111111111----1-------"),
|
||||
//INST(&V::thumb32_UXTAH, "UXTAH", "111110100001----1111----1-------"),
|
||||
//INST(&V::thumb32_SXTB16, "SXTB16", "11111010001011111111----1-------"),
|
||||
//INST(&V::thumb32_SXTAB16, "SXTAB16", "111110100010----1111----1-------"),
|
||||
//INST(&V::thumb32_UXTB16, "UXTB16", "11111010001111111111----1-------"),
|
||||
//INST(&V::thumb32_UXTAB16, "UXTAB16", "111110100011----1111----1-------"),
|
||||
//INST(&V::thumb32_SXTB, "SXTB", "11111010010011111111----1-------"),
|
||||
//INST(&V::thumb32_SXTAB, "SXTAB", "111110100100----1111----1-------"),
|
||||
//INST(&V::thumb32_UXTB, "UXTB", "11111010010111111111----1-------"),
|
||||
//INST(&V::thumb32_UXTAB, "UXTAB", "111110100101----1111----1-------"),
|
||||
|
||||
// Parallel Addition and Subtraction (signed)
|
||||
//INST(&V::thumb32_SADD16, "SADD16", "111110101001----1111----0000----"),
|
||||
//INST(&V::thumb32_SASX, "SASX", "111110101010----1111----0000----"),
|
||||
//INST(&V::thumb32_SSAX, "SSAX", "111110101110----1111----0000----"),
|
||||
//INST(&V::thumb32_SSUB16, "SSUB16", "111110101101----1111----0000----"),
|
||||
//INST(&V::thumb32_SADD8, "SADD8", "111110101000----1111----0000----"),
|
||||
//INST(&V::thumb32_SSUB8, "SSUB8", "111110101100----1111----0000----"),
|
||||
//INST(&V::thumb32_QADD16, "QADD16", "111110101001----1111----0001----"),
|
||||
//INST(&V::thumb32_QASX, "QASX", "111110101010----1111----0001----"),
|
||||
//INST(&V::thumb32_QSAX, "QSAX", "111110101110----1111----0001----"),
|
||||
//INST(&V::thumb32_QSUB16, "QSUB16", "111110101101----1111----0001----"),
|
||||
//INST(&V::thumb32_QADD8, "QADD8", "111110101000----1111----0001----"),
|
||||
//INST(&V::thumb32_QSUB8, "QSUB8", "111110101100----1111----0001----"),
|
||||
//INST(&V::thumb32_SHADD16, "SHADD16", "111110101001----1111----0010----"),
|
||||
//INST(&V::thumb32_SHASX, "SHASX", "111110101010----1111----0010----"),
|
||||
//INST(&V::thumb32_SHSAX, "SHSAX", "111110101110----1111----0010----"),
|
||||
//INST(&V::thumb32_SHSUB16, "SHSUB16", "111110101101----1111----0010----"),
|
||||
//INST(&V::thumb32_SHADD8, "SHADD8", "111110101000----1111----0010----"),
|
||||
//INST(&V::thumb32_SHSUB8, "SHSUB8", "111110101100----1111----0010----"),
|
||||
|
||||
// Parallel Addition and Subtraction (unsigned)
|
||||
//INST(&V::thumb32_UADD16, "UADD16", "111110101001----1111----0100----"),
|
||||
//INST(&V::thumb32_UASX, "UASX", "111110101010----1111----0100----"),
|
||||
//INST(&V::thumb32_USAX, "USAX", "111110101110----1111----0100----"),
|
||||
//INST(&V::thumb32_USUB16, "USUB16", "111110101101----1111----0100----"),
|
||||
//INST(&V::thumb32_UADD8, "UADD8", "111110101000----1111----0100----"),
|
||||
//INST(&V::thumb32_USUB8, "USUB8", "111110101100----1111----0100----"),
|
||||
//INST(&V::thumb32_UQADD16, "UQADD16", "111110101001----1111----0101----"),
|
||||
//INST(&V::thumb32_UQASX, "UQASX", "111110101010----1111----0101----"),
|
||||
//INST(&V::thumb32_UQSAX, "UQSAX", "111110101110----1111----0101----"),
|
||||
//INST(&V::thumb32_UQSUB16, "UQSUB16", "111110101101----1111----0101----"),
|
||||
//INST(&V::thumb32_UQADD8, "UQADD8", "111110101000----1111----0101----"),
|
||||
//INST(&V::thumb32_UQSUB8, "UQSUB8", "111110101100----1111----0101----"),
|
||||
//INST(&V::thumb32_UHADD16, "UHADD16", "111110101001----1111----0110----"),
|
||||
//INST(&V::thumb32_UHASX, "UHASX", "111110101010----1111----0110----"),
|
||||
//INST(&V::thumb32_UHSAX, "UHSAX", "111110101110----1111----0110----"),
|
||||
//INST(&V::thumb32_UHSUB16, "UHSUB16", "111110101101----1111----0110----"),
|
||||
//INST(&V::thumb32_UHADD8, "UHADD8", "111110101000----1111----0110----"),
|
||||
//INST(&V::thumb32_UHSUB8, "UHSUB8", "111110101100----1111----0110----"),
|
||||
|
||||
// Miscellaneous Operations
|
||||
//INST(&V::thumb32_QADD, "QADD", "111110101000----1111----1000----"),
|
||||
//INST(&V::thumb32_QDADD, "QDADD", "111110101000----1111----1001----"),
|
||||
//INST(&V::thumb32_QSUB, "QSUB", "111110101000----1111----1010----"),
|
||||
//INST(&V::thumb32_QDSUB, "QDSUB", "111110101000----1111----1011----"),
|
||||
//INST(&V::thumb32_REV, "REV", "111110101001----1111----1000----"),
|
||||
//INST(&V::thumb32_REV16, "REV16", "111110101001----1111----1001----"),
|
||||
//INST(&V::thumb32_RBIT, "RBIT", "111110101001----1111----1010----"),
|
||||
//INST(&V::thumb32_REVSH, "REVSH", "111110101001----1111----1011----"),
|
||||
//INST(&V::thumb32_SEL, "SEL", "111110101010----1111----1000----"),
|
||||
//INST(&V::thumb32_CLZ, "CLZ", "111110101011----1111----1000----"),
|
||||
|
||||
// Multiply, Multiply Accumulate, and Absolute Difference
|
||||
//INST(&V::thumb32_MUL, "MUL", "111110110000----1111----0000----"),
|
||||
//INST(&V::thumb32_MLA, "MLA", "111110110000------------0000----"),
|
||||
//INST(&V::thumb32_MLS, "MLS", "111110110000------------0001----"),
|
||||
//INST(&V::thumb32_SMULXY, "SMULXY", "111110110001----1111----00------"),
|
||||
//INST(&V::thumb32_SMLAXY, "SMLAXY", "111110110001------------00------"),
|
||||
//INST(&V::thumb32_SMUAD, "SMUAD", "111110110010----1111----000-----"),
|
||||
//INST(&V::thumb32_SMLAD, "SMLAD", "111110110010------------000-----"),
|
||||
//INST(&V::thumb32_SMULWY, "SMULWY", "111110110011----1111----000-----"),
|
||||
//INST(&V::thumb32_SMLAWY, "SMLAWY", "111110110011------------000-----"),
|
||||
//INST(&V::thumb32_SMUSD, "SMUSD", "111110110100----1111----000-----"),
|
||||
//INST(&V::thumb32_SMLSD, "SMLSD", "111110110100------------000-----"),
|
||||
//INST(&V::thumb32_SMMUL, "SMMUL", "111110110101----1111----000-----"),
|
||||
//INST(&V::thumb32_SMMLA, "SMMLA", "111110110101------------000-----"),
|
||||
//INST(&V::thumb32_SMMLS, "SMMLS", "111110110110------------000-----"),
|
||||
//INST(&V::thumb32_USAD8, "USAD8", "111110110111----1111----0000----"),
|
||||
//INST(&V::thumb32_USADA8, "USADA8", "111110110111------------0000----"),
|
||||
|
||||
// Long Multiply, Long Multiply Accumulate, and Divide
|
||||
//INST(&V::thumb32_SMULL, "SMULL", "111110111000------------0000----"),
|
||||
//INST(&V::thumb32_SDIV, "SDIV", "111110111001------------1111----"),
|
||||
//INST(&V::thumb32_UMULL, "UMULL", "111110111010------------0000----"),
|
||||
//INST(&V::thumb32_UDIV, "UDIV", "111110111011------------1111----"),
|
||||
//INST(&V::thumb32_SMLAL, "SMLAL", "111110111100------------0000----"),
|
||||
//INST(&V::thumb32_SMLALXY, "SMLALXY", "111110111100------------10------"),
|
||||
//INST(&V::thumb32_SMLALD, "SMLALD", "111110111100------------110-----"),
|
||||
//INST(&V::thumb32_SMLSLD, "SMLSLD", "111110111101------------110-----"),
|
||||
//INST(&V::thumb32_UMLAL, "UMLAL", "111110111110------------0000----"),
|
||||
//INST(&V::thumb32_UMAAL, "UMAAL", "111110111110------------0110----"),
|
||||
|
||||
// Coprocessor
|
||||
//INST(&V::thumb32_MCRR2, "MCRR2", "111111000100--------------------"),
|
||||
//INST(&V::thumb32_MCRR, "MCRR", "111011000100--------------------"),
|
||||
//INST(&V::thumb32_STC2, "STC2", "1111110----0--------------------"),
|
||||
//INST(&V::thumb32_STC, "STC", "1110110----0--------------------"),
|
||||
//INST(&V::thumb32_MRRC2, "MRRC2", "111111000101--------------------"),
|
||||
//INST(&V::thumb32_MRRC, "MRRC", "111011000101--------------------"),
|
||||
//INST(&V::thumb32_LDC2_lit, "LDC2 (lit)", "1111110----11111----------------"),
|
||||
//INST(&V::thumb32_LDC_lit, "LDC (lit)", "1110110----11111----------------"),
|
||||
//INST(&V::thumb32_LDC2_imm, "LDC2 (imm)", "1111110----1--------------------"),
|
||||
//INST(&V::thumb32_LDC_imm, "LDC (imm)", "1110110----1--------------------"),
|
||||
//INST(&V::thumb32_CDP2, "CDP2", "11111110-------------------0----"),
|
||||
//INST(&V::thumb32_CDP, "CDP", "11101110-------------------0----"),
|
||||
//INST(&V::thumb32_MCR2, "MCR2", "11111110---0---------------1----"),
|
||||
//INST(&V::thumb32_MCR, "MCR", "11101110---0---------------1----"),
|
||||
//INST(&V::thumb32_MRC2, "MRC2", "11111110---1---------------1----"),
|
||||
//INST(&V::thumb32_MRC, "MRC", "11101110---1---------------1----"),
|
||||
|
||||
// Branch instructions
|
||||
INST(&V::thumb32_BL_imm, "BL (imm)", "11110vvvvvvvvvvv11111vvvvvvvvvvv"), // v4T
|
||||
INST(&V::thumb32_BLX_imm, "BLX (imm)", "11110vvvvvvvvvvv11101vvvvvvvvvvv"), // v5T
|
||||
|
||||
// Misc instructions
|
||||
INST(&V::thumb32_UDF, "UDF", "111101111111----1010------------"), // v6T2
|
||||
|
||||
#undef INST
|
||||
|
||||
};
|
||||
|
||||
const auto matches_instruction = [instruction](const auto& matcher){ return matcher.Matches(instruction); };
|
||||
|
||||
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
|
||||
return iter != table.end() ? std::optional<std::reference_wrapper<const Thumb32Matcher<V>>>(*iter) : std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
58
externals/dynarmic/src/frontend/A32/decoder/vfp.h
vendored
Executable file
58
externals/dynarmic/src/frontend/A32/decoder/vfp.h
vendored
Executable file
@@ -0,0 +1,58 @@
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2032 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "frontend/decoder/decoder_detail.h"
|
||||
#include "frontend/decoder/matcher.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
template <typename Visitor>
|
||||
using VFPMatcher = Decoder::Matcher<Visitor, u32>;
|
||||
|
||||
template<typename V>
|
||||
std::optional<std::reference_wrapper<const VFPMatcher<V>>> DecodeVFP(u32 instruction) {
|
||||
using Table = std::vector<VFPMatcher<V>>;
|
||||
|
||||
static const struct Tables {
|
||||
Table unconditional;
|
||||
Table conditional;
|
||||
} tables = []{
|
||||
Table list = {
|
||||
|
||||
#define INST(fn, name, bitstring) Decoder::detail::detail<VFPMatcher<V>>::GetMatcher(&V::fn, name, bitstring),
|
||||
#include "vfp.inc"
|
||||
#undef INST
|
||||
|
||||
};
|
||||
|
||||
const auto division = std::stable_partition(list.begin(), list.end(), [&](const auto& matcher) {
|
||||
return (matcher.GetMask() & 0xF0000000) == 0xF0000000;
|
||||
});
|
||||
|
||||
return Tables{
|
||||
Table{list.begin(), division},
|
||||
Table{division, list.end()},
|
||||
};
|
||||
}();
|
||||
|
||||
const bool is_unconditional = (instruction & 0xF0000000) == 0xF0000000;
|
||||
const Table& table = is_unconditional ? tables.unconditional : tables.conditional;
|
||||
|
||||
const auto matches_instruction = [instruction](const auto& matcher){ return matcher.Matches(instruction); };
|
||||
|
||||
auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
|
||||
return iter != table.end() ? std::optional<std::reference_wrapper<const VFPMatcher<V>>>(*iter) : std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
71
externals/dynarmic/src/frontend/A32/decoder/vfp.inc
vendored
Executable file
71
externals/dynarmic/src/frontend/A32/decoder/vfp.inc
vendored
Executable file
@@ -0,0 +1,71 @@
|
||||
// Floating-point three-register data processing instructions
|
||||
INST(vfp_VMLA, "VMLA", "cccc11100D00nnnndddd101zN0M0mmmm") // VFPv2
|
||||
INST(vfp_VMLS, "VMLS", "cccc11100D00nnnndddd101zN1M0mmmm") // VFPv2
|
||||
INST(vfp_VNMLS, "VNMLS", "cccc11100D01nnnndddd101zN0M0mmmm") // VFPv2
|
||||
INST(vfp_VNMLA, "VNMLA", "cccc11100D01nnnndddd101zN1M0mmmm") // VFPv2
|
||||
INST(vfp_VMUL, "VMUL", "cccc11100D10nnnndddd101zN0M0mmmm") // VFPv2
|
||||
INST(vfp_VNMUL, "VNMUL", "cccc11100D10nnnndddd101zN1M0mmmm") // VFPv2
|
||||
INST(vfp_VADD, "VADD", "cccc11100D11nnnndddd101zN0M0mmmm") // VFPv2
|
||||
INST(vfp_VSUB, "VSUB", "cccc11100D11nnnndddd101zN1M0mmmm") // VFPv2
|
||||
INST(vfp_VDIV, "VDIV", "cccc11101D00nnnndddd101zN0M0mmmm") // VFPv2
|
||||
INST(vfp_VFNMS, "VFNMS", "cccc11101D01nnnndddd101zN0M0mmmm") // VFPv4
|
||||
INST(vfp_VFNMA, "VFNMA", "cccc11101D01nnnndddd101zN1M0mmmm") // VFPv4
|
||||
INST(vfp_VFMA, "VFMA", "cccc11101D10nnnndddd101zN0M0mmmm") // VFPv4
|
||||
INST(vfp_VFMS, "VFMS", "cccc11101D10nnnndddd101zN1M0mmmm") // VFPv4
|
||||
INST(vfp_VSEL, "VSEL", "111111100Dccnnnndddd101zN0M0mmmm") // VFPv5
|
||||
INST(vfp_VMAXNM, "VMAXNNM", "111111101D00nnnndddd101zN0M0mmmm") // VFPv5
|
||||
INST(vfp_VMINNM, "VMINNM", "111111101D00nnnndddd101zN1M0mmmm") // VFPv5
|
||||
|
||||
// Other floating-point data-processing instructions
|
||||
INST(vfp_VMOV_imm, "VMOV (immediate)", "cccc11101D11vvvvdddd101z0000vvvv") // VFPv3
|
||||
INST(vfp_VMOV_reg, "VMOV (reg)", "cccc11101D110000dddd101z01M0mmmm") // VFPv2
|
||||
INST(vfp_VABS, "VABS", "cccc11101D110000dddd101z11M0mmmm") // VFPv2
|
||||
INST(vfp_VNEG, "VNEG", "cccc11101D110001dddd101z01M0mmmm") // VFPv2
|
||||
INST(vfp_VSQRT, "VSQRT", "cccc11101D110001dddd101z11M0mmmm") // VFPv2
|
||||
INST(vfp_VCVTB, "VCVTB", "cccc11101D11001odddd101z01M0mmmm") // VFPv3HP
|
||||
INST(vfp_VCVTT, "VCVTT", "cccc11101D11001odddd101z11M0mmmm") // VFPv3HP
|
||||
INST(vfp_VCMP, "VCMP", "cccc11101D110100dddd101zE1M0mmmm") // VFPv2
|
||||
INST(vfp_VCMP_zero, "VCMP (with zero)", "cccc11101D110101dddd101zE1000000") // VFPv2
|
||||
INST(vfp_VRINTR, "VRINTR", "cccc11101D110110dddd101z01M0mmmm") // VFPv5
|
||||
INST(vfp_VRINTZ, "VRINTZ", "cccc11101D110110dddd101z11M0mmmm") // VFPv5
|
||||
INST(vfp_VRINTX, "VRINTX", "cccc11101D110111dddd101z01M0mmmm") // VFPv5
|
||||
INST(vfp_VCVT_f_to_f, "VCVT (f32<->f64)", "cccc11101D110111dddd101z11M0mmmm") // VFPv2
|
||||
INST(vfp_VCVT_from_int, "VCVT (from int)", "cccc11101D111000dddd101zs1M0mmmm") // VFPv2
|
||||
INST(vfp_VCVT_from_fixed, "VCVT (from fixed)", "cccc11101D11101Udddd101zx1i0vvvv") // VFPv3
|
||||
INST(vfp_VCVT_to_u32, "VCVT (to u32)", "cccc11101D111100dddd101zr1M0mmmm") // VFPv2
|
||||
INST(vfp_VCVT_to_s32, "VCVT (to s32)", "cccc11101D111101dddd101zr1M0mmmm") // VFPv2
|
||||
INST(vfp_VCVT_to_fixed, "VCVT (to fixed)", "cccc11101D11111Udddd101zx1i0vvvv") // VFPv3
|
||||
INST(vfp_VRINT_rm, "VRINT{A,N,P,M}", "111111101D1110mmdddd101z01M0mmmm") // VFPv5
|
||||
INST(vfp_VCVT_rm, "VCVT{A,N,P,M}", "111111101D1111mmdddd101zU1M0mmmm") // VFPv5
|
||||
|
||||
// Floating-point move instructions
|
||||
INST(vfp_VMOV_u32_f64, "VMOV (core to f64)", "cccc11100000ddddtttt1011D0010000") // VFPv2
|
||||
INST(vfp_VMOV_f64_u32, "VMOV (f64 to core)", "cccc11100001nnnntttt1011N0010000") // VFPv2
|
||||
INST(vfp_VMOV_u32_f32, "VMOV (core to f32)", "cccc11100000nnnntttt1010N0010000") // VFPv2
|
||||
INST(vfp_VMOV_f32_u32, "VMOV (f32 to core)", "cccc11100001nnnntttt1010N0010000") // VFPv2
|
||||
INST(vfp_VMOV_2u32_2f32, "VMOV (2xcore to 2xf32)", "cccc11000100uuuutttt101000M1mmmm") // VFPv2
|
||||
INST(vfp_VMOV_2f32_2u32, "VMOV (2xf32 to 2xcore)", "cccc11000101uuuutttt101000M1mmmm") // VFPv2
|
||||
INST(vfp_VMOV_2u32_f64, "VMOV (2xcore to f64)", "cccc11000100uuuutttt101100M1mmmm") // VFPv2
|
||||
INST(vfp_VMOV_f64_2u32, "VMOV (f64 to 2xcore)", "cccc11000101uuuutttt101100M1mmmm") // VFPv2
|
||||
INST(vfp_VMOV_from_i32, "VMOV (core to i32)" , "cccc111000i0nnnntttt1011N0010000") // VFPv4
|
||||
INST(vfp_VMOV_from_i16, "VMOV (core to i16)" , "cccc111000i0nnnntttt1011Ni110000") // ASIMD
|
||||
INST(vfp_VMOV_from_i8, "VMOV (core to i8)", "cccc111001i0nnnntttt1011Nii10000") // ASIMD
|
||||
INST(vfp_VMOV_to_i32, "VMOV (i32 to core)" , "cccc111000i1nnnntttt1011N0010000") // VFPv4
|
||||
INST(vfp_VMOV_to_i16, "VMOV (i16 to core)" , "cccc1110U0i1nnnntttt1011Ni110000") // ASIMD
|
||||
INST(vfp_VMOV_to_i8, "VMOV (i8 to core)", "cccc1110U1i1nnnntttt1011Nii10000") // ASIMD
|
||||
INST(vfp_VDUP, "VDUP (from core)", "cccc11101BQ0ddddtttt1011D0E10000") // ASIMD
|
||||
|
||||
// Floating-point system register access
|
||||
INST(vfp_VMSR, "VMSR", "cccc111011100001tttt101000010000") // VFPv2
|
||||
INST(vfp_VMRS, "VMRS", "cccc111011110001tttt101000010000") // VFPv2
|
||||
|
||||
// Extension register load-store instructions
|
||||
INST(vfp_VPUSH, "VPUSH", "cccc11010D101101dddd101zvvvvvvvv") // VFPv2
|
||||
INST(vfp_VPOP, "VPOP", "cccc11001D111101dddd101zvvvvvvvv") // VFPv2
|
||||
INST(vfp_VLDR, "VLDR", "cccc1101UD01nnnndddd101zvvvvvvvv") // VFPv2
|
||||
INST(vfp_VSTR, "VSTR", "cccc1101UD00nnnndddd101zvvvvvvvv") // VFPv2
|
||||
INST(arm_UDF, "Undefined VSTM/VLDM", "----11000-0---------101---------") // VFPv2
|
||||
INST(vfp_VSTM_a1, "VSTM (A1)", "cccc110puDw0nnnndddd1011vvvvvvvv") // VFPv2
|
||||
INST(vfp_VSTM_a2, "VSTM (A2)", "cccc110puDw0nnnndddd1010vvvvvvvv") // VFPv2
|
||||
INST(vfp_VLDM_a1, "VLDM (A1)", "cccc110puDw1nnnndddd1011vvvvvvvv") // VFPv2
|
||||
INST(vfp_VLDM_a2, "VLDM (A2)", "cccc110puDw1nnnndddd1010vvvvvvvv") // VFPv2
|
Reference in New Issue
Block a user