forked from OSchip/llvm-project
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 llvm-svn: 119127
This commit is contained in:
parent
85e37684bf
commit
6566112e9c
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue