From 482eba054ab3543ee0e1f453d3d6441092f4b76d Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Fri, 14 May 2010 01:50:28 +0000 Subject: [PATCH] Add AsmParser support for darwin tbss directive. Nothing uses this yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103757 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCParser/AsmParser.h | 1 + include/llvm/MC/MCStreamer.h | 8 ++++ lib/MC/MCAsmStreamer.cpp | 18 +++++++++ lib/MC/MCMachOStreamer.cpp | 7 ++++ lib/MC/MCNullStreamer.cpp | 3 +- lib/MC/MCParser/AsmParser.cpp | 57 ++++++++++++++++++++++++++++ test/MC/AsmParser/directive_tbss.s | 7 ++++ 7 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 test/MC/AsmParser/directive_tbss.s diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h index 7a78906733a..e668e6474e8 100644 --- a/include/llvm/MC/MCParser/AsmParser.h +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -136,6 +136,7 @@ private: bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" bool ParseDirectiveDarwinZerofill(); // Darwin specific ".zerofill" + bool ParseDirectiveDarwinTBSS(); // Darwin specific ".tbss" // Darwin specific ".subsections_via_symbols" bool ParseDirectiveDarwinSubsectionsViaSymbols(); diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 9e9f68a8daa..400f4c027db 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -188,6 +188,14 @@ namespace llvm { virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0,unsigned ByteAlignment = 0) = 0; + /// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol. + /// + /// @param Symbol - The thread local common symbol to emit. + /// @param Size - The size of the symbol. + /// @param ByteAlignment - The alignment of the thread local common symbol + /// if non-zero. This must be a power of 2 on some targets. + virtual void EmitTBSSSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment = 0) = 0; /// @} /// @name Generating Data /// @{ diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 6acc90af8a5..62735ad3f3a 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -126,6 +126,9 @@ public: virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0); + virtual void EmitTBSSSymbol (MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment = 0); + virtual void EmitBytes(StringRef Data, unsigned AddrSpace); virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); @@ -360,6 +363,21 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, EmitEOL(); } +// .tbss sym$tlv$init, size, align +void MCAsmStreamer::EmitTBSSSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + assert(Symbol != NULL && "Symbol shouldn't be NULL!"); + OS << ".tbss "; + + // This is a mach-o specific directive and the name requires some mangling. + OS << *Symbol << "$tlv$init, " << Size; + + // Output align if we have it. + if (ByteAlignment != 0) OS << ", " << Log2_32(ByteAlignment); + + EmitEOL(); +} + static inline char toOctal(int X) { return (X&7)+'0'; } static void PrintQuotedString(StringRef Data, raw_ostream &OS) { diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 62abf745ba7..b27f151f434 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -126,6 +126,8 @@ public: } virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0); + virtual void EmitTBSSSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment = 0); virtual void EmitBytes(StringRef Data, unsigned AddrSpace); virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); virtual void EmitGPRel32Value(const MCExpr *Value) { @@ -337,6 +339,11 @@ void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, SectData.setAlignment(ByteAlignment); } +void MCMachOStreamer::EmitTBSSSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + assert(false && "Implement me!"); +} + void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); } diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 8bde2d9b06c..c206bb34517 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -55,7 +55,8 @@ namespace { virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0) {} - + virtual void EmitTBSSSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) {} virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {} virtual void EmitValue(const MCExpr *Value, unsigned Size, diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index fe2164cfd88..18977de8adb 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -703,6 +703,8 @@ bool AsmParser::ParseStatement() { return ParseDirectiveDarwinSymbolDesc(); if (IDVal == ".lsym") return ParseDirectiveDarwinLsym(); + if (IDVal == ".tbss") + return ParseDirectiveDarwinTBSS(); if (IDVal == ".subsections_via_symbols") return ParseDirectiveDarwinSubsectionsViaSymbols(); @@ -1427,6 +1429,61 @@ bool AsmParser::ParseDirectiveDarwinZerofill() { return false; } +/// ParseDirectiveDarwinTBSS +/// ::= .tbss identifier, size, align +bool AsmParser::ParseDirectiveDarwinTBSS() { + SMLoc IDLoc = Lexer.getLoc(); + StringRef Name; + if (ParseIdentifier(Name)) + return TokError("expected identifier in directive"); + + // Demangle the name output. The trailing characters are guaranteed to be + // $tlv$init so just strip that off. + StringRef DemName = Name.substr(0, Name.size() - strlen("$tlv$init")); + + // Handle the identifier as the key symbol. + MCSymbol *Sym = CreateSymbol(DemName); + + if (Lexer.isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + + int64_t Size; + SMLoc SizeLoc = Lexer.getLoc(); + if (ParseAbsoluteExpression(Size)) + return true; + + int64_t Pow2Alignment = 0; + SMLoc Pow2AlignmentLoc; + if (Lexer.is(AsmToken::Comma)) { + Lex(); + Pow2AlignmentLoc = Lexer.getLoc(); + if (ParseAbsoluteExpression(Pow2Alignment)) + return true; + } + + if (Lexer.isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.tbss' directive"); + + Lex(); + + if (Size < 0) + return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" + "zero"); + + // FIXME: Diagnose overflow. + if (Pow2Alignment < 0) + return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" + "than zero"); + + if (!Sym->isUndefined()) + return Error(IDLoc, "invalid symbol redefinition"); + + Out.EmitTBSSSymbol(Sym, Size, Pow2Alignment ? 1 << Pow2Alignment : 0); + + return false; +} + /// ParseDirectiveDarwinSubsectionsViaSymbols /// ::= .subsections_via_symbols bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() { diff --git a/test/MC/AsmParser/directive_tbss.s b/test/MC/AsmParser/directive_tbss.s new file mode 100644 index 00000000000..01ba17be263 --- /dev/null +++ b/test/MC/AsmParser/directive_tbss.s @@ -0,0 +1,7 @@ +# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s + +# CHECK: .tbss _a$tlv$init, 4 +# CHECK: .tbss _b$tlv$init, 4, 3 + +.tbss _a$tlv$init, 4 +.tbss _b$tlv$init, 4, 3