aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llvm-mc
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-06-30 02:08:27 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-06-30 02:08:27 +0000
commitc2aacfc0e5120c5ecb7534fccd65b2abe3096454 (patch)
tree4e25dc1794151213f18393b6fe806bdb05a80b52 /tools/llvm-mc
parentc6c054eb8d2bc644fce937e17224f9fe87d496c6 (diff)
downloadexternal_llvm-c2aacfc0e5120c5ecb7534fccd65b2abe3096454.zip
external_llvm-c2aacfc0e5120c5ecb7534fccd65b2abe3096454.tar.gz
external_llvm-c2aacfc0e5120c5ecb7534fccd65b2abe3096454.tar.bz2
llvm-mc: Rewrite binary subtraction for relocatable expressions, we can't always
legally negate an MCValue. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74497 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-mc')
-rw-r--r--tools/llvm-mc/AsmExpr.cpp59
1 files changed, 33 insertions, 26 deletions
diff --git a/tools/llvm-mc/AsmExpr.cpp b/tools/llvm-mc/AsmExpr.cpp
index ffc09eb..868cd0d 100644
--- a/tools/llvm-mc/AsmExpr.cpp
+++ b/tools/llvm-mc/AsmExpr.cpp
@@ -26,6 +26,29 @@ bool AsmExpr::EvaluateAsAbsolute(MCContext &Ctx, int64_t &Res) const {
return true;
}
+static bool EvaluateSymbolicAdd(const MCValue &LHS, MCSymbol *RHS_A,
+ MCSymbol *RHS_B, int64_t RHS_Cst,
+ MCValue &Res) {
+ // We can't add or subtract two symbols.
+ if ((LHS.getSymA() && RHS_A) ||
+ (LHS.getSymB() && RHS_B))
+ return false;
+
+ MCSymbol *A = LHS.getSymA() ? LHS.getSymA() : RHS_A;
+ MCSymbol *B = LHS.getSymB() ? LHS.getSymB() : RHS_B;
+ if (B) {
+ // If we have a negated symbol, then we must have also have a
+ // non-negated symbol, and both symbols must be in the same
+ // non-external section. We can do this check later to permit
+ // expressions which eventually fold to a representable form -- such
+ // as (a + (0 - b)) -- if necessary.
+ if (!A || !A->getSection() || A->getSection() != B->getSection())
+ return false;
+ }
+ Res = MCValue::get(A, B, LHS.getConstant() + RHS_Cst);
+ return true;
+}
+
bool AsmExpr::EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const {
switch (getKind()) {
default:
@@ -92,33 +115,17 @@ bool AsmExpr::EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const {
default:
return false;
case AsmBinaryExpr::Sub:
- // Negate RHS and fall through.
- RHSValue = MCValue::get(RHSValue.getSymB(), RHSValue.getSymA(),
- -RHSValue.getConstant());
+ // Negate RHS and add.
+ return EvaluateSymbolicAdd(LHSValue,
+ RHSValue.getSymB(), RHSValue.getSymA(),
+ -RHSValue.getConstant(),
+ Res);
+
case AsmBinaryExpr::Add:
- // (a_0 - b_0 + cst_0) + (a_1 - b_1 + cst_1)
-
- // We can't add or subtract two symbols.
- if ((LHSValue.getSymA() && RHSValue.getSymB()) ||
- (LHSValue.getSymB() && RHSValue.getSymB()))
- return false;
-
- MCSymbol *A =
- LHSValue.getSymA() ? LHSValue.getSymA() : RHSValue.getSymA();
- MCSymbol *B =
- LHSValue.getSymB() ? LHSValue.getSymB() : RHSValue.getSymB();
- if (B) {
- // If we have a negated symbol, then we must have also have a
- // non-negated symbol, and both symbols must be in the same
- // non-external section. We can do this check later to permit
- // expressions which eventually fold to a representable form -- such
- // as (a + (0 - b)) -- if necessary.
- if (!A || !A->getSection() || A->getSection() != B->getSection())
- return false;
- }
- Res = MCValue::get(A, B,
- LHSValue.getConstant() + RHSValue.getConstant());
- return true;
+ return EvaluateSymbolicAdd(LHSValue,
+ RHSValue.getSymA(), RHSValue.getSymB(),
+ RHSValue.getConstant(),
+ Res);
}
}