1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This class implements the parser for assembly files. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ADT/APFloat.h" 15 #include "llvm/ADT/SmallString.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/ADT/Twine.h" 19 #include "llvm/MC/MCAsmInfo.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCDwarf.h" 22 #include "llvm/MC/MCExpr.h" 23 #include "llvm/MC/MCInstPrinter.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCParser/AsmCond.h" 26 #include "llvm/MC/MCParser/AsmLexer.h" 27 #include "llvm/MC/MCParser/MCAsmParser.h" 28 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 29 #include "llvm/MC/MCRegisterInfo.h" 30 #include "llvm/MC/MCSectionMachO.h" 31 #include "llvm/MC/MCStreamer.h" 32 #include "llvm/MC/MCSymbol.h" 33 #include "llvm/MC/MCTargetAsmParser.h" 34 #include "llvm/Support/CommandLine.h" 35 #include "llvm/Support/ErrorHandling.h" 36 #include "llvm/Support/MathExtras.h" 37 #include "llvm/Support/MemoryBuffer.h" 38 #include "llvm/Support/SourceMgr.h" 39 #include "llvm/Support/raw_ostream.h" 40 #include <cctype> 41 #include <set> 42 #include <string> 43 #include <vector> 44 using namespace llvm; 45 46 static cl::opt<bool> 47 FatalAssemblerWarnings("fatal-assembler-warnings", 48 cl::desc("Consider warnings as error")); 49 50 MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {} 51 52 namespace { 53 54 /// \brief Helper types for tracking macro definitions. 55 typedef std::vector<AsmToken> MCAsmMacroArgument; 56 typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments; 57 typedef std::pair<StringRef, MCAsmMacroArgument> MCAsmMacroParameter; 58 typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters; 59 60 struct MCAsmMacro { 61 StringRef Name; 62 StringRef Body; 63 MCAsmMacroParameters Parameters; 64 65 public: 66 MCAsmMacro(StringRef N, StringRef B, const MCAsmMacroParameters &P) : 67 Name(N), Body(B), Parameters(P) {} 68 69 MCAsmMacro(const MCAsmMacro& Other) 70 : Name(Other.Name), Body(Other.Body), Parameters(Other.Parameters) {} 71 }; 72 73 /// \brief Helper class for storing information about an active macro 74 /// instantiation. 75 struct MacroInstantiation { 76 /// The macro being instantiated. 77 const MCAsmMacro *TheMacro; 78 79 /// The macro instantiation with substitutions. 80 MemoryBuffer *Instantiation; 81 82 /// The location of the instantiation. 83 SMLoc InstantiationLoc; 84 85 /// The buffer where parsing should resume upon instantiation completion. 86 int ExitBuffer; 87 88 /// The location where parsing should resume upon instantiation completion. 89 SMLoc ExitLoc; 90 91 public: 92 MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, SMLoc EL, 93 MemoryBuffer *I); 94 }; 95 96 struct ParseStatementInfo { 97 /// ParsedOperands - The parsed operands from the last parsed statement. 98 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; 99 100 /// Opcode - The opcode from the last parsed instruction. 101 unsigned Opcode; 102 103 /// Error - Was there an error parsing the inline assembly? 104 bool ParseError; 105 106 SmallVectorImpl<AsmRewrite> *AsmRewrites; 107 108 ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(0) {} 109 ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites) 110 : Opcode(~0), ParseError(false), AsmRewrites(rewrites) {} 111 112 ~ParseStatementInfo() { 113 // Free any parsed operands. 114 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) 115 delete ParsedOperands[i]; 116 ParsedOperands.clear(); 117 } 118 }; 119 120 /// \brief The concrete assembly parser instance. 121 class AsmParser : public MCAsmParser { 122 AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION; 123 void operator=(const AsmParser &) LLVM_DELETED_FUNCTION; 124 private: 125 AsmLexer Lexer; 126 MCContext &Ctx; 127 MCStreamer &Out; 128 const MCAsmInfo &MAI; 129 SourceMgr &SrcMgr; 130 SourceMgr::DiagHandlerTy SavedDiagHandler; 131 void *SavedDiagContext; 132 MCAsmParserExtension *PlatformParser; 133 134 /// This is the current buffer index we're lexing from as managed by the 135 /// SourceMgr object. 136 int CurBuffer; 137 138 AsmCond TheCondState; 139 std::vector<AsmCond> TheCondStack; 140 141 /// ExtensionDirectiveMap - maps directive names to handler methods in parser 142 /// extensions. Extensions register themselves in this map by calling 143 /// addDirectiveHandler. 144 StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap; 145 146 /// MacroMap - Map of currently defined macros. 147 StringMap<MCAsmMacro*> MacroMap; 148 149 /// ActiveMacros - Stack of active macro instantiations. 150 std::vector<MacroInstantiation*> ActiveMacros; 151 152 /// MacroLikeBodies - List of bodies of anonymous macros. 153 std::deque<MCAsmMacro> MacroLikeBodies; 154 155 /// Boolean tracking whether macro substitution is enabled. 156 unsigned MacrosEnabledFlag : 1; 157 158 /// Flag tracking whether any errors have been encountered. 159 unsigned HadError : 1; 160 161 /// The values from the last parsed cpp hash file line comment if any. 162 StringRef CppHashFilename; 163 int64_t CppHashLineNumber; 164 SMLoc CppHashLoc; 165 int CppHashBuf; 166 /// When generating dwarf for assembly source files we need to calculate the 167 /// logical line number based on the last parsed cpp hash file line comment 168 /// and current line. Since this is slow and messes up the SourceMgr's 169 /// cache we save the last info we queried with SrcMgr.FindLineNumber(). 170 SMLoc LastQueryIDLoc; 171 int LastQueryBuffer; 172 unsigned LastQueryLine; 173 174 /// AssemblerDialect. ~OU means unset value and use value provided by MAI. 175 unsigned AssemblerDialect; 176 177 /// IsDarwin - is Darwin compatibility enabled? 178 bool IsDarwin; 179 180 /// ParsingInlineAsm - Are we parsing ms-style inline assembly? 181 bool ParsingInlineAsm; 182 183 public: 184 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, 185 const MCAsmInfo &MAI); 186 virtual ~AsmParser(); 187 188 virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false); 189 190 virtual void addDirectiveHandler(StringRef Directive, 191 ExtensionDirectiveHandler Handler) { 192 ExtensionDirectiveMap[Directive] = Handler; 193 } 194 195 public: 196 /// @name MCAsmParser Interface 197 /// { 198 199 virtual SourceMgr &getSourceManager() { return SrcMgr; } 200 virtual MCAsmLexer &getLexer() { return Lexer; } 201 virtual MCContext &getContext() { return Ctx; } 202 virtual MCStreamer &getStreamer() { return Out; } 203 virtual unsigned getAssemblerDialect() { 204 if (AssemblerDialect == ~0U) 205 return MAI.getAssemblerDialect(); 206 else 207 return AssemblerDialect; 208 } 209 virtual void setAssemblerDialect(unsigned i) { 210 AssemblerDialect = i; 211 } 212 213 virtual bool Warning(SMLoc L, const Twine &Msg, 214 ArrayRef<SMRange> Ranges = None); 215 virtual bool Error(SMLoc L, const Twine &Msg, 216 ArrayRef<SMRange> Ranges = None); 217 218 virtual const AsmToken &Lex(); 219 220 void setParsingInlineAsm(bool V) { ParsingInlineAsm = V; } 221 bool isParsingInlineAsm() { return ParsingInlineAsm; } 222 223 bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, 224 unsigned &NumOutputs, unsigned &NumInputs, 225 SmallVectorImpl<std::pair<void *,bool> > &OpDecls, 226 SmallVectorImpl<std::string> &Constraints, 227 SmallVectorImpl<std::string> &Clobbers, 228 const MCInstrInfo *MII, 229 const MCInstPrinter *IP, 230 MCAsmParserSemaCallback &SI); 231 232 bool parseExpression(const MCExpr *&Res); 233 virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc); 234 virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); 235 virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc); 236 virtual bool parseAbsoluteExpression(int64_t &Res); 237 238 /// parseIdentifier - Parse an identifier or string (as a quoted identifier) 239 /// and set \p Res to the identifier contents. 240 virtual bool parseIdentifier(StringRef &Res); 241 virtual void eatToEndOfStatement(); 242 243 virtual void checkForValidSection(); 244 /// } 245 246 private: 247 248 bool ParseStatement(ParseStatementInfo &Info); 249 void EatToEndOfLine(); 250 bool ParseCppHashLineFilenameComment(const SMLoc &L); 251 252 void CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body, 253 MCAsmMacroParameters Parameters); 254 bool expandMacro(raw_svector_ostream &OS, StringRef Body, 255 const MCAsmMacroParameters &Parameters, 256 const MCAsmMacroArguments &A, 257 const SMLoc &L); 258 259 /// \brief Are macros enabled in the parser? 260 bool MacrosEnabled() {return MacrosEnabledFlag;} 261 262 /// \brief Control a flag in the parser that enables or disables macros. 263 void SetMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;} 264 265 /// \brief Lookup a previously defined macro. 266 /// \param Name Macro name. 267 /// \returns Pointer to macro. NULL if no such macro was defined. 268 const MCAsmMacro* LookupMacro(StringRef Name); 269 270 /// \brief Define a new macro with the given name and information. 271 void DefineMacro(StringRef Name, const MCAsmMacro& Macro); 272 273 /// \brief Undefine a macro. If no such macro was defined, it's a no-op. 274 void UndefineMacro(StringRef Name); 275 276 /// \brief Are we inside a macro instantiation? 277 bool InsideMacroInstantiation() {return !ActiveMacros.empty();} 278 279 /// \brief Handle entry to macro instantiation. 280 /// 281 /// \param M The macro. 282 /// \param NameLoc Instantiation location. 283 bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc); 284 285 /// \brief Handle exit from macro instantiation. 286 void HandleMacroExit(); 287 288 /// \brief Extract AsmTokens for a macro argument. If the argument delimiter 289 /// is initially unknown, set it to AsmToken::Eof. It will be set to the 290 /// correct delimiter by the method. 291 bool ParseMacroArgument(MCAsmMacroArgument &MA, 292 AsmToken::TokenKind &ArgumentDelimiter); 293 294 /// \brief Parse all macro arguments for a given macro. 295 bool ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A); 296 297 void PrintMacroInstantiations(); 298 void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, 299 ArrayRef<SMRange> Ranges = None) const { 300 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges); 301 } 302 static void DiagHandler(const SMDiagnostic &Diag, void *Context); 303 304 /// EnterIncludeFile - Enter the specified file. This returns true on failure. 305 bool EnterIncludeFile(const std::string &Filename); 306 /// ProcessIncbinFile - Process the specified file for the .incbin directive. 307 /// This returns true on failure. 308 bool ProcessIncbinFile(const std::string &Filename); 309 310 /// \brief Reset the current lexer position to that given by \p Loc. The 311 /// current token is not set; clients should ensure Lex() is called 312 /// subsequently. 313 /// 314 /// \param InBuffer If not -1, should be the known buffer id that contains the 315 /// location. 316 void JumpToLoc(SMLoc Loc, int InBuffer=-1); 317 318 /// \brief Parse up to the end of statement and a return the contents from the 319 /// current token until the end of the statement; the current token on exit 320 /// will be either the EndOfStatement or EOF. 321 virtual StringRef parseStringToEndOfStatement(); 322 323 /// \brief Parse until the end of a statement or a comma is encountered, 324 /// return the contents from the current token up to the end or comma. 325 StringRef ParseStringToComma(); 326 327 bool ParseAssignment(StringRef Name, bool allow_redef, 328 bool NoDeadStrip = false); 329 330 bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); 331 bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); 332 bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); 333 bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); 334 335 bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc); 336 337 // Generic (target and platform independent) directive parsing. 338 enum DirectiveKind { 339 DK_NO_DIRECTIVE, // Placeholder 340 DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT, 341 DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_SINGLE, 342 DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW, 343 DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR, 344 DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK, 345 DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, DK_INDIRECT_SYMBOL, 346 DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN, 347 DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, 348 DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, 349 DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC, 350 DK_IF, DK_IFB, DK_IFNB, DK_IFC, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF, 351 DK_ELSEIF, DK_ELSE, DK_ENDIF, 352 DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS, 353 DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA, 354 DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER, 355 DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA, 356 DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE, 357 DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED, 358 DK_CFI_REGISTER, 359 DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM, 360 DK_SLEB128, DK_ULEB128 361 }; 362 363 /// DirectiveKindMap - Maps directive name --> DirectiveKind enum, for 364 /// directives parsed by this class. 365 StringMap<DirectiveKind> DirectiveKindMap; 366 367 // ".ascii", ".asciz", ".string" 368 bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); 369 bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ... 370 bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ... 371 bool ParseDirectiveFill(); // ".fill" 372 bool ParseDirectiveZero(); // ".zero" 373 // ".set", ".equ", ".equiv" 374 bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); 375 bool ParseDirectiveOrg(); // ".org" 376 // ".align{,32}", ".p2align{,w,l}" 377 bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize); 378 379 // ".file", ".line", ".loc", ".stabs" 380 bool ParseDirectiveFile(SMLoc DirectiveLoc); 381 bool ParseDirectiveLine(); 382 bool ParseDirectiveLoc(); 383 bool ParseDirectiveStabs(); 384 385 // .cfi directives 386 bool ParseDirectiveCFIRegister(SMLoc DirectiveLoc); 387 bool ParseDirectiveCFISections(); 388 bool ParseDirectiveCFIStartProc(); 389 bool ParseDirectiveCFIEndProc(); 390 bool ParseDirectiveCFIDefCfaOffset(); 391 bool ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc); 392 bool ParseDirectiveCFIAdjustCfaOffset(); 393 bool ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc); 394 bool ParseDirectiveCFIOffset(SMLoc DirectiveLoc); 395 bool ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc); 396 bool ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality); 397 bool ParseDirectiveCFIRememberState(); 398 bool ParseDirectiveCFIRestoreState(); 399 bool ParseDirectiveCFISameValue(SMLoc DirectiveLoc); 400 bool ParseDirectiveCFIRestore(SMLoc DirectiveLoc); 401 bool ParseDirectiveCFIEscape(); 402 bool ParseDirectiveCFISignalFrame(); 403 bool ParseDirectiveCFIUndefined(SMLoc DirectiveLoc); 404 405 // macro directives 406 bool ParseDirectivePurgeMacro(SMLoc DirectiveLoc); 407 bool ParseDirectiveEndMacro(StringRef Directive); 408 bool ParseDirectiveMacro(SMLoc DirectiveLoc); 409 bool ParseDirectiveMacrosOnOff(StringRef Directive); 410 411 // ".bundle_align_mode" 412 bool ParseDirectiveBundleAlignMode(); 413 // ".bundle_lock" 414 bool ParseDirectiveBundleLock(); 415 // ".bundle_unlock" 416 bool ParseDirectiveBundleUnlock(); 417 418 // ".space", ".skip" 419 bool ParseDirectiveSpace(StringRef IDVal); 420 421 // .sleb128 (Signed=true) and .uleb128 (Signed=false) 422 bool ParseDirectiveLEB128(bool Signed); 423 424 /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which 425 /// accepts a single symbol (which should be a label or an external). 426 bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr); 427 428 bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" 429 430 bool ParseDirectiveAbort(); // ".abort" 431 bool ParseDirectiveInclude(); // ".include" 432 bool ParseDirectiveIncbin(); // ".incbin" 433 434 bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if" 435 // ".ifb" or ".ifnb", depending on ExpectBlank. 436 bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); 437 // ".ifc" or ".ifnc", depending on ExpectEqual. 438 bool ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); 439 // ".ifdef" or ".ifndef", depending on expect_defined 440 bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); 441 bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" 442 bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else" 443 bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif 444 virtual bool parseEscapedString(std::string &Data); 445 446 const MCExpr *ApplyModifierToExpr(const MCExpr *E, 447 MCSymbolRefExpr::VariantKind Variant); 448 449 // Macro-like directives 450 MCAsmMacro *ParseMacroLikeBody(SMLoc DirectiveLoc); 451 void InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 452 raw_svector_ostream &OS); 453 bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept" 454 bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" 455 bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" 456 bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" 457 458 // "_emit" or "__emit" 459 bool ParseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info, 460 size_t Len); 461 462 // "align" 463 bool ParseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info); 464 465 void initializeDirectiveKindMap(); 466 }; 467 } 468 469 namespace llvm { 470 471 extern MCAsmParserExtension *createDarwinAsmParser(); 472 extern MCAsmParserExtension *createELFAsmParser(); 473 extern MCAsmParserExtension *createCOFFAsmParser(); 474 475 } 476 477 enum { DEFAULT_ADDRSPACE = 0 }; 478 479 AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, 480 MCStreamer &_Out, const MCAsmInfo &_MAI) 481 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), 482 PlatformParser(0), 483 CurBuffer(0), MacrosEnabledFlag(true), CppHashLineNumber(0), 484 AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { 485 // Save the old handler. 486 SavedDiagHandler = SrcMgr.getDiagHandler(); 487 SavedDiagContext = SrcMgr.getDiagContext(); 488 // Set our own handler which calls the saved handler. 489 SrcMgr.setDiagHandler(DiagHandler, this); 490 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 491 492 // Initialize the platform / file format parser. 493 // 494 // FIXME: This is a hack, we need to (majorly) cleanup how these objects are 495 // created. 496 if (_MAI.hasMicrosoftFastStdCallMangling()) { 497 PlatformParser = createCOFFAsmParser(); 498 PlatformParser->Initialize(*this); 499 } else if (_MAI.hasSubsectionsViaSymbols()) { 500 PlatformParser = createDarwinAsmParser(); 501 PlatformParser->Initialize(*this); 502 IsDarwin = true; 503 } else { 504 PlatformParser = createELFAsmParser(); 505 PlatformParser->Initialize(*this); 506 } 507 508 initializeDirectiveKindMap(); 509 } 510 511 AsmParser::~AsmParser() { 512 assert(ActiveMacros.empty() && "Unexpected active macro instantiation!"); 513 514 // Destroy any macros. 515 for (StringMap<MCAsmMacro*>::iterator it = MacroMap.begin(), 516 ie = MacroMap.end(); it != ie; ++it) 517 delete it->getValue(); 518 519 delete PlatformParser; 520 } 521 522 void AsmParser::PrintMacroInstantiations() { 523 // Print the active macro instantiation stack. 524 for (std::vector<MacroInstantiation*>::const_reverse_iterator 525 it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it) 526 PrintMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, 527 "while in macro instantiation"); 528 } 529 530 bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 531 if (FatalAssemblerWarnings) 532 return Error(L, Msg, Ranges); 533 PrintMessage(L, SourceMgr::DK_Warning, Msg, Ranges); 534 PrintMacroInstantiations(); 535 return false; 536 } 537 538 bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 539 HadError = true; 540 PrintMessage(L, SourceMgr::DK_Error, Msg, Ranges); 541 PrintMacroInstantiations(); 542 return true; 543 } 544 545 bool AsmParser::EnterIncludeFile(const std::string &Filename) { 546 std::string IncludedFile; 547 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 548 if (NewBuf == -1) 549 return true; 550 551 CurBuffer = NewBuf; 552 553 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 554 555 return false; 556 } 557 558 /// Process the specified .incbin file by searching for it in the include paths 559 /// then just emitting the byte contents of the file to the streamer. This 560 /// returns true on failure. 561 bool AsmParser::ProcessIncbinFile(const std::string &Filename) { 562 std::string IncludedFile; 563 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 564 if (NewBuf == -1) 565 return true; 566 567 // Pick up the bytes from the file and emit them. 568 getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer()); 569 return false; 570 } 571 572 void AsmParser::JumpToLoc(SMLoc Loc, int InBuffer) { 573 if (InBuffer != -1) { 574 CurBuffer = InBuffer; 575 } else { 576 CurBuffer = SrcMgr.FindBufferContainingLoc(Loc); 577 } 578 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer()); 579 } 580 581 const AsmToken &AsmParser::Lex() { 582 const AsmToken *tok = &Lexer.Lex(); 583 584 if (tok->is(AsmToken::Eof)) { 585 // If this is the end of an included file, pop the parent file off the 586 // include stack. 587 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 588 if (ParentIncludeLoc != SMLoc()) { 589 JumpToLoc(ParentIncludeLoc); 590 tok = &Lexer.Lex(); 591 } 592 } 593 594 if (tok->is(AsmToken::Error)) 595 Error(Lexer.getErrLoc(), Lexer.getErr()); 596 597 return *tok; 598 } 599 600 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { 601 // Create the initial section, if requested. 602 if (!NoInitialTextSection) 603 Out.InitSections(); 604 605 // Prime the lexer. 606 Lex(); 607 608 HadError = false; 609 AsmCond StartingCondState = TheCondState; 610 611 // If we are generating dwarf for assembly source files save the initial text 612 // section and generate a .file directive. 613 if (getContext().getGenDwarfForAssembly()) { 614 getContext().setGenDwarfSection(getStreamer().getCurrentSection().first); 615 MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); 616 getStreamer().EmitLabel(SectionStartSym); 617 getContext().setGenDwarfSectionStartSym(SectionStartSym); 618 getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), 619 StringRef(), 620 getContext().getMainFileName()); 621 } 622 623 // While we have input, parse each statement. 624 while (Lexer.isNot(AsmToken::Eof)) { 625 ParseStatementInfo Info; 626 if (!ParseStatement(Info)) continue; 627 628 // We had an error, validate that one was emitted and recover by skipping to 629 // the next line. 630 assert(HadError && "Parse statement returned an error, but none emitted!"); 631 eatToEndOfStatement(); 632 } 633 634 if (TheCondState.TheCond != StartingCondState.TheCond || 635 TheCondState.Ignore != StartingCondState.Ignore) 636 return TokError("unmatched .ifs or .elses"); 637 638 // Check to see there are no empty DwarfFile slots. 639 const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles = 640 getContext().getMCDwarfFiles(); 641 for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { 642 if (!MCDwarfFiles[i]) 643 TokError("unassigned file number: " + Twine(i) + " for .file directives"); 644 } 645 646 // Check to see that all assembler local symbols were actually defined. 647 // Targets that don't do subsections via symbols may not want this, though, 648 // so conservatively exclude them. Only do this if we're finalizing, though, 649 // as otherwise we won't necessarilly have seen everything yet. 650 if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) { 651 const MCContext::SymbolTable &Symbols = getContext().getSymbols(); 652 for (MCContext::SymbolTable::const_iterator i = Symbols.begin(), 653 e = Symbols.end(); 654 i != e; ++i) { 655 MCSymbol *Sym = i->getValue(); 656 // Variable symbols may not be marked as defined, so check those 657 // explicitly. If we know it's a variable, we have a definition for 658 // the purposes of this check. 659 if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined()) 660 // FIXME: We would really like to refer back to where the symbol was 661 // first referenced for a source location. We need to add something 662 // to track that. Currently, we just point to the end of the file. 663 PrintMessage(getLexer().getLoc(), SourceMgr::DK_Error, 664 "assembler local symbol '" + Sym->getName() + 665 "' not defined"); 666 } 667 } 668 669 670 // Finalize the output stream if there are no errors and if the client wants 671 // us to. 672 if (!HadError && !NoFinalize) 673 Out.Finish(); 674 675 return HadError; 676 } 677 678 void AsmParser::checkForValidSection() { 679 if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) { 680 TokError("expected section directive before assembly directive"); 681 Out.InitToTextSection(); 682 } 683 } 684 685 /// eatToEndOfStatement - Throw away the rest of the line for testing purposes. 686 void AsmParser::eatToEndOfStatement() { 687 while (Lexer.isNot(AsmToken::EndOfStatement) && 688 Lexer.isNot(AsmToken::Eof)) 689 Lex(); 690 691 // Eat EOL. 692 if (Lexer.is(AsmToken::EndOfStatement)) 693 Lex(); 694 } 695 696 StringRef AsmParser::parseStringToEndOfStatement() { 697 const char *Start = getTok().getLoc().getPointer(); 698 699 while (Lexer.isNot(AsmToken::EndOfStatement) && 700 Lexer.isNot(AsmToken::Eof)) 701 Lex(); 702 703 const char *End = getTok().getLoc().getPointer(); 704 return StringRef(Start, End - Start); 705 } 706 707 StringRef AsmParser::ParseStringToComma() { 708 const char *Start = getTok().getLoc().getPointer(); 709 710 while (Lexer.isNot(AsmToken::EndOfStatement) && 711 Lexer.isNot(AsmToken::Comma) && 712 Lexer.isNot(AsmToken::Eof)) 713 Lex(); 714 715 const char *End = getTok().getLoc().getPointer(); 716 return StringRef(Start, End - Start); 717 } 718 719 /// ParseParenExpr - Parse a paren expression and return it. 720 /// NOTE: This assumes the leading '(' has already been consumed. 721 /// 722 /// parenexpr ::= expr) 723 /// 724 bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { 725 if (parseExpression(Res)) return true; 726 if (Lexer.isNot(AsmToken::RParen)) 727 return TokError("expected ')' in parentheses expression"); 728 EndLoc = Lexer.getTok().getEndLoc(); 729 Lex(); 730 return false; 731 } 732 733 /// ParseBracketExpr - Parse a bracket expression and return it. 734 /// NOTE: This assumes the leading '[' has already been consumed. 735 /// 736 /// bracketexpr ::= expr] 737 /// 738 bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { 739 if (parseExpression(Res)) return true; 740 if (Lexer.isNot(AsmToken::RBrac)) 741 return TokError("expected ']' in brackets expression"); 742 EndLoc = Lexer.getTok().getEndLoc(); 743 Lex(); 744 return false; 745 } 746 747 /// ParsePrimaryExpr - Parse a primary expression and return it. 748 /// primaryexpr ::= (parenexpr 749 /// primaryexpr ::= symbol 750 /// primaryexpr ::= number 751 /// primaryexpr ::= '.' 752 /// primaryexpr ::= ~,+,- primaryexpr 753 bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 754 SMLoc FirstTokenLoc = getLexer().getLoc(); 755 AsmToken::TokenKind FirstTokenKind = Lexer.getKind(); 756 switch (FirstTokenKind) { 757 default: 758 return TokError("unknown token in expression"); 759 // If we have an error assume that we've already handled it. 760 case AsmToken::Error: 761 return true; 762 case AsmToken::Exclaim: 763 Lex(); // Eat the operator. 764 if (ParsePrimaryExpr(Res, EndLoc)) 765 return true; 766 Res = MCUnaryExpr::CreateLNot(Res, getContext()); 767 return false; 768 case AsmToken::Dollar: 769 case AsmToken::String: 770 case AsmToken::Identifier: { 771 StringRef Identifier; 772 if (parseIdentifier(Identifier)) { 773 if (FirstTokenKind == AsmToken::Dollar) 774 return Error(FirstTokenLoc, "invalid token in expression"); 775 return true; 776 } 777 778 EndLoc = SMLoc::getFromPointer(Identifier.end()); 779 780 // This is a symbol reference. 781 std::pair<StringRef, StringRef> Split = Identifier.split('@'); 782 MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first); 783 784 // Lookup the symbol variant if used. 785 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 786 if (Split.first.size() != Identifier.size()) { 787 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 788 if (Variant == MCSymbolRefExpr::VK_Invalid) { 789 Variant = MCSymbolRefExpr::VK_None; 790 return TokError("invalid variant '" + Split.second + "'"); 791 } 792 } 793 794 // If this is an absolute variable reference, substitute it now to preserve 795 // semantics in the face of reassignment. 796 if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) { 797 if (Variant) 798 return Error(EndLoc, "unexpected modifier on variable reference"); 799 800 Res = Sym->getVariableValue(); 801 return false; 802 } 803 804 // Otherwise create a symbol ref. 805 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 806 return false; 807 } 808 case AsmToken::Integer: { 809 SMLoc Loc = getTok().getLoc(); 810 int64_t IntVal = getTok().getIntVal(); 811 Res = MCConstantExpr::Create(IntVal, getContext()); 812 EndLoc = Lexer.getTok().getEndLoc(); 813 Lex(); // Eat token. 814 // Look for 'b' or 'f' following an Integer as a directional label 815 if (Lexer.getKind() == AsmToken::Identifier) { 816 StringRef IDVal = getTok().getString(); 817 // Lookup the symbol variant if used. 818 std::pair<StringRef, StringRef> Split = IDVal.split('@'); 819 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 820 if (Split.first.size() != IDVal.size()) { 821 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 822 if (Variant == MCSymbolRefExpr::VK_Invalid) { 823 Variant = MCSymbolRefExpr::VK_None; 824 return TokError("invalid variant '" + Split.second + "'"); 825 } 826 IDVal = Split.first; 827 } 828 if (IDVal == "f" || IDVal == "b"){ 829 MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal, 830 IDVal == "f" ? 1 : 0); 831 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 832 if (IDVal == "b" && Sym->isUndefined()) 833 return Error(Loc, "invalid reference to undefined symbol"); 834 EndLoc = Lexer.getTok().getEndLoc(); 835 Lex(); // Eat identifier. 836 } 837 } 838 return false; 839 } 840 case AsmToken::Real: { 841 APFloat RealVal(APFloat::IEEEdouble, getTok().getString()); 842 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 843 Res = MCConstantExpr::Create(IntVal, getContext()); 844 EndLoc = Lexer.getTok().getEndLoc(); 845 Lex(); // Eat token. 846 return false; 847 } 848 case AsmToken::Dot: { 849 // This is a '.' reference, which references the current PC. Emit a 850 // temporary label to the streamer and refer to it. 851 MCSymbol *Sym = Ctx.CreateTempSymbol(); 852 Out.EmitLabel(Sym); 853 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 854 EndLoc = Lexer.getTok().getEndLoc(); 855 Lex(); // Eat identifier. 856 return false; 857 } 858 case AsmToken::LParen: 859 Lex(); // Eat the '('. 860 return ParseParenExpr(Res, EndLoc); 861 case AsmToken::LBrac: 862 if (!PlatformParser->HasBracketExpressions()) 863 return TokError("brackets expression not supported on this target"); 864 Lex(); // Eat the '['. 865 return ParseBracketExpr(Res, EndLoc); 866 case AsmToken::Minus: 867 Lex(); // Eat the operator. 868 if (ParsePrimaryExpr(Res, EndLoc)) 869 return true; 870 Res = MCUnaryExpr::CreateMinus(Res, getContext()); 871 return false; 872 case AsmToken::Plus: 873 Lex(); // Eat the operator. 874 if (ParsePrimaryExpr(Res, EndLoc)) 875 return true; 876 Res = MCUnaryExpr::CreatePlus(Res, getContext()); 877 return false; 878 case AsmToken::Tilde: 879 Lex(); // Eat the operator. 880 if (ParsePrimaryExpr(Res, EndLoc)) 881 return true; 882 Res = MCUnaryExpr::CreateNot(Res, getContext()); 883 return false; 884 } 885 } 886 887 bool AsmParser::parseExpression(const MCExpr *&Res) { 888 SMLoc EndLoc; 889 return parseExpression(Res, EndLoc); 890 } 891 892 bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 893 return ParsePrimaryExpr(Res, EndLoc); 894 } 895 896 const MCExpr * 897 AsmParser::ApplyModifierToExpr(const MCExpr *E, 898 MCSymbolRefExpr::VariantKind Variant) { 899 // Recurse over the given expression, rebuilding it to apply the given variant 900 // if there is exactly one symbol. 901 switch (E->getKind()) { 902 case MCExpr::Target: 903 case MCExpr::Constant: 904 return 0; 905 906 case MCExpr::SymbolRef: { 907 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 908 909 if (SRE->getKind() != MCSymbolRefExpr::VK_None) { 910 TokError("invalid variant on expression '" + 911 getTok().getIdentifier() + "' (already modified)"); 912 return E; 913 } 914 915 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 916 } 917 918 case MCExpr::Unary: { 919 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 920 const MCExpr *Sub = ApplyModifierToExpr(UE->getSubExpr(), Variant); 921 if (!Sub) 922 return 0; 923 return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext()); 924 } 925 926 case MCExpr::Binary: { 927 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 928 const MCExpr *LHS = ApplyModifierToExpr(BE->getLHS(), Variant); 929 const MCExpr *RHS = ApplyModifierToExpr(BE->getRHS(), Variant); 930 931 if (!LHS && !RHS) 932 return 0; 933 934 if (!LHS) LHS = BE->getLHS(); 935 if (!RHS) RHS = BE->getRHS(); 936 937 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 938 } 939 } 940 941 llvm_unreachable("Invalid expression kind!"); 942 } 943 944 /// parseExpression - Parse an expression and return it. 945 /// 946 /// expr ::= expr &&,|| expr -> lowest. 947 /// expr ::= expr |,^,&,! expr 948 /// expr ::= expr ==,!=,<>,<,<=,>,>= expr 949 /// expr ::= expr <<,>> expr 950 /// expr ::= expr +,- expr 951 /// expr ::= expr *,/,% expr -> highest. 952 /// expr ::= primaryexpr 953 /// 954 bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 955 // Parse the expression. 956 Res = 0; 957 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc)) 958 return true; 959 960 // As a special case, we support 'a op b @ modifier' by rewriting the 961 // expression to include the modifier. This is inefficient, but in general we 962 // expect users to use 'a@modifier op b'. 963 if (Lexer.getKind() == AsmToken::At) { 964 Lex(); 965 966 if (Lexer.isNot(AsmToken::Identifier)) 967 return TokError("unexpected symbol modifier following '@'"); 968 969 MCSymbolRefExpr::VariantKind Variant = 970 MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier()); 971 if (Variant == MCSymbolRefExpr::VK_Invalid) 972 return TokError("invalid variant '" + getTok().getIdentifier() + "'"); 973 974 const MCExpr *ModifiedRes = ApplyModifierToExpr(Res, Variant); 975 if (!ModifiedRes) { 976 return TokError("invalid modifier '" + getTok().getIdentifier() + 977 "' (no symbols present)"); 978 } 979 980 Res = ModifiedRes; 981 Lex(); 982 } 983 984 // Try to constant fold it up front, if possible. 985 int64_t Value; 986 if (Res->EvaluateAsAbsolute(Value)) 987 Res = MCConstantExpr::Create(Value, getContext()); 988 989 return false; 990 } 991 992 bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 993 Res = 0; 994 return ParseParenExpr(Res, EndLoc) || 995 ParseBinOpRHS(1, Res, EndLoc); 996 } 997 998 bool AsmParser::parseAbsoluteExpression(int64_t &Res) { 999 const MCExpr *Expr; 1000 1001 SMLoc StartLoc = Lexer.getLoc(); 1002 if (parseExpression(Expr)) 1003 return true; 1004 1005 if (!Expr->EvaluateAsAbsolute(Res)) 1006 return Error(StartLoc, "expected absolute expression"); 1007 1008 return false; 1009 } 1010 1011 static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 1012 MCBinaryExpr::Opcode &Kind) { 1013 switch (K) { 1014 default: 1015 return 0; // not a binop. 1016 1017 // Lowest Precedence: &&, || 1018 case AsmToken::AmpAmp: 1019 Kind = MCBinaryExpr::LAnd; 1020 return 1; 1021 case AsmToken::PipePipe: 1022 Kind = MCBinaryExpr::LOr; 1023 return 1; 1024 1025 1026 // Low Precedence: |, &, ^ 1027 // 1028 // FIXME: gas seems to support '!' as an infix operator? 1029 case AsmToken::Pipe: 1030 Kind = MCBinaryExpr::Or; 1031 return 2; 1032 case AsmToken::Caret: 1033 Kind = MCBinaryExpr::Xor; 1034 return 2; 1035 case AsmToken::Amp: 1036 Kind = MCBinaryExpr::And; 1037 return 2; 1038 1039 // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >= 1040 case AsmToken::EqualEqual: 1041 Kind = MCBinaryExpr::EQ; 1042 return 3; 1043 case AsmToken::ExclaimEqual: 1044 case AsmToken::LessGreater: 1045 Kind = MCBinaryExpr::NE; 1046 return 3; 1047 case AsmToken::Less: 1048 Kind = MCBinaryExpr::LT; 1049 return 3; 1050 case AsmToken::LessEqual: 1051 Kind = MCBinaryExpr::LTE; 1052 return 3; 1053 case AsmToken::Greater: 1054 Kind = MCBinaryExpr::GT; 1055 return 3; 1056 case AsmToken::GreaterEqual: 1057 Kind = MCBinaryExpr::GTE; 1058 return 3; 1059 1060 // Intermediate Precedence: <<, >> 1061 case AsmToken::LessLess: 1062 Kind = MCBinaryExpr::Shl; 1063 return 4; 1064 case AsmToken::GreaterGreater: 1065 Kind = MCBinaryExpr::Shr; 1066 return 4; 1067 1068 // High Intermediate Precedence: +, - 1069 case AsmToken::Plus: 1070 Kind = MCBinaryExpr::Add; 1071 return 5; 1072 case AsmToken::Minus: 1073 Kind = MCBinaryExpr::Sub; 1074 return 5; 1075 1076 // Highest Precedence: *, /, % 1077 case AsmToken::Star: 1078 Kind = MCBinaryExpr::Mul; 1079 return 6; 1080 case AsmToken::Slash: 1081 Kind = MCBinaryExpr::Div; 1082 return 6; 1083 case AsmToken::Percent: 1084 Kind = MCBinaryExpr::Mod; 1085 return 6; 1086 } 1087 } 1088 1089 1090 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. 1091 /// Res contains the LHS of the expression on input. 1092 bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 1093 SMLoc &EndLoc) { 1094 while (1) { 1095 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 1096 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); 1097 1098 // If the next token is lower precedence than we are allowed to eat, return 1099 // successfully with what we ate already. 1100 if (TokPrec < Precedence) 1101 return false; 1102 1103 Lex(); 1104 1105 // Eat the next primary expression. 1106 const MCExpr *RHS; 1107 if (ParsePrimaryExpr(RHS, EndLoc)) return true; 1108 1109 // If BinOp binds less tightly with RHS than the operator after RHS, let 1110 // the pending operator take RHS as its LHS. 1111 MCBinaryExpr::Opcode Dummy; 1112 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 1113 if (TokPrec < NextTokPrec) { 1114 if (ParseBinOpRHS(TokPrec+1, RHS, EndLoc)) return true; 1115 } 1116 1117 // Merge LHS and RHS according to operator. 1118 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); 1119 } 1120 } 1121 1122 /// ParseStatement: 1123 /// ::= EndOfStatement 1124 /// ::= Label* Directive ...Operands... EndOfStatement 1125 /// ::= Label* Identifier OperandList* EndOfStatement 1126 bool AsmParser::ParseStatement(ParseStatementInfo &Info) { 1127 if (Lexer.is(AsmToken::EndOfStatement)) { 1128 Out.AddBlankLine(); 1129 Lex(); 1130 return false; 1131 } 1132 1133 // Statements always start with an identifier or are a full line comment. 1134 AsmToken ID = getTok(); 1135 SMLoc IDLoc = ID.getLoc(); 1136 StringRef IDVal; 1137 int64_t LocalLabelVal = -1; 1138 // A full line comment is a '#' as the first token. 1139 if (Lexer.is(AsmToken::Hash)) 1140 return ParseCppHashLineFilenameComment(IDLoc); 1141 1142 // Allow an integer followed by a ':' as a directional local label. 1143 if (Lexer.is(AsmToken::Integer)) { 1144 LocalLabelVal = getTok().getIntVal(); 1145 if (LocalLabelVal < 0) { 1146 if (!TheCondState.Ignore) 1147 return TokError("unexpected token at start of statement"); 1148 IDVal = ""; 1149 } else { 1150 IDVal = getTok().getString(); 1151 Lex(); // Consume the integer token to be used as an identifier token. 1152 if (Lexer.getKind() != AsmToken::Colon) { 1153 if (!TheCondState.Ignore) 1154 return TokError("unexpected token at start of statement"); 1155 } 1156 } 1157 } else if (Lexer.is(AsmToken::Dot)) { 1158 // Treat '.' as a valid identifier in this context. 1159 Lex(); 1160 IDVal = "."; 1161 } else if (parseIdentifier(IDVal)) { 1162 if (!TheCondState.Ignore) 1163 return TokError("unexpected token at start of statement"); 1164 IDVal = ""; 1165 } 1166 1167 // Handle conditional assembly here before checking for skipping. We 1168 // have to do this so that .endif isn't skipped in a ".if 0" block for 1169 // example. 1170 StringMap<DirectiveKind>::const_iterator DirKindIt = 1171 DirectiveKindMap.find(IDVal); 1172 DirectiveKind DirKind = 1173 (DirKindIt == DirectiveKindMap.end()) ? DK_NO_DIRECTIVE : 1174 DirKindIt->getValue(); 1175 switch (DirKind) { 1176 default: 1177 break; 1178 case DK_IF: 1179 return ParseDirectiveIf(IDLoc); 1180 case DK_IFB: 1181 return ParseDirectiveIfb(IDLoc, true); 1182 case DK_IFNB: 1183 return ParseDirectiveIfb(IDLoc, false); 1184 case DK_IFC: 1185 return ParseDirectiveIfc(IDLoc, true); 1186 case DK_IFNC: 1187 return ParseDirectiveIfc(IDLoc, false); 1188 case DK_IFDEF: 1189 return ParseDirectiveIfdef(IDLoc, true); 1190 case DK_IFNDEF: 1191 case DK_IFNOTDEF: 1192 return ParseDirectiveIfdef(IDLoc, false); 1193 case DK_ELSEIF: 1194 return ParseDirectiveElseIf(IDLoc); 1195 case DK_ELSE: 1196 return ParseDirectiveElse(IDLoc); 1197 case DK_ENDIF: 1198 return ParseDirectiveEndIf(IDLoc); 1199 } 1200 1201 // Ignore the statement if in the middle of inactive conditional 1202 // (e.g. ".if 0"). 1203 if (TheCondState.Ignore) { 1204 eatToEndOfStatement(); 1205 return false; 1206 } 1207 1208 // FIXME: Recurse on local labels? 1209 1210 // See what kind of statement we have. 1211 switch (Lexer.getKind()) { 1212 case AsmToken::Colon: { 1213 checkForValidSection(); 1214 1215 // identifier ':' -> Label. 1216 Lex(); 1217 1218 // Diagnose attempt to use '.' as a label. 1219 if (IDVal == ".") 1220 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label"); 1221 1222 // Diagnose attempt to use a variable as a label. 1223 // 1224 // FIXME: Diagnostics. Note the location of the definition as a label. 1225 // FIXME: This doesn't diagnose assignment to a symbol which has been 1226 // implicitly marked as external. 1227 MCSymbol *Sym; 1228 if (LocalLabelVal == -1) 1229 Sym = getContext().GetOrCreateSymbol(IDVal); 1230 else 1231 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); 1232 if (!Sym->isUndefined() || Sym->isVariable()) 1233 return Error(IDLoc, "invalid symbol redefinition"); 1234 1235 // Emit the label. 1236 if (!ParsingInlineAsm) 1237 Out.EmitLabel(Sym); 1238 1239 // If we are generating dwarf for assembly source files then gather the 1240 // info to make a dwarf label entry for this label if needed. 1241 if (getContext().getGenDwarfForAssembly()) 1242 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), 1243 IDLoc); 1244 1245 // Consume any end of statement token, if present, to avoid spurious 1246 // AddBlankLine calls(). 1247 if (Lexer.is(AsmToken::EndOfStatement)) { 1248 Lex(); 1249 if (Lexer.is(AsmToken::Eof)) 1250 return false; 1251 } 1252 1253 return false; 1254 } 1255 1256 case AsmToken::Equal: 1257 // identifier '=' ... -> assignment statement 1258 Lex(); 1259 1260 return ParseAssignment(IDVal, true); 1261 1262 default: // Normal instruction or directive. 1263 break; 1264 } 1265 1266 // If macros are enabled, check to see if this is a macro instantiation. 1267 if (MacrosEnabled()) 1268 if (const MCAsmMacro *M = LookupMacro(IDVal)) { 1269 return HandleMacroEntry(M, IDLoc); 1270 } 1271 1272 // Otherwise, we have a normal instruction or directive. 1273 1274 // Directives start with "." 1275 if (IDVal[0] == '.' && IDVal != ".") { 1276 // There are several entities interested in parsing directives: 1277 // 1278 // 1. The target-specific assembly parser. Some directives are target 1279 // specific or may potentially behave differently on certain targets. 1280 // 2. Asm parser extensions. For example, platform-specific parsers 1281 // (like the ELF parser) register themselves as extensions. 1282 // 3. The generic directive parser implemented by this class. These are 1283 // all the directives that behave in a target and platform independent 1284 // manner, or at least have a default behavior that's shared between 1285 // all targets and platforms. 1286 1287 // First query the target-specific parser. It will return 'true' if it 1288 // isn't interested in this directive. 1289 if (!getTargetParser().ParseDirective(ID)) 1290 return false; 1291 1292 // Next, check the extention directive map to see if any extension has 1293 // registered itself to parse this directive. 1294 std::pair<MCAsmParserExtension*, DirectiveHandler> Handler = 1295 ExtensionDirectiveMap.lookup(IDVal); 1296 if (Handler.first) 1297 return (*Handler.second)(Handler.first, IDVal, IDLoc); 1298 1299 // Finally, if no one else is interested in this directive, it must be 1300 // generic and familiar to this class. 1301 switch (DirKind) { 1302 default: 1303 break; 1304 case DK_SET: 1305 case DK_EQU: 1306 return ParseDirectiveSet(IDVal, true); 1307 case DK_EQUIV: 1308 return ParseDirectiveSet(IDVal, false); 1309 case DK_ASCII: 1310 return ParseDirectiveAscii(IDVal, false); 1311 case DK_ASCIZ: 1312 case DK_STRING: 1313 return ParseDirectiveAscii(IDVal, true); 1314 case DK_BYTE: 1315 return ParseDirectiveValue(1); 1316 case DK_SHORT: 1317 case DK_VALUE: 1318 case DK_2BYTE: 1319 return ParseDirectiveValue(2); 1320 case DK_LONG: 1321 case DK_INT: 1322 case DK_4BYTE: 1323 return ParseDirectiveValue(4); 1324 case DK_QUAD: 1325 case DK_8BYTE: 1326 return ParseDirectiveValue(8); 1327 case DK_SINGLE: 1328 case DK_FLOAT: 1329 return ParseDirectiveRealValue(APFloat::IEEEsingle); 1330 case DK_DOUBLE: 1331 return ParseDirectiveRealValue(APFloat::IEEEdouble); 1332 case DK_ALIGN: { 1333 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes(); 1334 return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1); 1335 } 1336 case DK_ALIGN32: { 1337 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes(); 1338 return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4); 1339 } 1340 case DK_BALIGN: 1341 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); 1342 case DK_BALIGNW: 1343 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); 1344 case DK_BALIGNL: 1345 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); 1346 case DK_P2ALIGN: 1347 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 1348 case DK_P2ALIGNW: 1349 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); 1350 case DK_P2ALIGNL: 1351 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 1352 case DK_ORG: 1353 return ParseDirectiveOrg(); 1354 case DK_FILL: 1355 return ParseDirectiveFill(); 1356 case DK_ZERO: 1357 return ParseDirectiveZero(); 1358 case DK_EXTERN: 1359 eatToEndOfStatement(); // .extern is the default, ignore it. 1360 return false; 1361 case DK_GLOBL: 1362 case DK_GLOBAL: 1363 return ParseDirectiveSymbolAttribute(MCSA_Global); 1364 case DK_INDIRECT_SYMBOL: 1365 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); 1366 case DK_LAZY_REFERENCE: 1367 return ParseDirectiveSymbolAttribute(MCSA_LazyReference); 1368 case DK_NO_DEAD_STRIP: 1369 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip); 1370 case DK_SYMBOL_RESOLVER: 1371 return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver); 1372 case DK_PRIVATE_EXTERN: 1373 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); 1374 case DK_REFERENCE: 1375 return ParseDirectiveSymbolAttribute(MCSA_Reference); 1376 case DK_WEAK_DEFINITION: 1377 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); 1378 case DK_WEAK_REFERENCE: 1379 return ParseDirectiveSymbolAttribute(MCSA_WeakReference); 1380 case DK_WEAK_DEF_CAN_BE_HIDDEN: 1381 return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); 1382 case DK_COMM: 1383 case DK_COMMON: 1384 return ParseDirectiveComm(/*IsLocal=*/false); 1385 case DK_LCOMM: 1386 return ParseDirectiveComm(/*IsLocal=*/true); 1387 case DK_ABORT: 1388 return ParseDirectiveAbort(); 1389 case DK_INCLUDE: 1390 return ParseDirectiveInclude(); 1391 case DK_INCBIN: 1392 return ParseDirectiveIncbin(); 1393 case DK_CODE16: 1394 case DK_CODE16GCC: 1395 return TokError(Twine(IDVal) + " not supported yet"); 1396 case DK_REPT: 1397 return ParseDirectiveRept(IDLoc); 1398 case DK_IRP: 1399 return ParseDirectiveIrp(IDLoc); 1400 case DK_IRPC: 1401 return ParseDirectiveIrpc(IDLoc); 1402 case DK_ENDR: 1403 return ParseDirectiveEndr(IDLoc); 1404 case DK_BUNDLE_ALIGN_MODE: 1405 return ParseDirectiveBundleAlignMode(); 1406 case DK_BUNDLE_LOCK: 1407 return ParseDirectiveBundleLock(); 1408 case DK_BUNDLE_UNLOCK: 1409 return ParseDirectiveBundleUnlock(); 1410 case DK_SLEB128: 1411 return ParseDirectiveLEB128(true); 1412 case DK_ULEB128: 1413 return ParseDirectiveLEB128(false); 1414 case DK_SPACE: 1415 case DK_SKIP: 1416 return ParseDirectiveSpace(IDVal); 1417 case DK_FILE: 1418 return ParseDirectiveFile(IDLoc); 1419 case DK_LINE: 1420 return ParseDirectiveLine(); 1421 case DK_LOC: 1422 return ParseDirectiveLoc(); 1423 case DK_STABS: 1424 return ParseDirectiveStabs(); 1425 case DK_CFI_SECTIONS: 1426 return ParseDirectiveCFISections(); 1427 case DK_CFI_STARTPROC: 1428 return ParseDirectiveCFIStartProc(); 1429 case DK_CFI_ENDPROC: 1430 return ParseDirectiveCFIEndProc(); 1431 case DK_CFI_DEF_CFA: 1432 return ParseDirectiveCFIDefCfa(IDLoc); 1433 case DK_CFI_DEF_CFA_OFFSET: 1434 return ParseDirectiveCFIDefCfaOffset(); 1435 case DK_CFI_ADJUST_CFA_OFFSET: 1436 return ParseDirectiveCFIAdjustCfaOffset(); 1437 case DK_CFI_DEF_CFA_REGISTER: 1438 return ParseDirectiveCFIDefCfaRegister(IDLoc); 1439 case DK_CFI_OFFSET: 1440 return ParseDirectiveCFIOffset(IDLoc); 1441 case DK_CFI_REL_OFFSET: 1442 return ParseDirectiveCFIRelOffset(IDLoc); 1443 case DK_CFI_PERSONALITY: 1444 return ParseDirectiveCFIPersonalityOrLsda(true); 1445 case DK_CFI_LSDA: 1446 return ParseDirectiveCFIPersonalityOrLsda(false); 1447 case DK_CFI_REMEMBER_STATE: 1448 return ParseDirectiveCFIRememberState(); 1449 case DK_CFI_RESTORE_STATE: 1450 return ParseDirectiveCFIRestoreState(); 1451 case DK_CFI_SAME_VALUE: 1452 return ParseDirectiveCFISameValue(IDLoc); 1453 case DK_CFI_RESTORE: 1454 return ParseDirectiveCFIRestore(IDLoc); 1455 case DK_CFI_ESCAPE: 1456 return ParseDirectiveCFIEscape(); 1457 case DK_CFI_SIGNAL_FRAME: 1458 return ParseDirectiveCFISignalFrame(); 1459 case DK_CFI_UNDEFINED: 1460 return ParseDirectiveCFIUndefined(IDLoc); 1461 case DK_CFI_REGISTER: 1462 return ParseDirectiveCFIRegister(IDLoc); 1463 case DK_MACROS_ON: 1464 case DK_MACROS_OFF: 1465 return ParseDirectiveMacrosOnOff(IDVal); 1466 case DK_MACRO: 1467 return ParseDirectiveMacro(IDLoc); 1468 case DK_ENDM: 1469 case DK_ENDMACRO: 1470 return ParseDirectiveEndMacro(IDVal); 1471 case DK_PURGEM: 1472 return ParseDirectivePurgeMacro(IDLoc); 1473 } 1474 1475 return Error(IDLoc, "unknown directive"); 1476 } 1477 1478 // __asm _emit or __asm __emit 1479 if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" || 1480 IDVal == "_EMIT" || IDVal == "__EMIT")) 1481 return ParseDirectiveMSEmit(IDLoc, Info, IDVal.size()); 1482 1483 // __asm align 1484 if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN")) 1485 return ParseDirectiveMSAlign(IDLoc, Info); 1486 1487 checkForValidSection(); 1488 1489 // Canonicalize the opcode to lower case. 1490 std::string OpcodeStr = IDVal.lower(); 1491 ParseInstructionInfo IInfo(Info.AsmRewrites); 1492 bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, 1493 IDLoc, Info.ParsedOperands); 1494 Info.ParseError = HadError; 1495 1496 // Dump the parsed representation, if requested. 1497 if (getShowParsedOperands()) { 1498 SmallString<256> Str; 1499 raw_svector_ostream OS(Str); 1500 OS << "parsed instruction: ["; 1501 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) { 1502 if (i != 0) 1503 OS << ", "; 1504 Info.ParsedOperands[i]->print(OS); 1505 } 1506 OS << "]"; 1507 1508 PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str()); 1509 } 1510 1511 // If we are generating dwarf for assembly source files and the current 1512 // section is the initial text section then generate a .loc directive for 1513 // the instruction. 1514 if (!HadError && getContext().getGenDwarfForAssembly() && 1515 getContext().getGenDwarfSection() == 1516 getStreamer().getCurrentSection().first) { 1517 1518 unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); 1519 1520 // If we previously parsed a cpp hash file line comment then make sure the 1521 // current Dwarf File is for the CppHashFilename if not then emit the 1522 // Dwarf File table for it and adjust the line number for the .loc. 1523 const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles = 1524 getContext().getMCDwarfFiles(); 1525 if (CppHashFilename.size() != 0) { 1526 if (MCDwarfFiles[getContext().getGenDwarfFileNumber()]->getName() != 1527 CppHashFilename) 1528 getStreamer().EmitDwarfFileDirective( 1529 getContext().nextGenDwarfFileNumber(), StringRef(), CppHashFilename); 1530 1531 // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's 1532 // cache with the different Loc from the call above we save the last 1533 // info we queried here with SrcMgr.FindLineNumber(). 1534 unsigned CppHashLocLineNo; 1535 if (LastQueryIDLoc == CppHashLoc && LastQueryBuffer == CppHashBuf) 1536 CppHashLocLineNo = LastQueryLine; 1537 else { 1538 CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf); 1539 LastQueryLine = CppHashLocLineNo; 1540 LastQueryIDLoc = CppHashLoc; 1541 LastQueryBuffer = CppHashBuf; 1542 } 1543 Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo); 1544 } 1545 1546 getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(), 1547 Line, 0, DWARF2_LINE_DEFAULT_IS_STMT ? 1548 DWARF2_FLAG_IS_STMT : 0, 0, 0, 1549 StringRef()); 1550 } 1551 1552 // If parsing succeeded, match the instruction. 1553 if (!HadError) { 1554 unsigned ErrorInfo; 1555 HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode, 1556 Info.ParsedOperands, 1557 Out, ErrorInfo, 1558 ParsingInlineAsm); 1559 } 1560 1561 // Don't skip the rest of the line, the instruction parser is responsible for 1562 // that. 1563 return false; 1564 } 1565 1566 /// EatToEndOfLine uses the Lexer to eat the characters to the end of the line 1567 /// since they may not be able to be tokenized to get to the end of line token. 1568 void AsmParser::EatToEndOfLine() { 1569 if (!Lexer.is(AsmToken::EndOfStatement)) 1570 Lexer.LexUntilEndOfLine(); 1571 // Eat EOL. 1572 Lex(); 1573 } 1574 1575 /// ParseCppHashLineFilenameComment as this: 1576 /// ::= # number "filename" 1577 /// or just as a full line comment if it doesn't have a number and a string. 1578 bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { 1579 Lex(); // Eat the hash token. 1580 1581 if (getLexer().isNot(AsmToken::Integer)) { 1582 // Consume the line since in cases it is not a well-formed line directive, 1583 // as if were simply a full line comment. 1584 EatToEndOfLine(); 1585 return false; 1586 } 1587 1588 int64_t LineNumber = getTok().getIntVal(); 1589 Lex(); 1590 1591 if (getLexer().isNot(AsmToken::String)) { 1592 EatToEndOfLine(); 1593 return false; 1594 } 1595 1596 StringRef Filename = getTok().getString(); 1597 // Get rid of the enclosing quotes. 1598 Filename = Filename.substr(1, Filename.size()-2); 1599 1600 // Save the SMLoc, Filename and LineNumber for later use by diagnostics. 1601 CppHashLoc = L; 1602 CppHashFilename = Filename; 1603 CppHashLineNumber = LineNumber; 1604 CppHashBuf = CurBuffer; 1605 1606 // Ignore any trailing characters, they're just comment. 1607 EatToEndOfLine(); 1608 return false; 1609 } 1610 1611 /// DiagHandler - will use the last parsed cpp hash line filename comment 1612 /// for the Filename and LineNo if any in the diagnostic. 1613 void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { 1614 const AsmParser *Parser = static_cast<const AsmParser*>(Context); 1615 raw_ostream &OS = errs(); 1616 1617 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); 1618 const SMLoc &DiagLoc = Diag.getLoc(); 1619 int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1620 int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); 1621 1622 // Like SourceMgr::PrintMessage() we need to print the include stack if any 1623 // before printing the message. 1624 int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1625 if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) { 1626 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); 1627 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); 1628 } 1629 1630 // If we have not parsed a cpp hash line filename comment or the source 1631 // manager changed or buffer changed (like in a nested include) then just 1632 // print the normal diagnostic using its Filename and LineNo. 1633 if (!Parser->CppHashLineNumber || 1634 &DiagSrcMgr != &Parser->SrcMgr || 1635 DiagBuf != CppHashBuf) { 1636 if (Parser->SavedDiagHandler) 1637 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); 1638 else 1639 Diag.print(0, OS); 1640 return; 1641 } 1642 1643 // Use the CppHashFilename and calculate a line number based on the 1644 // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for 1645 // the diagnostic. 1646 const std::string Filename = Parser->CppHashFilename; 1647 1648 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); 1649 int CppHashLocLineNo = 1650 Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); 1651 int LineNo = Parser->CppHashLineNumber - 1 + 1652 (DiagLocLineNo - CppHashLocLineNo); 1653 1654 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), 1655 Filename, LineNo, Diag.getColumnNo(), 1656 Diag.getKind(), Diag.getMessage(), 1657 Diag.getLineContents(), Diag.getRanges()); 1658 1659 if (Parser->SavedDiagHandler) 1660 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); 1661 else 1662 NewDiag.print(0, OS); 1663 } 1664 1665 // FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The 1666 // difference being that that function accepts '@' as part of identifiers and 1667 // we can't do that. AsmLexer.cpp should probably be changed to handle 1668 // '@' as a special case when needed. 1669 static bool isIdentifierChar(char c) { 1670 return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' || 1671 c == '.'; 1672 } 1673 1674 bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, 1675 const MCAsmMacroParameters &Parameters, 1676 const MCAsmMacroArguments &A, 1677 const SMLoc &L) { 1678 unsigned NParameters = Parameters.size(); 1679 if (NParameters != 0 && NParameters != A.size()) 1680 return Error(L, "Wrong number of arguments"); 1681 1682 // A macro without parameters is handled differently on Darwin: 1683 // gas accepts no arguments and does no substitutions 1684 while (!Body.empty()) { 1685 // Scan for the next substitution. 1686 std::size_t End = Body.size(), Pos = 0; 1687 for (; Pos != End; ++Pos) { 1688 // Check for a substitution or escape. 1689 if (!NParameters) { 1690 // This macro has no parameters, look for $0, $1, etc. 1691 if (Body[Pos] != '$' || Pos + 1 == End) 1692 continue; 1693 1694 char Next = Body[Pos + 1]; 1695 if (Next == '$' || Next == 'n' || 1696 isdigit(static_cast<unsigned char>(Next))) 1697 break; 1698 } else { 1699 // This macro has parameters, look for \foo, \bar, etc. 1700 if (Body[Pos] == '\\' && Pos + 1 != End) 1701 break; 1702 } 1703 } 1704 1705 // Add the prefix. 1706 OS << Body.slice(0, Pos); 1707 1708 // Check if we reached the end. 1709 if (Pos == End) 1710 break; 1711 1712 if (!NParameters) { 1713 switch (Body[Pos+1]) { 1714 // $$ => $ 1715 case '$': 1716 OS << '$'; 1717 break; 1718 1719 // $n => number of arguments 1720 case 'n': 1721 OS << A.size(); 1722 break; 1723 1724 // $[0-9] => argument 1725 default: { 1726 // Missing arguments are ignored. 1727 unsigned Index = Body[Pos+1] - '0'; 1728 if (Index >= A.size()) 1729 break; 1730 1731 // Otherwise substitute with the token values, with spaces eliminated. 1732 for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), 1733 ie = A[Index].end(); it != ie; ++it) 1734 OS << it->getString(); 1735 break; 1736 } 1737 } 1738 Pos += 2; 1739 } else { 1740 unsigned I = Pos + 1; 1741 while (isIdentifierChar(Body[I]) && I + 1 != End) 1742 ++I; 1743 1744 const char *Begin = Body.data() + Pos +1; 1745 StringRef Argument(Begin, I - (Pos +1)); 1746 unsigned Index = 0; 1747 for (; Index < NParameters; ++Index) 1748 if (Parameters[Index].first == Argument) 1749 break; 1750 1751 if (Index == NParameters) { 1752 if (Body[Pos+1] == '(' && Body[Pos+2] == ')') 1753 Pos += 3; 1754 else { 1755 OS << '\\' << Argument; 1756 Pos = I; 1757 } 1758 } else { 1759 for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), 1760 ie = A[Index].end(); it != ie; ++it) 1761 if (it->getKind() == AsmToken::String) 1762 OS << it->getStringContents(); 1763 else 1764 OS << it->getString(); 1765 1766 Pos += 1 + Argument.size(); 1767 } 1768 } 1769 // Update the scan point. 1770 Body = Body.substr(Pos); 1771 } 1772 1773 return false; 1774 } 1775 1776 MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL, 1777 int EB, SMLoc EL, 1778 MemoryBuffer *I) 1779 : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), 1780 ExitLoc(EL) 1781 { 1782 } 1783 1784 static bool IsOperator(AsmToken::TokenKind kind) 1785 { 1786 switch (kind) 1787 { 1788 default: 1789 return false; 1790 case AsmToken::Plus: 1791 case AsmToken::Minus: 1792 case AsmToken::Tilde: 1793 case AsmToken::Slash: 1794 case AsmToken::Star: 1795 case AsmToken::Dot: 1796 case AsmToken::Equal: 1797 case AsmToken::EqualEqual: 1798 case AsmToken::Pipe: 1799 case AsmToken::PipePipe: 1800 case AsmToken::Caret: 1801 case AsmToken::Amp: 1802 case AsmToken::AmpAmp: 1803 case AsmToken::Exclaim: 1804 case AsmToken::ExclaimEqual: 1805 case AsmToken::Percent: 1806 case AsmToken::Less: 1807 case AsmToken::LessEqual: 1808 case AsmToken::LessLess: 1809 case AsmToken::LessGreater: 1810 case AsmToken::Greater: 1811 case AsmToken::GreaterEqual: 1812 case AsmToken::GreaterGreater: 1813 return true; 1814 } 1815 } 1816 1817 bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA, 1818 AsmToken::TokenKind &ArgumentDelimiter) { 1819 unsigned ParenLevel = 0; 1820 unsigned AddTokens = 0; 1821 1822 // gas accepts arguments separated by whitespace, except on Darwin 1823 if (!IsDarwin) 1824 Lexer.setSkipSpace(false); 1825 1826 for (;;) { 1827 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) { 1828 Lexer.setSkipSpace(true); 1829 return TokError("unexpected token in macro instantiation"); 1830 } 1831 1832 if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) { 1833 // Spaces and commas cannot be mixed to delimit parameters 1834 if (ArgumentDelimiter == AsmToken::Eof) 1835 ArgumentDelimiter = AsmToken::Comma; 1836 else if (ArgumentDelimiter != AsmToken::Comma) { 1837 Lexer.setSkipSpace(true); 1838 return TokError("expected ' ' for macro argument separator"); 1839 } 1840 break; 1841 } 1842 1843 if (Lexer.is(AsmToken::Space)) { 1844 Lex(); // Eat spaces 1845 1846 // Spaces can delimit parameters, but could also be part an expression. 1847 // If the token after a space is an operator, add the token and the next 1848 // one into this argument 1849 if (ArgumentDelimiter == AsmToken::Space || 1850 ArgumentDelimiter == AsmToken::Eof) { 1851 if (IsOperator(Lexer.getKind())) { 1852 // Check to see whether the token is used as an operator, 1853 // or part of an identifier 1854 const char *NextChar = getTok().getEndLoc().getPointer(); 1855 if (*NextChar == ' ') 1856 AddTokens = 2; 1857 } 1858 1859 if (!AddTokens && ParenLevel == 0) { 1860 if (ArgumentDelimiter == AsmToken::Eof && 1861 !IsOperator(Lexer.getKind())) 1862 ArgumentDelimiter = AsmToken::Space; 1863 break; 1864 } 1865 } 1866 } 1867 1868 // HandleMacroEntry relies on not advancing the lexer here 1869 // to be able to fill in the remaining default parameter values 1870 if (Lexer.is(AsmToken::EndOfStatement)) 1871 break; 1872 1873 // Adjust the current parentheses level. 1874 if (Lexer.is(AsmToken::LParen)) 1875 ++ParenLevel; 1876 else if (Lexer.is(AsmToken::RParen) && ParenLevel) 1877 --ParenLevel; 1878 1879 // Append the token to the current argument list. 1880 MA.push_back(getTok()); 1881 if (AddTokens) 1882 AddTokens--; 1883 Lex(); 1884 } 1885 1886 Lexer.setSkipSpace(true); 1887 if (ParenLevel != 0) 1888 return TokError("unbalanced parentheses in macro argument"); 1889 return false; 1890 } 1891 1892 // Parse the macro instantiation arguments. 1893 bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A) { 1894 const unsigned NParameters = M ? M->Parameters.size() : 0; 1895 // Argument delimiter is initially unknown. It will be set by 1896 // ParseMacroArgument() 1897 AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof; 1898 1899 // Parse two kinds of macro invocations: 1900 // - macros defined without any parameters accept an arbitrary number of them 1901 // - macros defined with parameters accept at most that many of them 1902 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; 1903 ++Parameter) { 1904 MCAsmMacroArgument MA; 1905 1906 if (ParseMacroArgument(MA, ArgumentDelimiter)) 1907 return true; 1908 1909 if (!MA.empty() || !NParameters) 1910 A.push_back(MA); 1911 else if (NParameters) { 1912 if (!M->Parameters[Parameter].second.empty()) 1913 A.push_back(M->Parameters[Parameter].second); 1914 } 1915 1916 // At the end of the statement, fill in remaining arguments that have 1917 // default values. If there aren't any, then the next argument is 1918 // required but missing 1919 if (Lexer.is(AsmToken::EndOfStatement)) { 1920 if (NParameters && Parameter < NParameters - 1) { 1921 if (M->Parameters[Parameter + 1].second.empty()) 1922 return TokError("macro argument '" + 1923 Twine(M->Parameters[Parameter + 1].first) + 1924 "' is missing"); 1925 else 1926 continue; 1927 } 1928 return false; 1929 } 1930 1931 if (Lexer.is(AsmToken::Comma)) 1932 Lex(); 1933 } 1934 return TokError("Too many arguments"); 1935 } 1936 1937 const MCAsmMacro* AsmParser::LookupMacro(StringRef Name) { 1938 StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name); 1939 return (I == MacroMap.end()) ? NULL : I->getValue(); 1940 } 1941 1942 void AsmParser::DefineMacro(StringRef Name, const MCAsmMacro& Macro) { 1943 MacroMap[Name] = new MCAsmMacro(Macro); 1944 } 1945 1946 void AsmParser::UndefineMacro(StringRef Name) { 1947 StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name); 1948 if (I != MacroMap.end()) { 1949 delete I->getValue(); 1950 MacroMap.erase(I); 1951 } 1952 } 1953 1954 bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { 1955 // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate 1956 // this, although we should protect against infinite loops. 1957 if (ActiveMacros.size() == 20) 1958 return TokError("macros cannot be nested more than 20 levels deep"); 1959 1960 MCAsmMacroArguments A; 1961 if (ParseMacroArguments(M, A)) 1962 return true; 1963 1964 // Remove any trailing empty arguments. Do this after-the-fact as we have 1965 // to keep empty arguments in the middle of the list or positionality 1966 // gets off. e.g., "foo 1, , 2" vs. "foo 1, 2," 1967 while (!A.empty() && A.back().empty()) 1968 A.pop_back(); 1969 1970 // Macro instantiation is lexical, unfortunately. We construct a new buffer 1971 // to hold the macro body with substitutions. 1972 SmallString<256> Buf; 1973 StringRef Body = M->Body; 1974 raw_svector_ostream OS(Buf); 1975 1976 if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc())) 1977 return true; 1978 1979 // We include the .endmacro in the buffer as our cue to exit the macro 1980 // instantiation. 1981 OS << ".endmacro\n"; 1982 1983 MemoryBuffer *Instantiation = 1984 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 1985 1986 // Create the macro instantiation object and add to the current macro 1987 // instantiation stack. 1988 MacroInstantiation *MI = new MacroInstantiation(M, NameLoc, 1989 CurBuffer, 1990 getTok().getLoc(), 1991 Instantiation); 1992 ActiveMacros.push_back(MI); 1993 1994 // Jump to the macro instantiation and prime the lexer. 1995 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 1996 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 1997 Lex(); 1998 1999 return false; 2000 } 2001 2002 void AsmParser::HandleMacroExit() { 2003 // Jump to the EndOfStatement we should return to, and consume it. 2004 JumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer); 2005 Lex(); 2006 2007 // Pop the instantiation entry. 2008 delete ActiveMacros.back(); 2009 ActiveMacros.pop_back(); 2010 } 2011 2012 static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) { 2013 switch (Value->getKind()) { 2014 case MCExpr::Binary: { 2015 const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value); 2016 return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS()); 2017 } 2018 case MCExpr::Target: 2019 case MCExpr::Constant: 2020 return false; 2021 case MCExpr::SymbolRef: { 2022 const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol(); 2023 if (S.isVariable()) 2024 return IsUsedIn(Sym, S.getVariableValue()); 2025 return &S == Sym; 2026 } 2027 case MCExpr::Unary: 2028 return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr()); 2029 } 2030 2031 llvm_unreachable("Unknown expr kind!"); 2032 } 2033 2034 bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef, 2035 bool NoDeadStrip) { 2036 // FIXME: Use better location, we should use proper tokens. 2037 SMLoc EqualLoc = Lexer.getLoc(); 2038 2039 const MCExpr *Value; 2040 if (parseExpression(Value)) 2041 return true; 2042 2043 // Note: we don't count b as used in "a = b". This is to allow 2044 // a = b 2045 // b = c 2046 2047 if (Lexer.isNot(AsmToken::EndOfStatement)) 2048 return TokError("unexpected token in assignment"); 2049 2050 // Error on assignment to '.'. 2051 if (Name == ".") { 2052 return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported " 2053 "(use '.space' or '.org').)")); 2054 } 2055 2056 // Eat the end of statement marker. 2057 Lex(); 2058 2059 // Validate that the LHS is allowed to be a variable (either it has not been 2060 // used as a symbol, or it is an absolute symbol). 2061 MCSymbol *Sym = getContext().LookupSymbol(Name); 2062 if (Sym) { 2063 // Diagnose assignment to a label. 2064 // 2065 // FIXME: Diagnostics. Note the location of the definition as a label. 2066 // FIXME: Diagnose assignment to protected identifier (e.g., register name). 2067 if (IsUsedIn(Sym, Value)) 2068 return Error(EqualLoc, "Recursive use of '" + Name + "'"); 2069 else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable()) 2070 ; // Allow redefinitions of undefined symbols only used in directives. 2071 else if (Sym->isVariable() && !Sym->isUsed() && allow_redef) 2072 ; // Allow redefinitions of variables that haven't yet been used. 2073 else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef)) 2074 return Error(EqualLoc, "redefinition of '" + Name + "'"); 2075 else if (!Sym->isVariable()) 2076 return Error(EqualLoc, "invalid assignment to '" + Name + "'"); 2077 else if (!isa<MCConstantExpr>(Sym->getVariableValue())) 2078 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + 2079 Name + "'"); 2080 2081 // Don't count these checks as uses. 2082 Sym->setUsed(false); 2083 } else 2084 Sym = getContext().GetOrCreateSymbol(Name); 2085 2086 // FIXME: Handle '.'. 2087 2088 // Do the assignment. 2089 Out.EmitAssignment(Sym, Value); 2090 if (NoDeadStrip) 2091 Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip); 2092 2093 2094 return false; 2095 } 2096 2097 /// parseIdentifier: 2098 /// ::= identifier 2099 /// ::= string 2100 bool AsmParser::parseIdentifier(StringRef &Res) { 2101 // The assembler has relaxed rules for accepting identifiers, in particular we 2102 // allow things like '.globl $foo', which would normally be separate 2103 // tokens. At this level, we have already lexed so we cannot (currently) 2104 // handle this as a context dependent token, instead we detect adjacent tokens 2105 // and return the combined identifier. 2106 if (Lexer.is(AsmToken::Dollar)) { 2107 SMLoc DollarLoc = getLexer().getLoc(); 2108 2109 // Consume the dollar sign, and check for a following identifier. 2110 Lex(); 2111 if (Lexer.isNot(AsmToken::Identifier)) 2112 return true; 2113 2114 // We have a '$' followed by an identifier, make sure they are adjacent. 2115 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 2116 return true; 2117 2118 // Construct the joined identifier and consume the token. 2119 Res = StringRef(DollarLoc.getPointer(), 2120 getTok().getIdentifier().size() + 1); 2121 Lex(); 2122 return false; 2123 } 2124 2125 if (Lexer.isNot(AsmToken::Identifier) && 2126 Lexer.isNot(AsmToken::String)) 2127 return true; 2128 2129 Res = getTok().getIdentifier(); 2130 2131 Lex(); // Consume the identifier token. 2132 2133 return false; 2134 } 2135 2136 /// ParseDirectiveSet: 2137 /// ::= .equ identifier ',' expression 2138 /// ::= .equiv identifier ',' expression 2139 /// ::= .set identifier ',' expression 2140 bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) { 2141 StringRef Name; 2142 2143 if (parseIdentifier(Name)) 2144 return TokError("expected identifier after '" + Twine(IDVal) + "'"); 2145 2146 if (getLexer().isNot(AsmToken::Comma)) 2147 return TokError("unexpected token in '" + Twine(IDVal) + "'"); 2148 Lex(); 2149 2150 return ParseAssignment(Name, allow_redef, true); 2151 } 2152 2153 bool AsmParser::parseEscapedString(std::string &Data) { 2154 assert(getLexer().is(AsmToken::String) && "Unexpected current token!"); 2155 2156 Data = ""; 2157 StringRef Str = getTok().getStringContents(); 2158 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 2159 if (Str[i] != '\\') { 2160 Data += Str[i]; 2161 continue; 2162 } 2163 2164 // Recognize escaped characters. Note that this escape semantics currently 2165 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes. 2166 ++i; 2167 if (i == e) 2168 return TokError("unexpected backslash at end of string"); 2169 2170 // Recognize octal sequences. 2171 if ((unsigned) (Str[i] - '0') <= 7) { 2172 // Consume up to three octal characters. 2173 unsigned Value = Str[i] - '0'; 2174 2175 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 2176 ++i; 2177 Value = Value * 8 + (Str[i] - '0'); 2178 2179 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 2180 ++i; 2181 Value = Value * 8 + (Str[i] - '0'); 2182 } 2183 } 2184 2185 if (Value > 255) 2186 return TokError("invalid octal escape sequence (out of range)"); 2187 2188 Data += (unsigned char) Value; 2189 continue; 2190 } 2191 2192 // Otherwise recognize individual escapes. 2193 switch (Str[i]) { 2194 default: 2195 // Just reject invalid escape sequences for now. 2196 return TokError("invalid escape sequence (unrecognized character)"); 2197 2198 case 'b': Data += '\b'; break; 2199 case 'f': Data += '\f'; break; 2200 case 'n': Data += '\n'; break; 2201 case 'r': Data += '\r'; break; 2202 case 't': Data += '\t'; break; 2203 case '"': Data += '"'; break; 2204 case '\\': Data += '\\'; break; 2205 } 2206 } 2207 2208 return false; 2209 } 2210 2211 /// ParseDirectiveAscii: 2212 /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ] 2213 bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { 2214 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2215 checkForValidSection(); 2216 2217 for (;;) { 2218 if (getLexer().isNot(AsmToken::String)) 2219 return TokError("expected string in '" + Twine(IDVal) + "' directive"); 2220 2221 std::string Data; 2222 if (parseEscapedString(Data)) 2223 return true; 2224 2225 getStreamer().EmitBytes(Data); 2226 if (ZeroTerminated) 2227 getStreamer().EmitBytes(StringRef("\0", 1)); 2228 2229 Lex(); 2230 2231 if (getLexer().is(AsmToken::EndOfStatement)) 2232 break; 2233 2234 if (getLexer().isNot(AsmToken::Comma)) 2235 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 2236 Lex(); 2237 } 2238 } 2239 2240 Lex(); 2241 return false; 2242 } 2243 2244 /// ParseDirectiveValue 2245 /// ::= (.byte | .short | ... ) [ expression (, expression)* ] 2246 bool AsmParser::ParseDirectiveValue(unsigned Size) { 2247 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2248 checkForValidSection(); 2249 2250 for (;;) { 2251 const MCExpr *Value; 2252 SMLoc ExprLoc = getLexer().getLoc(); 2253 if (parseExpression(Value)) 2254 return true; 2255 2256 // Special case constant expressions to match code generator. 2257 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2258 assert(Size <= 8 && "Invalid size"); 2259 uint64_t IntValue = MCE->getValue(); 2260 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 2261 return Error(ExprLoc, "literal value out of range for directive"); 2262 getStreamer().EmitIntValue(IntValue, Size); 2263 } else 2264 getStreamer().EmitValue(Value, Size); 2265 2266 if (getLexer().is(AsmToken::EndOfStatement)) 2267 break; 2268 2269 // FIXME: Improve diagnostic. 2270 if (getLexer().isNot(AsmToken::Comma)) 2271 return TokError("unexpected token in directive"); 2272 Lex(); 2273 } 2274 } 2275 2276 Lex(); 2277 return false; 2278 } 2279 2280 /// ParseDirectiveRealValue 2281 /// ::= (.single | .double) [ expression (, expression)* ] 2282 bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) { 2283 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2284 checkForValidSection(); 2285 2286 for (;;) { 2287 // We don't truly support arithmetic on floating point expressions, so we 2288 // have to manually parse unary prefixes. 2289 bool IsNeg = false; 2290 if (getLexer().is(AsmToken::Minus)) { 2291 Lex(); 2292 IsNeg = true; 2293 } else if (getLexer().is(AsmToken::Plus)) 2294 Lex(); 2295 2296 if (getLexer().isNot(AsmToken::Integer) && 2297 getLexer().isNot(AsmToken::Real) && 2298 getLexer().isNot(AsmToken::Identifier)) 2299 return TokError("unexpected token in directive"); 2300 2301 // Convert to an APFloat. 2302 APFloat Value(Semantics); 2303 StringRef IDVal = getTok().getString(); 2304 if (getLexer().is(AsmToken::Identifier)) { 2305 if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf")) 2306 Value = APFloat::getInf(Semantics); 2307 else if (!IDVal.compare_lower("nan")) 2308 Value = APFloat::getNaN(Semantics, false, ~0); 2309 else 2310 return TokError("invalid floating point literal"); 2311 } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) == 2312 APFloat::opInvalidOp) 2313 return TokError("invalid floating point literal"); 2314 if (IsNeg) 2315 Value.changeSign(); 2316 2317 // Consume the numeric token. 2318 Lex(); 2319 2320 // Emit the value as an integer. 2321 APInt AsInt = Value.bitcastToAPInt(); 2322 getStreamer().EmitIntValue(AsInt.getLimitedValue(), 2323 AsInt.getBitWidth() / 8); 2324 2325 if (getLexer().is(AsmToken::EndOfStatement)) 2326 break; 2327 2328 if (getLexer().isNot(AsmToken::Comma)) 2329 return TokError("unexpected token in directive"); 2330 Lex(); 2331 } 2332 } 2333 2334 Lex(); 2335 return false; 2336 } 2337 2338 /// ParseDirectiveZero 2339 /// ::= .zero expression 2340 bool AsmParser::ParseDirectiveZero() { 2341 checkForValidSection(); 2342 2343 int64_t NumBytes; 2344 if (parseAbsoluteExpression(NumBytes)) 2345 return true; 2346 2347 int64_t Val = 0; 2348 if (getLexer().is(AsmToken::Comma)) { 2349 Lex(); 2350 if (parseAbsoluteExpression(Val)) 2351 return true; 2352 } 2353 2354 if (getLexer().isNot(AsmToken::EndOfStatement)) 2355 return TokError("unexpected token in '.zero' directive"); 2356 2357 Lex(); 2358 2359 getStreamer().EmitFill(NumBytes, Val); 2360 2361 return false; 2362 } 2363 2364 /// ParseDirectiveFill 2365 /// ::= .fill expression , expression , expression 2366 bool AsmParser::ParseDirectiveFill() { 2367 checkForValidSection(); 2368 2369 int64_t NumValues; 2370 if (parseAbsoluteExpression(NumValues)) 2371 return true; 2372 2373 if (getLexer().isNot(AsmToken::Comma)) 2374 return TokError("unexpected token in '.fill' directive"); 2375 Lex(); 2376 2377 int64_t FillSize; 2378 if (parseAbsoluteExpression(FillSize)) 2379 return true; 2380 2381 if (getLexer().isNot(AsmToken::Comma)) 2382 return TokError("unexpected token in '.fill' directive"); 2383 Lex(); 2384 2385 int64_t FillExpr; 2386 if (parseAbsoluteExpression(FillExpr)) 2387 return true; 2388 2389 if (getLexer().isNot(AsmToken::EndOfStatement)) 2390 return TokError("unexpected token in '.fill' directive"); 2391 2392 Lex(); 2393 2394 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8) 2395 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); 2396 2397 for (uint64_t i = 0, e = NumValues; i != e; ++i) 2398 getStreamer().EmitIntValue(FillExpr, FillSize); 2399 2400 return false; 2401 } 2402 2403 /// ParseDirectiveOrg 2404 /// ::= .org expression [ , expression ] 2405 bool AsmParser::ParseDirectiveOrg() { 2406 checkForValidSection(); 2407 2408 const MCExpr *Offset; 2409 SMLoc Loc = getTok().getLoc(); 2410 if (parseExpression(Offset)) 2411 return true; 2412 2413 // Parse optional fill expression. 2414 int64_t FillExpr = 0; 2415 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2416 if (getLexer().isNot(AsmToken::Comma)) 2417 return TokError("unexpected token in '.org' directive"); 2418 Lex(); 2419 2420 if (parseAbsoluteExpression(FillExpr)) 2421 return true; 2422 2423 if (getLexer().isNot(AsmToken::EndOfStatement)) 2424 return TokError("unexpected token in '.org' directive"); 2425 } 2426 2427 Lex(); 2428 2429 // Only limited forms of relocatable expressions are accepted here, it 2430 // has to be relative to the current section. The streamer will return 2431 // 'true' if the expression wasn't evaluatable. 2432 if (getStreamer().EmitValueToOffset(Offset, FillExpr)) 2433 return Error(Loc, "expected assembly-time absolute expression"); 2434 2435 return false; 2436 } 2437 2438 /// ParseDirectiveAlign 2439 /// ::= {.align, ...} expression [ , expression [ , expression ]] 2440 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { 2441 checkForValidSection(); 2442 2443 SMLoc AlignmentLoc = getLexer().getLoc(); 2444 int64_t Alignment; 2445 if (parseAbsoluteExpression(Alignment)) 2446 return true; 2447 2448 SMLoc MaxBytesLoc; 2449 bool HasFillExpr = false; 2450 int64_t FillExpr = 0; 2451 int64_t MaxBytesToFill = 0; 2452 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2453 if (getLexer().isNot(AsmToken::Comma)) 2454 return TokError("unexpected token in directive"); 2455 Lex(); 2456 2457 // The fill expression can be omitted while specifying a maximum number of 2458 // alignment bytes, e.g: 2459 // .align 3,,4 2460 if (getLexer().isNot(AsmToken::Comma)) { 2461 HasFillExpr = true; 2462 if (parseAbsoluteExpression(FillExpr)) 2463 return true; 2464 } 2465 2466 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2467 if (getLexer().isNot(AsmToken::Comma)) 2468 return TokError("unexpected token in directive"); 2469 Lex(); 2470 2471 MaxBytesLoc = getLexer().getLoc(); 2472 if (parseAbsoluteExpression(MaxBytesToFill)) 2473 return true; 2474 2475 if (getLexer().isNot(AsmToken::EndOfStatement)) 2476 return TokError("unexpected token in directive"); 2477 } 2478 } 2479 2480 Lex(); 2481 2482 if (!HasFillExpr) 2483 FillExpr = 0; 2484 2485 // Compute alignment in bytes. 2486 if (IsPow2) { 2487 // FIXME: Diagnose overflow. 2488 if (Alignment >= 32) { 2489 Error(AlignmentLoc, "invalid alignment value"); 2490 Alignment = 31; 2491 } 2492 2493 Alignment = 1ULL << Alignment; 2494 } else { 2495 // Reject alignments that aren't a power of two, for gas compatibility. 2496 if (!isPowerOf2_64(Alignment)) 2497 Error(AlignmentLoc, "alignment must be a power of 2"); 2498 } 2499 2500 // Diagnose non-sensical max bytes to align. 2501 if (MaxBytesLoc.isValid()) { 2502 if (MaxBytesToFill < 1) { 2503 Error(MaxBytesLoc, "alignment directive can never be satisfied in this " 2504 "many bytes, ignoring maximum bytes expression"); 2505 MaxBytesToFill = 0; 2506 } 2507 2508 if (MaxBytesToFill >= Alignment) { 2509 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " 2510 "has no effect"); 2511 MaxBytesToFill = 0; 2512 } 2513 } 2514 2515 // Check whether we should use optimal code alignment for this .align 2516 // directive. 2517 bool UseCodeAlign = getStreamer().getCurrentSection().first->UseCodeAlign(); 2518 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) && 2519 ValueSize == 1 && UseCodeAlign) { 2520 getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill); 2521 } else { 2522 // FIXME: Target specific behavior about how the "extra" bytes are filled. 2523 getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize, 2524 MaxBytesToFill); 2525 } 2526 2527 return false; 2528 } 2529 2530 /// ParseDirectiveFile 2531 /// ::= .file [number] filename 2532 /// ::= .file number directory filename 2533 bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) { 2534 // FIXME: I'm not sure what this is. 2535 int64_t FileNumber = -1; 2536 SMLoc FileNumberLoc = getLexer().getLoc(); 2537 if (getLexer().is(AsmToken::Integer)) { 2538 FileNumber = getTok().getIntVal(); 2539 Lex(); 2540 2541 if (FileNumber < 1) 2542 return TokError("file number less than one"); 2543 } 2544 2545 if (getLexer().isNot(AsmToken::String)) 2546 return TokError("unexpected token in '.file' directive"); 2547 2548 // Usually the directory and filename together, otherwise just the directory. 2549 StringRef Path = getTok().getString(); 2550 Path = Path.substr(1, Path.size()-2); 2551 Lex(); 2552 2553 StringRef Directory; 2554 StringRef Filename; 2555 if (getLexer().is(AsmToken::String)) { 2556 if (FileNumber == -1) 2557 return TokError("explicit path specified, but no file number"); 2558 Filename = getTok().getString(); 2559 Filename = Filename.substr(1, Filename.size()-2); 2560 Directory = Path; 2561 Lex(); 2562 } else { 2563 Filename = Path; 2564 } 2565 2566 if (getLexer().isNot(AsmToken::EndOfStatement)) 2567 return TokError("unexpected token in '.file' directive"); 2568 2569 if (FileNumber == -1) 2570 getStreamer().EmitFileDirective(Filename); 2571 else { 2572 if (getContext().getGenDwarfForAssembly() == true) 2573 Error(DirectiveLoc, "input can't have .file dwarf directives when -g is " 2574 "used to generate dwarf debug info for assembly code"); 2575 2576 if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename)) 2577 Error(FileNumberLoc, "file number already allocated"); 2578 } 2579 2580 return false; 2581 } 2582 2583 /// ParseDirectiveLine 2584 /// ::= .line [number] 2585 bool AsmParser::ParseDirectiveLine() { 2586 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2587 if (getLexer().isNot(AsmToken::Integer)) 2588 return TokError("unexpected token in '.line' directive"); 2589 2590 int64_t LineNumber = getTok().getIntVal(); 2591 (void) LineNumber; 2592 Lex(); 2593 2594 // FIXME: Do something with the .line. 2595 } 2596 2597 if (getLexer().isNot(AsmToken::EndOfStatement)) 2598 return TokError("unexpected token in '.line' directive"); 2599 2600 return false; 2601 } 2602 2603 /// ParseDirectiveLoc 2604 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] 2605 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE] 2606 /// The first number is a file number, must have been previously assigned with 2607 /// a .file directive, the second number is the line number and optionally the 2608 /// third number is a column position (zero if not specified). The remaining 2609 /// optional items are .loc sub-directives. 2610 bool AsmParser::ParseDirectiveLoc() { 2611 if (getLexer().isNot(AsmToken::Integer)) 2612 return TokError("unexpected token in '.loc' directive"); 2613 int64_t FileNumber = getTok().getIntVal(); 2614 if (FileNumber < 1) 2615 return TokError("file number less than one in '.loc' directive"); 2616 if (!getContext().isValidDwarfFileNumber(FileNumber)) 2617 return TokError("unassigned file number in '.loc' directive"); 2618 Lex(); 2619 2620 int64_t LineNumber = 0; 2621 if (getLexer().is(AsmToken::Integer)) { 2622 LineNumber = getTok().getIntVal(); 2623 if (LineNumber < 1) 2624 return TokError("line number less than one in '.loc' directive"); 2625 Lex(); 2626 } 2627 2628 int64_t ColumnPos = 0; 2629 if (getLexer().is(AsmToken::Integer)) { 2630 ColumnPos = getTok().getIntVal(); 2631 if (ColumnPos < 0) 2632 return TokError("column position less than zero in '.loc' directive"); 2633 Lex(); 2634 } 2635 2636 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 2637 unsigned Isa = 0; 2638 int64_t Discriminator = 0; 2639 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2640 for (;;) { 2641 if (getLexer().is(AsmToken::EndOfStatement)) 2642 break; 2643 2644 StringRef Name; 2645 SMLoc Loc = getTok().getLoc(); 2646 if (parseIdentifier(Name)) 2647 return TokError("unexpected token in '.loc' directive"); 2648 2649 if (Name == "basic_block") 2650 Flags |= DWARF2_FLAG_BASIC_BLOCK; 2651 else if (Name == "prologue_end") 2652 Flags |= DWARF2_FLAG_PROLOGUE_END; 2653 else if (Name == "epilogue_begin") 2654 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; 2655 else if (Name == "is_stmt") { 2656 Loc = getTok().getLoc(); 2657 const MCExpr *Value; 2658 if (parseExpression(Value)) 2659 return true; 2660 // The expression must be the constant 0 or 1. 2661 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2662 int Value = MCE->getValue(); 2663 if (Value == 0) 2664 Flags &= ~DWARF2_FLAG_IS_STMT; 2665 else if (Value == 1) 2666 Flags |= DWARF2_FLAG_IS_STMT; 2667 else 2668 return Error(Loc, "is_stmt value not 0 or 1"); 2669 } else { 2670 return Error(Loc, "is_stmt value not the constant value of 0 or 1"); 2671 } 2672 } else if (Name == "isa") { 2673 Loc = getTok().getLoc(); 2674 const MCExpr *Value; 2675 if (parseExpression(Value)) 2676 return true; 2677 // The expression must be a constant greater or equal to 0. 2678 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2679 int Value = MCE->getValue(); 2680 if (Value < 0) 2681 return Error(Loc, "isa number less than zero"); 2682 Isa = Value; 2683 } else { 2684 return Error(Loc, "isa number not a constant value"); 2685 } 2686 } else if (Name == "discriminator") { 2687 if (parseAbsoluteExpression(Discriminator)) 2688 return true; 2689 } else { 2690 return Error(Loc, "unknown sub-directive in '.loc' directive"); 2691 } 2692 2693 if (getLexer().is(AsmToken::EndOfStatement)) 2694 break; 2695 } 2696 } 2697 2698 getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags, 2699 Isa, Discriminator, StringRef()); 2700 2701 return false; 2702 } 2703 2704 /// ParseDirectiveStabs 2705 /// ::= .stabs string, number, number, number 2706 bool AsmParser::ParseDirectiveStabs() { 2707 return TokError("unsupported directive '.stabs'"); 2708 } 2709 2710 /// ParseDirectiveCFISections 2711 /// ::= .cfi_sections section [, section] 2712 bool AsmParser::ParseDirectiveCFISections() { 2713 StringRef Name; 2714 bool EH = false; 2715 bool Debug = false; 2716 2717 if (parseIdentifier(Name)) 2718 return TokError("Expected an identifier"); 2719 2720 if (Name == ".eh_frame") 2721 EH = true; 2722 else if (Name == ".debug_frame") 2723 Debug = true; 2724 2725 if (getLexer().is(AsmToken::Comma)) { 2726 Lex(); 2727 2728 if (parseIdentifier(Name)) 2729 return TokError("Expected an identifier"); 2730 2731 if (Name == ".eh_frame") 2732 EH = true; 2733 else if (Name == ".debug_frame") 2734 Debug = true; 2735 } 2736 2737 getStreamer().EmitCFISections(EH, Debug); 2738 return false; 2739 } 2740 2741 /// ParseDirectiveCFIStartProc 2742 /// ::= .cfi_startproc 2743 bool AsmParser::ParseDirectiveCFIStartProc() { 2744 getStreamer().EmitCFIStartProc(); 2745 return false; 2746 } 2747 2748 /// ParseDirectiveCFIEndProc 2749 /// ::= .cfi_endproc 2750 bool AsmParser::ParseDirectiveCFIEndProc() { 2751 getStreamer().EmitCFIEndProc(); 2752 return false; 2753 } 2754 2755 /// ParseRegisterOrRegisterNumber - parse register name or number. 2756 bool AsmParser::ParseRegisterOrRegisterNumber(int64_t &Register, 2757 SMLoc DirectiveLoc) { 2758 unsigned RegNo; 2759 2760 if (getLexer().isNot(AsmToken::Integer)) { 2761 if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) 2762 return true; 2763 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true); 2764 } else 2765 return parseAbsoluteExpression(Register); 2766 2767 return false; 2768 } 2769 2770 /// ParseDirectiveCFIDefCfa 2771 /// ::= .cfi_def_cfa register, offset 2772 bool AsmParser::ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { 2773 int64_t Register = 0; 2774 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2775 return true; 2776 2777 if (getLexer().isNot(AsmToken::Comma)) 2778 return TokError("unexpected token in directive"); 2779 Lex(); 2780 2781 int64_t Offset = 0; 2782 if (parseAbsoluteExpression(Offset)) 2783 return true; 2784 2785 getStreamer().EmitCFIDefCfa(Register, Offset); 2786 return false; 2787 } 2788 2789 /// ParseDirectiveCFIDefCfaOffset 2790 /// ::= .cfi_def_cfa_offset offset 2791 bool AsmParser::ParseDirectiveCFIDefCfaOffset() { 2792 int64_t Offset = 0; 2793 if (parseAbsoluteExpression(Offset)) 2794 return true; 2795 2796 getStreamer().EmitCFIDefCfaOffset(Offset); 2797 return false; 2798 } 2799 2800 /// ParseDirectiveCFIRegister 2801 /// ::= .cfi_register register, register 2802 bool AsmParser::ParseDirectiveCFIRegister(SMLoc DirectiveLoc) { 2803 int64_t Register1 = 0; 2804 if (ParseRegisterOrRegisterNumber(Register1, DirectiveLoc)) 2805 return true; 2806 2807 if (getLexer().isNot(AsmToken::Comma)) 2808 return TokError("unexpected token in directive"); 2809 Lex(); 2810 2811 int64_t Register2 = 0; 2812 if (ParseRegisterOrRegisterNumber(Register2, DirectiveLoc)) 2813 return true; 2814 2815 getStreamer().EmitCFIRegister(Register1, Register2); 2816 return false; 2817 } 2818 2819 /// ParseDirectiveCFIAdjustCfaOffset 2820 /// ::= .cfi_adjust_cfa_offset adjustment 2821 bool AsmParser::ParseDirectiveCFIAdjustCfaOffset() { 2822 int64_t Adjustment = 0; 2823 if (parseAbsoluteExpression(Adjustment)) 2824 return true; 2825 2826 getStreamer().EmitCFIAdjustCfaOffset(Adjustment); 2827 return false; 2828 } 2829 2830 /// ParseDirectiveCFIDefCfaRegister 2831 /// ::= .cfi_def_cfa_register register 2832 bool AsmParser::ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) { 2833 int64_t Register = 0; 2834 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2835 return true; 2836 2837 getStreamer().EmitCFIDefCfaRegister(Register); 2838 return false; 2839 } 2840 2841 /// ParseDirectiveCFIOffset 2842 /// ::= .cfi_offset register, offset 2843 bool AsmParser::ParseDirectiveCFIOffset(SMLoc DirectiveLoc) { 2844 int64_t Register = 0; 2845 int64_t Offset = 0; 2846 2847 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2848 return true; 2849 2850 if (getLexer().isNot(AsmToken::Comma)) 2851 return TokError("unexpected token in directive"); 2852 Lex(); 2853 2854 if (parseAbsoluteExpression(Offset)) 2855 return true; 2856 2857 getStreamer().EmitCFIOffset(Register, Offset); 2858 return false; 2859 } 2860 2861 /// ParseDirectiveCFIRelOffset 2862 /// ::= .cfi_rel_offset register, offset 2863 bool AsmParser::ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc) { 2864 int64_t Register = 0; 2865 2866 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2867 return true; 2868 2869 if (getLexer().isNot(AsmToken::Comma)) 2870 return TokError("unexpected token in directive"); 2871 Lex(); 2872 2873 int64_t Offset = 0; 2874 if (parseAbsoluteExpression(Offset)) 2875 return true; 2876 2877 getStreamer().EmitCFIRelOffset(Register, Offset); 2878 return false; 2879 } 2880 2881 static bool isValidEncoding(int64_t Encoding) { 2882 if (Encoding & ~0xff) 2883 return false; 2884 2885 if (Encoding == dwarf::DW_EH_PE_omit) 2886 return true; 2887 2888 const unsigned Format = Encoding & 0xf; 2889 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && 2890 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && 2891 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && 2892 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) 2893 return false; 2894 2895 const unsigned Application = Encoding & 0x70; 2896 if (Application != dwarf::DW_EH_PE_absptr && 2897 Application != dwarf::DW_EH_PE_pcrel) 2898 return false; 2899 2900 return true; 2901 } 2902 2903 /// ParseDirectiveCFIPersonalityOrLsda 2904 /// IsPersonality true for cfi_personality, false for cfi_lsda 2905 /// ::= .cfi_personality encoding, [symbol_name] 2906 /// ::= .cfi_lsda encoding, [symbol_name] 2907 bool AsmParser::ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { 2908 int64_t Encoding = 0; 2909 if (parseAbsoluteExpression(Encoding)) 2910 return true; 2911 if (Encoding == dwarf::DW_EH_PE_omit) 2912 return false; 2913 2914 if (!isValidEncoding(Encoding)) 2915 return TokError("unsupported encoding."); 2916 2917 if (getLexer().isNot(AsmToken::Comma)) 2918 return TokError("unexpected token in directive"); 2919 Lex(); 2920 2921 StringRef Name; 2922 if (parseIdentifier(Name)) 2923 return TokError("expected identifier in directive"); 2924 2925 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2926 2927 if (IsPersonality) 2928 getStreamer().EmitCFIPersonality(Sym, Encoding); 2929 else 2930 getStreamer().EmitCFILsda(Sym, Encoding); 2931 return false; 2932 } 2933 2934 /// ParseDirectiveCFIRememberState 2935 /// ::= .cfi_remember_state 2936 bool AsmParser::ParseDirectiveCFIRememberState() { 2937 getStreamer().EmitCFIRememberState(); 2938 return false; 2939 } 2940 2941 /// ParseDirectiveCFIRestoreState 2942 /// ::= .cfi_remember_state 2943 bool AsmParser::ParseDirectiveCFIRestoreState() { 2944 getStreamer().EmitCFIRestoreState(); 2945 return false; 2946 } 2947 2948 /// ParseDirectiveCFISameValue 2949 /// ::= .cfi_same_value register 2950 bool AsmParser::ParseDirectiveCFISameValue(SMLoc DirectiveLoc) { 2951 int64_t Register = 0; 2952 2953 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2954 return true; 2955 2956 getStreamer().EmitCFISameValue(Register); 2957 return false; 2958 } 2959 2960 /// ParseDirectiveCFIRestore 2961 /// ::= .cfi_restore register 2962 bool AsmParser::ParseDirectiveCFIRestore(SMLoc DirectiveLoc) { 2963 int64_t Register = 0; 2964 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2965 return true; 2966 2967 getStreamer().EmitCFIRestore(Register); 2968 return false; 2969 } 2970 2971 /// ParseDirectiveCFIEscape 2972 /// ::= .cfi_escape expression[,...] 2973 bool AsmParser::ParseDirectiveCFIEscape() { 2974 std::string Values; 2975 int64_t CurrValue; 2976 if (parseAbsoluteExpression(CurrValue)) 2977 return true; 2978 2979 Values.push_back((uint8_t)CurrValue); 2980 2981 while (getLexer().is(AsmToken::Comma)) { 2982 Lex(); 2983 2984 if (parseAbsoluteExpression(CurrValue)) 2985 return true; 2986 2987 Values.push_back((uint8_t)CurrValue); 2988 } 2989 2990 getStreamer().EmitCFIEscape(Values); 2991 return false; 2992 } 2993 2994 /// ParseDirectiveCFISignalFrame 2995 /// ::= .cfi_signal_frame 2996 bool AsmParser::ParseDirectiveCFISignalFrame() { 2997 if (getLexer().isNot(AsmToken::EndOfStatement)) 2998 return Error(getLexer().getLoc(), 2999 "unexpected token in '.cfi_signal_frame'"); 3000 3001 getStreamer().EmitCFISignalFrame(); 3002 return false; 3003 } 3004 3005 /// ParseDirectiveCFIUndefined 3006 /// ::= .cfi_undefined register 3007 bool AsmParser::ParseDirectiveCFIUndefined(SMLoc DirectiveLoc) { 3008 int64_t Register = 0; 3009 3010 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3011 return true; 3012 3013 getStreamer().EmitCFIUndefined(Register); 3014 return false; 3015 } 3016 3017 /// ParseDirectiveMacrosOnOff 3018 /// ::= .macros_on 3019 /// ::= .macros_off 3020 bool AsmParser::ParseDirectiveMacrosOnOff(StringRef Directive) { 3021 if (getLexer().isNot(AsmToken::EndOfStatement)) 3022 return Error(getLexer().getLoc(), 3023 "unexpected token in '" + Directive + "' directive"); 3024 3025 SetMacrosEnabled(Directive == ".macros_on"); 3026 return false; 3027 } 3028 3029 /// ParseDirectiveMacro 3030 /// ::= .macro name [parameters] 3031 bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) { 3032 StringRef Name; 3033 if (parseIdentifier(Name)) 3034 return TokError("expected identifier in '.macro' directive"); 3035 3036 MCAsmMacroParameters Parameters; 3037 // Argument delimiter is initially unknown. It will be set by 3038 // ParseMacroArgument() 3039 AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof; 3040 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3041 for (;;) { 3042 MCAsmMacroParameter Parameter; 3043 if (parseIdentifier(Parameter.first)) 3044 return TokError("expected identifier in '.macro' directive"); 3045 3046 if (getLexer().is(AsmToken::Equal)) { 3047 Lex(); 3048 if (ParseMacroArgument(Parameter.second, ArgumentDelimiter)) 3049 return true; 3050 } 3051 3052 Parameters.push_back(Parameter); 3053 3054 if (getLexer().is(AsmToken::Comma)) 3055 Lex(); 3056 else if (getLexer().is(AsmToken::EndOfStatement)) 3057 break; 3058 } 3059 } 3060 3061 // Eat the end of statement. 3062 Lex(); 3063 3064 AsmToken EndToken, StartToken = getTok(); 3065 3066 // Lex the macro definition. 3067 for (;;) { 3068 // Check whether we have reached the end of the file. 3069 if (getLexer().is(AsmToken::Eof)) 3070 return Error(DirectiveLoc, "no matching '.endmacro' in definition"); 3071 3072 // Otherwise, check whether we have reach the .endmacro. 3073 if (getLexer().is(AsmToken::Identifier) && 3074 (getTok().getIdentifier() == ".endm" || 3075 getTok().getIdentifier() == ".endmacro")) { 3076 EndToken = getTok(); 3077 Lex(); 3078 if (getLexer().isNot(AsmToken::EndOfStatement)) 3079 return TokError("unexpected token in '" + EndToken.getIdentifier() + 3080 "' directive"); 3081 break; 3082 } 3083 3084 // Otherwise, scan til the end of the statement. 3085 eatToEndOfStatement(); 3086 } 3087 3088 if (LookupMacro(Name)) { 3089 return Error(DirectiveLoc, "macro '" + Name + "' is already defined"); 3090 } 3091 3092 const char *BodyStart = StartToken.getLoc().getPointer(); 3093 const char *BodyEnd = EndToken.getLoc().getPointer(); 3094 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 3095 CheckForBadMacro(DirectiveLoc, Name, Body, Parameters); 3096 DefineMacro(Name, MCAsmMacro(Name, Body, Parameters)); 3097 return false; 3098 } 3099 3100 /// CheckForBadMacro 3101 /// 3102 /// With the support added for named parameters there may be code out there that 3103 /// is transitioning from positional parameters. In versions of gas that did 3104 /// not support named parameters they would be ignored on the macro defintion. 3105 /// But to support both styles of parameters this is not possible so if a macro 3106 /// defintion has named parameters but does not use them and has what appears 3107 /// to be positional parameters, strings like $1, $2, ... and $n, then issue a 3108 /// warning that the positional parameter found in body which have no effect. 3109 /// Hoping the developer will either remove the named parameters from the macro 3110 /// definiton so the positional parameters get used if that was what was 3111 /// intended or change the macro to use the named parameters. It is possible 3112 /// this warning will trigger when the none of the named parameters are used 3113 /// and the strings like $1 are infact to simply to be passed trough unchanged. 3114 void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, 3115 StringRef Body, 3116 MCAsmMacroParameters Parameters) { 3117 // If this macro is not defined with named parameters the warning we are 3118 // checking for here doesn't apply. 3119 unsigned NParameters = Parameters.size(); 3120 if (NParameters == 0) 3121 return; 3122 3123 bool NamedParametersFound = false; 3124 bool PositionalParametersFound = false; 3125 3126 // Look at the body of the macro for use of both the named parameters and what 3127 // are likely to be positional parameters. This is what expandMacro() is 3128 // doing when it finds the parameters in the body. 3129 while (!Body.empty()) { 3130 // Scan for the next possible parameter. 3131 std::size_t End = Body.size(), Pos = 0; 3132 for (; Pos != End; ++Pos) { 3133 // Check for a substitution or escape. 3134 // This macro is defined with parameters, look for \foo, \bar, etc. 3135 if (Body[Pos] == '\\' && Pos + 1 != End) 3136 break; 3137 3138 // This macro should have parameters, but look for $0, $1, ..., $n too. 3139 if (Body[Pos] != '$' || Pos + 1 == End) 3140 continue; 3141 char Next = Body[Pos + 1]; 3142 if (Next == '$' || Next == 'n' || 3143 isdigit(static_cast<unsigned char>(Next))) 3144 break; 3145 } 3146 3147 // Check if we reached the end. 3148 if (Pos == End) 3149 break; 3150 3151 if (Body[Pos] == '$') { 3152 switch (Body[Pos+1]) { 3153 // $$ => $ 3154 case '$': 3155 break; 3156 3157 // $n => number of arguments 3158 case 'n': 3159 PositionalParametersFound = true; 3160 break; 3161 3162 // $[0-9] => argument 3163 default: { 3164 PositionalParametersFound = true; 3165 break; 3166 } 3167 } 3168 Pos += 2; 3169 } else { 3170 unsigned I = Pos + 1; 3171 while (isIdentifierChar(Body[I]) && I + 1 != End) 3172 ++I; 3173 3174 const char *Begin = Body.data() + Pos +1; 3175 StringRef Argument(Begin, I - (Pos +1)); 3176 unsigned Index = 0; 3177 for (; Index < NParameters; ++Index) 3178 if (Parameters[Index].first == Argument) 3179 break; 3180 3181 if (Index == NParameters) { 3182 if (Body[Pos+1] == '(' && Body[Pos+2] == ')') 3183 Pos += 3; 3184 else { 3185 Pos = I; 3186 } 3187 } else { 3188 NamedParametersFound = true; 3189 Pos += 1 + Argument.size(); 3190 } 3191 } 3192 // Update the scan point. 3193 Body = Body.substr(Pos); 3194 } 3195 3196 if (!NamedParametersFound && PositionalParametersFound) 3197 Warning(DirectiveLoc, "macro defined with named parameters which are not " 3198 "used in macro body, possible positional parameter " 3199 "found in body which will have no effect"); 3200 } 3201 3202 /// ParseDirectiveEndMacro 3203 /// ::= .endm 3204 /// ::= .endmacro 3205 bool AsmParser::ParseDirectiveEndMacro(StringRef Directive) { 3206 if (getLexer().isNot(AsmToken::EndOfStatement)) 3207 return TokError("unexpected token in '" + Directive + "' directive"); 3208 3209 // If we are inside a macro instantiation, terminate the current 3210 // instantiation. 3211 if (InsideMacroInstantiation()) { 3212 HandleMacroExit(); 3213 return false; 3214 } 3215 3216 // Otherwise, this .endmacro is a stray entry in the file; well formed 3217 // .endmacro directives are handled during the macro definition parsing. 3218 return TokError("unexpected '" + Directive + "' in file, " 3219 "no current macro definition"); 3220 } 3221 3222 /// ParseDirectivePurgeMacro 3223 /// ::= .purgem 3224 bool AsmParser::ParseDirectivePurgeMacro(SMLoc DirectiveLoc) { 3225 StringRef Name; 3226 if (parseIdentifier(Name)) 3227 return TokError("expected identifier in '.purgem' directive"); 3228 3229 if (getLexer().isNot(AsmToken::EndOfStatement)) 3230 return TokError("unexpected token in '.purgem' directive"); 3231 3232 if (!LookupMacro(Name)) 3233 return Error(DirectiveLoc, "macro '" + Name + "' is not defined"); 3234 3235 UndefineMacro(Name); 3236 return false; 3237 } 3238 3239 /// ParseDirectiveBundleAlignMode 3240 /// ::= {.bundle_align_mode} expression 3241 bool AsmParser::ParseDirectiveBundleAlignMode() { 3242 checkForValidSection(); 3243 3244 // Expect a single argument: an expression that evaluates to a constant 3245 // in the inclusive range 0-30. 3246 SMLoc ExprLoc = getLexer().getLoc(); 3247 int64_t AlignSizePow2; 3248 if (parseAbsoluteExpression(AlignSizePow2)) 3249 return true; 3250 else if (getLexer().isNot(AsmToken::EndOfStatement)) 3251 return TokError("unexpected token after expression in" 3252 " '.bundle_align_mode' directive"); 3253 else if (AlignSizePow2 < 0 || AlignSizePow2 > 30) 3254 return Error(ExprLoc, 3255 "invalid bundle alignment size (expected between 0 and 30)"); 3256 3257 Lex(); 3258 3259 // Because of AlignSizePow2's verified range we can safely truncate it to 3260 // unsigned. 3261 getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2)); 3262 return false; 3263 } 3264 3265 /// ParseDirectiveBundleLock 3266 /// ::= {.bundle_lock} [align_to_end] 3267 bool AsmParser::ParseDirectiveBundleLock() { 3268 checkForValidSection(); 3269 bool AlignToEnd = false; 3270 3271 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3272 StringRef Option; 3273 SMLoc Loc = getTok().getLoc(); 3274 const char *kInvalidOptionError = 3275 "invalid option for '.bundle_lock' directive"; 3276 3277 if (parseIdentifier(Option)) 3278 return Error(Loc, kInvalidOptionError); 3279 3280 if (Option != "align_to_end") 3281 return Error(Loc, kInvalidOptionError); 3282 else if (getLexer().isNot(AsmToken::EndOfStatement)) 3283 return Error(Loc, 3284 "unexpected token after '.bundle_lock' directive option"); 3285 AlignToEnd = true; 3286 } 3287 3288 Lex(); 3289 3290 getStreamer().EmitBundleLock(AlignToEnd); 3291 return false; 3292 } 3293 3294 /// ParseDirectiveBundleLock 3295 /// ::= {.bundle_lock} 3296 bool AsmParser::ParseDirectiveBundleUnlock() { 3297 checkForValidSection(); 3298 3299 if (getLexer().isNot(AsmToken::EndOfStatement)) 3300 return TokError("unexpected token in '.bundle_unlock' directive"); 3301 Lex(); 3302 3303 getStreamer().EmitBundleUnlock(); 3304 return false; 3305 } 3306 3307 /// ParseDirectiveSpace 3308 /// ::= (.skip | .space) expression [ , expression ] 3309 bool AsmParser::ParseDirectiveSpace(StringRef IDVal) { 3310 checkForValidSection(); 3311 3312 int64_t NumBytes; 3313 if (parseAbsoluteExpression(NumBytes)) 3314 return true; 3315 3316 int64_t FillExpr = 0; 3317 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3318 if (getLexer().isNot(AsmToken::Comma)) 3319 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 3320 Lex(); 3321 3322 if (parseAbsoluteExpression(FillExpr)) 3323 return true; 3324 3325 if (getLexer().isNot(AsmToken::EndOfStatement)) 3326 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 3327 } 3328 3329 Lex(); 3330 3331 if (NumBytes <= 0) 3332 return TokError("invalid number of bytes in '" + 3333 Twine(IDVal) + "' directive"); 3334 3335 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. 3336 getStreamer().EmitFill(NumBytes, FillExpr); 3337 3338 return false; 3339 } 3340 3341 /// ParseDirectiveLEB128 3342 /// ::= (.sleb128 | .uleb128) expression 3343 bool AsmParser::ParseDirectiveLEB128(bool Signed) { 3344 checkForValidSection(); 3345 const MCExpr *Value; 3346 3347 if (parseExpression(Value)) 3348 return true; 3349 3350 if (getLexer().isNot(AsmToken::EndOfStatement)) 3351 return TokError("unexpected token in directive"); 3352 3353 if (Signed) 3354 getStreamer().EmitSLEB128Value(Value); 3355 else 3356 getStreamer().EmitULEB128Value(Value); 3357 3358 return false; 3359 } 3360 3361 /// ParseDirectiveSymbolAttribute 3362 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 3363 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 3364 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3365 for (;;) { 3366 StringRef Name; 3367 SMLoc Loc = getTok().getLoc(); 3368 3369 if (parseIdentifier(Name)) 3370 return Error(Loc, "expected identifier in directive"); 3371 3372 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3373 3374 // Assembler local symbols don't make any sense here. Complain loudly. 3375 if (Sym->isTemporary()) 3376 return Error(Loc, "non-local symbol required in directive"); 3377 3378 getStreamer().EmitSymbolAttribute(Sym, Attr); 3379 3380 if (getLexer().is(AsmToken::EndOfStatement)) 3381 break; 3382 3383 if (getLexer().isNot(AsmToken::Comma)) 3384 return TokError("unexpected token in directive"); 3385 Lex(); 3386 } 3387 } 3388 3389 Lex(); 3390 return false; 3391 } 3392 3393 /// ParseDirectiveComm 3394 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 3395 bool AsmParser::ParseDirectiveComm(bool IsLocal) { 3396 checkForValidSection(); 3397 3398 SMLoc IDLoc = getLexer().getLoc(); 3399 StringRef Name; 3400 if (parseIdentifier(Name)) 3401 return TokError("expected identifier in directive"); 3402 3403 // Handle the identifier as the key symbol. 3404 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3405 3406 if (getLexer().isNot(AsmToken::Comma)) 3407 return TokError("unexpected token in directive"); 3408 Lex(); 3409 3410 int64_t Size; 3411 SMLoc SizeLoc = getLexer().getLoc(); 3412 if (parseAbsoluteExpression(Size)) 3413 return true; 3414 3415 int64_t Pow2Alignment = 0; 3416 SMLoc Pow2AlignmentLoc; 3417 if (getLexer().is(AsmToken::Comma)) { 3418 Lex(); 3419 Pow2AlignmentLoc = getLexer().getLoc(); 3420 if (parseAbsoluteExpression(Pow2Alignment)) 3421 return true; 3422 3423 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); 3424 if (IsLocal && LCOMM == LCOMM::NoAlignment) 3425 return Error(Pow2AlignmentLoc, "alignment not supported on this target"); 3426 3427 // If this target takes alignments in bytes (not log) validate and convert. 3428 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || 3429 (IsLocal && LCOMM == LCOMM::ByteAlignment)) { 3430 if (!isPowerOf2_64(Pow2Alignment)) 3431 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 3432 Pow2Alignment = Log2_64(Pow2Alignment); 3433 } 3434 } 3435 3436 if (getLexer().isNot(AsmToken::EndOfStatement)) 3437 return TokError("unexpected token in '.comm' or '.lcomm' directive"); 3438 3439 Lex(); 3440 3441 // NOTE: a size of zero for a .comm should create a undefined symbol 3442 // but a size of .lcomm creates a bss symbol of size zero. 3443 if (Size < 0) 3444 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 3445 "be less than zero"); 3446 3447 // NOTE: The alignment in the directive is a power of 2 value, the assembler 3448 // may internally end up wanting an alignment in bytes. 3449 // FIXME: Diagnose overflow. 3450 if (Pow2Alignment < 0) 3451 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 3452 "alignment, can't be less than zero"); 3453 3454 if (!Sym->isUndefined()) 3455 return Error(IDLoc, "invalid symbol redefinition"); 3456 3457 // Create the Symbol as a common or local common with Size and Pow2Alignment 3458 if (IsLocal) { 3459 getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); 3460 return false; 3461 } 3462 3463 getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 3464 return false; 3465 } 3466 3467 /// ParseDirectiveAbort 3468 /// ::= .abort [... message ...] 3469 bool AsmParser::ParseDirectiveAbort() { 3470 // FIXME: Use loc from directive. 3471 SMLoc Loc = getLexer().getLoc(); 3472 3473 StringRef Str = parseStringToEndOfStatement(); 3474 if (getLexer().isNot(AsmToken::EndOfStatement)) 3475 return TokError("unexpected token in '.abort' directive"); 3476 3477 Lex(); 3478 3479 if (Str.empty()) 3480 Error(Loc, ".abort detected. Assembly stopping."); 3481 else 3482 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping."); 3483 // FIXME: Actually abort assembly here. 3484 3485 return false; 3486 } 3487 3488 /// ParseDirectiveInclude 3489 /// ::= .include "filename" 3490 bool AsmParser::ParseDirectiveInclude() { 3491 if (getLexer().isNot(AsmToken::String)) 3492 return TokError("expected string in '.include' directive"); 3493 3494 std::string Filename = getTok().getString(); 3495 SMLoc IncludeLoc = getLexer().getLoc(); 3496 Lex(); 3497 3498 if (getLexer().isNot(AsmToken::EndOfStatement)) 3499 return TokError("unexpected token in '.include' directive"); 3500 3501 // Strip the quotes. 3502 Filename = Filename.substr(1, Filename.size()-2); 3503 3504 // Attempt to switch the lexer to the included file before consuming the end 3505 // of statement to avoid losing it when we switch. 3506 if (EnterIncludeFile(Filename)) { 3507 Error(IncludeLoc, "Could not find include file '" + Filename + "'"); 3508 return true; 3509 } 3510 3511 return false; 3512 } 3513 3514 /// ParseDirectiveIncbin 3515 /// ::= .incbin "filename" 3516 bool AsmParser::ParseDirectiveIncbin() { 3517 if (getLexer().isNot(AsmToken::String)) 3518 return TokError("expected string in '.incbin' directive"); 3519 3520 std::string Filename = getTok().getString(); 3521 SMLoc IncbinLoc = getLexer().getLoc(); 3522 Lex(); 3523 3524 if (getLexer().isNot(AsmToken::EndOfStatement)) 3525 return TokError("unexpected token in '.incbin' directive"); 3526 3527 // Strip the quotes. 3528 Filename = Filename.substr(1, Filename.size()-2); 3529 3530 // Attempt to process the included file. 3531 if (ProcessIncbinFile(Filename)) { 3532 Error(IncbinLoc, "Could not find incbin file '" + Filename + "'"); 3533 return true; 3534 } 3535 3536 return false; 3537 } 3538 3539 /// ParseDirectiveIf 3540 /// ::= .if expression 3541 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { 3542 TheCondStack.push_back(TheCondState); 3543 TheCondState.TheCond = AsmCond::IfCond; 3544 if (TheCondState.Ignore) { 3545 eatToEndOfStatement(); 3546 } else { 3547 int64_t ExprValue; 3548 if (parseAbsoluteExpression(ExprValue)) 3549 return true; 3550 3551 if (getLexer().isNot(AsmToken::EndOfStatement)) 3552 return TokError("unexpected token in '.if' directive"); 3553 3554 Lex(); 3555 3556 TheCondState.CondMet = ExprValue; 3557 TheCondState.Ignore = !TheCondState.CondMet; 3558 } 3559 3560 return false; 3561 } 3562 3563 /// ParseDirectiveIfb 3564 /// ::= .ifb string 3565 bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 3566 TheCondStack.push_back(TheCondState); 3567 TheCondState.TheCond = AsmCond::IfCond; 3568 3569 if (TheCondState.Ignore) { 3570 eatToEndOfStatement(); 3571 } else { 3572 StringRef Str = parseStringToEndOfStatement(); 3573 3574 if (getLexer().isNot(AsmToken::EndOfStatement)) 3575 return TokError("unexpected token in '.ifb' directive"); 3576 3577 Lex(); 3578 3579 TheCondState.CondMet = ExpectBlank == Str.empty(); 3580 TheCondState.Ignore = !TheCondState.CondMet; 3581 } 3582 3583 return false; 3584 } 3585 3586 /// ParseDirectiveIfc 3587 /// ::= .ifc string1, string2 3588 bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { 3589 TheCondStack.push_back(TheCondState); 3590 TheCondState.TheCond = AsmCond::IfCond; 3591 3592 if (TheCondState.Ignore) { 3593 eatToEndOfStatement(); 3594 } else { 3595 StringRef Str1 = ParseStringToComma(); 3596 3597 if (getLexer().isNot(AsmToken::Comma)) 3598 return TokError("unexpected token in '.ifc' directive"); 3599 3600 Lex(); 3601 3602 StringRef Str2 = parseStringToEndOfStatement(); 3603 3604 if (getLexer().isNot(AsmToken::EndOfStatement)) 3605 return TokError("unexpected token in '.ifc' directive"); 3606 3607 Lex(); 3608 3609 TheCondState.CondMet = ExpectEqual == (Str1 == Str2); 3610 TheCondState.Ignore = !TheCondState.CondMet; 3611 } 3612 3613 return false; 3614 } 3615 3616 /// ParseDirectiveIfdef 3617 /// ::= .ifdef symbol 3618 bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { 3619 StringRef Name; 3620 TheCondStack.push_back(TheCondState); 3621 TheCondState.TheCond = AsmCond::IfCond; 3622 3623 if (TheCondState.Ignore) { 3624 eatToEndOfStatement(); 3625 } else { 3626 if (parseIdentifier(Name)) 3627 return TokError("expected identifier after '.ifdef'"); 3628 3629 Lex(); 3630 3631 MCSymbol *Sym = getContext().LookupSymbol(Name); 3632 3633 if (expect_defined) 3634 TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined()); 3635 else 3636 TheCondState.CondMet = (Sym == NULL || Sym->isUndefined()); 3637 TheCondState.Ignore = !TheCondState.CondMet; 3638 } 3639 3640 return false; 3641 } 3642 3643 /// ParseDirectiveElseIf 3644 /// ::= .elseif expression 3645 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { 3646 if (TheCondState.TheCond != AsmCond::IfCond && 3647 TheCondState.TheCond != AsmCond::ElseIfCond) 3648 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " 3649 " an .elseif"); 3650 TheCondState.TheCond = AsmCond::ElseIfCond; 3651 3652 bool LastIgnoreState = false; 3653 if (!TheCondStack.empty()) 3654 LastIgnoreState = TheCondStack.back().Ignore; 3655 if (LastIgnoreState || TheCondState.CondMet) { 3656 TheCondState.Ignore = true; 3657 eatToEndOfStatement(); 3658 } else { 3659 int64_t ExprValue; 3660 if (parseAbsoluteExpression(ExprValue)) 3661 return true; 3662 3663 if (getLexer().isNot(AsmToken::EndOfStatement)) 3664 return TokError("unexpected token in '.elseif' directive"); 3665 3666 Lex(); 3667 TheCondState.CondMet = ExprValue; 3668 TheCondState.Ignore = !TheCondState.CondMet; 3669 } 3670 3671 return false; 3672 } 3673 3674 /// ParseDirectiveElse 3675 /// ::= .else 3676 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) { 3677 if (getLexer().isNot(AsmToken::EndOfStatement)) 3678 return TokError("unexpected token in '.else' directive"); 3679 3680 Lex(); 3681 3682 if (TheCondState.TheCond != AsmCond::IfCond && 3683 TheCondState.TheCond != AsmCond::ElseIfCond) 3684 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an " 3685 ".elseif"); 3686 TheCondState.TheCond = AsmCond::ElseCond; 3687 bool LastIgnoreState = false; 3688 if (!TheCondStack.empty()) 3689 LastIgnoreState = TheCondStack.back().Ignore; 3690 if (LastIgnoreState || TheCondState.CondMet) 3691 TheCondState.Ignore = true; 3692 else 3693 TheCondState.Ignore = false; 3694 3695 return false; 3696 } 3697 3698 /// ParseDirectiveEndIf 3699 /// ::= .endif 3700 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { 3701 if (getLexer().isNot(AsmToken::EndOfStatement)) 3702 return TokError("unexpected token in '.endif' directive"); 3703 3704 Lex(); 3705 3706 if ((TheCondState.TheCond == AsmCond::NoCond) || 3707 TheCondStack.empty()) 3708 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " 3709 ".else"); 3710 if (!TheCondStack.empty()) { 3711 TheCondState = TheCondStack.back(); 3712 TheCondStack.pop_back(); 3713 } 3714 3715 return false; 3716 } 3717 3718 void AsmParser::initializeDirectiveKindMap() { 3719 DirectiveKindMap[".set"] = DK_SET; 3720 DirectiveKindMap[".equ"] = DK_EQU; 3721 DirectiveKindMap[".equiv"] = DK_EQUIV; 3722 DirectiveKindMap[".ascii"] = DK_ASCII; 3723 DirectiveKindMap[".asciz"] = DK_ASCIZ; 3724 DirectiveKindMap[".string"] = DK_STRING; 3725 DirectiveKindMap[".byte"] = DK_BYTE; 3726 DirectiveKindMap[".short"] = DK_SHORT; 3727 DirectiveKindMap[".value"] = DK_VALUE; 3728 DirectiveKindMap[".2byte"] = DK_2BYTE; 3729 DirectiveKindMap[".long"] = DK_LONG; 3730 DirectiveKindMap[".int"] = DK_INT; 3731 DirectiveKindMap[".4byte"] = DK_4BYTE; 3732 DirectiveKindMap[".quad"] = DK_QUAD; 3733 DirectiveKindMap[".8byte"] = DK_8BYTE; 3734 DirectiveKindMap[".single"] = DK_SINGLE; 3735 DirectiveKindMap[".float"] = DK_FLOAT; 3736 DirectiveKindMap[".double"] = DK_DOUBLE; 3737 DirectiveKindMap[".align"] = DK_ALIGN; 3738 DirectiveKindMap[".align32"] = DK_ALIGN32; 3739 DirectiveKindMap[".balign"] = DK_BALIGN; 3740 DirectiveKindMap[".balignw"] = DK_BALIGNW; 3741 DirectiveKindMap[".balignl"] = DK_BALIGNL; 3742 DirectiveKindMap[".p2align"] = DK_P2ALIGN; 3743 DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW; 3744 DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL; 3745 DirectiveKindMap[".org"] = DK_ORG; 3746 DirectiveKindMap[".fill"] = DK_FILL; 3747 DirectiveKindMap[".zero"] = DK_ZERO; 3748 DirectiveKindMap[".extern"] = DK_EXTERN; 3749 DirectiveKindMap[".globl"] = DK_GLOBL; 3750 DirectiveKindMap[".global"] = DK_GLOBAL; 3751 DirectiveKindMap[".indirect_symbol"] = DK_INDIRECT_SYMBOL; 3752 DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE; 3753 DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP; 3754 DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER; 3755 DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN; 3756 DirectiveKindMap[".reference"] = DK_REFERENCE; 3757 DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION; 3758 DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE; 3759 DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN; 3760 DirectiveKindMap[".comm"] = DK_COMM; 3761 DirectiveKindMap[".common"] = DK_COMMON; 3762 DirectiveKindMap[".lcomm"] = DK_LCOMM; 3763 DirectiveKindMap[".abort"] = DK_ABORT; 3764 DirectiveKindMap[".include"] = DK_INCLUDE; 3765 DirectiveKindMap[".incbin"] = DK_INCBIN; 3766 DirectiveKindMap[".code16"] = DK_CODE16; 3767 DirectiveKindMap[".code16gcc"] = DK_CODE16GCC; 3768 DirectiveKindMap[".rept"] = DK_REPT; 3769 DirectiveKindMap[".irp"] = DK_IRP; 3770 DirectiveKindMap[".irpc"] = DK_IRPC; 3771 DirectiveKindMap[".endr"] = DK_ENDR; 3772 DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE; 3773 DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK; 3774 DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK; 3775 DirectiveKindMap[".if"] = DK_IF; 3776 DirectiveKindMap[".ifb"] = DK_IFB; 3777 DirectiveKindMap[".ifnb"] = DK_IFNB; 3778 DirectiveKindMap[".ifc"] = DK_IFC; 3779 DirectiveKindMap[".ifnc"] = DK_IFNC; 3780 DirectiveKindMap[".ifdef"] = DK_IFDEF; 3781 DirectiveKindMap[".ifndef"] = DK_IFNDEF; 3782 DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF; 3783 DirectiveKindMap[".elseif"] = DK_ELSEIF; 3784 DirectiveKindMap[".else"] = DK_ELSE; 3785 DirectiveKindMap[".endif"] = DK_ENDIF; 3786 DirectiveKindMap[".skip"] = DK_SKIP; 3787 DirectiveKindMap[".space"] = DK_SPACE; 3788 DirectiveKindMap[".file"] = DK_FILE; 3789 DirectiveKindMap[".line"] = DK_LINE; 3790 DirectiveKindMap[".loc"] = DK_LOC; 3791 DirectiveKindMap[".stabs"] = DK_STABS; 3792 DirectiveKindMap[".sleb128"] = DK_SLEB128; 3793 DirectiveKindMap[".uleb128"] = DK_ULEB128; 3794 DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS; 3795 DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC; 3796 DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC; 3797 DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA; 3798 DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET; 3799 DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET; 3800 DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER; 3801 DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET; 3802 DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET; 3803 DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY; 3804 DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA; 3805 DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE; 3806 DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE; 3807 DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE; 3808 DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE; 3809 DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE; 3810 DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME; 3811 DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED; 3812 DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER; 3813 DirectiveKindMap[".macros_on"] = DK_MACROS_ON; 3814 DirectiveKindMap[".macros_off"] = DK_MACROS_OFF; 3815 DirectiveKindMap[".macro"] = DK_MACRO; 3816 DirectiveKindMap[".endm"] = DK_ENDM; 3817 DirectiveKindMap[".endmacro"] = DK_ENDMACRO; 3818 DirectiveKindMap[".purgem"] = DK_PURGEM; 3819 } 3820 3821 3822 MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) { 3823 AsmToken EndToken, StartToken = getTok(); 3824 3825 unsigned NestLevel = 0; 3826 for (;;) { 3827 // Check whether we have reached the end of the file. 3828 if (getLexer().is(AsmToken::Eof)) { 3829 Error(DirectiveLoc, "no matching '.endr' in definition"); 3830 return 0; 3831 } 3832 3833 if (Lexer.is(AsmToken::Identifier) && 3834 (getTok().getIdentifier() == ".rept")) { 3835 ++NestLevel; 3836 } 3837 3838 // Otherwise, check whether we have reached the .endr. 3839 if (Lexer.is(AsmToken::Identifier) && 3840 getTok().getIdentifier() == ".endr") { 3841 if (NestLevel == 0) { 3842 EndToken = getTok(); 3843 Lex(); 3844 if (Lexer.isNot(AsmToken::EndOfStatement)) { 3845 TokError("unexpected token in '.endr' directive"); 3846 return 0; 3847 } 3848 break; 3849 } 3850 --NestLevel; 3851 } 3852 3853 // Otherwise, scan till the end of the statement. 3854 eatToEndOfStatement(); 3855 } 3856 3857 const char *BodyStart = StartToken.getLoc().getPointer(); 3858 const char *BodyEnd = EndToken.getLoc().getPointer(); 3859 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 3860 3861 // We Are Anonymous. 3862 StringRef Name; 3863 MCAsmMacroParameters Parameters; 3864 MacroLikeBodies.push_back(MCAsmMacro(Name, Body, Parameters)); 3865 return &MacroLikeBodies.back(); 3866 } 3867 3868 void AsmParser::InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 3869 raw_svector_ostream &OS) { 3870 OS << ".endr\n"; 3871 3872 MemoryBuffer *Instantiation = 3873 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 3874 3875 // Create the macro instantiation object and add to the current macro 3876 // instantiation stack. 3877 MacroInstantiation *MI = new MacroInstantiation(M, DirectiveLoc, 3878 CurBuffer, 3879 getTok().getLoc(), 3880 Instantiation); 3881 ActiveMacros.push_back(MI); 3882 3883 // Jump to the macro instantiation and prime the lexer. 3884 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 3885 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 3886 Lex(); 3887 } 3888 3889 bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) { 3890 int64_t Count; 3891 if (parseAbsoluteExpression(Count)) 3892 return TokError("unexpected token in '.rept' directive"); 3893 3894 if (Count < 0) 3895 return TokError("Count is negative"); 3896 3897 if (Lexer.isNot(AsmToken::EndOfStatement)) 3898 return TokError("unexpected token in '.rept' directive"); 3899 3900 // Eat the end of statement. 3901 Lex(); 3902 3903 // Lex the rept definition. 3904 MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc); 3905 if (!M) 3906 return true; 3907 3908 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3909 // to hold the macro body with substitutions. 3910 SmallString<256> Buf; 3911 MCAsmMacroParameters Parameters; 3912 MCAsmMacroArguments A; 3913 raw_svector_ostream OS(Buf); 3914 while (Count--) { 3915 if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc())) 3916 return true; 3917 } 3918 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 3919 3920 return false; 3921 } 3922 3923 /// ParseDirectiveIrp 3924 /// ::= .irp symbol,values 3925 bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { 3926 MCAsmMacroParameters Parameters; 3927 MCAsmMacroParameter Parameter; 3928 3929 if (parseIdentifier(Parameter.first)) 3930 return TokError("expected identifier in '.irp' directive"); 3931 3932 Parameters.push_back(Parameter); 3933 3934 if (Lexer.isNot(AsmToken::Comma)) 3935 return TokError("expected comma in '.irp' directive"); 3936 3937 Lex(); 3938 3939 MCAsmMacroArguments A; 3940 if (ParseMacroArguments(0, A)) 3941 return true; 3942 3943 // Eat the end of statement. 3944 Lex(); 3945 3946 // Lex the irp definition. 3947 MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc); 3948 if (!M) 3949 return true; 3950 3951 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3952 // to hold the macro body with substitutions. 3953 SmallString<256> Buf; 3954 raw_svector_ostream OS(Buf); 3955 3956 for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { 3957 MCAsmMacroArguments Args; 3958 Args.push_back(*i); 3959 3960 if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) 3961 return true; 3962 } 3963 3964 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 3965 3966 return false; 3967 } 3968 3969 /// ParseDirectiveIrpc 3970 /// ::= .irpc symbol,values 3971 bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { 3972 MCAsmMacroParameters Parameters; 3973 MCAsmMacroParameter Parameter; 3974 3975 if (parseIdentifier(Parameter.first)) 3976 return TokError("expected identifier in '.irpc' directive"); 3977 3978 Parameters.push_back(Parameter); 3979 3980 if (Lexer.isNot(AsmToken::Comma)) 3981 return TokError("expected comma in '.irpc' directive"); 3982 3983 Lex(); 3984 3985 MCAsmMacroArguments A; 3986 if (ParseMacroArguments(0, A)) 3987 return true; 3988 3989 if (A.size() != 1 || A.front().size() != 1) 3990 return TokError("unexpected token in '.irpc' directive"); 3991 3992 // Eat the end of statement. 3993 Lex(); 3994 3995 // Lex the irpc definition. 3996 MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc); 3997 if (!M) 3998 return true; 3999 4000 // Macro instantiation is lexical, unfortunately. We construct a new buffer 4001 // to hold the macro body with substitutions. 4002 SmallString<256> Buf; 4003 raw_svector_ostream OS(Buf); 4004 4005 StringRef Values = A.front().front().getString(); 4006 std::size_t I, End = Values.size(); 4007 for (I = 0; I < End; ++I) { 4008 MCAsmMacroArgument Arg; 4009 Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1))); 4010 4011 MCAsmMacroArguments Args; 4012 Args.push_back(Arg); 4013 4014 if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) 4015 return true; 4016 } 4017 4018 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 4019 4020 return false; 4021 } 4022 4023 bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) { 4024 if (ActiveMacros.empty()) 4025 return TokError("unmatched '.endr' directive"); 4026 4027 // The only .repl that should get here are the ones created by 4028 // InstantiateMacroLikeBody. 4029 assert(getLexer().is(AsmToken::EndOfStatement)); 4030 4031 HandleMacroExit(); 4032 return false; 4033 } 4034 4035 bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, 4036 size_t Len) { 4037 const MCExpr *Value; 4038 SMLoc ExprLoc = getLexer().getLoc(); 4039 if (parseExpression(Value)) 4040 return true; 4041 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 4042 if (!MCE) 4043 return Error(ExprLoc, "unexpected expression in _emit"); 4044 uint64_t IntValue = MCE->getValue(); 4045 if (!isUIntN(8, IntValue) && !isIntN(8, IntValue)) 4046 return Error(ExprLoc, "literal value out of range for directive"); 4047 4048 Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, Len)); 4049 return false; 4050 } 4051 4052 bool AsmParser::ParseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { 4053 const MCExpr *Value; 4054 SMLoc ExprLoc = getLexer().getLoc(); 4055 if (parseExpression(Value)) 4056 return true; 4057 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 4058 if (!MCE) 4059 return Error(ExprLoc, "unexpected expression in align"); 4060 uint64_t IntValue = MCE->getValue(); 4061 if (!isPowerOf2_64(IntValue)) 4062 return Error(ExprLoc, "literal value not a power of two greater then zero"); 4063 4064 Info.AsmRewrites->push_back(AsmRewrite(AOK_Align, IDLoc, 5, 4065 Log2_64(IntValue))); 4066 return false; 4067 } 4068 4069 // We are comparing pointers, but the pointers are relative to a single string. 4070 // Thus, this should always be deterministic. 4071 static int RewritesSort(const void *A, const void *B) { 4072 const AsmRewrite *AsmRewriteA = static_cast<const AsmRewrite *>(A); 4073 const AsmRewrite *AsmRewriteB = static_cast<const AsmRewrite *>(B); 4074 if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) 4075 return -1; 4076 if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) 4077 return 1; 4078 4079 // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output 4080 // rewrite to the same location. Make sure the SizeDirective rewrite is 4081 // performed first, then the Imm/ImmPrefix and finally the Input/Output. This 4082 // ensures the sort algorithm is stable. 4083 if (AsmRewritePrecedence [AsmRewriteA->Kind] > 4084 AsmRewritePrecedence [AsmRewriteB->Kind]) 4085 return -1; 4086 4087 if (AsmRewritePrecedence [AsmRewriteA->Kind] < 4088 AsmRewritePrecedence [AsmRewriteB->Kind]) 4089 return 1; 4090 llvm_unreachable ("Unstable rewrite sort."); 4091 } 4092 4093 bool 4094 AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString, 4095 unsigned &NumOutputs, unsigned &NumInputs, 4096 SmallVectorImpl<std::pair<void *, bool> > &OpDecls, 4097 SmallVectorImpl<std::string> &Constraints, 4098 SmallVectorImpl<std::string> &Clobbers, 4099 const MCInstrInfo *MII, 4100 const MCInstPrinter *IP, 4101 MCAsmParserSemaCallback &SI) { 4102 SmallVector<void *, 4> InputDecls; 4103 SmallVector<void *, 4> OutputDecls; 4104 SmallVector<bool, 4> InputDeclsAddressOf; 4105 SmallVector<bool, 4> OutputDeclsAddressOf; 4106 SmallVector<std::string, 4> InputConstraints; 4107 SmallVector<std::string, 4> OutputConstraints; 4108 SmallVector<unsigned, 4> ClobberRegs; 4109 4110 SmallVector<AsmRewrite, 4> AsmStrRewrites; 4111 4112 // Prime the lexer. 4113 Lex(); 4114 4115 // While we have input, parse each statement. 4116 unsigned InputIdx = 0; 4117 unsigned OutputIdx = 0; 4118 while (getLexer().isNot(AsmToken::Eof)) { 4119 ParseStatementInfo Info(&AsmStrRewrites); 4120 if (ParseStatement(Info)) 4121 return true; 4122 4123 if (Info.ParseError) 4124 return true; 4125 4126 if (Info.Opcode == ~0U) 4127 continue; 4128 4129 const MCInstrDesc &Desc = MII->get(Info.Opcode); 4130 4131 // Build the list of clobbers, outputs and inputs. 4132 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) { 4133 MCParsedAsmOperand *Operand = Info.ParsedOperands[i]; 4134 4135 // Immediate. 4136 if (Operand->isImm()) 4137 continue; 4138 4139 // Register operand. 4140 if (Operand->isReg() && !Operand->needAddressOf()) { 4141 unsigned NumDefs = Desc.getNumDefs(); 4142 // Clobber. 4143 if (NumDefs && Operand->getMCOperandNum() < NumDefs) 4144 ClobberRegs.push_back(Operand->getReg()); 4145 continue; 4146 } 4147 4148 // Expr/Input or Output. 4149 StringRef SymName = Operand->getSymName(); 4150 if (SymName.empty()) 4151 continue; 4152 4153 void *OpDecl = Operand->getOpDecl(); 4154 if (!OpDecl) 4155 continue; 4156 4157 bool isOutput = (i == 1) && Desc.mayStore(); 4158 SMLoc Start = SMLoc::getFromPointer(SymName.data()); 4159 if (isOutput) { 4160 ++InputIdx; 4161 OutputDecls.push_back(OpDecl); 4162 OutputDeclsAddressOf.push_back(Operand->needAddressOf()); 4163 OutputConstraints.push_back('=' + Operand->getConstraint().str()); 4164 AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Start, SymName.size())); 4165 } else { 4166 InputDecls.push_back(OpDecl); 4167 InputDeclsAddressOf.push_back(Operand->needAddressOf()); 4168 InputConstraints.push_back(Operand->getConstraint().str()); 4169 AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size())); 4170 } 4171 } 4172 } 4173 4174 // Set the number of Outputs and Inputs. 4175 NumOutputs = OutputDecls.size(); 4176 NumInputs = InputDecls.size(); 4177 4178 // Set the unique clobbers. 4179 array_pod_sort(ClobberRegs.begin(), ClobberRegs.end()); 4180 ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()), 4181 ClobberRegs.end()); 4182 Clobbers.assign(ClobberRegs.size(), std::string()); 4183 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) { 4184 raw_string_ostream OS(Clobbers[I]); 4185 IP->printRegName(OS, ClobberRegs[I]); 4186 } 4187 4188 // Merge the various outputs and inputs. Output are expected first. 4189 if (NumOutputs || NumInputs) { 4190 unsigned NumExprs = NumOutputs + NumInputs; 4191 OpDecls.resize(NumExprs); 4192 Constraints.resize(NumExprs); 4193 for (unsigned i = 0; i < NumOutputs; ++i) { 4194 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]); 4195 Constraints[i] = OutputConstraints[i]; 4196 } 4197 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) { 4198 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]); 4199 Constraints[j] = InputConstraints[i]; 4200 } 4201 } 4202 4203 // Build the IR assembly string. 4204 std::string AsmStringIR; 4205 raw_string_ostream OS(AsmStringIR); 4206 const char *AsmStart = SrcMgr.getMemoryBuffer(0)->getBufferStart(); 4207 const char *AsmEnd = SrcMgr.getMemoryBuffer(0)->getBufferEnd(); 4208 array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), RewritesSort); 4209 for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(), 4210 E = AsmStrRewrites.end(); 4211 I != E; ++I) { 4212 AsmRewriteKind Kind = (*I).Kind; 4213 if (Kind == AOK_Delete) 4214 continue; 4215 4216 const char *Loc = (*I).Loc.getPointer(); 4217 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!"); 4218 4219 // Emit everything up to the immediate/expression. 4220 unsigned Len = Loc - AsmStart; 4221 if (Len) 4222 OS << StringRef(AsmStart, Len); 4223 4224 // Skip the original expression. 4225 if (Kind == AOK_Skip) { 4226 AsmStart = Loc + (*I).Len; 4227 continue; 4228 } 4229 4230 unsigned AdditionalSkip = 0; 4231 // Rewrite expressions in $N notation. 4232 switch (Kind) { 4233 default: break; 4234 case AOK_Imm: 4235 OS << "$$" << (*I).Val; 4236 break; 4237 case AOK_ImmPrefix: 4238 OS << "$$"; 4239 break; 4240 case AOK_Input: 4241 OS << '$' << InputIdx++; 4242 break; 4243 case AOK_Output: 4244 OS << '$' << OutputIdx++; 4245 break; 4246 case AOK_SizeDirective: 4247 switch ((*I).Val) { 4248 default: break; 4249 case 8: OS << "byte ptr "; break; 4250 case 16: OS << "word ptr "; break; 4251 case 32: OS << "dword ptr "; break; 4252 case 64: OS << "qword ptr "; break; 4253 case 80: OS << "xword ptr "; break; 4254 case 128: OS << "xmmword ptr "; break; 4255 case 256: OS << "ymmword ptr "; break; 4256 } 4257 break; 4258 case AOK_Emit: 4259 OS << ".byte"; 4260 break; 4261 case AOK_Align: { 4262 unsigned Val = (*I).Val; 4263 OS << ".align " << Val; 4264 4265 // Skip the original immediate. 4266 assert(Val < 10 && "Expected alignment less then 2^10."); 4267 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4; 4268 break; 4269 } 4270 case AOK_DotOperator: 4271 OS << (*I).Val; 4272 break; 4273 } 4274 4275 // Skip the original expression. 4276 AsmStart = Loc + (*I).Len + AdditionalSkip; 4277 } 4278 4279 // Emit the remainder of the asm string. 4280 if (AsmStart != AsmEnd) 4281 OS << StringRef(AsmStart, AsmEnd - AsmStart); 4282 4283 AsmString = OS.str(); 4284 return false; 4285 } 4286 4287 /// \brief Create an MCAsmParser instance. 4288 MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, 4289 MCContext &C, MCStreamer &Out, 4290 const MCAsmInfo &MAI) { 4291 return new AsmParser(SM, C, Out, MAI); 4292 } 4293