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