@@ -698,14 +698,11 @@ class X86AsmParser : public MCTargetAsmParser {
698
698
std::unique_ptr<X86Operand> ParseIntelOperator (unsigned OpKind);
699
699
std::unique_ptr<X86Operand>
700
700
ParseIntelSegmentOverride (unsigned SegReg, SMLoc Start, unsigned Size );
701
- std::unique_ptr<X86Operand>
702
- ParseIntelMemOperand (int64_t ImmDisp, SMLoc StartLoc, unsigned Size );
703
701
std::unique_ptr<X86Operand> ParseRoundingModeOp (SMLoc Start, SMLoc End);
704
702
bool ParseIntelExpression (IntelExprStateMachine &SM, SMLoc &End);
705
- std::unique_ptr<X86Operand> ParseIntelBracExpression (unsigned SegReg,
706
- SMLoc Start,
707
- int64_t ImmDisp,
708
- unsigned Size );
703
+ std::unique_ptr<X86Operand>
704
+ ParseIntelBracExpression (unsigned SegReg, SMLoc Start, int64_t ImmDisp,
705
+ bool isSymbol, unsigned Size );
709
706
bool ParseIntelIdentifier (const MCExpr *&Val, StringRef &Identifier,
710
707
InlineAsmIdentifierInfo &Info,
711
708
bool IsUnevaluatedOperand, SMLoc &End);
@@ -1271,7 +1268,7 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1271
1268
1272
1269
// The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
1273
1270
// identifier. Don't try an parse it as a register.
1274
- if (Tok.getString ().startswith (" ." ))
1271
+ if (PrevTK != AsmToken::Error && Tok.getString ().startswith (" ." ))
1275
1272
break ;
1276
1273
1277
1274
// If we're parsing an immediate expression, we don't expect a '['.
@@ -1386,7 +1383,8 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1386
1383
1387
1384
std::unique_ptr<X86Operand>
1388
1385
X86AsmParser::ParseIntelBracExpression (unsigned SegReg, SMLoc Start,
1389
- int64_t ImmDisp, unsigned Size ) {
1386
+ int64_t ImmDisp, bool isSymbol,
1387
+ unsigned Size ) {
1390
1388
MCAsmParser &Parser = getParser ();
1391
1389
const AsmToken &Tok = Parser.getTok ();
1392
1390
SMLoc BracLoc = Tok.getLoc (), End = Tok.getEndLoc ();
@@ -1436,6 +1434,21 @@ X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
1436
1434
Disp = NewDisp;
1437
1435
}
1438
1436
1437
+ if (isSymbol) {
1438
+ if (SM.getSym ()) {
1439
+ Error (Start, " cannot use more than one symbol in memory operand" );
1440
+ return nullptr ;
1441
+ }
1442
+ if (SM.getBaseReg ()) {
1443
+ Error (Start, " cannot use base register with variable reference" );
1444
+ return nullptr ;
1445
+ }
1446
+ if (SM.getIndexReg ()) {
1447
+ Error (Start, " cannot use index register with variable reference" );
1448
+ return nullptr ;
1449
+ }
1450
+ }
1451
+
1439
1452
int BaseReg = SM.getBaseReg ();
1440
1453
int IndexReg = SM.getIndexReg ();
1441
1454
int Scale = SM.getScale ();
@@ -1541,7 +1554,7 @@ X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start,
1541
1554
}
1542
1555
1543
1556
if (getLexer ().is (AsmToken::LBrac))
1544
- return ParseIntelBracExpression (SegReg, Start, ImmDisp, Size );
1557
+ return ParseIntelBracExpression (SegReg, Start, ImmDisp, false , Size );
1545
1558
1546
1559
const MCExpr *Val;
1547
1560
SMLoc End;
@@ -1598,66 +1611,6 @@ X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) {
1598
1611
}
1599
1612
return ErrorOperand (Tok.getLoc (), " unknown token in expression" );
1600
1613
}
1601
- // / ParseIntelMemOperand - Parse intel style memory operand.
1602
- std::unique_ptr<X86Operand> X86AsmParser::ParseIntelMemOperand (int64_t ImmDisp,
1603
- SMLoc Start,
1604
- unsigned Size ) {
1605
- MCAsmParser &Parser = getParser ();
1606
- const AsmToken &Tok = Parser.getTok ();
1607
- SMLoc End;
1608
-
1609
- // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1610
- if (getLexer ().is (AsmToken::LBrac))
1611
- return ParseIntelBracExpression (/* SegReg=*/ 0 , Start, ImmDisp, Size );
1612
- assert (ImmDisp == 0 );
1613
-
1614
- const MCExpr *Val;
1615
- if (!isParsingInlineAsm ()) {
1616
- if (getParser ().parsePrimaryExpr (Val, End))
1617
- return ErrorOperand (Tok.getLoc (), " unknown token in expression" );
1618
-
1619
- return X86Operand::CreateMem (getPointerWidth (), Val, Start, End, Size );
1620
- }
1621
-
1622
- InlineAsmIdentifierInfo Info;
1623
- StringRef Identifier = Tok.getString ();
1624
- if (ParseIntelIdentifier (Val, Identifier, Info,
1625
- /* Unevaluated=*/ false , End))
1626
- return nullptr ;
1627
-
1628
- if (!getLexer ().is (AsmToken::LBrac))
1629
- return CreateMemForInlineAsm (/* SegReg=*/ 0 , Val, /* BaseReg=*/ 0 , /* IndexReg=*/ 0 ,
1630
- /* Scale=*/ 1 , Start, End, Size , Identifier, Info);
1631
-
1632
- Parser.Lex (); // Eat '['
1633
-
1634
- // Parse Identifier [ ImmDisp ]
1635
- IntelExprStateMachine SM (/* ImmDisp=*/ 0 , /* StopOnLBrac=*/ true ,
1636
- /* AddImmPrefix=*/ false );
1637
- if (ParseIntelExpression (SM, End))
1638
- return nullptr ;
1639
-
1640
- if (SM.getSym ()) {
1641
- Error (Start, " cannot use more than one symbol in memory operand" );
1642
- return nullptr ;
1643
- }
1644
- if (SM.getBaseReg ()) {
1645
- Error (Start, " cannot use base register with variable reference" );
1646
- return nullptr ;
1647
- }
1648
- if (SM.getIndexReg ()) {
1649
- Error (Start, " cannot use index register with variable reference" );
1650
- return nullptr ;
1651
- }
1652
-
1653
- const MCExpr *Disp = MCConstantExpr::create (SM.getImm (), getContext ());
1654
- // BaseReg is non-zero to avoid assertions. In the context of inline asm,
1655
- // we're pointing to a local variable in memory, so the base register is
1656
- // really the frame or stack pointer.
1657
- return X86Operand::CreateMem (getPointerWidth (), /* SegReg=*/ 0 , Disp,
1658
- /* BaseReg=*/ 1 , /* IndexReg=*/ 0 , /* Scale=*/ 1 ,
1659
- Start, End, Size , Identifier, Info.OpDecl );
1660
- }
1661
1614
1662
1615
// / Parse the '.' operator.
1663
1616
bool X86AsmParser::ParseIntelDotOperator (const MCExpr *Disp,
@@ -1804,49 +1757,8 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1804
1757
Parser.Lex (); // Eat ptr.
1805
1758
PtrInOperand = true ;
1806
1759
}
1807
- Start = Tok.getLoc ();
1808
-
1809
- // Immediate.
1810
- if (getLexer ().is (AsmToken::Integer) || getLexer ().is (AsmToken::Minus) ||
1811
- getLexer ().is (AsmToken::Tilde) || getLexer ().is (AsmToken::LParen)) {
1812
- AsmToken StartTok = Tok;
1813
- IntelExprStateMachine SM (/* Imm=*/ 0 , /* StopOnLBrac=*/ true ,
1814
- /* AddImmPrefix=*/ false );
1815
- if (ParseIntelExpression (SM, End))
1816
- return nullptr ;
1817
-
1818
- int64_t Imm = SM.getImm ();
1819
- if (isParsingInlineAsm ()) {
1820
- unsigned Len = Tok.getLoc ().getPointer () - Start.getPointer ();
1821
- if (StartTok.getString ().size () == Len)
1822
- // Just add a prefix if this wasn't a complex immediate expression.
1823
- InstInfo->AsmRewrites ->emplace_back (AOK_ImmPrefix, Start);
1824
- else
1825
- // Otherwise, rewrite the complex expression as a single immediate.
1826
- InstInfo->AsmRewrites ->emplace_back (AOK_Imm, Start, Len, Imm);
1827
- }
1828
-
1829
- if (getLexer ().isNot (AsmToken::LBrac)) {
1830
- // If a directional label (ie. 1f or 2b) was parsed above from
1831
- // ParseIntelExpression() then SM.getSym() was set to a pointer to
1832
- // to the MCExpr with the directional local symbol and this is a
1833
- // memory operand not an immediate operand.
1834
- if (SM.getSym ())
1835
- return X86Operand::CreateMem (getPointerWidth (), SM.getSym (), Start, End,
1836
- Size );
1837
-
1838
- const MCExpr *ImmExpr = MCConstantExpr::create (Imm, getContext ());
1839
- return X86Operand::CreateImm (ImmExpr, Start, End);
1840
- }
1841
-
1842
- // Only positive immediates are valid.
1843
- if (Imm < 0 )
1844
- return ErrorOperand (Start, " expected a positive immediate displacement "
1845
- " before bracketed expr." );
1846
1760
1847
- // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1848
- return ParseIntelMemOperand (Imm, Start, Size );
1849
- }
1761
+ Start = Tok.getLoc ();
1850
1762
1851
1763
// rounding mode token
1852
1764
if (getSTI ().getFeatureBits ()[X86::FeatureAVX512] &&
@@ -1855,7 +1767,8 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1855
1767
1856
1768
// Register.
1857
1769
unsigned RegNo = 0 ;
1858
- if (!ParseRegister (RegNo, Start, End)) {
1770
+ if (getLexer ().is (AsmToken::Identifier) &&
1771
+ !ParseRegister (RegNo, Start, End)) {
1859
1772
// If this is a segment register followed by a ':', then this is the start
1860
1773
// of a segment override, otherwise this is a normal register reference.
1861
1774
// In case it is a normal register and there is ptr in the operand this
@@ -1867,12 +1780,63 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
1867
1780
}
1868
1781
return X86Operand::CreateReg (RegNo, Start, End);
1869
1782
}
1870
-
1871
1783
return ParseIntelSegmentOverride (/* SegReg=*/ RegNo, Start, Size );
1872
1784
}
1873
1785
1874
- // Memory operand.
1875
- return ParseIntelMemOperand (/* Disp=*/ 0 , Start, Size );
1786
+ // Immediates and Memory
1787
+
1788
+ // Parse [ BaseReg + Scale*IndexReg + Disp ].
1789
+ if (getLexer ().is (AsmToken::LBrac))
1790
+ return ParseIntelBracExpression (/* SegReg=*/ 0 , Start, /* ImmDisp=*/ 0 , false ,
1791
+ Size );
1792
+
1793
+ AsmToken StartTok = Tok;
1794
+ IntelExprStateMachine SM (/* Imm=*/ 0 , /* StopOnLBrac=*/ true ,
1795
+ /* AddImmPrefix=*/ false );
1796
+ if (ParseIntelExpression (SM, End))
1797
+ return nullptr ;
1798
+
1799
+ bool isSymbol = SM.getSym () && SM.getSym ()->getKind () != MCExpr::Constant;
1800
+ int64_t Imm = SM.getImm ();
1801
+ if (SM.getSym () && SM.getSym ()->getKind () == MCExpr::Constant)
1802
+ SM.getSym ()->evaluateAsAbsolute (Imm);
1803
+
1804
+ if (StartTok.isNot (AsmToken::Identifier) &&
1805
+ StartTok.isNot (AsmToken::String) && isParsingInlineAsm ()) {
1806
+ unsigned Len = Tok.getLoc ().getPointer () - Start.getPointer ();
1807
+ if (StartTok.getString ().size () == Len)
1808
+ // Just add a prefix if this wasn't a complex immediate expression.
1809
+ InstInfo->AsmRewrites ->emplace_back (AOK_ImmPrefix, Start);
1810
+ else
1811
+ // Otherwise, rewrite the complex expression as a single immediate.
1812
+ InstInfo->AsmRewrites ->emplace_back (AOK_Imm, Start, Len, Imm);
1813
+ }
1814
+
1815
+ if (getLexer ().isNot (AsmToken::LBrac)) {
1816
+ // If a directional label (ie. 1f or 2b) was parsed above from
1817
+ // ParseIntelExpression() then SM.getSym() was set to a pointer to
1818
+ // to the MCExpr with the directional local symbol and this is a
1819
+ // memory operand not an immediate operand.
1820
+ if (isSymbol) {
1821
+ if (isParsingInlineAsm ())
1822
+ return CreateMemForInlineAsm (/* SegReg=*/ 0 , SM.getSym (), /* BaseReg=*/ 0 ,
1823
+ /* IndexReg=*/ 0 ,
1824
+ /* Scale=*/ 1 , Start, End, Size ,
1825
+ SM.getSymName (), SM.getIdentifierInfo ());
1826
+ return X86Operand::CreateMem (getPointerWidth (), SM.getSym (), Start, End,
1827
+ Size );
1828
+ }
1829
+
1830
+ const MCExpr *ImmExpr = MCConstantExpr::create (Imm, getContext ());
1831
+ return X86Operand::CreateImm (ImmExpr, Start, End);
1832
+ }
1833
+
1834
+ // Only positive immediates are valid.
1835
+ if (Imm < 0 )
1836
+ return ErrorOperand (Start, " expected a positive immediate displacement "
1837
+ " before bracketed expr." );
1838
+
1839
+ return ParseIntelBracExpression (/* SegReg=*/ 0 , Start, Imm, isSymbol, Size );
1876
1840
}
1877
1841
1878
1842
std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand () {
@@ -1916,7 +1880,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
1916
1880
SMLoc Start = Parser.getTok ().getLoc (), End;
1917
1881
if (getSTI ().getFeatureBits ()[X86::FeatureAVX512])
1918
1882
return ParseRoundingModeOp (Start, End);
1919
- return ErrorOperand (Start, " unknown token in expression" );
1883
+ return ErrorOperand (Start, " Unexpected '{' in expression" );
1920
1884
}
1921
1885
}
1922
1886
}
0 commit comments