summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp40
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp38
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp42
-rw-r--r--llvm/lib/MC/MCStreamer.cpp16
4 files changed, 102 insertions, 34 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index c47ef73e718..612e176e5af 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -31,6 +31,7 @@
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/SourceMgr.h"
#include <cctype>
using namespace llvm;
@@ -178,6 +179,14 @@ public:
void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
+ void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
+ SMLoc Loc = SMLoc()) override;
+
+ void emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) override;
+
+ void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
+ SMLoc Loc = SMLoc()) override;
+
void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) override;
@@ -799,16 +808,41 @@ void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
if (NumBytes == 0) return;
+ const MCExpr *E = MCConstantExpr::create(NumBytes, getContext());
+ emitFill(*E, FillValue);
+}
+
+void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
+ SMLoc Loc) {
if (const char *ZeroDirective = MAI->getZeroDirective()) {
- OS << ZeroDirective << NumBytes;
+ // FIXME: Emit location directives
+ OS << ZeroDirective;
+ NumBytes.print(OS, MAI);
if (FillValue != 0)
OS << ',' << (int)FillValue;
EmitEOL();
return;
}
- // Emit a byte at a time.
- MCStreamer::EmitFill(NumBytes, FillValue);
+ MCStreamer::emitFill(NumBytes, FillValue);
+}
+
+void MCAsmStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
+ if (NumValues == 0)
+ return;
+
+ const MCExpr *E = MCConstantExpr::create(NumValues, getContext());
+ emitFill(*E, Size, Expr);
+}
+
+void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
+ int64_t Expr, SMLoc Loc) {
+ // FIXME: Emit location directives
+ OS << "\t.fill\t";
+ NumValues.print(OS, MAI);
+ OS << ", " << Size << ", 0x";
+ OS.write_hex(truncateToSize(Expr, 32));
+ EmitEOL();
}
void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index b90f0a80cfe..bf7d0f241c0 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -20,6 +20,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
@@ -496,6 +497,43 @@ void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
insert(new MCFillFragment(FillValue, NumBytes));
}
+void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
+ SMLoc Loc) {
+ MCDataFragment *DF = getOrCreateDataFragment();
+ flushPendingLabels(DF, DF->getContents().size());
+
+ int64_t IntNumBytes;
+ if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) {
+ getContext().reportError(Loc, "expected absolute expression");
+ return;
+ }
+
+ if (IntNumBytes <= 0) {
+ getContext().reportError(Loc, "invalid number of bytes");
+ return;
+ }
+
+ EmitFill(IntNumBytes, FillValue);
+}
+
+void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
+ int64_t Expr, SMLoc Loc) {
+ int64_t IntNumValues;
+ if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) {
+ getContext().reportError(Loc, "expected absolute expression");
+ return;
+ }
+
+ if (IntNumValues < 0) {
+ getContext().getSourceManager()->PrintMessage(
+ Loc, SourceMgr::DK_Warning,
+ "'.fill' directive with negative repeat count has no effect");
+ return;
+ }
+
+ MCStreamer::emitFill(IntNumValues, Size, Expr);
+}
+
void MCObjectStreamer::FinishImpl() {
// If we are generating dwarf for assembly source files dump out the sections.
if (getContext().getGenDwarfForAssembly())
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 5de8c7d603a..dcc02a9ab8c 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -2738,8 +2738,9 @@ bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
bool AsmParser::parseDirectiveZero() {
checkForValidSection();
- int64_t NumBytes;
- if (parseAbsoluteExpression(NumBytes))
+ SMLoc NumBytesLoc = Lexer.getLoc();
+ const MCExpr *NumBytes;
+ if (parseExpression(NumBytes))
return true;
int64_t Val = 0;
@@ -2754,7 +2755,7 @@ bool AsmParser::parseDirectiveZero() {
Lex();
- getStreamer().EmitFill(NumBytes, Val);
+ getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
return false;
}
@@ -2764,17 +2765,11 @@ bool AsmParser::parseDirectiveZero() {
bool AsmParser::parseDirectiveFill() {
checkForValidSection();
- SMLoc RepeatLoc = getLexer().getLoc();
- int64_t NumValues;
- if (parseAbsoluteExpression(NumValues))
+ SMLoc NumValuesLoc = Lexer.getLoc();
+ const MCExpr *NumValues;
+ if (parseExpression(NumValues))
return true;
- if (NumValues < 0) {
- Warning(RepeatLoc,
- "'.fill' directive with negative repeat count has no effect");
- NumValues = 0;
- }
-
int64_t FillSize = 1;
int64_t FillExpr = 0;
@@ -2806,7 +2801,7 @@ bool AsmParser::parseDirectiveFill() {
if (FillSize < 0) {
Warning(SizeLoc, "'.fill' directive with negative size has no effect");
- NumValues = 0;
+ NumValues = MCConstantExpr::create(0, getStreamer().getContext());
}
if (FillSize > 8) {
Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
@@ -2816,15 +2811,7 @@ bool AsmParser::parseDirectiveFill() {
if (!isUInt<32>(FillExpr) && FillSize > 4)
Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
- if (NumValues > 0) {
- int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize;
- FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8);
- for (uint64_t i = 0, e = NumValues; i != e; ++i) {
- getStreamer().EmitIntValue(FillExpr, NonZeroFillSize);
- if (NonZeroFillSize < FillSize)
- getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize);
- }
- }
+ getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
return false;
}
@@ -4057,8 +4044,9 @@ bool AsmParser::parseDirectiveBundleUnlock() {
bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
checkForValidSection();
- int64_t NumBytes;
- if (parseAbsoluteExpression(NumBytes))
+ SMLoc NumBytesLoc = Lexer.getLoc();
+ const MCExpr *NumBytes;
+ if (parseExpression(NumBytes))
return true;
int64_t FillExpr = 0;
@@ -4076,12 +4064,8 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
Lex();
- if (NumBytes <= 0)
- return TokError("invalid number of bytes in '" + Twine(IDVal) +
- "' directive");
-
// FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- getStreamer().EmitFill(NumBytes, FillExpr);
+ getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
return false;
}
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 59bbc2ece1d..9ed5a5faacd 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -135,9 +135,18 @@ void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
/// 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) {
- const MCExpr *E = MCConstantExpr::create(FillValue, getContext());
for (uint64_t i = 0, e = NumBytes; i != e; ++i)
- EmitValue(E, 1);
+ EmitIntValue(FillValue, 1);
+}
+
+void MCStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
+ int64_t NonZeroSize = Size > 4 ? 4 : Size;
+ Expr &= ~0ULL >> (64 - NonZeroSize * 8);
+ for (uint64_t i = 0, e = NumValues; i != e; ++i) {
+ EmitIntValue(Expr, NonZeroSize);
+ if (NonZeroSize < Size)
+ EmitIntValue(0, Size - NonZeroSize);
+ }
}
/// The implementation in this class just redirects to EmitFill.
@@ -757,6 +766,9 @@ void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
}
void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
+void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
+void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
+ SMLoc Loc) {}
void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
unsigned ValueSize,
unsigned MaxBytesToEmit) {}
OpenPOWER on IntegriCloud