diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 | 
| commit | 5a5ac124e1efaf208671f01c46edb15f29ed2a0b (patch) | |
| tree | a6140557876943cdd800ee997c9317283394b22c /lib/MC/MCExpr.cpp | |
| parent | f03b5bed27d0d2eafd68562ce14f8b5e3f1f0801 (diff) | |
Notes
Diffstat (limited to 'lib/MC/MCExpr.cpp')
| -rw-r--r-- | lib/MC/MCExpr.cpp | 162 | 
1 files changed, 86 insertions, 76 deletions
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 709dc6b413e47..7f048d7b3d9d8 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -89,6 +89,7 @@ void MCExpr::print(raw_ostream &OS) const {        OS <<  '+';        break; +    case MCBinaryExpr::AShr: OS << ">>"; break;      case MCBinaryExpr::And:  OS <<  '&'; break;      case MCBinaryExpr::Div:  OS <<  '/'; break;      case MCBinaryExpr::EQ:   OS << "=="; break; @@ -96,6 +97,7 @@ void MCExpr::print(raw_ostream &OS) const {      case MCBinaryExpr::GTE:  OS << ">="; break;      case MCBinaryExpr::LAnd: OS << "&&"; break;      case MCBinaryExpr::LOr:  OS << "||"; break; +    case MCBinaryExpr::LShr: OS << ">>"; break;      case MCBinaryExpr::LT:   OS <<  '<'; break;      case MCBinaryExpr::LTE:  OS << "<="; break;      case MCBinaryExpr::Mod:  OS <<  '%'; break; @@ -103,7 +105,6 @@ void MCExpr::print(raw_ostream &OS) const {      case MCBinaryExpr::NE:   OS << "!="; break;      case MCBinaryExpr::Or:   OS <<  '|'; break;      case MCBinaryExpr::Shl:  OS << "<<"; break; -    case MCBinaryExpr::Shr:  OS << ">>"; break;      case MCBinaryExpr::Sub:  OS <<  '-'; break;      case MCBinaryExpr::Xor:  OS <<  '^'; break;      } @@ -123,7 +124,7 @@ void MCExpr::print(raw_ostream &OS) const {  #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)  void MCExpr::dump() const { -  print(dbgs()); +  dbgs() << *this;    dbgs() << '\n';  }  #endif @@ -163,7 +164,7 @@ const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym,  const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind,                                                 MCContext &Ctx) { -  return Create(Ctx.GetOrCreateSymbol(Name), Kind, Ctx); +  return Create(Ctx.getOrCreateSymbol(Name), Kind, Ctx);  }  StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { @@ -192,6 +193,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {    case VK_GOTPAGE: return "GOTPAGE";    case VK_GOTPAGEOFF: return "GOTPAGEOFF";    case VK_SECREL: return "SECREL32"; +  case VK_SIZE: return "SIZE";    case VK_WEAKREF: return "WEAKREF";    case VK_ARM_NONE: return "none";    case VK_ARM_TARGET1: return "target1"; @@ -281,6 +283,18 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {    case VK_Mips_PCREL_HI16: return "PCREL_HI16";    case VK_Mips_PCREL_LO16: return "PCREL_LO16";    case VK_COFF_IMGREL32: return "IMGREL"; +  case VK_Hexagon_PCREL: return "PCREL"; +  case VK_Hexagon_LO16: return "LO16"; +  case VK_Hexagon_HI16: return "HI16"; +  case VK_Hexagon_GPREL: return "GPREL"; +  case VK_Hexagon_GD_GOT: return "GDGOT"; +  case VK_Hexagon_LD_GOT: return "LDGOT"; +  case VK_Hexagon_GD_PLT: return "GDPLT"; +  case VK_Hexagon_LD_PLT: return "LDPLT"; +  case VK_Hexagon_IE: return "IE"; +  case VK_Hexagon_IE_GOT: return "IEGOT"; +  case VK_TPREL: return "tprel"; +  case VK_DTPREL: return "dtprel";    }    llvm_unreachable("Invalid variant kind");  } @@ -311,6 +325,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {      .Case("gotpageoff", VK_GOTPAGEOFF)      .Case("imgrel", VK_COFF_IMGREL32)      .Case("secrel32", VK_SECREL) +    .Case("size", VK_SIZE)      .Case("l", VK_PPC_LO)      .Case("h", VK_PPC_HI)      .Case("ha", VK_PPC_HA) @@ -404,13 +419,10 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const {    return EvaluateAsAbsolute(Res, &Asm, nullptr, nullptr);  } -int64_t MCExpr::evaluateKnownAbsolute(const MCAsmLayout &Layout) const { -  int64_t Res; -  bool Abs = -      evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr, true); -  (void)Abs; -  assert(Abs && "Not actually absolute"); -  return Res; +bool MCExpr::evaluateKnownAbsolute(int64_t &Res, +                                   const MCAsmLayout &Layout) const { +  return evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr, +                            true);  }  bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, @@ -433,8 +445,8 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,      return true;    } -  bool IsRelocatable = EvaluateAsRelocatableImpl( -      Value, Asm, Layout, nullptr, Addrs, InSet, /*ForceVarExpansion*/ false); +  bool IsRelocatable = +      EvaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet);    // Record the current value.    Res = Value.getConstant(); @@ -443,13 +455,10 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,  }  /// \brief Helper method for \see EvaluateSymbolAdd(). -static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, -                                                const MCAsmLayout *Layout, -                                                const SectionAddrMap *Addrs, -                                                bool InSet, -                                                const MCSymbolRefExpr *&A, -                                                const MCSymbolRefExpr *&B, -                                                int64_t &Addend) { +static void AttemptToFoldSymbolOffsetDifference( +    const MCAssembler *Asm, const MCAsmLayout *Layout, +    const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A, +    const MCSymbolRefExpr *&B, int64_t &Addend) {    if (!A || !B)      return; @@ -482,15 +491,15 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,    if (!Layout)      return; -  const MCSectionData &SecA = *AD.getFragment()->getParent(); -  const MCSectionData &SecB = *BD.getFragment()->getParent(); +  const MCSection &SecA = *AD.getFragment()->getParent(); +  const MCSection &SecB = *BD.getFragment()->getParent();    if ((&SecA != &SecB) && !Addrs)      return;    // Eagerly evaluate. -  Addend += (Layout->getSymbolOffset(&Asm->getSymbolData(A->getSymbol())) - -             Layout->getSymbolOffset(&Asm->getSymbolData(B->getSymbol()))); +  Addend += Layout->getSymbolOffset(A->getSymbol()) - +            Layout->getSymbolOffset(B->getSymbol());    if (Addrs && (&SecA != &SecB))      Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB)); @@ -523,13 +532,11 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,  /// They might look redundant, but this function can be used before layout  /// is done (see the object streamer for example) and having the Asm argument  /// lets us avoid relaxations early. -static bool EvaluateSymbolicAdd(const MCAssembler *Asm, -                                const MCAsmLayout *Layout, -                                const SectionAddrMap *Addrs, -                                bool InSet, -                                const MCValue &LHS,const MCSymbolRefExpr *RHS_A, -                                const MCSymbolRefExpr *RHS_B, int64_t RHS_Cst, -                                MCValue &Res) { +static bool +EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout, +                    const SectionAddrMap *Addrs, bool InSet, const MCValue &LHS, +                    const MCSymbolRefExpr *RHS_A, const MCSymbolRefExpr *RHS_B, +                    int64_t RHS_Cst, MCValue &Res) {    // FIXME: This routine (and other evaluation parts) are *incredibly* sloppy    // about dealing with modifiers. This will ultimately bite us, one day.    const MCSymbolRefExpr *LHS_A = LHS.getSymA(); @@ -587,21 +594,28 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res,                                     const MCFixup *Fixup) const {    MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;    return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr, -                                   false, /*ForceVarExpansion*/ false); +                                   false);  } -bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout, -                             const MCFixup *Fixup) const { -  MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; -  return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr, -                                   false, /*ForceVarExpansion*/ true); +bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const { +  MCAssembler *Assembler = &Layout.getAssembler(); +  return EvaluateAsRelocatableImpl(Res, Assembler, &Layout, nullptr, nullptr, +                                   true); +} + +static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm, bool InSet) { +  if (InSet) +    return true; +  if (!Asm) +    return false; +  return !Asm->getWriter().isWeak(Sym);  }  bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,                                         const MCAsmLayout *Layout,                                         const MCFixup *Fixup, -                                       const SectionAddrMap *Addrs, bool InSet, -                                       bool ForceVarExpansion) const { +                                       const SectionAddrMap *Addrs, +                                       bool InSet) const {    ++stats::MCExprEvaluate;    switch (getKind()) { @@ -618,28 +632,24 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,      const MCSymbol &Sym = SRE->getSymbol();      // Evaluate recursively if this is a variable. -    if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) { +    if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None && +        canExpand(Sym, Asm, InSet)) { +      bool IsMachO = SRE->hasSubsectionsViaSymbols();        if (Sym.getVariableValue()->EvaluateAsRelocatableImpl( -              Res, Asm, Layout, Fixup, Addrs, true, ForceVarExpansion)) { +              Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) { +        if (!IsMachO) +          return true; +          const MCSymbolRefExpr *A = Res.getSymA();          const MCSymbolRefExpr *B = Res.getSymB(); - -        if (SRE->hasSubsectionsViaSymbols()) { -          // FIXME: This is small hack. Given -          // a = b + 4 -          // .long a -          // the OS X assembler will completely drop the 4. We should probably -          // include it in the relocation or produce an error if that is not -          // possible. -          if (!A && !B) -            return true; -        } else { -          if (ForceVarExpansion) -            return true; -          bool IsSymbol = A && A->getSymbol().isDefined(); -          if (!IsSymbol) -            return true; -        } +        // FIXME: This is small hack. Given +        // a = b + 4 +        // .long a +        // the OS X assembler will completely drop the 4. We should probably +        // include it in the relocation or produce an error if that is not +        // possible. +        if (!A && !B) +          return true;        }      } @@ -651,9 +661,8 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,      const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);      MCValue Value; -    if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, -                                                      Fixup, Addrs, InSet, -                                                      ForceVarExpansion)) +    if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, Fixup, +                                                      Addrs, InSet))        return false;      switch (AUE->getOpcode()) { @@ -686,12 +695,10 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,      const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);      MCValue LHSValue, RHSValue; -    if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, -                                                  Fixup, Addrs, InSet, -                                                  ForceVarExpansion) || -        !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, -                                                  Fixup, Addrs, InSet, -                                                  ForceVarExpansion)) +    if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, Fixup, +                                                  Addrs, InSet) || +        !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup, +                                                  Addrs, InSet))        return false;      // We only support a few operations on non-constant expressions, handle @@ -704,23 +711,22 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,          // Negate RHS and add.          return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,                                     RHSValue.getSymB(), RHSValue.getSymA(), -                                   -RHSValue.getConstant(), -                                   Res); +                                   -RHSValue.getConstant(), Res);        case MCBinaryExpr::Add:          return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue,                                     RHSValue.getSymA(), RHSValue.getSymB(), -                                   RHSValue.getConstant(), -                                   Res); +                                   RHSValue.getConstant(), Res);        }      }      // FIXME: We need target hooks for the evaluation. It may be limited in -    // width, and gas defines the result of comparisons and right shifts -    // differently from Apple as. +    // width, and gas defines the result of comparisons differently from +    // Apple as.      int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant();      int64_t Result = 0;      switch (ABE->getOpcode()) { +    case MCBinaryExpr::AShr: Result = LHS >> RHS; break;      case MCBinaryExpr::Add:  Result = LHS + RHS; break;      case MCBinaryExpr::And:  Result = LHS & RHS; break;      case MCBinaryExpr::Div:  Result = LHS / RHS; break; @@ -729,6 +735,7 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,      case MCBinaryExpr::GTE:  Result = LHS >= RHS; break;      case MCBinaryExpr::LAnd: Result = LHS && RHS; break;      case MCBinaryExpr::LOr:  Result = LHS || RHS; break; +    case MCBinaryExpr::LShr: Result = uint64_t(LHS) >> uint64_t(RHS); break;      case MCBinaryExpr::LT:   Result = LHS < RHS; break;      case MCBinaryExpr::LTE:  Result = LHS <= RHS; break;      case MCBinaryExpr::Mod:  Result = LHS % RHS; break; @@ -736,7 +743,6 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,      case MCBinaryExpr::NE:   Result = LHS != RHS; break;      case MCBinaryExpr::Or:   Result = LHS | RHS; break;      case MCBinaryExpr::Shl:  Result = LHS << RHS; break; -    case MCBinaryExpr::Shr:  Result = LHS >> RHS; break;      case MCBinaryExpr::Sub:  Result = LHS - RHS; break;      case MCBinaryExpr::Xor:  Result = LHS ^ RHS; break;      } @@ -749,7 +755,7 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,    llvm_unreachable("Invalid assembly expression kind!");  } -const MCSection *MCExpr::FindAssociatedSection() const { +MCSection *MCExpr::FindAssociatedSection() const {    switch (getKind()) {    case Target:      // We never look through target specific expressions. @@ -773,8 +779,8 @@ const MCSection *MCExpr::FindAssociatedSection() const {    case Binary: {      const MCBinaryExpr *BE = cast<MCBinaryExpr>(this); -    const MCSection *LHS_S = BE->getLHS()->FindAssociatedSection(); -    const MCSection *RHS_S = BE->getRHS()->FindAssociatedSection(); +    MCSection *LHS_S = BE->getLHS()->FindAssociatedSection(); +    MCSection *RHS_S = BE->getRHS()->FindAssociatedSection();      // If either section is absolute, return the other.      if (LHS_S == MCSymbol::AbsolutePseudoSection) @@ -782,6 +788,10 @@ const MCSection *MCExpr::FindAssociatedSection() const {      if (RHS_S == MCSymbol::AbsolutePseudoSection)        return LHS_S; +    // Not always correct, but probably the best we can do without more context. +    if (BE->getOpcode() == MCBinaryExpr::Sub) +      return MCSymbol::AbsolutePseudoSection; +      // Otherwise, return the first non-null section.      return LHS_S ? LHS_S : RHS_S;    }  | 
