aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-15 05:57:53 +0000
committerChris Lattner <sabre@nondot.org>2010-11-15 05:57:53 +0000
commita9d9ab9673ec73817f3059ea430f1930a5b14948 (patch)
tree7f6d1d9e28dfc30a89d16120253b5dbbaf63c752 /lib
parent3170a3bc04deadfc0a4de5ff3cba7680be548f29 (diff)
downloadexternal_llvm-a9d9ab9673ec73817f3059ea430f1930a5b14948.zip
external_llvm-a9d9ab9673ec73817f3059ea430f1930a5b14948.tar.gz
external_llvm-a9d9ab9673ec73817f3059ea430f1930a5b14948.tar.bz2
split call operands out to their own encoding class, simplifying
code in the JIT. Use this to form the first fixup for the PPC backend, giving us stuff like this: bl L_foo$stub ; encoding: [0b010010AA,A,A,0bAAAAAA01] ; fixup A - offset: 0, value: L_foo$stub, kind: fixup_ppc_br24 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119123 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/PowerPC/PPCCodeEmitter.cpp158
-rw-r--r--lib/Target/PowerPC/PPCFixupKinds.h28
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td1
-rw-r--r--lib/Target/PowerPC/PPCMCCodeEmitter.cpp20
4 files changed, 130 insertions, 77 deletions
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp
index db8e2c5..a5517f0 100644
--- a/lib/Target/PowerPC/PPCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp
@@ -50,15 +50,18 @@ namespace {
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
/// machine instructions.
-
unsigned getBinaryCodeForInstr(const MachineInstr &MI) const;
+
+ MachineRelocation GetRelocation(const MachineOperand &MO,
+ unsigned RelocID) const;
+
/// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
-
unsigned getMachineOpValue(const MachineInstr &MI,
const MachineOperand &MO) const;
unsigned get_crbitm_encoding(const MachineInstr &MI, unsigned OpNo) const;
+ unsigned getCallTargetEncoding(const MachineInstr &MI, unsigned OpNo) const;
const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
@@ -134,12 +137,41 @@ unsigned PPCCodeEmitter::get_crbitm_encoding(const MachineInstr &MI,
return 0x80 >> PPCRegisterInfo::getRegisterNumbering(MO.getReg());
}
+MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO,
+ unsigned RelocID) const {
+ if (MO.isGlobal())
+ return MachineRelocation::getGV(MCE.getCurrentPCOffset(), RelocID,
+ const_cast<GlobalValue *>(MO.getGlobal()),0,
+ isa<Function>(MO.getGlobal()));
+ if (MO.isSymbol())
+ return MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
+ RelocID, MO.getSymbolName(), 0);
+ if (MO.isCPI())
+ return MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
+ RelocID, MO.getIndex(), 0);
+
+ if (MO.isMBB())
+ MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
+ RelocID, MO.getMBB()));
+
+ assert(MO.isJTI());
+ return MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
+ RelocID, MO.getIndex(), 0);
+}
+
+unsigned PPCCodeEmitter::getCallTargetEncoding(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_pcrel_bx));
+ return 0;
+}
+
unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
const MachineOperand &MO) const {
- unsigned rv = 0; // Return value; defaults to 0 for unhandled cases
- // or things that get fixed up later by the JIT.
if (MO.isReg()) {
assert(MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MFOCRF);
return PPCRegisterInfo::getRegisterNumbering(MO.getReg());
@@ -150,81 +182,59 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
if (MO.isGlobal() || MO.isSymbol() || MO.isCPI() || MO.isJTI()) {
unsigned Reloc = 0;
- if (MI.getOpcode() == PPC::BL_Darwin || MI.getOpcode() == PPC::BL8_Darwin ||
- MI.getOpcode() == PPC::BL_SVR4 || MI.getOpcode() == PPC::BL8_ELF ||
- MI.getOpcode() == PPC::TAILB || MI.getOpcode() == PPC::TAILB8)
- Reloc = PPC::reloc_pcrel_bx;
- else {
- if (TM.getRelocationModel() == Reloc::PIC_) {
- assert(MovePCtoLROffset && "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:
- case PPC::LHA:
- case PPC::LHA8:
- case PPC::LHZ:
- case PPC::LHZ8:
- case PPC::LWZ:
- case PPC::LWZ8:
- case PPC::LFS:
- case PPC::LFD:
-
- // Stores.
- case PPC::STB:
- case PPC::STB8:
- case PPC::STH:
- case PPC::STH8:
- case PPC::STW:
- case PPC::STW8:
- case PPC::STFS:
- case PPC::STFD:
- Reloc = PPC::reloc_absolute_low;
- break;
-
- case PPC::LWA:
- case PPC::LD:
- case PPC::STD:
- case PPC::STD_32:
- Reloc = PPC::reloc_absolute_low_ix;
- break;
- }
- }
+ assert((TM.getRelocationModel() != Reloc::PIC_ || MovePCtoLROffset) &&
+ "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:
+ case PPC::LHA:
+ case PPC::LHA8:
+ case PPC::LHZ:
+ case PPC::LHZ8:
+ case PPC::LWZ:
+ case PPC::LWZ8:
+ case PPC::LFS:
+ case PPC::LFD:
+
+ // Stores.
+ case PPC::STB:
+ case PPC::STB8:
+ case PPC::STH:
+ case PPC::STH8:
+ case PPC::STW:
+ case PPC::STW8:
+ case PPC::STFS:
+ case PPC::STFD:
+ Reloc = PPC::reloc_absolute_low;
+ break;
- MachineRelocation R;
- if (MO.isGlobal()) {
- R = MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
- const_cast<GlobalValue *>(MO.getGlobal()), 0,
- isa<Function>(MO.getGlobal()));
- } else if (MO.isSymbol()) {
- R = MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
- Reloc, MO.getSymbolName(), 0);
- } else if (MO.isCPI()) {
- R = MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
- Reloc, MO.getIndex(), 0);
- } else {
- assert(MO.isJTI());
- R = MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
- Reloc, MO.getIndex(), 0);
+ case PPC::LWA:
+ case PPC::LD:
+ case PPC::STD:
+ case PPC::STD_32:
+ Reloc = PPC::reloc_absolute_low_ix;
+ 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_ && Reloc != PPC::reloc_pcrel_bx){
+ if (TM.getRelocationModel() == Reloc::PIC_) {
assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
R.setConstantVal(-(intptr_t)MovePCtoLROffset - 4);
}
@@ -233,9 +243,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
} else if (MO.isMBB()) {
unsigned Reloc = 0;
unsigned Opcode = MI.getOpcode();
- if (Opcode == PPC::B || Opcode == PPC::BL_Darwin ||
- Opcode == PPC::BLA_Darwin|| Opcode == PPC::BL_SVR4 ||
- Opcode == PPC::BLA_SVR4)
+ if (Opcode == PPC::B)
Reloc = PPC::reloc_pcrel_bx;
else // BCC instruction
Reloc = PPC::reloc_pcrel_bcx;
@@ -249,7 +257,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
llvm_unreachable(0);
}
- return rv;
+ return 0;
}
#include "PPCGenCodeEmitter.inc"
diff --git a/lib/Target/PowerPC/PPCFixupKinds.h b/lib/Target/PowerPC/PPCFixupKinds.h
new file mode 100644
index 0000000..d1d44f5
--- /dev/null
+++ b/lib/Target/PowerPC/PPCFixupKinds.h
@@ -0,0 +1,28 @@
+//===-- PPCFixupKinds.h - PPC Specific Fixup Entries ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PPC_PPCFIXUPKINDS_H
+#define LLVM_PPC_PPCFIXUPKINDS_H
+
+#include "llvm/MC/MCFixup.h"
+
+namespace llvm {
+namespace PPC {
+enum Fixups {
+ // fixup_ppc_br24 - 24-bit PC relative relocation for calls like 'bl'.
+ fixup_ppc_br24 = FirstTargetFixupKind,
+
+ // Marker
+ LastTargetFixupKind,
+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+};
+}
+}
+
+#endif
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index add8009..c93d955 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -291,6 +291,7 @@ def target : Operand<OtherVT> {
}
def calltarget : Operand<iPTR> {
let PrintMethod = "printCallOperand";
+ let EncoderMethod = "getCallTargetEncoding";
}
def aaddr : Operand<iPTR> {
let PrintMethod = "printAbsAddrOperand";
diff --git a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp
index bbadcb0..67ab665 100644
--- a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp
@@ -14,6 +14,7 @@
#define DEBUG_TYPE "mccodeemitter"
#include "PPC.h"
#include "PPCRegisterInfo.h"
+#include "PPCFixupKinds.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInst.h"
#include "llvm/ADT/Statistic.h"
@@ -37,12 +38,12 @@ public:
~PPCMCCodeEmitter() {}
- unsigned getNumFixupKinds() const { return 0 /*PPC::NumTargetFixupKinds*/; }
+ unsigned getNumFixupKinds() const { return PPC::NumTargetFixupKinds; }
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
const static MCFixupKindInfo Infos[] = {
// name offset bits flags
- { "fixup_arm_pcrel_12", 2, 12, MCFixupKindInfo::FKF_IsPCRel }
+ { "fixup_ppc_br24", 6, 24, MCFixupKindInfo::FKF_IsPCRel }
#if 0
{ "fixup_arm_vfp_pcrel_12", 3, 8, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
@@ -57,6 +58,9 @@ public:
return Infos[Kind - FirstTargetFixupKind];
}
+ unsigned getCallTargetEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const;
@@ -92,6 +96,18 @@ MCCodeEmitter *llvm::createPPCMCCodeEmitter(const Target &, TargetMachine &TM,
}
unsigned PPCMCCodeEmitter::
+getCallTargetEncoding(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_br24));
+ return 0;
+}
+
+unsigned PPCMCCodeEmitter::
get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const {
const MCOperand &MO = MI.getOperand(OpNo);