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 | |
parent | 8c18a6fe370f7f1fb3208a12434e862fc5e9b2e6 (diff) | |
download | llvm-edaa58ee66699b99841ee5dfdd485aedbae3bf90.tar.gz llvm-edaa58ee66699b99841ee5dfdd485aedbae3bf90.tar.bz2 llvm-edaa58ee66699b99841ee5dfdd485aedbae3bf90.tar.xz |
[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')
-rw-r--r-- | lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp | 42 | ||||
-rw-r--r-- | lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h | 4 | ||||
-rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp | 9 | ||||
-rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp | 108 | ||||
-rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h | 78 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCAsmPrinter.cpp | 23 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstr64Bit.td | 4 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 4 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCMCInstLower.cpp | 67 |
10 files changed, 250 insertions, 90 deletions
diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp index 3dc717067e..432167e335 100644 --- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp @@ -129,7 +129,10 @@ void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo, void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { - O << (short)MI->getOperand(OpNo).getImm(); + if (MI->getOperand(OpNo).isImm()) + O << (short)MI->getOperand(OpNo).getImm(); + else + printOperand(MI, OpNo, O); } void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, @@ -174,7 +177,7 @@ void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo, void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo, raw_ostream &O) { - printSymbolLo(MI, OpNo, O); + printS16ImmOperand(MI, OpNo, O); O << '('; if (MI->getOperand(OpNo+1).getReg() == PPC::R0) O << "0"; @@ -232,39 +235,4 @@ void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, assert(Op.isExpr() && "unknown operand kind in printOperand"); O << *Op.getExpr(); } - -void PPCInstPrinter::printSymbolLo(const MCInst *MI, unsigned OpNo, - raw_ostream &O) { - if (MI->getOperand(OpNo).isImm()) - return printS16ImmOperand(MI, OpNo, O); - - // FIXME: This is a terrible hack because we can't encode lo16() as an operand - // flag of a subtraction. See the FIXME in GetSymbolRef in PPCMCInstLower. - if (MI->getOperand(OpNo).isExpr() && - isa<MCBinaryExpr>(MI->getOperand(OpNo).getExpr())) { - O << "lo16("; - printOperand(MI, OpNo, O); - O << ')'; - } else { - printOperand(MI, OpNo, O); - } -} - -void PPCInstPrinter::printSymbolHi(const MCInst *MI, unsigned OpNo, - raw_ostream &O) { - if (MI->getOperand(OpNo).isImm()) - return printS16ImmOperand(MI, OpNo, O); - - // FIXME: This is a terrible hack because we can't encode lo16() as an operand - // flag of a subtraction. See the FIXME in GetSymbolRef in PPCMCInstLower. - if (MI->getOperand(OpNo).isExpr() && - isa<MCBinaryExpr>(MI->getOperand(OpNo).getExpr())) { - O << "ha16("; - printOperand(MI, OpNo, O); - O << ')'; - } else { - printOperand(MI, OpNo, O); - } -} - diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h index 76f90ef886..f64a329505 100644 --- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h +++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h @@ -57,10 +57,6 @@ public: void printMemRegImm(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printMemRegReg(const MCInst *MI, unsigned OpNo, raw_ostream &O); - - // FIXME: Remove - void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O); - void printSymbolHi(const MCInst *MI, unsigned OpNo, raw_ostream &O); }; } // end namespace llvm diff --git a/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt b/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt index b674883db7..45be4713b6 100644 --- a/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt @@ -3,6 +3,7 @@ add_llvm_library(LLVMPowerPCDesc PPCMCTargetDesc.cpp PPCMCAsmInfo.cpp PPCMCCodeEmitter.cpp + PPCMCExpr.cpp PPCPredicates.cpp PPCELFObjectWriter.cpp ) diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp index 5c272c0ee9..7188f936fe 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -90,8 +90,7 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_PPC_DTPREL16_HA: Type = ELF::R_PPC64_DTPREL16_HA; break; - case MCSymbolRefExpr::VK_PPC_GAS_HA16: - case MCSymbolRefExpr::VK_PPC_DARWIN_HA16: + case MCSymbolRefExpr::VK_PPC_ADDR16_HA: Type = ELF::R_PPC_ADDR16_HA; break; case MCSymbolRefExpr::VK_PPC_TOC16_HA: @@ -115,8 +114,7 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_None: Type = ELF::R_PPC_ADDR16; break; - case MCSymbolRefExpr::VK_PPC_GAS_LO16: - case MCSymbolRefExpr::VK_PPC_DARWIN_LO16: + case MCSymbolRefExpr::VK_PPC_ADDR16_LO: Type = ELF::R_PPC_ADDR16_LO; break; case MCSymbolRefExpr::VK_PPC_TOC_ENTRY: @@ -139,8 +137,7 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_None: Type = ELF::R_PPC64_ADDR16_DS; break; - case MCSymbolRefExpr::VK_PPC_GAS_LO16: - case MCSymbolRefExpr::VK_PPC_DARWIN_LO16: + case MCSymbolRefExpr::VK_PPC_ADDR16_LO: Type = ELF::R_PPC64_ADDR16_LO_DS; break; case MCSymbolRefExpr::VK_PPC_TOC_ENTRY: diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp new file mode 100644 index 0000000000..f0613ff632 --- /dev/null +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp @@ -0,0 +1,108 @@ +//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "ppcmcexpr" +#include "PPCMCExpr.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" + +using namespace llvm; + +const PPCMCExpr* +PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr, + MCContext &Ctx) { + return new (Ctx) PPCMCExpr(Kind, Expr); +} + +void PPCMCExpr::PrintImpl(raw_ostream &OS) const { + switch (Kind) { + default: llvm_unreachable("Invalid kind!"); + case VK_PPC_HA16: OS << "ha16"; break; + case VK_PPC_LO16: OS << "lo16"; break; + } + + OS << '('; + getSubExpr()->print(OS); + OS << ')'; +} + +bool +PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout) const { + MCValue Value; + + if (!getSubExpr()->EvaluateAsRelocatable(Value, *Layout)) + return false; + + if (Value.isAbsolute()) { + int64_t Result = Value.getConstant(); + switch (Kind) { + default: + llvm_unreachable("Invalid kind!"); + case VK_PPC_HA16: + Result = ((Result >> 16) + ((Result & 0x8000) ? 1 : 0)) & 0xffff; + break; + case VK_PPC_LO16: + Result = Result & 0xffff; + break; + } + Res = MCValue::get(Result); + } else { + MCContext &Context = Layout->getAssembler().getContext(); + const MCSymbolRefExpr *Sym = Value.getSymA(); + MCSymbolRefExpr::VariantKind Modifier = Sym->getKind(); + if (Modifier != MCSymbolRefExpr::VK_None) + return false; + switch (Kind) { + default: + llvm_unreachable("Invalid kind!"); + case VK_PPC_HA16: + Modifier = MCSymbolRefExpr::VK_PPC_ADDR16_HA; + break; + case VK_PPC_LO16: + Modifier = MCSymbolRefExpr::VK_PPC_ADDR16_LO; + break; + } + Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context); + Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant()); + } + + return true; +} + +// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps +// that method should be made public? +static void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) { + switch (Value->getKind()) { + case MCExpr::Target: + llvm_unreachable("Can't handle nested target expr!"); + + case MCExpr::Constant: + break; + + case MCExpr::Binary: { + const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); + AddValueSymbols_(BE->getLHS(), Asm); + AddValueSymbols_(BE->getRHS(), Asm); + break; + } + + case MCExpr::SymbolRef: + Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); + break; + + case MCExpr::Unary: + AddValueSymbols_(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm); + break; + } +} + +void PPCMCExpr::AddValueSymbols(MCAssembler *Asm) const { + AddValueSymbols_(getSubExpr(), Asm); +} diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h new file mode 100644 index 0000000000..a0805374a4 --- /dev/null +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h @@ -0,0 +1,78 @@ +//===-- PPCMCExpr.h - PPC specific MC expression classes --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef PPCMCEXPR_H +#define PPCMCEXPR_H + +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCAsmLayout.h" + +namespace llvm { + +class PPCMCExpr : public MCTargetExpr { +public: + enum VariantKind { + VK_PPC_None, + VK_PPC_HA16, + VK_PPC_LO16 + }; + +private: + const VariantKind Kind; + const MCExpr *Expr; + + explicit PPCMCExpr(VariantKind _Kind, const MCExpr *_Expr) + : Kind(_Kind), Expr(_Expr) {} + +public: + /// @name Construction + /// @{ + + static const PPCMCExpr *Create(VariantKind Kind, const MCExpr *Expr, + MCContext &Ctx); + + static const PPCMCExpr *CreateHa16(const MCExpr *Expr, MCContext &Ctx) { + return Create(VK_PPC_HA16, Expr, Ctx); + } + + static const PPCMCExpr *CreateLo16(const MCExpr *Expr, MCContext &Ctx) { + return Create(VK_PPC_LO16, Expr, Ctx); + } + + /// @} + /// @name Accessors + /// @{ + + /// getOpcode - Get the kind of this expression. + VariantKind getKind() const { return Kind; } + + /// getSubExpr - Get the child of this expression. + const MCExpr *getSubExpr() const { return Expr; } + + /// @} + + void PrintImpl(raw_ostream &OS) const; + bool EvaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout) const; + void AddValueSymbols(MCAssembler *) const; + const MCSection *FindAssociatedSection() const { + return getSubExpr()->FindAssociatedSection(); + } + + // There are no TLS PPCMCExprs at the moment. + void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } +}; +} // end namespace llvm + +#endif diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 3c7cc4ed0e..c43b5c9a12 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -20,6 +20,7 @@ #include "PPC.h" #include "InstPrinter/PPCInstPrinter.h" #include "MCTargetDesc/PPCPredicates.h" +#include "MCTargetDesc/PPCMCExpr.h" #include "PPCSubtarget.h" #include "PPCTargetMachine.h" #include "llvm/ADT/MapVector.h" @@ -910,6 +911,9 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext); + const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); + const MCExpr *Sub = + MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext); // mflr r0 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); @@ -919,21 +923,20 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { // mflr r11 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); // addis r11, r11, ha16(LazyPtr - AnonSymbol) - const MCExpr *Sub = - MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext), - Anon, OutContext); + const MCExpr *SubHa16 = PPCMCExpr::CreateHa16(Sub, OutContext); OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS) .addReg(PPC::R11) .addReg(PPC::R11) - .addExpr(Sub)); + .addExpr(SubHa16)); // mtlr r0 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) + const MCExpr *SubLo16 = PPCMCExpr::CreateLo16(Sub, OutContext); OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) .addReg(PPC::R12) - .addExpr(Sub).addExpr(Sub) + .addExpr(SubLo16).addExpr(SubLo16) .addReg(PPC::R11)); // mtctr r12 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); @@ -967,24 +970,22 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { MCSymbol *Stub = Stubs[i].first; MCSymbol *RawSym = Stubs[i].second.getPointer(); MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); + const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); OutStreamer.SwitchSection(StubSection); EmitAlignment(4); OutStreamer.EmitLabel(Stub); OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); + // lis r11, ha16(LazyPtr) - const MCExpr *LazyPtrHa16 = - MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16, - OutContext); + const MCExpr *LazyPtrHa16 = PPCMCExpr::CreateHa16(LazyPtrExpr, OutContext); OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS) .addReg(PPC::R11) .addExpr(LazyPtrHa16)); - const MCExpr *LazyPtrLo16 = - MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16, - OutContext); // ldu r12, lo16(LazyPtr)(r11) // lwzu r12, lo16(LazyPtr)(r11) + const MCExpr *LazyPtrLo16 = PPCMCExpr::CreateLo16(LazyPtrExpr, OutContext); OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) .addReg(PPC::R12) .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 9732262608..da2e0b3db3 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -24,12 +24,12 @@ def u16imm64 : Operand<i64> { let ParserMatchClass = PPCU16ImmAsmOperand; } def symbolHi64 : Operand<i64> { - let PrintMethod = "printSymbolHi"; + let PrintMethod = "printS16ImmOperand"; let EncoderMethod = "getS16ImmEncoding"; let ParserMatchClass = PPCS16ImmAsmOperand; } def symbolLo64 : Operand<i64> { - let PrintMethod = "printSymbolLo"; + let PrintMethod = "printS16ImmOperand"; let EncoderMethod = "getS16ImmEncoding"; let ParserMatchClass = PPCS16ImmAsmOperand; } diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 33a5a0e089..9a1a89ae9b 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -459,12 +459,12 @@ def aaddr : Operand<iPTR> { let PrintMethod = "printAbsAddrOperand"; } def symbolHi: Operand<i32> { - let PrintMethod = "printSymbolHi"; + let PrintMethod = "printS16ImmOperand"; let EncoderMethod = "getS16ImmEncoding"; let ParserMatchClass = PPCS16ImmAsmOperand; } def symbolLo: Operand<i32> { - let PrintMethod = "printSymbolLo"; + let PrintMethod = "printS16ImmOperand"; let EncoderMethod = "getS16ImmEncoding"; let ParserMatchClass = PPCS16ImmAsmOperand; } diff --git a/lib/Target/PowerPC/PPCMCInstLower.cpp b/lib/Target/PowerPC/PPCMCInstLower.cpp index f8cf3a589c..ba7efc1880 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); } |