aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCAsmInfo.h7
-rw-r--r--lib/MC/MCAsmInfo.cpp1
-rw-r--r--lib/MC/MCParser/AsmParser.cpp16
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp2
-rw-r--r--test/MC/PowerPC/ppc64-operands.s5
5 files changed, 28 insertions, 3 deletions
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index f5acd17..3734d7e 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -93,6 +93,10 @@ namespace llvm {
/// this value. Factored out in .debug_frame and .debug_line.
unsigned MinInstAlignment; // Defaults to 1.
+ /// DollarIsPC - The '$' token, when not referencing an identifier or
+ /// constant, refers to the current PC.
+ bool DollarIsPC; // Defaults to false.
+
/// SeparatorString - This string, if specified, is used to separate
/// instructions from each other when on the same line.
const char *SeparatorString; // Defaults to ';'
@@ -421,6 +425,9 @@ namespace llvm {
unsigned getMinInstAlignment() const {
return MinInstAlignment;
}
+ bool getDollarIsPC() const {
+ return DollarIsPC;
+ }
const char *getSeparatorString() const {
return SeparatorString;
}
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index 73dc74a..152aae1 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -35,6 +35,7 @@ MCAsmInfo::MCAsmInfo() {
LinkerRequiresNonEmptyDwarfLines = false;
MaxInstLength = 4;
MinInstAlignment = 1;
+ DollarIsPC = false;
SeparatorString = ";";
CommentColumn = 40;
CommentString = "#";
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 1267dc8..21cbd34 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -772,9 +772,19 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
case AsmToken::Identifier: {
StringRef Identifier;
if (parseIdentifier(Identifier)) {
- if (FirstTokenKind == AsmToken::Dollar)
- return Error(FirstTokenLoc, "invalid token in expression");
- return true;
+ if (FirstTokenKind == AsmToken::Dollar) {
+ if (Lexer.getMAI().getDollarIsPC()) {
+ // This is a '$' reference, which references the current PC. Emit a
+ // temporary label to the streamer and refer to it.
+ MCSymbol *Sym = Ctx.CreateTempSymbol();
+ Out.EmitLabel(Sym);
+ Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
+ EndLoc = FirstTokenLoc;
+ return false;
+ } else
+ return Error(FirstTokenLoc, "invalid token in expression");
+ return true;
+ }
}
EndLoc = SMLoc::getFromPointer(Identifier.end());
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
index 1f3e5b4..91578a9 100644
--- a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
+++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp
@@ -54,6 +54,8 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
// Debug Information
SupportsDebugInformation = true;
+ DollarIsPC = true;
+
// Set up DWARF directives
HasLEB128 = true; // Target asm supports leb128 directives (little-endian)
MinInstAlignment = 4;
diff --git a/test/MC/PowerPC/ppc64-operands.s b/test/MC/PowerPC/ppc64-operands.s
index cb96fd4..fc1cbeb 100644
--- a/test/MC/PowerPC/ppc64-operands.s
+++ b/test/MC/PowerPC/ppc64-operands.s
@@ -108,3 +108,8 @@
# CHECK: beqa 0, 1024 # encoding: [0x41,0x82,0x04,0x02]
beqa 1024
+# CHECK: # encoding: [0x42,0x9f,A,0bAAAAAA01]
+ bcl 20, 31, $+4
+
+# CHECK: # encoding: [0x42,0x00,A,0bAAAAAA00]
+ bdnz $-8