Home | History | Annotate | Download | only in ARM
      1 //===-- ARMBaseInfo.h - Top level definitions for ARM -------- --*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains small standalone helper functions and enum definitions for
     11 // the ARM target useful for the compiler back-end and the MC libraries.
     12 // As such, it deliberately does not include references to LLVM core
     13 // code gen types, passes, etc..
     14 //
     15 //===----------------------------------------------------------------------===//
     16 
     17 /* Capstone Disassembly Engine */
     18 /* By Nguyen Anh Quynh <aquynh (at) gmail.com>, 2013-2014 */
     19 
     20 #ifndef CS_ARMBASEINFO_H
     21 #define CS_ARMBASEINFO_H
     22 
     23 #include "../../include/arm.h"
     24 
     25 // Defines symbolic names for ARM registers.  This defines a mapping from
     26 // register name to register number.
     27 //
     28 #define GET_REGINFO_ENUM
     29 #include "ARMGenRegisterInfo.inc"
     30 
     31 // Enums corresponding to ARM condition codes
     32 // The CondCodes constants map directly to the 4-bit encoding of the
     33 // condition field for predicated instructions.
     34 typedef enum ARMCC_CondCodes { // Meaning (integer)          Meaning (floating-point)
     35 	ARMCC_EQ,            // Equal                      Equal
     36 	ARMCC_NE,            // Not equal                  Not equal, or unordered
     37 	ARMCC_HS,            // Carry set                  >, ==, or unordered
     38 	ARMCC_LO,            // Carry clear                Less than
     39 	ARMCC_MI,            // Minus, negative            Less than
     40 	ARMCC_PL,            // Plus, positive or zero     >, ==, or unordered
     41 	ARMCC_VS,            // Overflow                   Unordered
     42 	ARMCC_VC,            // No overflow                Not unordered
     43 	ARMCC_HI,            // Unsigned higher            Greater than, or unordered
     44 	ARMCC_LS,            // Unsigned lower or same     Less than or equal
     45 	ARMCC_GE,            // Greater than or equal      Greater than or equal
     46 	ARMCC_LT,            // Less than                  Less than, or unordered
     47 	ARMCC_GT,            // Greater than               Greater than
     48 	ARMCC_LE,            // Less than or equal         <, ==, or unordered
     49 	ARMCC_AL             // Always (unconditional)     Always (unconditional)
     50 } ARMCC_CondCodes;
     51 
     52 inline static ARMCC_CondCodes ARMCC_getOppositeCondition(ARMCC_CondCodes CC)
     53 {
     54 	switch (CC) {
     55 		case ARMCC_EQ: return ARMCC_NE;
     56 		case ARMCC_NE: return ARMCC_EQ;
     57 		case ARMCC_HS: return ARMCC_LO;
     58 		case ARMCC_LO: return ARMCC_HS;
     59 		case ARMCC_MI: return ARMCC_PL;
     60 		case ARMCC_PL: return ARMCC_MI;
     61 		case ARMCC_VS: return ARMCC_VC;
     62 		case ARMCC_VC: return ARMCC_VS;
     63 		case ARMCC_HI: return ARMCC_LS;
     64 		case ARMCC_LS: return ARMCC_HI;
     65 		case ARMCC_GE: return ARMCC_LT;
     66 		case ARMCC_LT: return ARMCC_GE;
     67 		case ARMCC_GT: return ARMCC_LE;
     68 		case ARMCC_LE: return ARMCC_GT;
     69 		default: return ARMCC_AL;
     70 	}
     71 }
     72 
     73 inline static char *ARMCC_ARMCondCodeToString(ARMCC_CondCodes CC)
     74 {
     75 	switch (CC) {
     76 		case ARMCC_EQ:  return "eq";
     77 		case ARMCC_NE:  return "ne";
     78 		case ARMCC_HS:  return "hs";
     79 		case ARMCC_LO:  return "lo";
     80 		case ARMCC_MI:  return "mi";
     81 		case ARMCC_PL:  return "pl";
     82 		case ARMCC_VS:  return "vs";
     83 		case ARMCC_VC:  return "vc";
     84 		case ARMCC_HI:  return "hi";
     85 		case ARMCC_LS:  return "ls";
     86 		case ARMCC_GE:  return "ge";
     87 		case ARMCC_LT:  return "lt";
     88 		case ARMCC_GT:  return "gt";
     89 		case ARMCC_LE:  return "le";
     90 		case ARMCC_AL:  return "al";
     91 		default: return "";
     92 	}
     93 }
     94 
     95 inline static char *ARM_PROC_IFlagsToString(unsigned val)
     96 {
     97 	switch (val) {
     98 		case ARM_CPSFLAG_F: return "f";
     99 		case ARM_CPSFLAG_I: return "i";
    100 		case ARM_CPSFLAG_A: return "a";
    101 		default: return "";
    102 	}
    103 }
    104 
    105 inline static char *ARM_PROC_IModToString(unsigned val)
    106 {
    107 	switch (val) {
    108 		case ARM_CPSMODE_IE: return "ie";
    109 		case ARM_CPSMODE_ID: return "id";
    110 		default: return "";
    111 	}
    112 }
    113 
    114 inline static char *ARM_MB_MemBOptToString(unsigned val, bool HasV8)
    115 {
    116 	switch (val) {
    117 		default: return "BUGBUG";
    118 		case ARM_MB_SY:    return "sy";
    119 		case ARM_MB_ST:    return "st";
    120 		case ARM_MB_LD: return HasV8 ? "ld" : "#0xd";
    121 		case ARM_MB_RESERVED_12: return "#0xc";
    122 		case ARM_MB_ISH:   return "ish";
    123 		case ARM_MB_ISHST: return "ishst";
    124 		case ARM_MB_ISHLD: return HasV8 ?  "ishld" : "#0x9";
    125 		case ARM_MB_RESERVED_8: return "#0x8";
    126 		case ARM_MB_NSH:   return "nsh";
    127 		case ARM_MB_NSHST: return "nshst";
    128 		case ARM_MB_NSHLD: return HasV8 ? "nshld" : "#0x5";
    129 		case ARM_MB_RESERVED_4: return "#0x4";
    130 		case ARM_MB_OSH:   return "osh";
    131 		case ARM_MB_OSHST: return "oshst";
    132 		case ARM_MB_OSHLD: return HasV8 ? "oshld" : "#0x1";
    133 		case ARM_MB_RESERVED_0: return "#0x0";
    134 	}
    135 }
    136 
    137 enum ARM_ISB_InstSyncBOpt {
    138     ARM_ISB_RESERVED_0 = 0,
    139     ARM_ISB_RESERVED_1 = 1,
    140     ARM_ISB_RESERVED_2 = 2,
    141     ARM_ISB_RESERVED_3 = 3,
    142     ARM_ISB_RESERVED_4 = 4,
    143     ARM_ISB_RESERVED_5 = 5,
    144     ARM_ISB_RESERVED_6 = 6,
    145     ARM_ISB_RESERVED_7 = 7,
    146     ARM_ISB_RESERVED_8 = 8,
    147     ARM_ISB_RESERVED_9 = 9,
    148     ARM_ISB_RESERVED_10 = 10,
    149     ARM_ISB_RESERVED_11 = 11,
    150     ARM_ISB_RESERVED_12 = 12,
    151     ARM_ISB_RESERVED_13 = 13,
    152     ARM_ISB_RESERVED_14 = 14,
    153     ARM_ISB_SY = 15
    154 };
    155 
    156 inline static char *ARM_ISB_InstSyncBOptToString(unsigned val)
    157 {
    158 	switch (val) {
    159 		default: // never reach
    160 		case ARM_ISB_RESERVED_0:  return "#0x0";
    161 		case ARM_ISB_RESERVED_1:  return "#0x1";
    162 		case ARM_ISB_RESERVED_2:  return "#0x2";
    163 		case ARM_ISB_RESERVED_3:  return "#0x3";
    164 		case ARM_ISB_RESERVED_4:  return "#0x4";
    165 		case ARM_ISB_RESERVED_5:  return "#0x5";
    166 		case ARM_ISB_RESERVED_6:  return "#0x6";
    167 		case ARM_ISB_RESERVED_7:  return "#0x7";
    168 		case ARM_ISB_RESERVED_8:  return "#0x8";
    169 		case ARM_ISB_RESERVED_9:  return "#0x9";
    170 		case ARM_ISB_RESERVED_10: return "#0xa";
    171 		case ARM_ISB_RESERVED_11: return "#0xb";
    172 		case ARM_ISB_RESERVED_12: return "#0xc";
    173 		case ARM_ISB_RESERVED_13: return "#0xd";
    174 		case ARM_ISB_RESERVED_14: return "#0xe";
    175 		case ARM_ISB_SY:          return "sy";
    176 	}
    177 }
    178 
    179 /// isARMLowRegister - Returns true if the register is a low register (r0-r7).
    180 ///
    181 static inline bool isARMLowRegister(unsigned Reg)
    182 {
    183 	//using namespace ARM;
    184 	switch (Reg) {
    185 		case ARM_R0:  case ARM_R1:  case ARM_R2:  case ARM_R3:
    186 		case ARM_R4:  case ARM_R5:  case ARM_R6:  case ARM_R7:
    187 			return true;
    188 		default:
    189 			return false;
    190 	}
    191 }
    192 
    193 /// ARMII - This namespace holds all of the target specific flags that
    194 /// instruction info tracks.
    195 ///
    196 /// ARM Index Modes
    197 enum ARMII_IndexMode {
    198 	ARMII_IndexModeNone  = 0,
    199 	ARMII_IndexModePre   = 1,
    200 	ARMII_IndexModePost  = 2,
    201 	ARMII_IndexModeUpd   = 3
    202 };
    203 
    204 /// ARM Addressing Modes
    205 typedef enum ARMII_AddrMode {
    206 	ARMII_AddrModeNone    = 0,
    207 	ARMII_AddrMode1       = 1,
    208 	ARMII_AddrMode2       = 2,
    209 	ARMII_AddrMode3       = 3,
    210 	ARMII_AddrMode4       = 4,
    211 	ARMII_AddrMode5       = 5,
    212 	ARMII_AddrMode6       = 6,
    213 	ARMII_AddrModeT1_1    = 7,
    214 	ARMII_AddrModeT1_2    = 8,
    215 	ARMII_AddrModeT1_4    = 9,
    216 	ARMII_AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
    217 	ARMII_AddrModeT2_i12  = 11,
    218 	ARMII_AddrModeT2_i8   = 12,
    219 	ARMII_AddrModeT2_so   = 13,
    220 	ARMII_AddrModeT2_pc   = 14, // +/- i12 for pc relative data
    221 	ARMII_AddrModeT2_i8s4 = 15, // i8 * 4
    222 	ARMII_AddrMode_i12    = 16
    223 } ARMII_AddrMode;
    224 
    225 inline static char *ARMII_AddrModeToString(ARMII_AddrMode addrmode)
    226 {
    227 	switch (addrmode) {
    228 		case ARMII_AddrModeNone:    return "AddrModeNone";
    229 		case ARMII_AddrMode1:       return "AddrMode1";
    230 		case ARMII_AddrMode2:       return "AddrMode2";
    231 		case ARMII_AddrMode3:       return "AddrMode3";
    232 		case ARMII_AddrMode4:       return "AddrMode4";
    233 		case ARMII_AddrMode5:       return "AddrMode5";
    234 		case ARMII_AddrMode6:       return "AddrMode6";
    235 		case ARMII_AddrModeT1_1:    return "AddrModeT1_1";
    236 		case ARMII_AddrModeT1_2:    return "AddrModeT1_2";
    237 		case ARMII_AddrModeT1_4:    return "AddrModeT1_4";
    238 		case ARMII_AddrModeT1_s:    return "AddrModeT1_s";
    239 		case ARMII_AddrModeT2_i12:  return "AddrModeT2_i12";
    240 		case ARMII_AddrModeT2_i8:   return "AddrModeT2_i8";
    241 		case ARMII_AddrModeT2_so:   return "AddrModeT2_so";
    242 		case ARMII_AddrModeT2_pc:   return "AddrModeT2_pc";
    243 		case ARMII_AddrModeT2_i8s4: return "AddrModeT2_i8s4";
    244 		case ARMII_AddrMode_i12:    return "AddrMode_i12";
    245 	}
    246 }
    247 
    248 /// Target Operand Flag enum.
    249 enum ARMII_TOF {
    250 	//===------------------------------------------------------------------===//
    251 	// ARM Specific MachineOperand flags.
    252 
    253 	ARMII_MO_NO_FLAG,
    254 
    255 	/// MO_LO16 - On a symbol operand, this represents a relocation containing
    256 	/// lower 16 bit of the address. Used only via movw instruction.
    257 	ARMII_MO_LO16,
    258 
    259 	/// MO_HI16 - On a symbol operand, this represents a relocation containing
    260 	/// higher 16 bit of the address. Used only via movt instruction.
    261 	ARMII_MO_HI16,
    262 
    263 	/// MO_LO16_NONLAZY - On a symbol operand "FOO", this represents a
    264 	/// 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.
    267 	ARMII_MO_LO16_NONLAZY,
    268 
    269 	/// MO_HI16_NONLAZY - On a symbol operand "FOO", this represents a
    270 	/// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol,
    271 	/// i.e. "FOO$non_lazy_ptr". Used only via movt instruction.
    272 	ARMII_MO_HI16_NONLAZY,
    273 
    274 	/// MO_LO16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
    275 	/// relocation containing lower 16 bit of the PC relative address of the
    276 	/// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
    277 	/// Used only via movw instruction.
    278 	ARMII_MO_LO16_NONLAZY_PIC,
    279 
    280 	/// MO_HI16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
    281 	/// relocation containing lower 16 bit of the PC relative address of the
    282 	/// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
    283 	/// Used only via movt instruction.
    284 	ARMII_MO_HI16_NONLAZY_PIC,
    285 
    286 	/// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a
    287 	/// call operand.
    288 	ARMII_MO_PLT
    289 };
    290 
    291 enum {
    292 	//===------------------------------------------------------------------===//
    293 	// Instruction Flags.
    294 
    295 	//===------------------------------------------------------------------===//
    296 	// This four-bit field describes the addressing mode used.
    297 	ARMII_AddrModeMask  = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
    298 
    299 	// IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
    300 	// and store ops only.  Generic "updating" flag is used for ld/st multiple.
    301 	// The index mode enums are declared in ARMBaseInfo.h
    302 	ARMII_IndexModeShift = 5,
    303 	ARMII_IndexModeMask  = 3 << ARMII_IndexModeShift,
    304 
    305 	//===------------------------------------------------------------------===//
    306 	// Instruction encoding formats.
    307 	//
    308 	ARMII_FormShift     = 7,
    309 	ARMII_FormMask      = 0x3f << ARMII_FormShift,
    310 
    311 	// Pseudo instructions
    312 	ARMII_Pseudo        = 0  << ARMII_FormShift,
    313 
    314 	// Multiply instructions
    315 	ARMII_MulFrm        = 1  << ARMII_FormShift,
    316 
    317 	// Branch instructions
    318 	ARMII_BrFrm         = 2  << ARMII_FormShift,
    319 	ARMII_BrMiscFrm     = 3  << ARMII_FormShift,
    320 
    321 	// Data Processing instructions
    322 	ARMII_DPFrm         = 4  << ARMII_FormShift,
    323 	ARMII_DPSoRegFrm    = 5  << ARMII_FormShift,
    324 
    325 	// Load and Store
    326 	ARMII_LdFrm         = 6  << ARMII_FormShift,
    327 	ARMII_StFrm         = 7  << ARMII_FormShift,
    328 	ARMII_LdMiscFrm     = 8  << ARMII_FormShift,
    329 	ARMII_StMiscFrm     = 9  << ARMII_FormShift,
    330 	ARMII_LdStMulFrm    = 10 << ARMII_FormShift,
    331 
    332 	ARMII_LdStExFrm     = 11 << ARMII_FormShift,
    333 
    334 	// Miscellaneous arithmetic instructions
    335 	ARMII_ArithMiscFrm  = 12 << ARMII_FormShift,
    336 	ARMII_SatFrm        = 13 << ARMII_FormShift,
    337 
    338 	// Extend instructions
    339 	ARMII_ExtFrm        = 14 << ARMII_FormShift,
    340 
    341 	// VFP formats
    342 	ARMII_VFPUnaryFrm   = 15 << ARMII_FormShift,
    343 	ARMII_VFPBinaryFrm  = 16 << ARMII_FormShift,
    344 	ARMII_VFPConv1Frm   = 17 << ARMII_FormShift,
    345 	ARMII_VFPConv2Frm   = 18 << ARMII_FormShift,
    346 	ARMII_VFPConv3Frm   = 19 << ARMII_FormShift,
    347 	ARMII_VFPConv4Frm   = 20 << ARMII_FormShift,
    348 	ARMII_VFPConv5Frm   = 21 << ARMII_FormShift,
    349 	ARMII_VFPLdStFrm    = 22 << ARMII_FormShift,
    350 	ARMII_VFPLdStMulFrm = 23 << ARMII_FormShift,
    351 	ARMII_VFPMiscFrm    = 24 << ARMII_FormShift,
    352 
    353 	// Thumb format
    354 	ARMII_ThumbFrm      = 25 << ARMII_FormShift,
    355 
    356 	// Miscelleaneous format
    357 	ARMII_MiscFrm       = 26 << ARMII_FormShift,
    358 
    359 	// NEON formats
    360 	ARMII_NGetLnFrm     = 27 << ARMII_FormShift,
    361 	ARMII_NSetLnFrm     = 28 << ARMII_FormShift,
    362 	ARMII_NDupFrm       = 29 << ARMII_FormShift,
    363 	ARMII_NLdStFrm      = 30 << ARMII_FormShift,
    364 	ARMII_N1RegModImmFrm= 31 << ARMII_FormShift,
    365 	ARMII_N2RegFrm      = 32 << ARMII_FormShift,
    366 	ARMII_NVCVTFrm      = 33 << ARMII_FormShift,
    367 	ARMII_NVDupLnFrm    = 34 << ARMII_FormShift,
    368 	ARMII_N2RegVShLFrm  = 35 << ARMII_FormShift,
    369 	ARMII_N2RegVShRFrm  = 36 << ARMII_FormShift,
    370 	ARMII_N3RegFrm      = 37 << ARMII_FormShift,
    371 	ARMII_N3RegVShFrm   = 38 << ARMII_FormShift,
    372 	ARMII_NVExtFrm      = 39 << ARMII_FormShift,
    373 	ARMII_NVMulSLFrm    = 40 << ARMII_FormShift,
    374 	ARMII_NVTBLFrm      = 41 << ARMII_FormShift,
    375 
    376 	//===------------------------------------------------------------------===//
    377 	// Misc flags.
    378 
    379 	// UnaryDP - Indicates this is a unary data processing instruction, i.e.
    380 	// it doesn't have a Rn operand.
    381 	ARMII_UnaryDP       = 1 << 13,
    382 
    383 	// Xform16Bit - Indicates this Thumb2 instruction may be transformed into
    384 	// a 16-bit Thumb instruction if certain conditions are met.
    385 	ARMII_Xform16Bit    = 1 << 14,
    386 
    387 	// ThumbArithFlagSetting - The instruction is a 16-bit flag setting Thumb
    388 	// 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 (when
    390 	// in an IT block).
    391 	ARMII_ThumbArithFlagSetting = 1 << 18,
    392 
    393 	//===------------------------------------------------------------------===//
    394 	// Code domain.
    395 	ARMII_DomainShift   = 15,
    396 	ARMII_DomainMask    = 7 << ARMII_DomainShift,
    397 	ARMII_DomainGeneral = 0 << ARMII_DomainShift,
    398 	ARMII_DomainVFP     = 1 << ARMII_DomainShift,
    399 	ARMII_DomainNEON    = 2 << ARMII_DomainShift,
    400 	ARMII_DomainNEONA8  = 4 << ARMII_DomainShift,
    401 
    402 	//===------------------------------------------------------------------===//
    403 	// Field shifts - such shifts are used to set field while generating
    404 	// machine instructions.
    405 	//
    406 	// FIXME: This list will need adjusting/fixing as the MC code emitter
    407 	// takes shape and the ARMCodeEmitter.cpp bits go away.
    408 	ARMII_ShiftTypeShift = 4,
    409 
    410 	ARMII_M_BitShift     = 5,
    411 	ARMII_ShiftImmShift  = 5,
    412 	ARMII_ShiftShift     = 7,
    413 	ARMII_N_BitShift     = 7,
    414 	ARMII_ImmHiShift     = 8,
    415 	ARMII_SoRotImmShift  = 8,
    416 	ARMII_RegRsShift     = 8,
    417 	ARMII_ExtRotImmShift = 10,
    418 	ARMII_RegRdLoShift   = 12,
    419 	ARMII_RegRdShift     = 12,
    420 	ARMII_RegRdHiShift   = 16,
    421 	ARMII_RegRnShift     = 16,
    422 	ARMII_S_BitShift     = 20,
    423 	ARMII_W_BitShift     = 21,
    424 	ARMII_AM3_I_BitShift = 22,
    425 	ARMII_D_BitShift     = 22,
    426 	ARMII_U_BitShift     = 23,
    427 	ARMII_P_BitShift     = 24,
    428 	ARMII_I_BitShift     = 25,
    429 	ARMII_CondShift      = 28
    430 };
    431 
    432 #endif
    433