Index: lib/Target/ARM64/ARM64InstrFormats.td =================================================================== --- lib/Target/ARM64/ARM64InstrFormats.td +++ lib/Target/ARM64/ARM64InstrFormats.td @@ -167,6 +167,11 @@ let ParserMethod = "tryParseFPImm"; } +def CondCode : AsmOperandClass { + let Name = "CondCode"; + let DiagnosticType = "InvalidCondCode"; +} + // 8-bit immediate for AdvSIMD where 64-bit values of the form: // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh // are encoded as the eight bit value 'abcdefgh'. @@ -901,10 +906,16 @@ //--- // Conditional branch instruction. //--- -// Branch condition code. -// 4-bit immediate. Pretty-printed as . -def dotCcode : Operand { - let PrintMethod = "printDotCondCode"; + +// Condition code. +// 4-bit immediate. Pretty-printed as +def ccode : Operand { + let PrintMethod = "printCondCode"; + let ParserMatchClass = CondCode; +} +def inv_ccode : Operand { + let PrintMethod = "printInverseCondCode"; + let ParserMatchClass = CondCode; } // Conditional branch target. 19-bit immediate. The low two bits of the target @@ -920,8 +931,8 @@ let ParserMatchClass = PCRelLabel19Operand; } -class BranchCond : I<(outs), (ins dotCcode:$cond, am_brcond:$target), - "b", "$cond\t$target", "", +class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), + "b", ".$cond\t$target", "", [(ARM64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { let isBranch = 1; @@ -1005,6 +1016,7 @@ //--- def BranchTarget26Operand : AsmOperandClass { let Name = "BranchTarget26"; + let DiagnosticType = "InvalidLabel"; } def am_b_target : Operand { let EncoderMethod = "getBranchTargetOpValue"; @@ -1901,16 +1913,6 @@ // Conditionally set flags //--- -// Condition code. -// 4-bit immediate. Pretty-printed as -def ccode : Operand { - let PrintMethod = "printCondCode"; -} - -def inv_ccode : Operand { - let PrintMethod = "printInverseCondCode"; -} - let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in class BaseCondSetFlagsImm : I<(outs), (ins regtype:$Rn, imm0_31:$imm, imm0_15:$nzcv, ccode:$cond), Index: lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp =================================================================== --- lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -52,7 +52,7 @@ SMLoc getLoc() const { return Parser.getTok().getLoc(); } bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands); - unsigned parseCondCodeString(StringRef Cond); + ARM64CC::CondCode parseCondCodeString(StringRef Cond); bool parseCondCode(OperandVector &Operands, bool invertCondCode); int tryParseRegister(); int tryMatchVectorRegister(StringRef &Kind, bool expected); @@ -143,6 +143,7 @@ enum KindTy { k_Immediate, k_ShiftedImm, + k_CondCode, k_Memory, k_Register, k_VectorList, @@ -189,6 +190,10 @@ unsigned ShiftAmount; }; + struct CondCodeOp { + ARM64CC::CondCode Code; + }; + struct FPImmOp { unsigned Val; // Encoded 8-bit representation. }; @@ -239,6 +244,7 @@ struct VectorIndexOp VectorIndex; struct ImmOp Imm; struct ShiftedImmOp ShiftedImm; + struct CondCodeOp CondCode; struct FPImmOp FPImm; struct BarrierOp Barrier; struct SysRegOp SysReg; @@ -270,6 +276,9 @@ case k_ShiftedImm: ShiftedImm = o.ShiftedImm; break; + case k_CondCode: + CondCode = o.CondCode; + break; case k_FPImm: FPImm = o.FPImm; break; @@ -335,6 +344,11 @@ return ShiftedImm.ShiftAmount; } + ARM64CC::CondCode getCondCode() const { + assert(Kind == k_CondCode && "Invalid access!"); + return CondCode.Code; + } + unsigned getFPImm() const { assert(Kind == k_FPImm && "Invalid access!"); return FPImm.Val; @@ -604,6 +618,7 @@ const MCConstantExpr *CE = cast(Expr); return CE->getValue() >= 0 && CE->getValue() <= 0xfff; } + bool isCondCode() const { return Kind == k_CondCode; } bool isSIMDImmType10() const { if (!isImm()) return false; @@ -1241,6 +1256,11 @@ } } + void addCondCodeOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateImm(getCondCode())); + } + void addAdrpLabelOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); const MCConstantExpr *MCE = dyn_cast(getImm()); @@ -1755,6 +1775,15 @@ return Op; } + static ARM64Operand *CreateCondCode(ARM64CC::CondCode Code, SMLoc S, SMLoc E, + MCContext &Ctx) { + ARM64Operand *Op = new ARM64Operand(k_CondCode, Ctx); + Op->CondCode.Code = Code; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; + } + static ARM64Operand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) { ARM64Operand *Op = new ARM64Operand(k_FPImm, Ctx); Op->FPImm.Val = Val; @@ -1871,6 +1900,9 @@ OS << ", lsl #" << ARM64_AM::getShiftValue(Shift) << ">"; break; } + case k_CondCode: + OS << ""; + break; case k_Memory: OS << ""; break; @@ -2382,8 +2414,8 @@ } /// parseCondCodeString - Parse a Condition Code string. -unsigned ARM64AsmParser::parseCondCodeString(StringRef Cond) { - unsigned CC = StringSwitch(Cond.lower()) +ARM64CC::CondCode ARM64AsmParser::parseCondCodeString(StringRef Cond) { + ARM64CC::CondCode CC = StringSwitch(Cond.lower()) .Case("eq", ARM64CC::EQ) .Case("ne", ARM64CC::NE) .Case("cs", ARM64CC::HS) @@ -2414,7 +2446,7 @@ assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); StringRef Cond = Tok.getString(); - unsigned CC = parseCondCodeString(Cond); + ARM64CC::CondCode CC = parseCondCodeString(Cond); if (CC == ARM64CC::Invalid) return TokError("invalid condition code"); Parser.Lex(); // Eat identifier token. @@ -2422,9 +2454,8 @@ if (invertCondCode) CC = ARM64CC::getInvertedCondCode(ARM64CC::CondCode(CC)); - const MCExpr *CCExpr = MCConstantExpr::Create(CC, getContext()); Operands.push_back( - ARM64Operand::CreateImm(CCExpr, S, getLoc(), getContext())); + ARM64Operand::CreateCondCode(CC, S, getLoc(), getContext())); return false; } @@ -3426,12 +3457,13 @@ SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + (Head.data() - Name.data())); - unsigned CC = parseCondCodeString(Head); + ARM64CC::CondCode CC = parseCondCodeString(Head); if (CC == ARM64CC::Invalid) return Error(SuffixLoc, "invalid condition code"); - const MCExpr *CCExpr = MCConstantExpr::Create(CC, getContext()); Operands.push_back( - ARM64Operand::CreateImm(CCExpr, NameLoc, NameLoc, getContext())); + ARM64Operand::CreateToken(".", true, SuffixLoc, getContext())); + Operands.push_back( + ARM64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext())); } // Add the remaining tokens in the mnemonic. @@ -3674,6 +3706,8 @@ return Error(Loc, "invalid operand for instruction"); case Match_InvalidSuffix: return Error(Loc, "invalid type suffix for instruction"); + case Match_InvalidCondCode: + return Error(Loc, "expected AArch64 condition code"); case Match_AddSubRegExtendSmall: return Error(Loc, "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]"); @@ -4144,6 +4178,7 @@ ((ARM64Operand *)Operands[ErrorInfo + 1])->isTokenEqual("!")) MatchResult = Match_InvalidMemoryIndexedSImm9; // FALL THROUGH + case Match_InvalidCondCode: case Match_AddSubRegExtendSmall: case Match_AddSubRegExtendLarge: case Match_AddSubSecondSource: Index: lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h =================================================================== --- lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h +++ lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h @@ -65,7 +65,6 @@ void printExtend(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printCondCode(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printInverseCondCode(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printDotCondCode(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printAlignedLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printAMIndexed(const MCInst *MI, unsigned OpNum, unsigned Scale, raw_ostream &O); Index: lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp =================================================================== --- lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp +++ lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp @@ -1112,12 +1112,6 @@ O << " #" << ShiftVal; } -void ARM64InstPrinter::printDotCondCode(const MCInst *MI, unsigned OpNum, - raw_ostream &O) { - ARM64CC::CondCode CC = (ARM64CC::CondCode)MI->getOperand(OpNum).getImm(); - O << '.' << ARM64CC::getCondCodeName(CC); -} - void ARM64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum, raw_ostream &O) { ARM64CC::CondCode CC = (ARM64CC::CondCode)MI->getOperand(OpNum).getImm();