OS << '+';
break;
+ case MCBinaryExpr::AShr: OS << ">>"; break;
case MCBinaryExpr::And: OS << '&'; break;
case MCBinaryExpr::Div: OS << '/'; break;
case MCBinaryExpr::EQ: OS << "=="; break;
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;
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;
}
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");
}
false);
}
-static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm) {
+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;
const MCSymbolData &SD = Asm->getSymbolData(Sym);
// Evaluate recursively if this is a variable.
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None &&
- canExpand(Sym, Asm)) {
+ canExpand(Sym, Asm, InSet)) {
+ bool IsMachO = SRE->hasSubsectionsViaSymbols();
if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(
- Res, Asm, Layout, Fixup, Addrs, true)) {
- if (!SRE->hasSubsectionsViaSymbols())
+ Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) {
+ if (!IsMachO)
return true;
const MCSymbolRefExpr *A = Res.getSymA();
}
// 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;
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;
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;
}
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;
}