diff options
author | Chris Lattner <sabre@nondot.org> | 2010-11-15 08:22:03 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-11-15 08:22:03 +0000 |
commit | b7035d04421112a4585245f67bc564170ec45b29 (patch) | |
tree | ff86ab219c3c14c38b6b39f42e73d545d30f0ca0 /lib/Target/PowerPC/PPCCodeEmitter.cpp | |
parent | 17e2c188359769a1df18c42593a94ce0fc2a9a75 (diff) | |
download | llvm-b7035d04421112a4585245f67bc564170ec45b29.tar.gz llvm-b7035d04421112a4585245f67bc564170ec45b29.tar.bz2 llvm-b7035d04421112a4585245f67bc564170ec45b29.tar.xz |
split out an encoder for memri operands, allowing a relocation to be plopped
into the immediate field. This allows us to encode stuff like this:
lbz r3, lo16(__ZL4init)(r4) ; globalopt.cpp:5
; encoding: [0x88,0x64,A,A]
; fixup A - offset: 0, value: lo16(__ZL4init), kind: fixup_ppc_lo16
stw r3, lo16(__ZL1s)(r5) ; globalopt.cpp:6
; encoding: [0x90,0x65,A,A]
; fixup A - offset: 0, value: lo16(__ZL1s), kind: fixup_ppc_lo16
With this, we should have a completely function MCCodeEmitter for PPC, wewt.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119134 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCCodeEmitter.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCCodeEmitter.cpp | 63 |
1 files changed, 20 insertions, 43 deletions
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 48848e3713..46332158fb 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -66,6 +66,7 @@ namespace { unsigned getHA16Encoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const; + unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const; const char *getPassName() const { return "PowerPC Machine Code Emitter"; } @@ -209,6 +210,22 @@ unsigned PPCCodeEmitter::getLO16Encoding(const MachineInstr &MI, return 0; } +unsigned PPCCodeEmitter::getMemRIEncoding(const MachineInstr &MI, + unsigned OpNo) const { + // Encode (imm, reg) as a memri, which has the low 16-bits as the + // displacement and the next 5 bits as the register #. + assert(MI.getOperand(OpNo+1).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 16; + + const MachineOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return (getMachineOpValue(MI, MO) & 0xFFFF) | RegBits; + + // Add a fixup for the displacement field. + MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low)); + return RegBits; +} + unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const { // Encode (imm, reg) as a memrix, which has the low 14-bits as the @@ -233,49 +250,9 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); } - if (MO.isImm()) - return MO.getImm(); - - if (MO.isGlobal() || MO.isSymbol() || MO.isCPI() || MO.isJTI()) { - unsigned Reloc = 0; - assert((TM.getRelocationModel() != Reloc::PIC_ || MovePCtoLROffset) && - "MovePCtoLR not seen yet?"); - switch (MI.getOpcode()) { - default: MI.dump(); llvm_unreachable("Unknown instruction for relocation!"); - // 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; - } - - MCE.addRelocation(GetRelocation(MO, Reloc)); - } else { -#ifndef NDEBUG - errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; -#endif - llvm_unreachable(0); - } - - return 0; + assert(MO.isImm() && + "Relocation required in an instruction that we cannot encode!"); + return MO.getImm(); } #include "PPCGenCodeEmitter.inc" |