[llvm] ca02fab - [AsmParser][SystemZ][z/OS] Implement HLASM location counter syntax ("*") for Z PC-relative instructions.
Anirudh Prasad via llvm-commits
llvm-commits at lists.llvm.org
Mon May 3 11:58:30 PDT 2021
Author: Anirudh Prasad
Date: 2021-05-03T14:58:24-04:00
New Revision: ca02fab7e7b677f77e2c6e3dec172a3bb0a0b1c0
URL: https://github.com/llvm/llvm-project/commit/ca02fab7e7b677f77e2c6e3dec172a3bb0a0b1c0
DIFF: https://github.com/llvm/llvm-project/commit/ca02fab7e7b677f77e2c6e3dec172a3bb0a0b1c0.diff
LOG: [AsmParser][SystemZ][z/OS] Implement HLASM location counter syntax ("*") for Z PC-relative instructions.
- This patch attempts to implement the location counter syntax (*) for the HLASM variant for PC-relative instructions.
- In the HLASM variant, for purely constant relocatable values, we expect a * token preceding it, with special support for " *" which is parsed as "<pc-rel-insn 0>"
- For combinations of absolute values and relocatable values, we don't expect the "*" preceding the token.
When you have a " * " what’s accepted is:
```
*<space>.*{.*} -> <pc-rel-insn> 0
*[+|-][constant-value] -> <pc-rel-insn> [+|-]constant-value
```
When you don’t have a " * " what’s accepted is:
```
brasl 1,func is allowed (MCSymbolRef type)
brasl 1,func+4 is allowed (MCBinary type)
brasl 1,4+func is allowed (MCBinary type)
brasl 1,-4+func is allowed (MCBinary type)
brasl 1,func-4 is allowed (MCBinary type)
brasl 1,*func is not allowed (* cannot be used for non-MCConstantExprs)
brasl 1,*+func is not allowed (* cannot be used for non-MCConstantExprs)
brasl 1,*+func+4 is not allowed (* cannot be used for non-MCConstantExprs)
brasl 1,*+4+func is not allowed (* cannot be used for non-MCConstantExprs)
brasl 1,*-4+8+func is not allowed (* cannot be used for non-MCConstantExprs)
```
Reviewed By: Kai
Differential Revision: https://reviews.llvm.org/D100987
Added:
Modified:
llvm/include/llvm/MC/MCAsmInfo.h
llvm/lib/MC/MCParser/AsmParser.cpp
llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
llvm/test/MC/AsmParser/directive_rept-diagnostics.s
llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h
index a0e7ba6e2a5aa..8de2f60d48984 100644
--- a/llvm/include/llvm/MC/MCAsmInfo.h
+++ b/llvm/include/llvm/MC/MCAsmInfo.h
@@ -122,6 +122,10 @@ class MCAsmInfo {
/// to the current PC. Defaults to true.
bool DotIsPC = true;
+ /// Whether the '*' token refers to the current PC. This is used for the
+ /// HLASM dialect.
+ bool StarIsPC = false;
+
/// This string, if specified, is used to separate instructions from each
/// other when on the same line. Defaults to ';'
const char *SeparatorString;
@@ -598,6 +602,7 @@ class MCAsmInfo {
unsigned getMinInstAlignment() const { return MinInstAlignment; }
bool getDollarIsPC() const { return DollarIsPC; }
bool getDotIsPC() const { return DotIsPC; }
+ bool getStarIsPC() const { return StarIsPC; }
const char *getSeparatorString() const { return SeparatorString; }
/// This indicates the column (zero-based) at which asm comments should be
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 5d037931bb0f5..5f807d8f7ef2c 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1110,25 +1110,33 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Dollar:
+ case AsmToken::Star:
case AsmToken::At:
case AsmToken::String:
case AsmToken::Identifier: {
StringRef Identifier;
if (parseIdentifier(Identifier)) {
- // We may have failed but $ may be a valid token.
- if (getTok().is(AsmToken::Dollar)) {
- if (Lexer.getMAI().getDollarIsPC()) {
- Lex();
- // 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;
- }
- return Error(FirstTokenLoc, "invalid token in expression");
+ // We may have failed but '$'|'*' may be a valid token in context of
+ // the current PC.
+ if (getTok().is(AsmToken::Dollar) || getTok().is(AsmToken::Star)) {
+ bool ShouldGenerateTempSymbol = false;
+ if ((getTok().is(AsmToken::Dollar) && MAI.getDollarIsPC()) ||
+ (getTok().is(AsmToken::Star) && MAI.getStarIsPC()))
+ ShouldGenerateTempSymbol = true;
+
+ if (!ShouldGenerateTempSymbol)
+ return Error(FirstTokenLoc, "invalid token in expression");
+
+ // Eat the '$'|'*' token.
+ Lex();
+ // This is either 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;
}
}
// Parse symbol variant
diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index 42980d6174972..435c68165c385 100644
--- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -1542,6 +1542,10 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
// For consistency with the GNU assembler, treat immediates as offsets
// from ".".
if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
+ if (isParsingHLASM()) {
+ Error(StartLoc, "Expected PC-relative expression");
+ return MatchOperand_ParseFail;
+ }
if (isOutOfRangeConstant(CE)) {
Error(StartLoc, "offset out of range");
return MatchOperand_ParseFail;
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
index 6422ca93b6d77..e3d71f21f70c9 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
@@ -28,6 +28,7 @@ SystemZMCAsmInfo::SystemZMCAsmInfo(const Triple &TT) {
AllowDollarAtStartOfIdentifier = (AssemblerDialect == AD_HLASM);
AllowHashAtStartOfIdentifier = (AssemblerDialect == AD_HLASM);
DotIsPC = (AssemblerDialect == AD_ATT);
+ StarIsPC = (AssemblerDialect == AD_HLASM);
ZeroDirective = "\t.space\t";
Data64bitsDirective = "\t.quad\t";
diff --git a/llvm/test/MC/AsmParser/directive_rept-diagnostics.s b/llvm/test/MC/AsmParser/directive_rept-diagnostics.s
index 40c355514a054..3d12907656445 100644
--- a/llvm/test/MC/AsmParser/directive_rept-diagnostics.s
+++ b/llvm/test/MC/AsmParser/directive_rept-diagnostics.s
@@ -8,7 +8,7 @@
invalid_expression:
.rept *
-# CHECK: error: unknown token in expression
+# CHECK: error: invalid token in expression
# CHECK: .rept *
# CHECK: ^
diff --git a/llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp b/llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp
index 6c868ce861674..353084a7a28b3 100644
--- a/llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp
+++ b/llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp
@@ -685,4 +685,19 @@ TEST_F(SystemZAsmLexerTest, CheckRejectDotAsCurrentPC) {
EXPECT_EQ(ParsePrimaryExpr, true);
EXPECT_EQ(Parser->hasPendingError(), true);
}
+
+TEST_F(SystemZAsmLexerTest, CheckRejectStarAsCurrentPC) {
+ StringRef AsmStr = "*-4";
+
+ // Setup.
+ setupCallToAsmParser(AsmStr);
+
+ // Lex initially to get the string.
+ Parser->getLexer().Lex();
+
+ const MCExpr *Expr;
+ bool ParsePrimaryExpr = Parser->parseExpression(Expr);
+ EXPECT_EQ(ParsePrimaryExpr, true);
+ EXPECT_EQ(Parser->hasPendingError(), true);
+}
} // end anonymous namespace
More information about the llvm-commits
mailing list