From aaec205b87637cd0d59d4f11630db603686eb73d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 19 Jan 2010 19:46:13 +0000 Subject: [PATCH] Generalize mcasmstreamer data emission APIs to take an address space identifier. There is no way to work around it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93896 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCStreamer.h | 8 ++-- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 20 +++------ lib/MC/MCAsmStreamer.cpp | 53 +++++++++++++---------- lib/MC/MCMachOStreamer.cpp | 11 ++--- lib/MC/MCNullStreamer.cpp | 5 ++- lib/MC/MCStreamer.cpp | 5 ++- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 2 +- lib/Target/X86/AsmParser/X86AsmParser.cpp | 2 +- tools/llvm-mc/AsmParser.cpp | 14 +++--- 9 files changed, 64 insertions(+), 56 deletions(-) diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 6e655a59053..5b51916e764 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -155,7 +155,7 @@ namespace llvm { /// /// This is used to implement assembler directives such as .byte, .ascii, /// etc. - virtual void EmitBytes(StringRef Data) = 0; + virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0; /// EmitValue - Emit the expression @param Value into the output as a native /// integer of the given @param Size bytes. @@ -166,11 +166,13 @@ namespace llvm { /// @param Value - The value to emit. /// @param Size - The size of the integer (in bytes) to emit. This must /// match a native machine width. - virtual void EmitValue(const MCExpr *Value, unsigned Size) = 0; + virtual void EmitValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace) = 0; /// EmitFill - Emit NumBytes bytes worth of the value specified by /// FillValue. This implements directives such as '.space'. - virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue = 0); + virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, + unsigned AddrSpace); /// EmitValueToAlignment - Emit some number of copies of @param Value until diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 54a93095ed2..03672411f4e 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -436,7 +436,7 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { // Emit inter-object padding for alignment. unsigned AlignMask = CPE.getAlignment() - 1; unsigned NewOffset = (Offset + AlignMask) & ~AlignMask; - OutStreamer.EmitFill(NewOffset - Offset); + OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/); const Type *Ty = CPE.getType(); Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); @@ -913,18 +913,6 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV, OutStreamer.EmitValueToAlignment(1 << NumBits, FillValue, 1, 0); } -/// EmitZeros - Emit a block of zeros. -/// -void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const { - if (NumZeros == 0) return; - if (MAI->getZeroDirective() || AddrSpace == 0) { - OutStreamer.EmitFill(NumZeros); - } else { - for (; NumZeros; --NumZeros) - O << MAI->getData8bitsDirective(AddrSpace) << "0\n"; - } -} - // Print out the specified constant, without a storage class. Only the // constants valid in constant expressions can occur here. void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { @@ -1070,6 +1058,12 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { } } +/// EmitZeros - Emit a block of zeros. +/// +void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const { + OutStreamer.EmitFill(NumZeros, 0, AddrSpace); +} + /// printAsCString - Print the specified array as a C compatible string, only if /// the predicate isString is true. /// diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 1fd048ef667..f3346006436 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -58,10 +58,11 @@ public: virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0); - virtual void EmitBytes(StringRef Data); + virtual void EmitBytes(StringRef Data, unsigned AddrSpace); - virtual void EmitValue(const MCExpr *Value, unsigned Size); - virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue); + virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); + virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, + unsigned AddrSpace); virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, unsigned ValueSize = 1, @@ -179,41 +180,45 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, OS << '\n'; } -void MCAsmStreamer::EmitBytes(StringRef Data) { +void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { assert(CurSection && "Cannot emit contents before setting section!"); + const char *Directive = MAI.getData8bitsDirective(AddrSpace); for (unsigned i = 0, e = Data.size(); i != e; ++i) - OS << ".byte " << (unsigned) (unsigned char) Data[i] << '\n'; + OS << Directive << (unsigned)(unsigned char)Data[i] << '\n'; } -void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size) { +void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace) { assert(CurSection && "Cannot emit contents before setting section!"); // Need target hooks to know how to print this. switch (Size) { - default: - llvm_unreachable("Invalid size for machine code value!"); - case 1: OS << ".byte"; break; - case 2: OS << ".short"; break; - case 4: OS << ".long"; break; - case 8: OS << ".quad"; break; + default: assert(0 && "Invalid size for machine code value!"); + case 1: OS << MAI.getData8bitsDirective(AddrSpace); break; + case 2: OS << MAI.getData16bitsDirective(AddrSpace); break; + case 4: OS << MAI.getData32bitsDirective(AddrSpace); break; + case 8: OS << MAI.getData64bitsDirective(AddrSpace); break; } - - OS << ' ' << *truncateToSize(Value, Size) << '\n'; + + OS << *truncateToSize(Value, Size) << '\n'; } /// EmitFill - Emit NumBytes bytes worth of the value specified by /// FillValue. This implements directives such as '.space'. -void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { +void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, + unsigned AddrSpace) { if (NumBytes == 0) return; - if (const char *ZeroDirective = MAI.getZeroDirective()) { - OS << ZeroDirective << NumBytes; - if (FillValue != 0) - OS << ',' << (int)FillValue; - OS << '\n'; - } else { - // Emit a byte at a time. - MCStreamer::EmitFill(NumBytes, FillValue); - } + if (AddrSpace == 0) + if (const char *ZeroDirective = MAI.getZeroDirective()) { + OS << ZeroDirective << NumBytes; + if (FillValue != 0) + OS << ',' << (int)FillValue; + OS << '\n'; + return; + } + + // Emit a byte at a time. + MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace); } void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 5f120cc6506..ffdd421f4e0 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -134,9 +134,9 @@ public: virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0); - virtual void EmitBytes(StringRef Data); + virtual void EmitBytes(StringRef Data, unsigned AddrSpace); - virtual void EmitValue(const MCExpr *Value, unsigned Size); + virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, unsigned ValueSize = 1, @@ -315,14 +315,15 @@ void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, SectData.setAlignment(ByteAlignment); } -void MCMachOStreamer::EmitBytes(StringRef Data) { +void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { MCDataFragment *DF = dyn_cast_or_null(getCurrentFragment()); if (!DF) DF = new MCDataFragment(CurSectionData); DF->getContents().append(Data.begin(), Data.end()); } -void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size) { +void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace) { new MCFillFragment(*AddValueSymbols(Value), Size, 1, CurSectionData); } @@ -359,7 +360,7 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { SmallString<256> Code; raw_svector_ostream VecOS(Code); Emitter->EncodeInstruction(Inst, VecOS); - EmitBytes(VecOS.str()); + EmitBytes(VecOS.str(), 0); } void MCMachOStreamer::Finish() { diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index ddc4e69d239..b1357926f1f 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -45,9 +45,10 @@ namespace { virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0) {} - virtual void EmitBytes(StringRef Data) {} + virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {} - virtual void EmitValue(const MCExpr *Value, unsigned Size) {} + virtual void EmitValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace) {} virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, unsigned ValueSize = 1, diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index e43d9413093..20767de3bee 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -20,8 +20,9 @@ MCStreamer::~MCStreamer() { /// EmitFill - Emit NumBytes bytes worth of the value specified by /// FillValue. This implements directives such as '.space'. -void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { +void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, + unsigned AddrSpace) { const MCExpr *E = MCConstantExpr::Create(FillValue, getContext()); for (uint64_t i = 0, e = NumBytes; i != e; ++i) - EmitValue(E, 1); + EmitValue(E, 1, AddrSpace); } diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 132738efdfb..ac30cd0883a 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -629,7 +629,7 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { if (getParser().ParseExpression(Value)) return true; - getParser().getStreamer().EmitValue(Value, Size); + getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); if (getLexer().is(AsmToken::EndOfStatement)) break; diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index c2459c9e654..a9f87812cd7 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -470,7 +470,7 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { if (getParser().ParseExpression(Value)) return true; - getParser().getStreamer().EmitValue(Value, Size); + getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/); if (getLexer().is(AsmToken::EndOfStatement)) break; diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index 3a57953e65a..3b05f1569c7 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -29,6 +29,9 @@ #include "llvm/Target/TargetAsmParser.h" using namespace llvm; + +enum { DEFAULT_ADDRSPACE = 0 }; + // Mach-O section uniquing. // // FIXME: Figure out where this should live, it should be shared by @@ -967,9 +970,9 @@ bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) { if (ParseEscapedString(Data)) return true; - Out.EmitBytes(Data); + Out.EmitBytes(Data, DEFAULT_ADDRSPACE); if (ZeroTerminated) - Out.EmitBytes(StringRef("\0", 1)); + Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE); Lexer.Lex(); @@ -996,7 +999,7 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) { if (ParseExpression(Value)) return true; - Out.EmitValue(Value, Size); + Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE); if (Lexer.is(AsmToken::EndOfStatement)) break; @@ -1041,7 +1044,7 @@ bool AsmParser::ParseDirectiveSpace() { return TokError("invalid number of bytes in '.space' directive"); // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. - Out.EmitFill(NumBytes, FillExpr); + Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE); return false; } @@ -1078,7 +1081,8 @@ bool AsmParser::ParseDirectiveFill() { return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); for (uint64_t i = 0, e = NumValues; i != e; ++i) - Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize); + Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize, + DEFAULT_ADDRSPACE); return false; } -- 2.34.1