diff options
author | Chris Lattner <sabre@nondot.org> | 2010-11-15 05:57:53 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-11-15 05:57:53 +0000 |
commit | a9d9ab9673ec73817f3059ea430f1930a5b14948 (patch) | |
tree | 7f6d1d9e28dfc30a89d16120253b5dbbaf63c752 /lib | |
parent | 3170a3bc04deadfc0a4de5ff3cba7680be548f29 (diff) | |
download | external_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.cpp | 158 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCFixupKinds.h | 28 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 1 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCMCCodeEmitter.cpp | 20 |
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); |