@@ -295,19 +295,18 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
295
295
}
296
296
297
297
// / Helper method for \see EvaluateSymbolAdd().
298
- static void AttemptToFoldSymbolOffsetDifference (
299
- const MCAssembler *Asm, const SectionAddrMap *Addrs, bool InSet,
300
- const MCSymbolRefExpr *&A, const MCSymbolRefExpr *&B, int64_t &Addend) {
298
+ static void attemptToFoldSymbolOffsetDifference (const MCAssembler *Asm,
299
+ const SectionAddrMap *Addrs,
300
+ bool InSet, const MCSymbol *&A,
301
+ const MCSymbol *&B,
302
+ int64_t &Addend) {
301
303
if (!A || !B)
302
304
return ;
303
305
304
- const MCSymbol &SA = A->getSymbol ();
305
- const MCSymbol &SB = B->getSymbol ();
306
-
306
+ const MCSymbol &SA = *A, &SB = *B;
307
307
if (SA.isUndefined () || SB.isUndefined ())
308
308
return ;
309
-
310
- if (!Asm->getWriter ().isSymbolRefDifferenceFullyResolved (*Asm, A, B, InSet))
309
+ if (!Asm->getWriter ().isSymbolRefDifferenceFullyResolved (*Asm, SA, SB, InSet))
311
310
return ;
312
311
313
312
auto FinalizeFolding = [&]() {
@@ -345,8 +344,7 @@ static void AttemptToFoldSymbolOffsetDifference(
345
344
}
346
345
347
346
// Eagerly evaluate when layout is finalized.
348
- Addend += Asm->getSymbolOffset (A->getSymbol ()) -
349
- Asm->getSymbolOffset (B->getSymbol ());
347
+ Addend += Asm->getSymbolOffset (SA) - Asm->getSymbolOffset (SB);
350
348
if (Addrs && (&SecA != &SecB))
351
349
Addend += (Addrs->lookup (&SecA) - Addrs->lookup (&SecB));
352
350
@@ -420,65 +418,52 @@ static void AttemptToFoldSymbolOffsetDifference(
420
418
}
421
419
}
422
420
423
- // / Evaluate the result of an add between (conceptually) two MCValues.
424
- // /
425
- // / This routine conceptually attempts to construct an MCValue:
426
- // / Result = (Result_A - Result_B + Result_Cst)
427
- // / from two MCValue's LHS and RHS where
428
- // / Result = LHS + RHS
429
- // / and
430
- // / Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
431
- // /
432
- // / This routine attempts to aggressively fold the operands such that the result
433
- // / is representable in an MCValue, but may not always succeed.
434
- // /
435
- // / \returns True on success, false if the result is not representable in an
436
- // / MCValue.
437
-
438
- // / NOTE: It is really important to have both the Asm and Layout arguments.
439
- // / They might look redundant, but this function can be used before layout
440
- // / is done (see the object streamer for example) and having the Asm argument
441
- // / lets us avoid relaxations early.
421
+ // Evaluate the sum of two relocatable expressions.
422
+ //
423
+ // Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
424
+ //
425
+ // This routine attempts to aggressively fold the operands such that the result
426
+ // is representable in an MCValue, but may not always succeed.
427
+ //
428
+ // LHS_A and RHS_A might have relocation specifiers while LHS_B and RHS_B
429
+ // cannot have specifiers.
430
+ //
431
+ // \returns True on success, false if the result is not representable in an
432
+ // MCValue.
433
+
434
+ // NOTE: This function can be used before layout is done (see the object
435
+ // streamer for example) and having the Asm argument lets us avoid relaxations
436
+ // early.
442
437
static bool evaluateSymbolicAdd (const MCAssembler *Asm,
443
438
const SectionAddrMap *Addrs, bool InSet,
444
- const MCValue &LHS, const MCValue &RHS,
439
+ const MCValue &LHS,
440
+ const MCSymbolRefExpr *RhsAdd,
441
+ const MCSymbolRefExpr *RhsSub, int64_t RHS_Cst,
445
442
MCValue &Res) {
446
- // FIXME: This routine (and other evaluation parts) are *incredibly* sloppy
447
- // about dealing with modifiers. This will ultimately bite us, one day.
448
- const MCSymbolRefExpr *LHS_A = LHS.getSymA ();
449
- const MCSymbolRefExpr *LHS_B = LHS.getSymB ();
443
+ const MCSymbol *LHS_A = LHS.getAddSym ();
444
+ const MCSymbol *LHS_B = LHS.getSubSym ();
450
445
int64_t LHS_Cst = LHS.getConstant ();
451
446
452
- const MCSymbolRefExpr *RHS_A = RHS.getSymA ();
453
- const MCSymbolRefExpr *RHS_B = RHS.getSymB ();
454
- int64_t RHS_Cst = RHS.getConstant ();
455
-
456
- if (LHS.getRefKind () != RHS.getRefKind ())
457
- return false ;
447
+ const MCSymbol *RHS_A = RhsAdd ? &RhsAdd->getSymbol () : nullptr ;
448
+ const MCSymbol *RHS_B = RhsSub ? &RhsSub->getSymbol () : nullptr ;
458
449
459
450
// Fold the result constant immediately.
460
451
int64_t Result_Cst = LHS_Cst + RHS_Cst;
461
452
462
453
// If we have a layout, we can fold resolved differences.
463
454
if (Asm) {
464
- // First, fold out any differences which are fully resolved. By
465
- // reassociating terms in
455
+ // While LHS_A-LHS_B and RHS_A-RHS_B from recursive calls have already been
456
+ // folded, reassociating terms in
466
457
// Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
467
- // we have the four possible differences:
468
- // (LHS_A - LHS_B),
469
- // (LHS_A - RHS_B),
470
- // (RHS_A - LHS_B),
471
- // (RHS_A - RHS_B).
472
- // Since we are attempting to be as aggressive as possible about folding, we
473
- // attempt to evaluate each possible alternative.
474
- AttemptToFoldSymbolOffsetDifference (Asm, Addrs, InSet, LHS_A, LHS_B,
475
- Result_Cst);
476
- AttemptToFoldSymbolOffsetDifference (Asm, Addrs, InSet, LHS_A, RHS_B,
477
- Result_Cst);
478
- AttemptToFoldSymbolOffsetDifference (Asm, Addrs, InSet, RHS_A, LHS_B,
479
- Result_Cst);
480
- AttemptToFoldSymbolOffsetDifference (Asm, Addrs, InSet, RHS_A, RHS_B,
481
- Result_Cst);
458
+ // might bring more opportunities.
459
+ if (LHS_A && RHS_B && !LHS.getSymA ()->getSpecifier ()) {
460
+ attemptToFoldSymbolOffsetDifference (Asm, Addrs, InSet, LHS_A, RHS_B,
461
+ Result_Cst);
462
+ }
463
+ if (RHS_A && LHS_B && !RhsAdd->getSpecifier ()) {
464
+ attemptToFoldSymbolOffsetDifference (Asm, Addrs, InSet, RHS_A, LHS_B,
465
+ Result_Cst);
466
+ }
482
467
}
483
468
484
469
// We can't represent the addition or subtraction of two symbols.
@@ -487,9 +472,10 @@ static bool evaluateSymbolicAdd(const MCAssembler *Asm,
487
472
488
473
// At this point, we have at most one additive symbol and one subtractive
489
474
// symbol -- find them.
490
- const MCSymbolRefExpr *A = LHS_A ? LHS_A : RHS_A;
491
- const MCSymbolRefExpr *B = LHS_B ? LHS_B : RHS_B;
492
-
475
+ auto *A = LHS_A ? LHS.getSymA () : RHS_A ? RhsAdd : nullptr ;
476
+ auto *B = LHS_B ? LHS.getSymB () : RHS_B ? RhsSub : nullptr ;
477
+ if (B && B->getKind () != MCSymbolRefExpr::VK_None)
478
+ return false ;
493
479
Res = MCValue::get (A, B, Result_Cst);
494
480
return true ;
495
481
}
@@ -641,31 +627,40 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
641
627
642
628
// We only support a few operations on non-constant expressions, handle
643
629
// those first.
630
+ auto Op = ABE->getOpcode ();
631
+ int64_t LHS = LHSValue.getConstant (), RHS = RHSValue.getConstant ();
644
632
if (!LHSValue.isAbsolute () || !RHSValue.isAbsolute ()) {
645
- switch (ABE-> getOpcode () ) {
633
+ switch (Op ) {
646
634
default :
647
635
return false ;
648
- case MCBinaryExpr::Sub:
649
- // Negate RHS and add.
650
- // The cast avoids undefined behavior if the constant is INT64_MIN.
651
- return evaluateSymbolicAdd (
652
- Asm, Addrs, InSet, LHSValue,
653
- MCValue::get (RHSValue.getSymB (), RHSValue.getSymA (),
654
- -(uint64_t )RHSValue.getConstant (),
655
- RHSValue.getRefKind ()),
656
- Res);
657
-
658
636
case MCBinaryExpr::Add:
659
- return evaluateSymbolicAdd (Asm, Addrs, InSet, LHSValue, RHSValue, Res);
637
+ case MCBinaryExpr::Sub:
638
+ // TODO: Prevent folding for AArch64 @AUTH operands.
639
+ if (LHSValue.getSpecifier () || RHSValue.getSpecifier ())
640
+ return false ;
641
+ if (Op == MCBinaryExpr::Sub) {
642
+ std::swap (RHSValue.SymA , RHSValue.SymB );
643
+ RHSValue.Cst = -(uint64_t )RHSValue.Cst ;
644
+ }
645
+ if (RHSValue.isAbsolute ()) {
646
+ LHSValue.Cst += RHSValue.Cst ;
647
+ Res = LHSValue;
648
+ return true ;
649
+ }
650
+ if (LHSValue.isAbsolute ()) {
651
+ RHSValue.Cst += LHSValue.Cst ;
652
+ Res = RHSValue;
653
+ return true ;
654
+ }
655
+ return evaluateSymbolicAdd (Asm, Addrs, InSet, LHSValue, RHSValue.SymA ,
656
+ RHSValue.SymB , RHSValue.Cst , Res);
660
657
}
661
658
}
662
659
663
660
// FIXME: We need target hooks for the evaluation. It may be limited in
664
661
// width, and gas defines the result of comparisons differently from
665
662
// Apple as.
666
- int64_t LHS = LHSValue.getConstant (), RHS = RHSValue.getConstant ();
667
663
int64_t Result = 0 ;
668
- auto Op = ABE->getOpcode ();
669
664
switch (Op) {
670
665
case MCBinaryExpr::AShr: Result = LHS >> RHS; break ;
671
666
case MCBinaryExpr::Add: Result = LHS + RHS; break ;
0 commit comments