diff options
author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2013-05-23 22:26:41 +0000 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2013-05-23 22:26:41 +0000 |
commit | edaa58ee66699b99841ee5dfdd485aedbae3bf90 (patch) | |
tree | f72d8a956e66c212217173df3cbf39a45b1eef97 /lib/Target/PowerPC/PPCMCInstLower.cpp | |
parent | 8c18a6fe370f7f1fb3208a12434e862fc5e9b2e6 (diff) | |
download | external_llvm-edaa58ee66699b99841ee5dfdd485aedbae3bf90.zip external_llvm-edaa58ee66699b99841ee5dfdd485aedbae3bf90.tar.gz external_llvm-edaa58ee66699b99841ee5dfdd485aedbae3bf90.tar.bz2 |
[PowerPC] Clean up generation of ha16() / lo16() markers
When targeting the Darwin assembler, we need to generate markers ha16() and
lo16() to designate the high and low parts of a (symbolic) immediate. This
is necessary not just for plain symbols, but also for certain symbolic
expression, typically along the lines of ha16(A - B). The latter doesn't
work when simply using VariantKind flags on the symbol reference.
This is why the current back-end uses hacks (explicitly called out as such
via multiple FIXMEs) in the symbolLo/symbolHi print methods.
This patch uses target-defined MCExpr codes to represent the Darwin
ha16/lo16 constructs, following along the lines of the equivalent solution
used by the ARM back end to handle their :upper16: / :lower16: markers.
This allows us to get rid of special handling both in the symbolLo/symbolHi
print method and in the common code MCExpr::print routine. Instead, the
ha16 / lo16 markers are printed simply in a custom print routine for the
target MCExpr types. (As a result, the symbolLo/symbolHi print methods
can now replaced by a single printS16ImmOperand routine that also handles
symbolic operands.)
The patch also provides a EvaluateAsRelocatableImpl routine to handle
ha16/lo16 constructs. This is not actually used at the moment by any
in-tree code, but is provided as it makes merging into David Fang's
out-of-tree Mach-O object writer simpler.
Since there is no longer any need to treat VK_PPC_GAS_HA16 and
VK_PPC_DARWIN_HA16 differently, they are merged into a single
VK_PPC_ADDR16_HA (and likewise for the _LO16 types).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182616 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCMCInstLower.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCMCInstLower.cpp | 67 |
1 files changed, 39 insertions, 28 deletions
diff --git a/lib/Target/PowerPC/PPCMCInstLower.cpp b/lib/Target/PowerPC/PPCMCInstLower.cpp index f8cf3a5..ba7efc1 100644 --- a/lib/Target/PowerPC/PPCMCInstLower.cpp +++ b/lib/Target/PowerPC/PPCMCInstLower.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "PPC.h" +#include "MCTargetDesc/PPCMCExpr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" @@ -110,32 +111,32 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK; - switch (access) { - case PPCII::MO_HA16: RefKind = isDarwin ? - MCSymbolRefExpr::VK_PPC_DARWIN_HA16 : - MCSymbolRefExpr::VK_PPC_GAS_HA16; - break; - case PPCII::MO_LO16: RefKind = isDarwin ? - MCSymbolRefExpr::VK_PPC_DARWIN_LO16 : - MCSymbolRefExpr::VK_PPC_GAS_LO16; - break; - case PPCII::MO_TPREL16_HA: RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA; - break; - case PPCII::MO_TPREL16_LO: RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO; - break; - case PPCII::MO_DTPREL16_LO: RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO; - break; - case PPCII::MO_TLSLD16_LO: RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO; - break; - case PPCII::MO_TOC16_LO: RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO; - break; - } + if (!isDarwin) { + switch (access) { + case PPCII::MO_HA16: + RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_HA; + break; + case PPCII::MO_LO16: + RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_LO; + break; + case PPCII::MO_TPREL16_HA: + RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA; + break; + case PPCII::MO_TPREL16_LO: + RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO; + break; + case PPCII::MO_DTPREL16_LO: + RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO; + break; + case PPCII::MO_TLSLD16_LO: + RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO; + break; + case PPCII::MO_TOC16_LO: + RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO; + break; + } + } - // FIXME: This isn't right, but we don't have a good way to express this in - // the MC Level, see below. - if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) - RefKind = MCSymbolRefExpr::VK_None; - const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx); if (!MO.isJTI() && MO.getOffset()) @@ -149,10 +150,20 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx); Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx); - // FIXME: We have no way to make the result be VK_PPC_LO16/VK_PPC_HA16, - // since it is not a symbol! } - + + // Add Darwin ha16() / lo16() markers if required. + if (isDarwin) { + switch (access) { + case PPCII::MO_HA16: + Expr = PPCMCExpr::CreateHa16(Expr, Ctx); + break; + case PPCII::MO_LO16: + Expr = PPCMCExpr::CreateLo16(Expr, Ctx); + break; + } + } + return MCOperand::CreateExpr(Expr); } |