1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 10:32:48 +02:00

[AsmParser][SystemZ][z/OS] Support for emitting labels in upper case

- Currently, the emitting of labels in the parsePrimaryExpr function is case independent. It just takes the identifier and emits it.
- However, for HLASM the emitting of labels is case independent. We are emitting them in the upper case only, to enforce case independency. So we need to ensure that at the time of parsing the label we are emitting the upper case (in `parseAsHLASMLabel`), but also, when we are processing a PC-relative relocatable expression, we need to ensure we emit it in upper case (in `parsePrimaryExpr`)
- To achieve this a new MCAsmInfo attribute has been introduced which corresponding targets can override if needed.

Reviewed By: abhina.sreeskantharajan, uweigand

Differential Revision: https://reviews.llvm.org/D104715
This commit is contained in:
Anirudh Prasad 2021-06-24 12:49:38 -04:00
parent d12ae1eaf8
commit 6fc759537e
4 changed files with 44 additions and 3 deletions

View File

@ -153,6 +153,9 @@ protected:
/// This is appended to emitted labels. Defaults to ":" /// This is appended to emitted labels. Defaults to ":"
const char *LabelSuffix; const char *LabelSuffix;
/// Emit labels in purely upper case. Defaults to false.
bool EmitLabelsInUpperCase = false;
// Print the EH begin symbol with an assignment. Defaults to false. // Print the EH begin symbol with an assignment. Defaults to false.
bool UseAssignmentForEHBegin = false; bool UseAssignmentForEHBegin = false;
@ -637,6 +640,7 @@ public:
return EmitGNUAsmStartIndentationMarker; return EmitGNUAsmStartIndentationMarker;
} }
const char *getLabelSuffix() const { return LabelSuffix; } const char *getLabelSuffix() const { return LabelSuffix; }
bool shouldEmitLabelsInUpperCase() const { return EmitLabelsInUpperCase; }
bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; } bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }
bool needsLocalForSize() const { return NeedsLocalForSize; } bool needsLocalForSize() const { return NeedsLocalForSize; }

View File

@ -1231,7 +1231,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName); MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
if (!Sym) if (!Sym)
Sym = getContext().getOrCreateSymbol(SymbolName); Sym = getContext().getOrCreateSymbol(
MAI.shouldEmitLabelsInUpperCase() ? SymbolName.upper() : SymbolName);
// If this is an absolute variable reference, substitute it now to preserve // If this is an absolute variable reference, substitute it now to preserve
// semantics in the face of reassignment. // semantics in the face of reassignment.
@ -6212,8 +6213,10 @@ bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
return Error(LabelLoc, return Error(LabelLoc,
"Cannot have just a label for an HLASM inline asm statement"); "Cannot have just a label for an HLASM inline asm statement");
// FIXME: Later on, ensure emitted labels are case-insensitive. MCSymbol *Sym = getContext().getOrCreateSymbol(
MCSymbol *Sym = getContext().getOrCreateSymbol(LabelVal); getContext().getAsmInfo()->shouldEmitLabelsInUpperCase()
? LabelVal.upper()
: LabelVal);
getTargetParser().doBeforeLabelEmit(Sym); getTargetParser().doBeforeLabelEmit(Sym);

View File

@ -31,6 +31,7 @@ SystemZMCAsmInfo::SystemZMCAsmInfo(const Triple &TT) {
StarIsPC = (AssemblerDialect == AD_HLASM); StarIsPC = (AssemblerDialect == AD_HLASM);
EmitGNUAsmStartIndentationMarker = (AssemblerDialect == AD_ATT); EmitGNUAsmStartIndentationMarker = (AssemblerDialect == AD_ATT);
AllowAtInName = (AssemblerDialect == AD_HLASM); AllowAtInName = (AssemblerDialect == AD_HLASM);
EmitLabelsInUpperCase = (AssemblerDialect == AD_HLASM);
ZeroDirective = "\t.space\t"; ZeroDirective = "\t.space\t";
Data64bitsDirective = "\t.quad\t"; Data64bitsDirective = "\t.quad\t";

View File

@ -49,6 +49,7 @@ public:
} }
void setAllowDotIsPC(bool Value) { DotIsPC = Value; } void setAllowDotIsPC(bool Value) { DotIsPC = Value; }
void setAssemblerDialect(unsigned Value) { AssemblerDialect = Value; } void setAssemblerDialect(unsigned Value) { AssemblerDialect = Value; }
void setEmitLabelsInUpperCase(bool Value) { EmitLabelsInUpperCase = Value; }
}; };
// Setup a testing class that the GTest framework can call. // Setup a testing class that the GTest framework can call.
@ -750,4 +751,36 @@ TEST_F(SystemZAsmLexerTest, CheckPrintAcceptableSymbol2) {
AsmStr += "#"; AsmStr += "#";
EXPECT_EQ(true, MUPMAI->isValidUnquotedName(AsmStr)); EXPECT_EQ(true, MUPMAI->isValidUnquotedName(AsmStr));
} }
TEST_F(SystemZAsmLexerTest, CheckLabelCaseUpperCase2) {
StringRef AsmStr = "label\nlabel";
// Setup.
setupCallToAsmParser(AsmStr);
// Lex initially to get the string.
Parser->getLexer().Lex();
const MCExpr *Expr;
bool ParsePrimaryExpr = Parser->parseExpression(Expr);
EXPECT_EQ(ParsePrimaryExpr, false);
const MCSymbolRefExpr *SymbolExpr = dyn_cast<MCSymbolRefExpr>(Expr);
EXPECT_NE(SymbolExpr, nullptr);
EXPECT_NE(&SymbolExpr->getSymbol(), nullptr);
EXPECT_EQ((&SymbolExpr->getSymbol())->getName(), StringRef("label"));
// Lex the end of statement token.
Parser->getLexer().Lex();
MUPMAI->setEmitLabelsInUpperCase(true);
ParsePrimaryExpr = Parser->parseExpression(Expr);
EXPECT_EQ(ParsePrimaryExpr, false);
SymbolExpr = dyn_cast<MCSymbolRefExpr>(Expr);
EXPECT_NE(SymbolExpr, nullptr);
EXPECT_NE(&SymbolExpr->getSymbol(), nullptr);
EXPECT_EQ((&SymbolExpr->getSymbol())->getName(), StringRef("LABEL"));
}
} // end anonymous namespace } // end anonymous namespace