From edaa58ee66699b99841ee5dfdd485aedbae3bf90 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 23 May 2013 22:26:41 +0000 Subject: [PATCH] [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 --- include/llvm/MC/MCExpr.h | 6 +- lib/MC/MCExpr.cpp | 25 ++-- .../PowerPC/InstPrinter/PPCInstPrinter.cpp | 42 +------ .../PowerPC/InstPrinter/PPCInstPrinter.h | 4 - .../PowerPC/MCTargetDesc/CMakeLists.txt | 1 + .../MCTargetDesc/PPCELFObjectWriter.cpp | 9 +- lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp | 108 ++++++++++++++++++ lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h | 78 +++++++++++++ lib/Target/PowerPC/PPCAsmPrinter.cpp | 23 ++-- lib/Target/PowerPC/PPCInstr64Bit.td | 4 +- lib/Target/PowerPC/PPCInstrInfo.td | 4 +- lib/Target/PowerPC/PPCMCInstLower.cpp | 67 ++++++----- 12 files changed, 259 insertions(+), 112 deletions(-) create mode 100644 lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp create mode 100644 lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index a2c5bd3f766..d851f643c6e 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -173,10 +173,8 @@ public: VK_PPC_TOC, // TOC base VK_PPC_TOC_ENTRY, // TOC entry - VK_PPC_DARWIN_HA16, // ha16(symbol) - VK_PPC_DARWIN_LO16, // lo16(symbol) - VK_PPC_GAS_HA16, // symbol@ha - VK_PPC_GAS_LO16, // symbol@l + VK_PPC_ADDR16_HA, // symbol@ha + VK_PPC_ADDR16_LO, // symbol@l VK_PPC_TPREL16_HA, // symbol@tprel@ha VK_PPC_TPREL16_LO, // symbol@tprel@l VK_PPC_DTPREL16_HA, // symbol@dtprel@ha diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 06bc72f2c6b..040b9289cf6 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -42,13 +42,6 @@ void MCExpr::print(raw_ostream &OS) const { // Parenthesize names that start with $ so that they don't look like // absolute names. bool UseParens = Sym.getName()[0] == '$'; - - if (SRE.getKind() == MCSymbolRefExpr::VK_PPC_DARWIN_HA16 || - SRE.getKind() == MCSymbolRefExpr::VK_PPC_DARWIN_LO16) { - OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); - UseParens = true; - } - if (UseParens) OS << '(' << Sym << ')'; else @@ -65,9 +58,7 @@ void MCExpr::print(raw_ostream &OS) const { SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2 || SRE.getKind() == MCSymbolRefExpr::VK_ARM_PREL31) OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); - else if (SRE.getKind() != MCSymbolRefExpr::VK_None && - SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_HA16 && - SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_LO16) + else if (SRE.getKind() != MCSymbolRefExpr::VK_None) OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); return; @@ -207,10 +198,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_ARM_PREL31: return "(prel31)"; case VK_PPC_TOC: return "tocbase"; case VK_PPC_TOC_ENTRY: return "toc"; - case VK_PPC_DARWIN_HA16: return "ha16"; - case VK_PPC_DARWIN_LO16: return "lo16"; - case VK_PPC_GAS_HA16: return "ha"; - case VK_PPC_GAS_LO16: return "l"; + case VK_PPC_ADDR16_HA: return "ha"; + case VK_PPC_ADDR16_LO: return "l"; case VK_PPC_TPREL16_HA: return "tprel@ha"; case VK_PPC_TPREL16_LO: return "tprel@l"; case VK_PPC_DTPREL16_HA: return "dtprel@ha"; @@ -290,10 +279,10 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("imgrel", VK_COFF_IMGREL32) .Case("SECREL32", VK_SECREL) .Case("secrel32", VK_SECREL) - .Case("HA", VK_PPC_GAS_HA16) - .Case("ha", VK_PPC_GAS_HA16) - .Case("L", VK_PPC_GAS_LO16) - .Case("l", VK_PPC_GAS_LO16) + .Case("HA", VK_PPC_ADDR16_HA) + .Case("ha", VK_PPC_ADDR16_HA) + .Case("L", VK_PPC_ADDR16_LO) + .Case("l", VK_PPC_ADDR16_LO) .Case("TOCBASE", VK_PPC_TOC) .Case("tocbase", VK_PPC_TOC) .Case("TOC", VK_PPC_TOC_ENTRY) diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp index 3dc717067e9..432167e3355 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(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(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 76f90ef8867..f64a3295055 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 b674883db7d..45be4713b6d 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 5c272c0ee97..7188f936fea 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 00000000000..f0613ff6328 --- /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(Value); + AddValueSymbols_(BE->getLHS(), Asm); + AddValueSymbols_(BE->getRHS(), Asm); + break; + } + + case MCExpr::SymbolRef: + Asm->getOrCreateSymbolData(cast(Value)->getSymbol()); + break; + + case MCExpr::Unary: + AddValueSymbols_(cast(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 00000000000..a0805374a43 --- /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 3c7cc4ed0eb..c43b5c9a127 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 9732262608d..da2e0b3db3e 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -24,12 +24,12 @@ def u16imm64 : Operand { let ParserMatchClass = PPCU16ImmAsmOperand; } def symbolHi64 : Operand { - let PrintMethod = "printSymbolHi"; + let PrintMethod = "printS16ImmOperand"; let EncoderMethod = "getS16ImmEncoding"; let ParserMatchClass = PPCS16ImmAsmOperand; } def symbolLo64 : Operand { - 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 33a5a0e0891..9a1a89ae9bc 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -459,12 +459,12 @@ def aaddr : Operand { let PrintMethod = "printAbsAddrOperand"; } def symbolHi: Operand { - let PrintMethod = "printSymbolHi"; + let PrintMethod = "printS16ImmOperand"; let EncoderMethod = "getS16ImmEncoding"; let ParserMatchClass = PPCS16ImmAsmOperand; } def symbolLo: Operand { - 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 f8cf3a589c1..ba7efc18802 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); }