@@ -1544,24 +1544,58 @@ bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
1544
1544
Operands.push_back (PPCOperand::CreateFromMCExpr (EVal, S, E, isPPC64 ()));
1545
1545
1546
1546
// Check whether this is a TLS call expression
1547
- bool TLSCall = false ;
1548
- if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal))
1549
- TLSCall = Ref->getSymbol ().getName () == " __tls_get_addr" ;
1547
+ const char TlsGetAddr[] = " __tls_get_addr" ;
1548
+ bool TlsCall = false ;
1549
+ const MCExpr *TlsCallAddend = nullptr ;
1550
+ if (auto *Ref = dyn_cast<MCSymbolRefExpr>(EVal)) {
1551
+ TlsCall = Ref->getSymbol ().getName () == TlsGetAddr;
1552
+ } else if (auto *Bin = dyn_cast<MCBinaryExpr>(EVal);
1553
+ Bin && Bin->getOpcode () == MCBinaryExpr::Add) {
1554
+ if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Bin->getLHS ())) {
1555
+ TlsCall = Ref->getSymbol ().getName () == TlsGetAddr;
1556
+ TlsCallAddend = Bin->getRHS ();
1557
+ }
1558
+ }
1550
1559
1551
- if (TLSCall && parseOptionalToken (AsmToken::LParen)) {
1560
+ if (TlsCall && parseOptionalToken (AsmToken::LParen)) {
1552
1561
const MCExpr *TLSSym;
1553
- S = Parser.getTok ().getLoc ();
1562
+ const SMLoc S2 = Parser.getTok ().getLoc ();
1554
1563
if (ParseExpression (TLSSym))
1555
- return Error (S, " invalid TLS call expression" );
1564
+ return Error (S2, " invalid TLS call expression" );
1565
+ E = Parser.getTok ().getLoc ();
1556
1566
if (parseToken (AsmToken::RParen, " expected ')'" ))
1557
1567
return true ;
1558
- E = Parser.getTok ().getLoc ();
1568
+ // PPC32 allows bl __tls_get_addr[+a](x@tlsgd)@plt+b. Parse "@plt[+b]".
1569
+ if (!isPPC64 () && parseOptionalToken (AsmToken::At)) {
1570
+ AsmToken Tok = getTok ();
1571
+ if (!(parseOptionalToken (AsmToken::Identifier) &&
1572
+ Tok.getString ().compare_insensitive (" plt" ) == 0 ))
1573
+ return Error (Tok.getLoc (), " expected 'plt'" );
1574
+ EVal = MCSymbolRefExpr::create (TlsGetAddr, MCSymbolRefExpr::VK_PLT,
1575
+ getContext ());
1576
+ if (parseOptionalToken (AsmToken::Plus)) {
1577
+ const MCExpr *Addend = nullptr ;
1578
+ SMLoc EndLoc;
1579
+ if (parsePrimaryExpr (Addend, EndLoc))
1580
+ return true ;
1581
+ if (TlsCallAddend) // __tls_get_addr+a(x@tlsgd)@plt+b
1582
+ TlsCallAddend =
1583
+ MCBinaryExpr::createAdd (TlsCallAddend, Addend, getContext ());
1584
+ else // __tls_get_addr(x@tlsgd)@plt+b
1585
+ TlsCallAddend = Addend;
1586
+ }
1587
+ if (TlsCallAddend)
1588
+ EVal = MCBinaryExpr::createAdd (EVal, TlsCallAddend, getContext ());
1589
+ // Add a __tls_get_addr operand with addend a, b, or a+b.
1590
+ Operands.back () = PPCOperand::CreateFromMCExpr (
1591
+ EVal, S, Parser.getTok ().getLoc (), false );
1592
+ }
1559
1593
1560
1594
Operands.push_back (PPCOperand::CreateFromMCExpr (TLSSym, S, E, isPPC64 ()));
1561
1595
}
1562
1596
1563
1597
// Otherwise, check for D-form memory operands
1564
- if (!TLSCall && parseOptionalToken (AsmToken::LParen)) {
1598
+ if (!TlsCall && parseOptionalToken (AsmToken::LParen)) {
1565
1599
S = Parser.getTok ().getLoc ();
1566
1600
1567
1601
int64_t IntVal;
0 commit comments