Add a new MachineJumpTableInfo entry type, EK_GPRel64BlockAddress, which is
authorAkira Hatanaka <ahatanaka@mips.com>
Fri, 3 Feb 2012 04:33:00 +0000 (04:33 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Fri, 3 Feb 2012 04:33:00 +0000 (04:33 +0000)
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

14 files changed:
include/llvm/CodeGen/MachineJumpTableInfo.h
include/llvm/MC/MCAsmInfo.h
include/llvm/MC/MCStreamer.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/MachineFunction.cpp
lib/ExecutionEngine/JIT/JITEmitter.cpp
lib/MC/MCAsmInfo.cpp
lib/MC/MCAsmStreamer.cpp
lib/MC/MCStreamer.cpp
lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h
lib/Target/Mips/MipsInstrInfo.cpp
test/CodeGen/Mips/2010-07-20-Switch.ll

index 62643497655a4df1d7a9ed4025f5542c53b9bf76..6bd6682dd39c6145b4bf485b5ab85ce4848c4b47 100644 (file)
@@ -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
index 5accabcd9f4efcaaf75be7d5b175db53d06c242a..5027a8f424d660e2648bce572a10f7d8bd710d83 100644 (file)
@@ -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.
index c141dfbc96e0e623bde9cb1d164496373aa53619..99323067c47c62bead068aa67fb3271749df28be 100644 (file)
@@ -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.
     ///
index 4c093665c8c7433eb7d226760690316158508b1d..43af3423de9834f0830252a6bf06671f80bafcdf 100644 (file)
@@ -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
index 3aaae855651cb6e7b90262e9f3fb172945f78b5a..8195f9f6790063bb912c890ec635ab65ad6eee38 100644 (file)
@@ -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:
index 91305fd38474f038d03a728607a893dbed4b4a41..26201c397d1d604f59e812c89a01e459de5cf2aa 100644 (file)
@@ -1161,6 +1161,9 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
     }
     break;
   }
+  case MachineJumpTableInfo::EK_GPRel64BlockAddress:
+    assert(false &&
+           "JT Info emission not implemented for GPRel64BlockAddress yet.");
   }
 }
 
index b1e1bdf6c758c52ad0da9d5de702f903b249691c..582d21fe90c7926f6b61d2ebb15f3c467fb34ca6 100644 (file)
@@ -67,6 +67,7 @@ MCAsmInfo::MCAsmInfo() {
   AlignDirective = "\t.align\t";
   AlignmentIsInBytes = true;
   TextAlignFillValue = 0;
+  GPRel64Directive = 0;
   GPRel32Directive = 0;
   GlobalDirective = "\t.globl\t";
   HasSetDirective = true;
index afad5d530cf2d865bf67f7fa32f346274f2d0822..ba6dee7cc2ddbf6891a76b53724ae8efd69c9ef6 100644 (file)
@@ -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;
index 1690eea73c74c1138f94879f08ef1bc3ac14fe92..50a5f8d1699ad75ec85617eb5f94c080e486c580 100644 (file)
@@ -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");
 }
index 4f0ff2a3c6626af3920eb0daabb3146752cbca7c..adda0a1c2a9e8c543df158f9c7dc9d48ff87e1cf 100644 (file)
@@ -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;
index 8c161679d5c5a64c7cd29d42116d4f4d6407072d..5449663450f06ac343d3d12806e58e8fd1a5c425 100644 (file)
@@ -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();
+}
index 81d093f42bb3d53c5514de78b5f9138c7f8b8aad..7cd511008688f4c66d858bbeeaf1cf8a3fcc0175 100644 (file)
@@ -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,
index 5797112b8f4d28ae03d19095ab2291878db13c97..a8afe58d765d650d29adfc2ae96a7df04e012cc6 100644 (file)
@@ -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;
index 23b5349ba8126b1694ec5b17406161ea5e21c107..785a416ab049221cf4b902da4b97d3dd7df6a4f0 100644 (file)
@@ -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 
+