std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
unsigned IdentifyIntelOperator(StringRef Name);
- unsigned ParseIntelOperator(unsigned OpKind);
+ unsigned ParseIntelOperator(unsigned OpKind, bool AddImmPrefix);
std::unique_ptr<X86Operand>
ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
InlineAsmIdentifierInfo &Info, bool AllowBetterSizeMatch) {
// If we found a decl other than a VarDecl, then assume it is a FuncDecl or
// some other label reference.
- if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
+ if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.isVarDecl()) {
// Insert an explicit size if the user didn't have one.
if (!Size) {
Size = getPointerWidth();
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);
+ int64_t Val = ParseIntelOperator(OpKind,SM.getAddImmPrefix());
if (!Val)
return true;
StringRef ErrMsg;
PrevTK == AsmToken::RBrac) {
return false;
} else {
- InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
- if (ParseIntelIdentifier(Val, Identifier, Info,
+ InlineAsmIdentifierInfo Info;
+ if (ParseIntelIdentifier(Val, Identifier, Info,\r
/*Unevaluated=*/false, End))
- return true;
- SM.onIdentifierExpr(Val, Identifier);
+ return true;\r
+ // Check if the parsed identifier was a constant Integer. Here we\r
+ // assume Val is of type MCConstantExpr only when it is safe to replace\r
+ // the identifier with its constant value.\r
+ if (const MCConstantExpr *CE =\r
+ dyn_cast_or_null<const MCConstantExpr>(Val)) {\r
+ StringRef ErrMsg;\r
+ // Pass the enum identifier integer value to the SM calculator.\r
+ if (SM.onInteger(CE->getValue(), ErrMsg))\r
+ return Error(IdentLoc, ErrMsg);\r
+ // Match the behavior of integer tokens when getAddImmPrefix flag is\r
+ // set.\r
+ if (SM.getAddImmPrefix()) {\r
+ assert(isParsingInlineAsm() &&\r
+ "Expected to be parsing inline assembly.");\r
+ // A single rewrite of the integer value is preformed for each enum\r
+ // identifier. This is only done when we are inside a bracketed\r
+ // expression.\r
+ size_t Len = End.getPointer() - IdentLoc.getPointer();\r
+ InstInfo->AsmRewrites->emplace_back(AOK_Imm, IdentLoc, Len,\r
+ CE->getValue());\r
+ break;\r
+ }\r
+ } else {\r
+ // Notify the SM a variable identifier was found.\r
+ InlineAsmIdentifierInfo &SMInfo = SM.getIdentifierInfo();\r
+ SMInfo = Info;\r
+ SM.onIdentifierExpr(Val, Identifier);\r
+ }\r
}
break;
}
assert((End.getPointer() == EndPtr || !Result) &&
"frontend claimed part of a token?");
+ // Check if the search yielded a constant integer (enum identifier).
+ if (Result && Info.isConstEnum()) {
+ // By creating MCConstantExpr we let the user of Val know it is safe
+ // to use as an explicit constant with value = ConstVal.
+ Val = MCConstantExpr::create(Info.ConstIntValue.getSExtValue(),
+ getParser().getContext());
+ return false;
+ }
// If the identifier lookup was unsuccessful, assume that we are dealing with
// a label.
if (!Result) {
/// 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.
-unsigned X86AsmParser::ParseIntelOperator(unsigned OpKind) {
+unsigned X86AsmParser::ParseIntelOperator(unsigned OpKind, bool AddImmPrefix) {
MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
SMLoc TypeLoc = Tok.getLoc();
case IOK_SIZE: CVal = Info.Size; break;
case IOK_TYPE: CVal = Info.Type; break;
}
-
- // Rewrite the type operator and the C or C++ type or variable in terms of an
- // immediate. E.g. TYPE foo -> $$4
- unsigned Len = End.getPointer() - TypeLoc.getPointer();
- InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
-
+
+ // Only when in bracketed mode, preform explicit rewrite. This is requierd to
+ // avoid rewrite collision.
+ if (AddImmPrefix) {
+ // Rewrite the type operator and the C or C++ type or variable in terms of
+ // an immediate. e.g. mov eax, [eax + SIZE _foo * $$4] ->
+ // mov eax, [eax + $$1 * $$4].
+ unsigned Len = End.getPointer() - TypeLoc.getPointer();
+ InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
+ }
+
return CVal;
}
if (SM.getSym() && SM.getSym()->getKind() == MCExpr::Constant)
SM.getSym()->evaluateAsAbsolute(Imm);
- if (StartTok.isNot(AsmToken::Identifier) &&
- StartTok.isNot(AsmToken::String) && isParsingInlineAsm()) {
+ if (isParsingInlineAsm() && !isSymbol) {
unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
- if (StartTok.getString().size() == Len)
- // Just add a prefix if this wasn't a complex immediate expression.
- InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
- else
- // Otherwise, rewrite the complex expression as a single immediate.
InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
}