From: Chris Lattner Date: Thu, 9 Jul 2009 17:25:12 +0000 (+0000) Subject: add llvm-mc support for parsing the .lcomm directive, patch by Kevin Enderby! X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=1fc3d7558139eb6081a7ee5a8f88506d44c8dd7f;p=oota-llvm.git 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 --- diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index bc3dd738ee3..6e204571d60 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 f4aeaf39f33..b7f198232f3 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 00000000000..2247ed61c4f --- /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 1a3543aac77..65ec9628a38 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 bafdfb76a0e..8bfeaac2a7e 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" };