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/PPCMCCodeEmitter.cpp | |
parent | 17e2c188359769a1df18c42593a94ce0fc2a9a75 (diff) |
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/PPCMCCodeEmitter.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCMCCodeEmitter.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp index 66c0bb72a9..ea5275aa31 100644 --- a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCMCCodeEmitter.cpp @@ -66,6 +66,8 @@ public: SmallVectorImpl<MCFixup> &Fixups) const; unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const; + unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const; unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const; unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo, @@ -147,10 +149,29 @@ unsigned PPCMCCodeEmitter::getLO16Encoding(const MCInst &MI, unsigned OpNo, return 0; } +unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) 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), Fixups) << 16; + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return (getMachineOpValue(MI, MO, Fixups) & 0xFFFF) | RegBits; + + // Add a fixup for the displacement field. + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), + (MCFixupKind)PPC::fixup_ppc_lo16)); + return RegBits; +} + + unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const { // Encode (imm, reg) as a memrix, which has the low 14-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), Fixups) << 14; const MCOperand &MO = MI.getOperand(OpNo); @@ -182,11 +203,9 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); } - if (MO.isImm()) - return MO.getImm(); - - // FIXME. - return 0; + assert(MO.isImm() && + "Relocation required in an instruction that we cannot encode!"); + return MO.getImm(); } |