mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-17 15:38:40 +00:00
[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
This commit is contained in:
parent
8c18a6fe37
commit
edaa58ee66
@ -173,10 +173,8 @@ public:
|
|||||||
|
|
||||||
VK_PPC_TOC, // TOC base
|
VK_PPC_TOC, // TOC base
|
||||||
VK_PPC_TOC_ENTRY, // TOC entry
|
VK_PPC_TOC_ENTRY, // TOC entry
|
||||||
VK_PPC_DARWIN_HA16, // ha16(symbol)
|
VK_PPC_ADDR16_HA, // symbol@ha
|
||||||
VK_PPC_DARWIN_LO16, // lo16(symbol)
|
VK_PPC_ADDR16_LO, // symbol@l
|
||||||
VK_PPC_GAS_HA16, // symbol@ha
|
|
||||||
VK_PPC_GAS_LO16, // symbol@l
|
|
||||||
VK_PPC_TPREL16_HA, // symbol@tprel@ha
|
VK_PPC_TPREL16_HA, // symbol@tprel@ha
|
||||||
VK_PPC_TPREL16_LO, // symbol@tprel@l
|
VK_PPC_TPREL16_LO, // symbol@tprel@l
|
||||||
VK_PPC_DTPREL16_HA, // symbol@dtprel@ha
|
VK_PPC_DTPREL16_HA, // symbol@dtprel@ha
|
||||||
|
@ -42,13 +42,6 @@ void MCExpr::print(raw_ostream &OS) const {
|
|||||||
// Parenthesize names that start with $ so that they don't look like
|
// Parenthesize names that start with $ so that they don't look like
|
||||||
// absolute names.
|
// absolute names.
|
||||||
bool UseParens = Sym.getName()[0] == '$';
|
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)
|
if (UseParens)
|
||||||
OS << '(' << Sym << ')';
|
OS << '(' << Sym << ')';
|
||||||
else
|
else
|
||||||
@ -65,9 +58,7 @@ void MCExpr::print(raw_ostream &OS) const {
|
|||||||
SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2 ||
|
SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2 ||
|
||||||
SRE.getKind() == MCSymbolRefExpr::VK_ARM_PREL31)
|
SRE.getKind() == MCSymbolRefExpr::VK_ARM_PREL31)
|
||||||
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
|
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
|
||||||
else if (SRE.getKind() != MCSymbolRefExpr::VK_None &&
|
else if (SRE.getKind() != MCSymbolRefExpr::VK_None)
|
||||||
SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_HA16 &&
|
|
||||||
SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_LO16)
|
|
||||||
OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
|
OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -207,10 +198,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
|
|||||||
case VK_ARM_PREL31: return "(prel31)";
|
case VK_ARM_PREL31: return "(prel31)";
|
||||||
case VK_PPC_TOC: return "tocbase";
|
case VK_PPC_TOC: return "tocbase";
|
||||||
case VK_PPC_TOC_ENTRY: return "toc";
|
case VK_PPC_TOC_ENTRY: return "toc";
|
||||||
case VK_PPC_DARWIN_HA16: return "ha16";
|
case VK_PPC_ADDR16_HA: return "ha";
|
||||||
case VK_PPC_DARWIN_LO16: return "lo16";
|
case VK_PPC_ADDR16_LO: return "l";
|
||||||
case VK_PPC_GAS_HA16: return "ha";
|
|
||||||
case VK_PPC_GAS_LO16: return "l";
|
|
||||||
case VK_PPC_TPREL16_HA: return "tprel@ha";
|
case VK_PPC_TPREL16_HA: return "tprel@ha";
|
||||||
case VK_PPC_TPREL16_LO: return "tprel@l";
|
case VK_PPC_TPREL16_LO: return "tprel@l";
|
||||||
case VK_PPC_DTPREL16_HA: return "dtprel@ha";
|
case VK_PPC_DTPREL16_HA: return "dtprel@ha";
|
||||||
@ -290,10 +279,10 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
|
|||||||
.Case("imgrel", VK_COFF_IMGREL32)
|
.Case("imgrel", VK_COFF_IMGREL32)
|
||||||
.Case("SECREL32", VK_SECREL)
|
.Case("SECREL32", VK_SECREL)
|
||||||
.Case("secrel32", VK_SECREL)
|
.Case("secrel32", VK_SECREL)
|
||||||
.Case("HA", VK_PPC_GAS_HA16)
|
.Case("HA", VK_PPC_ADDR16_HA)
|
||||||
.Case("ha", VK_PPC_GAS_HA16)
|
.Case("ha", VK_PPC_ADDR16_HA)
|
||||||
.Case("L", VK_PPC_GAS_LO16)
|
.Case("L", VK_PPC_ADDR16_LO)
|
||||||
.Case("l", VK_PPC_GAS_LO16)
|
.Case("l", VK_PPC_ADDR16_LO)
|
||||||
.Case("TOCBASE", VK_PPC_TOC)
|
.Case("TOCBASE", VK_PPC_TOC)
|
||||||
.Case("tocbase", VK_PPC_TOC)
|
.Case("tocbase", VK_PPC_TOC)
|
||||||
.Case("TOC", VK_PPC_TOC_ENTRY)
|
.Case("TOC", VK_PPC_TOC_ENTRY)
|
||||||
|
@ -129,7 +129,10 @@ void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
|
|||||||
|
|
||||||
void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
|
void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
|
||||||
raw_ostream &O) {
|
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,
|
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,
|
void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
printSymbolLo(MI, OpNo, O);
|
printS16ImmOperand(MI, OpNo, O);
|
||||||
O << '(';
|
O << '(';
|
||||||
if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
|
if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
|
||||||
O << "0";
|
O << "0";
|
||||||
@ -232,39 +235,4 @@ void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
|||||||
assert(Op.isExpr() && "unknown operand kind in printOperand");
|
assert(Op.isExpr() && "unknown operand kind in printOperand");
|
||||||
O << *Op.getExpr();
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,10 +57,6 @@ public:
|
|||||||
|
|
||||||
void printMemRegImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
void printMemRegImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||||
void printMemRegReg(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
|
} // end namespace llvm
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ add_llvm_library(LLVMPowerPCDesc
|
|||||||
PPCMCTargetDesc.cpp
|
PPCMCTargetDesc.cpp
|
||||||
PPCMCAsmInfo.cpp
|
PPCMCAsmInfo.cpp
|
||||||
PPCMCCodeEmitter.cpp
|
PPCMCCodeEmitter.cpp
|
||||||
|
PPCMCExpr.cpp
|
||||||
PPCPredicates.cpp
|
PPCPredicates.cpp
|
||||||
PPCELFObjectWriter.cpp
|
PPCELFObjectWriter.cpp
|
||||||
)
|
)
|
||||||
|
@ -90,8 +90,7 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
|
|||||||
case MCSymbolRefExpr::VK_PPC_DTPREL16_HA:
|
case MCSymbolRefExpr::VK_PPC_DTPREL16_HA:
|
||||||
Type = ELF::R_PPC64_DTPREL16_HA;
|
Type = ELF::R_PPC64_DTPREL16_HA;
|
||||||
break;
|
break;
|
||||||
case MCSymbolRefExpr::VK_PPC_GAS_HA16:
|
case MCSymbolRefExpr::VK_PPC_ADDR16_HA:
|
||||||
case MCSymbolRefExpr::VK_PPC_DARWIN_HA16:
|
|
||||||
Type = ELF::R_PPC_ADDR16_HA;
|
Type = ELF::R_PPC_ADDR16_HA;
|
||||||
break;
|
break;
|
||||||
case MCSymbolRefExpr::VK_PPC_TOC16_HA:
|
case MCSymbolRefExpr::VK_PPC_TOC16_HA:
|
||||||
@ -115,8 +114,7 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
|
|||||||
case MCSymbolRefExpr::VK_None:
|
case MCSymbolRefExpr::VK_None:
|
||||||
Type = ELF::R_PPC_ADDR16;
|
Type = ELF::R_PPC_ADDR16;
|
||||||
break;
|
break;
|
||||||
case MCSymbolRefExpr::VK_PPC_GAS_LO16:
|
case MCSymbolRefExpr::VK_PPC_ADDR16_LO:
|
||||||
case MCSymbolRefExpr::VK_PPC_DARWIN_LO16:
|
|
||||||
Type = ELF::R_PPC_ADDR16_LO;
|
Type = ELF::R_PPC_ADDR16_LO;
|
||||||
break;
|
break;
|
||||||
case MCSymbolRefExpr::VK_PPC_TOC_ENTRY:
|
case MCSymbolRefExpr::VK_PPC_TOC_ENTRY:
|
||||||
@ -139,8 +137,7 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
|
|||||||
case MCSymbolRefExpr::VK_None:
|
case MCSymbolRefExpr::VK_None:
|
||||||
Type = ELF::R_PPC64_ADDR16_DS;
|
Type = ELF::R_PPC64_ADDR16_DS;
|
||||||
break;
|
break;
|
||||||
case MCSymbolRefExpr::VK_PPC_GAS_LO16:
|
case MCSymbolRefExpr::VK_PPC_ADDR16_LO:
|
||||||
case MCSymbolRefExpr::VK_PPC_DARWIN_LO16:
|
|
||||||
Type = ELF::R_PPC64_ADDR16_LO_DS;
|
Type = ELF::R_PPC64_ADDR16_LO_DS;
|
||||||
break;
|
break;
|
||||||
case MCSymbolRefExpr::VK_PPC_TOC_ENTRY:
|
case MCSymbolRefExpr::VK_PPC_TOC_ENTRY:
|
||||||
|
108
lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
Normal file
108
lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
Normal file
@ -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);
|
||||||
|
}
|
78
lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
Normal file
78
lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
Normal file
@ -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
|
@ -20,6 +20,7 @@
|
|||||||
#include "PPC.h"
|
#include "PPC.h"
|
||||||
#include "InstPrinter/PPCInstPrinter.h"
|
#include "InstPrinter/PPCInstPrinter.h"
|
||||||
#include "MCTargetDesc/PPCPredicates.h"
|
#include "MCTargetDesc/PPCPredicates.h"
|
||||||
|
#include "MCTargetDesc/PPCMCExpr.h"
|
||||||
#include "PPCSubtarget.h"
|
#include "PPCSubtarget.h"
|
||||||
#include "PPCTargetMachine.h"
|
#include "PPCTargetMachine.h"
|
||||||
#include "llvm/ADT/MapVector.h"
|
#include "llvm/ADT/MapVector.h"
|
||||||
@ -910,6 +911,9 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
|
|||||||
OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
|
OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
|
||||||
|
|
||||||
const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext);
|
const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext);
|
||||||
|
const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
|
||||||
|
const MCExpr *Sub =
|
||||||
|
MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext);
|
||||||
|
|
||||||
// mflr r0
|
// mflr r0
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
|
||||||
@ -919,21 +923,20 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
|
|||||||
// mflr r11
|
// mflr r11
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
|
||||||
// addis r11, r11, ha16(LazyPtr - AnonSymbol)
|
// addis r11, r11, ha16(LazyPtr - AnonSymbol)
|
||||||
const MCExpr *Sub =
|
const MCExpr *SubHa16 = PPCMCExpr::CreateHa16(Sub, OutContext);
|
||||||
MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext),
|
|
||||||
Anon, OutContext);
|
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
|
||||||
.addReg(PPC::R11)
|
.addReg(PPC::R11)
|
||||||
.addReg(PPC::R11)
|
.addReg(PPC::R11)
|
||||||
.addExpr(Sub));
|
.addExpr(SubHa16));
|
||||||
// mtlr r0
|
// mtlr r0
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
|
||||||
|
|
||||||
// ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
|
// ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
|
||||||
// lwzu 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)
|
OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
|
||||||
.addReg(PPC::R12)
|
.addReg(PPC::R12)
|
||||||
.addExpr(Sub).addExpr(Sub)
|
.addExpr(SubLo16).addExpr(SubLo16)
|
||||||
.addReg(PPC::R11));
|
.addReg(PPC::R11));
|
||||||
// mtctr r12
|
// mtctr r12
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
|
||||||
@ -967,24 +970,22 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
|
|||||||
MCSymbol *Stub = Stubs[i].first;
|
MCSymbol *Stub = Stubs[i].first;
|
||||||
MCSymbol *RawSym = Stubs[i].second.getPointer();
|
MCSymbol *RawSym = Stubs[i].second.getPointer();
|
||||||
MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
|
MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
|
||||||
|
const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
|
||||||
|
|
||||||
OutStreamer.SwitchSection(StubSection);
|
OutStreamer.SwitchSection(StubSection);
|
||||||
EmitAlignment(4);
|
EmitAlignment(4);
|
||||||
OutStreamer.EmitLabel(Stub);
|
OutStreamer.EmitLabel(Stub);
|
||||||
OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
|
OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
|
||||||
|
|
||||||
// lis r11, ha16(LazyPtr)
|
// lis r11, ha16(LazyPtr)
|
||||||
const MCExpr *LazyPtrHa16 =
|
const MCExpr *LazyPtrHa16 = PPCMCExpr::CreateHa16(LazyPtrExpr, OutContext);
|
||||||
MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
|
|
||||||
OutContext);
|
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
|
||||||
.addReg(PPC::R11)
|
.addReg(PPC::R11)
|
||||||
.addExpr(LazyPtrHa16));
|
.addExpr(LazyPtrHa16));
|
||||||
|
|
||||||
const MCExpr *LazyPtrLo16 =
|
|
||||||
MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
|
|
||||||
OutContext);
|
|
||||||
// ldu r12, lo16(LazyPtr)(r11)
|
// ldu r12, lo16(LazyPtr)(r11)
|
||||||
// lwzu r12, lo16(LazyPtr)(r11)
|
// lwzu r12, lo16(LazyPtr)(r11)
|
||||||
|
const MCExpr *LazyPtrLo16 = PPCMCExpr::CreateLo16(LazyPtrExpr, OutContext);
|
||||||
OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
|
OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
|
||||||
.addReg(PPC::R12)
|
.addReg(PPC::R12)
|
||||||
.addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
|
.addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
|
||||||
|
@ -24,12 +24,12 @@ def u16imm64 : Operand<i64> {
|
|||||||
let ParserMatchClass = PPCU16ImmAsmOperand;
|
let ParserMatchClass = PPCU16ImmAsmOperand;
|
||||||
}
|
}
|
||||||
def symbolHi64 : Operand<i64> {
|
def symbolHi64 : Operand<i64> {
|
||||||
let PrintMethod = "printSymbolHi";
|
let PrintMethod = "printS16ImmOperand";
|
||||||
let EncoderMethod = "getS16ImmEncoding";
|
let EncoderMethod = "getS16ImmEncoding";
|
||||||
let ParserMatchClass = PPCS16ImmAsmOperand;
|
let ParserMatchClass = PPCS16ImmAsmOperand;
|
||||||
}
|
}
|
||||||
def symbolLo64 : Operand<i64> {
|
def symbolLo64 : Operand<i64> {
|
||||||
let PrintMethod = "printSymbolLo";
|
let PrintMethod = "printS16ImmOperand";
|
||||||
let EncoderMethod = "getS16ImmEncoding";
|
let EncoderMethod = "getS16ImmEncoding";
|
||||||
let ParserMatchClass = PPCS16ImmAsmOperand;
|
let ParserMatchClass = PPCS16ImmAsmOperand;
|
||||||
}
|
}
|
||||||
|
@ -459,12 +459,12 @@ def aaddr : Operand<iPTR> {
|
|||||||
let PrintMethod = "printAbsAddrOperand";
|
let PrintMethod = "printAbsAddrOperand";
|
||||||
}
|
}
|
||||||
def symbolHi: Operand<i32> {
|
def symbolHi: Operand<i32> {
|
||||||
let PrintMethod = "printSymbolHi";
|
let PrintMethod = "printS16ImmOperand";
|
||||||
let EncoderMethod = "getS16ImmEncoding";
|
let EncoderMethod = "getS16ImmEncoding";
|
||||||
let ParserMatchClass = PPCS16ImmAsmOperand;
|
let ParserMatchClass = PPCS16ImmAsmOperand;
|
||||||
}
|
}
|
||||||
def symbolLo: Operand<i32> {
|
def symbolLo: Operand<i32> {
|
||||||
let PrintMethod = "printSymbolLo";
|
let PrintMethod = "printS16ImmOperand";
|
||||||
let EncoderMethod = "getS16ImmEncoding";
|
let EncoderMethod = "getS16ImmEncoding";
|
||||||
let ParserMatchClass = PPCS16ImmAsmOperand;
|
let ParserMatchClass = PPCS16ImmAsmOperand;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "PPC.h"
|
#include "PPC.h"
|
||||||
|
#include "MCTargetDesc/PPCMCExpr.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
#include "llvm/CodeGen/AsmPrinter.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;
|
unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK;
|
||||||
|
|
||||||
switch (access) {
|
if (!isDarwin) {
|
||||||
case PPCII::MO_HA16: RefKind = isDarwin ?
|
switch (access) {
|
||||||
MCSymbolRefExpr::VK_PPC_DARWIN_HA16 :
|
case PPCII::MO_HA16:
|
||||||
MCSymbolRefExpr::VK_PPC_GAS_HA16;
|
RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_HA;
|
||||||
break;
|
break;
|
||||||
case PPCII::MO_LO16: RefKind = isDarwin ?
|
case PPCII::MO_LO16:
|
||||||
MCSymbolRefExpr::VK_PPC_DARWIN_LO16 :
|
RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_LO;
|
||||||
MCSymbolRefExpr::VK_PPC_GAS_LO16;
|
break;
|
||||||
break;
|
case PPCII::MO_TPREL16_HA:
|
||||||
case PPCII::MO_TPREL16_HA: RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
|
RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
|
||||||
break;
|
break;
|
||||||
case PPCII::MO_TPREL16_LO: RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
|
case PPCII::MO_TPREL16_LO:
|
||||||
break;
|
RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
|
||||||
case PPCII::MO_DTPREL16_LO: RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
|
break;
|
||||||
break;
|
case PPCII::MO_DTPREL16_LO:
|
||||||
case PPCII::MO_TLSLD16_LO: RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO;
|
RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
|
||||||
break;
|
break;
|
||||||
case PPCII::MO_TOC16_LO: RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO;
|
case PPCII::MO_TLSLD16_LO:
|
||||||
break;
|
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);
|
const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
|
||||||
|
|
||||||
if (!MO.isJTI() && MO.getOffset())
|
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);
|
const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx);
|
||||||
Expr = MCBinaryExpr::CreateSub(Expr, PB, 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);
|
return MCOperand::CreateExpr(Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user