Path: blob/master/libs/capstone/arch/AArch64/AArch64InstPrinter.c
4389 views
//==-- AArch64InstPrinter.cpp - Convert AArch64 MCInst to assembly syntax --==//1//2// The LLVM Compiler Infrastructure3//4// This file is distributed under the University of Illinois Open Source5// License. See LICENSE.TXT for details.6//7//===----------------------------------------------------------------------===//8//9// This class prints an AArch64 MCInst to a .s file.10//11//===----------------------------------------------------------------------===//1213/* Capstone Disassembly Engine */14/* By Nguyen Anh Quynh <[email protected]>, 2013-2016 */1516#ifdef CAPSTONE_HAS_ARM641718#include <capstone/platform.h>19#include <stdio.h>20#include <stdlib.h>2122#include "AArch64InstPrinter.h"23#include "AArch64Disassembler.h"24#include "AArch64BaseInfo.h"25#include "../../utils.h"26#include "../../MCInst.h"27#include "../../SStream.h"28#include "../../MCRegisterInfo.h"29#include "../../MathExtras.h"3031#include "AArch64Mapping.h"32#include "AArch64AddressingModes.h"3334#define GET_REGINFO_ENUM35#include "AArch64GenRegisterInfo.inc"3637#define GET_INSTRINFO_ENUM38#include "AArch64GenInstrInfo.inc"3940#include "AArch64GenSubtargetInfo.inc"414243static const char *getRegisterName(unsigned RegNo, unsigned AltIdx);44static void printOperand(MCInst *MI, unsigned OpNum, SStream *O);45static bool printSysAlias(MCInst *MI, SStream *O);46static char *printAliasInstr(MCInst *MI, SStream *OS, MCRegisterInfo *MRI);47static void printInstruction(MCInst *MI, SStream *O);48static void printShifter(MCInst *MI, unsigned OpNum, SStream *O);49static void printCustomAliasOperand(MCInst *MI, uint64_t Address, unsigned OpIdx,50unsigned PrintMethodIdx, SStream *OS);515253static cs_ac_type get_op_access(cs_struct *h, unsigned int id, unsigned int index)54{55#ifndef CAPSTONE_DIET56const uint8_t *arr = AArch64_get_op_access(h, id);5758if (arr[index] == CS_AC_IGNORE)59return 0;6061return arr[index];62#else63return 0;64#endif65}6667static void op_addImm(MCInst *MI, int v)68{69if (MI->csh->detail) {70MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;71MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = v;72MI->flat_insn->detail->arm64.op_count++;73}74}7576static void set_sme_index(MCInst *MI, bool status)77{78// Doing SME Index operand79MI->csh->doing_SME_Index = status;8081if (MI->csh->detail != CS_OPT_ON)82return;8384if (status) {85unsigned prevOpNum = MI->flat_insn->detail->arm64.op_count - 1;86unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, prevOpNum));87// Replace previous SME register operand with an OP_SME_INDEX operand88MI->flat_insn->detail->arm64.operands[prevOpNum].type = ARM64_OP_SME_INDEX;89MI->flat_insn->detail->arm64.operands[prevOpNum].sme_index.reg = Reg;90MI->flat_insn->detail->arm64.operands[prevOpNum].sme_index.base = ARM64_REG_INVALID;91MI->flat_insn->detail->arm64.operands[prevOpNum].sme_index.disp = 0;92}93}9495static void set_mem_access(MCInst *MI, bool status)96{97// If status == false, check if this is meant for SME_index98if(!status && MI->csh->doing_SME_Index) {99MI->csh->doing_SME_Index = status;100return;101}102103// Doing Memory Operation104MI->csh->doing_mem = status;105106107if (MI->csh->detail != CS_OPT_ON)108return;109110if (status) {111#ifndef CAPSTONE_DIET112uint8_t access;113access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);114MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;115MI->ac_idx++;116#endif117MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_MEM;118MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base = ARM64_REG_INVALID;119MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index = ARM64_REG_INVALID;120MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = 0;121} else {122// done, create the next operand slot123MI->flat_insn->detail->arm64.op_count++;124}125}126127void AArch64_printInst(MCInst *MI, SStream *O, void *Info)128{129// Check for special encodings and print the canonical alias instead.130unsigned Opcode = MCInst_getOpcode(MI);131int LSB, Width;132char *mnem;133134// printf(">>> opcode = %u\n", MCInst_getOpcode(MI));135136if (Opcode == AArch64_SYSxt && printSysAlias(MI, O))137return;138139// SBFM/UBFM should print to a nicer aliased form if possible.140if (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri ||141Opcode == AArch64_UBFMXri || Opcode == AArch64_UBFMWri) {142bool IsSigned = (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri);143bool Is64Bit = (Opcode == AArch64_SBFMXri || Opcode == AArch64_UBFMXri);144145MCOperand *Op0 = MCInst_getOperand(MI, 0);146MCOperand *Op1 = MCInst_getOperand(MI, 1);147MCOperand *Op2 = MCInst_getOperand(MI, 2);148MCOperand *Op3 = MCInst_getOperand(MI, 3);149150if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) == 0 && MCOperand_isImm(Op3)) {151const char *AsmMnemonic = NULL;152153switch (MCOperand_getImm(Op3)) {154default:155break;156157case 7:158if (IsSigned)159AsmMnemonic = "sxtb";160else if (!Is64Bit)161AsmMnemonic = "uxtb";162break;163164case 15:165if (IsSigned)166AsmMnemonic = "sxth";167else if (!Is64Bit)168AsmMnemonic = "uxth";169break;170171case 31:172// *xtw is only valid for signed 64-bit operations.173if (Is64Bit && IsSigned)174AsmMnemonic = "sxtw";175break;176}177178if (AsmMnemonic) {179SStream_concat(O, "%s\t%s, %s", AsmMnemonic,180getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),181getRegisterName(getWRegFromXReg(MCOperand_getReg(Op1)), AArch64_NoRegAltName));182183if (MI->csh->detail) {184#ifndef CAPSTONE_DIET185uint8_t access;186access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);187MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;188MI->ac_idx++;189#endif190MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;191MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);192MI->flat_insn->detail->arm64.op_count++;193#ifndef CAPSTONE_DIET194access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);195MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;196MI->ac_idx++;197#endif198MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;199MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = getWRegFromXReg(MCOperand_getReg(Op1));200MI->flat_insn->detail->arm64.op_count++;201}202203MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic));204205return;206}207}208209// All immediate shifts are aliases, implemented using the Bitfield210// instruction. In all cases the immediate shift amount shift must be in211// the range 0 to (reg.size -1).212if (MCOperand_isImm(Op2) && MCOperand_isImm(Op3)) {213const char *AsmMnemonic = NULL;214int shift = 0;215int immr = (int)MCOperand_getImm(Op2);216int imms = (int)MCOperand_getImm(Op3);217218if (Opcode == AArch64_UBFMWri && imms != 0x1F && ((imms + 1) == immr)) {219AsmMnemonic = "lsl";220shift = 31 - imms;221} else if (Opcode == AArch64_UBFMXri && imms != 0x3f &&222((imms + 1 == immr))) {223AsmMnemonic = "lsl";224shift = 63 - imms;225} else if (Opcode == AArch64_UBFMWri && imms == 0x1f) {226AsmMnemonic = "lsr";227shift = immr;228} else if (Opcode == AArch64_UBFMXri && imms == 0x3f) {229AsmMnemonic = "lsr";230shift = immr;231} else if (Opcode == AArch64_SBFMWri && imms == 0x1f) {232AsmMnemonic = "asr";233shift = immr;234} else if (Opcode == AArch64_SBFMXri && imms == 0x3f) {235AsmMnemonic = "asr";236shift = immr;237}238239if (AsmMnemonic) {240SStream_concat(O, "%s\t%s, %s, ", AsmMnemonic,241getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),242getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));243244printInt32Bang(O, shift);245246MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic));247248if (MI->csh->detail) {249#ifndef CAPSTONE_DIET250uint8_t access;251access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);252MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;253MI->ac_idx++;254#endif255MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;256MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);257MI->flat_insn->detail->arm64.op_count++;258#ifndef CAPSTONE_DIET259access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);260MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;261MI->ac_idx++;262#endif263MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;264MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);265MI->flat_insn->detail->arm64.op_count++;266#ifndef CAPSTONE_DIET267access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);268MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;269MI->ac_idx++;270#endif271MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;272MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = shift;273MI->flat_insn->detail->arm64.op_count++;274}275276return;277}278}279280// SBFIZ/UBFIZ aliases281if (MCOperand_getImm(Op2) > MCOperand_getImm(Op3)) {282SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfiz" : "ubfiz"),283getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),284getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));285286printInt32Bang(O, (int)((Is64Bit ? 64 : 32) - MCOperand_getImm(Op2)));287288SStream_concat0(O, ", ");289290printInt32Bang(O, (int)MCOperand_getImm(Op3) + 1);291292MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfiz" : "ubfiz"));293294if (MI->csh->detail) {295#ifndef CAPSTONE_DIET296uint8_t access;297access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);298MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;299MI->ac_idx++;300#endif301MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;302MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);303MI->flat_insn->detail->arm64.op_count++;304#ifndef CAPSTONE_DIET305access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);306MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;307MI->ac_idx++;308#endif309MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;310MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);311MI->flat_insn->detail->arm64.op_count++;312#ifndef CAPSTONE_DIET313access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);314MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;315MI->ac_idx++;316#endif317MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;318MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (Is64Bit ? 64 : 32) - (int)MCOperand_getImm(Op2);319MI->flat_insn->detail->arm64.op_count++;320#ifndef CAPSTONE_DIET321access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);322MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;323MI->ac_idx++;324#endif325MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;326MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op3) + 1;327MI->flat_insn->detail->arm64.op_count++;328}329330return;331}332333// Otherwise SBFX/UBFX is the preferred form334SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfx" : "ubfx"),335getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),336getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));337338printInt32Bang(O, (int)MCOperand_getImm(Op2));339SStream_concat0(O, ", ");340printInt32Bang(O, (int)MCOperand_getImm(Op3) - (int)MCOperand_getImm(Op2) + 1);341342MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfx" : "ubfx"));343344if (MI->csh->detail) {345#ifndef CAPSTONE_DIET346uint8_t access;347access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);348MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;349MI->ac_idx++;350#endif351MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;352MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);353MI->flat_insn->detail->arm64.op_count++;354#ifndef CAPSTONE_DIET355access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);356MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;357MI->ac_idx++;358#endif359MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;360MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);361MI->flat_insn->detail->arm64.op_count++;362#ifndef CAPSTONE_DIET363access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);364MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;365MI->ac_idx++;366#endif367MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;368MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op2);369MI->flat_insn->detail->arm64.op_count++;370#ifndef CAPSTONE_DIET371access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);372MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;373MI->ac_idx++;374#endif375MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;376MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op3) - MCOperand_getImm(Op2) + 1;377MI->flat_insn->detail->arm64.op_count++;378}379380return;381}382383if (Opcode == AArch64_BFMXri || Opcode == AArch64_BFMWri) {384MCOperand *Op0 = MCInst_getOperand(MI, 0); // Op1 == Op0385MCOperand *Op2 = MCInst_getOperand(MI, 2);386int ImmR = (int)MCOperand_getImm(MCInst_getOperand(MI, 3));387int ImmS = (int)MCOperand_getImm(MCInst_getOperand(MI, 4));388389if ((MCOperand_getReg(Op2) == AArch64_WZR || MCOperand_getReg(Op2) == AArch64_XZR) &&390(ImmR == 0 || ImmS < ImmR)) {391// BFC takes precedence over its entire range, sligtly differently to BFI.392int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;393int LSB = (BitWidth - ImmR) % BitWidth;394int Width = ImmS + 1;395396SStream_concat(O, "bfc\t%s, ",397getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName));398399printInt32Bang(O, LSB);400SStream_concat0(O, ", ");401printInt32Bang(O, Width);402MCInst_setOpcodePub(MI, AArch64_map_insn("bfc"));403404if (MI->csh->detail) {405#ifndef CAPSTONE_DIET406uint8_t access;407access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);408MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;409MI->ac_idx++;410#endif411MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;412MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);413MI->flat_insn->detail->arm64.op_count++;414415#ifndef CAPSTONE_DIET416access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);417MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;418MI->ac_idx++;419#endif420MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;421MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;422MI->flat_insn->detail->arm64.op_count++;423#ifndef CAPSTONE_DIET424access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);425MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;426MI->ac_idx++;427#endif428MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;429MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;430MI->flat_insn->detail->arm64.op_count++;431}432433return;434} else if (ImmS < ImmR) {435// BFI alias436int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;437LSB = (BitWidth - ImmR) % BitWidth;438Width = ImmS + 1;439440SStream_concat(O, "bfi\t%s, %s, ",441getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),442getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName));443444printInt32Bang(O, LSB);445SStream_concat0(O, ", ");446printInt32Bang(O, Width);447448MCInst_setOpcodePub(MI, AArch64_map_insn("bfi"));449450if (MI->csh->detail) {451#ifndef CAPSTONE_DIET452uint8_t access;453access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);454MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;455MI->ac_idx++;456#endif457MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;458MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);459MI->flat_insn->detail->arm64.op_count++;460#ifndef CAPSTONE_DIET461access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);462MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;463MI->ac_idx++;464#endif465MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;466MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2);467MI->flat_insn->detail->arm64.op_count++;468#ifndef CAPSTONE_DIET469access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);470MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;471MI->ac_idx++;472#endif473MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;474MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;475MI->flat_insn->detail->arm64.op_count++;476#ifndef CAPSTONE_DIET477access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);478MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;479MI->ac_idx++;480#endif481MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;482MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;483MI->flat_insn->detail->arm64.op_count++;484}485486return;487}488489LSB = ImmR;490Width = ImmS - ImmR + 1;491// Otherwise BFXIL the preferred form492SStream_concat(O, "bfxil\t%s, %s, ",493getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),494getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName));495496printInt32Bang(O, LSB);497SStream_concat0(O, ", ");498printInt32Bang(O, Width);499500MCInst_setOpcodePub(MI, AArch64_map_insn("bfxil"));501502if (MI->csh->detail) {503#ifndef CAPSTONE_DIET504uint8_t access;505access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);506MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;507MI->ac_idx++;508#endif509MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;510MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);511MI->flat_insn->detail->arm64.op_count++;512#ifndef CAPSTONE_DIET513access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);514MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;515MI->ac_idx++;516#endif517MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;518MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2);519MI->flat_insn->detail->arm64.op_count++;520#ifndef CAPSTONE_DIET521access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);522MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;523MI->ac_idx++;524#endif525MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;526MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;527MI->flat_insn->detail->arm64.op_count++;528#ifndef CAPSTONE_DIET529access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);530MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;531MI->ac_idx++;532#endif533MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;534MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;535MI->flat_insn->detail->arm64.op_count++;536}537538return;539}540541// MOVZ, MOVN and "ORR wzr, #imm" instructions are aliases for MOV, but their542// domains overlap so they need to be prioritized. The chain is "MOVZ lsl #0 >543// MOVZ lsl #N > MOVN lsl #0 > MOVN lsl #N > ORR". The highest instruction544// that can represent the move is the MOV alias, and the rest get printed545// normally.546if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi) &&547MCOperand_isImm(MCInst_getOperand(MI, 1)) && MCOperand_isImm(MCInst_getOperand(MI, 2))) {548int RegWidth = Opcode == AArch64_MOVZXi ? 64 : 32;549int Shift = MCOperand_getImm(MCInst_getOperand(MI, 2));550uint64_t Value = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, 1)) << Shift;551552if (isMOVZMovAlias(Value, Shift,553Opcode == AArch64_MOVZXi ? 64 : 32)) {554SStream_concat(O, "mov\t%s, ", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, 0)), AArch64_NoRegAltName));555556printInt64Bang(O, SignExtend64(Value, RegWidth));557558if (MI->csh->detail) {559#ifndef CAPSTONE_DIET560uint8_t access;561access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);562MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;563MI->ac_idx++;564#endif565MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;566MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));567MI->flat_insn->detail->arm64.op_count++;568569MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;570MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = SignExtend64(Value, RegWidth);571MI->flat_insn->detail->arm64.op_count++;572}573574MCInst_setOpcodePub(MI, AArch64_map_insn("mov"));575576return;577}578}579580if ((Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&581MCOperand_isImm(MCInst_getOperand(MI, 1)) && MCOperand_isImm(MCInst_getOperand(MI, 2))) {582int RegWidth = Opcode == AArch64_MOVNXi ? 64 : 32;583int Shift = MCOperand_getImm(MCInst_getOperand(MI, 2));584uint64_t Value = ~((uint64_t)MCOperand_getImm(MCInst_getOperand(MI, 1)) << Shift);585586if (RegWidth == 32)587Value = Value & 0xffffffff;588589if (AArch64_AM_isMOVNMovAlias(Value, Shift, RegWidth)) {590SStream_concat(O, "mov\t%s, ", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, 0)), AArch64_NoRegAltName));591592printInt64Bang(O, SignExtend64(Value, RegWidth));593594if (MI->csh->detail) {595#ifndef CAPSTONE_DIET596uint8_t access;597access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);598MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;599MI->ac_idx++;600#endif601MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;602MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));603MI->flat_insn->detail->arm64.op_count++;604605MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;606MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = SignExtend64(Value, RegWidth);607MI->flat_insn->detail->arm64.op_count++;608}609610MCInst_setOpcodePub(MI, AArch64_map_insn("mov"));611612return;613}614}615616if ((Opcode == AArch64_ORRXri || Opcode == AArch64_ORRWri) &&617(MCOperand_getReg(MCInst_getOperand(MI, 1)) == AArch64_XZR ||618MCOperand_getReg(MCInst_getOperand(MI, 1)) == AArch64_WZR) &&619MCOperand_isImm(MCInst_getOperand(MI, 2))) {620int RegWidth = Opcode == AArch64_ORRXri ? 64 : 32;621uint64_t Value = AArch64_AM_decodeLogicalImmediate(622MCOperand_getImm(MCInst_getOperand(MI, 2)), RegWidth);623SStream_concat(O, "mov\t%s, ", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, 0)), AArch64_NoRegAltName));624625printInt64Bang(O, SignExtend64(Value, RegWidth));626627if (MI->csh->detail) {628#ifndef CAPSTONE_DIET629uint8_t access;630access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);631MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;632MI->ac_idx++;633#endif634MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;635MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));636MI->flat_insn->detail->arm64.op_count++;637638MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;639MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = SignExtend64(Value, RegWidth);640MI->flat_insn->detail->arm64.op_count++;641}642643MCInst_setOpcodePub(MI, AArch64_map_insn("mov"));644645return;646}647648// Instruction TSB is specified as a one operand instruction, but 'csync' is649// not encoded, so for printing it is treated as a special case here:650if (Opcode == AArch64_TSB) {651SStream_concat0(O, "tsb\tcsync");652MCInst_setOpcodePub(MI, AArch64_map_insn("tsb"));653return;654}655656MI->MRI = Info;657658mnem = printAliasInstr(MI, O, (MCRegisterInfo *)Info);659if (mnem) {660MCInst_setOpcodePub(MI, AArch64_map_insn(mnem));661cs_mem_free(mnem);662663switch(MCInst_getOpcode(MI)) {664default: break;665case AArch64_LD1i8_POST:666arm64_op_addImm(MI, 1);667break;668case AArch64_LD1i16_POST:669arm64_op_addImm(MI, 2);670break;671case AArch64_LD1i32_POST:672arm64_op_addImm(MI, 4);673break;674case AArch64_LD1Onev1d_POST:675case AArch64_LD1Onev2s_POST:676case AArch64_LD1Onev4h_POST:677case AArch64_LD1Onev8b_POST:678case AArch64_LD1i64_POST:679arm64_op_addImm(MI, 8);680break;681case AArch64_LD1Onev16b_POST:682case AArch64_LD1Onev2d_POST:683case AArch64_LD1Onev4s_POST:684case AArch64_LD1Onev8h_POST:685case AArch64_LD1Twov1d_POST:686case AArch64_LD1Twov2s_POST:687case AArch64_LD1Twov4h_POST:688case AArch64_LD1Twov8b_POST:689arm64_op_addImm(MI, 16);690break;691case AArch64_LD1Threev1d_POST:692case AArch64_LD1Threev2s_POST:693case AArch64_LD1Threev4h_POST:694case AArch64_LD1Threev8b_POST:695arm64_op_addImm(MI, 24);696break;697case AArch64_LD1Fourv1d_POST:698case AArch64_LD1Fourv2s_POST:699case AArch64_LD1Fourv4h_POST:700case AArch64_LD1Fourv8b_POST:701case AArch64_LD1Twov16b_POST:702case AArch64_LD1Twov2d_POST:703case AArch64_LD1Twov4s_POST:704case AArch64_LD1Twov8h_POST:705arm64_op_addImm(MI, 32);706break;707case AArch64_LD1Threev16b_POST:708case AArch64_LD1Threev2d_POST:709case AArch64_LD1Threev4s_POST:710case AArch64_LD1Threev8h_POST:711arm64_op_addImm(MI, 48);712break;713case AArch64_LD1Fourv16b_POST:714case AArch64_LD1Fourv2d_POST:715case AArch64_LD1Fourv4s_POST:716case AArch64_LD1Fourv8h_POST:717arm64_op_addImm(MI, 64);718break;719case AArch64_UMOVvi64:720arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1D);721break;722case AArch64_UMOVvi32:723arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1S);724break;725case AArch64_INSvi8gpr:726case AArch64_DUP_ZI_B:727case AArch64_CPY_ZPmI_B:728case AArch64_CPY_ZPzI_B:729case AArch64_CPY_ZPmV_B:730case AArch64_CPY_ZPmR_B:731case AArch64_DUP_ZR_B:732if (MI->csh->detail) {733MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1B;734}735break;736case AArch64_INSvi16gpr:737case AArch64_DUP_ZI_H:738case AArch64_CPY_ZPmI_H:739case AArch64_CPY_ZPzI_H:740case AArch64_CPY_ZPmV_H:741case AArch64_CPY_ZPmR_H:742case AArch64_DUP_ZR_H:743case AArch64_FCPY_ZPmI_H:744case AArch64_FDUP_ZI_H:745if (MI->csh->detail) {746MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1H;747}748break;749case AArch64_INSvi32gpr:750case AArch64_DUP_ZI_S:751case AArch64_CPY_ZPmI_S:752case AArch64_CPY_ZPzI_S:753case AArch64_CPY_ZPmV_S:754case AArch64_CPY_ZPmR_S:755case AArch64_DUP_ZR_S:756case AArch64_FCPY_ZPmI_S:757case AArch64_FDUP_ZI_S:758if (MI->csh->detail) {759MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1S;760}761break;762case AArch64_INSvi64gpr:763case AArch64_DUP_ZI_D:764case AArch64_CPY_ZPmI_D:765case AArch64_CPY_ZPzI_D:766case AArch64_CPY_ZPmV_D:767case AArch64_CPY_ZPmR_D:768case AArch64_DUP_ZR_D:769case AArch64_FCPY_ZPmI_D:770case AArch64_FDUP_ZI_D:771if (MI->csh->detail) {772MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1D;773}774break;775case AArch64_INSvi8lane:776case AArch64_ORR_PPzPP:777case AArch64_ORRS_PPzPP:778if (MI->csh->detail) {779MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1B;780MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1B;781}782break;783case AArch64_INSvi16lane:784if (MI->csh->detail) {785MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1H;786MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1H;787}788break;789case AArch64_INSvi32lane:790if (MI->csh->detail) {791MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1S;792MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1S;793}794break;795case AArch64_INSvi64lane:796case AArch64_ORR_ZZZ:797if (MI->csh->detail) {798MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1D;799MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1D;800}801break;802case AArch64_ORRv16i8:803case AArch64_NOTv16i8:804if (MI->csh->detail) {805MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_16B;806MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_16B;807}808break;809case AArch64_ORRv8i8:810case AArch64_NOTv8i8:811if (MI->csh->detail) {812MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_8B;813MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_8B;814}815break;816case AArch64_AND_PPzPP:817case AArch64_ANDS_PPzPP:818case AArch64_EOR_PPzPP:819case AArch64_EORS_PPzPP:820case AArch64_SEL_PPPP:821case AArch64_SEL_ZPZZ_B:822if (MI->csh->detail) {823MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1B;824MI->flat_insn->detail->arm64.operands[2].vas = ARM64_VAS_1B;825}826break;827case AArch64_SEL_ZPZZ_D:828if (MI->csh->detail) {829MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1D;830MI->flat_insn->detail->arm64.operands[2].vas = ARM64_VAS_1D;831}832break;833case AArch64_SEL_ZPZZ_H:834if (MI->csh->detail) {835MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1H;836MI->flat_insn->detail->arm64.operands[2].vas = ARM64_VAS_1H;837}838break;839case AArch64_SEL_ZPZZ_S:840if (MI->csh->detail) {841MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1S;842MI->flat_insn->detail->arm64.operands[2].vas = ARM64_VAS_1S;843}844break;845case AArch64_DUP_ZZI_B:846if (MI->csh->detail) {847MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1B;848if (MI->flat_insn->detail->arm64.op_count == 1) {849arm64_op_addReg(MI, ARM64_REG_B0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);850} else {851MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1B;852}853}854break;855case AArch64_DUP_ZZI_D:856if (MI->csh->detail) {857MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1D;858if (MI->flat_insn->detail->arm64.op_count == 1) {859arm64_op_addReg(MI, ARM64_REG_D0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);860} else {861MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1D;862}863}864break;865case AArch64_DUP_ZZI_H:866if (MI->csh->detail) {867MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1H;868if (MI->flat_insn->detail->arm64.op_count == 1) {869arm64_op_addReg(MI, ARM64_REG_H0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);870} else {871MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1H;872}873}874break;875case AArch64_DUP_ZZI_Q:876if (MI->csh->detail) {877MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1Q;878if (MI->flat_insn->detail->arm64.op_count == 1) {879arm64_op_addReg(MI, ARM64_REG_Q0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);880} else {881MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1Q;882}883}884break;885case AArch64_DUP_ZZI_S:886if (MI->csh->detail) {887MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1S;888if (MI->flat_insn->detail->arm64.op_count == 1) {889arm64_op_addReg(MI, ARM64_REG_S0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);890} else {891MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1S;892}893}894break;895// Hacky detail filling of SMSTART and SMSTOP alias'896case AArch64_MSRpstatesvcrImm1:{897if(MI->csh->detail){898MI->flat_insn->detail->arm64.op_count = 2;899#ifndef CAPSTONE_DIET900MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);901MI->ac_idx++;902MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);903MI->ac_idx++;904#endif905MI->flat_insn->detail->arm64.operands[0].type = ARM64_OP_SVCR;906MI->flat_insn->detail->arm64.operands[0].sys = (unsigned)ARM64_SYSREG_SVCR;907MI->flat_insn->detail->arm64.operands[0].svcr = lookupSVCRByEncoding(MCOperand_getImm(MCInst_getOperand(MI, 0)))->Encoding;908MI->flat_insn->detail->arm64.operands[1].type = ARM64_OP_IMM;909MI->flat_insn->detail->arm64.operands[1].imm = MCOperand_getImm(MCInst_getOperand(MI, 1));910}911break;912}913}914} else {915printInstruction(MI, O);916}917}918919static bool printSysAlias(MCInst *MI, SStream *O)920{921// unsigned Opcode = MCInst_getOpcode(MI);922//assert(Opcode == AArch64_SYSxt && "Invalid opcode for SYS alias!");923924const char *Ins;925uint16_t Encoding;926bool NeedsReg;927char Name[64];928MCOperand *Op1 = MCInst_getOperand(MI, 0);929MCOperand *Cn = MCInst_getOperand(MI, 1);930MCOperand *Cm = MCInst_getOperand(MI, 2);931MCOperand *Op2 = MCInst_getOperand(MI, 3);932933unsigned Op1Val = (unsigned)MCOperand_getImm(Op1);934unsigned CnVal = (unsigned)MCOperand_getImm(Cn);935unsigned CmVal = (unsigned)MCOperand_getImm(Cm);936unsigned Op2Val = (unsigned)MCOperand_getImm(Op2);937938Encoding = Op2Val;939Encoding |= CmVal << 3;940Encoding |= CnVal << 7;941Encoding |= Op1Val << 11;942943if (CnVal == 7) {944switch (CmVal) {945default:946return false;947948// IC aliases949case 1: case 5: {950const IC *IC = lookupICByEncoding(Encoding);951// if (!IC || !IC->haveFeatures(STI.getFeatureBits()))952if (!IC)953return false;954955NeedsReg = IC->NeedsReg;956Ins = "ic";957strncpy(Name, IC->Name, sizeof(Name) - 1);958}959break;960961// DC aliases962case 4: case 6: case 10: case 11: case 12: case 14: {963const DC *DC = lookupDCByEncoding(Encoding);964// if (!DC || !DC->haveFeatures(STI.getFeatureBits()))965if (!DC)966return false;967968NeedsReg = true;969Ins = "dc";970strncpy(Name, DC->Name, sizeof(Name) - 1);971}972break;973974// AT aliases975case 8: case 9: {976const AT *AT = lookupATByEncoding(Encoding);977// if (!AT || !AT->haveFeatures(STI.getFeatureBits()))978if (!AT)979return false;980981NeedsReg = true;982Ins = "at";983strncpy(Name, AT->Name, sizeof(Name) - 1);984}985break;986}987} else if (CnVal == 8) {988// TLBI aliases989const TLBI *TLBI = lookupTLBIByEncoding(Encoding);990// if (!TLBI || !TLBI->haveFeatures(STI.getFeatureBits()))991if (!TLBI)992return false;993994NeedsReg = TLBI->NeedsReg;995Ins = "tlbi";996strncpy(Name, TLBI->Name, sizeof(Name) - 1);997} else998return false;9991000SStream_concat(O, "%s\t%s", Ins, Name);10011002if (NeedsReg) {1003SStream_concat(O, ", %s", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, 4)), AArch64_NoRegAltName));1004}10051006MCInst_setOpcodePub(MI, AArch64_map_insn(Ins));10071008if (MI->csh->detail) {1009#if 01010#ifndef CAPSTONE_DIET1011uint8_t access;1012access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1013MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1014MI->ac_idx++;1015#endif1016#endif1017MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;1018MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = AArch64_map_sys_op(Name);1019MI->flat_insn->detail->arm64.op_count++;10201021if (NeedsReg) {1022MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1023MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 4));1024MI->flat_insn->detail->arm64.op_count++;1025}1026}10271028return true;1029}10301031static void printOperand(MCInst *MI, unsigned OpNum, SStream *O)1032{1033MCOperand *Op = MCInst_getOperand(MI, OpNum);10341035if (MCOperand_isReg(Op)) {1036unsigned Reg = MCOperand_getReg(Op);10371038SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));10391040if (MI->csh->detail) {1041if (MI->csh->doing_mem) {1042if (MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base == ARM64_REG_INVALID) {1043MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base = Reg;1044}1045else if (MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index == ARM64_REG_INVALID) {1046MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index = Reg;1047}1048} else if (MI->csh->doing_SME_Index) {1049// Access op_count-1 as We want to add info to previous operand, not create a new one1050MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count-1].sme_index.base = Reg;1051} else {1052#ifndef CAPSTONE_DIET1053uint8_t access;10541055access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1056MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1057MI->ac_idx++;1058#endif1059MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1060MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;1061MI->flat_insn->detail->arm64.op_count++;1062}1063}1064} else if (MCOperand_isImm(Op)) {1065int64_t imm = MCOperand_getImm(Op);10661067if (MI->Opcode == AArch64_ADR) {1068imm += MI->address;1069printUInt64Bang(O, imm);1070} else {1071if (MI->csh->doing_mem) {1072if (MI->csh->imm_unsigned) {1073printUInt64Bang(O, imm);1074} else {1075printInt64Bang(O, imm);1076}1077} else1078printUInt64Bang(O, imm);1079}10801081if (MI->csh->detail) {1082if (MI->csh->doing_mem) {1083MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)imm;1084} else if (MI->csh->doing_SME_Index) {1085// Access op_count-1 as We want to add info to previous operand, not create a new one1086MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count-1].sme_index.disp = (int32_t)imm;1087} else {1088#ifndef CAPSTONE_DIET1089uint8_t access;10901091access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1092MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1093#endif1094MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1095MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;1096MI->flat_insn->detail->arm64.op_count++;1097}1098}1099}1100}11011102static void printImm(MCInst *MI, unsigned OpNum, SStream *O)1103{1104MCOperand *Op = MCInst_getOperand(MI, OpNum);1105printUInt64Bang(O, MCOperand_getImm(Op));11061107if (MI->csh->detail) {1108#ifndef CAPSTONE_DIET1109uint8_t access;1110access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1111MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1112MI->ac_idx++;1113#endif1114MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1115MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);1116MI->flat_insn->detail->arm64.op_count++;1117}1118}11191120static void printImmHex(MCInst *MI, unsigned OpNum, SStream *O)1121{1122MCOperand *Op = MCInst_getOperand(MI, OpNum);1123printUInt64Bang(O, MCOperand_getImm(Op));11241125if (MI->csh->detail) {1126#ifndef CAPSTONE_DIET1127uint8_t access;1128access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1129MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1130MI->ac_idx++;1131#endif1132MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1133MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);1134MI->flat_insn->detail->arm64.op_count++;1135}1136}11371138static void printSImm(MCInst *MI, unsigned OpNo, SStream *O, int Size) {1139MCOperand *Op = MCInst_getOperand(MI, OpNo);1140if (Size == 8)1141printInt64Bang(O, (signed char) MCOperand_getImm(Op));1142else if (Size == 16)1143printInt64Bang(O, (signed short) MCOperand_getImm(Op));1144else1145printInt64Bang(O, MCOperand_getImm(Op));11461147if (MI->csh->detail) {1148#ifndef CAPSTONE_DIET1149uint8_t access;1150access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1151MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1152MI->ac_idx++;1153#endif1154MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1155MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);1156MI->flat_insn->detail->arm64.op_count++;1157}1158}11591160static void printPostIncOperand(MCInst *MI, unsigned OpNum, SStream *O,1161unsigned Imm)1162{1163MCOperand *Op = MCInst_getOperand(MI, OpNum);11641165if (MCOperand_isReg(Op)) {1166unsigned Reg = MCOperand_getReg(Op);1167if (Reg == AArch64_XZR) {1168printInt32Bang(O, Imm);11691170if (MI->csh->detail) {1171#ifndef CAPSTONE_DIET1172uint8_t access;11731174access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1175MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1176MI->ac_idx++;1177#endif1178MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1179MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Imm;1180MI->flat_insn->detail->arm64.op_count++;1181}1182} else {1183SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));11841185if (MI->csh->detail) {1186#ifndef CAPSTONE_DIET1187uint8_t access;11881189access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1190MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1191MI->ac_idx++;1192#endif1193MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1194MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;1195MI->flat_insn->detail->arm64.op_count++;1196}1197}1198}1199//llvm_unreachable("unknown operand kind in printPostIncOperand64");1200}12011202static void printVRegOperand(MCInst *MI, unsigned OpNum, SStream *O)1203{1204MCOperand *Op = MCInst_getOperand(MI, OpNum);1205//assert(Op.isReg() && "Non-register vreg operand!");1206unsigned Reg = MCOperand_getReg(Op);12071208SStream_concat0(O, getRegisterName(Reg, AArch64_vreg));12091210if (MI->csh->detail) {1211#ifndef CAPSTONE_DIET1212uint8_t access;1213access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1214MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1215MI->ac_idx++;1216#endif1217MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1218MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = AArch64_map_vregister(Reg);1219MI->flat_insn->detail->arm64.op_count++;1220}1221}12221223static void printSysCROperand(MCInst *MI, unsigned OpNum, SStream *O)1224{1225MCOperand *Op = MCInst_getOperand(MI, OpNum);1226//assert(Op.isImm() && "System instruction C[nm] operands must be immediates!");1227SStream_concat(O, "c%u", MCOperand_getImm(Op));12281229if (MI->csh->detail) {1230#ifndef CAPSTONE_DIET1231uint8_t access;12321233access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1234MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1235MI->ac_idx++;1236#endif1237MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_CIMM;1238MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);1239MI->flat_insn->detail->arm64.op_count++;1240}1241}12421243static void printAddSubImm(MCInst *MI, unsigned OpNum, SStream *O)1244{1245MCOperand *MO = MCInst_getOperand(MI, OpNum);1246if (MCOperand_isImm(MO)) {1247unsigned Val = (MCOperand_getImm(MO) & 0xfff);1248//assert(Val == MO.getImm() && "Add/sub immediate out of range!");1249unsigned Shift = AArch64_AM_getShiftValue((int)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)));12501251printInt32Bang(O, Val);12521253if (MI->csh->detail) {1254#ifndef CAPSTONE_DIET1255uint8_t access;12561257access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1258MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1259MI->ac_idx++;1260#endif1261MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1262MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;1263MI->flat_insn->detail->arm64.op_count++;1264}12651266if (Shift != 0)1267printShifter(MI, OpNum + 1, O);1268}1269}12701271static void printLogicalImm32(MCInst *MI, unsigned OpNum, SStream *O)1272{1273int64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));12741275Val = AArch64_AM_decodeLogicalImmediate(Val, 32);1276printUInt32Bang(O, (int)Val);12771278if (MI->csh->detail) {1279#ifndef CAPSTONE_DIET1280uint8_t access;12811282access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1283MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1284MI->ac_idx++;1285#endif1286MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1287MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;1288MI->flat_insn->detail->arm64.op_count++;1289}1290}12911292static void printLogicalImm64(MCInst *MI, unsigned OpNum, SStream *O)1293{1294int64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));1295Val = AArch64_AM_decodeLogicalImmediate(Val, 64);12961297switch(MI->flat_insn->id) {1298default:1299printInt64Bang(O, Val);1300break;13011302case ARM64_INS_ORR:1303case ARM64_INS_AND:1304case ARM64_INS_EOR:1305case ARM64_INS_TST:1306// do not print number in negative form1307if (Val >= 0 && Val <= HEX_THRESHOLD)1308SStream_concat(O, "#%u", (int)Val);1309else1310SStream_concat(O, "#0x%"PRIx64, Val);1311break;1312}13131314if (MI->csh->detail) {1315#ifndef CAPSTONE_DIET1316uint8_t access;13171318access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1319MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1320MI->ac_idx++;1321#endif1322MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1323MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int64_t)Val;1324MI->flat_insn->detail->arm64.op_count++;1325}1326}13271328static void printShifter(MCInst *MI, unsigned OpNum, SStream *O)1329{1330unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));13311332// LSL #0 should not be printed.1333if (AArch64_AM_getShiftType(Val) == AArch64_AM_LSL &&1334AArch64_AM_getShiftValue(Val) == 0)1335return;13361337SStream_concat(O, ", %s ", AArch64_AM_getShiftExtendName(AArch64_AM_getShiftType(Val)));1338printInt32BangDec(O, AArch64_AM_getShiftValue(Val));13391340if (MI->csh->detail) {1341arm64_shifter shifter = ARM64_SFT_INVALID;13421343switch(AArch64_AM_getShiftType(Val)) {1344default: // never reach1345case AArch64_AM_LSL:1346shifter = ARM64_SFT_LSL;1347break;13481349case AArch64_AM_LSR:1350shifter = ARM64_SFT_LSR;1351break;13521353case AArch64_AM_ASR:1354shifter = ARM64_SFT_ASR;1355break;13561357case AArch64_AM_ROR:1358shifter = ARM64_SFT_ROR;1359break;13601361case AArch64_AM_MSL:1362shifter = ARM64_SFT_MSL;1363break;1364}13651366MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = shifter;1367MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = AArch64_AM_getShiftValue(Val);1368}1369}13701371static void printShiftedRegister(MCInst *MI, unsigned OpNum, SStream *O)1372{1373SStream_concat0(O, getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, OpNum)), AArch64_NoRegAltName));13741375if (MI->csh->detail) {1376#ifndef CAPSTONE_DIET1377uint8_t access;1378access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1379MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1380MI->ac_idx++;1381#endif1382MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1383MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));1384MI->flat_insn->detail->arm64.op_count++;1385}13861387printShifter(MI, OpNum + 1, O);1388}13891390static void printArithExtend(MCInst *MI, unsigned OpNum, SStream *O)1391{1392unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));1393AArch64_AM_ShiftExtendType ExtType = AArch64_AM_getArithExtendType(Val);1394unsigned ShiftVal = AArch64_AM_getArithShiftValue(Val);13951396// If the destination or first source register operand is [W]SP, print1397// UXTW/UXTX as LSL, and if the shift amount is also zero, print nothing at1398// all.1399if (ExtType == AArch64_AM_UXTW || ExtType == AArch64_AM_UXTX) {1400unsigned Dest = MCOperand_getReg(MCInst_getOperand(MI, 0));1401unsigned Src1 = MCOperand_getReg(MCInst_getOperand(MI, 1));14021403if (((Dest == AArch64_SP || Src1 == AArch64_SP) &&1404ExtType == AArch64_AM_UXTX) ||1405((Dest == AArch64_WSP || Src1 == AArch64_WSP) &&1406ExtType == AArch64_AM_UXTW)) {1407if (ShiftVal != 0) {1408SStream_concat0(O, ", lsl ");1409printInt32Bang(O, ShiftVal);14101411if (MI->csh->detail) {1412MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = ARM64_SFT_LSL;1413MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = ShiftVal;1414}1415}14161417return;1418}1419}14201421SStream_concat(O, ", %s", AArch64_AM_getShiftExtendName(ExtType));14221423if (MI->csh->detail) {1424arm64_extender ext = ARM64_EXT_INVALID;1425switch(ExtType) {1426default: // never reach14271428case AArch64_AM_UXTB:1429ext = ARM64_EXT_UXTB;1430break;14311432case AArch64_AM_UXTH:1433ext = ARM64_EXT_UXTH;1434break;14351436case AArch64_AM_UXTW:1437ext = ARM64_EXT_UXTW;1438break;14391440case AArch64_AM_UXTX:1441ext = ARM64_EXT_UXTX;1442break;14431444case AArch64_AM_SXTB:1445ext = ARM64_EXT_SXTB;1446break;14471448case AArch64_AM_SXTH:1449ext = ARM64_EXT_SXTH;1450break;14511452case AArch64_AM_SXTW:1453ext = ARM64_EXT_SXTW;1454break;14551456case AArch64_AM_SXTX:1457ext = ARM64_EXT_SXTX;1458break;1459}14601461MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].ext = ext;1462}14631464if (ShiftVal != 0) {1465SStream_concat0(O, " ");1466printInt32Bang(O, ShiftVal);14671468if (MI->csh->detail) {1469MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = ARM64_SFT_LSL;1470MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = ShiftVal;1471}1472}1473}14741475static void printExtendedRegister(MCInst *MI, unsigned OpNum, SStream *O)1476{1477unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));14781479SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));14801481if (MI->csh->detail) {1482#ifndef CAPSTONE_DIET1483uint8_t access;1484access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1485MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1486MI->ac_idx++;1487#endif1488MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1489MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;1490MI->flat_insn->detail->arm64.op_count++;1491}14921493printArithExtend(MI, OpNum + 1, O);1494}14951496static void printMemExtendImpl(MCInst *MI, bool SignExtend, bool DoShift, unsigned Width,1497char SrcRegKind, SStream *O)1498{1499// sxtw, sxtx, uxtw or lsl (== uxtx)1500bool IsLSL = !SignExtend && SrcRegKind == 'x';1501if (IsLSL) {1502SStream_concat0(O, "lsl");15031504if (MI->csh->detail) {1505MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.type = ARM64_SFT_LSL;1506}1507} else {1508SStream_concat(O, "%cxt%c", (SignExtend ? 's' : 'u'), SrcRegKind);15091510if (MI->csh->detail) {1511if (!SignExtend) {1512switch(SrcRegKind) {1513default: break;1514case 'b':1515MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTB;1516break;1517case 'h':1518MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTH;1519break;1520case 'w':1521MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTW;1522break;1523}1524} else {1525switch(SrcRegKind) {1526default: break;1527case 'b':1528MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTB;1529break;1530case 'h':1531MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTH;1532break;1533case 'w':1534MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTW;1535break;1536case 'x':1537MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTX;1538break;1539}1540}1541}1542}15431544if (DoShift || IsLSL) {1545SStream_concat(O, " #%u", Log2_32(Width / 8));15461547if (MI->csh->detail) {1548MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.type = ARM64_SFT_LSL;1549MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.value = Log2_32(Width / 8);1550}1551}1552}15531554static void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKind, unsigned Width)1555{1556unsigned SignExtend = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));1557unsigned DoShift = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));15581559printMemExtendImpl(MI, SignExtend, DoShift, Width, SrcRegKind, O);1560}15611562static void printRegWithShiftExtend(MCInst *MI, unsigned OpNum, SStream *O,1563bool SignExtend, int ExtWidth,1564char SrcRegKind, char Suffix)1565{1566bool DoShift;15671568printOperand(MI, OpNum, O);15691570if (Suffix == 's' || Suffix == 'd')1571SStream_concat(O, ".%c", Suffix);15721573DoShift = ExtWidth != 8;1574if (SignExtend || DoShift || SrcRegKind == 'w') {1575SStream_concat0(O, ", ");1576printMemExtendImpl(MI, SignExtend, DoShift, ExtWidth, SrcRegKind, O);1577}1578}15791580static void printCondCode(MCInst *MI, unsigned OpNum, SStream *O)1581{1582AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, OpNum));1583SStream_concat0(O, getCondCodeName(CC));15841585if (MI->csh->detail)1586MI->flat_insn->detail->arm64.cc = (arm64_cc)(CC + 1);1587}15881589static void printInverseCondCode(MCInst *MI, unsigned OpNum, SStream *O)1590{1591AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, OpNum));1592SStream_concat0(O, getCondCodeName(getInvertedCondCode(CC)));15931594if (MI->csh->detail) {1595MI->flat_insn->detail->arm64.cc = (arm64_cc)(getInvertedCondCode(CC) + 1);1596}1597}15981599static void printImmScale(MCInst *MI, unsigned OpNum, SStream *O, int Scale)1600{1601int64_t val = Scale * MCOperand_getImm(MCInst_getOperand(MI, OpNum));16021603printInt64Bang(O, val);16041605if (MI->csh->detail) {1606if (MI->csh->doing_mem) {1607MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)val;1608} else {1609#ifndef CAPSTONE_DIET1610uint8_t access;16111612access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1613MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1614MI->ac_idx++;1615#endif1616MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1617MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = val;1618MI->flat_insn->detail->arm64.op_count++;1619}1620}1621}16221623static void printUImm12Offset(MCInst *MI, unsigned OpNum, SStream *O, unsigned Scale)1624{1625MCOperand *MO = MCInst_getOperand(MI, OpNum);16261627if (MCOperand_isImm(MO)) {1628int64_t val = Scale * MCOperand_getImm(MO);1629printInt64Bang(O, val);16301631if (MI->csh->detail) {1632if (MI->csh->doing_mem) {1633MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)val;1634} else {1635#ifndef CAPSTONE_DIET1636uint8_t access;16371638access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1639MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1640MI->ac_idx++;1641#endif1642MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1643MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)val;1644MI->flat_insn->detail->arm64.op_count++;1645}1646}1647}1648}16491650#if 01651static void printAMIndexedWB(MCInst *MI, unsigned OpNum, SStream *O, unsigned int Scale)1652{1653MCOperand *MO = MCInst_getOperand(MI, OpNum + 1);16541655SStream_concat(O, "[%s", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, OpNum)), AArch64_NoRegAltName));16561657if (MCOperand_isImm(MO)) {1658int64_t val = Scale * MCOperand_getImm(MCInst_getOperand(MI, OpNum));1659printInt64Bang(O, val);1660// } else {1661// // assert(MO1.isExpr() && "Unexpected operand type!");1662// SStream_concat0(O, ", ");1663// MO1.getExpr()->print(O, &MAI);1664}16651666SStream_concat0(O, "]");1667}1668#endif16691670// IsSVEPrefetch = false1671static void printPrefetchOp(MCInst *MI, unsigned OpNum, SStream *O, bool IsSVEPrefetch)1672{1673unsigned prfop = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));16741675if (IsSVEPrefetch) {1676const SVEPRFM *PRFM = lookupSVEPRFMByEncoding(prfop);1677if (PRFM)1678SStream_concat0(O, PRFM->Name);16791680return;1681} else {1682const PRFM *PRFM = lookupPRFMByEncoding(prfop);1683if (PRFM)1684SStream_concat0(O, PRFM->Name);16851686return;1687}16881689// FIXME: set OpcodePub?16901691printInt32Bang(O, prfop);16921693if (MI->csh->detail) {1694#ifndef CAPSTONE_DIET1695uint8_t access;1696access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1697MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1698MI->ac_idx++;1699#endif1700MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;1701MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = prfop;1702MI->flat_insn->detail->arm64.op_count++;1703}1704}17051706static void printPSBHintOp(MCInst *MI, unsigned OpNum, SStream *O)1707{1708MCOperand *Op = MCInst_getOperand(MI, OpNum);1709unsigned int psbhintop = MCOperand_getImm(Op);17101711const PSB *PSB = lookupPSBByEncoding(psbhintop);1712if (PSB)1713SStream_concat0(O, PSB->Name);1714else1715printUInt32Bang(O, psbhintop);1716}17171718static void printBTIHintOp(MCInst *MI, unsigned OpNum, SStream *O) {1719unsigned btihintop = MCOperand_getImm(MCInst_getOperand(MI, OpNum)) ^ 32;17201721const BTI *BTI = lookupBTIByEncoding(btihintop);1722if (BTI)1723SStream_concat0(O, BTI->Name);1724else1725printUInt32Bang(O, btihintop);1726}17271728static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)1729{1730MCOperand *MO = MCInst_getOperand(MI, OpNum);1731float FPImm = MCOperand_isFPImm(MO) ? MCOperand_getFPImm(MO) : AArch64_AM_getFPImmFloat((int)MCOperand_getImm(MO));17321733// 8 decimal places are enough to perfectly represent permitted floats.1734#if defined(_KERNEL_MODE)1735// Issue #681: Windows kernel does not support formatting float point1736SStream_concat0(O, "#<float_point_unsupported>");1737#else1738SStream_concat(O, "#%.8f", FPImm);1739#endif17401741if (MI->csh->detail) {1742#ifndef CAPSTONE_DIET1743uint8_t access;17441745access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1746MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1747MI->ac_idx++;1748#endif1749MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_FP;1750MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].fp = FPImm;1751MI->flat_insn->detail->arm64.op_count++;1752}1753}17541755//static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1)1756static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride)1757{1758while (Stride--) {1759if (Reg >= AArch64_Q0 && Reg <= AArch64_Q30) // AArch64_Q0 .. AArch64_Q301760Reg += 1;1761else if (Reg == AArch64_Q31) // Vector lists can wrap around.1762Reg = AArch64_Q0;1763else if (Reg >= AArch64_Z0 && Reg <= AArch64_Z30) // AArch64_Z0 .. AArch64_Z301764Reg += 1;1765else if (Reg == AArch64_Z31) // Vector lists can wrap around.1766Reg = AArch64_Z0;1767}17681769return Reg;1770}17711772static void printGPRSeqPairsClassOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned int size)1773{1774// static_assert(size == 64 || size == 32,1775// "Template parameter must be either 32 or 64");1776unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));1777unsigned Sube = (size == 32) ? AArch64_sube32 : AArch64_sube64;1778unsigned Subo = (size == 32) ? AArch64_subo32 : AArch64_subo64;1779unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube);1780unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo);17811782SStream_concat(O, "%s, %s", getRegisterName(Even, AArch64_NoRegAltName),1783getRegisterName(Odd, AArch64_NoRegAltName));17841785if (MI->csh->detail) {1786#ifndef CAPSTONE_DIET1787uint8_t access;17881789access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1790MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1791MI->ac_idx++;1792#endif17931794MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1795MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Even;1796MI->flat_insn->detail->arm64.op_count++;17971798MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1799MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Odd;1800MI->flat_insn->detail->arm64.op_count++;1801}1802}18031804static void printVectorList(MCInst *MI, unsigned OpNum, SStream *O,1805char *LayoutSuffix, MCRegisterInfo *MRI, arm64_vas vas)1806{1807#define GETREGCLASS_CONTAIN0(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), _reg)1808unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));1809unsigned NumRegs = 1, FirstReg, i;18101811SStream_concat0(O, "{");18121813// Work out how many registers there are in the list (if there is an actual1814// list).1815if (GETREGCLASS_CONTAIN0(AArch64_DDRegClassID , Reg) ||1816GETREGCLASS_CONTAIN0(AArch64_ZPR2RegClassID, Reg) ||1817GETREGCLASS_CONTAIN0(AArch64_QQRegClassID, Reg))1818NumRegs = 2;1819else if (GETREGCLASS_CONTAIN0(AArch64_DDDRegClassID, Reg) ||1820GETREGCLASS_CONTAIN0(AArch64_ZPR3RegClassID, Reg) ||1821GETREGCLASS_CONTAIN0(AArch64_QQQRegClassID, Reg))1822NumRegs = 3;1823else if (GETREGCLASS_CONTAIN0(AArch64_DDDDRegClassID, Reg) ||1824GETREGCLASS_CONTAIN0(AArch64_ZPR4RegClassID, Reg) ||1825GETREGCLASS_CONTAIN0(AArch64_QQQQRegClassID, Reg))1826NumRegs = 4;18271828// Now forget about the list and find out what the first register is.1829if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_dsub0)))1830Reg = FirstReg;1831else if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_qsub0)))1832Reg = FirstReg;1833else if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_zsub0)))1834Reg = FirstReg;18351836// If it's a D-reg, we need to promote it to the equivalent Q-reg before1837// printing (otherwise getRegisterName fails).1838if (GETREGCLASS_CONTAIN0(AArch64_FPR64RegClassID, Reg)) {1839const MCRegisterClass *FPR128RC = MCRegisterInfo_getRegClass(MRI, AArch64_FPR128RegClassID);1840Reg = MCRegisterInfo_getMatchingSuperReg(MRI, Reg, AArch64_dsub, FPR128RC);1841}18421843for (i = 0; i < NumRegs; ++i, Reg = getNextVectorRegister(Reg, 1)) {1844bool isZReg = GETREGCLASS_CONTAIN0(AArch64_ZPRRegClassID, Reg);1845if (isZReg)1846SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_NoRegAltName), LayoutSuffix);1847else1848SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_vreg), LayoutSuffix);18491850if (MI->csh->detail) {1851#ifndef CAPSTONE_DIET1852uint8_t access;18531854access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);1855MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;1856MI->ac_idx++;1857#endif1858unsigned regForDetail = isZReg ? Reg : AArch64_map_vregister(Reg);1859MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;1860MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = regForDetail;1861MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].vas = vas;1862MI->flat_insn->detail->arm64.op_count++;1863}18641865if (i + 1 != NumRegs)1866SStream_concat0(O, ", ");1867}18681869SStream_concat0(O, "}");1870}18711872static void printTypedVectorList(MCInst *MI, unsigned OpNum, SStream *O, unsigned NumLanes, char LaneKind)1873{1874char Suffix[32];1875arm64_vas vas = 0;18761877if (NumLanes) {1878cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, LaneKind);18791880switch(LaneKind) {1881default: break;1882case 'b':1883switch(NumLanes) {1884default: break;1885case 1:1886vas = ARM64_VAS_1B;1887break;1888case 4:1889vas = ARM64_VAS_4B;1890break;1891case 8:1892vas = ARM64_VAS_8B;1893break;1894case 16:1895vas = ARM64_VAS_16B;1896break;1897}1898break;1899case 'h':1900switch(NumLanes) {1901default: break;1902case 1:1903vas = ARM64_VAS_1H;1904break;1905case 2:1906vas = ARM64_VAS_2H;1907break;1908case 4:1909vas = ARM64_VAS_4H;1910break;1911case 8:1912vas = ARM64_VAS_8H;1913break;1914}1915break;1916case 's':1917switch(NumLanes) {1918default: break;1919case 1:1920vas = ARM64_VAS_1S;1921break;1922case 2:1923vas = ARM64_VAS_2S;1924break;1925case 4:1926vas = ARM64_VAS_4S;1927break;1928}1929break;1930case 'd':1931switch(NumLanes) {1932default: break;1933case 1:1934vas = ARM64_VAS_1D;1935break;1936case 2:1937vas = ARM64_VAS_2D;1938break;1939}1940break;1941case 'q':1942switch(NumLanes) {1943default: break;1944case 1:1945vas = ARM64_VAS_1Q;1946break;1947}1948break;1949}1950} else {1951cs_snprintf(Suffix, sizeof(Suffix), ".%c", LaneKind);19521953switch(LaneKind) {1954default: break;1955case 'b':1956vas = ARM64_VAS_1B;1957break;1958case 'h':1959vas = ARM64_VAS_1H;1960break;1961case 's':1962vas = ARM64_VAS_1S;1963break;1964case 'd':1965vas = ARM64_VAS_1D;1966break;1967case 'q':1968vas = ARM64_VAS_1Q;1969break;1970}1971}19721973printVectorList(MI, OpNum, O, Suffix, MI->MRI, vas);1974}19751976static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)1977{1978SStream_concat0(O, "[");1979printInt32(O, (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)));1980SStream_concat0(O, "]");19811982if (MI->csh->detail) {1983MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vector_index = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));1984}1985}19861987static void printAlignedLabel(MCInst *MI, unsigned OpNum, SStream *O)1988{1989MCOperand *Op = MCInst_getOperand(MI, OpNum);19901991// If the label has already been resolved to an immediate offset (say, when1992// we're running the disassembler), just print the immediate.1993if (MCOperand_isImm(Op)) {1994uint64_t imm = (MCOperand_getImm(Op) * 4) + MI->address;1995printUInt64Bang(O, imm);19961997if (MI->csh->detail) {1998#ifndef CAPSTONE_DIET1999uint8_t access;20002001access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2002MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2003MI->ac_idx++;2004#endif2005MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;2006MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;2007MI->flat_insn->detail->arm64.op_count++;2008}2009}2010}20112012static void printAdrpLabel(MCInst *MI, unsigned OpNum, SStream *O)2013{2014MCOperand *Op = MCInst_getOperand(MI, OpNum);20152016if (MCOperand_isImm(Op)) {2017// ADRP sign extends a 21-bit offset, shifts it left by 122018// and adds it to the value of the PC with its bottom 12 bits cleared2019uint64_t imm = (MCOperand_getImm(Op) * 0x1000) + (MI->address & ~0xfff);2020printUInt64Bang(O, imm);20212022if (MI->csh->detail) {2023#ifndef CAPSTONE_DIET2024uint8_t access;20252026access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2027MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2028MI->ac_idx++;2029#endif2030MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;2031MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;2032MI->flat_insn->detail->arm64.op_count++;2033}2034}2035}20362037static void printBarrierOption(MCInst *MI, unsigned OpNum, SStream *O)2038{2039unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));2040unsigned Opcode = MCInst_getOpcode(MI);2041const char *Name = NULL;20422043if (Opcode == AArch64_ISB) {2044const ISB *ISB = lookupISBByEncoding(Val);2045Name = ISB ? ISB->Name : NULL;2046} else if (Opcode == AArch64_TSB) {2047const TSB *TSB = lookupTSBByEncoding(Val);2048Name = TSB ? TSB->Name : NULL;2049} else {2050const DB *DB = lookupDBByEncoding(Val);2051Name = DB ? DB->Name : NULL;2052}20532054if (Name) {2055SStream_concat0(O, Name);20562057if (MI->csh->detail) {2058#ifndef CAPSTONE_DIET2059uint8_t access;20602061access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2062MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2063MI->ac_idx++;2064#endif2065MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_BARRIER;2066MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].barrier = Val;2067MI->flat_insn->detail->arm64.op_count++;2068}2069} else {2070printUInt32Bang(O, Val);20712072if (MI->csh->detail) {2073#ifndef CAPSTONE_DIET2074uint8_t access;20752076access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2077MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2078MI->ac_idx++;2079#endif2080MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;2081MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;2082MI->flat_insn->detail->arm64.op_count++;2083}2084}2085}20862087static void printBarriernXSOption(MCInst *MI, unsigned OpNo, SStream *O) {2088unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, OpNo));2089// assert(MI->getOpcode() == AArch64::DSBnXS);20902091const char *Name = NULL;2092const DBnXS *DB = lookupDBnXSByEncoding(Val);2093Name = DB ? DB->Name : NULL;20942095if (Name) {2096SStream_concat0(O, Name);20972098if (MI->csh->detail) {2099#ifndef CAPSTONE_DIET2100uint8_t access;21012102access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2103MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2104MI->ac_idx++;2105#endif2106MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_BARRIER;2107MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].barrier = Val;2108MI->flat_insn->detail->arm64.op_count++;2109}2110}2111else {2112printUInt32Bang(O, Val);21132114if (MI->csh->detail) {2115#ifndef CAPSTONE_DIET2116uint8_t access;21172118access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2119MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2120MI->ac_idx++;2121#endif2122MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;2123MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;2124MI->flat_insn->detail->arm64.op_count++;2125}2126}2127}21282129static void printMRSSystemRegister(MCInst *MI, unsigned OpNum, SStream *O)2130{2131unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));2132const SysReg *Reg = lookupSysRegByEncoding(Val);21332134// Horrible hack for the one register that has identical encodings but2135// different names in MSR and MRS. Because of this, one of MRS and MSR is2136// going to get the wrong entry2137if (Val == ARM64_SYSREG_DBGDTRRX_EL0) {2138SStream_concat0(O, "dbgdtrrx_el0");21392140if (MI->csh->detail) {2141#ifndef CAPSTONE_DIET2142uint8_t access;21432144access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2145MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2146MI->ac_idx++;2147#endif21482149MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;2150MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Val;2151MI->flat_insn->detail->arm64.op_count++;2152}21532154return;2155}21562157// Another hack for a register which has an alternative name which is not an alias,2158// and is not in the Armv9-A documentation.2159if( Val == ARM64_SYSREG_VSCTLR_EL2){2160SStream_concat0(O, "ttbr0_el2");21612162if (MI->csh->detail) {2163#ifndef CAPSTONE_DIET2164uint8_t access;21652166access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2167MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2168MI->ac_idx++;2169#endif21702171MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;2172MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Val;2173MI->flat_insn->detail->arm64.op_count++;2174}21752176return;2177}21782179// if (Reg && Reg->Readable && Reg->haveFeatures(STI.getFeatureBits()))2180if (Reg && Reg->Readable) {2181SStream_concat0(O, Reg->Name);21822183if (MI->csh->detail) {2184#ifndef CAPSTONE_DIET2185uint8_t access;21862187access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2188MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2189MI->ac_idx++;2190#endif21912192MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;2193MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Reg->Encoding;2194MI->flat_insn->detail->arm64.op_count++;2195}2196} else {2197char result[128];21982199AArch64SysReg_genericRegisterString(Val, result);2200SStream_concat0(O, result);22012202if (MI->csh->detail) {2203#ifndef CAPSTONE_DIET2204uint8_t access;2205access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2206MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2207MI->ac_idx++;2208#endif2209MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG_MRS;2210MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Val;2211MI->flat_insn->detail->arm64.op_count++;2212}2213}2214}22152216static void printMSRSystemRegister(MCInst *MI, unsigned OpNum, SStream *O)2217{2218unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));2219const SysReg *Reg = lookupSysRegByEncoding(Val);22202221// Horrible hack for the one register that has identical encodings but2222// different names in MSR and MRS. Because of this, one of MRS and MSR is2223// going to get the wrong entry2224if (Val == ARM64_SYSREG_DBGDTRTX_EL0) {2225SStream_concat0(O, "dbgdtrtx_el0");22262227if (MI->csh->detail) {2228#ifndef CAPSTONE_DIET2229uint8_t access;22302231access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2232MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2233MI->ac_idx++;2234#endif22352236MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;2237MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Val;2238MI->flat_insn->detail->arm64.op_count++;2239}22402241return;2242}22432244// Another hack for a register which has an alternative name which is not an alias,2245// and is not in the Armv9-A documentation.2246if( Val == ARM64_SYSREG_VSCTLR_EL2){2247SStream_concat0(O, "ttbr0_el2");22482249if (MI->csh->detail) {2250#ifndef CAPSTONE_DIET2251uint8_t access;22522253access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2254MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2255MI->ac_idx++;2256#endif22572258MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;2259MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Val;2260MI->flat_insn->detail->arm64.op_count++;2261}22622263return;2264}22652266// if (Reg && Reg->Writeable && Reg->haveFeatures(STI.getFeatureBits()))2267if (Reg && Reg->Writeable) {2268SStream_concat0(O, Reg->Name);22692270if (MI->csh->detail) {2271#ifndef CAPSTONE_DIET2272uint8_t access;22732274access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2275MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2276MI->ac_idx++;2277#endif22782279MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;2280MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Reg->Encoding;2281MI->flat_insn->detail->arm64.op_count++;2282}2283} else {2284char result[128];22852286AArch64SysReg_genericRegisterString(Val, result);2287SStream_concat0(O, result);22882289if (MI->csh->detail) {2290#ifndef CAPSTONE_DIET2291uint8_t access;2292access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2293MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2294MI->ac_idx++;2295#endif2296MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG_MRS;2297MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Val;2298MI->flat_insn->detail->arm64.op_count++;2299}2300}2301}23022303static void printSystemPStateField(MCInst *MI, unsigned OpNum, SStream *O)2304{2305unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));23062307const PState *PState = lookupPStateByEncoding(Val);23082309if (PState) {2310SStream_concat0(O, PState->Name);23112312if (MI->csh->detail) {2313#ifndef CAPSTONE_DIET2314uint8_t access;2315access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2316MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2317MI->ac_idx++;2318#endif2319MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_PSTATE;2320MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].pstate = Val;2321MI->flat_insn->detail->arm64.op_count++;2322}2323} else {2324printUInt32Bang(O, Val);23252326if (MI->csh->detail) {2327#ifndef CAPSTONE_DIET2328unsigned char access;23292330access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2331MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2332MI->ac_idx++;2333#endif23342335MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;2336MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;2337MI->flat_insn->detail->arm64.op_count++;2338}2339}2340}23412342static void printSIMDType10Operand(MCInst *MI, unsigned OpNum, SStream *O)2343{2344uint8_t RawVal = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));2345uint64_t Val = AArch64_AM_decodeAdvSIMDModImmType10(RawVal);23462347SStream_concat(O, "#%#016llx", Val);23482349if (MI->csh->detail) {2350#ifndef CAPSTONE_DIET2351unsigned char access;23522353access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2354MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2355MI->ac_idx++;2356#endif2357MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;2358MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;2359MI->flat_insn->detail->arm64.op_count++;2360}2361}23622363static void printComplexRotationOp(MCInst *MI, unsigned OpNum, SStream *O, int64_t Angle, int64_t Remainder)2364{2365unsigned int Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));2366printInt64Bang(O, (Val * Angle) + Remainder);2367op_addImm(MI, (Val * Angle) + Remainder);2368}23692370static void printSVCROp(MCInst *MI, unsigned OpNum, SStream *O)2371{2372MCOperand *MO = MCInst_getOperand(MI, OpNum);2373// assert(MCOperand_isImm(MO) && "Unexpected operand type!");2374unsigned svcrop = MCOperand_getImm(MO);2375const SVCR *svcr = lookupSVCRByEncoding(svcrop);2376// assert(svcr && "Unexpected SVCR operand!");2377SStream_concat0(O, svcr->Name);23782379if (MI->csh->detail) {2380#ifndef CAPSTONE_DIET2381uint8_t access;23822383access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2384MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2385MI->ac_idx++;2386#endif23872388MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SVCR;2389MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = (unsigned)ARM64_SYSREG_SVCR;2390MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].svcr = svcr->Encoding;2391MI->flat_insn->detail->arm64.op_count++;2392}2393}23942395static void printMatrix(MCInst *MI, unsigned OpNum, SStream *O, int EltSize)2396{2397MCOperand *RegOp = MCInst_getOperand(MI, OpNum);2398// assert(MCOperand_isReg(RegOp) && "Unexpected operand type!");2399unsigned Reg = MCOperand_getReg(RegOp);24002401SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));2402const char *sizeStr = "";2403switch (EltSize) {2404case 0:2405sizeStr = "";2406break;2407case 8:2408sizeStr = ".b";2409break;2410case 16:2411sizeStr = ".h";2412break;2413case 32:2414sizeStr = ".s";2415break;2416case 64:2417sizeStr = ".d";2418break;2419case 128:2420sizeStr = ".q";2421break;2422default:2423break;2424// llvm_unreachable("Unsupported element size");2425}2426SStream_concat0(O, sizeStr);24272428if (MI->csh->detail) {2429#ifndef CAPSTONE_DIET2430uint8_t access;24312432access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2433MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2434MI->ac_idx++;2435#endif24362437MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;2438MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;2439MI->flat_insn->detail->arm64.op_count++;2440}2441}24422443static void printMatrixIndex(MCInst *MI, unsigned OpNum, SStream *O)2444{2445int64_t imm = MCOperand_getImm(MCInst_getOperand(MI, OpNum));2446printInt64(O, imm);24472448if (MI->csh->detail) {2449if (MI->csh->doing_SME_Index) {2450// Access op_count-1 as We want to add info to previous operand, not create a new one2451MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count-1].sme_index.disp = imm;2452}2453}2454}24552456static void printMatrixTile(MCInst *MI, unsigned OpNum, SStream *O)2457{2458MCOperand *RegOp = MCInst_getOperand(MI, OpNum);2459// assert(MCOperand_isReg(RegOp) && "Unexpected operand type!");2460unsigned Reg = MCOperand_getReg(RegOp);2461SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));24622463if (MI->csh->detail) {2464#ifndef CAPSTONE_DIET2465uint8_t access;24662467access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2468MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2469MI->ac_idx++;2470#endif24712472MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;2473MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;2474MI->flat_insn->detail->arm64.op_count++;2475}2476}24772478static void printMatrixTileVector(MCInst *MI, unsigned OpNum, SStream *O, bool IsVertical)2479{2480MCOperand *RegOp = MCInst_getOperand(MI, OpNum);2481// assert(MCOperand_isReg(RegOp) && "Unexpected operand type!");2482unsigned Reg = MCOperand_getReg(RegOp);2483#ifndef CAPSTONE_DIET2484const char *RegName = getRegisterName(Reg, AArch64_NoRegAltName);24852486const size_t strLn = strlen(RegName);2487// +2 for extra chars, + 1 for null char \02488char *RegNameNew = cs_mem_malloc(sizeof(char) * (strLn + 2 + 1));2489int index = 0, i;2490for (i = 0; i < (strLn + 2); i++){2491if(RegName[i] != '.'){2492RegNameNew[index] = RegName[i];2493index++;2494}2495else{2496RegNameNew[index] = IsVertical ? 'v' : 'h';2497RegNameNew[index + 1] = '.';2498index += 2;2499}2500}2501SStream_concat0(O, RegNameNew);2502#endif25032504if (MI->csh->detail) {2505#ifndef CAPSTONE_DIET2506uint8_t access;25072508access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2509MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2510MI->ac_idx++;2511#endif25122513MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;2514MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;2515MI->flat_insn->detail->arm64.op_count++;2516}2517#ifndef CAPSTONE_DIET2518cs_mem_free(RegNameNew);2519#endif2520}25212522static const unsigned MatrixZADRegisterTable[] = {2523AArch64_ZAD0, AArch64_ZAD1, AArch64_ZAD2, AArch64_ZAD3,2524AArch64_ZAD4, AArch64_ZAD5, AArch64_ZAD6, AArch64_ZAD72525};25262527static void printMatrixTileList(MCInst *MI, unsigned OpNum, SStream *O){2528unsigned MaxRegs = 8;2529unsigned RegMask = MCOperand_getImm(MCInst_getOperand(MI, OpNum));25302531unsigned NumRegs = 0, I;2532for (I = 0; I < MaxRegs; ++I)2533if ((RegMask & (1 << I)) != 0)2534++NumRegs;25352536SStream_concat0(O, "{");2537unsigned Printed = 0, J;2538for (J = 0; J < MaxRegs; ++J) {2539unsigned Reg = RegMask & (1 << J);2540if (Reg == 0)2541continue;2542SStream_concat0(O, getRegisterName(MatrixZADRegisterTable[J], AArch64_NoRegAltName));25432544if (MI->csh->detail) {2545#ifndef CAPSTONE_DIET2546uint8_t access;25472548access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2549MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2550MI->ac_idx++;2551#endif25522553MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;2554MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MatrixZADRegisterTable[J];2555MI->flat_insn->detail->arm64.op_count++;2556}25572558if (Printed + 1 != NumRegs)2559SStream_concat0(O, ", ");2560++Printed;2561}2562SStream_concat0(O, "}");2563}25642565static void printSVEPattern(MCInst *MI, unsigned OpNum, SStream *O)2566{2567unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));25682569const SVEPREDPAT *Pat = lookupSVEPREDPATByEncoding(Val);2570if (Pat)2571SStream_concat0(O, Pat->Name);2572else2573printUInt32Bang(O, Val);2574}25752576// default suffix = 02577static void printSVERegOp(MCInst *MI, unsigned OpNum, SStream *O, char suffix)2578{2579unsigned int Reg;25802581#if 02582switch (suffix) {2583case 0:2584case 'b':2585case 'h':2586case 's':2587case 'd':2588case 'q':2589break;2590default:2591// llvm_unreachable("Invalid kind specifier.");2592}2593#endif25942595Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));25962597if (MI->csh->detail) {2598#ifndef CAPSTONE_DIET2599uint8_t access;26002601access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2602MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2603MI->ac_idx++;2604#endif2605MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;2606MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;2607MI->flat_insn->detail->arm64.op_count++;2608}26092610SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));26112612if (suffix != '\0')2613SStream_concat(O, ".%c", suffix);2614}26152616static void printImmSVE16(int16_t Val, SStream *O)2617{2618printUInt32Bang(O, Val);2619}26202621static void printImmSVE32(int32_t Val, SStream *O)2622{2623printUInt32Bang(O, Val);2624}26252626static void printImmSVE64(int64_t Val, SStream *O)2627{2628printUInt64Bang(O, Val);2629}26302631static void printImm8OptLsl32(MCInst *MI, unsigned OpNum, SStream *O)2632{2633unsigned UnscaledVal = MCOperand_getImm(MCInst_getOperand(MI, OpNum));2634unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));2635uint32_t Val;26362637// assert(AArch64_AM::getShiftType(Shift) == AArch64_AM::LSL &&2638// "Unexepected shift type!");26392640// #0 lsl #8 is never pretty printed2641if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) {2642printUInt32Bang(O, UnscaledVal);2643printShifter(MI, OpNum + 1, O);2644return;2645}26462647Val = UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift));2648printImmSVE32(Val, O);2649}26502651static void printImm8OptLsl64(MCInst *MI, unsigned OpNum, SStream *O)2652{2653unsigned UnscaledVal = MCOperand_getImm(MCInst_getOperand(MI, OpNum));2654unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));2655uint64_t Val;26562657// assert(AArch64_AM::getShiftType(Shift) == AArch64_AM::LSL &&2658// "Unexepected shift type!");26592660// #0 lsl #8 is never pretty printed2661if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) {2662printUInt32Bang(O, UnscaledVal);2663printShifter(MI, OpNum + 1, O);2664return;2665}26662667Val = UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift));2668printImmSVE64(Val, O);2669}26702671static void printSVELogicalImm16(MCInst *MI, unsigned OpNum, SStream *O)2672{2673uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));2674uint64_t PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64);26752676// Prefer the default format for 16bit values, hex otherwise.2677printImmSVE16(PrintVal, O);2678}26792680static void printSVELogicalImm32(MCInst *MI, unsigned OpNum, SStream *O)2681{2682uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));2683uint64_t PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64);26842685// Prefer the default format for 16bit values, hex otherwise.2686if ((uint16_t)PrintVal == (uint32_t)PrintVal)2687printImmSVE16(PrintVal, O);2688else2689printUInt64Bang(O, PrintVal);2690}26912692static void printSVELogicalImm64(MCInst *MI, unsigned OpNum, SStream *O)2693{2694uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));2695uint64_t PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64);26962697printImmSVE64(PrintVal, O);2698}26992700static void printZPRasFPR(MCInst *MI, unsigned OpNum, SStream *O, int Width)2701{2702unsigned int Base, Reg;27032704switch (Width) {2705default: // llvm_unreachable("Unsupported width");2706case 8: Base = AArch64_B0; break;2707case 16: Base = AArch64_H0; break;2708case 32: Base = AArch64_S0; break;2709case 64: Base = AArch64_D0; break;2710case 128: Base = AArch64_Q0; break;2711}27122713Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) - AArch64_Z0 + Base;27142715SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));27162717if (MI->csh->detail) {2718#ifndef CAPSTONE_DIET2719uint8_t access;27202721access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);2722MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;2723MI->ac_idx++;2724#endif2725MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;2726MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;2727MI->flat_insn->detail->arm64.op_count++;2728}2729}27302731static void printExactFPImm(MCInst *MI, unsigned OpNum, SStream *O, unsigned ImmIs0, unsigned ImmIs1)2732{2733const ExactFPImm *Imm0Desc = lookupExactFPImmByEnum(ImmIs0);2734const ExactFPImm *Imm1Desc = lookupExactFPImmByEnum(ImmIs1);2735unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));27362737SStream_concat0(O, Val ? Imm1Desc->Repr : Imm0Desc->Repr);2738}27392740static void printGPR64as32(MCInst *MI, unsigned OpNum, SStream *O)2741{2742unsigned int Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));27432744SStream_concat0(O, getRegisterName(getWRegFromXReg(Reg), AArch64_NoRegAltName));2745}27462747static void printGPR64x8(MCInst *MI, unsigned OpNum, SStream *O)2748{2749unsigned int Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));27502751SStream_concat0(O, getRegisterName(MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_x8sub_0), AArch64_NoRegAltName));2752}27532754#define PRINT_ALIAS_INSTR2755#include "AArch64GenAsmWriter.inc"2756#include "AArch64GenRegisterName.inc"27572758void AArch64_post_printer(csh handle, cs_insn *flat_insn, char *insn_asm, MCInst *mci)2759{2760if (((cs_struct *)handle)->detail != CS_OPT_ON)2761return;27622763if (mci->csh->detail) {2764unsigned opcode = MCInst_getOpcode(mci);27652766switch (opcode) {2767default:2768break;2769case AArch64_LD1Fourv16b_POST:2770case AArch64_LD1Fourv1d_POST:2771case AArch64_LD1Fourv2d_POST:2772case AArch64_LD1Fourv2s_POST:2773case AArch64_LD1Fourv4h_POST:2774case AArch64_LD1Fourv4s_POST:2775case AArch64_LD1Fourv8b_POST:2776case AArch64_LD1Fourv8h_POST:2777case AArch64_LD1Onev16b_POST:2778case AArch64_LD1Onev1d_POST:2779case AArch64_LD1Onev2d_POST:2780case AArch64_LD1Onev2s_POST:2781case AArch64_LD1Onev4h_POST:2782case AArch64_LD1Onev4s_POST:2783case AArch64_LD1Onev8b_POST:2784case AArch64_LD1Onev8h_POST:2785case AArch64_LD1Rv16b_POST:2786case AArch64_LD1Rv1d_POST:2787case AArch64_LD1Rv2d_POST:2788case AArch64_LD1Rv2s_POST:2789case AArch64_LD1Rv4h_POST:2790case AArch64_LD1Rv4s_POST:2791case AArch64_LD1Rv8b_POST:2792case AArch64_LD1Rv8h_POST:2793case AArch64_LD1Threev16b_POST:2794case AArch64_LD1Threev1d_POST:2795case AArch64_LD1Threev2d_POST:2796case AArch64_LD1Threev2s_POST:2797case AArch64_LD1Threev4h_POST:2798case AArch64_LD1Threev4s_POST:2799case AArch64_LD1Threev8b_POST:2800case AArch64_LD1Threev8h_POST:2801case AArch64_LD1Twov16b_POST:2802case AArch64_LD1Twov1d_POST:2803case AArch64_LD1Twov2d_POST:2804case AArch64_LD1Twov2s_POST:2805case AArch64_LD1Twov4h_POST:2806case AArch64_LD1Twov4s_POST:2807case AArch64_LD1Twov8b_POST:2808case AArch64_LD1Twov8h_POST:2809case AArch64_LD1i16_POST:2810case AArch64_LD1i32_POST:2811case AArch64_LD1i64_POST:2812case AArch64_LD1i8_POST:2813case AArch64_LD2Rv16b_POST:2814case AArch64_LD2Rv1d_POST:2815case AArch64_LD2Rv2d_POST:2816case AArch64_LD2Rv2s_POST:2817case AArch64_LD2Rv4h_POST:2818case AArch64_LD2Rv4s_POST:2819case AArch64_LD2Rv8b_POST:2820case AArch64_LD2Rv8h_POST:2821case AArch64_LD2Twov16b_POST:2822case AArch64_LD2Twov2d_POST:2823case AArch64_LD2Twov2s_POST:2824case AArch64_LD2Twov4h_POST:2825case AArch64_LD2Twov4s_POST:2826case AArch64_LD2Twov8b_POST:2827case AArch64_LD2Twov8h_POST:2828case AArch64_LD2i16_POST:2829case AArch64_LD2i32_POST:2830case AArch64_LD2i64_POST:2831case AArch64_LD2i8_POST:2832case AArch64_LD3Rv16b_POST:2833case AArch64_LD3Rv1d_POST:2834case AArch64_LD3Rv2d_POST:2835case AArch64_LD3Rv2s_POST:2836case AArch64_LD3Rv4h_POST:2837case AArch64_LD3Rv4s_POST:2838case AArch64_LD3Rv8b_POST:2839case AArch64_LD3Rv8h_POST:2840case AArch64_LD3Threev16b_POST:2841case AArch64_LD3Threev2d_POST:2842case AArch64_LD3Threev2s_POST:2843case AArch64_LD3Threev4h_POST:2844case AArch64_LD3Threev4s_POST:2845case AArch64_LD3Threev8b_POST:2846case AArch64_LD3Threev8h_POST:2847case AArch64_LD3i16_POST:2848case AArch64_LD3i32_POST:2849case AArch64_LD3i64_POST:2850case AArch64_LD3i8_POST:2851case AArch64_LD4Fourv16b_POST:2852case AArch64_LD4Fourv2d_POST:2853case AArch64_LD4Fourv2s_POST:2854case AArch64_LD4Fourv4h_POST:2855case AArch64_LD4Fourv4s_POST:2856case AArch64_LD4Fourv8b_POST:2857case AArch64_LD4Fourv8h_POST:2858case AArch64_LD4Rv16b_POST:2859case AArch64_LD4Rv1d_POST:2860case AArch64_LD4Rv2d_POST:2861case AArch64_LD4Rv2s_POST:2862case AArch64_LD4Rv4h_POST:2863case AArch64_LD4Rv4s_POST:2864case AArch64_LD4Rv8b_POST:2865case AArch64_LD4Rv8h_POST:2866case AArch64_LD4i16_POST:2867case AArch64_LD4i32_POST:2868case AArch64_LD4i64_POST:2869case AArch64_LD4i8_POST:2870case AArch64_LDRBBpost:2871case AArch64_LDRBpost:2872case AArch64_LDRDpost:2873case AArch64_LDRHHpost:2874case AArch64_LDRHpost:2875case AArch64_LDRQpost:2876case AArch64_LDPDpost:2877case AArch64_LDPQpost:2878case AArch64_LDPSWpost:2879case AArch64_LDPSpost:2880case AArch64_LDPWpost:2881case AArch64_LDPXpost:2882case AArch64_ST1Fourv16b_POST:2883case AArch64_ST1Fourv1d_POST:2884case AArch64_ST1Fourv2d_POST:2885case AArch64_ST1Fourv2s_POST:2886case AArch64_ST1Fourv4h_POST:2887case AArch64_ST1Fourv4s_POST:2888case AArch64_ST1Fourv8b_POST:2889case AArch64_ST1Fourv8h_POST:2890case AArch64_ST1Onev16b_POST:2891case AArch64_ST1Onev1d_POST:2892case AArch64_ST1Onev2d_POST:2893case AArch64_ST1Onev2s_POST:2894case AArch64_ST1Onev4h_POST:2895case AArch64_ST1Onev4s_POST:2896case AArch64_ST1Onev8b_POST:2897case AArch64_ST1Onev8h_POST:2898case AArch64_ST1Threev16b_POST:2899case AArch64_ST1Threev1d_POST:2900case AArch64_ST1Threev2d_POST:2901case AArch64_ST1Threev2s_POST:2902case AArch64_ST1Threev4h_POST:2903case AArch64_ST1Threev4s_POST:2904case AArch64_ST1Threev8b_POST:2905case AArch64_ST1Threev8h_POST:2906case AArch64_ST1Twov16b_POST:2907case AArch64_ST1Twov1d_POST:2908case AArch64_ST1Twov2d_POST:2909case AArch64_ST1Twov2s_POST:2910case AArch64_ST1Twov4h_POST:2911case AArch64_ST1Twov4s_POST:2912case AArch64_ST1Twov8b_POST:2913case AArch64_ST1Twov8h_POST:2914case AArch64_ST1i16_POST:2915case AArch64_ST1i32_POST:2916case AArch64_ST1i64_POST:2917case AArch64_ST1i8_POST:2918case AArch64_ST2GPostIndex:2919case AArch64_ST2Twov16b_POST:2920case AArch64_ST2Twov2d_POST:2921case AArch64_ST2Twov2s_POST:2922case AArch64_ST2Twov4h_POST:2923case AArch64_ST2Twov4s_POST:2924case AArch64_ST2Twov8b_POST:2925case AArch64_ST2Twov8h_POST:2926case AArch64_ST2i16_POST:2927case AArch64_ST2i32_POST:2928case AArch64_ST2i64_POST:2929case AArch64_ST2i8_POST:2930case AArch64_ST3Threev16b_POST:2931case AArch64_ST3Threev2d_POST:2932case AArch64_ST3Threev2s_POST:2933case AArch64_ST3Threev4h_POST:2934case AArch64_ST3Threev4s_POST:2935case AArch64_ST3Threev8b_POST:2936case AArch64_ST3Threev8h_POST:2937case AArch64_ST3i16_POST:2938case AArch64_ST3i32_POST:2939case AArch64_ST3i64_POST:2940case AArch64_ST3i8_POST:2941case AArch64_ST4Fourv16b_POST:2942case AArch64_ST4Fourv2d_POST:2943case AArch64_ST4Fourv2s_POST:2944case AArch64_ST4Fourv4h_POST:2945case AArch64_ST4Fourv4s_POST:2946case AArch64_ST4Fourv8b_POST:2947case AArch64_ST4Fourv8h_POST:2948case AArch64_ST4i16_POST:2949case AArch64_ST4i32_POST:2950case AArch64_ST4i64_POST:2951case AArch64_ST4i8_POST:2952case AArch64_STPDpost:2953case AArch64_STPQpost:2954case AArch64_STPSpost:2955case AArch64_STPWpost:2956case AArch64_STPXpost:2957case AArch64_STRBBpost:2958case AArch64_STRBpost:2959case AArch64_STRDpost:2960case AArch64_STRHHpost:2961case AArch64_STRHpost:2962case AArch64_STRQpost:2963case AArch64_STRSpost:2964case AArch64_STRWpost:2965case AArch64_STRXpost:2966case AArch64_STZ2GPostIndex:2967case AArch64_STZGPostIndex:2968case AArch64_STGPostIndex:2969case AArch64_STGPpost:2970case AArch64_LDRSBWpost:2971case AArch64_LDRSBXpost:2972case AArch64_LDRSHWpost:2973case AArch64_LDRSHXpost:2974case AArch64_LDRSWpost:2975case AArch64_LDRSpost:2976case AArch64_LDRWpost:2977case AArch64_LDRXpost:2978flat_insn->detail->arm64.writeback = true;2979flat_insn->detail->arm64.post_index = true;2980break;2981case AArch64_LDRAAwriteback:2982case AArch64_LDRABwriteback:2983case AArch64_ST2GPreIndex:2984case AArch64_LDPDpre:2985case AArch64_LDPQpre:2986case AArch64_LDPSWpre:2987case AArch64_LDPSpre:2988case AArch64_LDPWpre:2989case AArch64_LDPXpre:2990case AArch64_LDRBBpre:2991case AArch64_LDRBpre:2992case AArch64_LDRDpre:2993case AArch64_LDRHHpre:2994case AArch64_LDRHpre:2995case AArch64_LDRQpre:2996case AArch64_LDRSBWpre:2997case AArch64_LDRSBXpre:2998case AArch64_LDRSHWpre:2999case AArch64_LDRSHXpre:3000case AArch64_LDRSWpre:3001case AArch64_LDRSpre:3002case AArch64_LDRWpre:3003case AArch64_LDRXpre:3004case AArch64_STGPreIndex:3005case AArch64_STPDpre:3006case AArch64_STPQpre:3007case AArch64_STPSpre:3008case AArch64_STPWpre:3009case AArch64_STPXpre:3010case AArch64_STRBBpre:3011case AArch64_STRBpre:3012case AArch64_STRDpre:3013case AArch64_STRHHpre:3014case AArch64_STRHpre:3015case AArch64_STRQpre:3016case AArch64_STRSpre:3017case AArch64_STRWpre:3018case AArch64_STRXpre:3019case AArch64_STZ2GPreIndex:3020case AArch64_STZGPreIndex:3021case AArch64_STGPpre:3022flat_insn->detail->arm64.writeback = true;3023break;3024}3025}3026}30273028#endif302930303031