aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PowerPC/PPCMCInstLower.cpp
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2013-05-23 22:26:41 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2013-05-23 22:26:41 +0000
commitedaa58ee66699b99841ee5dfdd485aedbae3bf90 (patch)
treef72d8a956e66c212217173df3cbf39a45b1eef97 /lib/Target/PowerPC/PPCMCInstLower.cpp
parent8c18a6fe370f7f1fb3208a12434e862fc5e9b2e6 (diff)
downloadexternal_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.cpp67
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);
}