From e6d1592492a3a379186bfb02bd0f4eda0669c0d5 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Tue, 20 Aug 2019 20:50:12 +0000 Subject: Vendor import of stripped llvm trunk r366426 (just before the release_90 branch point): https://llvm.org/svn/llvm-project/llvm/trunk@366426 --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 102 +++++++++++----------- 1 file changed, 53 insertions(+), 49 deletions(-) (limited to 'lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp') diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 6cc9b67e4d27..f4c55d48d215 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1,9 +1,8 @@ //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -11,6 +10,7 @@ #include "MCTargetDesc/AArch64MCExpr.h" #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "MCTargetDesc/AArch64TargetStreamer.h" +#include "TargetInfo/AArch64TargetInfo.h" #include "AArch64InstrInfo.h" #include "Utils/AArch64BaseInfo.h" #include "llvm/ADT/APFloat.h" @@ -242,11 +242,13 @@ public: if (S.getTargetStreamer() == nullptr) new AArch64TargetStreamer(S); - // Alias .hword/.word/xword to the target-independent .2byte/.4byte/.8byte - // directives as they have the same form and semantics: - /// ::= (.hword | .word | .xword ) [ expression (, expression)* ] + // Alias .hword/.word/.[dx]word to the target-independent + // .2byte/.4byte/.8byte directives as they have the same form and + // semantics: + /// ::= (.hword | .word | .dword | .xword ) [ expression (, expression)* ] Parser.addAliasForDirective(".hword", ".2byte"); Parser.addAliasForDirective(".word", ".4byte"); + Parser.addAliasForDirective(".dword", ".8byte"); Parser.addAliasForDirective(".xword", ".8byte"); // Initialize the set of available features. @@ -1079,8 +1081,7 @@ public: if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateVector) return DiagnosticPredicateTy::NoMatch; - if (isSVEVectorReg() && - (ElementWidth == 0 || Reg.ElementWidth == ElementWidth)) + if (isSVEVectorReg() && (Reg.ElementWidth == ElementWidth)) return DiagnosticPredicateTy::Match; return DiagnosticPredicateTy::NearMatch; @@ -1091,8 +1092,7 @@ public: if (Kind != k_Register || Reg.Kind != RegKind::SVEDataVector) return DiagnosticPredicateTy::NoMatch; - if (isSVEVectorReg() && - (ElementWidth == 0 || Reg.ElementWidth == ElementWidth)) + if (isSVEVectorReg() && Reg.ElementWidth == ElementWidth) return DiagnosticPredicateTy::Match; return DiagnosticPredicateTy::NearMatch; @@ -1272,9 +1272,11 @@ public: bool isExtend64() const { if (!isExtend()) return false; - // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class). + // Make sure the extend expects a 32-bit source register. AArch64_AM::ShiftExtendType ET = getShiftExtendType(); - return ET != AArch64_AM::UXTX && ET != AArch64_AM::SXTX; + return ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB || + ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH || + ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW; } bool isExtendLSL64() const { @@ -2473,7 +2475,7 @@ OperandMatchResultTy AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); - const MCExpr *Expr; + const MCExpr *Expr = nullptr; if (Parser.getTok().is(AsmToken::Hash)) { Parser.Lex(); // Eat hash token. @@ -2500,6 +2502,7 @@ AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE && DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE && DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE && + ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC && ELFRefKind != AArch64MCExpr::VK_GOT_PAGE && ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE && ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) { @@ -2523,7 +2526,7 @@ AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { OperandMatchResultTy AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) { SMLoc S = getLoc(); - const MCExpr *Expr; + const MCExpr *Expr = nullptr; // Leave anything with a bracket to the default for SVE if (getParser().getTok().is(AsmToken::LBrac)) @@ -2621,7 +2624,7 @@ AArch64AsmParser::tryParseImmWithOptionalShift(OperandVector &Operands) { // Operand should start from # or should be integer, emit error otherwise. return MatchOperand_NoMatch; - const MCExpr *Imm; + const MCExpr *Imm = nullptr; if (parseSymbolicImmVal(Imm)) return MatchOperand_ParseFail; else if (Parser.getTok().isNot(AsmToken::Comma)) { @@ -2660,7 +2663,7 @@ AArch64AsmParser::tryParseImmWithOptionalShift(OperandVector &Operands) { Parser.Lex(); // Eat the number // Just in case the optional lsl #0 is used for immediates other than zero. - if (ShiftAmount == 0 && Imm != 0) { + if (ShiftAmount == 0 && Imm != nullptr) { SMLoc E = Parser.getTok().getLoc(); Operands.push_back(AArch64Operand::CreateImm(Imm, S, E, getContext())); return MatchOperand_Success; @@ -2833,6 +2836,11 @@ static const struct Extension { {"pan-rwv", {AArch64::FeaturePAN_RWV}}, {"ccpp", {AArch64::FeatureCCPP}}, {"sve", {AArch64::FeatureSVE}}, + {"sve2", {AArch64::FeatureSVE2}}, + {"sve2-aes", {AArch64::FeatureSVE2AES}}, + {"sve2-sm4", {AArch64::FeatureSVE2SM4}}, + {"sve2-sha3", {AArch64::FeatureSVE2SHA3}}, + {"bitperm", {AArch64::FeatureSVE2BitPerm}}, // FIXME: Unsupported extensions {"pan", {}}, {"lor", {}}, @@ -3260,6 +3268,7 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12) .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12) .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC) + .Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC) .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2) .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1) .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC) @@ -4098,15 +4107,6 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc, "unpredictable STXP instruction, status is also a source"); break; } - case AArch64::LDGV: { - unsigned Rt = Inst.getOperand(0).getReg(); - unsigned Rn = Inst.getOperand(1).getReg(); - if (RI->isSubRegisterEq(Rt, Rn)) { - return Error(Loc[0], - "unpredictable LDGV instruction, writeback register is also " - "the target register"); - } - } } @@ -4167,7 +4167,8 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc, } } -static std::string AArch64MnemonicSpellCheck(StringRef S, uint64_t FBS, +static std::string AArch64MnemonicSpellCheck(StringRef S, + const FeatureBitset &FBS, unsigned VariantID = 0); bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, @@ -4199,7 +4200,7 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, 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]"); + "expected '[su]xt[bhw]' with optional integer in range [0, 4]"); case Match_AddSubRegExtendLarge: return Error(Loc, "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]"); @@ -4442,7 +4443,7 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, case Match_InvalidZPR64LSL64: return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #3'"); case Match_InvalidZPR0: - return Error(Loc, "expected register without element width sufix"); + return Error(Loc, "expected register without element width suffix"); case Match_InvalidZPR8: case Match_InvalidZPR16: case Match_InvalidZPR32: @@ -4470,11 +4471,15 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, case Match_InvalidSVEPredicateDReg: return Error(Loc, "invalid predicate register."); case Match_InvalidSVEPredicate3bAnyReg: + return Error(Loc, "invalid restricted predicate register, expected p0..p7 (without element suffix)"); case Match_InvalidSVEPredicate3bBReg: + return Error(Loc, "invalid restricted predicate register, expected p0.b..p7.b"); case Match_InvalidSVEPredicate3bHReg: + return Error(Loc, "invalid restricted predicate register, expected p0.h..p7.h"); case Match_InvalidSVEPredicate3bSReg: + return Error(Loc, "invalid restricted predicate register, expected p0.s..p7.s"); case Match_InvalidSVEPredicate3bDReg: - return Error(Loc, "restricted predicate has range [0, 7]."); + return Error(Loc, "invalid restricted predicate register, expected p0.d..p7.d"); case Match_InvalidSVEExactFPImmOperandHalfOne: return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0."); case Match_InvalidSVEExactFPImmOperandHalfTwo: @@ -4777,10 +4782,12 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, } MCInst Inst; + FeatureBitset MissingFeatures; // First try to match against the secondary set of tables containing the // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2"). unsigned MatchResult = - MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1); + MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, + MatchingInlineAsm, 1); // If that fails, try against the alternate table containing long-form NEON: // "fadd v0.2s, v1.2s, v2.2s" @@ -4789,9 +4796,11 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, // long-form match also fails. auto ShortFormNEONErrorInfo = ErrorInfo; auto ShortFormNEONMatchResult = MatchResult; + auto ShortFormNEONMissingFeatures = MissingFeatures; MatchResult = - MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0); + MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, + MatchingInlineAsm, 0); // Now, both matches failed, and the long-form match failed on the mnemonic // suffix token operand. The short-form match failure is probably more @@ -4801,6 +4810,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, ((AArch64Operand &)*Operands[1]).isTokenSuffix()) { MatchResult = ShortFormNEONMatchResult; ErrorInfo = ShortFormNEONErrorInfo; + MissingFeatures = ShortFormNEONMissingFeatures; } } @@ -4819,17 +4829,15 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return false; } case Match_MissingFeature: { - assert(ErrorInfo && "Unknown missing feature!"); + assert(MissingFeatures.any() && "Unknown missing feature!"); // Special case the error message for the very common case where only // a single subtarget feature is missing (neon, e.g.). std::string Msg = "instruction requires:"; - uint64_t Mask = 1; - for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { - if (ErrorInfo & Mask) { + for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { + if (MissingFeatures[i]) { Msg += " "; - Msg += getSubtargetFeatureName(ErrorInfo & Mask); + Msg += getSubtargetFeatureName(i); } - Mask <<= 1; } return Error(IDLoc, Msg); } @@ -5148,7 +5156,7 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { FeatureBitset ToggleFeatures = EnableFeature ? (~Features & Extension.Features) : ( Features & Extension.Features); - uint64_t Features = + FeatureBitset Features = ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); setAvailableFeatures(Features); break; @@ -5160,15 +5168,9 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { /// parseDirectiveArchExtension /// ::= .arch_extension [no]feature bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) { - MCAsmParser &Parser = getParser(); - - if (getLexer().isNot(AsmToken::Identifier)) - return Error(getLexer().getLoc(), "expected architecture extension name"); + SMLoc ExtLoc = getLoc(); - const AsmToken &Tok = Parser.getTok(); - StringRef Name = Tok.getString(); - SMLoc ExtLoc = Tok.getLoc(); - Lex(); + StringRef Name = getParser().parseStringToEndOfStatement().trim(); if (parseToken(AsmToken::EndOfStatement, "unexpected token in '.arch_extension' directive")) @@ -5192,7 +5194,7 @@ bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) { FeatureBitset ToggleFeatures = EnableFeature ? (~Features & Extension.Features) : (Features & Extension.Features); - uint64_t Features = + FeatureBitset Features = ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); setAvailableFeatures(Features); return false; @@ -5257,7 +5259,7 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) { FeatureBitset ToggleFeatures = EnableFeature ? (~Features & Extension.Features) : ( Features & Extension.Features); - uint64_t Features = + FeatureBitset Features = ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); setAvailableFeatures(Features); FoundExtension = true; @@ -5518,6 +5520,8 @@ extern "C" void LLVMInitializeAArch64AsmParser() { RegisterMCAsmParser X(getTheAArch64leTarget()); RegisterMCAsmParser Y(getTheAArch64beTarget()); RegisterMCAsmParser Z(getTheARM64Target()); + RegisterMCAsmParser W(getTheARM64_32Target()); + RegisterMCAsmParser V(getTheAArch64_32Target()); } #define GET_REGISTER_MATCHER -- cgit v1.3