Index: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -98,6 +98,14 @@ 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 InfixOperatorStack; @@ -704,7 +712,8 @@ std::unique_ptr ParseIntelOperand(); std::unique_ptr ParseIntelOffsetOfOperator(); bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp); - std::unique_ptr ParseIntelOperator(unsigned OpKind); + unsigned IdentifyIntelOperator(StringRef Name); + unsigned ParseIntelOperator(unsigned OpKind); std::unique_ptr ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size); std::unique_ptr ParseRoundingModeOp(SMLoc Start, SMLoc End); @@ -814,6 +823,7 @@ /// } public: + X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser, const MCInstrInfo &mii, const MCTargetOptions &Options) : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr), @@ -1266,10 +1276,12 @@ } } // 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 @@ 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 @@ 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(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 @@ /// 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 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 @@ 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 @@ 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 X86AsmParser::ParseIntelOperand() { @@ -1766,18 +1787,12 @@ 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());