summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-15 06:33:39 +0000
committerChris Lattner <sabre@nondot.org>2010-11-15 06:33:39 +0000
commit85cf7d737dd26e984974e072d28225bd00c625c2 (patch)
treeed57b511a6142d33fc75284afba80626fe7c2d6c /lib/Target/PowerPC
parentb719437325681bec89572cccb53916b7a17f1e60 (diff)
downloadllvm-85cf7d737dd26e984974e072d28225bd00c625c2.tar.gz
llvm-85cf7d737dd26e984974e072d28225bd00c625c2.tar.bz2
llvm-85cf7d737dd26e984974e072d28225bd00c625c2.tar.xz
implement the start of support for lo16 and ha16, allowing us to get stuff like:
lis r4, ha16(__ZL4init) ; encoding: [0x3c,0x80,A,A] ; fixup A - offset: 0, value: ha16(__ZL4init), kind: fixup_ppc_ha16 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119127 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC')
-rw-r--r--lib/Target/PowerPC/PPCCodeEmitter.cpp76
-rw-r--r--lib/Target/PowerPC/PPCFixupKinds.h12
-rw-r--r--lib/Target/PowerPC/PPCInstr64Bit.td2
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td2
-rw-r--r--lib/Target/PowerPC/PPCMCCodeEmitter.cpp46
5 files changed, 108 insertions, 30 deletions
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp
index 952a45684a..9335b183db 100644
--- a/lib/Target/PowerPC/PPCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp
@@ -63,7 +63,11 @@ namespace {
unsigned get_crbitm_encoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getDirectBrEncoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getCondBrEncoding(const MachineInstr &MI, unsigned OpNo) const;
-
+
+ unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const;
+ unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const;
+ unsigned getLO14Encoding(const MachineInstr &MI, unsigned OpNo) const;
+
const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
/// runOnMachineFunction - emits the given MachineFunction to memory
@@ -140,16 +144,27 @@ unsigned PPCCodeEmitter::get_crbitm_encoding(const MachineInstr &MI,
MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO,
unsigned RelocID) const {
+ // If in PIC mode, we need to encode the negated address of the
+ // 'movepctolr' into the unrelocated field. After relocation, we'll have
+ // &gv-&movepctolr-4 in the imm field. Once &movepctolr is added to the imm
+ // field, we get &gv. This doesn't happen for branch relocations, which are
+ // always implicitly pc relative.
+ intptr_t Cst = 0;
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
+ Cst = -(intptr_t)MovePCtoLROffset - 4;
+ }
+
if (MO.isGlobal())
return MachineRelocation::getGV(MCE.getCurrentPCOffset(), RelocID,
- const_cast<GlobalValue *>(MO.getGlobal()),0,
- isa<Function>(MO.getGlobal()));
+ const_cast<GlobalValue *>(MO.getGlobal()),
+ Cst, isa<Function>(MO.getGlobal()));
if (MO.isSymbol())
return MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
- RelocID, MO.getSymbolName(), 0);
+ RelocID, MO.getSymbolName(), Cst);
if (MO.isCPI())
return MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
- RelocID, MO.getIndex(), 0);
+ RelocID, MO.getIndex(), Cst);
if (MO.isMBB())
MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
@@ -157,7 +172,7 @@ MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO,
assert(MO.isJTI());
return MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
- RelocID, MO.getIndex(), 0);
+ RelocID, MO.getIndex(), Cst);
}
unsigned PPCCodeEmitter::getDirectBrEncoding(const MachineInstr &MI,
@@ -176,6 +191,33 @@ unsigned PPCCodeEmitter::getCondBrEncoding(const MachineInstr &MI,
return 0;
}
+unsigned PPCCodeEmitter::getHA16Encoding(const MachineInstr &MI,
+ unsigned OpNo) const {
+ const MachineOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
+
+ MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_high));
+ return 0;
+}
+
+unsigned PPCCodeEmitter::getLO16Encoding(const MachineInstr &MI,
+ unsigned OpNo) const {
+ const MachineOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
+
+ MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low));
+ return 0;
+}
+
+unsigned PPCCodeEmitter::getLO14Encoding(const MachineInstr &MI,
+ unsigned OpNo) const {
+ const MachineOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
+
+ MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low_ix));
+ return 0;
+}
+
unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
const MachineOperand &MO) const {
@@ -194,15 +236,6 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
"MovePCtoLR not seen yet?");
switch (MI.getOpcode()) {
default: MI.dump(); llvm_unreachable("Unknown instruction for relocation!");
- case PPC::LIS:
- case PPC::LIS8:
- case PPC::ADDIS:
- case PPC::ADDIS8:
- Reloc = PPC::reloc_absolute_high; // Pointer to symbol
- break;
- case PPC::LI:
- case PPC::LI8:
- case PPC::LA:
// Loads.
case PPC::LBZ:
case PPC::LBZ8:
@@ -235,18 +268,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
break;
}
- MachineRelocation R = GetRelocation(MO, Reloc);
-
- // If in PIC mode, we need to encode the negated address of the
- // 'movepctolr' into the unrelocated field. After relocation, we'll have
- // &gv-&movepctolr-4 in the imm field. Once &movepctolr is added to the imm
- // field, we get &gv. This doesn't happen for branch relocations, which are
- // always implicitly pc relative.
- if (TM.getRelocationModel() == Reloc::PIC_) {
- assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
- R.setConstantVal(-(intptr_t)MovePCtoLROffset - 4);
- }
- MCE.addRelocation(R);
+ MCE.addRelocation(GetRelocation(MO, Reloc));
} else {
#ifndef NDEBUG
errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
diff --git a/lib/Target/PowerPC/PPCFixupKinds.h b/lib/Target/PowerPC/PPCFixupKinds.h
index fcf3dbaa6c..b3c889e3f8 100644
--- a/lib/Target/PowerPC/PPCFixupKinds.h
+++ b/lib/Target/PowerPC/PPCFixupKinds.h
@@ -23,6 +23,18 @@ enum Fixups {
/// branches.
fixup_ppc_brcond14,
+ /// fixup_ppc_lo16 - A 16-bit fixup corresponding to lo16(_foo) for instrs
+ /// like 'li'.
+ fixup_ppc_lo16,
+
+ /// fixup_ppc_ha16 - A 16-bit fixup corresponding to ha16(_foo) for instrs
+ /// like 'lis'.
+ fixup_ppc_ha16,
+
+ /// fixup_ppc_lo14 - A 14-bit fixup corresponding to lo16(_foo) for instrs
+ /// like 'std'.
+ fixup_ppc_lo14,
+
// Marker
LastTargetFixupKind,
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td
index 53db733656..0b96bcd635 100644
--- a/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -23,9 +23,11 @@ def u16imm64 : Operand<i64> {
}
def symbolHi64 : Operand<i64> {
let PrintMethod = "printSymbolHi";
+ let EncoderMethod = "getHA16Encoding";
}
def symbolLo64 : Operand<i64> {
let PrintMethod = "printSymbolLo";
+ let EncoderMethod = "getLO16Encoding";
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index 269f371bda..11f84d0d84 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -302,9 +302,11 @@ def aaddr : Operand<iPTR> {
def piclabel: Operand<iPTR> {}
def symbolHi: Operand<i32> {
let PrintMethod = "printSymbolHi";
+ let EncoderMethod = "getHA16Encoding";
}
def symbolLo: Operand<i32> {
let PrintMethod = "printSymbolLo";
+ let EncoderMethod = "getLO16Encoding";
}
def crbitm: Operand<i8> {
let PrintMethod = "printcrbitm";
diff --git a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp
index 53183127c2..644f46f21d 100644
--- a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp
@@ -44,7 +44,10 @@ public:
const static MCFixupKindInfo Infos[] = {
// name offset bits flags
{ "fixup_ppc_br24", 6, 24, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel }
+ { "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_ppc_lo16", 16, 16, 0 },
+ { "fixup_ppc_ha16", 16, 16, 0 },
+ { "fixup_ppc_lo14", 16, 14, 0 }
};
if (Kind < FirstTargetFixupKind)
@@ -57,10 +60,14 @@ public:
unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const;
-
unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const;
-
+ unsigned getHA16Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+ unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+ unsigned getLO14Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const;
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const;
@@ -118,6 +125,39 @@ unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
return 0;
}
+unsigned PPCMCCodeEmitter::getHA16Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
+
+ // Add a fixup for the branch target.
+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
+ (MCFixupKind)PPC::fixup_ppc_ha16));
+ return 0;
+}
+
+unsigned PPCMCCodeEmitter::getLO16Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
+
+ // Add a fixup for the branch target.
+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
+ (MCFixupKind)PPC::fixup_ppc_lo16));
+ return 0;
+}
+
+unsigned PPCMCCodeEmitter::getLO14Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
+
+ // Add a fixup for the branch target.
+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
+ (MCFixupKind)PPC::fixup_ppc_lo14));
+ return 0;
+}
+
unsigned PPCMCCodeEmitter::
get_crbitm_encoding(const MCInst &MI, unsigned OpNo,