diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-06-30 02:08:27 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-06-30 02:08:27 +0000 |
commit | c2aacfc0e5120c5ecb7534fccd65b2abe3096454 (patch) | |
tree | 4e25dc1794151213f18393b6fe806bdb05a80b52 /tools/llvm-mc | |
parent | c6c054eb8d2bc644fce937e17224f9fe87d496c6 (diff) | |
download | external_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.cpp | 59 |
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); } } |