[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