mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Generalize mcasmstreamer data emission APIs to take an address space
identifier. There is no way to work around it. llvm-svn: 93896
This commit is contained in:
parent
4b916556a5
commit
336c2b0d47
@ -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
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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,
|
||||
|
@ -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<MCDataFragment>(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() {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user