llvm.org GIT mirror llvm / 1e509dc
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298425 91177308-0d34-0410-b5e6-96231b3b80d8 Coby Tayree 3 years ago
1 changed file(s) with 62 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
9595 IC_LPAREN,
9696 IC_IMM,
9797 IC_REGISTER
98 };
99
100 enum IntelOperatorKind {
101 IOK_INVALID = 0,
102 IOK_LENGTH,
103 IOK_SIZE,
104 IOK_TYPE,
105 IOK_OFFSET
98106 };
99107
100108 class InfixCalculator {
703711 std::unique_ptr ParseIntelOperand();
704712 std::unique_ptr ParseIntelOffsetOfOperator();
705713 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
706 std::unique_ptr ParseIntelOperator(unsigned OpKind);
714 unsigned IdentifyIntelOperator(StringRef Name);
715 unsigned ParseIntelOperator(unsigned OpKind);
707716 std::unique_ptr
708717 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
709718 std::unique_ptr ParseRoundingModeOp(SMLoc Start, SMLoc End);
813822 /// }
814823
815824 public:
825
816826 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
817827 const MCInstrInfo &mii, const MCTargetOptions &Options)
818828 : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr),
12651275 }
12661276 }
12671277 // Remove all the ImmPrefix rewrites within the brackets.
1278 // We may have some Imm rewrties as a result of an operator applying,
1279 // remove them as well
12681280 for (AsmRewrite &AR : AsmRewrites) {
12691281 if (AR.Loc.getPointer() < StartInBrac.getPointer())
12701282 continue;
1271 if (AR.Kind == AOK_ImmPrefix)
1283 if (AR.Kind == AOK_ImmPrefix || AR.Kind == AOK_Imm)
12721284 AR.Kind = AOK_Delete;
12731285 }
12741286 const char *SymLocPtr = SymName.data();
13231335 const MCExpr *Val;
13241336 SMLoc IdentLoc = Tok.getLoc();
13251337 StringRef Identifier = Tok.getString();
1338 UpdateLocLex = false;
13261339 if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
13271340 SM.onRegister(TmpReg);
1328 UpdateLocLex = false;
1329 break;
1341 } else if (!isParsingInlineAsm()) {
1342 if (getParser().parsePrimaryExpr(Val, End))
1343 return Error(Tok.getLoc(), "Unexpected identifier!");
1344 SM.onIdentifierExpr(Val, Identifier);
1345 } else if (unsigned OpKind = IdentifyIntelOperator(Identifier)) {
1346 if (OpKind == IOK_OFFSET)
1347 return Error(IdentLoc, "Dealing OFFSET operator as part of"
1348 "a compound immediate expression is yet to be supported");
1349 int64_t Val = ParseIntelOperator(OpKind);
1350 if (!Val)
1351 return true;
1352 StringRef ErrMsg;
1353 if (SM.onInteger(Val, ErrMsg))
1354 return Error(IdentLoc, ErrMsg);
1355 } else if (Identifier.find('.') != StringRef::npos &&
1356 PrevTK == AsmToken::RBrac) {
1357 return false;
13301358 } else {
1331 if (!isParsingInlineAsm()) {
1332 if (getParser().parsePrimaryExpr(Val, End))
1333 return Error(Tok.getLoc(), "Unexpected identifier!");
1334 } else {
1335 // This is a dot operator, not an adjacent identifier.
1336 if (Identifier.find('.') != StringRef::npos &&
1337 PrevTK == AsmToken::RBrac) {
1338 return false;
1339 } else {
1340 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1341 if (ParseIntelIdentifier(Val, Identifier, Info,
1342 /*Unevaluated=*/false, End))
1343 return true;
1344 }
1345 }
1359 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
1360 if (ParseIntelIdentifier(Val, Identifier, Info,
1361 /*Unevaluated=*/false, End))
1362 return true;
13461363 SM.onIdentifierExpr(Val, Identifier);
1347 UpdateLocLex = false;
1348 break;
1349 }
1350 return Error(Tok.getLoc(), "Unexpected identifier!");
1364 }
1365 break;
13511366 }
13521367 case AsmToken::Integer: {
13531368 StringRef ErrMsg;
17141729 OffsetOfLoc, Identifier, Info.OpDecl);
17151730 }
17161731
1717 enum IntelOperatorKind {
1718 IOK_LENGTH,
1719 IOK_SIZE,
1720 IOK_TYPE
1721 };
1732 // Query a candidate string for being an Intel assembly operator
1733 // Report back its kind, or IOK_INVALID if does not evaluated as a known one
1734 unsigned X86AsmParser::IdentifyIntelOperator(StringRef Name) {
1735 return StringSwitch(Name)
1736 .Cases("TYPE","type",IOK_TYPE)
1737 .Cases("SIZE","size",IOK_SIZE)
1738 .Cases("LENGTH","length",IOK_LENGTH)
1739 .Cases("OFFSET","offset",IOK_OFFSET)
1740 .Default(IOK_INVALID);
1741 }
17221742
17231743 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
17241744 /// returns the number of elements in an array. It returns the value 1 for
17261746 /// variable. A variable's size is the product of its LENGTH and TYPE. The
17271747 /// TYPE operator returns the size of a C or C++ type or variable. If the
17281748 /// variable is an array, TYPE returns the size of a single element.
1729 std::unique_ptr X86AsmParser::ParseIntelOperator(unsigned OpKind) {
1749 unsigned X86AsmParser::ParseIntelOperator(unsigned OpKind) {
17301750 MCAsmParser &Parser = getParser();
17311751 const AsmToken &Tok = Parser.getTok();
17321752 SMLoc TypeLoc = Tok.getLoc();
17381758 StringRef Identifier = Tok.getString();
17391759 if (ParseIntelIdentifier(Val, Identifier, Info,
17401760 /*Unevaluated=*/true, End))
1741 return nullptr;
1742
1743 if (!Info.OpDecl)
1744 return ErrorOperand(Start, "unable to lookup expression");
1745
1761 return 0;
1762
1763 if (!Info.OpDecl) {
1764 Error(Start, "unable to lookup expression");
1765 return 0;
1766 }
1767
17461768 unsigned CVal = 0;
17471769 switch(OpKind) {
17481770 default: llvm_unreachable("Unexpected operand kind!");
17561778 unsigned Len = End.getPointer() - TypeLoc.getPointer();
17571779 InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
17581780
1759 const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
1760 return X86Operand::CreateImm(Imm, Start, End);
1781 return CVal;
17611782 }
17621783
17631784 std::unique_ptr X86AsmParser::ParseIntelOperand() {
17651786 const AsmToken &Tok = Parser.getTok();
17661787 SMLoc Start, End;
17671788
1768 // Offset, length, type and size operators.
1769 if (isParsingInlineAsm()) {
1770 StringRef AsmTokStr = Tok.getString();
1771 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1789 // FIXME: Offset operator
1790 // Should be handled as part of immediate expression, as other operators
1791 // Currently, only supported as a stand-alone operand
1792 if (isParsingInlineAsm())
1793 if (IdentifyIntelOperator(Tok.getString()) == IOK_OFFSET)
17721794 return ParseIntelOffsetOfOperator();
1773 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1774 return ParseIntelOperator(IOK_LENGTH);
1775 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1776 return ParseIntelOperator(IOK_SIZE);
1777 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1778 return ParseIntelOperator(IOK_TYPE);
1779 }
17801795
17811796 bool PtrInOperand = false;
17821797 unsigned Size = getIntelMemOperandSize(Tok.getString());