diff options
author | Chris Lattner <sabre@nondot.org> | 2010-11-15 06:33:39 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-11-15 06:33:39 +0000 |
commit | 85cf7d737dd26e984974e072d28225bd00c625c2 (patch) | |
tree | ed57b511a6142d33fc75284afba80626fe7c2d6c | |
parent | b719437325681bec89572cccb53916b7a17f1e60 (diff) | |
download | external_llvm-85cf7d737dd26e984974e072d28225bd00c625c2.zip external_llvm-85cf7d737dd26e984974e072d28225bd00c625c2.tar.gz external_llvm-85cf7d737dd26e984974e072d28225bd00c625c2.tar.bz2 |
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119127 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/PowerPC/PPCCodeEmitter.cpp | 76 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCFixupKinds.h | 12 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstr64Bit.td | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCMCCodeEmitter.cpp | 46 |
5 files changed, 108 insertions, 30 deletions
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 952a456..9335b18 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -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"; diff --git a/lib/Target/PowerPC/PPCFixupKinds.h b/lib/Target/PowerPC/PPCFixupKinds.h index fcf3dba..b3c889e 100644 --- a/lib/Target/PowerPC/PPCFixupKinds.h +++ b/lib/Target/PowerPC/PPCFixupKinds.h @@ -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 diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 53db733..0b96bcd 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -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"; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 269f371..11f84d0 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -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"; diff --git a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp index 5318312..644f46f 100644 --- a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp @@ -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, |