diff options
author | Chris Lattner <sabre@nondot.org> | 2009-07-09 17:25:12 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-07-09 17:25:12 +0000 |
commit | 18359229ccd89907441a5a78aad433ec984ae9b9 (patch) | |
tree | 19e6cc5e5ba460dbefc9104f212aea7e810d75a3 | |
parent | db740ef17b07f82f4a15cebe5c18423f0ecd4318 (diff) | |
download | external_llvm-18359229ccd89907441a5a78aad433ec984ae9b9.zip external_llvm-18359229ccd89907441a5a78aad433ec984ae9b9.tar.gz external_llvm-18359229ccd89907441a5a78aad433ec984ae9b9.tar.bz2 |
add llvm-mc support for parsing the .lcomm directive, patch by Kevin Enderby!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75148 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 7 | ||||
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 9 | ||||
-rw-r--r-- | test/MC/AsmParser/directive_lcomm.s | 10 | ||||
-rw-r--r-- | tools/llvm-mc/AsmParser.cpp | 25 | ||||
-rw-r--r-- | tools/llvm-mc/AsmParser.h | 2 |
5 files changed, 35 insertions, 18 deletions
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index bc3dd73..6e20457 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -115,14 +115,15 @@ namespace llvm { virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute) = 0; - /// EmitCommonSymbol - Emit a common symbol of @param Size with the @param - /// Pow2Alignment if non-zero. + /// EmitCommonSymbol - Emit a common or local common symbol of @param Size + /// with the @param Pow2Alignment if non-zero. /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. /// @param Pow2Alignment - The alignment of the common symbol if non-zero. + /// @param IsLocal - If true, then the symbol is to be a local common virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, - unsigned Pow2Alignment) = 0; + unsigned Pow2Alignment, bool IsLocal) = 0; /// @} /// @name Generating Data diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index f4aeaf3..b7f1982 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -42,7 +42,7 @@ namespace { virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute); virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, - unsigned Pow2Alignment); + unsigned Pow2Alignment, bool IsLocal); virtual void EmitBytes(const char *Data, unsigned Length); @@ -146,8 +146,11 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, } void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, - unsigned Pow2Alignment) { - OS << ".comm"; + unsigned Pow2Alignment, bool IsLocal) { + if (IsLocal) + OS << ".lcomm"; + else + OS << ".comm"; OS << ' ' << Symbol->getName() << ',' << Size; if (Pow2Alignment != 0) OS << ',' << Pow2Alignment; diff --git a/test/MC/AsmParser/directive_lcomm.s b/test/MC/AsmParser/directive_lcomm.s new file mode 100644 index 0000000..2247ed6 --- /dev/null +++ b/test/MC/AsmParser/directive_lcomm.s @@ -0,0 +1,10 @@ +# RUN: llvm-mc %s | FileCheck %s + +# CHECK: TEST0: +# CHECK: .lcomm a,7,4 +# CHECK: .lcomm b,8 +# CHECK: .lcomm c,0 +TEST0: + .lcomm a, 8-1, 4 + .lcomm b,8 + .lcomm c, 0 diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index 1a3543a..65ec962 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -521,7 +521,9 @@ bool AsmParser::ParseStatement() { return ParseDirectiveSymbolAttribute(MCStreamer::WeakReference); if (!strcmp(IDVal, ".comm")) - return ParseDirectiveComm(); + return ParseDirectiveComm(/*IsLocal=*/false); + if (!strcmp(IDVal, ".lcomm")) + return ParseDirectiveComm(/*IsLocal=*/true); Warning(IDLoc, "ignoring directive for now"); EatToEndOfStatement(); @@ -901,8 +903,8 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr) { } /// ParseDirectiveComm -/// ::= .comm identifier , size_expression [ , align_expression ] -bool AsmParser::ParseDirectiveComm() { +/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] +bool AsmParser::ParseDirectiveComm(bool IsLocal) { if (Lexer.isNot(asmtok::Identifier)) return TokError("expected identifier in directive"); @@ -930,28 +932,29 @@ bool AsmParser::ParseDirectiveComm() { } if (Lexer.isNot(asmtok::EndOfStatement)) - return TokError("unexpected token in '.comm' directive"); + return TokError("unexpected token in '.comm' or '.lcomm' directive"); Lexer.Lex(); - // NOTE: a size of zero should create a undefined symbol + // NOTE: a size of zero for a .comm should create a undefined symbol + // but a size of .lcomm creates a bss symbol of size zero. if (Size < 0) - return Error(SizeLoc, "invalid '.comm' size, can't be less than zero"); + return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " + "be less than zero"); // NOTE: The alignment in the directive is a power of 2 value, the assember // may internally end up wanting an alignment in bytes. // FIXME: Diagnose overflow. if (Pow2Alignment < 0) - return Error(Pow2AlignmentLoc, "invalid '.comm' alignment, can't be less " - "than zero"); + return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " + "alignment, can't be less than zero"); // TODO: Symbol must be undefined or it is a error to re-defined the symbol if (Sym->getSection() || Ctx.GetSymbolValue(Sym)) return Error(IDLoc, "invalid symbol redefinition"); - // TODO: Symbol to be made into a common with this Size and Pow2Alignment - - Out.EmitCommonSymbol(Sym, Size, Pow2Alignment); + // Create the Symbol as a common or local common with Size and Pow2Alignment + Out.EmitCommonSymbol(Sym, Size, Pow2Alignment, IsLocal); return false; } diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h index bafdfb7..8bfeaac 100644 --- a/tools/llvm-mc/AsmParser.h +++ b/tools/llvm-mc/AsmParser.h @@ -110,7 +110,7 @@ private: /// accepts a single symbol (which should be a label or an external). bool ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr); - bool ParseDirectiveComm(); // ".comm" + bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" }; |