[llvm-commits] [llvm] PPC64 TOC support

Roman Divacky rdivacky at freebsd.org
Tue Aug 14 11:52:12 PDT 2012


After applying this patch not even a hello world can be compiled
(assembled), with just this patch I am getting:

Invalid variant kind
UNREACHABLE executed at MCExpr.cpp:228!

when I add the MCJIT patch too, it finishes the asm emission but
the asm does not like:

.quad   .TOC. at tocbase@TOC

should it be

.quad   .TOC. at tocbase

instead?

Anyway, please try to send patches that can be applied/committed
on itself. Also, previously the patch seems to have contained
more stuff. What happened to it (the .td encoding changes) ?

On Tue, Aug 14, 2012 at 03:07:45PM -0300, Adhemerval Zanella wrote:
> This patch adds preliminary small code (-mcmodel=small for GCC) TOC
> support for PPC64 code generation. I'm still working on checking the
> if llvm needs more relocation code generation as well if on some 
> proper tests to add.
> 
> -- 
> Adhemerval Zanella Netto
>   Software Engineer
>   Linux Technology Center Brazil
>   Toolchain / GLIBC on Power Architecture
>   azanella at linux.vnet.ibm.com / azanella at br.ibm.com
>   +55 61 8642-9890
> 

> Index: lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
> ===================================================================
> --- lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp	(revision 161879)
> +++ lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp	(working copy)
> @@ -15,6 +15,7 @@
>  #include "MCTargetDesc/PPCBaseInfo.h"
>  #include "MCTargetDesc/PPCFixupKinds.h"
>  #include "llvm/MC/MCCodeEmitter.h"
> +#include "llvm/MC/MCSubtargetInfo.h"
>  #include "llvm/MC/MCInst.h"
>  #include "llvm/ADT/Statistic.h"
>  #include "llvm/Support/raw_ostream.h"
> @@ -27,14 +28,26 @@
>  class PPCMCCodeEmitter : public MCCodeEmitter {
>    PPCMCCodeEmitter(const PPCMCCodeEmitter &); // DO NOT IMPLEMENT
>    void operator=(const PPCMCCodeEmitter &);   // DO NOT IMPLEMENT
> +
> +  const MCSubtargetInfo &STI;
> +  Triple TT;
>    
>  public:
>    PPCMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
> -                   MCContext &ctx) {
> +                   MCContext &ctx) 
> +    : STI(sti), 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,
> @@ -43,6 +56,8 @@
>                             SmallVectorImpl<MCFixup> &Fixups) const;
>    unsigned getLO16Encoding(const MCInst &MI, unsigned OpNo,
>                             SmallVectorImpl<MCFixup> &Fixups) const;
> +  unsigned getTOCEncoding(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,
> @@ -59,6 +74,7 @@
>    // binary encoding for an instruction.
>    uint64_t getBinaryCodeForInstr(const MCInst &MI,
>                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +
>    void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>                           SmallVectorImpl<MCFixup> &Fixups) const {
>      unsigned Bits = getBinaryCodeForInstr(MI, Fixups);
> @@ -71,7 +87,7 @@
>      
>      ++MCNumEmitted;  // Keep track of the # of mi's emitted.
>    }
> -  
> +
>  };
>    
>  } // end anonymous namespace
> @@ -128,6 +144,17 @@
>    return 0;
>  }
>  
> +
> +unsigned PPCMCCodeEmitter::getTOCEncoding(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);
> +  
> +  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
> +                                   (MCFixupKind)PPC::fixup_ppc_toc));
> +  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
> @@ -140,8 +167,12 @@
>      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));
> +  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));
>    return RegBits;
>  }
>  
> @@ -158,12 +189,15 @@
>      return (getMachineOpValue(MI, MO, Fixups) & 0x3FFF) | RegBits;
>    
>    // Add a fixup for the branch target.
> -  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
> -                                   (MCFixupKind)PPC::fixup_ppc_lo14));
> +  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));
>    return RegBits;
>  }
>  
> -
>  unsigned PPCMCCodeEmitter::
>  get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
>                      SmallVectorImpl<MCFixup> &Fixups) const {
> Index: lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
> ===================================================================
> --- lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp	(revision 161879)
> +++ lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp	(working copy)
> @@ -29,7 +29,12 @@
>    case FK_Data_1:
>    case FK_Data_2:
>    case FK_Data_4:
> +  case FK_Data_8:
> +  case PPC::fixup_ppc_toc:
>      return Value;
> +  case PPC::fixup_ppc_lo14:
> +  case PPC::fixup_ppc_toc16_ds:
> +    return (Value & 0xffff) >> 2;
>    case PPC::fixup_ppc_brcond14:
>      return Value & 0x3ffc;
>    case PPC::fixup_ppc_br24:
> @@ -40,6 +45,7 @@
>  #endif
>    case PPC::fixup_ppc_ha16:
>      return ((Value >> 16) + ((Value & 0x8000) ? 1 : 0)) & 0xffff;
> +  case PPC::fixup_ppc_toc16:
>    case PPC::fixup_ppc_lo16:
>      return Value & 0xffff;
>    }
> @@ -72,7 +78,10 @@
>        { "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 }
> +      { "fixup_ppc_lo14",        16,     14,   0 },
> +      { "fixup_ppc_toc",          0,     64,   0 },
> +      { "fixup_ppc_toc16",       16,     16,   0 },
> +      { "fixup_ppc_toc16_ds",    16,     14,   0 }
>      };
>  
>      if (Kind < FirstTargetFixupKind)
> Index: lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
> ===================================================================
> --- lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h	(revision 161879)
> +++ lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h	(working copy)
> @@ -34,6 +34,16 @@
>    /// fixup_ppc_lo14 - A 14-bit fixup corresponding to lo16(_foo) for instrs
>    /// like 'std'.
>    fixup_ppc_lo14,
> +
> +  /// fixup_ppc_toc - Insert value of TOC base (.TOC.).
> +  fixup_ppc_toc,
> +
> +  /// fixup_ppc_toc16 - A 16-bit signed fixup relative to the TOC base.
> +  fixup_ppc_toc16,
> +
> +  /// fixup_ppc_toc16_ds - A 14-bit signed fixup relative to the TOC base with
> +  /// implied 2 zero bits
> +  fixup_ppc_toc16_ds,
>    
>    // Marker
>    LastTargetFixupKind,
> Index: lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
> ===================================================================
> --- lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp	(revision 161879)
> +++ lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp	(working copy)
> @@ -10,6 +10,8 @@
>  #include "MCTargetDesc/PPCFixupKinds.h"
>  #include "MCTargetDesc/PPCMCTargetDesc.h"
>  #include "llvm/MC/MCELFObjectWriter.h"
> +#include "llvm/MC/MCExpr.h"
> +#include "llvm/MC/MCValue.h"
>  #include "llvm/Support/ErrorHandling.h"
>  
>  using namespace llvm;
> @@ -41,6 +43,9 @@
>                                               bool IsPCRel,
>                                               bool IsRelocWithSymbol,
>                                               int64_t Addend) const {
> +  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
> +    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
> +
>    // determine the type of the relocation
>    unsigned Type;
>    if (IsPCRel) {
> @@ -72,6 +77,26 @@
>      case PPC::fixup_ppc_lo14:
>        Type = ELF::R_PPC_ADDR14;
>        break;
> +    case PPC::fixup_ppc_toc:
> +      Type = ELF::R_PPC64_TOC;
> +      break;
> +    case PPC::fixup_ppc_toc16:
> +      Type = ELF::R_PPC64_TOC16;
> +      break;
> +    case PPC::fixup_ppc_toc16_ds:
> +      Type = ELF::R_PPC64_TOC16_DS;
> +      break;
> +    case FK_Data_8:
> +      switch (Modifier) {
> +      default: llvm_unreachable("Unsupported Modifier");
> +      case MCSymbolRefExpr::VK_PPC_TOC:
> +        Type = ELF::R_PPC64_TOC;
> +        break;
> +      case MCSymbolRefExpr::VK_None:
> +        Type = ELF::R_PPC64_ADDR64;
> +	break;
> +      }
> +      break;
>      case FK_Data_4:
>        Type = ELF::R_PPC_ADDR32;
>        break;
> Index: lib/Target/PowerPC/PPCInstr64Bit.td
> ===================================================================
> --- lib/Target/PowerPC/PPCInstr64Bit.td	(revision 161879)
> +++ lib/Target/PowerPC/PPCInstr64Bit.td	(working copy)
> @@ -29,6 +29,9 @@
>    let PrintMethod = "printSymbolLo";
>    let EncoderMethod = "getLO16Encoding";
>  }
> +def tocentry : Operand<iPTR> {
> +  let MIOperandInfo = (ops i32imm:$imm);
> +}
>  
>  //===----------------------------------------------------------------------===//
>  // 64-bit transformation functions.
> @@ -624,6 +627,14 @@
>                    "",
>                    [(set G8RC:$rD,
>                       (PPCtoc_entry tglobaladdr:$disp, G8RC:$reg))]>, isPPC64;
> +def LDtocJTI: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
> +                  "",
> +                  [(set G8RC:$rD,
> +                     (PPCtoc_entry tjumptable:$disp, G8RC:$reg))]>, isPPC64;
> +def LDtocCPT: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
> +                  "",
> +                  [(set G8RC:$rD,
> +                     (PPCtoc_entry tconstpool:$disp, G8RC:$reg))]>, isPPC64;
>  
>  let hasSideEffects = 1 in { 
>  let RST = 2, DS_RA = 0 in // FIXME: Should be a pseudo.
> Index: lib/Target/PowerPC/PPCInstrInfo.td
> ===================================================================
> --- lib/Target/PowerPC/PPCInstrInfo.td	(revision 161879)
> +++ lib/Target/PowerPC/PPCInstrInfo.td	(working copy)
> @@ -330,9 +330,6 @@
>    let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg);
>    let EncoderMethod = "getMemRIXEncoding";
>  }
> -def tocentry : Operand<iPTR> {
> -  let MIOperandInfo = (ops i32imm:$imm);
> -}
>  
>  // PowerPC Predicate operand.  20 = (0<<5)|20 = always, CR0 is a dummy reg
>  // that doesn't matter.
> Index: lib/Target/PowerPC/PPCISelLowering.cpp
> ===================================================================
> --- lib/Target/PowerPC/PPCISelLowering.cpp	(revision 161879)
> +++ lib/Target/PowerPC/PPCISelLowering.cpp	(working copy)
> @@ -106,7 +106,7 @@
>    // from FP_ROUND:  that rounds to nearest, this rounds to zero.
>    setOperationAction(ISD::FP_ROUND_INREG, MVT::ppcf128, Custom);
>  
> -  // We do not currently implment this libm ops for PowerPC.
> +  // We do not currently implement these libm ops for PowerPC.
>    setOperationAction(ISD::FFLOOR, MVT::ppcf128, Expand);
>    setOperationAction(ISD::FCEIL,  MVT::ppcf128, Expand);
>    setOperationAction(ISD::FTRUNC, MVT::ppcf128, Expand);
> @@ -1204,6 +1204,14 @@
>    ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
>    const Constant *C = CP->getConstVal();
>  
> +  // 64-bit SVR4 ABI code is always position-independent.
> +  // The actual address of the GlobalValue is stored in the TOC.
> +  if (PPCSubTarget.isSVR4ABI() && PPCSubTarget.isPPC64()) {
> +    SDValue GA = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0);
> +    return DAG.getNode(PPCISD::TOC_ENTRY, CP->getDebugLoc(), MVT::i64, GA,
> +                       DAG.getRegister(PPC::X2, MVT::i64));
> +  }
> +
>    unsigned MOHiFlag, MOLoFlag;
>    bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
>    SDValue CPIHi =
> @@ -1217,6 +1225,14 @@
>    EVT PtrVT = Op.getValueType();
>    JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
>  
> +  // 64-bit SVR4 ABI code is always position-independent.
> +  // The actual address of the GlobalValue is stored in the TOC.
> +  if (PPCSubTarget.isSVR4ABI() && PPCSubTarget.isPPC64()) {
> +    SDValue GA = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
> +    return DAG.getNode(PPCISD::TOC_ENTRY, JT->getDebugLoc(), MVT::i64, GA,
> +                       DAG.getRegister(PPC::X2, MVT::i64));
> +  }
> +
>    unsigned MOHiFlag, MOLoFlag;
>    bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
>    SDValue JTIHi = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOHiFlag);
> Index: lib/Target/PowerPC/PPCAsmPrinter.cpp
> ===================================================================
> --- lib/Target/PowerPC/PPCAsmPrinter.cpp	(revision 161879)
> +++ lib/Target/PowerPC/PPCAsmPrinter.cpp	(working copy)
> @@ -345,6 +345,29 @@
>      OutStreamer.EmitLabel(PICBase);
>      return;
>    }
> +  case PPC::LDtocJTI:
> +  case PPC::LDtocCPT: {
> +    // Transform %X3 = LDtoc <ga:@min1>, %X2
> +    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
> +
> +    // Change the opcode to LD, and the global address operand to be a
> +    // reference to the TOC entry we will synthesize later.
> +    TmpInst.setOpcode(PPC::LD);
> +    const MachineOperand &MO = MI->getOperand(1);
> +    assert(MO.isCPI() || MO.isJTI());
> +
> +    // Map symbol -> label of TOC entry
> +    MCSymbol *&TOCEntry = TOC[GetCPISymbol(MO.getIndex())];
> +    if (TOCEntry == 0)
> +      TOCEntry = GetTempSymbol("C", TOCLabelID++);
> +    
> +    const MCExpr *Exp =
> +      MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
> +			      OutContext);
> +    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
> +    OutStreamer.EmitInstruction(TmpInst);
> +    return;
> +  }
>    case PPC::LDtoc: {
>      // Transform %X3 = LDtoc <ga:@min1>, %X2
>      LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
> @@ -361,7 +384,7 @@
>        TOCEntry = GetTempSymbol("C", TOCLabelID++);
>        
>      const MCExpr *Exp =
> -      MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
> +      MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
>                                OutContext);
>      TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
>      OutStreamer.EmitInstruction(TmpInst);
> @@ -405,10 +428,14 @@
>    MCSymbol *Symbol1 = 
>      OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
>    MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC. at tocbase"));
> +  // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
> +  // entry point.
>    OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
> -                        Subtarget.isPPC64() ? 8 : 4/*size*/, 0/*addrspace*/);
> -  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, OutContext),
> -                        Subtarget.isPPC64() ? 8 : 4/*size*/, 0/*addrspace*/);
> +                        8 /* size */, 0 /*addrspace*/);
> +  // Generates a R_PPC64_TOC relocation for TOC base insertion.
> +  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
> +                        MCSymbolRefExpr::VK_PPC_TOC, OutContext),
> +                        8 /* size */, 0 /* addrspace */);
>    OutStreamer.SwitchSection(Current);
>  
>    MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
> @@ -433,8 +460,9 @@
>      for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
>           E = TOC.end(); I != E; ++I) {
>        OutStreamer.EmitLabel(I->second);
> -      OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) +
> -                              "[TC]," + I->first->getName());
> +      MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
> +      OutStreamer.EmitValue(MCSymbolRefExpr::Create(S, OutContext),
> +                            Subtarget.isPPC64() ? 8 : 4/*size*/, 0/*addrspace*/);	
>      }
>    }
>  

> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list