diff options
Diffstat (limited to 'lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp')
| -rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp | 75 | 
1 files changed, 44 insertions, 31 deletions
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index 21183024a509..2223cd623cb5 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -12,15 +12,17 @@  //===----------------------------------------------------------------------===//  #define DEBUG_TYPE "mccodeemitter" -#include "MCTargetDesc/PPCBaseInfo.h" +#include "MCTargetDesc/PPCMCTargetDesc.h"  #include "MCTargetDesc/PPCFixupKinds.h" +#include "llvm/ADT/Statistic.h"  #include "llvm/MC/MCCodeEmitter.h" -#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h"  #include "llvm/MC/MCInst.h"  #include "llvm/MC/MCInstrInfo.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/MC/MCSubtargetInfo.h"  #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h"  using namespace llvm;  STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); @@ -31,24 +33,17 @@ class PPCMCCodeEmitter : public MCCodeEmitter {    void operator=(const PPCMCCodeEmitter &) LLVM_DELETED_FUNCTION;    const MCSubtargetInfo &STI; +  const MCContext &CTX;    Triple TT;  public:    PPCMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,                     MCContext &ctx) -    : STI(sti), TT(STI.getTargetTriple()) { +    : STI(sti), CTX(ctx), TT(STI.getTargetTriple()) {    }    ~PPCMCCodeEmitter() {} -  bool is64BitMode() const { -    return (STI.getFeatureBits() & PPC::Feature64Bit) != 0; -  } - -  bool isSVR4ABI() const { -    return TT.isMacOSX() == 0; -  } -    unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo,                                 SmallVectorImpl<MCFixup> &Fixups) const;    unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo, @@ -61,6 +56,8 @@ public:                              SmallVectorImpl<MCFixup> &Fixups) const;    unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,                               SmallVectorImpl<MCFixup> &Fixups) const; +  unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo, +                             SmallVectorImpl<MCFixup> &Fixups) const;    unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,                                 SmallVectorImpl<MCFixup> &Fixups) const; @@ -77,11 +74,11 @@ public:                           SmallVectorImpl<MCFixup> &Fixups) const {      uint64_t Bits = getBinaryCodeForInstr(MI, Fixups); -    // BL8_NOPELF and BLA8_NOP_ELF is both size of 8 bacause of the -    // following 'nop'. +    // BL8_NOP etc. all have a size of 8 because of the following 'nop'.      unsigned Size = 4; // FIXME: Have Desc.getSize() return the correct value!      unsigned Opcode = MI.getOpcode(); -    if (Opcode == PPC::BL8_NOP_ELF || Opcode == PPC::BLA8_NOP_ELF) +    if (Opcode == PPC::BL8_NOP || Opcode == PPC::BLA8_NOP || +        Opcode == PPC::BL8_NOP_TLSGD || Opcode == PPC::BL8_NOP_TLSLD)        Size = 8;      // Output the constant in big endian byte order. @@ -114,6 +111,17 @@ getDirectBrEncoding(const MCInst &MI, unsigned OpNo,    // Add a fixup for the branch target.    Fixups.push_back(MCFixup::Create(0, MO.getExpr(),                                     (MCFixupKind)PPC::fixup_ppc_br24)); + +  // For special TLS calls, add another fixup for the symbol.  Apparently +  // BL8_NOP, BL8_NOP_TLSGD, and BL8_NOP_TLSLD are sufficiently +  // similar that TblGen will not generate a separate case for the latter +  // two, so this is the only way to get the extra fixup generated. +  unsigned Opcode = MI.getOpcode(); +  if (Opcode == PPC::BL8_NOP_TLSGD || Opcode == PPC::BL8_NOP_TLSLD) { +    const MCOperand &MO2 = MI.getOperand(OpNo+1); +    Fixups.push_back(MCFixup::Create(0, MO2.getExpr(), +                                     (MCFixupKind)PPC::fixup_ppc_nofixup)); +  }    return 0;  } @@ -162,12 +170,8 @@ unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,      return (getMachineOpValue(MI, MO, Fixups) & 0xFFFF) | RegBits;    // Add a fixup for the displacement field. -  if (isSVR4ABI() && is64BitMode()) -    Fixups.push_back(MCFixup::Create(0, MO.getExpr(), -                                     (MCFixupKind)PPC::fixup_ppc_toc16)); -  else -    Fixups.push_back(MCFixup::Create(0, MO.getExpr(), -                                     (MCFixupKind)PPC::fixup_ppc_lo16)); +  Fixups.push_back(MCFixup::Create(0, MO.getExpr(), +                                   (MCFixupKind)PPC::fixup_ppc_lo16));    return RegBits;  } @@ -183,17 +187,26 @@ unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,    if (MO.isImm())      return (getMachineOpValue(MI, MO, Fixups) & 0x3FFF) | RegBits; -  // Add a fixup for the branch target. -  if (isSVR4ABI() && is64BitMode()) -    Fixups.push_back(MCFixup::Create(0, MO.getExpr(), -                                     (MCFixupKind)PPC::fixup_ppc_toc16_ds)); -  else -    Fixups.push_back(MCFixup::Create(0, MO.getExpr(), -                                     (MCFixupKind)PPC::fixup_ppc_lo14)); +  // Add a fixup for the displacement field. +  Fixups.push_back(MCFixup::Create(0, MO.getExpr(), +                                   (MCFixupKind)PPC::fixup_ppc_lo16_ds));    return RegBits;  } +unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo, +                                       SmallVectorImpl<MCFixup> &Fixups) const { +  const MCOperand &MO = MI.getOperand(OpNo); +  if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups); +   +  // Add a fixup for the TLS register, which simply provides a relocation +  // hint to the linker that this statement is part of a relocation sequence. +  // Return the thread-pointer register's encoding. +  Fixups.push_back(MCFixup::Create(0, MO.getExpr(), +                                   (MCFixupKind)PPC::fixup_ppc_tlsreg)); +  return CTX.getRegisterInfo().getEncodingValue(PPC::X13); +} +  unsigned PPCMCCodeEmitter::  get_crbitm_encoding(const MCInst &MI, unsigned OpNo,                      SmallVectorImpl<MCFixup> &Fixups) const { @@ -202,7 +215,7 @@ get_crbitm_encoding(const MCInst &MI, unsigned OpNo,            MI.getOpcode() == PPC::MFOCRF ||            MI.getOpcode() == PPC::MTCRF8) &&           (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); -  return 0x80 >> getPPCRegisterNumbering(MO.getReg()); +  return 0x80 >> CTX.getRegisterInfo().getEncodingValue(MO.getReg());  } @@ -214,7 +227,7 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,      // The GPR operand should come through here though.      assert((MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MFOCRF) ||             MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); -    return getPPCRegisterNumbering(MO.getReg()); +    return CTX.getRegisterInfo().getEncodingValue(MO.getReg());    }    assert(MO.isImm() &&  | 
