[llvm] r298425 - [X86][MS-compatability][llvm] allow MS TYPE/SIZE/LENGTH operators as a part of a compound expression
Coby Tayree via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 21 12:31:56 PDT 2017
Author: coby
Date: Tue Mar 21 14:31:55 2017
New Revision: 298425
URL: http://llvm.org/viewvc/llvm-project?rev=298425&view=rev
Log:
[X86][MS-compatability][llvm] allow MS TYPE/SIZE/LENGTH operators as a part of a compound expression
This patch introduces X86AsmParser with the ability to handle the aforementioned ops within compound "MS" arithmetical expressions.
Currently - only supported as a stand alone Operand, e.g.:
"TYPE X"
now allowed :
"4 + TYPE X * 128"
Clang side: https://reviews.llvm.org/D31174
Differential Revision: https://reviews.llvm.org/D31173
Modified:
llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
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=298425&r1=298424&r2=298425&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue Mar 21 14:31:55 2017
@@ -98,6 +98,14 @@ private:
IC_REGISTER
};
+ enum IntelOperatorKind {
+ IOK_INVALID = 0,
+ IOK_LENGTH,
+ IOK_SIZE,
+ IOK_TYPE,
+ IOK_OFFSET
+ };
+
class InfixCalculator {
typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
@@ -704,7 +712,8 @@ private:
std::unique_ptr<X86Operand> ParseIntelOperand();
std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
- std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
+ unsigned IdentifyIntelOperator(StringRef Name);
+ unsigned ParseIntelOperator(unsigned OpKind);
std::unique_ptr<X86Operand>
ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
@@ -814,6 +823,7 @@ private:
/// }
public:
+
X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
const MCInstrInfo &mii, const MCTargetOptions &Options)
: MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr),
@@ -1266,10 +1276,12 @@ RewriteIntelBracExpression(SmallVectorIm
}
}
// Remove all the ImmPrefix rewrites within the brackets.
+ // We may have some Imm rewrties as a result of an operator applying,
+ // remove them as well
for (AsmRewrite &AR : AsmRewrites) {
if (AR.Loc.getPointer() < StartInBrac.getPointer())
continue;
- if (AR.Kind == AOK_ImmPrefix)
+ if (AR.Kind == AOK_ImmPrefix || AR.Kind == AOK_Imm)
AR.Kind = AOK_Delete;
}
const char *SymLocPtr = SymName.data();
@@ -1324,31 +1336,34 @@ bool X86AsmParser::ParseIntelExpression(
const MCExpr *Val;
SMLoc IdentLoc = Tok.getLoc();
StringRef Identifier = Tok.getString();
+ UpdateLocLex = false;
if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
SM.onRegister(TmpReg);
- UpdateLocLex = false;
- break;
+ } else if (!isParsingInlineAsm()) {
+ if (getParser().parsePrimaryExpr(Val, End))
+ return Error(Tok.getLoc(), "Unexpected identifier!");
+ SM.onIdentifierExpr(Val, Identifier);
+ } else if (unsigned OpKind = IdentifyIntelOperator(Identifier)) {
+ if (OpKind == IOK_OFFSET)
+ return Error(IdentLoc, "Dealing OFFSET operator as part of"
+ "a compound immediate expression is yet to be supported");
+ int64_t Val = ParseIntelOperator(OpKind);
+ if (!Val)
+ return true;
+ StringRef ErrMsg;
+ if (SM.onInteger(Val, ErrMsg))
+ return Error(IdentLoc, ErrMsg);
+ } else if (Identifier.find('.') != StringRef::npos &&
+ PrevTK == AsmToken::RBrac) {
+ return false;
} else {
- if (!isParsingInlineAsm()) {
- if (getParser().parsePrimaryExpr(Val, End))
- return Error(Tok.getLoc(), "Unexpected identifier!");
- } else {
- // This is a dot operator, not an adjacent identifier.
- if (Identifier.find('.') != StringRef::npos &&
- PrevTK == AsmToken::RBrac) {
- return false;
- } else {
- InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
- if (ParseIntelIdentifier(Val, Identifier, Info,
- /*Unevaluated=*/false, End))
- return true;
- }
- }
+ InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
+ if (ParseIntelIdentifier(Val, Identifier, Info,
+ /*Unevaluated=*/false, End))
+ return true;
SM.onIdentifierExpr(Val, Identifier);
- UpdateLocLex = false;
- break;
}
- return Error(Tok.getLoc(), "Unexpected identifier!");
+ break;
}
case AsmToken::Integer: {
StringRef ErrMsg;
@@ -1715,11 +1730,16 @@ std::unique_ptr<X86Operand> X86AsmParser
OffsetOfLoc, Identifier, Info.OpDecl);
}
-enum IntelOperatorKind {
- IOK_LENGTH,
- IOK_SIZE,
- IOK_TYPE
-};
+// Query a candidate string for being an Intel assembly operator
+// Report back its kind, or IOK_INVALID if does not evaluated as a known one
+unsigned X86AsmParser::IdentifyIntelOperator(StringRef Name) {
+ return StringSwitch<unsigned>(Name)
+ .Cases("TYPE","type",IOK_TYPE)
+ .Cases("SIZE","size",IOK_SIZE)
+ .Cases("LENGTH","length",IOK_LENGTH)
+ .Cases("OFFSET","offset",IOK_OFFSET)
+ .Default(IOK_INVALID);
+}
/// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
/// returns the number of elements in an array. It returns the value 1 for
@@ -1727,7 +1747,7 @@ enum IntelOperatorKind {
/// variable. A variable's size is the product of its LENGTH and TYPE. The
/// TYPE operator returns the size of a C or C++ type or variable. If the
/// variable is an array, TYPE returns the size of a single element.
-std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
+unsigned X86AsmParser::ParseIntelOperator(unsigned OpKind) {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
SMLoc TypeLoc = Tok.getLoc();
@@ -1739,11 +1759,13 @@ std::unique_ptr<X86Operand> X86AsmParser
StringRef Identifier = Tok.getString();
if (ParseIntelIdentifier(Val, Identifier, Info,
/*Unevaluated=*/true, End))
- return nullptr;
-
- if (!Info.OpDecl)
- return ErrorOperand(Start, "unable to lookup expression");
+ return 0;
+ if (!Info.OpDecl) {
+ Error(Start, "unable to lookup expression");
+ return 0;
+ }
+
unsigned CVal = 0;
switch(OpKind) {
default: llvm_unreachable("Unexpected operand kind!");
@@ -1757,8 +1779,7 @@ std::unique_ptr<X86Operand> X86AsmParser
unsigned Len = End.getPointer() - TypeLoc.getPointer();
InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
- const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
- return X86Operand::CreateImm(Imm, Start, End);
+ return CVal;
}
std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
@@ -1766,18 +1787,12 @@ std::unique_ptr<X86Operand> X86AsmParser
const AsmToken &Tok = Parser.getTok();
SMLoc Start, End;
- // Offset, length, type and size operators.
- if (isParsingInlineAsm()) {
- StringRef AsmTokStr = Tok.getString();
- if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
+ // FIXME: Offset operator
+ // Should be handled as part of immediate expression, as other operators
+ // Currently, only supported as a stand-alone operand
+ if (isParsingInlineAsm())
+ if (IdentifyIntelOperator(Tok.getString()) == IOK_OFFSET)
return ParseIntelOffsetOfOperator();
- if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
- return ParseIntelOperator(IOK_LENGTH);
- if (AsmTokStr == "size" || AsmTokStr == "SIZE")
- return ParseIntelOperator(IOK_SIZE);
- if (AsmTokStr == "type" || AsmTokStr == "TYPE")
- return ParseIntelOperator(IOK_TYPE);
- }
bool PtrInOperand = false;
unsigned Size = getIntelMemOperandSize(Tok.getString());
More information about the llvm-commits
mailing list