Path: blob/master/libs/capstone/arch/ARM/ARMBaseInfo.h
4395 views
//===-- ARMBaseInfo.h - Top level definitions for ARM -------- --*- 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 ARM 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_ARMBASEINFO_H20#define CS_ARMBASEINFO_H2122#include "capstone/arm.h"2324// Defines symbolic names for ARM registers. This defines a mapping from25// register name to register number.26//27#define GET_REGINFO_ENUM28#include "ARMGenRegisterInfo.inc"2930// Enums corresponding to ARM condition codes31// The CondCodes constants map directly to the 4-bit encoding of the32// condition field for predicated instructions.33typedef enum ARMCC_CondCodes { // Meaning (integer) Meaning (floating-point)34ARMCC_EQ, // Equal Equal35ARMCC_NE, // Not equal Not equal, or unordered36ARMCC_HS, // Carry set >, ==, or unordered37ARMCC_LO, // Carry clear Less than38ARMCC_MI, // Minus, negative Less than39ARMCC_PL, // Plus, positive or zero >, ==, or unordered40ARMCC_VS, // Overflow Unordered41ARMCC_VC, // No overflow Not unordered42ARMCC_HI, // Unsigned higher Greater than, or unordered43ARMCC_LS, // Unsigned lower or same Less than or equal44ARMCC_GE, // Greater than or equal Greater than or equal45ARMCC_LT, // Less than Less than, or unordered46ARMCC_GT, // Greater than Greater than47ARMCC_LE, // Less than or equal <, ==, or unordered48ARMCC_AL // Always (unconditional) Always (unconditional)49} ARMCC_CondCodes;5051inline static ARMCC_CondCodes ARMCC_getOppositeCondition(ARMCC_CondCodes CC)52{53switch (CC) {54case ARMCC_EQ: return ARMCC_NE;55case ARMCC_NE: return ARMCC_EQ;56case ARMCC_HS: return ARMCC_LO;57case ARMCC_LO: return ARMCC_HS;58case ARMCC_MI: return ARMCC_PL;59case ARMCC_PL: return ARMCC_MI;60case ARMCC_VS: return ARMCC_VC;61case ARMCC_VC: return ARMCC_VS;62case ARMCC_HI: return ARMCC_LS;63case ARMCC_LS: return ARMCC_HI;64case ARMCC_GE: return ARMCC_LT;65case ARMCC_LT: return ARMCC_GE;66case ARMCC_GT: return ARMCC_LE;67case ARMCC_LE: return ARMCC_GT;68default: return ARMCC_AL;69}70}7172inline static const char *ARMCC_ARMCondCodeToString(ARMCC_CondCodes CC)73{74switch (CC) {75case ARMCC_EQ: return "eq";76case ARMCC_NE: return "ne";77case ARMCC_HS: return "hs";78case ARMCC_LO: return "lo";79case ARMCC_MI: return "mi";80case ARMCC_PL: return "pl";81case ARMCC_VS: return "vs";82case ARMCC_VC: return "vc";83case ARMCC_HI: return "hi";84case ARMCC_LS: return "ls";85case ARMCC_GE: return "ge";86case ARMCC_LT: return "lt";87case ARMCC_GT: return "gt";88case ARMCC_LE: return "le";89case ARMCC_AL: return "al";90default: return "";91}92}9394inline static const char *ARM_PROC_IFlagsToString(unsigned val)95{96switch (val) {97case ARM_CPSFLAG_F: return "f";98case ARM_CPSFLAG_I: return "i";99case ARM_CPSFLAG_A: return "a";100default: return "";101}102}103104inline static const char *ARM_PROC_IModToString(unsigned val)105{106switch (val) {107case ARM_CPSMODE_IE: return "ie";108case ARM_CPSMODE_ID: return "id";109default: return "";110}111}112113inline static const char *ARM_MB_MemBOptToString(unsigned val, bool HasV8)114{115// TODO: add details116switch (val + 1) {117default: return "BUGBUG";118case ARM_MB_SY: return "sy";119case ARM_MB_ST: return "st";120case ARM_MB_LD: return HasV8 ? "ld" : "#0xd";121case ARM_MB_RESERVED_12: return "#0xc";122case ARM_MB_ISH: return "ish";123case ARM_MB_ISHST: return "ishst";124case ARM_MB_ISHLD: return HasV8 ? "ishld" : "#9";125case ARM_MB_RESERVED_8: return "#8";126case ARM_MB_NSH: return "nsh";127case ARM_MB_NSHST: return "nshst";128case ARM_MB_NSHLD: return HasV8 ? "nshld" : "#5";129case ARM_MB_RESERVED_4: return "#4";130case ARM_MB_OSH: return "osh";131case ARM_MB_OSHST: return "oshst";132case ARM_MB_OSHLD: return HasV8 ? "oshld" : "#1";133case ARM_MB_RESERVED_0: return "#0";134}135}136137enum ARM_ISB_InstSyncBOpt {138ARM_ISB_RESERVED_0 = 0,139ARM_ISB_RESERVED_1 = 1,140ARM_ISB_RESERVED_2 = 2,141ARM_ISB_RESERVED_3 = 3,142ARM_ISB_RESERVED_4 = 4,143ARM_ISB_RESERVED_5 = 5,144ARM_ISB_RESERVED_6 = 6,145ARM_ISB_RESERVED_7 = 7,146ARM_ISB_RESERVED_8 = 8,147ARM_ISB_RESERVED_9 = 9,148ARM_ISB_RESERVED_10 = 10,149ARM_ISB_RESERVED_11 = 11,150ARM_ISB_RESERVED_12 = 12,151ARM_ISB_RESERVED_13 = 13,152ARM_ISB_RESERVED_14 = 14,153ARM_ISB_SY = 15154};155156inline static const char *ARM_ISB_InstSyncBOptToString(unsigned val)157{158switch (val) {159default: // never reach160case ARM_ISB_RESERVED_0: return "#0x0";161case ARM_ISB_RESERVED_1: return "#0x1";162case ARM_ISB_RESERVED_2: return "#0x2";163case ARM_ISB_RESERVED_3: return "#0x3";164case ARM_ISB_RESERVED_4: return "#0x4";165case ARM_ISB_RESERVED_5: return "#0x5";166case ARM_ISB_RESERVED_6: return "#0x6";167case ARM_ISB_RESERVED_7: return "#0x7";168case ARM_ISB_RESERVED_8: return "#0x8";169case ARM_ISB_RESERVED_9: return "#0x9";170case ARM_ISB_RESERVED_10: return "#0xa";171case ARM_ISB_RESERVED_11: return "#0xb";172case ARM_ISB_RESERVED_12: return "#0xc";173case ARM_ISB_RESERVED_13: return "#0xd";174case ARM_ISB_RESERVED_14: return "#0xe";175case ARM_ISB_SY: return "sy";176}177}178179/// isARMLowRegister - Returns true if the register is a low register (r0-r7).180///181static inline bool isARMLowRegister(unsigned Reg)182{183//using namespace ARM;184switch (Reg) {185case ARM_R0: case ARM_R1: case ARM_R2: case ARM_R3:186case ARM_R4: case ARM_R5: case ARM_R6: case ARM_R7:187return true;188default:189return false;190}191}192193/// ARMII - This namespace holds all of the target specific flags that194/// instruction info tracks.195///196/// ARM Index Modes197enum ARMII_IndexMode {198ARMII_IndexModeNone = 0,199ARMII_IndexModePre = 1,200ARMII_IndexModePost = 2,201ARMII_IndexModeUpd = 3202};203204/// ARM Addressing Modes205typedef enum ARMII_AddrMode {206ARMII_AddrModeNone = 0,207ARMII_AddrMode1 = 1,208ARMII_AddrMode2 = 2,209ARMII_AddrMode3 = 3,210ARMII_AddrMode4 = 4,211ARMII_AddrMode5 = 5,212ARMII_AddrMode6 = 6,213ARMII_AddrModeT1_1 = 7,214ARMII_AddrModeT1_2 = 8,215ARMII_AddrModeT1_4 = 9,216ARMII_AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data217ARMII_AddrModeT2_i12 = 11,218ARMII_AddrModeT2_i8 = 12,219ARMII_AddrModeT2_so = 13,220ARMII_AddrModeT2_pc = 14, // +/- i12 for pc relative data221ARMII_AddrModeT2_i8s4 = 15, // i8 * 4222ARMII_AddrMode_i12 = 16223} ARMII_AddrMode;224225inline static const char *ARMII_AddrModeToString(ARMII_AddrMode addrmode)226{227switch (addrmode) {228case ARMII_AddrModeNone: return "AddrModeNone";229case ARMII_AddrMode1: return "AddrMode1";230case ARMII_AddrMode2: return "AddrMode2";231case ARMII_AddrMode3: return "AddrMode3";232case ARMII_AddrMode4: return "AddrMode4";233case ARMII_AddrMode5: return "AddrMode5";234case ARMII_AddrMode6: return "AddrMode6";235case ARMII_AddrModeT1_1: return "AddrModeT1_1";236case ARMII_AddrModeT1_2: return "AddrModeT1_2";237case ARMII_AddrModeT1_4: return "AddrModeT1_4";238case ARMII_AddrModeT1_s: return "AddrModeT1_s";239case ARMII_AddrModeT2_i12: return "AddrModeT2_i12";240case ARMII_AddrModeT2_i8: return "AddrModeT2_i8";241case ARMII_AddrModeT2_so: return "AddrModeT2_so";242case ARMII_AddrModeT2_pc: return "AddrModeT2_pc";243case ARMII_AddrModeT2_i8s4: return "AddrModeT2_i8s4";244case ARMII_AddrMode_i12: return "AddrMode_i12";245}246}247248/// Target Operand Flag enum.249enum ARMII_TOF {250//===------------------------------------------------------------------===//251// ARM Specific MachineOperand flags.252253ARMII_MO_NO_FLAG,254255/// MO_LO16 - On a symbol operand, this represents a relocation containing256/// lower 16 bit of the address. Used only via movw instruction.257ARMII_MO_LO16,258259/// MO_HI16 - On a symbol operand, this represents a relocation containing260/// higher 16 bit of the address. Used only via movt instruction.261ARMII_MO_HI16,262263/// MO_LO16_NONLAZY - On a symbol operand "FOO", this represents a264/// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,265/// i.e. "FOO$non_lazy_ptr".266/// Used only via movw instruction.267ARMII_MO_LO16_NONLAZY,268269/// MO_HI16_NONLAZY - On a symbol operand "FOO", this represents a270/// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,271/// i.e. "FOO$non_lazy_ptr". Used only via movt instruction.272ARMII_MO_HI16_NONLAZY,273274/// MO_LO16_NONLAZY_PIC - On a symbol operand "FOO", this represents a275/// relocation containing lower 16 bit of the PC relative address of the276/// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".277/// Used only via movw instruction.278ARMII_MO_LO16_NONLAZY_PIC,279280/// MO_HI16_NONLAZY_PIC - On a symbol operand "FOO", this represents a281/// relocation containing lower 16 bit of the PC relative address of the282/// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".283/// Used only via movt instruction.284ARMII_MO_HI16_NONLAZY_PIC,285286/// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a287/// call operand.288ARMII_MO_PLT289};290291enum {292//===------------------------------------------------------------------===//293// Instruction Flags.294295//===------------------------------------------------------------------===//296// This four-bit field describes the addressing mode used.297ARMII_AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h298299// IndexMode - Unindex, pre-indexed, or post-indexed are valid for load300// and store ops only. Generic "updating" flag is used for ld/st multiple.301// The index mode enums are declared in ARMBaseInfo.h302ARMII_IndexModeShift = 5,303ARMII_IndexModeMask = 3 << ARMII_IndexModeShift,304305//===------------------------------------------------------------------===//306// Instruction encoding formats.307//308ARMII_FormShift = 7,309ARMII_FormMask = 0x3f << ARMII_FormShift,310311// Pseudo instructions312ARMII_Pseudo = 0 << ARMII_FormShift,313314// Multiply instructions315ARMII_MulFrm = 1 << ARMII_FormShift,316317// Branch instructions318ARMII_BrFrm = 2 << ARMII_FormShift,319ARMII_BrMiscFrm = 3 << ARMII_FormShift,320321// Data Processing instructions322ARMII_DPFrm = 4 << ARMII_FormShift,323ARMII_DPSoRegFrm = 5 << ARMII_FormShift,324325// Load and Store326ARMII_LdFrm = 6 << ARMII_FormShift,327ARMII_StFrm = 7 << ARMII_FormShift,328ARMII_LdMiscFrm = 8 << ARMII_FormShift,329ARMII_StMiscFrm = 9 << ARMII_FormShift,330ARMII_LdStMulFrm = 10 << ARMII_FormShift,331332ARMII_LdStExFrm = 11 << ARMII_FormShift,333334// Miscellaneous arithmetic instructions335ARMII_ArithMiscFrm = 12 << ARMII_FormShift,336ARMII_SatFrm = 13 << ARMII_FormShift,337338// Extend instructions339ARMII_ExtFrm = 14 << ARMII_FormShift,340341// VFP formats342ARMII_VFPUnaryFrm = 15 << ARMII_FormShift,343ARMII_VFPBinaryFrm = 16 << ARMII_FormShift,344ARMII_VFPConv1Frm = 17 << ARMII_FormShift,345ARMII_VFPConv2Frm = 18 << ARMII_FormShift,346ARMII_VFPConv3Frm = 19 << ARMII_FormShift,347ARMII_VFPConv4Frm = 20 << ARMII_FormShift,348ARMII_VFPConv5Frm = 21 << ARMII_FormShift,349ARMII_VFPLdStFrm = 22 << ARMII_FormShift,350ARMII_VFPLdStMulFrm = 23 << ARMII_FormShift,351ARMII_VFPMiscFrm = 24 << ARMII_FormShift,352353// Thumb format354ARMII_ThumbFrm = 25 << ARMII_FormShift,355356// Miscelleaneous format357ARMII_MiscFrm = 26 << ARMII_FormShift,358359// NEON formats360ARMII_NGetLnFrm = 27 << ARMII_FormShift,361ARMII_NSetLnFrm = 28 << ARMII_FormShift,362ARMII_NDupFrm = 29 << ARMII_FormShift,363ARMII_NLdStFrm = 30 << ARMII_FormShift,364ARMII_N1RegModImmFrm= 31 << ARMII_FormShift,365ARMII_N2RegFrm = 32 << ARMII_FormShift,366ARMII_NVCVTFrm = 33 << ARMII_FormShift,367ARMII_NVDupLnFrm = 34 << ARMII_FormShift,368ARMII_N2RegVShLFrm = 35 << ARMII_FormShift,369ARMII_N2RegVShRFrm = 36 << ARMII_FormShift,370ARMII_N3RegFrm = 37 << ARMII_FormShift,371ARMII_N3RegVShFrm = 38 << ARMII_FormShift,372ARMII_NVExtFrm = 39 << ARMII_FormShift,373ARMII_NVMulSLFrm = 40 << ARMII_FormShift,374ARMII_NVTBLFrm = 41 << ARMII_FormShift,375376//===------------------------------------------------------------------===//377// Misc flags.378379// UnaryDP - Indicates this is a unary data processing instruction, i.e.380// it doesn't have a Rn operand.381ARMII_UnaryDP = 1 << 13,382383// Xform16Bit - Indicates this Thumb2 instruction may be transformed into384// a 16-bit Thumb instruction if certain conditions are met.385ARMII_Xform16Bit = 1 << 14,386387// ThumbArithFlagSetting - The instruction is a 16-bit flag setting Thumb388// instruction. Used by the parser to determine whether to require the 'S'389// suffix on the mnemonic (when not in an IT block) or preclude it (when390// in an IT block).391ARMII_ThumbArithFlagSetting = 1 << 18,392393//===------------------------------------------------------------------===//394// Code domain.395ARMII_DomainShift = 15,396ARMII_DomainMask = 7 << ARMII_DomainShift,397ARMII_DomainGeneral = 0 << ARMII_DomainShift,398ARMII_DomainVFP = 1 << ARMII_DomainShift,399ARMII_DomainNEON = 2 << ARMII_DomainShift,400ARMII_DomainNEONA8 = 4 << ARMII_DomainShift,401402//===------------------------------------------------------------------===//403// Field shifts - such shifts are used to set field while generating404// machine instructions.405//406// FIXME: This list will need adjusting/fixing as the MC code emitter407// takes shape and the ARMCodeEmitter.cpp bits go away.408ARMII_ShiftTypeShift = 4,409410ARMII_M_BitShift = 5,411ARMII_ShiftImmShift = 5,412ARMII_ShiftShift = 7,413ARMII_N_BitShift = 7,414ARMII_ImmHiShift = 8,415ARMII_SoRotImmShift = 8,416ARMII_RegRsShift = 8,417ARMII_ExtRotImmShift = 10,418ARMII_RegRdLoShift = 12,419ARMII_RegRdShift = 12,420ARMII_RegRdHiShift = 16,421ARMII_RegRnShift = 16,422ARMII_S_BitShift = 20,423ARMII_W_BitShift = 21,424ARMII_AM3_I_BitShift = 22,425ARMII_D_BitShift = 22,426ARMII_U_BitShift = 23,427ARMII_P_BitShift = 24,428ARMII_I_BitShift = 25,429ARMII_CondShift = 28430};431432typedef struct MClassSysReg {433const char *Name;434arm_sysreg sysreg;435uint16_t M1Encoding12;436uint16_t M2M3Encoding8;437uint16_t Encoding;438int FeaturesRequired[2]; // 2 is enough for MClassSysRegsList439} MClassSysReg;440441enum TraceSyncBOpt {442CSYNC = 0443};444445const MClassSysReg *lookupMClassSysRegByM2M3Encoding8(uint16_t encoding);446const MClassSysReg *lookupMClassSysRegByM1Encoding12(uint16_t M1Encoding12);447448// returns APSR with _<bits> qualifier.449// Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier450static inline const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm)451{452return lookupMClassSysRegByM2M3Encoding8((1<<9) | (SYSm & 0xFF));453}454455static inline const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm)456{457return lookupMClassSysRegByM2M3Encoding8((1<<8) | (SYSm & 0xFF));458}459460// returns true if TestFeatures are all present in FeaturesRequired461static inline bool MClassSysReg_isInRequiredFeatures(const MClassSysReg *TheReg, int TestFeatures)462{463return (TheReg->FeaturesRequired[0] == TestFeatures || TheReg->FeaturesRequired[1] == TestFeatures);464}465466// lookup system register using 12-bit SYSm value.467// Note: the search is uniqued using M1 mask468static inline const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm)469{470return lookupMClassSysRegByM1Encoding12(SYSm);471}472473static inline const char *ARM_TSB_TraceSyncBOptToString(unsigned val)474{475switch (val) {476default:477// llvm_unreachable("Unknown trace synchronization barrier operation");478return NULL;479480case CSYNC:481return "csync";482}483}484485#endif486487488