1226584Sdim//===-- ARMBaseInfo.h - Top level definitions for ARM -------- --*- C++ -*-===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim// 10226584Sdim// This file contains small standalone helper functions and enum definitions for 11226584Sdim// the ARM target useful for the compiler back-end and the MC libraries. 12226584Sdim// As such, it deliberately does not include references to LLVM core 13226584Sdim// code gen types, passes, etc.. 14226584Sdim// 15226584Sdim//===----------------------------------------------------------------------===// 16226584Sdim 17226584Sdim#ifndef ARMBASEINFO_H 18226584Sdim#define ARMBASEINFO_H 19226584Sdim 20226584Sdim#include "ARMMCTargetDesc.h" 21226584Sdim#include "llvm/Support/ErrorHandling.h" 22226584Sdim 23226584Sdimnamespace llvm { 24226584Sdim 25226584Sdim// Enums corresponding to ARM condition codes 26226584Sdimnamespace ARMCC { 27226584Sdim // The CondCodes constants map directly to the 4-bit encoding of the 28226584Sdim // condition field for predicated instructions. 29226584Sdim enum CondCodes { // Meaning (integer) Meaning (floating-point) 30226584Sdim EQ, // Equal Equal 31226584Sdim NE, // Not equal Not equal, or unordered 32226584Sdim HS, // Carry set >, ==, or unordered 33226584Sdim LO, // Carry clear Less than 34226584Sdim MI, // Minus, negative Less than 35226584Sdim PL, // Plus, positive or zero >, ==, or unordered 36226584Sdim VS, // Overflow Unordered 37226584Sdim VC, // No overflow Not unordered 38226584Sdim HI, // Unsigned higher Greater than, or unordered 39226584Sdim LS, // Unsigned lower or same Less than or equal 40226584Sdim GE, // Greater than or equal Greater than or equal 41226584Sdim LT, // Less than Less than, or unordered 42226584Sdim GT, // Greater than Greater than 43226584Sdim LE, // Less than or equal <, ==, or unordered 44226584Sdim AL // Always (unconditional) Always (unconditional) 45226584Sdim }; 46226584Sdim 47226584Sdim inline static CondCodes getOppositeCondition(CondCodes CC) { 48226584Sdim switch (CC) { 49226584Sdim default: llvm_unreachable("Unknown condition code"); 50226584Sdim case EQ: return NE; 51226584Sdim case NE: return EQ; 52226584Sdim case HS: return LO; 53226584Sdim case LO: return HS; 54226584Sdim case MI: return PL; 55226584Sdim case PL: return MI; 56226584Sdim case VS: return VC; 57226584Sdim case VC: return VS; 58226584Sdim case HI: return LS; 59226584Sdim case LS: return HI; 60226584Sdim case GE: return LT; 61226584Sdim case LT: return GE; 62226584Sdim case GT: return LE; 63226584Sdim case LE: return GT; 64226584Sdim } 65226584Sdim } 66226584Sdim} // namespace ARMCC 67226584Sdim 68226584Sdiminline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) { 69226584Sdim switch (CC) { 70226584Sdim case ARMCC::EQ: return "eq"; 71226584Sdim case ARMCC::NE: return "ne"; 72226584Sdim case ARMCC::HS: return "hs"; 73226584Sdim case ARMCC::LO: return "lo"; 74226584Sdim case ARMCC::MI: return "mi"; 75226584Sdim case ARMCC::PL: return "pl"; 76226584Sdim case ARMCC::VS: return "vs"; 77226584Sdim case ARMCC::VC: return "vc"; 78226584Sdim case ARMCC::HI: return "hi"; 79226584Sdim case ARMCC::LS: return "ls"; 80226584Sdim case ARMCC::GE: return "ge"; 81226584Sdim case ARMCC::LT: return "lt"; 82226584Sdim case ARMCC::GT: return "gt"; 83226584Sdim case ARMCC::LE: return "le"; 84226584Sdim case ARMCC::AL: return "al"; 85226584Sdim } 86234353Sdim llvm_unreachable("Unknown condition code"); 87226584Sdim} 88226584Sdim 89226584Sdimnamespace ARM_PROC { 90226584Sdim enum IMod { 91226584Sdim IE = 2, 92226584Sdim ID = 3 93226584Sdim }; 94226584Sdim 95226584Sdim enum IFlags { 96226584Sdim F = 1, 97226584Sdim I = 2, 98226584Sdim A = 4 99226584Sdim }; 100226584Sdim 101226584Sdim inline static const char *IFlagsToString(unsigned val) { 102226584Sdim switch (val) { 103226584Sdim default: llvm_unreachable("Unknown iflags operand"); 104226584Sdim case F: return "f"; 105226584Sdim case I: return "i"; 106226584Sdim case A: return "a"; 107226584Sdim } 108226584Sdim } 109226584Sdim 110226584Sdim inline static const char *IModToString(unsigned val) { 111226584Sdim switch (val) { 112226584Sdim default: llvm_unreachable("Unknown imod operand"); 113226584Sdim case IE: return "ie"; 114226584Sdim case ID: return "id"; 115226584Sdim } 116226584Sdim } 117226584Sdim} 118226584Sdim 119226584Sdimnamespace ARM_MB { 120226584Sdim // The Memory Barrier Option constants map directly to the 4-bit encoding of 121226584Sdim // the option field for memory barrier operations. 122226584Sdim enum MemBOpt { 123239462Sdim RESERVED_0 = 0, 124263508Sdim OSHLD = 1, 125239462Sdim OSHST = 2, 126239462Sdim OSH = 3, 127239462Sdim RESERVED_4 = 4, 128263508Sdim NSHLD = 5, 129239462Sdim NSHST = 6, 130239462Sdim NSH = 7, 131239462Sdim RESERVED_8 = 8, 132263508Sdim ISHLD = 9, 133239462Sdim ISHST = 10, 134239462Sdim ISH = 11, 135239462Sdim RESERVED_12 = 12, 136263508Sdim LD = 13, 137226584Sdim ST = 14, 138239462Sdim SY = 15 139226584Sdim }; 140226584Sdim 141263508Sdim inline static const char *MemBOptToString(unsigned val, bool HasV8) { 142226584Sdim switch (val) { 143226584Sdim default: llvm_unreachable("Unknown memory operation"); 144226584Sdim case SY: return "sy"; 145226584Sdim case ST: return "st"; 146263508Sdim case LD: return HasV8 ? "ld" : "#0xd"; 147239462Sdim case RESERVED_12: return "#0xc"; 148226584Sdim case ISH: return "ish"; 149226584Sdim case ISHST: return "ishst"; 150263508Sdim case ISHLD: return HasV8 ? "ishld" : "#0x9"; 151239462Sdim case RESERVED_8: return "#0x8"; 152226584Sdim case NSH: return "nsh"; 153226584Sdim case NSHST: return "nshst"; 154263508Sdim case NSHLD: return HasV8 ? "nshld" : "#0x5"; 155239462Sdim case RESERVED_4: return "#0x4"; 156226584Sdim case OSH: return "osh"; 157226584Sdim case OSHST: return "oshst"; 158263508Sdim case OSHLD: return HasV8 ? "oshld" : "#0x1"; 159239462Sdim case RESERVED_0: return "#0x0"; 160226584Sdim } 161226584Sdim } 162226584Sdim} // namespace ARM_MB 163226584Sdim 164263508Sdimnamespace ARM_ISB { 165263508Sdim enum InstSyncBOpt { 166263508Sdim RESERVED_0 = 0, 167263508Sdim RESERVED_1 = 1, 168263508Sdim RESERVED_2 = 2, 169263508Sdim RESERVED_3 = 3, 170263508Sdim RESERVED_4 = 4, 171263508Sdim RESERVED_5 = 5, 172263508Sdim RESERVED_6 = 6, 173263508Sdim RESERVED_7 = 7, 174263508Sdim RESERVED_8 = 8, 175263508Sdim RESERVED_9 = 9, 176263508Sdim RESERVED_10 = 10, 177263508Sdim RESERVED_11 = 11, 178263508Sdim RESERVED_12 = 12, 179263508Sdim RESERVED_13 = 13, 180263508Sdim RESERVED_14 = 14, 181263508Sdim SY = 15 182263508Sdim }; 183263508Sdim 184263508Sdim inline static const char *InstSyncBOptToString(unsigned val) { 185263508Sdim switch (val) { 186263508Sdim default: llvm_unreachable("Unkown memory operation"); 187263508Sdim case RESERVED_0: return "#0x0"; 188263508Sdim case RESERVED_1: return "#0x1"; 189263508Sdim case RESERVED_2: return "#0x2"; 190263508Sdim case RESERVED_3: return "#0x3"; 191263508Sdim case RESERVED_4: return "#0x4"; 192263508Sdim case RESERVED_5: return "#0x5"; 193263508Sdim case RESERVED_6: return "#0x6"; 194263508Sdim case RESERVED_7: return "#0x7"; 195263508Sdim case RESERVED_8: return "#0x8"; 196263508Sdim case RESERVED_9: return "#0x9"; 197263508Sdim case RESERVED_10: return "#0xa"; 198263508Sdim case RESERVED_11: return "#0xb"; 199263508Sdim case RESERVED_12: return "#0xc"; 200263508Sdim case RESERVED_13: return "#0xd"; 201263508Sdim case RESERVED_14: return "#0xe"; 202263508Sdim case SY: return "sy"; 203263508Sdim } 204263508Sdim } 205263508Sdim} // namespace ARM_ISB 206263508Sdim 207226584Sdim/// isARMLowRegister - Returns true if the register is a low register (r0-r7). 208226584Sdim/// 209226584Sdimstatic inline bool isARMLowRegister(unsigned Reg) { 210226584Sdim using namespace ARM; 211226584Sdim switch (Reg) { 212226584Sdim case R0: case R1: case R2: case R3: 213226584Sdim case R4: case R5: case R6: case R7: 214226584Sdim return true; 215226584Sdim default: 216226584Sdim return false; 217226584Sdim } 218226584Sdim} 219226584Sdim 220226584Sdim/// ARMII - This namespace holds all of the target specific flags that 221226584Sdim/// instruction info tracks. 222226584Sdim/// 223226584Sdimnamespace ARMII { 224226584Sdim 225226584Sdim /// ARM Index Modes 226226584Sdim enum IndexMode { 227226584Sdim IndexModeNone = 0, 228226584Sdim IndexModePre = 1, 229226584Sdim IndexModePost = 2, 230226584Sdim IndexModeUpd = 3 231226584Sdim }; 232226584Sdim 233226584Sdim /// ARM Addressing Modes 234226584Sdim enum AddrMode { 235226584Sdim AddrModeNone = 0, 236226584Sdim AddrMode1 = 1, 237226584Sdim AddrMode2 = 2, 238226584Sdim AddrMode3 = 3, 239226584Sdim AddrMode4 = 4, 240226584Sdim AddrMode5 = 5, 241226584Sdim AddrMode6 = 6, 242226584Sdim AddrModeT1_1 = 7, 243226584Sdim AddrModeT1_2 = 8, 244226584Sdim AddrModeT1_4 = 9, 245226584Sdim AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data 246226584Sdim AddrModeT2_i12 = 11, 247226584Sdim AddrModeT2_i8 = 12, 248226584Sdim AddrModeT2_so = 13, 249226584Sdim AddrModeT2_pc = 14, // +/- i12 for pc relative data 250226584Sdim AddrModeT2_i8s4 = 15, // i8 * 4 251226584Sdim AddrMode_i12 = 16 252226584Sdim }; 253226584Sdim 254226584Sdim inline static const char *AddrModeToString(AddrMode addrmode) { 255226584Sdim switch (addrmode) { 256226584Sdim case AddrModeNone: return "AddrModeNone"; 257226584Sdim case AddrMode1: return "AddrMode1"; 258226584Sdim case AddrMode2: return "AddrMode2"; 259226584Sdim case AddrMode3: return "AddrMode3"; 260226584Sdim case AddrMode4: return "AddrMode4"; 261226584Sdim case AddrMode5: return "AddrMode5"; 262226584Sdim case AddrMode6: return "AddrMode6"; 263226584Sdim case AddrModeT1_1: return "AddrModeT1_1"; 264226584Sdim case AddrModeT1_2: return "AddrModeT1_2"; 265226584Sdim case AddrModeT1_4: return "AddrModeT1_4"; 266226584Sdim case AddrModeT1_s: return "AddrModeT1_s"; 267226584Sdim case AddrModeT2_i12: return "AddrModeT2_i12"; 268226584Sdim case AddrModeT2_i8: return "AddrModeT2_i8"; 269226584Sdim case AddrModeT2_so: return "AddrModeT2_so"; 270226584Sdim case AddrModeT2_pc: return "AddrModeT2_pc"; 271226584Sdim case AddrModeT2_i8s4: return "AddrModeT2_i8s4"; 272226584Sdim case AddrMode_i12: return "AddrMode_i12"; 273226584Sdim } 274226584Sdim } 275226584Sdim 276226584Sdim /// Target Operand Flag enum. 277226584Sdim enum TOF { 278226584Sdim //===------------------------------------------------------------------===// 279226584Sdim // ARM Specific MachineOperand flags. 280226584Sdim 281226584Sdim MO_NO_FLAG, 282226584Sdim 283226584Sdim /// MO_LO16 - On a symbol operand, this represents a relocation containing 284226584Sdim /// lower 16 bit of the address. Used only via movw instruction. 285226584Sdim MO_LO16, 286226584Sdim 287226584Sdim /// MO_HI16 - On a symbol operand, this represents a relocation containing 288226584Sdim /// higher 16 bit of the address. Used only via movt instruction. 289226584Sdim MO_HI16, 290226584Sdim 291226584Sdim /// MO_LO16_NONLAZY - On a symbol operand "FOO", this represents a 292226584Sdim /// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol, 293226584Sdim /// i.e. "FOO$non_lazy_ptr". 294226584Sdim /// Used only via movw instruction. 295226584Sdim MO_LO16_NONLAZY, 296226584Sdim 297226584Sdim /// MO_HI16_NONLAZY - On a symbol operand "FOO", this represents a 298226584Sdim /// relocation containing lower 16 bit of the non-lazy-ptr indirect symbol, 299226584Sdim /// i.e. "FOO$non_lazy_ptr". Used only via movt instruction. 300226584Sdim MO_HI16_NONLAZY, 301226584Sdim 302226584Sdim /// MO_LO16_NONLAZY_PIC - On a symbol operand "FOO", this represents a 303226584Sdim /// relocation containing lower 16 bit of the PC relative address of the 304226584Sdim /// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL". 305226584Sdim /// Used only via movw instruction. 306226584Sdim MO_LO16_NONLAZY_PIC, 307226584Sdim 308226584Sdim /// MO_HI16_NONLAZY_PIC - On a symbol operand "FOO", this represents a 309226584Sdim /// relocation containing lower 16 bit of the PC relative address of the 310226584Sdim /// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL". 311226584Sdim /// Used only via movt instruction. 312226584Sdim MO_HI16_NONLAZY_PIC, 313226584Sdim 314226584Sdim /// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a 315226584Sdim /// call operand. 316226584Sdim MO_PLT 317226584Sdim }; 318226584Sdim 319226584Sdim enum { 320226584Sdim //===------------------------------------------------------------------===// 321226584Sdim // Instruction Flags. 322226584Sdim 323226584Sdim //===------------------------------------------------------------------===// 324226584Sdim // This four-bit field describes the addressing mode used. 325226584Sdim AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h 326226584Sdim 327226584Sdim // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load 328226584Sdim // and store ops only. Generic "updating" flag is used for ld/st multiple. 329226584Sdim // The index mode enums are declared in ARMBaseInfo.h 330226584Sdim IndexModeShift = 5, 331226584Sdim IndexModeMask = 3 << IndexModeShift, 332226584Sdim 333226584Sdim //===------------------------------------------------------------------===// 334226584Sdim // Instruction encoding formats. 335226584Sdim // 336226584Sdim FormShift = 7, 337226584Sdim FormMask = 0x3f << FormShift, 338226584Sdim 339226584Sdim // Pseudo instructions 340226584Sdim Pseudo = 0 << FormShift, 341226584Sdim 342226584Sdim // Multiply instructions 343226584Sdim MulFrm = 1 << FormShift, 344226584Sdim 345226584Sdim // Branch instructions 346226584Sdim BrFrm = 2 << FormShift, 347226584Sdim BrMiscFrm = 3 << FormShift, 348226584Sdim 349226584Sdim // Data Processing instructions 350226584Sdim DPFrm = 4 << FormShift, 351226584Sdim DPSoRegFrm = 5 << FormShift, 352226584Sdim 353226584Sdim // Load and Store 354226584Sdim LdFrm = 6 << FormShift, 355226584Sdim StFrm = 7 << FormShift, 356226584Sdim LdMiscFrm = 8 << FormShift, 357226584Sdim StMiscFrm = 9 << FormShift, 358226584Sdim LdStMulFrm = 10 << FormShift, 359226584Sdim 360226584Sdim LdStExFrm = 11 << FormShift, 361226584Sdim 362226584Sdim // Miscellaneous arithmetic instructions 363226584Sdim ArithMiscFrm = 12 << FormShift, 364226584Sdim SatFrm = 13 << FormShift, 365226584Sdim 366226584Sdim // Extend instructions 367226584Sdim ExtFrm = 14 << FormShift, 368226584Sdim 369226584Sdim // VFP formats 370226584Sdim VFPUnaryFrm = 15 << FormShift, 371226584Sdim VFPBinaryFrm = 16 << FormShift, 372226584Sdim VFPConv1Frm = 17 << FormShift, 373226584Sdim VFPConv2Frm = 18 << FormShift, 374226584Sdim VFPConv3Frm = 19 << FormShift, 375226584Sdim VFPConv4Frm = 20 << FormShift, 376226584Sdim VFPConv5Frm = 21 << FormShift, 377226584Sdim VFPLdStFrm = 22 << FormShift, 378226584Sdim VFPLdStMulFrm = 23 << FormShift, 379226584Sdim VFPMiscFrm = 24 << FormShift, 380226584Sdim 381226584Sdim // Thumb format 382226584Sdim ThumbFrm = 25 << FormShift, 383226584Sdim 384226584Sdim // Miscelleaneous format 385226584Sdim MiscFrm = 26 << FormShift, 386226584Sdim 387226584Sdim // NEON formats 388226584Sdim NGetLnFrm = 27 << FormShift, 389226584Sdim NSetLnFrm = 28 << FormShift, 390226584Sdim NDupFrm = 29 << FormShift, 391226584Sdim NLdStFrm = 30 << FormShift, 392226584Sdim N1RegModImmFrm= 31 << FormShift, 393226584Sdim N2RegFrm = 32 << FormShift, 394226584Sdim NVCVTFrm = 33 << FormShift, 395226584Sdim NVDupLnFrm = 34 << FormShift, 396226584Sdim N2RegVShLFrm = 35 << FormShift, 397226584Sdim N2RegVShRFrm = 36 << FormShift, 398226584Sdim N3RegFrm = 37 << FormShift, 399226584Sdim N3RegVShFrm = 38 << FormShift, 400226584Sdim NVExtFrm = 39 << FormShift, 401226584Sdim NVMulSLFrm = 40 << FormShift, 402226584Sdim NVTBLFrm = 41 << FormShift, 403226584Sdim 404226584Sdim //===------------------------------------------------------------------===// 405226584Sdim // Misc flags. 406226584Sdim 407226584Sdim // UnaryDP - Indicates this is a unary data processing instruction, i.e. 408226584Sdim // it doesn't have a Rn operand. 409226584Sdim UnaryDP = 1 << 13, 410226584Sdim 411226584Sdim // Xform16Bit - Indicates this Thumb2 instruction may be transformed into 412226584Sdim // a 16-bit Thumb instruction if certain conditions are met. 413226584Sdim Xform16Bit = 1 << 14, 414226584Sdim 415226584Sdim // ThumbArithFlagSetting - The instruction is a 16-bit flag setting Thumb 416226584Sdim // instruction. Used by the parser to determine whether to require the 'S' 417226584Sdim // suffix on the mnemonic (when not in an IT block) or preclude it (when 418226584Sdim // in an IT block). 419226584Sdim ThumbArithFlagSetting = 1 << 18, 420226584Sdim 421226584Sdim //===------------------------------------------------------------------===// 422226584Sdim // Code domain. 423226584Sdim DomainShift = 15, 424226584Sdim DomainMask = 7 << DomainShift, 425226584Sdim DomainGeneral = 0 << DomainShift, 426226584Sdim DomainVFP = 1 << DomainShift, 427226584Sdim DomainNEON = 2 << DomainShift, 428226584Sdim DomainNEONA8 = 4 << DomainShift, 429226584Sdim 430226584Sdim //===------------------------------------------------------------------===// 431226584Sdim // Field shifts - such shifts are used to set field while generating 432226584Sdim // machine instructions. 433226584Sdim // 434226584Sdim // FIXME: This list will need adjusting/fixing as the MC code emitter 435226584Sdim // takes shape and the ARMCodeEmitter.cpp bits go away. 436226584Sdim ShiftTypeShift = 4, 437226584Sdim 438226584Sdim M_BitShift = 5, 439226584Sdim ShiftImmShift = 5, 440226584Sdim ShiftShift = 7, 441226584Sdim N_BitShift = 7, 442226584Sdim ImmHiShift = 8, 443226584Sdim SoRotImmShift = 8, 444226584Sdim RegRsShift = 8, 445226584Sdim ExtRotImmShift = 10, 446226584Sdim RegRdLoShift = 12, 447226584Sdim RegRdShift = 12, 448226584Sdim RegRdHiShift = 16, 449226584Sdim RegRnShift = 16, 450226584Sdim S_BitShift = 20, 451226584Sdim W_BitShift = 21, 452226584Sdim AM3_I_BitShift = 22, 453226584Sdim D_BitShift = 22, 454226584Sdim U_BitShift = 23, 455226584Sdim P_BitShift = 24, 456226584Sdim I_BitShift = 25, 457226584Sdim CondShift = 28 458226584Sdim }; 459226584Sdim 460226584Sdim} // end namespace ARMII 461226584Sdim 462226584Sdim} // end namespace llvm; 463226584Sdim 464226584Sdim#endif 465