[llvm] r334022 - [MC][X86] Allow assembler variable assignment to register name.
Nirav Dave via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 5 08:13:40 PDT 2018
Author: niravd
Date: Tue Jun 5 08:13:39 2018
New Revision: 334022
URL: http://llvm.org/viewvc/llvm-project?rev=334022&view=rev
Log:
[MC][X86] Allow assembler variable assignment to register name.
Summary:
Allow extended parsing of variable assembler assignment syntax and modify X86 to permit
VAR = register assignment. As we emit these as .set directives when possible, we inline
such expressions in output assembly.
Fixes PR37425.
Reviewers: rnk, void, echristo
Reviewed By: rnk
Subscribers: nickdesaulniers, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D47545
Added:
llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCExpr.h
llvm/trunk/test/MC/X86/pr37425.s
Modified:
llvm/trunk/include/llvm/MC/MCExpr.h
llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h
llvm/trunk/include/llvm/MC/MCParser/MCAsmParserUtils.h
llvm/trunk/include/llvm/MC/MCParser/MCTargetAsmParser.h
llvm/trunk/lib/MC/MCAsmStreamer.cpp
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
llvm/trunk/lib/MC/MCParser/MCAsmParser.cpp
llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
Modified: llvm/trunk/include/llvm/MC/MCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCExpr.h?rev=334022&r1=334021&r2=334022&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCExpr.h (original)
+++ llvm/trunk/include/llvm/MC/MCExpr.h Tue Jun 5 08:13:39 2018
@@ -581,6 +581,9 @@ public:
virtual bool evaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout,
const MCFixup *Fixup) const = 0;
+ // This should be set when assigned expressions are not valid ".set"
+ // expressions, e.g. registers, and must be inlined.
+ virtual bool inlineAssignedExpr() const { return false; }
virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
virtual MCFragment *findAssociatedFragment() const = 0;
Modified: llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h?rev=334022&r1=334021&r2=334022&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h (original)
+++ llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h Tue Jun 5 08:13:39 2018
@@ -214,6 +214,8 @@ public:
return rv;
}
+ void clearPendingErrors() { PendingErrors.clear(); }
+
bool addErrorSuffix(const Twine &Suffix);
/// Get the next AsmToken in the stream, possibly handling file
Modified: llvm/trunk/include/llvm/MC/MCParser/MCAsmParserUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCParser/MCAsmParserUtils.h?rev=334022&r1=334021&r2=334022&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCParser/MCAsmParserUtils.h (original)
+++ llvm/trunk/include/llvm/MC/MCParser/MCAsmParserUtils.h Tue Jun 5 08:13:39 2018
@@ -25,7 +25,7 @@ namespace MCParserUtils {
/// On success, returns false and sets the Symbol and Value output parameters.
bool parseAssignmentExpression(StringRef Name, bool allow_redef,
MCAsmParser &Parser, MCSymbol *&Symbol,
- const MCExpr *&Value);
+ const MCExpr *&Value, bool AllowExtendedExpr = false);
} // namespace MCParserUtils
Modified: llvm/trunk/include/llvm/MC/MCParser/MCTargetAsmParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCParser/MCTargetAsmParser.h?rev=334022&r1=334021&r2=334022&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCParser/MCTargetAsmParser.h (original)
+++ llvm/trunk/include/llvm/MC/MCParser/MCTargetAsmParser.h Tue Jun 5 08:13:39 2018
@@ -371,6 +371,11 @@ public:
SemaCallback = Callback;
}
+ // Target-specific parsing of assembler-level variable assignment.
+ virtual bool parseAssignmentExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+ return getParser().parseExpression(Res, EndLoc);
+ }
+
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=334022&r1=334021&r2=334022&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Tue Jun 5 08:13:39 2018
@@ -548,12 +548,19 @@ void MCAsmStreamer::EmitThumbFunc(MCSymb
}
void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
- OS << ".set ";
- Symbol->print(OS, MAI);
- OS << ", ";
- Value->print(OS, MAI);
+ // Do not emit a .set on inlined target assignments.
+ bool EmitSet = true;
+ if (auto *E = dyn_cast<MCTargetExpr>(Value))
+ if (E->inlineAssignedExpr())
+ EmitSet = false;
+ if (EmitSet) {
+ OS << ".set ";
+ Symbol->print(OS, MAI);
+ OS << ", ";
+ Value->print(OS, MAI);
- EmitEOL();
+ EmitEOL();
+ }
MCStreamer::EmitAssignment(Symbol, Value);
}
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=334022&r1=334021&r2=334022&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Jun 5 08:13:39 2018
@@ -334,7 +334,7 @@ private:
StringRef parseStringToComma();
bool parseAssignment(StringRef Name, bool allow_redef,
- bool NoDeadStrip = false);
+ bool NoDeadStrip = false, bool AllowExtendedExpr = false);
unsigned getBinOpPrecedence(AsmToken::TokenKind K,
MCBinaryExpr::Opcode &Kind);
@@ -1113,13 +1113,17 @@ bool AsmParser::parsePrimaryExpr(const M
// If this is an absolute variable reference, substitute it now to preserve
// semantics in the face of reassignment.
- if (Sym->isVariable() &&
- isa<MCConstantExpr>(Sym->getVariableValue(/*SetUsed*/ false))) {
- if (Variant)
- return Error(EndLoc, "unexpected modifier on variable reference");
-
- Res = Sym->getVariableValue(/*SetUsed*/ false);
- return false;
+ if (Sym->isVariable()) {
+ auto V = Sym->getVariableValue(/*SetUsed*/ false);
+ bool DoInline = isa<MCConstantExpr>(V);
+ if (auto TV = dyn_cast<MCTargetExpr>(V))
+ DoInline = TV->inlineAssignedExpr();
+ if (DoInline) {
+ if (Variant)
+ return Error(EndLoc, "unexpected modifier on variable reference");
+ Res = Sym->getVariableValue(/*SetUsed*/ false);
+ return false;
+ }
}
// Otherwise create a symbol ref.
@@ -1814,7 +1818,7 @@ bool AsmParser::parseStatement(ParseStat
// identifier '=' ... -> assignment statement
Lex();
- return parseAssignment(IDVal, true);
+ return parseAssignment(IDVal, true, /*NoDeadStrip*/ false, /*AllowExtendedExpr*/true);
default: // Normal instruction or directive.
break;
@@ -2750,11 +2754,11 @@ void AsmParser::handleMacroExit() {
}
bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
- bool NoDeadStrip) {
+ bool NoDeadStrip, bool AllowExtendedExpr) {
MCSymbol *Sym;
const MCExpr *Value;
if (MCParserUtils::parseAssignmentExpression(Name, allow_redef, *this, Sym,
- Value))
+ Value, AllowExtendedExpr))
return true;
if (!Sym) {
@@ -5791,14 +5795,17 @@ static bool isSymbolUsedInExpression(con
bool parseAssignmentExpression(StringRef Name, bool allow_redef,
MCAsmParser &Parser, MCSymbol *&Sym,
- const MCExpr *&Value) {
+ const MCExpr *&Value, bool AllowExtendedExpr) {
// FIXME: Use better location, we should use proper tokens.
SMLoc EqualLoc = Parser.getTok().getLoc();
-
- if (Parser.parseExpression(Value)) {
- return Parser.TokError("missing expression");
- }
+ SMLoc EndLoc;
+ if (AllowExtendedExpr) {
+ if (Parser.getTargetParser().parseAssignmentExpression(Value, EndLoc)) {
+ return Parser.TokError("missing expression");
+ }
+ } else if (Parser.parseExpression(Value, EndLoc))
+ return Parser.TokError("missing expression");
// Note: we don't count b as used in "a = b". This is to allow
// a = b
Modified: llvm/trunk/lib/MC/MCParser/MCAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/MCAsmParser.cpp?rev=334022&r1=334021&r2=334022&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/MCAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/MCAsmParser.cpp Tue Jun 5 08:13:39 2018
@@ -86,7 +86,6 @@ bool MCAsmParser::TokError(const Twine &
}
bool MCAsmParser::Error(SMLoc L, const Twine &Msg, SMRange Range) {
- HadError = true;
MCPendingError PErr;
PErr.Loc = L;
Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=334022&r1=334021&r2=334022&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue Jun 5 08:13:39 2018
@@ -9,6 +9,7 @@
#include "InstPrinter/X86IntelInstPrinter.h"
#include "MCTargetDesc/X86BaseInfo.h"
+#include "MCTargetDesc/X86MCExpr.h"
#include "MCTargetDesc/X86TargetStreamer.h"
#include "X86AsmInstrumentation.h"
#include "X86AsmParserCommon.h"
@@ -953,6 +954,8 @@ public:
void SetFrameRegister(unsigned RegNo) override;
+ bool parseAssignmentExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
+
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override;
@@ -2018,6 +2021,9 @@ std::unique_ptr<X86Operand> X86AsmParser
if (getLexer().isNot(AsmToken::LParen)) {
SMLoc ExprEnd;
if (getParser().parseExpression(Disp, ExprEnd)) return nullptr;
+ // Disp may be a variable, handle register values.
+ if (auto *RE = dyn_cast<X86MCExpr>(Disp))
+ return X86Operand::CreateReg(RE->getRegNo(), MemStart, ExprEnd);
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
@@ -2182,6 +2188,25 @@ std::unique_ptr<X86Operand> X86AsmParser
return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
}
+// Parse either a standard expression or a register.
+bool X86AsmParser::parseAssignmentExpression(const MCExpr *&Res,
+ SMLoc &EndLoc) {
+ MCAsmParser &Parser = getParser();
+ if (Parser.parseExpression(Res, EndLoc)) {
+ SMLoc StartLoc = Parser.getTok().getLoc();
+ // Normal Expression parse fails, check if it could be a register.
+ unsigned RegNo;
+ if (Parser.getTargetParser().ParseRegister(RegNo, StartLoc, EndLoc))
+ return true;
+ // Clear previous parse error and return correct expression.
+ Parser.clearPendingErrors();
+ Res = X86MCExpr::create(RegNo, Parser.getContext());
+ return false;
+ }
+
+ return false;
+}
+
bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) {
MCAsmParser &Parser = getParser();
Added: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCExpr.h?rev=334022&view=auto
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCExpr.h (added)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCExpr.h Tue Jun 5 08:13:39 2018
@@ -0,0 +1,75 @@
+//=--- X86MCExpr.h - X86 specific MC expression classes ---*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes X86-specific MCExprs, i.e, registers used for
+// extended variable assignments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_X86_MCTARGETDESC_X86MCEXPR_H
+#define LLVM_LIB_TARGET_X86_MCTARGETDESC_X86MCEXPR_H
+
+#include "InstPrinter/X86ATTInstPrinter.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+class X86MCExpr : public MCTargetExpr {
+
+private:
+ const int64_t RegNo; // All
+
+ explicit X86MCExpr(int64_t R) : RegNo(R) {}
+
+public:
+ /// @name Construction
+ /// @{
+
+ static const X86MCExpr *create(int64_t RegNo, MCContext &Ctx) {
+ return new (Ctx) X86MCExpr(RegNo);
+ }
+
+ /// @}
+ /// @name Accessors
+ /// @{
+
+ /// getSubExpr - Get the child of this expression.
+ int64_t getRegNo() const { return RegNo; }
+
+ /// @}
+
+ void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override {
+ if (MAI->getAssemblerDialect() == 0)
+ OS << '%';
+ OS << X86ATTInstPrinter::getRegisterName(RegNo);
+ }
+
+ bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const override {
+ return false;
+ }
+ // Register values should be inlined as they are not valid .set expressions.
+ bool inlineAssignedExpr() const override { return true; }
+ void visitUsedExpr(MCStreamer &Streamer) const override{};
+ MCFragment *findAssociatedFragment() const override { return nullptr; }
+
+ // There are no TLS X86MCExprs at the moment.
+ void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Target;
+ }
+};
+
+} // end namespace llvm
+
+#endif
Added: llvm/trunk/test/MC/X86/pr37425.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/pr37425.s?rev=334022&view=auto
==============================================================================
--- llvm/trunk/test/MC/X86/pr37425.s (added)
+++ llvm/trunk/test/MC/X86/pr37425.s Tue Jun 5 08:13:39 2018
@@ -0,0 +1,16 @@
+// RUN: llvm-mc -triple x86_64-unknown-unknown -defsym=ERR=0 %s -o - | FileCheck %s
+// RUN: not llvm-mc -triple x86_64-unknown-unknown -defsym=ERR=1 %s -o - 2>&1 | FileCheck --check-prefix=ERR %s
+
+// CHECK-NOT: .set var_xdata
+var_xdata = %rcx
+
+// CHECK: xorq %rcx, %rcx
+xorq var_xdata, var_xdata
+
+.if (ERR==1)
+// ERR: [[@LINE+2]]:15: error: unknown token in expression in '.set' directive
+// ERR: [[@LINE+1]]:15: error: missing expression in '.set' directive
+.set err_var, %rcx
+.endif
+
+
More information about the llvm-commits
mailing list