forked from OSchip/llvm-project
parent
583ec6fa44
commit
9a2d4e04c7
|
@ -293,47 +293,22 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Helper method for \see EvaluateSymbolAdd().
|
/// \brief Helper method for \see EvaluateSymbolAdd().
|
||||||
static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
|
static void AttemptToFoldSymbolOffsetDifference(const MCAsmLayout *Layout,
|
||||||
const MCAsmLayout *Layout,
|
|
||||||
const SectionAddrMap *Addrs,
|
|
||||||
bool InSet,
|
|
||||||
const MCSymbolRefExpr *&A,
|
const MCSymbolRefExpr *&A,
|
||||||
const MCSymbolRefExpr *&B,
|
const MCSymbolRefExpr *&B,
|
||||||
int64_t &Addend) {
|
int64_t &Addend) {
|
||||||
if (!A || !B ||
|
const MCAssembler &Asm = Layout->getAssembler();
|
||||||
!Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
|
|
||||||
return;
|
|
||||||
|
|
||||||
MCSymbolData &AD = Asm->getSymbolData(A->getSymbol());
|
if (A && B &&
|
||||||
MCSymbolData &BD = Asm->getSymbolData(B->getSymbol());
|
Asm.getWriter().IsSymbolRefDifferenceFullyResolved(Asm, A, B, false)) {
|
||||||
|
// Eagerly evaluate.
|
||||||
if (AD.getFragment() == BD.getFragment()) {
|
Addend += (Layout->getSymbolOffset(&Asm.getSymbolData(A->getSymbol())) -
|
||||||
Addend += (AD.getOffset() - BD.getOffset());
|
Layout->getSymbolOffset(&Asm.getSymbolData(B->getSymbol())));
|
||||||
|
|
||||||
// Clear the symbol expr pointers to indicate we have folded these
|
// Clear the symbol expr pointers to indicate we have folded these
|
||||||
// operands.
|
// operands.
|
||||||
A = B = 0;
|
A = B = 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Layout)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const MCSectionData &SecA = *AD.getFragment()->getParent();
|
|
||||||
const MCSectionData &SecB = *BD.getFragment()->getParent();
|
|
||||||
|
|
||||||
if ((&SecA != &SecB) && !Addrs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Eagerly evaluate.
|
|
||||||
Addend += (Layout->getSymbolOffset(&Asm->getSymbolData(A->getSymbol())) -
|
|
||||||
Layout->getSymbolOffset(&Asm->getSymbolData(B->getSymbol())));
|
|
||||||
if (Addrs && (&SecA != &SecB))
|
|
||||||
Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB));
|
|
||||||
|
|
||||||
// Clear the symbol expr pointers to indicate we have folded these
|
|
||||||
// operands.
|
|
||||||
A = B = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Evaluate the result of an add between (conceptually) two MCValues.
|
/// \brief Evaluate the result of an add between (conceptually) two MCValues.
|
||||||
|
@ -371,11 +346,8 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
|
||||||
// Fold the result constant immediately.
|
// Fold the result constant immediately.
|
||||||
int64_t Result_Cst = LHS_Cst + RHS_Cst;
|
int64_t Result_Cst = LHS_Cst + RHS_Cst;
|
||||||
|
|
||||||
assert((!Layout || Asm) &&
|
|
||||||
"Must have an assembler object if layout is given!");
|
|
||||||
|
|
||||||
// If we have a layout, we can fold resolved differences.
|
// If we have a layout, we can fold resolved differences.
|
||||||
if (Asm) {
|
if (Layout) {
|
||||||
// First, fold out any differences which are fully resolved. By
|
// First, fold out any differences which are fully resolved. By
|
||||||
// reassociating terms in
|
// reassociating terms in
|
||||||
// Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
|
// Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).
|
||||||
|
@ -386,14 +358,10 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
|
||||||
// (RHS_A - RHS_B).
|
// (RHS_A - RHS_B).
|
||||||
// Since we are attempting to be as aggresive as possible about folding, we
|
// Since we are attempting to be as aggresive as possible about folding, we
|
||||||
// attempt to evaluate each possible alternative.
|
// attempt to evaluate each possible alternative.
|
||||||
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, LHS_B,
|
AttemptToFoldSymbolOffsetDifference(Layout, LHS_A, LHS_B, Result_Cst);
|
||||||
Result_Cst);
|
AttemptToFoldSymbolOffsetDifference(Layout, LHS_A, RHS_B, Result_Cst);
|
||||||
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, LHS_A, RHS_B,
|
AttemptToFoldSymbolOffsetDifference(Layout, RHS_A, LHS_B, Result_Cst);
|
||||||
Result_Cst);
|
AttemptToFoldSymbolOffsetDifference(Layout, RHS_A, RHS_B, Result_Cst);
|
||||||
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, LHS_B,
|
|
||||||
Result_Cst);
|
|
||||||
AttemptToFoldSymbolOffsetDifference(Asm, Layout, Addrs, InSet, RHS_A, RHS_B,
|
|
||||||
Result_Cst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can't represent the addition or subtraction of two symbols.
|
// We can't represent the addition or subtraction of two symbols.
|
||||||
|
@ -410,6 +378,44 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
|
||||||
if (B && !A)
|
if (B && !A)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Absolutize symbol differences between defined symbols when we have a
|
||||||
|
// layout object and the target requests it.
|
||||||
|
|
||||||
|
assert((!Layout || Asm) &&
|
||||||
|
"Must have an assembler object if layout is given!");
|
||||||
|
|
||||||
|
if (Asm && A && B) {
|
||||||
|
if (A->getSymbol().isDefined() && B->getSymbol().isDefined() &&
|
||||||
|
Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B,
|
||||||
|
InSet)) {
|
||||||
|
MCSymbolData &AD = Asm->getSymbolData(A->getSymbol());
|
||||||
|
MCSymbolData &BD = Asm->getSymbolData(B->getSymbol());
|
||||||
|
|
||||||
|
if (AD.getFragment() == BD.getFragment()) {
|
||||||
|
Res = MCValue::get(+ AD.getOffset()
|
||||||
|
- BD.getOffset()
|
||||||
|
+ Result_Cst);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Layout) {
|
||||||
|
const MCSectionData &SecA = *AD.getFragment()->getParent();
|
||||||
|
const MCSectionData &SecB = *BD.getFragment()->getParent();
|
||||||
|
int64_t Val = + Layout->getSymbolOffset(&AD)
|
||||||
|
- Layout->getSymbolOffset(&BD)
|
||||||
|
+ Result_Cst;
|
||||||
|
if (&SecA != &SecB) {
|
||||||
|
if (!Addrs)
|
||||||
|
return false;
|
||||||
|
Val += Addrs->lookup(&SecA);
|
||||||
|
Val -= Addrs->lookup(&SecB);
|
||||||
|
}
|
||||||
|
Res = MCValue::get(Val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Res = MCValue::get(A, B, Result_Cst);
|
Res = MCValue::get(A, B, Result_Cst);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue