diff --git a/lib/Target/ARM64/ARM64InstrFormats.td b/lib/Target/ARM64/ARM64InstrFormats.td index 85bc54421c9..883d9eb7c59 100644 --- a/lib/Target/ARM64/ARM64InstrFormats.td +++ b/lib/Target/ARM64/ARM64InstrFormats.td @@ -167,6 +167,11 @@ def FPImmOperand : AsmOperandClass { 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 @@ class SpecialReturn opc, string asm> //--- // 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 @@ def am_brcond : Operand { 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 @@ class TestBranch //--- def BranchTarget26Operand : AsmOperandClass { let Name = "BranchTarget26"; + let DiagnosticType = "InvalidLabel"; } def am_b_target : Operand { let EncoderMethod = "getBranchTargetOpValue"; @@ -1901,16 +1913,6 @@ multiclass LogicalRegS opc, bit N, string mnemonic, // 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), diff --git a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp index 892ba75b02b..6322448a8ac 100644 --- a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -52,7 +52,7 @@ private: 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 @@ private: enum KindTy { k_Immediate, k_ShiftedImm, + k_CondCode, k_Memory, k_Register, k_VectorList, @@ -189,6 +190,10 @@ private: unsigned ShiftAmount; }; + struct CondCodeOp { + ARM64CC::CondCode Code; + }; + struct FPImmOp { unsigned Val; // Encoded 8-bit representation. }; @@ -239,6 +244,7 @@ private: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: } } + 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 @@ public: 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 @@ void ARM64Operand::print(raw_ostream &OS) const { OS << ", lsl #" << ARM64_AM::getShiftValue(Shift) << ">"; break; } + case k_CondCode: + OS << ""; + break; case k_Memory: OS << ""; break; @@ -2382,8 +2414,8 @@ ARM64AsmParser::tryParseAddSubImm(OperandVector &Operands) { } /// 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 @@ bool ARM64AsmParser::parseCondCode(OperandVector &Operands, 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 @@ bool ARM64AsmParser::parseCondCode(OperandVector &Operands, 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 @@ bool ARM64AsmParser::ParseInstruction(ParseInstructionInfo &Info, 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 @@ bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) { 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 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, ((ARM64Operand *)Operands[ErrorInfo + 1])->isTokenEqual("!")) MatchResult = Match_InvalidMemoryIndexedSImm9; // FALL THROUGH + case Match_InvalidCondCode: case Match_AddSubRegExtendSmall: case Match_AddSubRegExtendLarge: case Match_AddSubSecondSource: diff --git a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp index 678d0a63ce7..f7b358d4f42 100644 --- a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp +++ b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp @@ -1112,12 +1112,6 @@ void ARM64InstPrinter::printExtend(const MCInst *MI, unsigned OpNum, 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(); diff --git a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h index d0fc34aa7da..31818dff980 100644 --- a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h +++ b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h @@ -65,7 +65,6 @@ protected: 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);