forked from OSchip/llvm-project
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
This commit is contained in:
parent
9e7d8c0313
commit
79fa37152a
|
@ -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:
|
||||
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<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);
|
||||
}
|
||||
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"
|
||||
|
|
|
@ -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
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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<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 {
|
||||
|
|
Loading…
Reference in New Issue