[llvm] r185477 - [PowerPC] Rework TLS call operand processing

Ulrich Weigand ulrich.weigand at de.ibm.com
Tue Jul 2 14:31:04 PDT 2013


Author: uweigand
Date: Tue Jul  2 16:31:04 2013
New Revision: 185477

URL: http://llvm.org/viewvc/llvm-project?rev=185477&view=rev
Log:

[PowerPC] Rework TLS call operand processing

As part of the global-dynamic and local-dynamic TLS sequences, we need
to use a special form of the call instruction:

 bl __tls_get_addr(sym at tlsld)
 bl __tls_get_addr(sym at tlsgd)

which generates two fixups.  The current implementation of this causes
problems with recognizing this form in the asm parser.  To fix this,
this patch reworks operand processing for this special form by using
a single operand to hold both __tls_get_addr and sym at tlsld and defining
a print method to output the above form, and an encoding method to
generate the two fixups.

As a side simplification, the patch replaces the two instruction
patterns BL8_NOP_TLSGD and BL8_NOP_TLSLD by a single BL8_NOP_TLS,
since the patterns already operate in an identical fashion (whether
we have a local-dynamic or global-dynamic symbol is already encoded
in the symbol modifier).

No change in code generation intended.


Modified:
    llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
    llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
    llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp
    llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td

Modified: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp?rev=185477&r1=185476&r2=185477&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp Tue Jul  2 16:31:04 2013
@@ -273,6 +273,13 @@ void PPCInstPrinter::printMemRegReg(cons
   printOperand(MI, OpNo+1, O);
 }
 
+void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
+                                  raw_ostream &O) {
+  printBranchOperand(MI, OpNo, O);
+  O << '(';
+  printOperand(MI, OpNo+1, O);
+  O << ')';
+}
 
 
 /// stripRegisterPrefix - This method strips the character prefix from a

Modified: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h?rev=185477&r1=185476&r2=185477&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h (original)
+++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h Tue Jul  2 16:31:04 2013
@@ -52,6 +52,7 @@ public:
   void printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
   void printAbsBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+  void printTLSCall(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 
   void printcrbitm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp?rev=185477&r1=185476&r2=185477&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp Tue Jul  2 16:31:04 2013
@@ -60,6 +60,8 @@ public:
                              SmallVectorImpl<MCFixup> &Fixups) const;
   unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
                              SmallVectorImpl<MCFixup> &Fixups) const;
+  unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
+                              SmallVectorImpl<MCFixup> &Fixups) const;
   unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
                                SmallVectorImpl<MCFixup> &Fixups) const;
 
@@ -80,7 +82,7 @@ public:
     unsigned Size = 4; // FIXME: Have Desc.getSize() return the correct value!
     unsigned Opcode = MI.getOpcode();
     if (Opcode == PPC::BL8_NOP || Opcode == PPC::BLA8_NOP ||
-        Opcode == PPC::BL8_NOP_TLSGD || Opcode == PPC::BL8_NOP_TLSLD)
+        Opcode == PPC::BL8_NOP_TLS)
       Size = 8;
     
     // Output the constant in big endian byte order.
@@ -113,17 +115,6 @@ getDirectBrEncoding(const MCInst &MI, un
   // 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;
 }
 
@@ -222,6 +213,17 @@ unsigned PPCMCCodeEmitter::getTLSRegEnco
   return CTX.getRegisterInfo()->getEncodingValue(PPC::X13);
 }
 
+unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
+                                       SmallVectorImpl<MCFixup> &Fixups) const {
+  // For special TLS calls, we need two fixups; one for the branch target
+  // (__tls_get_addr), which we create via getDirectBrEncoding as usual,
+  // and one for the TLSGD or TLSLD symbol, which is emitted here.
+  const MCOperand &MO = MI.getOperand(OpNo+1);
+  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
+                                   (MCFixupKind)PPC::fixup_ppc_nofixup));
+  return getDirectBrEncoding(MI, OpNo, Fixups);
+}
+
 unsigned PPCMCCodeEmitter::
 get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
                     SmallVectorImpl<MCFixup> &Fixups) const {

Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=185477&r1=185476&r2=185477&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue Jul  2 16:31:04 2013
@@ -562,7 +562,7 @@ void PPCAsmPrinter::EmitInstruction(cons
   }
   case PPC::GETtlsADDR: {
     // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
-    // Into:      BL8_NOP_TLSGD __tls_get_addr(sym at tlsgd)
+    // Into:      BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
 
     StringRef Name = "__tls_get_addr";
@@ -574,7 +574,7 @@ void PPCAsmPrinter::EmitInstruction(cons
     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
     const MCExpr *SymVar =
       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSGD, OutContext);
-    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSGD)
+    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
                                 .addExpr(TlsRef)
                                 .addExpr(SymVar));
     return;
@@ -613,7 +613,7 @@ void PPCAsmPrinter::EmitInstruction(cons
   }
   case PPC::GETtlsldADDR: {
     // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
-    // Into:      BL8_NOP_TLSLD __tls_get_addr(sym at tlsld)
+    // Into:      BL8_NOP_TLS __tls_get_addr(sym at tlsld)
     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
 
     StringRef Name = "__tls_get_addr";
@@ -625,7 +625,7 @@ void PPCAsmPrinter::EmitInstruction(cons
     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
     const MCExpr *SymVar =
       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSLD, OutContext);
-    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSLD)
+    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
                                 .addExpr(TlsRef)
                                 .addExpr(SymVar));
     return;

Modified: llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp?rev=185477&r1=185476&r2=185477&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCCodeEmitter.cpp Tue Jul  2 16:31:04 2013
@@ -71,6 +71,7 @@ namespace {
     unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const;
     unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;
     unsigned getTLSRegEncoding(const MachineInstr &MI, unsigned OpNo) const;
+    unsigned getTLSCallEncoding(const MachineInstr &MI, unsigned OpNo) const;
 
     const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
 
@@ -263,6 +264,11 @@ unsigned PPCCodeEmitter::getTLSRegEncodi
   return 0;
 }
 
+unsigned PPCCodeEmitter::getTLSCallEncoding(const MachineInstr &MI,
+                                            unsigned OpNo) const {
+  llvm_unreachable("TLS not supported on the old JIT.");
+  return 0;
+}
 
 unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                            const MachineOperand &MO) const {

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=185477&r1=185476&r2=185477&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Tue Jul  2 16:31:04 2013
@@ -40,6 +40,11 @@ def tlsreg : Operand<i64> {
   let EncoderMethod = "getTLSRegEncoding";
 }
 def tlsgd : Operand<i64> {}
+def tlscall : Operand<i64> {
+  let PrintMethod = "printTLSCall";
+  let MIOperandInfo = (ops calltarget:$func, tlsgd:$sym);
+  let EncoderMethod = "getTLSCallEncoding";
+}
 
 //===----------------------------------------------------------------------===//
 // 64-bit transformation functions.
@@ -119,13 +124,9 @@ let isCall = 1, PPC970_Unit = 7, Defs =
                              (outs), (ins calltarget:$func),
                              "bl $func\n\tnop", BrB, []>;
 
-    def BL8_NOP_TLSGD : IForm_and_DForm_4_zero<18, 0, 1, 24,
-                                  (outs), (ins calltarget:$func, tlsgd:$sym),
-                                  "bl $func($sym)\n\tnop", BrB, []>;
-
-    def BL8_NOP_TLSLD : IForm_and_DForm_4_zero<18, 0, 1, 24,
-                                  (outs), (ins calltarget:$func, tlsgd:$sym),
-                                  "bl $func($sym)\n\tnop", BrB, []>;
+    def BL8_NOP_TLS : IForm_and_DForm_4_zero<18, 0, 1, 24,
+                                  (outs), (ins tlscall:$func),
+                                  "bl $func\n\tnop", BrB, []>;
 
     def BLA8_NOP : IForm_and_DForm_4_zero<18, 1, 1, 24,
                              (outs), (ins abscalltarget:$func),





More information about the llvm-commits mailing list