[ARM] Add alias support (#2209)

This commit is contained in:
Rot127 2023-12-02 07:18:58 +00:00 committed by GitHub
parent 55818f2300
commit d54934201c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 338 additions and 85 deletions

View File

@ -4,6 +4,7 @@
#include "Mapping.h"
#include "capstone/capstone.h"
#include "utils.h"
// create a cache for fast id lookup
static unsigned short *make_id2insn(const insn_map *insns, unsigned int size)
@ -343,6 +344,10 @@ void map_set_is_alias_insn(MCInst *MI, bool Val, uint64_t Alias) {
MI->flat_insn->alias_id = Alias;
}
static inline bool char_ends_mnem(const char c) {
return (!c || c == ' ' || c == '\t');
}
/// Sets an alternative id for some instruction.
/// Or -1 if it fails.
/// You must add (<ARCH>_INS_ALIAS_BEGIN + 1) to the id to get the real id.
@ -354,7 +359,7 @@ void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_i
int i = 0, j = 0;
const char *asm_str_buf = O->buffer;
// Skip spaces and tabs
while (asm_str_buf[i] == ' ' || asm_str_buf[i] == '\t') {
while (is_blank_char(asm_str_buf[i])) {
if (!asm_str_buf[i]) {
MI->flat_insn->alias_id = -1;
return;
@ -362,7 +367,7 @@ void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_i
++i;
}
for (; j < sizeof(alias_mnem) - 1; ++j, ++i) {
if (!asm_str_buf[i] || asm_str_buf[i] == ' ' || asm_str_buf[i] == '\t')
if (char_ends_mnem(asm_str_buf[i]))
break;
alias_mnem[j] = asm_str_buf[i];
}

View File

@ -0,0 +1,48 @@
/* Capstone Disassembly Engine, https://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
/* Rot127 <unisono@quyllur.org> 2022-2023 */
/* Automatically generated file by Capstone's LLVM TableGen Disassembler Backend. */
/* LLVM-commit: <commit> */
/* LLVM-tag: <tag> */
/* Do not edit. */
/* Capstone's LLVM TableGen Backends: */
/* https://github.com/capstone-engine/llvm-capstone */
{ ARM_INS_ALIAS_VMOV, "vmov" },
{ ARM_INS_ALIAS_NOP, "nop" },
{ ARM_INS_ALIAS_YIELD, "yield" },
{ ARM_INS_ALIAS_WFE, "wfe" },
{ ARM_INS_ALIAS_WFI, "wfi" },
{ ARM_INS_ALIAS_SEV, "sev" },
{ ARM_INS_ALIAS_SEVL, "sevl" },
{ ARM_INS_ALIAS_ESB, "esb" },
{ ARM_INS_ALIAS_CSDB, "csdb" },
{ ARM_INS_ALIAS_CLRBHB, "clrbhb" },
{ ARM_INS_ALIAS_PACBTI, "pacbti" },
{ ARM_INS_ALIAS_BTI, "bti" },
{ ARM_INS_ALIAS_PAC, "pac" },
{ ARM_INS_ALIAS_AUT, "aut" },
{ ARM_INS_ALIAS_SSBB, "ssbb" },
{ ARM_INS_ALIAS_PSSBB, "pssbb" },
{ ARM_INS_ALIAS_DFB, "dfb" },
{ ARM_INS_ALIAS_CSETM, "csetm" },
{ ARM_INS_ALIAS_CSET, "cset" },
{ ARM_INS_ALIAS_CINC, "cinc" },
{ ARM_INS_ALIAS_CINV, "cinv" },
{ ARM_INS_ALIAS_CNEG, "cneg" },
{ ARM_INS_ALIAS_VMLAV, "vmlav" },
{ ARM_INS_ALIAS_VMLAVA, "vmlava" },
{ ARM_INS_ALIAS_VRMLALVH, "vrmlalvh" },
{ ARM_INS_ALIAS_VRMLALVHA, "vrmlalvha" },
{ ARM_INS_ALIAS_VMLALV, "vmlalv" },
{ ARM_INS_ALIAS_VMLALVA, "vmlalva" },
{ ARM_INS_ALIAS_VBIC, "vbic" },
{ ARM_INS_ALIAS_VEOR, "veor" },
{ ARM_INS_ALIAS_VORN, "vorn" },
{ ARM_INS_ALIAS_VORR, "vorr" },
{ ARM_INS_ALIAS_VAND, "vand" },
{ ARM_INS_ALIAS_VPSEL, "vpsel" },
{ ARM_INS_ALIAS_ERET, "eret" },

View File

@ -105,14 +105,17 @@ static void printRegName(SStream *OS, unsigned RegNo)
static void printInst(MCInst *MI, SStream *O, void *info)
{
bool isAlias = false;
bool useAliasDetails = map_use_alias_details(MI);
map_set_fill_detail_ops(MI, useAliasDetails);
unsigned Opcode = MCInst_getOpcode(MI);
MCRegisterInfo *MRI = (MCRegisterInfo *)info;
MI->MRI = MRI;
uint64_t Address = MI->address;
switch (Opcode) {
// Check for MOVs and print canonical forms, instead.
case ARM_MOVsr: {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
// FIXME: Thumb variants?
MCOperand *MO3 = MCInst_getOperand(MI, (3));
@ -131,11 +134,15 @@ static void printInst(MCInst *MI, SStream *O, void *info)
SStream_concat0(O, ", ");
printOperand(MI, 2, O);
;
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
}
case ARM_MOVsi: {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
// FIXME: Thumb variants?
MCOperand *MO2 = MCInst_getOperand(MI, (2));
@ -151,15 +158,20 @@ static void printInst(MCInst *MI, SStream *O, void *info)
printOperand(MI, 1, O);
if (ARM_AM_getSORegShOp(MCOperand_getImm(MO2)) == ARM_AM_rrx) {
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
}
SStream_concat(O, "%s%s%s%d", ", ", markup("<imm:"), "#",
translateShiftImm(ARM_AM_getSORegOffset(
MCOperand_getImm(MO2))));
SStream_concat0(O, markup(">"));
;
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
}
// A8.6.123 PUSH
@ -167,6 +179,8 @@ static void printInst(MCInst *MI, SStream *O, void *info)
case ARM_t2STMDB_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP &&
MCInst_getNumOperands(MI) > 5) {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
// Should only print PUSH if there are at least two registers in the
// list.
SStream_concat0(O, "push");
@ -176,20 +190,28 @@ static void printInst(MCInst *MI, SStream *O, void *info)
SStream_concat0(O, " ");
printRegisterList(MI, 4, O);
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
} else
break;
case ARM_STR_PRE_IMM:
if (MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP &&
MCOperand_getImm(MCInst_getOperand(MI, (3))) == -4) {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
SStream_concat1(O, ' ');
SStream_concat0(O, "push");
printPredicateOperand(MI, 4, O);
SStream_concat0(O, " {");
printOperand(MI, 1, O);
SStream_concat0(O, "}");
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
} else
break;
@ -198,6 +220,8 @@ static void printInst(MCInst *MI, SStream *O, void *info)
case ARM_t2LDMIA_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP &&
MCInst_getNumOperands(MI) > 5) {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
// Should only print POP if there are at least two registers in the
// list.
SStream_concat0(O, "pop");
@ -207,7 +231,10 @@ static void printInst(MCInst *MI, SStream *O, void *info)
SStream_concat0(O, " ");
printRegisterList(MI, 4, O);
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
} else
break;
@ -215,24 +242,34 @@ static void printInst(MCInst *MI, SStream *O, void *info)
if ((MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP) &&
((ARM_AM_getAM2Offset(MCOperand_getImm(
MCInst_getOperand(MI, (4)))) == 4))) {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
SStream_concat0(O, "pop");
printPredicateOperand(MI, 5, O);
SStream_concat0(O, " {");
printOperand(MI, 0, O);
SStream_concat0(O, "}");
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
} else
break;
case ARM_t2LDR_POST:
if ((MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP) &&
(Opcode == ARM_t2LDR_POST &&
(MCOperand_getImm(MCInst_getOperand(MI, (3))) == 4))) {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
SStream_concat0(O, "pop");
printPredicateOperand(MI, 4, O);
SStream_concat0(O, " {");
printOperand(MI, 0, O);
SStream_concat0(O, "}");
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
} else
break;
@ -240,12 +277,17 @@ static void printInst(MCInst *MI, SStream *O, void *info)
case ARM_VSTMSDB_UPD:
case ARM_VSTMDDB_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP) {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
SStream_concat0(O, "vpush");
printPredicateOperand(MI, 2, O);
SStream_concat0(O, " ");
printRegisterList(MI, 4, O);
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
} else
break;
@ -253,17 +295,24 @@ static void printInst(MCInst *MI, SStream *O, void *info)
case ARM_VLDMSIA_UPD:
case ARM_VLDMDIA_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP) {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
SStream_concat1(O, ' ');
SStream_concat0(O, "vpop");
printPredicateOperand(MI, 2, O);
SStream_concat0(O, " ");
printRegisterList(MI, 4, O);
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
} else
break;
case ARM_tLDMIA: {
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
bool Writeback = true;
unsigned BaseReg = MCOperand_getReg(MCInst_getOperand(MI, (0)));
for (unsigned i = 3; i < MCInst_getNumOperands(MI); ++i) {
@ -283,7 +332,10 @@ static void printInst(MCInst *MI, SStream *O, void *info)
}
SStream_concat0(O, ", ");
printRegisterList(MI, 3, O);
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
}
// Combine 2 GPRs from disassember into a GPRPair to match with instr def.
@ -297,7 +349,7 @@ static void printInst(MCInst *MI, SStream *O, void *info)
case ARM_LDAEXD:
case ARM_STLEXD: {
const MCRegisterClass *MRC =
MCRegisterInfo_getRegClass(MRI, ARM_GPRRegClassID);
MCRegisterInfo_getRegClass(MI->MRI, ARM_GPRRegClassID);
bool isStore = Opcode == ARM_STREXD || Opcode == ARM_STLEXD;
unsigned Reg = MCOperand_getReg(
MCInst_getOperand(MI, isStore ? 1 : 0));
@ -315,9 +367,9 @@ static void printInst(MCInst *MI, SStream *O, void *info)
MCOperand_CreateReg0(
&NewMI,
MCRegisterInfo_getMatchingSuperReg(
MRI, Reg, ARM_gsub_0,
MI->MRI, Reg, ARM_gsub_0,
MCRegisterInfo_getRegClass(
MRI, ARM_GPRPairRegClassID)));
MI->MRI, ARM_GPRPairRegClassID)));
// Copy the rest operands into NewMI.
for (unsigned i = isStore ? 3 : 2;
@ -332,9 +384,18 @@ static void printInst(MCInst *MI, SStream *O, void *info)
}
case ARM_TSB:
case ARM_t2TSB:
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
SStream_concat0(O, " tsb csync");
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
case ARM_t2DSB:
isAlias = true;
MCInst_setIsAlias(MI, isAlias);
switch (MCOperand_getImm(MCInst_getOperand(MI, (0)))) {
default:
if (!printAliasInstr(MI, Address, O))
@ -347,13 +408,25 @@ static void printInst(MCInst *MI, SStream *O, void *info)
SStream_concat0(O, " pssbb");
break;
};
return;
if (useAliasDetails)
return;
else
goto add_real_detail;
}
if (!printAliasInstr(MI, Address, O))
printInstruction(MI, Address, O);
if (!isAlias)
isAlias |= printAliasInstr(MI, Address, O);
;
add_real_detail:
MCInst_setIsAlias(MI, isAlias);
if (!isAlias || !useAliasDetails) {
map_set_fill_detail_ops(MI, !(isAlias && useAliasDetails));
if (isAlias)
SStream_Close(O);
printInstruction(MI, Address, O);
if (isAlias)
SStream_Open(O);
}
}
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)

View File

@ -22,6 +22,24 @@
#include "ARMInstPrinter.h"
#include "ARMMapping.h"
static const name_map insn_alias_mnem_map[] = {
#include "ARMGenCSAliasMnemMap.inc"
{ ARM_INS_ALIAS_ASR, "asr" },
{ ARM_INS_ALIAS_LSL, "lsl" },
{ ARM_INS_ALIAS_LSR, "lsr" },
{ ARM_INS_ALIAS_ROR, "ror" },
{ ARM_INS_ALIAS_RRX, "rrx" },
{ ARM_INS_ALIAS_UXTW, "uxtw" },
{ ARM_INS_ALIAS_LDM, "ldm" },
{ ARM_INS_ALIAS_POP, "pop" },
{ ARM_INS_ALIAS_PUSH, "push" },
{ ARM_INS_ALIAS_POPW, "pop.w" },
{ ARM_INS_ALIAS_PUSHW, "push.w" },
{ ARM_INS_ALIAS_VPOP, "vpop" },
{ ARM_INS_ALIAS_VPUSH, "vpush" },
{ ARM_INS_ALIAS_END, NULL }
};
static const char *get_custom_reg_alias(unsigned reg)
{
switch (reg) {
@ -165,6 +183,38 @@ static void ARM_add_cs_groups(MCInst *MI)
}
}
static void add_alias_details(MCInst *MI) {
if (!detail_is_set(MI))
return;
switch (MI->flat_insn->alias_id) {
default:
return;
case ARM_INS_ALIAS_POP:
// Doesn't get set because memop is not printed.
ARM_get_detail(MI)->post_index = true;
// fallthrough
case ARM_INS_ALIAS_PUSH:
case ARM_INS_ALIAS_VPUSH:
case ARM_INS_ALIAS_VPOP:
map_add_implicit_read(MI, ARM_REG_SP);
map_add_implicit_write(MI, ARM_REG_SP);
break;
case ARM_INS_ALIAS_LDM: {
bool Writeback = true;
unsigned BaseReg = MCInst_getOpVal(MI, 0);
for (unsigned i = 3; i < MCInst_getNumOperands(MI); ++i) {
if (MCInst_getOpVal(MI, i) == BaseReg)
Writeback = false;
}
if (Writeback && detail_is_set(MI)) {
ARM_get_detail(MI)->operands[0].access |= CS_AC_WRITE;
MI->flat_insn->detail->writeback = true;
}
break;
}
}
}
/// Some instructions have their operands not defined but
/// hardcoded as string.
/// Here we add those oprands to detail.
@ -172,6 +222,12 @@ static void ARM_add_not_defined_ops(MCInst *MI)
{
if (!detail_is_set(MI))
return;
if (MI->flat_insn->is_alias && MI->flat_insn->usesAliasDetails) {
add_alias_details(MI);
return;
}
unsigned Opcode = MCInst_getOpcode(MI);
switch (Opcode) {
default:
@ -424,45 +480,6 @@ static void ARM_add_not_defined_ops(MCInst *MI)
ARM_get_detail_op(MI, -1)->shift.value = translateShiftImm(
ARM_AM_getSORegOffset(MCInst_getOpVal(MI, 2)));
break;
case ARM_STMDB_UPD:
case ARM_t2STMDB_UPD:
if (MCInst_getOpVal(MI, 0) == ARM_SP &&
MCInst_getNumOperands(MI) > 5)
MI->flat_insn->id = ARM_INS_PUSH;
break;
case ARM_STR_PRE_IMM:
if (MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP &&
MCOperand_getImm(MCInst_getOperand(MI, (3))) == -4)
MI->flat_insn->id = ARM_INS_PUSH;
break;
case ARM_LDMIA_UPD:
case ARM_t2LDMIA_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP &&
MCInst_getNumOperands(MI) > 5)
MI->flat_insn->id = ARM_INS_POP;
break;
case ARM_LDR_POST_IMM:
if (MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP &&
ARM_AM_getAM2Offset(
MCOperand_getImm(MCInst_getOperand(MI, (4)))) == 4)
MI->flat_insn->id = ARM_INS_POP;
break;
case ARM_t2LDR_POST:
if ((MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP) &&
(Opcode == ARM_t2LDR_POST &&
(MCOperand_getImm(MCInst_getOperand(MI, (3))) == 4)))
MI->flat_insn->id = ARM_INS_POP;
break;
case ARM_VSTMSDB_UPD:
case ARM_VSTMDDB_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP)
MI->flat_insn->id = ARM_INS_VPUSH;
break;
case ARM_VLDMSIA_UPD:
case ARM_VLDMDIA_UPD:
if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP)
MI->flat_insn->id = ARM_INS_VPOP;
break;
case ARM_tLDMIA: {
bool Writeback = true;
unsigned BaseReg = MCInst_getOpVal(MI, 0);
@ -477,13 +494,6 @@ static void ARM_add_not_defined_ops(MCInst *MI)
break;
}
}
if (MI->flat_insn->id == ARM_INS_PUSH ||
MI->flat_insn->id == ARM_INS_POP ||
MI->flat_insn->id == ARM_INS_VPUSH ||
MI->flat_insn->id == ARM_INS_VPOP) {
map_add_implicit_read(MI, ARM_REG_SP);
map_add_implicit_write(MI, ARM_REG_SP);
}
}
/// Unfortunately there is currently no way to easily extract
@ -549,7 +559,12 @@ static void ARM_post_index_detection(MCInst *MI)
/// and fills the detail information about the instruction and its operands.
void ARM_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
{
MCRegisterInfo *MRI = (MCRegisterInfo *)info;
MI->MRI = MRI;
MI->fillDetailOps = detail_is_set(MI);
MI->flat_insn->usesAliasDetails = map_use_alias_details(MI);
ARM_LLVM_printInstruction(MI, O, info);
map_set_alias_id(MI, O, insn_alias_mnem_map, ARR_SIZE(insn_alias_mnem_map) - 1);
ARM_add_not_defined_ops(MI);
ARM_post_index_detection(MI);
ARM_add_cs_groups(MI);
@ -580,10 +595,20 @@ static arm_reg arm_flag_regs[] = {
const char *ARM_insn_name(csh handle, unsigned int id)
{
#ifndef CAPSTONE_DIET
if (id < ARM_INS_ALIAS_END && id > ARM_INS_ALIAS_BEGIN) {
if (id - ARM_INS_ALIAS_BEGIN >= ARR_SIZE(insn_alias_mnem_map))
return NULL;
return insn_alias_mnem_map[id - ARM_INS_ALIAS_BEGIN - 1].name;
}
if (id >= ARM_INS_ENDING)
return NULL;
return insn_name_maps[id];
if (id < ARR_SIZE(insn_name_maps))
return insn_name_maps[id];
// not found
return NULL;
#else
return NULL;
#endif
@ -1818,7 +1843,7 @@ static void add_cs_detail_template_2(MCInst *MI, arm_op_group op_group,
void ARM_add_cs_detail(MCInst *MI, int /* arm_op_group */ op_group,
va_list args)
{
if (!detail_is_set(MI))
if (!detail_is_set(MI) || !map_fill_detail_ops(MI))
return;
switch (op_group) {
case ARM_OP_GROUP_RegImmShift: {

View File

@ -1179,10 +1179,57 @@ ARM_INS_CBZ = 930
ARM_INS_POP = 931
ARM_INS_PUSH = 932
ARM_INS___BRKDIV0 = 933
ARM_INS_VPOP = 934
ARM_INS_VPUSH = 935
ARM_INS_ENDING = 936
ARM_INS_NOP = ARM_INS_HINT
ARM_INS_ENDING = 934
ARM_INS_ALIAS_BEGIN = 935
ARM_INS_ALIAS_VMOV = 936
ARM_INS_ALIAS_NOP = 937
ARM_INS_ALIAS_YIELD = 938
ARM_INS_ALIAS_WFE = 939
ARM_INS_ALIAS_WFI = 940
ARM_INS_ALIAS_SEV = 941
ARM_INS_ALIAS_SEVL = 942
ARM_INS_ALIAS_ESB = 943
ARM_INS_ALIAS_CSDB = 944
ARM_INS_ALIAS_CLRBHB = 945
ARM_INS_ALIAS_PACBTI = 946
ARM_INS_ALIAS_BTI = 947
ARM_INS_ALIAS_PAC = 948
ARM_INS_ALIAS_AUT = 949
ARM_INS_ALIAS_SSBB = 950
ARM_INS_ALIAS_PSSBB = 951
ARM_INS_ALIAS_DFB = 952
ARM_INS_ALIAS_CSETM = 953
ARM_INS_ALIAS_CSET = 954
ARM_INS_ALIAS_CINC = 955
ARM_INS_ALIAS_CINV = 956
ARM_INS_ALIAS_CNEG = 957
ARM_INS_ALIAS_VMLAV = 958
ARM_INS_ALIAS_VMLAVA = 959
ARM_INS_ALIAS_VRMLALVH = 960
ARM_INS_ALIAS_VRMLALVHA = 961
ARM_INS_ALIAS_VMLALV = 962
ARM_INS_ALIAS_VMLALVA = 963
ARM_INS_ALIAS_VBIC = 964
ARM_INS_ALIAS_VEOR = 965
ARM_INS_ALIAS_VORN = 966
ARM_INS_ALIAS_VORR = 967
ARM_INS_ALIAS_VAND = 968
ARM_INS_ALIAS_VPSEL = 969
ARM_INS_ALIAS_ERET = 970
ARM_INS_ALIAS_ASR = 971
ARM_INS_ALIAS_LSL = 972
ARM_INS_ALIAS_LSR = 973
ARM_INS_ALIAS_ROR = 974
ARM_INS_ALIAS_RRX = 975
ARM_INS_ALIAS_UXTW = 976
ARM_INS_ALIAS_LDM = 977
ARM_INS_ALIAS_POP = 978
ARM_INS_ALIAS_PUSH = 979
ARM_INS_ALIAS_POPW = 980
ARM_INS_ALIAS_PUSHW = 981
ARM_INS_ALIAS_VPOP = 982
ARM_INS_ALIAS_VPUSH = 983
ARM_INS_ALIAS_END = 984
ARM_GRP_INVALID = 0
ARM_GRP_JUMP = 1

View File

@ -1559,15 +1559,67 @@ typedef enum arm_insn {
// clang-format on
// generated content <ARMGenCSInsnEnum.inc> end
// Hard coded alias in LLVM, not defined as alias or instruction.
// We give them a unique ID for convenience.
ARM_INS_VPOP,
ARM_INS_VPUSH,
ARM_INS_ENDING, // <-- mark the end of the list of instructions
// Alias
ARM_INS_NOP = ARM_INS_HINT,
ARM_INS_ALIAS_BEGIN,
// generated content <ARMGenCSAliasEnum.inc> begin
// clang-format off
ARM_INS_ALIAS_VMOV, // Real instr.: ARM_MVE_VORR
ARM_INS_ALIAS_NOP, // Real instr.: ARM_HINT
ARM_INS_ALIAS_YIELD, // Real instr.: ARM_HINT
ARM_INS_ALIAS_WFE, // Real instr.: ARM_HINT
ARM_INS_ALIAS_WFI, // Real instr.: ARM_HINT
ARM_INS_ALIAS_SEV, // Real instr.: ARM_HINT
ARM_INS_ALIAS_SEVL, // Real instr.: ARM_HINT
ARM_INS_ALIAS_ESB, // Real instr.: ARM_HINT
ARM_INS_ALIAS_CSDB, // Real instr.: ARM_HINT
ARM_INS_ALIAS_CLRBHB, // Real instr.: ARM_HINT
ARM_INS_ALIAS_PACBTI, // Real instr.: ARM_t2HINT
ARM_INS_ALIAS_BTI, // Real instr.: ARM_t2HINT
ARM_INS_ALIAS_PAC, // Real instr.: ARM_t2HINT
ARM_INS_ALIAS_AUT, // Real instr.: ARM_t2HINT
ARM_INS_ALIAS_SSBB, // Real instr.: ARM_t2DSB
ARM_INS_ALIAS_PSSBB, // Real instr.: ARM_t2DSB
ARM_INS_ALIAS_DFB, // Real instr.: ARM_t2DSB
ARM_INS_ALIAS_CSETM, // Real instr.: ARM_t2CSINV
ARM_INS_ALIAS_CSET, // Real instr.: ARM_t2CSINC
ARM_INS_ALIAS_CINC, // Real instr.: ARM_t2CSINC
ARM_INS_ALIAS_CINV, // Real instr.: ARM_t2CSINV
ARM_INS_ALIAS_CNEG, // Real instr.: ARM_t2CSNEG
ARM_INS_ALIAS_VMLAV, // Real instr.: ARM_MVE_VMLADAVs8
ARM_INS_ALIAS_VMLAVA, // Real instr.: ARM_MVE_VMLADAVas8
ARM_INS_ALIAS_VRMLALVH, // Real instr.: ARM_MVE_VRMLALDAVHs32
ARM_INS_ALIAS_VRMLALVHA, // Real instr.: ARM_MVE_VRMLALDAVHas32
ARM_INS_ALIAS_VMLALV, // Real instr.: ARM_MVE_VMLALDAVs16
ARM_INS_ALIAS_VMLALVA, // Real instr.: ARM_MVE_VMLALDAVas16
ARM_INS_ALIAS_VBIC, // Real instr.: ARM_MVE_VBIC
ARM_INS_ALIAS_VEOR, // Real instr.: ARM_MVE_VEOR
ARM_INS_ALIAS_VORN, // Real instr.: ARM_MVE_VORN
ARM_INS_ALIAS_VORR, // Real instr.: ARM_MVE_VORR
ARM_INS_ALIAS_VAND, // Real instr.: ARM_MVE_VAND
ARM_INS_ALIAS_VPSEL, // Real instr.: ARM_MVE_VPSEL
ARM_INS_ALIAS_ERET, // Real instr.: ARM_t2SUBS_PC_LR
// clang-format on
// generated content <ARMGenCSAliasEnum.inc> end
// Hardcoded in LLVM printer
ARM_INS_ALIAS_ASR,
ARM_INS_ALIAS_LSL,
ARM_INS_ALIAS_LSR,
ARM_INS_ALIAS_ROR,
ARM_INS_ALIAS_RRX,
ARM_INS_ALIAS_UXTW,
ARM_INS_ALIAS_LDM,
ARM_INS_ALIAS_POP,
ARM_INS_ALIAS_PUSH,
ARM_INS_ALIAS_POPW,
ARM_INS_ALIAS_PUSHW,
ARM_INS_ALIAS_VPOP,
ARM_INS_ALIAS_VPUSH,
ARM_INS_ALIAS_END,
} arm_insn;
/// Group of ARM instructions

View File

@ -42,5 +42,8 @@ uint32_t readBytes32(MCInst *MI, const uint8_t *Bytes);
void append_to_str_lower(char *str, size_t str_size, const char *src);
static inline bool strings_match(const char *str0, const char *str1) { return strcmp(str0, str1) == 0; }
#endif
static inline bool is_blank_char(const char c) {
return c == ' ' || c == '\t';
}
#endif