llvm.org GIT mirror llvm / 965be18
[ARM][MC] Cleanup ARM Target Assembly Parser Summary: Correctly parse end-of-statement tokens and handle preprocessor end-of-line comments in ARM assembly processor. Reviewers: rnk, majnemer Subscribers: aemerson, rengolin, llvm-commits Differential Revision: https://reviews.llvm.org/D26152 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285830 91177308-0d34-0410-b5e6-96231b3b80d8 Nirav Dave 3 years ago
4 changed file(s) with 555 addition(s) and 561 deletion(s). Raw diff Collapse all Expand all
7979
8080 const AsmToken &Lex() { return getParser().Lex(); }
8181 const AsmToken &getTok() { return getParser().getTok(); }
82 bool parseToken(AsmToken::TokenKind T, const Twine &Msg) {
82 bool parseToken(AsmToken::TokenKind T,
83 const Twine &Msg = "unexpected token") {
8384 return getParser().parseToken(T, Msg);
85 }
86
87 bool parseMany(std::function parseOne, bool hasComma = true) {
88 return getParser().parseMany(parseOne, hasComma);
89 }
90
91 bool parseOptionalToken(AsmToken::TokenKind T) {
92 return getParser().parseOptionalToken(T);
93 }
94
95 bool check(bool P, const llvm::Twine &Msg) {
96 return getParser().check(P, Msg);
97 }
98
99 bool check(bool P, SMLoc Loc, const llvm::Twine &Msg) {
100 return getParser().check(P, Loc, Msg);
101 }
102
103 bool addErrorSuffix(const Twine &Suffix) {
104 return getParser().addErrorSuffix(Suffix);
84105 }
85106
86107 bool HasBracketExpressions() const { return BracketExpressionsSupported; }
36093609 /// Parse a register list.
36103610 bool ARMAsmParser::parseRegisterList(OperandVector &Operands) {
36113611 MCAsmParser &Parser = getParser();
3612 assert(Parser.getTok().is(AsmToken::LCurly) &&
3613 "Token is not a Left Curly Brace");
3612 if (Parser.getTok().isNot(AsmToken::LCurly))
3613 return TokError("Token is not a Left Curly Brace");
36143614 SMLoc S = Parser.getTok().getLoc();
36153615 Parser.Lex(); // Eat '{' token.
36163616 SMLoc RegLoc = Parser.getTok().getLoc();
49954995 bool ARMAsmParser::parseMemory(OperandVector &Operands) {
49964996 MCAsmParser &Parser = getParser();
49974997 SMLoc S, E;
4998 assert(Parser.getTok().is(AsmToken::LBrac) &&
4999 "Token is not a Left Bracket");
4998 if (Parser.getTok().isNot(AsmToken::LBrac))
4999 return TokError("Token is not a Left Bracket");
50005000 S = Parser.getTok().getLoc();
50015001 Parser.Lex(); // Eat left bracket token.
50025002
61176117 return true;
61186118 }
61196119
6120 while (getLexer().is(AsmToken::Comma)) {
6121 Parser.Lex(); // Eat the comma.
6122
6120 while (parseOptionalToken(AsmToken::Comma)) {
61236121 // Parse and remember the operand.
61246122 if (parseOperand(Operands, Mnemonic)) {
61256123 return true;
61276125 }
61286126 }
61296127
6130 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6131 return TokError("unexpected token in argument list");
6132 }
6133
6134 Parser.Lex(); // Consume the EndOfStatement
6128 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
6129 return true;
61356130
61366131 if (RequireVFPRegisterListCheck) {
61376132 ARMOperand &Op = static_cast(*Operands.back());
61956190
61966191 // Rt2 must be Rt + 1 and Rt must be even.
61976192 if (Rt + 1 != Rt2 || (Rt & 1)) {
6198 Error(Op2.getStartLoc(), isLoad
6199 ? "destination operands must be sequential"
6200 : "source operands must be sequential");
6201 return true;
6193 return Error(Op2.getStartLoc(),
6194 isLoad ? "destination operands must be sequential"
6195 : "source operands must be sequential");
62026196 }
62036197 unsigned NewReg = MRI->getMatchingSuperReg(Reg1, ARM::gsub_0,
62046198 &(MRI->getRegClass(ARM::GPRPairRegClassID)));
92369230
92379231 StringRef IDVal = DirectiveID.getIdentifier();
92389232 if (IDVal == ".word")
9239 return parseLiteralValues(4, DirectiveID.getLoc());
9233 parseLiteralValues(4, DirectiveID.getLoc());
92409234 else if (IDVal == ".short" || IDVal == ".hword")
9241 return parseLiteralValues(2, DirectiveID.getLoc());
9235 parseLiteralValues(2, DirectiveID.getLoc());
92429236 else if (IDVal == ".thumb")
9243 return parseDirectiveThumb(DirectiveID.getLoc());
9237 parseDirectiveThumb(DirectiveID.getLoc());
92449238 else if (IDVal == ".arm")
9245 return parseDirectiveARM(DirectiveID.getLoc());
9239 parseDirectiveARM(DirectiveID.getLoc());
92469240 else if (IDVal == ".thumb_func")
9247 return parseDirectiveThumbFunc(DirectiveID.getLoc());
9241 parseDirectiveThumbFunc(DirectiveID.getLoc());
92489242 else if (IDVal == ".code")
9249 return parseDirectiveCode(DirectiveID.getLoc());
9243 parseDirectiveCode(DirectiveID.getLoc());
92509244 else if (IDVal == ".syntax")
9251 return parseDirectiveSyntax(DirectiveID.getLoc());
9245 parseDirectiveSyntax(DirectiveID.getLoc());
92529246 else if (IDVal == ".unreq")
9253 return parseDirectiveUnreq(DirectiveID.getLoc());
9247 parseDirectiveUnreq(DirectiveID.getLoc());
92549248 else if (IDVal == ".fnend")
9255 return parseDirectiveFnEnd(DirectiveID.getLoc());
9249 parseDirectiveFnEnd(DirectiveID.getLoc());
92569250 else if (IDVal == ".cantunwind")
9257 return parseDirectiveCantUnwind(DirectiveID.getLoc());
9251 parseDirectiveCantUnwind(DirectiveID.getLoc());
92589252 else if (IDVal == ".personality")
9259 return parseDirectivePersonality(DirectiveID.getLoc());
9253 parseDirectivePersonality(DirectiveID.getLoc());
92609254 else if (IDVal == ".handlerdata")
9261 return parseDirectiveHandlerData(DirectiveID.getLoc());
9255 parseDirectiveHandlerData(DirectiveID.getLoc());
92629256 else if (IDVal == ".setfp")
9263 return parseDirectiveSetFP(DirectiveID.getLoc());
9257 parseDirectiveSetFP(DirectiveID.getLoc());
92649258 else if (IDVal == ".pad")
9265 return parseDirectivePad(DirectiveID.getLoc());
9259 parseDirectivePad(DirectiveID.getLoc());
92669260 else if (IDVal == ".save")
9267 return parseDirectiveRegSave(DirectiveID.getLoc(), false);
9261 parseDirectiveRegSave(DirectiveID.getLoc(), false);
92689262 else if (IDVal == ".vsave")
9269 return parseDirectiveRegSave(DirectiveID.getLoc(), true);
9263 parseDirectiveRegSave(DirectiveID.getLoc(), true);
92709264 else if (IDVal == ".ltorg" || IDVal == ".pool")
9271 return parseDirectiveLtorg(DirectiveID.getLoc());
9265 parseDirectiveLtorg(DirectiveID.getLoc());
92729266 else if (IDVal == ".even")
9273 return parseDirectiveEven(DirectiveID.getLoc());
9267 parseDirectiveEven(DirectiveID.getLoc());
92749268 else if (IDVal == ".personalityindex")
9275 return parseDirectivePersonalityIndex(DirectiveID.getLoc());
9269 parseDirectivePersonalityIndex(DirectiveID.getLoc());
92769270 else if (IDVal == ".unwind_raw")
9277 return parseDirectiveUnwindRaw(DirectiveID.getLoc());
9271 parseDirectiveUnwindRaw(DirectiveID.getLoc());
92789272 else if (IDVal == ".movsp")
9279 return parseDirectiveMovSP(DirectiveID.getLoc());
9273 parseDirectiveMovSP(DirectiveID.getLoc());
92809274 else if (IDVal == ".arch_extension")
9281 return parseDirectiveArchExtension(DirectiveID.getLoc());
9275 parseDirectiveArchExtension(DirectiveID.getLoc());
92829276 else if (IDVal == ".align")
9283 return parseDirectiveAlign(DirectiveID.getLoc());
9277 return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
92849278 else if (IDVal == ".thumb_set")
9285 return parseDirectiveThumbSet(DirectiveID.getLoc());
9286
9287 if (!IsMachO && !IsCOFF) {
9279 parseDirectiveThumbSet(DirectiveID.getLoc());
9280 else if (!IsMachO && !IsCOFF) {
92889281 if (IDVal == ".arch")
9289 return parseDirectiveArch(DirectiveID.getLoc());
9282 parseDirectiveArch(DirectiveID.getLoc());
92909283 else if (IDVal == ".cpu")
9291 return parseDirectiveCPU(DirectiveID.getLoc());
9284 parseDirectiveCPU(DirectiveID.getLoc());
92929285 else if (IDVal == ".eabi_attribute")
9293 return parseDirectiveEabiAttr(DirectiveID.getLoc());
9286 parseDirectiveEabiAttr(DirectiveID.getLoc());
92949287 else if (IDVal == ".fpu")
9295 return parseDirectiveFPU(DirectiveID.getLoc());
9288 parseDirectiveFPU(DirectiveID.getLoc());
92969289 else if (IDVal == ".fnstart")
9297 return parseDirectiveFnStart(DirectiveID.getLoc());
9290 parseDirectiveFnStart(DirectiveID.getLoc());
92989291 else if (IDVal == ".inst")
9299 return parseDirectiveInst(DirectiveID.getLoc());
9292 parseDirectiveInst(DirectiveID.getLoc());
93009293 else if (IDVal == ".inst.n")
9301 return parseDirectiveInst(DirectiveID.getLoc(), 'n');
9294 parseDirectiveInst(DirectiveID.getLoc(), 'n');
93029295 else if (IDVal == ".inst.w")
9303 return parseDirectiveInst(DirectiveID.getLoc(), 'w');
9296 parseDirectiveInst(DirectiveID.getLoc(), 'w');
93049297 else if (IDVal == ".object_arch")
9305 return parseDirectiveObjectArch(DirectiveID.getLoc());
9298 parseDirectiveObjectArch(DirectiveID.getLoc());
93069299 else if (IDVal == ".tlsdescseq")
9307 return parseDirectiveTLSDescSeq(DirectiveID.getLoc());
9308 }
9309
9310 return true;
9300 parseDirectiveTLSDescSeq(DirectiveID.getLoc());
9301 else
9302 return true;
9303 } else
9304 return true;
9305 return false;
93119306 }
93129307
93139308 /// parseLiteralValues
93159310 /// ::= .short expression [, expression]*
93169311 /// ::= .word expression [, expression]*
93179312 bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
9318 MCAsmParser &Parser = getParser();
9319 if (getLexer().isNot(AsmToken::EndOfStatement)) {
9320 for (;;) {
9321 const MCExpr *Value;
9322 if (getParser().parseExpression(Value)) {
9323 return false;
9324 }
9325
9326 getParser().getStreamer().EmitValue(Value, Size, L);
9327
9328 if (getLexer().is(AsmToken::EndOfStatement))
9329 break;
9330
9331 // FIXME: Improve diagnostic.
9332 if (getLexer().isNot(AsmToken::Comma)) {
9333 Error(L, "unexpected token in directive");
9334 return false;
9335 }
9336 Parser.Lex();
9337 }
9338 }
9339
9340 Parser.Lex();
9341 return false;
9313 auto parseOne = [&]() -> bool {
9314 const MCExpr *Value;
9315 if (getParser().parseExpression(Value))
9316 return true;
9317 getParser().getStreamer().EmitValue(Value, Size, L);
9318 return false;
9319 };
9320 return (parseMany(parseOne));
93429321 }
93439322
93449323 /// parseDirectiveThumb
93459324 /// ::= .thumb
93469325 bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
9347 MCAsmParser &Parser = getParser();
9348 if (getLexer().isNot(AsmToken::EndOfStatement)) {
9349 Error(L, "unexpected token in directive");
9350 return false;
9351 }
9352 Parser.Lex();
9353
9354 if (!hasThumb()) {
9355 Error(L, "target does not support Thumb mode");
9356 return false;
9357 }
9326 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive") ||
9327 check(!hasThumb(), L, "target does not support Thumb mode"))
9328 return true;
93589329
93599330 if (!isThumb())
93609331 SwitchMode();
93669337 /// parseDirectiveARM
93679338 /// ::= .arm
93689339 bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
9369 MCAsmParser &Parser = getParser();
9370 if (getLexer().isNot(AsmToken::EndOfStatement)) {
9371 Error(L, "unexpected token in directive");
9372 return false;
9373 }
9374 Parser.Lex();
9375
9376 if (!hasARM()) {
9377 Error(L, "target does not support ARM mode");
9378 return false;
9379 }
9340 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive") ||
9341 check(!hasARM(), L, "target does not support ARM mode"))
9342 return true;
93809343
93819344 if (isThumb())
93829345 SwitchMode();
9383
93849346 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
93859347 return false;
93869348 }
94049366
94059367 // Darwin asm has (optionally) function name after .thumb_func direction
94069368 // ELF doesn't
9369
94079370 if (IsMachO) {
9408 const AsmToken &Tok = Parser.getTok();
9409 if (Tok.isNot(AsmToken::EndOfStatement)) {
9410 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) {
9411 Error(L, "unexpected token in .thumb_func directive");
9412 return false;
9413 }
9414
9415 MCSymbol *Func =
9416 getParser().getContext().getOrCreateSymbol(Tok.getIdentifier());
9371 if (Parser.getTok().is(AsmToken::Identifier) ||
9372 Parser.getTok().is(AsmToken::String)) {
9373 MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
9374 Parser.getTok().getIdentifier());
94179375 getParser().getStreamer().EmitThumbFunc(Func);
9418 Parser.Lex(); // Consume the identifier token.
9376 Parser.Lex();
9377 if (parseToken(AsmToken::EndOfStatement,
9378 "unexpected token in '.thumb_func' directive"))
9379 return true;
94199380 return false;
94209381 }
94219382 }
94229383
9423 if (getLexer().isNot(AsmToken::EndOfStatement)) {
9424 Error(Parser.getTok().getLoc(), "unexpected token in directive");
9425 return false;
9426 }
9384 if (parseToken(AsmToken::EndOfStatement,
9385 "unexpected token in '.thumb_func' directive"))
9386 return true;
94279387
94289388 NextSymbolIsThumb = true;
94299389 return false;
94409400 }
94419401
94429402 StringRef Mode = Tok.getString();
9443 if (Mode == "unified" || Mode == "UNIFIED") {
9444 Parser.Lex();
9445 } else if (Mode == "divided" || Mode == "DIVIDED") {
9446 Error(L, "'.syntax divided' arm asssembly not supported");
9447 return false;
9448 } else {
9449 Error(L, "unrecognized syntax mode in .syntax directive");
9450 return false;
9451 }
9452
9453 if (getLexer().isNot(AsmToken::EndOfStatement)) {
9454 Error(Parser.getTok().getLoc(), "unexpected token in directive");
9455 return false;
9456 }
94579403 Parser.Lex();
9404 if (check(Mode == "divided" || Mode == "DIVIDED", L,
9405 "'.syntax divided' arm assembly not supported") ||
9406 check(Mode != "unified" && Mode != "UNIFIED", L,
9407 "unrecognized syntax mode in .syntax directive") ||
9408 parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
9409 return true;
94589410
94599411 // TODO tell the MC streamer the mode
94609412 // getParser().getStreamer().Emit???();
94669418 bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
94679419 MCAsmParser &Parser = getParser();
94689420 const AsmToken &Tok = Parser.getTok();
9469 if (Tok.isNot(AsmToken::Integer)) {
9470 Error(L, "unexpected token in .code directive");
9471 return false;
9472 }
9421 if (Tok.isNot(AsmToken::Integer))
9422 return Error(L, "unexpected token in .code directive");
94739423 int64_t Val = Parser.getTok().getIntVal();
94749424 if (Val != 16 && Val != 32) {
94759425 Error(L, "invalid operand to .code directive");
94779427 }
94789428 Parser.Lex();
94799429
9480 if (getLexer().isNot(AsmToken::EndOfStatement)) {
9481 Error(Parser.getTok().getLoc(), "unexpected token in directive");
9482 return false;
9483 }
9484 Parser.Lex();
9430 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
9431 return true;
94859432
94869433 if (Val == 16) {
9487 if (!hasThumb()) {
9488 Error(L, "target does not support Thumb mode");
9489 return false;
9490 }
9434 if (!hasThumb())
9435 return Error(L, "target does not support Thumb mode");
94919436
94929437 if (!isThumb())
94939438 SwitchMode();
94949439 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
94959440 } else {
9496 if (!hasARM()) {
9497 Error(L, "target does not support ARM mode");
9498 return false;
9499 }
9441 if (!hasARM())
9442 return Error(L, "target does not support ARM mode");
95009443
95019444 if (isThumb())
95029445 SwitchMode();
95139456 Parser.Lex(); // Eat the '.req' token.
95149457 unsigned Reg;
95159458 SMLoc SRegLoc, ERegLoc;
9516 if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
9517 Error(SRegLoc, "register name expected");
9518 return false;
9519 }
9520
9521 // Shouldn't be anything else.
9522 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
9523 Error(Parser.getTok().getLoc(), "unexpected input in .req directive.");
9524 return false;
9525 }
9526
9527 Parser.Lex(); // Consume the EndOfStatement
9528
9529 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg) {
9530 Error(SRegLoc, "redefinition of '" + Name + "' does not match original.");
9531 return false;
9532 }
9459 if (check(ParseRegister(Reg, SRegLoc, ERegLoc), SRegLoc,
9460 "register name expected") ||
9461 parseToken(AsmToken::EndOfStatement,
9462 "unexpected input in .req directive."))
9463 return true;
9464
9465 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg)
9466 return Error(SRegLoc,
9467 "redefinition of '" + Name + "' does not match original.");
95339468
95349469 return false;
95359470 }
95389473 /// ::= .unreq registername
95399474 bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
95409475 MCAsmParser &Parser = getParser();
9541 if (Parser.getTok().isNot(AsmToken::Identifier)) {
9542 Error(L, "unexpected input in .unreq directive.");
9543 return false;
9544 }
9476 if (Parser.getTok().isNot(AsmToken::Identifier))
9477 return Error(L, "unexpected input in .unreq directive.");
95459478 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
95469479 Parser.Lex(); // Eat the identifier.
9480 if (parseToken(AsmToken::EndOfStatement,
9481 "unexpected input in '.unreq' directive"))
9482 return true;
95479483 return false;
95489484 }
95499485
95769512 /// ::= .arch token
95779513 bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
95789514 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
9579
95809515 unsigned ID = ARM::parseArch(Arch);
95819516
9582 if (ID == ARM::AK_INVALID) {
9583 Error(L, "Unknown arch name");
9584 return false;
9585 }
9517 if (ID == ARM::AK_INVALID)
9518 return Error(L, "Unknown arch name");
95869519
95879520 bool WasThumb = isThumb();
95889521 Triple T;
96159548 const MCExpr *AttrExpr;
96169549
96179550 TagLoc = Parser.getTok().getLoc();
9618 if (Parser.parseExpression(AttrExpr)) {
9619 return false;
9620 }
9551 if (Parser.parseExpression(AttrExpr))
9552 return true;
96219553
96229554 const MCConstantExpr *CE = dyn_cast(AttrExpr);
9623 if (!CE) {
9624 Error(TagLoc, "expected numeric constant");
9625 return false;
9626 }
9555 if (check(!CE, TagLoc, "expected numeric constant"))
9556 return true;
96279557
96289558 Tag = CE->getValue();
96299559 }
96309560
9631 if (Parser.getTok().isNot(AsmToken::Comma)) {
9632 Error(Parser.getTok().getLoc(), "comma expected");
9633 return false;
9634 }
9635 Parser.Lex(); // skip comma
9561 if (Parser.parseToken(AsmToken::Comma, "comma expected"))
9562 return true;
96369563
96379564 StringRef StringValue = "";
96389565 bool IsStringValue = false;
96559582 if (IsIntegerValue) {
96569583 const MCExpr *ValueExpr;
96579584 SMLoc ValueExprLoc = Parser.getTok().getLoc();
9658 if (Parser.parseExpression(ValueExpr)) {
9659 return false;
9660 }
9585 if (Parser.parseExpression(ValueExpr))
9586 return true;
96619587
96629588 const MCConstantExpr *CE = dyn_cast(ValueExpr);
9663 if (!CE) {
9664 Error(ValueExprLoc, "expected numeric constant");
9665 return false;
9666 }
9667
9589 if (!CE)
9590 return Error(ValueExprLoc, "expected numeric constant");
96689591 IntegerValue = CE->getValue();
96699592 }
96709593
96719594 if (Tag == ARMBuildAttrs::compatibility) {
9672 if (Parser.getTok().isNot(AsmToken::Comma))
9673 IsStringValue = false;
9674 if (Parser.getTok().isNot(AsmToken::Comma)) {
9675 Error(Parser.getTok().getLoc(), "comma expected");
9676 return false;
9677 } else {
9678 Parser.Lex();
9679 }
9595 if (Parser.parseToken(AsmToken::Comma, "comma expected"))
9596 return true;
96809597 }
96819598
96829599 if (IsStringValue) {
9683 if (Parser.getTok().isNot(AsmToken::String)) {
9684 Error(Parser.getTok().getLoc(), "bad string constant");
9685 return false;
9686 }
9600 if (Parser.getTok().isNot(AsmToken::String))
9601 return Error(Parser.getTok().getLoc(), "bad string constant");
96879602
96889603 StringValue = Parser.getTok().getStringContents();
96899604 Parser.Lex();
96909605 }
9606
9607 if (Parser.parseToken(AsmToken::EndOfStatement,
9608 "unexpected token in '.eabi_attribute' directive"))
9609 return true;
96919610
96929611 if (IsIntegerValue && IsStringValue) {
96939612 assert(Tag == ARMBuildAttrs::compatibility);
97079626
97089627 // FIXME: This is using table-gen data, but should be moved to
97099628 // ARMTargetParser once that is table-gen'd.
9710 if (!getSTI().isCPUStringValid(CPU)) {
9711 Error(L, "Unknown CPU name");
9712 return false;
9713 }
9629 if (!getSTI().isCPUStringValid(CPU))
9630 return Error(L, "Unknown CPU name");
97149631
97159632 bool WasThumb = isThumb();
97169633 MCSubtargetInfo &STI = copySTI();
97289645
97299646 unsigned ID = ARM::parseFPU(FPU);
97309647 std::vector Features;
9731 if (!ARM::getFPUFeatures(ID, Features)) {
9732 Error(FPUNameLoc, "Unknown FPU name");
9733 return false;
9734 }
9648 if (!ARM::getFPUFeatures(ID, Features))
9649 return Error(FPUNameLoc, "Unknown FPU name");
97359650
97369651 MCSubtargetInfo &STI = copySTI();
97379652 for (auto Feature : Features)
97459660 /// parseDirectiveFnStart
97469661 /// ::= .fnstart
97479662 bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
9663 if (parseToken(AsmToken::EndOfStatement,
9664 "unexpected token in '.fnstart' directive"))
9665 return true;
9666
97489667 if (UC.hasFnStart()) {
97499668 Error(L, ".fnstart starts before the end of previous one");
97509669 UC.emitFnStartLocNotes();
9751 return false;
9670 return true;
97529671 }
97539672
97549673 // Reset the unwind directives parser state
97639682 /// parseDirectiveFnEnd
97649683 /// ::= .fnend
97659684 bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
9685 if (parseToken(AsmToken::EndOfStatement,
9686 "unexpected token in '.fnend' directive"))
9687 return true;
97669688 // Check the ordering of unwind directives
9767 if (!UC.hasFnStart()) {
9768 Error(L, ".fnstart must precede .fnend directive");
9769 return false;
9770 }
9689 if (!UC.hasFnStart())
9690 return Error(L, ".fnstart must precede .fnend directive");
97719691
97729692 // Reset the unwind directives parser state
97739693 getTargetStreamer().emitFnEnd();
97799699 /// parseDirectiveCantUnwind
97809700 /// ::= .cantunwind
97819701 bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
9702 if (parseToken(AsmToken::EndOfStatement,
9703 "unexpected token in '.cantunwind' directive"))
9704 return true;
9705
97829706 UC.recordCantUnwind(L);
9783
97849707 // Check the ordering of unwind directives
9785 if (!UC.hasFnStart()) {
9786 Error(L, ".fnstart must precede .cantunwind directive");
9787 return false;
9788 }
9708 if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive"))
9709 return true;
9710
97899711 if (UC.hasHandlerData()) {
97909712 Error(L, ".cantunwind can't be used with .handlerdata directive");
97919713 UC.emitHandlerDataLocNotes();
9792 return false;
9714 return true;
97939715 }
97949716 if (UC.hasPersonality()) {
97959717 Error(L, ".cantunwind can't be used with .personality directive");
97969718 UC.emitPersonalityLocNotes();
9797 return false;
9719 return true;
97989720 }
97999721
98009722 getTargetStreamer().emitCantUnwind();
98079729 MCAsmParser &Parser = getParser();
98089730 bool HasExistingPersonality = UC.hasPersonality();
98099731
9732 // Parse the name of the personality routine
9733 if (Parser.getTok().isNot(AsmToken::Identifier))
9734 return Error(L, "unexpected input in .personality directive.");
9735 StringRef Name(Parser.getTok().getIdentifier());
9736 Parser.Lex();
9737
9738 if (parseToken(AsmToken::EndOfStatement,
9739 "unexpected token in '.personality' directive"))
9740 return true;
9741
98109742 UC.recordPersonality(L);
98119743
98129744 // Check the ordering of unwind directives
9813 if (!UC.hasFnStart()) {
9814 Error(L, ".fnstart must precede .personality directive");
9815 return false;
9816 }
9745 if (!UC.hasFnStart())
9746 return Error(L, ".fnstart must precede .personality directive");
98179747 if (UC.cantUnwind()) {
98189748 Error(L, ".personality can't be used with .cantunwind directive");
98199749 UC.emitCantUnwindLocNotes();
9820 return false;
9750 return true;
98219751 }
98229752 if (UC.hasHandlerData()) {
98239753 Error(L, ".personality must precede .handlerdata directive");
98249754 UC.emitHandlerDataLocNotes();
9825 return false;
9755 return true;
98269756 }
98279757 if (HasExistingPersonality) {
98289758 Error(L, "multiple personality directives");
98299759 UC.emitPersonalityLocNotes();
9830 return false;
9831 }
9832
9833 // Parse the name of the personality routine
9834 if (Parser.getTok().isNot(AsmToken::Identifier)) {
9835 Error(L, "unexpected input in .personality directive.");
9836 return false;
9837 }
9838 StringRef Name(Parser.getTok().getIdentifier());
9839 Parser.Lex();
9760 return true;
9761 }
98409762
98419763 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
98429764 getTargetStreamer().emitPersonality(PR);
98469768 /// parseDirectiveHandlerData
98479769 /// ::= .handlerdata
98489770 bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
9771 if (parseToken(AsmToken::EndOfStatement,
9772 "unexpected token in '.handlerdata' directive"))
9773 return true;
9774
98499775 UC.recordHandlerData(L);
9850
98519776 // Check the ordering of unwind directives
9852 if (!UC.hasFnStart()) {
9853 Error(L, ".fnstart must precede .personality directive");
9854 return false;
9855 }
9777 if (!UC.hasFnStart())
9778 return Error(L, ".fnstart must precede .personality directive");
98569779 if (UC.cantUnwind()) {
98579780 Error(L, ".handlerdata can't be used with .cantunwind directive");
98589781 UC.emitCantUnwindLocNotes();
9859 return false;
9782 return true;
98609783 }
98619784
98629785 getTargetStreamer().emitHandlerData();
98689791 bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
98699792 MCAsmParser &Parser = getParser();
98709793 // Check the ordering of unwind directives
9871 if (!UC.hasFnStart()) {
9872 Error(L, ".fnstart must precede .setfp directive");
9873 return false;
9874 }
9875 if (UC.hasHandlerData()) {
9876 Error(L, ".setfp must precede .handlerdata directive");
9877 return false;
9878 }
9794 if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") ||
9795 check(UC.hasHandlerData(), L,
9796 ".setfp must precede .handlerdata directive"))
9797 return true;
98799798
98809799 // Parse fpreg
98819800 SMLoc FPRegLoc = Parser.getTok().getLoc();
98829801 int FPReg = tryParseRegister();
9883 if (FPReg == -1) {
9884 Error(FPRegLoc, "frame pointer register expected");
9885 return false;
9886 }
9887
9888 // Consume comma
9889 if (Parser.getTok().isNot(AsmToken::Comma)) {
9890 Error(Parser.getTok().getLoc(), "comma expected");
9891 return false;
9892 }
9893 Parser.Lex(); // skip comma
9802
9803 if (check(FPReg == -1, FPRegLoc, "frame pointer register expected") ||
9804 Parser.parseToken(AsmToken::Comma, "comma expected"))
9805 return true;
98949806
98959807 // Parse spreg
98969808 SMLoc SPRegLoc = Parser.getTok().getLoc();
98979809 int SPReg = tryParseRegister();
9898 if (SPReg == -1) {
9899 Error(SPRegLoc, "stack pointer register expected");
9900 return false;
9901 }
9902
9903 if (SPReg != ARM::SP && SPReg != UC.getFPReg()) {
9904 Error(SPRegLoc, "register should be either $sp or the latest fp register");
9905 return false;
9906 }
9810 if (check(SPReg == -1, SPRegLoc, "stack pointer register expected") ||
9811 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
9812 "register should be either $sp or the latest fp register"))
9813 return true;
99079814
99089815 // Update the frame pointer register
99099816 UC.saveFPReg(FPReg);
99109817
99119818 // Parse offset
99129819 int64_t Offset = 0;
9913 if (Parser.getTok().is(AsmToken::Comma)) {
9914 Parser.Lex(); // skip comma
9915
9820 if (Parser.parseOptionalToken(AsmToken::Comma)) {
99169821 if (Parser.getTok().isNot(AsmToken::Hash) &&
9917 Parser.getTok().isNot(AsmToken::Dollar)) {
9918 Error(Parser.getTok().getLoc(), "'#' expected");
9919 return false;
9920 }
9822 Parser.getTok().isNot(AsmToken::Dollar))
9823 return Error(Parser.getTok().getLoc(), "'#' expected");
99219824 Parser.Lex(); // skip hash token.
99229825
99239826 const MCExpr *OffsetExpr;
99249827 SMLoc ExLoc = Parser.getTok().getLoc();
99259828 SMLoc EndLoc;
9926 if (getParser().parseExpression(OffsetExpr, EndLoc)) {
9927 Error(ExLoc, "malformed setfp offset");
9928 return false;
9929 }
9829 if (getParser().parseExpression(OffsetExpr, EndLoc))
9830 return Error(ExLoc, "malformed setfp offset");
99309831 const MCConstantExpr *CE = dyn_cast(OffsetExpr);
9931 if (!CE) {
9932 Error(ExLoc, "setfp offset must be an immediate");
9933 return false;
9934 }
9935
9832 if (check(!CE, ExLoc, "setfp offset must be an immediate"))
9833 return true;
99369834 Offset = CE->getValue();
99379835 }
9836
9837 if (Parser.parseToken(AsmToken::EndOfStatement))
9838 return true;
99389839
99399840 getTargetStreamer().emitSetFP(static_cast(FPReg),
99409841 static_cast(SPReg), Offset);
99469847 bool ARMAsmParser::parseDirectivePad(SMLoc L) {
99479848 MCAsmParser &Parser = getParser();
99489849 // Check the ordering of unwind directives
9949 if (!UC.hasFnStart()) {
9950 Error(L, ".fnstart must precede .pad directive");
9951 return false;
9952 }
9953 if (UC.hasHandlerData()) {
9954 Error(L, ".pad must precede .handlerdata directive");
9955 return false;
9956 }
9850 if (!UC.hasFnStart())
9851 return Error(L, ".fnstart must precede .pad directive");
9852 if (UC.hasHandlerData())
9853 return Error(L, ".pad must precede .handlerdata directive");
99579854
99589855 // Parse the offset
99599856 if (Parser.getTok().isNot(AsmToken::Hash) &&
9960 Parser.getTok().isNot(AsmToken::Dollar)) {
9961 Error(Parser.getTok().getLoc(), "'#' expected");
9962 return false;
9963 }
9857 Parser.getTok().isNot(AsmToken::Dollar))
9858 return Error(Parser.getTok().getLoc(), "'#' expected");
99649859 Parser.Lex(); // skip hash token.
99659860
99669861 const MCExpr *OffsetExpr;
99679862 SMLoc ExLoc = Parser.getTok().getLoc();
99689863 SMLoc EndLoc;
9969 if (getParser().parseExpression(OffsetExpr, EndLoc)) {
9970 Error(ExLoc, "malformed pad offset");
9971 return false;
9972 }
9864 if (getParser().parseExpression(OffsetExpr, EndLoc))
9865 return Error(ExLoc, "malformed pad offset");
99739866 const MCConstantExpr *CE = dyn_cast(OffsetExpr);
9974 if (!CE) {
9975 Error(ExLoc, "pad offset must be an immediate");
9976 return false;
9977 }
9867 if (!CE)
9868 return Error(ExLoc, "pad offset must be an immediate");
9869
9870 if (parseToken(AsmToken::EndOfStatement,
9871 "unexpected token in '.pad' directive"))
9872 return true;
99789873
99799874 getTargetStreamer().emitPad(CE->getValue());
99809875 return false;
99859880 /// ::= .vsave { registers }
99869881 bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
99879882 // Check the ordering of unwind directives
9988 if (!UC.hasFnStart()) {
9989 Error(L, ".fnstart must precede .save or .vsave directives");
9990 return false;
9991 }
9992 if (UC.hasHandlerData()) {
9993 Error(L, ".save or .vsave must precede .handlerdata directive");
9994 return false;
9995 }
9883 if (!UC.hasFnStart())
9884 return Error(L, ".fnstart must precede .save or .vsave directives");
9885 if (UC.hasHandlerData())
9886 return Error(L, ".save or .vsave must precede .handlerdata directive");
99969887
99979888 // RAII object to make sure parsed operands are deleted.
99989889 SmallVector, 1> Operands;
99999890
100009891 // Parse the register list
10001 if (parseRegisterList(Operands))
10002 return false;
9892 if (parseRegisterList(Operands) ||
9893 parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
9894 return true;
100039895 ARMOperand &Op = (ARMOperand &)*Operands[0];
10004 if (!IsVector && !Op.isRegList()) {
10005 Error(L, ".save expects GPR registers");
10006 return false;
10007 }
10008 if (IsVector && !Op.isDPRRegList()) {
10009 Error(L, ".vsave expects DPR registers");
10010 return false;
10011 }
9896 if (!IsVector && !Op.isRegList())
9897 return Error(L, ".save expects GPR registers");
9898 if (IsVector && !Op.isDPRRegList())
9899 return Error(L, ".vsave expects DPR registers");
100129900
100139901 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
100149902 return false;
100199907 /// ::= .inst.n opcode [, ...]
100209908 /// ::= .inst.w opcode [, ...]
100219909 bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
10022 MCAsmParser &Parser = getParser();
10023 int Width;
9910 int Width = 4;
100249911
100259912 if (isThumb()) {
100269913 switch (Suffix) {
100289915 Width = 2;
100299916 break;
100309917 case 'w':
10031 Width = 4;
100329918 break;
100339919 default:
10034 Error(Loc, "cannot determine Thumb instruction size, "
10035 "use inst.n/inst.w instead");
10036 return false;
9920 return Error(Loc, "cannot determine Thumb instruction size, "
9921 "use inst.n/inst.w instead");
100379922 }
100389923 } else {
10039 if (Suffix) {
10040 Error(Loc, "width suffixes are invalid in ARM mode");
10041 return false;
10042 }
10043 Width = 4;
10044 }
10045
10046 if (getLexer().is(AsmToken::EndOfStatement)) {
10047 Error(Loc, "expected expression following directive");
10048 return false;
10049 }
10050
10051 for (;;) {
9924 if (Suffix)
9925 return Error(Loc, "width suffixes are invalid in ARM mode");
9926 }
9927
9928 auto parseOne = [&]() -> bool {
100529929 const MCExpr *Expr;
10053
10054 if (getParser().parseExpression(Expr)) {
10055 Error(Loc, "expected expression");
10056 return false;
10057 }
10058
9930 if (getParser().parseExpression(Expr))
9931 return true;
100599932 const MCConstantExpr *Value = dyn_cast_or_null(Expr);
100609933 if (!Value) {
10061 Error(Loc, "expected constant expression");
10062 return false;
9934 return Error(Loc, "expected constant expression");
100639935 }
100649936
100659937 switch (Width) {
100669938 case 2:
10067 if (Value->getValue() > 0xffff) {
10068 Error(Loc, "inst.n operand is too big, use inst.w instead");
10069 return false;
10070 }
9939 if (Value->getValue() > 0xffff)
9940 return Error(Loc, "inst.n operand is too big, use inst.w instead");
100719941 break;
100729942 case 4:
10073 if (Value->getValue() > 0xffffffff) {
10074 Error(Loc,
10075 StringRef(Suffix ? "inst.w" : "inst") + " operand is too big");
10076 return false;
10077 }
9943 if (Value->getValue() > 0xffffffff)
9944 return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +
9945 " operand is too big");
100789946 break;
100799947 default:
100809948 llvm_unreachable("only supported widths are 2 and 4");
100819949 }
100829950
100839951 getTargetStreamer().emitInst(Value->getValue(), Suffix);
10084
10085 if (getLexer().is(AsmToken::EndOfStatement))
10086 break;
10087
10088 if (getLexer().isNot(AsmToken::Comma)) {
10089 Error(Loc, "unexpected token in directive");
10090 return false;
10091 }
10092
10093 Parser.Lex();
10094 }
10095
10096 Parser.Lex();
9952 return false;
9953 };
9954
9955 if (parseOptionalToken(AsmToken::EndOfStatement))
9956 return Error(Loc, "expected expression following directive");
9957 if (parseMany(parseOne))
9958 return true;
100979959 return false;
100989960 }
100999961
101009962 /// parseDirectiveLtorg
101019963 /// ::= .ltorg | .pool
101029964 bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
9965 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
9966 return true;
101039967 getTargetStreamer().emitCurrentConstantPool();
101049968 return false;
101059969 }
101079971 bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
101089972 const MCSection *Section = getStreamer().getCurrentSectionOnly();
101099973
10110 if (getLexer().isNot(AsmToken::EndOfStatement)) {
10111 TokError("unexpected token in directive");
10112 return false;
10113 }
9974 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
9975 return true;
101149976
101159977 if (!Section) {
101169978 getStreamer().InitSections(false);
101329994 MCAsmParser &Parser = getParser();
101339995 bool HasExistingPersonality = UC.hasPersonality();
101349996
9997 const MCExpr *IndexExpression;
9998 SMLoc IndexLoc = Parser.getTok().getLoc();
9999 if (Parser.parseExpression(IndexExpression) ||
10000 parseToken(AsmToken::EndOfStatement,
10001 "unexpected token in '.personalityindex' directive")) {
10002 return true;
10003 }
10004
1013510005 UC.recordPersonalityIndex(L);
1013610006
1013710007 if (!UC.hasFnStart()) {
10138 Error(L, ".fnstart must precede .personalityindex directive");
10139 return false;
10008 return Error(L, ".fnstart must precede .personalityindex directive");
1014010009 }
1014110010 if (UC.cantUnwind()) {
1014210011 Error(L, ".personalityindex cannot be used with .cantunwind");
1014310012 UC.emitCantUnwindLocNotes();
10144 return false;
10013 return true;
1014510014 }
1014610015 if (UC.hasHandlerData()) {
1014710016 Error(L, ".personalityindex must precede .handlerdata directive");
1014810017 UC.emitHandlerDataLocNotes();
10149 return false;
10018 return true;
1015010019 }
1015110020 if (HasExistingPersonality) {
1015210021 Error(L, "multiple personality directives");
1015310022 UC.emitPersonalityLocNotes();
10154 return false;
10155 }
10156
10157 const MCExpr *IndexExpression;
10158 SMLoc IndexLoc = Parser.getTok().getLoc();
10159 if (Parser.parseExpression(IndexExpression)) {
10160 return false;
10023 return true;
1016110024 }
1016210025
1016310026 const MCConstantExpr *CE = dyn_cast(IndexExpression);
10164 if (!CE) {
10165 Error(IndexLoc, "index must be a constant number");
10166 return false;
10167 }
10168 if (CE->getValue() < 0 ||
10169 CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX) {
10170 Error(IndexLoc, "personality routine index should be in range [0-3]");
10171 return false;
10172 }
10027 if (!CE)
10028 return Error(IndexLoc, "index must be a constant number");
10029 if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX)
10030 return Error(IndexLoc,
10031 "personality routine index should be in range [0-3]");
1017310032
1017410033 getTargetStreamer().emitPersonalityIndex(CE->getValue());
1017510034 return false;
1017910038 /// ::= .unwind_raw offset, opcode [, opcode...]
1018010039 bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
1018110040 MCAsmParser &Parser = getParser();
10182 if (!UC.hasFnStart()) {
10183 Error(L, ".fnstart must precede .unwind_raw directives");
10184 return false;
10185 }
10186
1018710041 int64_t StackOffset;
10188
1018910042 const MCExpr *OffsetExpr;
1019010043 SMLoc OffsetLoc = getLexer().getLoc();
10191 if (getLexer().is(AsmToken::EndOfStatement) ||
10192 getParser().parseExpression(OffsetExpr)) {
10193 Error(OffsetLoc, "expected expression");
10044
10045 if (!UC.hasFnStart())
10046 return Error(L, ".fnstart must precede .unwind_raw directives");
10047 if (getParser().parseExpression(OffsetExpr))
10048 return Error(OffsetLoc, "expected expression");
10049
10050 const MCConstantExpr *CE = dyn_cast(OffsetExpr);
10051 if (!CE)
10052 return Error(OffsetLoc, "offset must be a constant");
10053
10054 StackOffset = CE->getValue();
10055
10056 if (Parser.parseToken(AsmToken::Comma, "expected comma"))
10057 return true;
10058
10059 SmallVector Opcodes;
10060
10061 auto parseOne = [&]() -> bool {
10062 const MCExpr *OE;
10063 SMLoc OpcodeLoc = getLexer().getLoc();
10064 if (check(getLexer().is(AsmToken::EndOfStatement) ||
10065 Parser.parseExpression(OE),
10066 OpcodeLoc, "expected opcode expression"))
10067 return true;
10068 const MCConstantExpr *OC = dyn_cast(OE);
10069 if (!OC)
10070 return Error(OpcodeLoc, "opcode value must be a constant");
10071 const int64_t Opcode = OC->getValue();
10072 if (Opcode & ~0xff)
10073 return Error(OpcodeLoc, "invalid opcode");
10074 Opcodes.push_back(uint8_t(Opcode));
1019410075 return false;
10195 }
10196
10197 const MCConstantExpr *CE = dyn_cast(OffsetExpr);
10198 if (!CE) {
10199 Error(OffsetLoc, "offset must be a constant");
10200 return false;
10201 }
10202
10203 StackOffset = CE->getValue();
10204
10205 if (getLexer().isNot(AsmToken::Comma)) {
10206 Error(getLexer().getLoc(), "expected comma");
10207 return false;
10208 }
10209 Parser.Lex();
10210
10211 SmallVector Opcodes;
10212 for (;;) {
10213 const MCExpr *OE;
10214
10215 SMLoc OpcodeLoc = getLexer().getLoc();
10216 if (getLexer().is(AsmToken::EndOfStatement) || Parser.parseExpression(OE)) {
10217 Error(OpcodeLoc, "expected opcode expression");
10218 return false;
10219 }
10220
10221 const MCConstantExpr *OC = dyn_cast(OE);
10222 if (!OC) {
10223 Error(OpcodeLoc, "opcode value must be a constant");
10224 return false;
10225 }
10226
10227 const int64_t Opcode = OC->getValue();
10228 if (Opcode & ~0xff) {
10229 Error(OpcodeLoc, "invalid opcode");
10230 return false;
10231 }
10232
10233 Opcodes.push_back(uint8_t(Opcode));
10234
10235 if (getLexer().is(AsmToken::EndOfStatement))
10236 break;
10237
10238 if (getLexer().isNot(AsmToken::Comma)) {
10239 Error(getLexer().getLoc(), "unexpected token in directive");
10240 return false;
10241 }
10242
10243 Parser.Lex();
10244 }
10076 };
10077
10078 // Must have at least 1 element
10079 SMLoc OpcodeLoc = getLexer().getLoc();
10080 if (parseOptionalToken(AsmToken::EndOfStatement))
10081 return Error(OpcodeLoc, "expected opcode expression");
10082 if (parseMany(parseOne))
10083 return true;
1024510084
1024610085 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
10247
10248 Parser.Lex();
1024910086 return false;
1025010087 }
1025110088
1025410091 bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
1025510092 MCAsmParser &Parser = getParser();
1025610093
10257 if (getLexer().isNot(AsmToken::Identifier)) {
10258 TokError("expected variable after '.tlsdescseq' directive");
10259 return false;
10260 }
10094 if (getLexer().isNot(AsmToken::Identifier))
10095 return TokError("expected variable after '.tlsdescseq' directive");
1026110096
1026210097 const MCSymbolRefExpr *SRE =
1026310098 MCSymbolRefExpr::create(Parser.getTok().getIdentifier(),
1026410099 MCSymbolRefExpr::VK_ARM_TLSDESCSEQ, getContext());
1026510100 Lex();
1026610101
10267 if (getLexer().isNot(AsmToken::EndOfStatement)) {
10268 Error(Parser.getTok().getLoc(), "unexpected token");
10269 return false;
10270 }
10102 if (parseToken(AsmToken::EndOfStatement,
10103 "unexpected token in '.tlsdescseq' directive"))
10104 return true;
1027110105
1027210106 getTargetStreamer().AnnotateTLSDescriptorSequence(SRE);
1027310107 return false;
1027710111 /// ::= .movsp reg [, #offset]
1027810112 bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
1027910113 MCAsmParser &Parser = getParser();
10280 if (!UC.hasFnStart()) {
10281 Error(L, ".fnstart must precede .movsp directives");
10282 return false;
10283 }
10284 if (UC.getFPReg() != ARM::SP) {
10285 Error(L, "unexpected .movsp directive");
10286 return false;
10287 }
10114 if (!UC.hasFnStart())
10115 return Error(L, ".fnstart must precede .movsp directives");
10116 if (UC.getFPReg() != ARM::SP)
10117 return Error(L, "unexpected .movsp directive");
1028810118
1028910119 SMLoc SPRegLoc = Parser.getTok().getLoc();
1029010120 int SPReg = tryParseRegister();
10291 if (SPReg == -1) {
10292 Error(SPRegLoc, "register expected");
10293 return false;
10294 }
10295
10296 if (SPReg == ARM::SP || SPReg == ARM::PC) {
10297 Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
10298 return false;
10299 }
10121 if (SPReg == -1)
10122 return Error(SPRegLoc, "register expected");
10123 if (SPReg == ARM::SP || SPReg == ARM::PC)
10124 return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
1030010125
1030110126 int64_t Offset = 0;
10302 if (Parser.getTok().is(AsmToken::Comma)) {
10303 Parser.Lex();
10304
10305 if (Parser.getTok().isNot(AsmToken::Hash)) {
10306 Error(Parser.getTok().getLoc(), "expected #constant");
10307 return false;
10308 }
10309 Parser.Lex();
10127 if (Parser.parseOptionalToken(AsmToken::Comma)) {
10128 if (Parser.parseToken(AsmToken::Hash, "expected #constant"))
10129 return true;
1031010130
1031110131 const MCExpr *OffsetExpr;
1031210132 SMLoc OffsetLoc = Parser.getTok().getLoc();
10313 if (Parser.parseExpression(OffsetExpr)) {
10314 Error(OffsetLoc, "malformed offset expression");
10315 return false;
10316 }
10133
10134 if (Parser.parseExpression(OffsetExpr))
10135 return Error(OffsetLoc, "malformed offset expression");
1031710136
1031810137 const MCConstantExpr *CE = dyn_cast(OffsetExpr);
10319 if (!CE) {
10320 Error(OffsetLoc, "offset must be an immediate constant");
10321 return false;
10322 }
10138 if (!CE)
10139 return Error(OffsetLoc, "offset must be an immediate constant");
1032310140
1032410141 Offset = CE->getValue();
1032510142 }
10143
10144 if (parseToken(AsmToken::EndOfStatement,
10145 "unexpected token in '.movsp' directive"))
10146 return true;
1032610147
1032710148 getTargetStreamer().emitMovSP(SPReg, Offset);
1032810149 UC.saveFPReg(SPReg);
1033410155 /// ::= .object_arch name
1033510156 bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
1033610157 MCAsmParser &Parser = getParser();
10337 if (getLexer().isNot(AsmToken::Identifier)) {
10338 Error(getLexer().getLoc(), "unexpected token");
10339 return false;
10340 }
10158 if (getLexer().isNot(AsmToken::Identifier))
10159 return Error(getLexer().getLoc(), "unexpected token");
1034110160
1034210161 StringRef Arch = Parser.getTok().getString();
1034310162 SMLoc ArchLoc = Parser.getTok().getLoc();
1034510164
1034610165 unsigned ID = ARM::parseArch(Arch);
1034710166
10348 if (ID == ARM::AK_INVALID) {
10349 Error(ArchLoc, "unknown architecture '" + Arch + "'");
10350 return false;
10351 }
10167 if (ID == ARM::AK_INVALID)
10168 return Error(ArchLoc, "unknown architecture '" + Arch + "'");
10169 if (parseToken(AsmToken::EndOfStatement))
10170 return true;
1035210171
1035310172 getTargetStreamer().emitObjectArch(ID);
10354
10355 if (getLexer().isNot(AsmToken::EndOfStatement)) {
10356 Error(getLexer().getLoc(), "unexpected token");
10357 }
10358
1035910173 return false;
1036010174 }
1036110175
1036410178 bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
1036510179 // NOTE: if this is not the end of the statement, fall back to the target
1036610180 // agnostic handling for this directive which will correctly handle this.
10367 if (getLexer().isNot(AsmToken::EndOfStatement))
10368 return true;
10369
10370 // '.align' is target specifically handled to mean 2**2 byte alignment.
10371 const MCSection *Section = getStreamer().getCurrentSectionOnly();
10372 assert(Section && "must have section to emit alignment");
10373 if (Section->UseCodeAlign())
10374 getStreamer().EmitCodeAlignment(4, 0);
10375 else
10376 getStreamer().EmitValueToAlignment(4, 0, 1, 0);
10377
10378 return false;
10181 if (parseOptionalToken(AsmToken::EndOfStatement)) {
10182 // '.align' is target specifically handled to mean 2**2 byte alignment.
10183 const MCSection *Section = getStreamer().getCurrentSectionOnly();
10184 assert(Section && "must have section to emit alignment");
10185 if (Section->UseCodeAlign())
10186 getStreamer().EmitCodeAlignment(4, 0);
10187 else
10188 getStreamer().EmitValueToAlignment(4, 0, 1, 0);
10189 return false;
10190 }
10191 return true;
1037910192 }
1038010193
1038110194 /// parseDirectiveThumbSet
1038410197 MCAsmParser &Parser = getParser();
1038510198
1038610199 StringRef Name;
10387 if (Parser.parseIdentifier(Name)) {
10388 TokError("expected identifier after '.thumb_set'");
10389 return false;
10390 }
10391
10392 if (getLexer().isNot(AsmToken::Comma)) {
10393 TokError("expected comma after name '" + Name + "'");
10394 return false;
10395 }
10396 Lex();
10200 if (check(Parser.parseIdentifier(Name),
10201 "expected identifier after '.thumb_set'") ||
10202 parseToken(AsmToken::Comma, "expected comma after name '" + Name + "'"))
10203 return true;
1039710204
1039810205 MCSymbol *Sym;
1039910206 const MCExpr *Value;
1045210259 bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
1045310260 MCAsmParser &Parser = getParser();
1045410261
10455 if (getLexer().isNot(AsmToken::Identifier)) {
10456 Error(getLexer().getLoc(), "expected architecture extension name");
10457 return false;
10458 }
10262 if (getLexer().isNot(AsmToken::Identifier))
10263 return Error(getLexer().getLoc(), "expected architecture extension name");
1045910264
1046010265 StringRef Name = Parser.getTok().getString();
1046110266 SMLoc ExtLoc = Parser.getTok().getLoc();
1046210267 Lex();
10268
10269 if (parseToken(AsmToken::EndOfStatement,
10270 "unexpected token in '.arch_extension' directive"))
10271 return true;
1046310272
1046410273 bool EnableFeature = true;
1046510274 if (Name.startswith_lower("no")) {
1046710276 Name = Name.substr(2);
1046810277 }
1046910278 unsigned FeatureKind = ARM::parseArchExt(Name);
10470 if (FeatureKind == ARM::AEK_INVALID) {
10471 Error(ExtLoc, "unknown architectural extension: " + Name);
10472 return false;
10473 }
10279 if (FeatureKind == ARM::AEK_INVALID)
10280 return Error(ExtLoc, "unknown architectural extension: " + Name);
1047410281
1047510282 for (const auto &Extension : Extensions) {
1047610283 if (Extension.Kind != FeatureKind)
1047710284 continue;
1047810285
10479 if (Extension.Features.none()) {
10480 Error(ExtLoc, "unsupported architectural extension: " + Name);
10481 return false;
10482 }
10483
10484 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck) {
10485 Error(ExtLoc, "architectural extension '" + Name + "' is not "
10486 "allowed for the current base architecture");
10487 return false;
10488 }
10286 if (Extension.Features.none())
10287 return Error(ExtLoc, "unsupported architectural extension: " + Name);
10288
10289 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck)
10290 return Error(ExtLoc, "architectural extension '" + Name +
10291 "' is not "
10292 "allowed for the current base architecture");
1048910293
1049010294 MCSubtargetInfo &STI = copySTI();
1049110295 FeatureBitset ToggleFeatures = EnableFeature
1049810302 return false;
1049910303 }
1050010304
10501 Error(ExtLoc, "unknown architectural extension: " + Name);
10502 return false;
10305 return Error(ExtLoc, "unknown architectural extension: " + Name);
1050310306 }
1050410307
1050510308 // Define this matcher function after the auto-generated include so we
1313 suffix:
1414 bx lr
1515
16 // CHECK-EABI: error: unexpected token in directive
16 // CHECK-EABI: error: unexpected token in '.thumb_func' directive
1717 // CHECK-EABI: .thumb_func suffix
1818 // CHECK-EABI: ^
1919
0 // RUN: not llvm-mc -triple armv7--none-eabi %s 2>&1 | FileCheck %s
1 // RUN: not llvm-mc -triple armv7--none-eabi %s 2>&1 | grep "error:" | count 33
2
3 // CHECK: [[@LINE+1]]:10: error: unexpected token
4 .word 0 $
5 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
6 .word 0 # EOL COMMENT
7 // CHECK: [[@LINE+1]]:11: error: unexpected token
8 .short 0 $
9 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
10 .short 0 # EOL COMMENT
11 // CHECK: [[@LINE+1]]:11: error: unexpected token
12 .hword 0 $
13 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
14 .hword 0 # EOL COMMENT
15
16 .arch armv7-a
17 // CHECK: [[@LINE+1]]:9: error: unexpected token in directive
18 .thumb $
19 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
20 .thumb # EOL COMMENT
21
22 // CHECK: [[@LINE+1]]:7: error: unexpected token in directive
23 .arm $
24 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
25 .arm # EOL COMMENT
26 // CHECK: [[@LINE+1]]:14: error: unexpected token in '.thumb_func' directive
27 .thumb_func $
28 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
29 .thumb_func # EOL COMMENT
30 // CHECK: [[@LINE+1]]:11: error: unexpected token in directive
31 .code 16 $
32 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
33 .code 16 # EOL COMMENTS
34 // CHECK: [[@LINE+1]]:18: error: unexpected token in directive
35 .syntax unified $
36 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
37 .syntax unified # EOL COMMENT
38 fred .req r5
39 // CHECK: [[@LINE+1]]:14: error: unexpected input in '.unreq' directive
40 .unreq fred $
41 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
42 .unreq fred # EOL COMMENTS
43
44 // CHECK: [[@LINE+1]]:18: error: unexpected token in '.fnstart' directive
45 .fnstart $
46 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
47 .fnstart # EOL COMMENT
48 // CHECK: [[@LINE+1]]:23: error: unexpected token in '.cantunwind' directive
49 .cantunwind $
50 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
51 .cantunwind # EOL COMMENT
52
53
54 // CHECK: [[@LINE+1]]:18: error: unexpected token in '.fnend' directive
55 .fnend $
56 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
57 .fnend # EOL COMMENT
58
59 .fnstart
60 // CHECK: [[@LINE+1]]:43: error: unexpected token in '.personality' directive
61 .personality __gxx_personality_v0 $
62 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
63 .personality __gxx_personality_v0 # EOL COMMENET
64
65 // CHECK: [[@LINE+1]]:28: error: unexpected token
66 .setfp fp, sp, #0 $
67 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
68 .setfp fp, sp, #0 # EOL COMMENT
69
70
71 // CHECK: [[@LINE+1]]:17: error: unexpected token in '.pad' directive
72 .pad #0 $
73 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
74 .pad #0 # EOL COMMENT
75
76 // CHECK: [[@LINE+1]]:20: error: unexpected token in directive
77 .save {r0} $
78 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
79 .save {r0} # EOL COMMENT
80
81 // CHECK: [[@LINE+1]]:21: error: unexpected token in directive
82 .vsave {d0} $
83 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
84 .vsave {d0} # EOL COMMENT
85
86
87 // CHECK: [[@LINE+1]]:22: error: unexpected token in '.handlerdata' directive
88 .handlerdata $
89 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
90 .handlerdata # EOL COMMENT
91
92 .fnend
93
94 // CHECK: [[@LINE+1]]:9: error: unexpected token in directive
95 .ltorg $
96 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
97 .ltorg # EOL COMMENT
98 // CHECK: [[@LINE+1]]:8: error: unexpected token in directive
99 .pool $
100 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
101 .pool # EOL COMMENT
102 // CHECK: [[@LINE+1]]:8: error: unexpected token in directive
103 .even $
104 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
105 .even # EOL COMMENT
106 .fnstart
107 // CHECK: [[@LINE+1]]:22: error: unexpected token in '.personalityindex' directive
108 .personalityindex 0 $
109 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
110 .personalityindex 0 # EOL COMMENT
111 .fnend
112
113 .fnstart
114 // CHECK: [[@LINE+1]]:19: error: unexpected token
115 .unwind_raw 0, 0 $
116 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
117 .unwind_raw 0, 0 # EOL COMMENT
118
119 // CHECK: [[@LINE+1]]:12: error: unexpected token in '.movsp' directive
120 .movsp r0 $
121 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
122 .movsp r1 # EOL COMMENT
123 .fnend
124
125 // CHECK: [[@LINE+1]]:21: error: unexpected token in '.arch_extension' directive
126 .arch_extension mp $
127 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
128 .arch_extension mp # EOL COMMENT
129
130 // CHECK: [[@LINE+1]]:21: error: unexpected token in '.arch_extension' directive
131 .arch_extension mp $
132 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
133 .arch_extension mp # EOL COMMENT
134
135 .type arm_func,%function
136 arm_func:
137 nop
138 // CHECK: [[@LINE+1]]:45: error: unexpected token
139 .thumb_set alias_arm_func, arm_func $
140 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
141 .thumb_set alias_arm_func, arm_func # EOL COMMENT
142
143 // CHECK: [[@LINE+1]]:23: error: unexpected token in '.eabi_attribute' directive
144 .eabi_attribute 0, 0 $
145 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
146 .eabi_attribute 0, 0 # EOL COMMENT
147
148 .arm
149 // CHECK: [[@LINE+1]]:10: error: unexpected token
150 .inst 2 $
151 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
152 .inst 2 # EOL COMMENT
153 .thumb
154 // CHECK: [[@LINE+1]]:12: error: unexpected token
155 .inst.n 2 $
156 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
157 .inst.n 2 # EOL COMMENT
158 // CHECK: [[@LINE+1]]:12: error: unexpected token
159 .inst.w 4 $
160 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
161 .inst.w 4 # EOL COMMENT
162 // CHECK: [[@LINE+1]]:21: error: unexpected token
163 .object_arch armv7 $
164 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
165 .object_arch armv7 # EOL COMMENT
166 // CHECK: [[@LINE+1]]:23: error: unexpected token in '.tlsdescseq' directive
167 .tlsdescseq variable $
168 // CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
169 .tlsdescseq variable # EOL COMMENT