From 6c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 3 Feb 2012 04:33:00 +0000 Subject: [PATCH] Add a new MachineJumpTableInfo entry type, EK_GPRel64BlockAddress, which is needed to emit a 64-bit gp-relative relocation entry. Make changes necessary for emitting jump tables which have entries with directive .gpdword. This patch does not implement the parts needed for direct object emission or JIT. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149668 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineJumpTableInfo.h | 7 +++++- include/llvm/MC/MCAsmInfo.h | 6 +++++ include/llvm/MC/MCStreamer.h | 7 ++++++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 9 ++++++++ lib/CodeGen/MachineFunction.cpp | 4 ++++ lib/ExecutionEngine/JIT/JITEmitter.cpp | 3 +++ lib/MC/MCAsmInfo.cpp | 1 + lib/MC/MCAsmStreamer.cpp | 8 +++++++ lib/MC/MCStreamer.cpp | 4 ++++ .../Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 1 + lib/Target/Mips/MipsISelLowering.cpp | 7 ++++++ lib/Target/Mips/MipsISelLowering.h | 2 ++ lib/Target/Mips/MipsInstrInfo.cpp | 9 +++++--- test/CodeGen/Mips/2010-07-20-Switch.ll | 22 ++++++++++++++++++- 14 files changed, 85 insertions(+), 5 deletions(-) diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index 62643497655..6bd6682dd39 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -47,7 +47,12 @@ public: /// EK_BlockAddress - Each entry is a plain address of block, e.g.: /// .word LBB123 EK_BlockAddress, - + + /// EK_GPRel64BlockAddress - Each entry is an address of block, encoded + /// with a relocation as gp-relative, e.g.: + /// .gpdword LBB123 + EK_GPRel64BlockAddress, + /// EK_GPRel32BlockAddress - Each entry is an address of block, encoded /// with a relocation as gp-relative, e.g.: /// .gprel32 LBB123 diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 5accabcd9f4..5027a8f424d 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -180,6 +180,11 @@ namespace llvm { const char *JT32Begin; // Defaults to "$a." bool SupportsDataRegions; + /// GPRel64Directive - if non-null, a directive that is used to emit a word + /// which should be relocated as a 64-bit GP-relative offset, e.g. .gpdword + /// on Mips. + const char *GPRel64Directive; // Defaults to NULL. + /// GPRel32Directive - if non-null, a directive that is used to emit a word /// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword /// on Mips or .gprel32 on Alpha. @@ -376,6 +381,7 @@ namespace llvm { const char *getData64bitsDirective(unsigned AS = 0) const { return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS); } + const char *getGPRel64Directive() const { return GPRel64Directive; } const char *getGPRel32Directive() const { return GPRel32Directive; } /// [Code|Data]Begin label name accessors. diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index c141dfbc96e..99323067c47 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -441,6 +441,13 @@ namespace llvm { void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, unsigned AddrSpace = 0); + /// EmitGPRel64Value - Emit the expression @p Value into the output as a + /// gprel64 (64-bit GP relative) value. + /// + /// This is used to implement assembler directives such as .gpdword on + /// targets that support them. + virtual void EmitGPRel64Value(const MCExpr *Value); + /// EmitGPRel32Value - Emit the expression @p Value into the output as a /// gprel32 (32-bit GP relative) value. /// diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 4c093665c8c..43af3423de9 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1155,6 +1155,15 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, return; } + case MachineJumpTableInfo::EK_GPRel64BlockAddress: { + // EK_GPRel64BlockAddress - Each entry is an address of block, encoded + // with a relocation as gp-relative, e.g.: + // .gpdword LBB123 + MCSymbol *MBBSym = MBB->getSymbol(); + OutStreamer.EmitGPRel64Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); + return; + } + case MachineJumpTableInfo::EK_LabelDifference32: { // EK_LabelDifference32 - Each entry is the address of the block minus // the address of the jump table. This is used for PIC jump tables where diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 3aaae855651..8195f9f6790 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -530,6 +530,8 @@ unsigned MachineJumpTableInfo::getEntrySize(const TargetData &TD) const { switch (getEntryKind()) { case MachineJumpTableInfo::EK_BlockAddress: return TD.getPointerSize(); + case MachineJumpTableInfo::EK_GPRel64BlockAddress: + return 8; case MachineJumpTableInfo::EK_GPRel32BlockAddress: case MachineJumpTableInfo::EK_LabelDifference32: case MachineJumpTableInfo::EK_Custom32: @@ -549,6 +551,8 @@ unsigned MachineJumpTableInfo::getEntryAlignment(const TargetData &TD) const { switch (getEntryKind()) { case MachineJumpTableInfo::EK_BlockAddress: return TD.getPointerABIAlignment(); + case MachineJumpTableInfo::EK_GPRel64BlockAddress: + return TD.getABIIntegerTypeAlignment(64); case MachineJumpTableInfo::EK_GPRel32BlockAddress: case MachineJumpTableInfo::EK_LabelDifference32: case MachineJumpTableInfo::EK_Custom32: diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index 91305fd3847..26201c397d1 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -1161,6 +1161,9 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { } break; } + case MachineJumpTableInfo::EK_GPRel64BlockAddress: + assert(false && + "JT Info emission not implemented for GPRel64BlockAddress yet."); } } diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index b1e1bdf6c75..582d21fe90c 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -67,6 +67,7 @@ MCAsmInfo::MCAsmInfo() { AlignDirective = "\t.align\t"; AlignmentIsInBytes = true; TextAlignFillValue = 0; + GPRel64Directive = 0; GPRel32Directive = 0; GlobalDirective = "\t.globl\t"; HasSetDirective = true; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index afad5d530cf..ba6dee7cc2d 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -186,6 +186,8 @@ public: virtual void EmitSLEB128Value(const MCExpr *Value); + virtual void EmitGPRel64Value(const MCExpr *Value); + virtual void EmitGPRel32Value(const MCExpr *Value); @@ -663,6 +665,12 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) { EmitEOL(); } +void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) { + assert(MAI.getGPRel64Directive() != 0); + OS << MAI.getGPRel64Directive() << *Value; + EmitEOL(); +} + void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) { assert(MAI.getGPRel32Directive() != 0); OS << MAI.getGPRel32Directive() << *Value; diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 1690eea73c7..50a5f8d1699 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -128,6 +128,10 @@ void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, AddrSpace); } +void MCStreamer::EmitGPRel64Value(const MCExpr *Value) { + report_fatal_error("unsupported directive in streamer"); +} + void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { report_fatal_error("unsupported directive in streamer"); } diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp index 4f0ff2a3c66..adda0a1c2a9 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp @@ -32,6 +32,7 @@ MipsMCAsmInfo::MipsMCAsmInfo(const Target &T, StringRef TT) { CommentString = "#"; ZeroDirective = "\t.space\t"; GPRel32Directive = "\t.gpword\t"; + GPRel64Directive = "\t.gpdword\t"; WeakRefDirective = "\t.weak\t"; SupportsDebugInformation = true; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 8c161679d5c..5449663450f 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2909,3 +2909,10 @@ bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { return false; return Imm.isZero(); } + +unsigned MipsTargetLowering::getJumpTableEncoding() const { + if (IsN64) + return MachineJumpTableInfo::EK_GPRel64BlockAddress; + + return TargetLowering::getJumpTableEncoding(); +} diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 81d093f42bb..7cd51100868 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -181,6 +181,8 @@ namespace llvm { /// materialize the FP immediate as a load from a constant pool. virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; + virtual unsigned getJumpTableEncoding() const; + MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode, bool Nand = false) const; MachineBasicBlock *EmitAtomicBinaryPartword(MachineInstr *MI, diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 5797112b8f4..a8afe58d765 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -469,11 +469,14 @@ unsigned MipsInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { MachineBasicBlock::iterator MBBI = FirstMBB.begin(); MachineRegisterInfo &RegInfo = MF->getRegInfo(); const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); + unsigned GP = IsN64 ? Mips::GP_64 : Mips::GP; + const TargetRegisterClass *RC + = IsN64 ? Mips::CPU64RegsRegisterClass : Mips::CPURegsRegisterClass; - GlobalBaseReg = RegInfo.createVirtualRegister(Mips::CPURegsRegisterClass); + GlobalBaseReg = RegInfo.createVirtualRegister(RC); BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), - GlobalBaseReg).addReg(Mips::GP); - RegInfo.addLiveIn(Mips::GP); + GlobalBaseReg).addReg(GP); + RegInfo.addLiveIn(GP); MipsFI->setGlobalBaseReg(GlobalBaseReg); return GlobalBaseReg; diff --git a/test/CodeGen/Mips/2010-07-20-Switch.ll b/test/CodeGen/Mips/2010-07-20-Switch.ll index 23b5349ba81..785a416ab04 100644 --- a/test/CodeGen/Mips/2010-07-20-Switch.ll +++ b/test/CodeGen/Mips/2010-07-20-Switch.ll @@ -15,7 +15,7 @@ entry: ; PIC-O32: sll ${{[0-9]+}}, ${{[0-9]+}}, 2 ; PIC-N64: ld $[[R0:[0-9]+]], %got_page($JTI0_0) ; PIC-N64: daddiu ${{[0-9]+}}, $[[R0]], %got_ofst($JTI0_0) -; PIC-N64: dsll ${{[0-9]+}}, ${{[0-9]+}}, 2 +; PIC-N64: dsll ${{[0-9]+}}, ${{[0-9]+}}, 3 switch i32 %0, label %bb4 [ i32 0, label %bb5 i32 1, label %bb1 @@ -39,3 +39,23 @@ bb4: ; preds = %entry bb5: ; preds = %entry ret i32 1 } + +; STATIC-O32: .align 2 +; STATIC-O32: $JTI0_0: +; STATIC-O32: .4byte +; STATIC-O32: .4byte +; STATIC-O32: .4byte +; STATIC-O32: .4byte +; PIC-O32: .align 2 +; PIC-O32: $JTI0_0: +; PIC-O32: .gpword +; PIC-O32: .gpword +; PIC-O32: .gpword +; PIC-O32: .gpword +; PIC-N64: .align 3 +; PIC-N64: $JTI0_0: +; PIC-N64: .gpdword +; PIC-N64: .gpdword +; PIC-N64: .gpdword +; PIC-N64: .gpdword + -- 2.34.1