From d305035155ef3d138e102434bf5a733ea2e32405 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 14 Apr 2010 04:40:28 +0000 Subject: [PATCH] implement mc asmparser support for '.', which gets the current PC. rdar://7834775 We now produce an identical .o file compared to the cctools assembler for something like this: _f0: L0: jmp L1 .long . - L0 L1: jmp A .long . - L1 .zerofill __DATA,_bss,A,0 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101227 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCParser/MCAsmLexer.h | 2 +- lib/MC/MCParser/AsmLexer.cpp | 5 +++++ lib/MC/MCParser/AsmParser.cpp | 12 ++++++++++++ test/MC/AsmParser/exprs.s | 11 +++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 043c3633086..075b69b628a 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -42,7 +42,7 @@ public: Plus, Minus, Tilde, Slash, // '/' LParen, RParen, LBrac, RBrac, LCurly, RCurly, - Star, Comma, Dollar, Equal, EqualEqual, + Star, Dot, Comma, Dollar, Equal, EqualEqual, Pipe, PipePipe, Caret, Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash, diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index 22c8d762df3..11833127848 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -74,6 +74,11 @@ AsmToken AsmLexer::LexIdentifier() { while (isalnum(*CurPtr) || *CurPtr == '_' || *CurPtr == '$' || *CurPtr == '.' || *CurPtr == '@') ++CurPtr; + + // Handle . as a special case. + if (CurPtr == TokStart+1 && TokStart[0] == '.') + return AsmToken(AsmToken::Dot, StringRef(TokStart, 1)); + return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart)); } diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 7120d912905..e2c43f487a8 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -209,6 +209,7 @@ MCSymbol *AsmParser::CreateSymbol(StringRef Name) { /// primaryexpr ::= (parenexpr /// primaryexpr ::= symbol /// primaryexpr ::= number +/// primaryexpr ::= '.' /// primaryexpr ::= ~,+,- primaryexpr bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { switch (Lexer.getKind()) { @@ -253,6 +254,17 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { EndLoc = Lexer.getLoc(); Lex(); // Eat token. return false; + case AsmToken::Dot: { + // This is a '.' reference, which references the current PC. Emit a + // temporary label to the streamer and refer to it. + MCSymbol *Sym = Ctx.CreateTempSymbol(); + Out.EmitLabel(Sym); + Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); + EndLoc = Lexer.getLoc(); + Lex(); // Eat identifier. + return false; + } + case AsmToken::LParen: Lex(); // Eat the '('. return ParseParenExpr(Res, EndLoc); diff --git a/test/MC/AsmParser/exprs.s b/test/MC/AsmParser/exprs.s index 62b11c2d4e4..d9a248cd94f 100644 --- a/test/MC/AsmParser/exprs.s +++ b/test/MC/AsmParser/exprs.s @@ -61,3 +61,14 @@ n: movw $8, (42)+66(%eax) + +// "." support: +_f0: +L0: + jmp L1 + .long . - L0 +L1: + jmp A + .long . - L1 + + .zerofill __DATA,_bss,A,0 -- 2.34.1