Path: blob/master/libs/capstone/arch/AArch64/AArch64BaseInfo.h
4389 views
//===-- AArch64BaseInfo.h - Top level definitions for AArch64- --*- C++ -*-===//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 file contains small standalone helper functions and enum definitions for10// the AArch64 target useful for the compiler back-end and the MC libraries.11// As such, it deliberately does not include references to LLVM core12// code gen types, passes, etc..13//14//===----------------------------------------------------------------------===//1516/* Capstone Disassembly Engine */17/* By Nguyen Anh Quynh <[email protected]>, 2013-2019 */1819#ifndef CS_LLVM_AARCH64_BASEINFO_H20#define CS_LLVM_AARCH64_BASEINFO_H2122#include <ctype.h>23#include <string.h>24#include "AArch64Mapping.h"2526#ifndef __cplusplus27#if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)28#define inline /* inline */29#endif30#endif3132inline static unsigned getWRegFromXReg(unsigned Reg)33{34switch (Reg) {35default: break;36case ARM64_REG_X0: return ARM64_REG_W0;37case ARM64_REG_X1: return ARM64_REG_W1;38case ARM64_REG_X2: return ARM64_REG_W2;39case ARM64_REG_X3: return ARM64_REG_W3;40case ARM64_REG_X4: return ARM64_REG_W4;41case ARM64_REG_X5: return ARM64_REG_W5;42case ARM64_REG_X6: return ARM64_REG_W6;43case ARM64_REG_X7: return ARM64_REG_W7;44case ARM64_REG_X8: return ARM64_REG_W8;45case ARM64_REG_X9: return ARM64_REG_W9;46case ARM64_REG_X10: return ARM64_REG_W10;47case ARM64_REG_X11: return ARM64_REG_W11;48case ARM64_REG_X12: return ARM64_REG_W12;49case ARM64_REG_X13: return ARM64_REG_W13;50case ARM64_REG_X14: return ARM64_REG_W14;51case ARM64_REG_X15: return ARM64_REG_W15;52case ARM64_REG_X16: return ARM64_REG_W16;53case ARM64_REG_X17: return ARM64_REG_W17;54case ARM64_REG_X18: return ARM64_REG_W18;55case ARM64_REG_X19: return ARM64_REG_W19;56case ARM64_REG_X20: return ARM64_REG_W20;57case ARM64_REG_X21: return ARM64_REG_W21;58case ARM64_REG_X22: return ARM64_REG_W22;59case ARM64_REG_X23: return ARM64_REG_W23;60case ARM64_REG_X24: return ARM64_REG_W24;61case ARM64_REG_X25: return ARM64_REG_W25;62case ARM64_REG_X26: return ARM64_REG_W26;63case ARM64_REG_X27: return ARM64_REG_W27;64case ARM64_REG_X28: return ARM64_REG_W28;65case ARM64_REG_FP: return ARM64_REG_W29;66case ARM64_REG_LR: return ARM64_REG_W30;67case ARM64_REG_SP: return ARM64_REG_WSP;68case ARM64_REG_XZR: return ARM64_REG_WZR;69}7071// For anything else, return it unchanged.72return Reg;73}7475inline static unsigned getXRegFromWReg(unsigned Reg)76{77switch (Reg) {78case ARM64_REG_W0: return ARM64_REG_X0;79case ARM64_REG_W1: return ARM64_REG_X1;80case ARM64_REG_W2: return ARM64_REG_X2;81case ARM64_REG_W3: return ARM64_REG_X3;82case ARM64_REG_W4: return ARM64_REG_X4;83case ARM64_REG_W5: return ARM64_REG_X5;84case ARM64_REG_W6: return ARM64_REG_X6;85case ARM64_REG_W7: return ARM64_REG_X7;86case ARM64_REG_W8: return ARM64_REG_X8;87case ARM64_REG_W9: return ARM64_REG_X9;88case ARM64_REG_W10: return ARM64_REG_X10;89case ARM64_REG_W11: return ARM64_REG_X11;90case ARM64_REG_W12: return ARM64_REG_X12;91case ARM64_REG_W13: return ARM64_REG_X13;92case ARM64_REG_W14: return ARM64_REG_X14;93case ARM64_REG_W15: return ARM64_REG_X15;94case ARM64_REG_W16: return ARM64_REG_X16;95case ARM64_REG_W17: return ARM64_REG_X17;96case ARM64_REG_W18: return ARM64_REG_X18;97case ARM64_REG_W19: return ARM64_REG_X19;98case ARM64_REG_W20: return ARM64_REG_X20;99case ARM64_REG_W21: return ARM64_REG_X21;100case ARM64_REG_W22: return ARM64_REG_X22;101case ARM64_REG_W23: return ARM64_REG_X23;102case ARM64_REG_W24: return ARM64_REG_X24;103case ARM64_REG_W25: return ARM64_REG_X25;104case ARM64_REG_W26: return ARM64_REG_X26;105case ARM64_REG_W27: return ARM64_REG_X27;106case ARM64_REG_W28: return ARM64_REG_X28;107case ARM64_REG_W29: return ARM64_REG_FP;108case ARM64_REG_W30: return ARM64_REG_LR;109case ARM64_REG_WSP: return ARM64_REG_SP;110case ARM64_REG_WZR: return ARM64_REG_XZR;111}112113// For anything else, return it unchanged.114return Reg;115}116117inline static unsigned getBRegFromDReg(unsigned Reg)118{119switch (Reg) {120case ARM64_REG_D0: return ARM64_REG_B0;121case ARM64_REG_D1: return ARM64_REG_B1;122case ARM64_REG_D2: return ARM64_REG_B2;123case ARM64_REG_D3: return ARM64_REG_B3;124case ARM64_REG_D4: return ARM64_REG_B4;125case ARM64_REG_D5: return ARM64_REG_B5;126case ARM64_REG_D6: return ARM64_REG_B6;127case ARM64_REG_D7: return ARM64_REG_B7;128case ARM64_REG_D8: return ARM64_REG_B8;129case ARM64_REG_D9: return ARM64_REG_B9;130case ARM64_REG_D10: return ARM64_REG_B10;131case ARM64_REG_D11: return ARM64_REG_B11;132case ARM64_REG_D12: return ARM64_REG_B12;133case ARM64_REG_D13: return ARM64_REG_B13;134case ARM64_REG_D14: return ARM64_REG_B14;135case ARM64_REG_D15: return ARM64_REG_B15;136case ARM64_REG_D16: return ARM64_REG_B16;137case ARM64_REG_D17: return ARM64_REG_B17;138case ARM64_REG_D18: return ARM64_REG_B18;139case ARM64_REG_D19: return ARM64_REG_B19;140case ARM64_REG_D20: return ARM64_REG_B20;141case ARM64_REG_D21: return ARM64_REG_B21;142case ARM64_REG_D22: return ARM64_REG_B22;143case ARM64_REG_D23: return ARM64_REG_B23;144case ARM64_REG_D24: return ARM64_REG_B24;145case ARM64_REG_D25: return ARM64_REG_B25;146case ARM64_REG_D26: return ARM64_REG_B26;147case ARM64_REG_D27: return ARM64_REG_B27;148case ARM64_REG_D28: return ARM64_REG_B28;149case ARM64_REG_D29: return ARM64_REG_B29;150case ARM64_REG_D30: return ARM64_REG_B30;151case ARM64_REG_D31: return ARM64_REG_B31;152}153154// For anything else, return it unchanged.155return Reg;156}157158inline static unsigned getDRegFromBReg(unsigned Reg)159{160switch (Reg) {161case ARM64_REG_B0: return ARM64_REG_D0;162case ARM64_REG_B1: return ARM64_REG_D1;163case ARM64_REG_B2: return ARM64_REG_D2;164case ARM64_REG_B3: return ARM64_REG_D3;165case ARM64_REG_B4: return ARM64_REG_D4;166case ARM64_REG_B5: return ARM64_REG_D5;167case ARM64_REG_B6: return ARM64_REG_D6;168case ARM64_REG_B7: return ARM64_REG_D7;169case ARM64_REG_B8: return ARM64_REG_D8;170case ARM64_REG_B9: return ARM64_REG_D9;171case ARM64_REG_B10: return ARM64_REG_D10;172case ARM64_REG_B11: return ARM64_REG_D11;173case ARM64_REG_B12: return ARM64_REG_D12;174case ARM64_REG_B13: return ARM64_REG_D13;175case ARM64_REG_B14: return ARM64_REG_D14;176case ARM64_REG_B15: return ARM64_REG_D15;177case ARM64_REG_B16: return ARM64_REG_D16;178case ARM64_REG_B17: return ARM64_REG_D17;179case ARM64_REG_B18: return ARM64_REG_D18;180case ARM64_REG_B19: return ARM64_REG_D19;181case ARM64_REG_B20: return ARM64_REG_D20;182case ARM64_REG_B21: return ARM64_REG_D21;183case ARM64_REG_B22: return ARM64_REG_D22;184case ARM64_REG_B23: return ARM64_REG_D23;185case ARM64_REG_B24: return ARM64_REG_D24;186case ARM64_REG_B25: return ARM64_REG_D25;187case ARM64_REG_B26: return ARM64_REG_D26;188case ARM64_REG_B27: return ARM64_REG_D27;189case ARM64_REG_B28: return ARM64_REG_D28;190case ARM64_REG_B29: return ARM64_REG_D29;191case ARM64_REG_B30: return ARM64_REG_D30;192case ARM64_REG_B31: return ARM64_REG_D31;193}194195// For anything else, return it unchanged.196return Reg;197}198199// // Enums corresponding to AArch64 condition codes200// The CondCodes constants map directly to the 4-bit encoding of the201// condition field for predicated instructions.202typedef enum AArch64CC_CondCode { // Meaning (integer) Meaning (floating-point)203AArch64CC_EQ = 0x0, // Equal Equal204AArch64CC_NE = 0x1, // Not equal Not equal, or unordered205AArch64CC_HS = 0x2, // Unsigned higher or same >, ==, or unordered206AArch64CC_LO = 0x3, // Unsigned lower Less than207AArch64CC_MI = 0x4, // Minus, negative Less than208AArch64CC_PL = 0x5, // Plus, positive or zero >, ==, or unordered209AArch64CC_VS = 0x6, // Overflow Unordered210AArch64CC_VC = 0x7, // No overflow Not unordered211AArch64CC_HI = 0x8, // Unsigned higher Greater than, or unordered212AArch64CC_LS = 0x9, // Unsigned lower or same Less than or equal213AArch64CC_GE = 0xa, // Greater than or equal Greater than or equal214AArch64CC_LT = 0xb, // Less than Less than, or unordered215AArch64CC_GT = 0xc, // Greater than Greater than216AArch64CC_LE = 0xd, // Less than or equal <, ==, or unordered217AArch64CC_AL = 0xe, // Always (unconditional) Always (unconditional)218AArch64CC_NV = 0xf, // Always (unconditional) Always (unconditional)219// Note the NV exists purely to disassemble 0b1111. Execution is "always".220AArch64CC_Invalid221} AArch64CC_CondCode;222223inline static AArch64CC_CondCode getInvertedCondCode(AArch64CC_CondCode Code)224{225// To reverse a condition it's necessary to only invert the low bit:226return (AArch64CC_CondCode)((unsigned)Code ^ 0x1);227}228229inline static const char *getCondCodeName(AArch64CC_CondCode CC)230{231switch (CC) {232default: return NULL; // never reach233case AArch64CC_EQ: return "eq";234case AArch64CC_NE: return "ne";235case AArch64CC_HS: return "hs";236case AArch64CC_LO: return "lo";237case AArch64CC_MI: return "mi";238case AArch64CC_PL: return "pl";239case AArch64CC_VS: return "vs";240case AArch64CC_VC: return "vc";241case AArch64CC_HI: return "hi";242case AArch64CC_LS: return "ls";243case AArch64CC_GE: return "ge";244case AArch64CC_LT: return "lt";245case AArch64CC_GT: return "gt";246case AArch64CC_LE: return "le";247case AArch64CC_AL: return "al";248case AArch64CC_NV: return "nv";249}250}251252/// Given a condition code, return NZCV flags that would satisfy that condition.253/// The flag bits are in the format expected by the ccmp instructions.254/// Note that many different flag settings can satisfy a given condition code,255/// this function just returns one of them.256inline static unsigned getNZCVToSatisfyCondCode(AArch64CC_CondCode Code)257{258// NZCV flags encoded as expected by ccmp instructions, ARMv8 ISA 5.5.7.259enum { N = 8, Z = 4, C = 2, V = 1 };260switch (Code) {261default: // llvm_unreachable("Unknown condition code");262case AArch64CC_EQ: return Z; // Z == 1263case AArch64CC_NE: return 0; // Z == 0264case AArch64CC_HS: return C; // C == 1265case AArch64CC_LO: return 0; // C == 0266case AArch64CC_MI: return N; // N == 1267case AArch64CC_PL: return 0; // N == 0268case AArch64CC_VS: return V; // V == 1269case AArch64CC_VC: return 0; // V == 0270case AArch64CC_HI: return C; // C == 1 && Z == 0271case AArch64CC_LS: return 0; // C == 0 || Z == 1272case AArch64CC_GE: return 0; // N == V273case AArch64CC_LT: return N; // N != V274case AArch64CC_GT: return 0; // Z == 0 && N == V275case AArch64CC_LE: return Z; // Z == 1 || N != V276}277}278279/// Instances of this class can perform bidirectional mapping from random280/// identifier strings to operand encodings. For example "MSR" takes a named281/// system-register which must be encoded somehow and decoded for printing. This282/// central location means that the information for those transformations is not283/// duplicated and remains in sync.284///285/// FIXME: currently the algorithm is a completely unoptimised linear286/// search. Obviously this could be improved, but we would probably want to work287/// out just how often these instructions are emitted before working on it. It288/// might even be optimal to just reorder the tables for the common instructions289/// rather than changing the algorithm.290typedef struct A64NamedImmMapper_Mapping {291const char *Name;292uint32_t Value;293} A64NamedImmMapper_Mapping;294295typedef struct A64NamedImmMapper {296const A64NamedImmMapper_Mapping *Pairs;297size_t NumPairs;298uint32_t TooBigImm;299} A64NamedImmMapper;300301typedef struct A64SysRegMapper {302const A64NamedImmMapper_Mapping *SysRegPairs;303const A64NamedImmMapper_Mapping *InstPairs;304size_t NumInstPairs;305} A64SysRegMapper;306307typedef enum A64SE_ShiftExtSpecifiers {308A64SE_Invalid = -1,309A64SE_LSL,310A64SE_MSL,311A64SE_LSR,312A64SE_ASR,313A64SE_ROR,314315A64SE_UXTB,316A64SE_UXTH,317A64SE_UXTW,318A64SE_UXTX,319320A64SE_SXTB,321A64SE_SXTH,322A64SE_SXTW,323A64SE_SXTX324} A64SE_ShiftExtSpecifiers;325326typedef enum A64Layout_VectorLayout {327A64Layout_Invalid = -1,328A64Layout_VL_8B,329A64Layout_VL_4H,330A64Layout_VL_2S,331A64Layout_VL_1D,332333A64Layout_VL_16B,334A64Layout_VL_8H,335A64Layout_VL_4S,336A64Layout_VL_2D,337338// Bare layout for the 128-bit vector339// (only show ".b", ".h", ".s", ".d" without vector number)340A64Layout_VL_B,341A64Layout_VL_H,342A64Layout_VL_S,343A64Layout_VL_D344} A64Layout_VectorLayout;345346inline static const char *347AArch64VectorLayoutToString(A64Layout_VectorLayout Layout)348{349switch (Layout) {350default: return NULL; // never reach351case A64Layout_VL_8B: return ".8b";352case A64Layout_VL_4H: return ".4h";353case A64Layout_VL_2S: return ".2s";354case A64Layout_VL_1D: return ".1d";355case A64Layout_VL_16B: return ".16b";356case A64Layout_VL_8H: return ".8h";357case A64Layout_VL_4S: return ".4s";358case A64Layout_VL_2D: return ".2d";359case A64Layout_VL_B: return ".b";360case A64Layout_VL_H: return ".h";361case A64Layout_VL_S: return ".s";362case A64Layout_VL_D: return ".d";363}364}365366inline static A64Layout_VectorLayout367AArch64StringToVectorLayout(char *LayoutStr)368{369if (!strcmp(LayoutStr, ".8b"))370return A64Layout_VL_8B;371372if (!strcmp(LayoutStr, ".4h"))373return A64Layout_VL_4H;374375if (!strcmp(LayoutStr, ".2s"))376return A64Layout_VL_2S;377378if (!strcmp(LayoutStr, ".1d"))379return A64Layout_VL_1D;380381if (!strcmp(LayoutStr, ".16b"))382return A64Layout_VL_16B;383384if (!strcmp(LayoutStr, ".8h"))385return A64Layout_VL_8H;386387if (!strcmp(LayoutStr, ".4s"))388return A64Layout_VL_4S;389390if (!strcmp(LayoutStr, ".2d"))391return A64Layout_VL_2D;392393if (!strcmp(LayoutStr, ".b"))394return A64Layout_VL_B;395396if (!strcmp(LayoutStr, ".s"))397return A64Layout_VL_S;398399if (!strcmp(LayoutStr, ".d"))400return A64Layout_VL_D;401402return A64Layout_Invalid;403}404405/// Target Operand Flag enum.406enum TOF {407//===------------------------------------------------------------------===//408// AArch64 Specific MachineOperand flags.409410MO_NO_FLAG,411412MO_FRAGMENT = 0xf,413414/// MO_PAGE - A symbol operand with this flag represents the pc-relative415/// offset of the 4K page containing the symbol. This is used with the416/// ADRP instruction.417MO_PAGE = 1,418419/// MO_PAGEOFF - A symbol operand with this flag represents the offset of420/// that symbol within a 4K page. This offset is added to the page address421/// to produce the complete address.422MO_PAGEOFF = 2,423424/// MO_G3 - A symbol operand with this flag (granule 3) represents the high425/// 16-bits of a 64-bit address, used in a MOVZ or MOVK instruction426MO_G3 = 3,427428/// MO_G2 - A symbol operand with this flag (granule 2) represents the bits429/// 32-47 of a 64-bit address, used in a MOVZ or MOVK instruction430MO_G2 = 4,431432/// MO_G1 - A symbol operand with this flag (granule 1) represents the bits433/// 16-31 of a 64-bit address, used in a MOVZ or MOVK instruction434MO_G1 = 5,435436/// MO_G0 - A symbol operand with this flag (granule 0) represents the bits437/// 0-15 of a 64-bit address, used in a MOVZ or MOVK instruction438MO_G0 = 6,439440/// MO_HI12 - This flag indicates that a symbol operand represents the bits441/// 13-24 of a 64-bit address, used in a arithmetic immediate-shifted-left-442/// by-12-bits instruction.443MO_HI12 = 7,444445/// MO_GOT - This flag indicates that a symbol operand represents the446/// address of the GOT entry for the symbol, rather than the address of447/// the symbol itself.448MO_GOT = 0x10,449450/// MO_NC - Indicates whether the linker is expected to check the symbol451/// reference for overflow. For example in an ADRP/ADD pair of relocations452/// the ADRP usually does check, but not the ADD.453MO_NC = 0x20,454455/// MO_TLS - Indicates that the operand being accessed is some kind of456/// thread-local symbol. On Darwin, only one type of thread-local access457/// exists (pre linker-relaxation), but on ELF the TLSModel used for the458/// referee will affect interpretation.459MO_TLS = 0x40,460461/// MO_DLLIMPORT - On a symbol operand, this represents that the reference462/// to the symbol is for an import stub. This is used for DLL import463/// storage class indication on Windows.464MO_DLLIMPORT = 0x80,465};466467typedef struct SysAlias {468const char *Name;469uint16_t Encoding;470} SysAlias;471472#define AT SysAlias473#define DB SysAlias474#define DC SysAlias475#define SVEPRFM SysAlias476#define PRFM SysAlias477#define PSB SysAlias478#define ISB SysAlias479#define TSB SysAlias480#define PState SysAlias481#define SVEPREDPAT SysAlias482#define SVCR SysAlias483#define BTI SysAlias484485typedef struct SysAliasReg {486const char *Name;487uint16_t Encoding;488bool NeedsReg;489} SysAliasReg;490491#define IC SysAliasReg492#define TLBI SysAliasReg493494typedef struct SysAliasSysReg {495const char *Name;496uint16_t Encoding;497bool Readable;498bool Writeable;499} SysAliasSysReg;500501#define SysReg SysAliasSysReg502503typedef struct SysAliasImm {504const char *Name;505uint16_t Encoding;506uint16_t ImmValue;507} SysAliasImm;508509#define DBnXS SysAliasImm510511typedef struct ExactFPImm {512const char *Name;513int Enum;514const char *Repr;515} ExactFPImm;516517const AT *lookupATByEncoding(uint16_t Encoding);518const DB *lookupDBByEncoding(uint16_t Encoding);519const DC *lookupDCByEncoding(uint16_t Encoding);520const IC *lookupICByEncoding(uint16_t Encoding);521const TLBI *lookupTLBIByEncoding(uint16_t Encoding);522const SVEPRFM *lookupSVEPRFMByEncoding(uint16_t Encoding);523const PRFM *lookupPRFMByEncoding(uint16_t Encoding);524const PSB *lookupPSBByEncoding(uint16_t Encoding);525const ISB *lookupISBByEncoding(uint16_t Encoding);526const TSB *lookupTSBByEncoding(uint16_t Encoding);527const SysReg *lookupSysRegByEncoding(uint16_t Encoding);528const PState *lookupPStateByEncoding(uint16_t Encoding);529const SVEPREDPAT *lookupSVEPREDPATByEncoding(uint16_t Encoding);530const ExactFPImm *lookupExactFPImmByEnum(uint16_t Encoding);531const SVCR *lookupSVCRByEncoding(uint8_t Encoding);532const BTI *lookupBTIByEncoding(uint8_t Encoding);533const DBnXS *lookupDBnXSByEncoding(uint8_t Encoding);534535// NOTE: result must be 128 bytes to contain the result536void AArch64SysReg_genericRegisterString(uint32_t Bits, char *result);537538// ---------------------------------------------------------------------------539// The following Structs and Enum are taken from MCInstPrinter.h in llvm.540// These are required for the updated printAliasInstr() function in541// $ARCHGenAsmWriter.inc542543/// Map from opcode to pattern list by binary search.544typedef struct PatternsForOpcode {545uint32_t Opcode;546uint16_t PatternStart;547uint16_t NumPatterns;548} PatternsForOpcode;549550/// Data for each alias pattern. Includes feature bits, string, number of551/// operands, and a variadic list of conditions to check.552typedef struct AliasPattern {553uint32_t AsmStrOffset;554uint32_t AliasCondStart;555uint8_t NumOperands;556uint8_t NumConds;557} AliasPattern;558559enum CondKind {560AliasPatternCond_K_Feature, // Match only if a feature is enabled.561AliasPatternCond_K_NegFeature, // Match only if a feature is disabled.562AliasPatternCond_K_OrFeature, // Match only if one of a set of features is563// enabled.564AliasPatternCond_K_OrNegFeature, // Match only if one of a set of features is565// disabled.566AliasPatternCond_K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features.567AliasPatternCond_K_Ignore, // Match any operand.568AliasPatternCond_K_Reg, // Match a specific register.569AliasPatternCond_K_TiedReg, // Match another already matched register.570AliasPatternCond_K_Imm, // Match a specific immediate.571AliasPatternCond_K_RegClass, // Match registers in a class.572AliasPatternCond_K_Custom, // Call custom matcher by index.573};574575typedef struct AliasPatternCond {576int Kind;577uint32_t Value;578} AliasPatternCond;579580// ---------------------------------------------------------------------------581582#include "AArch64GenSystemOperands_enum.inc"583584#endif585586587