llvm.org GIT mirror llvm / 0e6a15a
Revert r276895 "[MC][X86] Fix Intel Operand assembly parsing for .set ids" This caused PR28805. Adding a regression test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277402 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 4 years ago
4 changed file(s) with 135 addition(s) and 97 deletion(s). Raw diff Collapse all Expand all
697697 std::unique_ptr ParseIntelOperator(unsigned OpKind);
698698 std::unique_ptr
699699 ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
700 std::unique_ptr
701 ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc, unsigned Size);
700702 std::unique_ptr ParseRoundingModeOp(SMLoc Start, SMLoc End);
701703 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
702 std::unique_ptr
703 ParseIntelBracExpression(unsigned SegReg, SMLoc Start, int64_t ImmDisp,
704 bool isSymbol, unsigned Size);
704 std::unique_ptr ParseIntelBracExpression(unsigned SegReg,
705 SMLoc Start,
706 int64_t ImmDisp,
707 unsigned Size);
705708 bool ParseIntelIdentifier(const MCExpr *&Val, StringRef &Identifier,
706709 InlineAsmIdentifierInfo &Info,
707710 bool IsUnevaluatedOperand, SMLoc &End);
13821385
13831386 std::unique_ptr
13841387 X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1385 int64_t ImmDisp, bool isSymbol,
1386 unsigned Size) {
1388 int64_t ImmDisp, unsigned Size) {
13871389 MCAsmParser &Parser = getParser();
13881390 const AsmToken &Tok = Parser.getTok();
13891391 SMLoc BracLoc = Tok.getLoc(), End = Tok.getEndLoc();
14331435 Disp = NewDisp;
14341436 }
14351437
1436 if (isSymbol) {
1437 if (SM.getSym()) {
1438 Error(Start, "cannot use more than one symbol in memory operand");
1439 return nullptr;
1440 }
1441 if (SM.getBaseReg()) {
1442 Error(Start, "cannot use base register with variable reference");
1443 return nullptr;
1444 }
1445 if (SM.getIndexReg()) {
1446 Error(Start, "cannot use index register with variable reference");
1447 return nullptr;
1448 }
1449 }
1450
14511438 int BaseReg = SM.getBaseReg();
14521439 int IndexReg = SM.getIndexReg();
14531440 int Scale = SM.getScale();
15531540 }
15541541
15551542 if (getLexer().is(AsmToken::LBrac))
1556 return ParseIntelBracExpression(SegReg, Start, ImmDisp, false, Size);
1543 return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
15571544
15581545 const MCExpr *Val;
15591546 SMLoc End;
16101597 }
16111598 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
16121599 }
1600 /// ParseIntelMemOperand - Parse intel style memory operand.
1601 std::unique_ptr X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp,
1602 SMLoc Start,
1603 unsigned Size) {
1604 MCAsmParser &Parser = getParser();
1605 const AsmToken &Tok = Parser.getTok();
1606 SMLoc End;
1607
1608 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1609 if (getLexer().is(AsmToken::LBrac))
1610 return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
1611 assert(ImmDisp == 0);
1612
1613 const MCExpr *Val;
1614 if (!isParsingInlineAsm()) {
1615 if (getParser().parsePrimaryExpr(Val, End))
1616 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
1617
1618 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
1619 }
1620
1621 InlineAsmIdentifierInfo Info;
1622 StringRef Identifier = Tok.getString();
1623 if (ParseIntelIdentifier(Val, Identifier, Info,
1624 /*Unevaluated=*/false, End))
1625 return nullptr;
1626
1627 if (!getLexer().is(AsmToken::LBrac))
1628 return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
1629 /*Scale=*/1, Start, End, Size, Identifier, Info);
1630
1631 Parser.Lex(); // Eat '['
1632
1633 // Parse Identifier [ ImmDisp ]
1634 IntelExprStateMachine SM(/*ImmDisp=*/0, /*StopOnLBrac=*/true,
1635 /*AddImmPrefix=*/false);
1636 if (ParseIntelExpression(SM, End))
1637 return nullptr;
1638
1639 if (SM.getSym()) {
1640 Error(Start, "cannot use more than one symbol in memory operand");
1641 return nullptr;
1642 }
1643 if (SM.getBaseReg()) {
1644 Error(Start, "cannot use base register with variable reference");
1645 return nullptr;
1646 }
1647 if (SM.getIndexReg()) {
1648 Error(Start, "cannot use index register with variable reference");
1649 return nullptr;
1650 }
1651
1652 const MCExpr *Disp = MCConstantExpr::create(SM.getImm(), getContext());
1653 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1654 // we're pointing to a local variable in memory, so the base register is
1655 // really the frame or stack pointer.
1656 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1657 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1658 Start, End, Size, Identifier, Info.OpDecl);
1659 }
16131660
16141661 /// Parse the '.' operator.
16151662 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
17561803 Parser.Lex(); // Eat ptr.
17571804 PtrInOperand = true;
17581805 }
1759
17601806 Start = Tok.getLoc();
1807
1808 // Immediate.
1809 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
1810 getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {
1811 AsmToken StartTok = Tok;
1812 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1813 /*AddImmPrefix=*/false);
1814 if (ParseIntelExpression(SM, End))
1815 return nullptr;
1816
1817 int64_t Imm = SM.getImm();
1818 if (isParsingInlineAsm()) {
1819 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1820 if (StartTok.getString().size() == Len)
1821 // Just add a prefix if this wasn't a complex immediate expression.
1822 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
1823 else
1824 // Otherwise, rewrite the complex expression as a single immediate.
1825 InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
1826 }
1827
1828 if (getLexer().isNot(AsmToken::LBrac)) {
1829 // If a directional label (ie. 1f or 2b) was parsed above from
1830 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1831 // to the MCExpr with the directional local symbol and this is a
1832 // memory operand not an immediate operand.
1833 if (SM.getSym())
1834 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1835 Size);
1836
1837 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1838 return X86Operand::CreateImm(ImmExpr, Start, End);
1839 }
1840
1841 // Only positive immediates are valid.
1842 if (Imm < 0)
1843 return ErrorOperand(Start, "expected a positive immediate displacement "
1844 "before bracketed expr.");
1845
1846 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1847 return ParseIntelMemOperand(Imm, Start, Size);
1848 }
17611849
17621850 // rounding mode token
17631851 if (getSTI().getFeatureBits()[X86::FeatureAVX512] &&
17661854
17671855 // Register.
17681856 unsigned RegNo = 0;
1769 if (getLexer().is(AsmToken::Identifier) &&
1770 !ParseRegister(RegNo, Start, End)) {
1857 if (!ParseRegister(RegNo, Start, End)) {
17711858 // If this is a segment register followed by a ':', then this is the start
17721859 // of a segment override, otherwise this is a normal register reference.
17731860 // In case it is a normal register and there is ptr in the operand this
17791866 }
17801867 return X86Operand::CreateReg(RegNo, Start, End);
17811868 }
1869
17821870 return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
17831871 }
17841872
1785 // Immediates and Memory
1786
1787 // Parse [ BaseReg + Scale*IndexReg + Disp ].
1788 if (getLexer().is(AsmToken::LBrac))
1789 return ParseIntelBracExpression(/*SegReg=*/0, Start, /*ImmDisp=*/0, false,
1790 Size);
1791
1792 AsmToken StartTok = Tok;
1793 IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,
1794 /*AddImmPrefix=*/false);
1795 if (ParseIntelExpression(SM, End))
1796 return nullptr;
1797
1798 bool isSymbol = SM.getSym() && SM.getSym()->getKind() != MCExpr::Constant;
1799 int64_t Imm = SM.getImm();
1800 if (SM.getSym() && SM.getSym()->getKind() == MCExpr::Constant)
1801 SM.getSym()->evaluateAsAbsolute(Imm);
1802
1803 if (StartTok.isNot(AsmToken::Identifier) &&
1804 StartTok.isNot(AsmToken::String) && isParsingInlineAsm()) {
1805 unsigned Len = Tok.getLoc().getPointer() - Start.getPointer();
1806 if (StartTok.getString().size() == Len)
1807 // Just add a prefix if this wasn't a complex immediate expression.
1808 InstInfo->AsmRewrites->emplace_back(AOK_ImmPrefix, Start);
1809 else
1810 // Otherwise, rewrite the complex expression as a single immediate.
1811 InstInfo->AsmRewrites->emplace_back(AOK_Imm, Start, Len, Imm);
1812 }
1813
1814 if (getLexer().isNot(AsmToken::LBrac)) {
1815 // If a directional label (ie. 1f or 2b) was parsed above from
1816 // ParseIntelExpression() then SM.getSym() was set to a pointer to
1817 // to the MCExpr with the directional local symbol and this is a
1818 // memory operand not an immediate operand.
1819 if (isSymbol) {
1820 if (isParsingInlineAsm())
1821 return CreateMemForInlineAsm(/*SegReg=*/0, SM.getSym(), /*BaseReg=*/0,
1822 /*IndexReg=*/0,
1823 /*Scale=*/1, Start, End, Size,
1824 SM.getSymName(), SM.getIdentifierInfo());
1825 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1826 Size);
1827 }
1828
1829 const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext());
1830 return X86Operand::CreateImm(ImmExpr, Start, End);
1831 }
1832
1833 // Only positive immediates are valid.
1834 if (Imm < 0)
1835 return ErrorOperand(Start, "expected a positive immediate displacement "
1836 "before bracketed expr.");
1837
1838 return ParseIntelBracExpression(/*SegReg=*/0, Start, Imm, isSymbol, Size);
1873 // Memory operand.
1874 return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
18391875 }
18401876
18411877 std::unique_ptr X86AsmParser::ParseATTOperand() {
18791915 SMLoc Start = Parser.getTok().getLoc(), End;
18801916 if (getSTI().getFeatureBits()[X86::FeatureAVX512])
18811917 return ParseRoundingModeOp(Start, End);
1882 return ErrorOperand(Start, "Unexpected '{' in expression");
1918 return ErrorOperand(Start, "unknown token in expression");
18831919 }
18841920 }
18851921 }
0 ; RUN: llc %s -o - | FileCheck %s
1
2 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-pc-windows-msvc18.0.31101"
4
5 define i32 @_xbegin() {
6 entry:
7 %res = alloca i32, align 4
8 %0 = bitcast i32* %res to i8*
9 store i32 -1, i32* %res, align 4
10 call void asm sideeffect inteldialect ".byte 0xC7\0A\09.byte 0xF8\0A\09.byte 2\0A\09.byte 0\0A\09.byte 0\0A\09.byte 0\0A\09jmp .L__MSASMLABEL_.0__L2\0A\09mov dword ptr $0, eax\0A\09.L__MSASMLABEL_.0__L2:", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* nonnull %res)
11 %1 = load i32, i32* %res, align 4
12 ret i32 %1
13 }
14
15 ; CHECK-NOT: Error parsing inline asm
16
17 ; CHECK-LABEL: _xbegin:
18 ; CHECK: jmp .L__MSASMLABEL_.0__L2
19 ; CHECK: .L__MSASMLABEL_.0__L2:
7575 // CHECK: encoding: [0xca,0x08,0x00]
7676 retf 8
7777
78 .set FOO, 2
79 cmp eax, FOO
80 // CHECK: encoding: [0x83,0xf8,0x02]
81 cmp eax, FOO[eax]
82 // CHECK: encoding: [0x67,0x3b,0x40,0x02]
1010 .att_syntax noprefix
1111 // CHECK: error: '.att_syntax noprefix' is not supported: registers must have a '%' prefix in .att_syntax
1212 movl $257, -4(esp)
13
14
15 .intel_syntax noprefix
16
17 .global arr
18 .global i
19 .set FOO, 2
20 //CHECK-STDERR: error: cannot use base register with variable reference
21 mov eax, DWORD PTR arr[ebp + 1 + (2 * 5) - 3 + 1<<1]
22 //CHECK-STDERR: error: cannot use index register with variable reference
23 mov eax, DWORD PTR arr[esi*4]
24 //CHECK-STDERR: error: cannot use more than one symbol in memory operand
25 mov eax, DWORD PTR arr[i]