diff options
author | Stephen Hines <srhines@google.com> | 2014-12-01 14:51:49 -0800 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-12-02 16:08:10 -0800 |
commit | 37ed9c199ca639565f6ce88105f9e39e898d82d0 (patch) | |
tree | 8fb36d3910e3ee4c4e1b7422f4f017108efc52f5 /lib/Target/AArch64/AsmParser | |
parent | d2327b22152ced7bc46dc629fc908959e8a52d03 (diff) | |
download | external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.zip external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.gz external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.bz2 |
Update aosp/master LLVM for rebase to r222494.
Change-Id: Ic787f5e0124df789bd26f3f24680f45e678eef2d
Diffstat (limited to 'lib/Target/AArch64/AsmParser')
-rw-r--r-- | lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 229 |
1 files changed, 146 insertions, 83 deletions
diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index c42d11e..98e0ea8 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -10,26 +10,28 @@ #include "MCTargetDesc/AArch64AddressingModes.h" #include "MCTargetDesc/AArch64MCExpr.h" #include "Utils/AArch64BaseInfo.h" -#include "llvm/MC/MCParser/MCAsmLexer.h" -#include "llvm/MC/MCParser/MCAsmParser.h" -#include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Twine.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCParser/MCAsmLexer.h" +#include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Twine.h" #include <cstdio> using namespace llvm; @@ -41,7 +43,6 @@ class AArch64AsmParser : public MCTargetAsmParser { private: StringRef Mnemonic; ///< Instruction mnemonic. MCSubtargetInfo &STI; - MCAsmParser &Parser; // Map of register aliases registers via the .req directive. StringMap<std::pair<bool, unsigned> > RegisterReqs; @@ -51,10 +52,7 @@ private: return static_cast<AArch64TargetStreamer &>(TS); } - MCAsmParser &getParser() const { return Parser; } - MCAsmLexer &getLexer() const { return Parser.getLexer(); } - - SMLoc getLoc() const { return Parser.getTok().getLoc(); } + SMLoc getLoc() const { return getParser().getTok().getLoc(); } bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands); AArch64CC::CondCode parseCondCodeString(StringRef Cond); @@ -68,11 +66,13 @@ private: bool parseOperand(OperandVector &Operands, bool isCondCode, bool invertCondCode); - void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } - bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } + void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); } + bool Error(SMLoc L, const Twine &Msg) { return getParser().Error(L, Msg); } bool showMatchError(SMLoc Loc, unsigned ErrCode); bool parseDirectiveWord(unsigned Size, SMLoc L); + bool parseDirectiveInst(SMLoc L); + bool parseDirectiveTLSDescCall(SMLoc L); bool parseDirectiveLOH(StringRef LOH, SMLoc L); @@ -84,7 +84,7 @@ private: bool validateInstruction(MCInst &Inst, SmallVectorImpl<SMLoc> &Loc); bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, - unsigned &ErrorInfo, + uint64_t &ErrorInfo, bool MatchingInlineAsm) override; /// @name Auto-generated Match Functions /// { @@ -116,10 +116,11 @@ public: AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { + : MCTargetAsmParser(), STI(_STI) { MCAsmParserExtension::Initialize(_Parser); - if (Parser.getStreamer().getTargetStreamer() == nullptr) - new AArch64TargetStreamer(Parser.getStreamer()); + MCStreamer &S = getParser().getStreamer(); + if (S.getTargetStreamer() == nullptr) + new AArch64TargetStreamer(S); // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); @@ -1253,134 +1254,116 @@ public: void addSImm9Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addSImm7s4Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 4)); } void addSImm7s8Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 8)); } void addSImm7s16Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue() / 16)); } void addImm0_7Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm1_8Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm0_15Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm1_16Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); assert(MCE && "Invalid constant immediate operand!"); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm0_31Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm1_31Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm1_32Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm0_63Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm1_63Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm1_64Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm0_127Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm0_255Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm0_65535Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addImm32_63Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid constant immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); Inst.addOperand(MCOperand::CreateImm(MCE->getValue())); } void addLogicalImm32Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid logical immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32); Inst.addOperand(MCOperand::CreateImm(encoding)); @@ -1388,8 +1371,7 @@ public: void addLogicalImm64Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid logical immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64); Inst.addOperand(MCOperand::CreateImm(encoding)); } @@ -1412,8 +1394,7 @@ public: void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); - assert(MCE && "Invalid immediate operand!"); + const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm()); uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue()); Inst.addOperand(MCOperand::CreateImm(encoding)); } @@ -1894,6 +1875,7 @@ unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name, /// Identifier when called, and if it is a register name the token is eaten and /// the register is added to the operand list. int AArch64AsmParser::tryParseRegister() { + MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); @@ -1918,6 +1900,7 @@ int AArch64AsmParser::tryParseRegister() { /// tryMatchVectorRegister - Try to parse a vector register name with optional /// kind specifier. If it is a register specifier, eat the token and return it. int AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) { + MCAsmParser &Parser = getParser(); if (Parser.getTok().isNot(AsmToken::Identifier)) { TokError("vector register expected"); return -1; @@ -1950,6 +1933,7 @@ int AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) { /// tryParseSysCROperand - Try to parse a system instruction CR operand name. AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); if (Parser.getTok().isNot(AsmToken::Identifier)) { @@ -1979,6 +1963,7 @@ AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) { /// tryParsePrefetch - Try to parse a prefetch operand. AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); const AsmToken &Tok = Parser.getTok(); // Either an identifier for named values or a 5-bit immediate. @@ -2026,6 +2011,7 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { /// instruction. AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); const MCExpr *Expr; @@ -2076,6 +2062,7 @@ AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { /// instruction. AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); const MCExpr *Expr; @@ -2095,6 +2082,7 @@ AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) { /// tryParseFPImm - A floating point immediate expression operand. AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseFPImm(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); bool Hash = false; @@ -2157,6 +2145,7 @@ AArch64AsmParser::tryParseFPImm(OperandVector &Operands) { /// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); if (Parser.getTok().is(AsmToken::Hash)) @@ -2248,6 +2237,7 @@ AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) { /// parseCondCode - Parse a Condition Code operand. bool AArch64AsmParser::parseCondCode(OperandVector &Operands, bool invertCondCode) { + MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); const AsmToken &Tok = Parser.getTok(); assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); @@ -2273,6 +2263,7 @@ bool AArch64AsmParser::parseCondCode(OperandVector &Operands, /// them if present. AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); std::string LowerID = Tok.getString().lower(); AArch64_AM::ShiftExtendType ShOp = @@ -2318,10 +2309,11 @@ AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) { if (Hash) Parser.Lex(); // Eat the '#'. - // Make sure we do actually have a number - if (!Parser.getTok().is(AsmToken::Integer)) { - Error(Parser.getTok().getLoc(), - "expected integer shift amount"); + // Make sure we do actually have a number or a parenthesized expression. + SMLoc E = Parser.getTok().getLoc(); + if (!Parser.getTok().is(AsmToken::Integer) && + !Parser.getTok().is(AsmToken::LParen)) { + Error(E, "expected integer shift amount"); return MatchOperand_ParseFail; } @@ -2331,11 +2323,11 @@ AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) { const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal); if (!MCE) { - TokError("expected #imm after shift specifier"); + Error(E, "expected constant '#imm' after shift specifier"); return MatchOperand_ParseFail; } - SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); + E = SMLoc::getFromPointer(getLoc().getPointer() - 1); Operands.push_back(AArch64Operand::CreateShiftExtend( ShOp, MCE->getValue(), true, S, E, getContext())); return MatchOperand_Success; @@ -2352,6 +2344,7 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc, Operands.push_back( AArch64Operand::CreateToken("sys", false, NameLoc, getContext())); + MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); StringRef Op = Tok.getString(); SMLoc S = Tok.getLoc(); @@ -2590,6 +2583,7 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc, AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); // Can be either a #imm style literal or an option name @@ -2643,6 +2637,7 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseSysReg(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); if (Tok.isNot(AsmToken::Identifier)) @@ -2657,6 +2652,7 @@ AArch64AsmParser::tryParseSysReg(OperandVector &Operands) { /// tryParseVectorRegister - Parse a vector register operand. bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); if (Parser.getTok().isNot(AsmToken::Identifier)) return true; @@ -2705,6 +2701,7 @@ bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) { /// parseRegister - Parse a non-vector register operand. bool AArch64AsmParser::parseRegister(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); // Try for a vector register. if (!tryParseVectorRegister(Operands)) @@ -2747,6 +2744,7 @@ bool AArch64AsmParser::parseRegister(OperandVector &Operands) { } bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { + MCAsmParser &Parser = getParser(); bool HasELFModifier = false; AArch64MCExpr::VariantKind RefKind; @@ -2825,6 +2823,7 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { /// parseVectorList - Parse a vector list operand for AdvSIMD instructions. bool AArch64AsmParser::parseVectorList(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket"); SMLoc S = getLoc(); Parser.Lex(); // Eat left bracket token. @@ -2923,6 +2922,7 @@ bool AArch64AsmParser::parseVectorList(OperandVector &Operands) { AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); const AsmToken &Tok = Parser.getTok(); if (!Tok.is(AsmToken::Identifier)) return MatchOperand_NoMatch; @@ -2968,6 +2968,7 @@ AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) { /// operand regardless of the mnemonic. bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, bool invertCondCode) { + MCAsmParser &Parser = getParser(); // Check if the current operand has a custom associated parser, if so, try to // custom parse the operand, or fallback to the general approach. OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); @@ -3087,13 +3088,18 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, if (getParser().parseExpression(SubExprVal)) return true; + if (Operands.size() < 2 || + !static_cast<AArch64Operand &>(*Operands[1]).isReg()) + return true; + + bool IsXReg = + AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( + Operands[1]->getReg()); + MCContext& Ctx = getContext(); E = SMLoc::getFromPointer(Loc.getPointer() - 1); // If the op is an imm and can be fit into a mov, then replace ldr with mov. - if (isa<MCConstantExpr>(SubExprVal) && Operands.size() >= 2 && - static_cast<AArch64Operand &>(*Operands[1]).isReg()) { - bool IsXReg = AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( - Operands[1]->getReg()); + if (isa<MCConstantExpr>(SubExprVal)) { uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue(); uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16; while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) { @@ -3109,9 +3115,14 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, ShiftAmt, true, S, E, Ctx)); return false; } + APInt Simm = APInt(64, Imm << ShiftAmt); + // check if the immediate is an unsigned or signed 32-bit int for W regs + if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32))) + return Error(Loc, "Immediate too large for register"); } // If it is a label or an imm that cannot fit in a movz, put it into CP. - const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal); + const MCExpr *CPLoc = + getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4); Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx)); return false; } @@ -3123,6 +3134,7 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) { + MCAsmParser &Parser = getParser(); Name = StringSwitch<StringRef>(Name.lower()) .Case("beq", "b.eq") .Case("bne", "b.ne") @@ -3571,12 +3583,12 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) { } } -static const char *getSubtargetFeatureName(unsigned Val); +static const char *getSubtargetFeatureName(uint64_t Val); bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, - unsigned &ErrorInfo, + uint64_t &ErrorInfo, bool MatchingInlineAsm) { assert(!Operands.empty() && "Unexpect empty operand list!"); AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]); @@ -3826,7 +3838,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, // 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:"; - unsigned Mask = 1; + uint64_t Mask = 1; for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { if (ErrorInfo & Mask) { Msg += " "; @@ -3840,7 +3852,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return showMatchError(IDLoc, MatchResult); case Match_InvalidOperand: { SMLoc ErrorLoc = IDLoc; - if (ErrorInfo != ~0U) { + if (ErrorInfo != ~0ULL) { if (ErrorInfo >= Operands.size()) return Error(IDLoc, "too few operands for instruction"); @@ -3920,6 +3932,11 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, /// ParseDirective parses the arm specific directives bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { + const MCObjectFileInfo::Environment Format = + getContext().getObjectFileInfo()->getObjectFileType(); + bool IsMachO = Format == MCObjectFileInfo::IsMachO; + bool IsCOFF = Format == MCObjectFileInfo::IsCOFF; + StringRef IDVal = DirectiveID.getIdentifier(); SMLoc Loc = DirectiveID.getLoc(); if (IDVal == ".hword") @@ -3935,12 +3952,18 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { if (IDVal == ".unreq") return parseDirectiveUnreq(DirectiveID.getLoc()); + if (!IsMachO && !IsCOFF) { + if (IDVal == ".inst") + return parseDirectiveInst(Loc); + } + return parseDirectiveLOH(IDVal, Loc); } /// parseDirectiveWord /// ::= .word [ expression (, expression)* ] bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { + MCAsmParser &Parser = getParser(); if (getLexer().isNot(AsmToken::EndOfStatement)) { for (;;) { const MCExpr *Value; @@ -3963,6 +3986,47 @@ bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { return false; } +/// parseDirectiveInst +/// ::= .inst opcode [, ...] +bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) { + MCAsmParser &Parser = getParser(); + if (getLexer().is(AsmToken::EndOfStatement)) { + Parser.eatToEndOfStatement(); + Error(Loc, "expected expression following directive"); + return false; + } + + for (;;) { + const MCExpr *Expr; + + if (getParser().parseExpression(Expr)) { + Error(Loc, "expected expression"); + return false; + } + + const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr); + if (!Value) { + Error(Loc, "expected constant expression"); + return false; + } + + getTargetStreamer().emitInst(Value->getValue()); + + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + if (getLexer().isNot(AsmToken::Comma)) { + Error(Loc, "unexpected token in directive"); + return false; + } + + Parser.Lex(); // Eat comma. + } + + Parser.Lex(); + return false; +} + // parseDirectiveTLSDescCall: // ::= .tlsdesccall symbol bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) { @@ -3994,10 +4058,9 @@ bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) { // We successfully get a numeric value for the identifier. // Check if it is valid. int64_t Id = getParser().getTok().getIntVal(); - Kind = (MCLOHType)Id; - // Check that Id does not overflow MCLOHType. - if (!isValidMCLOHType(Kind) || Id != Kind) + if (Id <= -1U && !isValidMCLOHType(Id)) return TokError("invalid numeric identifier in directive"); + Kind = (MCLOHType)Id; } else { StringRef Name = getTok().getIdentifier(); // We successfully parse an identifier. @@ -4045,6 +4108,7 @@ bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) { /// parseDirectiveReq /// ::= name .req registername bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { + MCAsmParser &Parser = getParser(); Parser.Lex(); // Eat the '.req' token. SMLoc SRegLoc = getLoc(); unsigned RegNum = tryParseRegister(); @@ -4076,7 +4140,7 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { Parser.Lex(); // Consume the EndOfStatement auto pair = std::make_pair(IsVector, RegNum); - if (RegisterReqs.GetOrCreateValue(Name, pair).getValue() != pair) + if (!RegisterReqs.insert(std::make_pair(Name, pair)).second) Warning(L, "ignoring redefinition of register alias '" + Name + "'"); return true; @@ -4085,6 +4149,7 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) { /// parseDirectiveUneq /// ::= .unreq registername bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) { + MCAsmParser &Parser = getParser(); if (Parser.getTok().isNot(AsmToken::Identifier)) { Error(Parser.getTok().getLoc(), "unexpected input in .unreq directive."); Parser.eatToEndOfStatement(); @@ -4149,9 +4214,7 @@ AArch64AsmParser::classifySymbolRef(const MCExpr *Expr, extern "C" void LLVMInitializeAArch64AsmParser() { RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64leTarget); RegisterMCAsmParser<AArch64AsmParser> Y(TheAArch64beTarget); - - RegisterMCAsmParser<AArch64AsmParser> Z(TheARM64leTarget); - RegisterMCAsmParser<AArch64AsmParser> W(TheARM64beTarget); + RegisterMCAsmParser<AArch64AsmParser> Z(TheARM64Target); } #define GET_REGISTER_MATCHER |