Index: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td @@ -265,6 +265,20 @@ def Imm1_32Operand : AsmImmRange<1, 32>; def Imm1_64Operand : AsmImmRange<1, 64>; +class BranchTarget : AsmOperandClass { + let Name = "BranchTarget" # N; + let DiagnosticType = "InvalidLabel"; + let PredicateMethod = "isBranchTarget<" # N # ">"; +} + +class PCRelLabel : BranchTarget { + let Name = "PCRelLabel" # N; +} + +def BranchTarget14Operand : BranchTarget<14>; +def BranchTarget26Operand : BranchTarget<26>; +def PCRelLabel19Operand : PCRelLabel<19>; + def MovZSymbolG3AsmOperand : AsmOperandClass { let Name = "MovZSymbolG3"; let RenderMethod = "addImmOperands"; @@ -1096,10 +1110,6 @@ // Conditional branch target. 19-bit immediate. The low two bits of the target // offset are implied zero and so are not part of the immediate. -def PCRelLabel19Operand : AsmOperandClass { - let Name = "PCRelLabel19"; - let DiagnosticType = "InvalidLabel"; -} def am_brcond : Operand { let EncoderMethod = "getCondBranchTargetOpValue"; let DecoderMethod = "DecodePCRelLabel19"; @@ -1156,9 +1166,6 @@ //--- // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of // the target offset are implied zero and so are not part of the immediate. -def BranchTarget14Operand : AsmOperandClass { - let Name = "BranchTarget14"; -} def am_tbrcond : Operand { let EncoderMethod = "getTestBranchTargetOpValue"; let PrintMethod = "printAlignedLabel"; @@ -1235,10 +1242,6 @@ //--- // Unconditional branch (immediate) instructions. //--- -def BranchTarget26Operand : AsmOperandClass { - let Name = "BranchTarget26"; - let DiagnosticType = "InvalidLabel"; -} def am_b_target : Operand { let EncoderMethod = "getBranchTargetOpValue"; let PrintMethod = "printAlignedLabel"; Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -665,7 +665,8 @@ return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue()); } - bool isBranchTarget26() const { + template + bool isBranchTarget() const { if (!isImm()) return false; const MCConstantExpr *MCE = dyn_cast(getImm()); @@ -674,31 +675,8 @@ int64_t Val = MCE->getValue(); if (Val & 0x3) return false; - return (Val >= -(0x2000000 << 2) && Val <= (0x1ffffff << 2)); - } - - bool isPCRelLabel19() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return true; - int64_t Val = MCE->getValue(); - if (Val & 0x3) - return false; - return (Val >= -(0x40000 << 2) && Val <= (0x3ffff << 2)); - } - - bool isBranchTarget14() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return true; - int64_t Val = MCE->getValue(); - if (Val & 0x3) - return false; - return (Val >= -(0x2000 << 2) && Val <= (0x1fff << 2)); + assert(N > 0 && "Branch target immediate cannot be 0 bits!"); + return (Val >= -((1<<(N-1)) << 2) && Val <= (((1<<(N-1))-1) << 2)); } bool