From 79fa37152a81f338b94b93ec0d08f45a5812d6b9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 15 Nov 2010 05:57:53 +0000 Subject: [PATCH] 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 llvm-svn: 119123 --- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp | 154 ++++++++++--------- llvm/lib/Target/PowerPC/PPCFixupKinds.h | 28 ++++ llvm/lib/Target/PowerPC/PPCInstrInfo.td | 1 + llvm/lib/Target/PowerPC/PPCMCCodeEmitter.cpp | 20 ++- 4 files changed, 128 insertions(+), 75 deletions(-) create mode 100644 llvm/lib/Target/PowerPC/PPCFixupKinds.h diff --git a/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp index db8e2c544a81..a5517f091f26 100644 --- a/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/llvm/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(MO.getGlobal()),0, + isa(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: + 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; + // 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; - } + case PPC::LWA: + case PPC::LD: + case PPC::STD: + case PPC::STD_32: + Reloc = PPC::reloc_absolute_low_ix; + break; } - MachineRelocation R; - if (MO.isGlobal()) { - R = MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, - const_cast(MO.getGlobal()), 0, - isa(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); - } + 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/llvm/lib/Target/PowerPC/PPCFixupKinds.h b/llvm/lib/Target/PowerPC/PPCFixupKinds.h new file mode 100644 index 000000000000..d1d44f54ff56 --- /dev/null +++ b/llvm/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/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index add8009b267f..c93d9554748e 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -291,6 +291,7 @@ def target : Operand { } def calltarget : Operand { let PrintMethod = "printCallOperand"; + let EncoderMethod = "getCallTargetEncoding"; } def aaddr : Operand { let PrintMethod = "printAbsAddrOperand"; diff --git a/llvm/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/PPCMCCodeEmitter.cpp index bbadcb07918d..67ab66537a46 100644 --- a/llvm/lib/Target/PowerPC/PPCMCCodeEmitter.cpp +++ b/llvm/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 &Fixups) const; + unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups) const; @@ -91,6 +95,18 @@ MCCodeEmitter *llvm::createPPCMCCodeEmitter(const Target &, TargetMachine &TM, return new PPCMCCodeEmitter(TM, Ctx); } +unsigned PPCMCCodeEmitter:: +getCallTargetEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &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 &Fixups) const {