[llvm] r185692 - [PowerPC] Support @tls in the asm parser

Ulrich Weigand ulrich.weigand at de.ibm.com
Fri Jul 5 05:22:37 PDT 2013


Author: uweigand
Date: Fri Jul  5 07:22:36 2013
New Revision: 185692

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

[PowerPC] Support @tls in the asm parser

This adds support for the last missing construct to parse TLS-related
assembler code:
   add 3, 4, symbol at tls

The ADD8TLS currently hard-codes the @tls into the assembler string.
This cannot be handled by the asm parser, since @tls is parsed as
a symbol variant.  This patch changes ADD8TLS to have the @tls suffix
printed as symbol variant on output too, which allows us to remove
the isCodeGenOnly marker from ADD8TLS.  This in turn means that we
can add a AsmOperand to accept @tls marked symbols on input.

As a side effect, this means that the fixup_ppc_tlsreg fixup type
is no longer necessary and can be merged into fixup_ppc_nofixup.


Modified:
    llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
    llvm/trunk/lib/Target/PowerPC/PPC.h
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
    llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp
    llvm/trunk/test/MC/PowerPC/ppc64-errors.s
    llvm/trunk/test/MC/PowerPC/ppc64-fixups.s

Modified: llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp Fri Jul  5 07:22:36 2013
@@ -237,7 +237,8 @@ struct PPCOperand : public MCParsedAsmOp
   enum KindTy {
     Token,
     Immediate,
-    Expression
+    Expression,
+    TLSRegister
   } Kind;
 
   SMLoc StartLoc, EndLoc;
@@ -257,10 +258,15 @@ struct PPCOperand : public MCParsedAsmOp
     int64_t CRVal;     // Cached result of EvaluateCRExpr(Val)
   };
 
+  struct TLSRegOp {
+    const MCSymbolRefExpr *Sym;
+  };
+
   union {
     struct TokOp Tok;
     struct ImmOp Imm;
     struct ExprOp Expr;
+    struct TLSRegOp TLSReg;
   };
 
   PPCOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
@@ -280,6 +286,9 @@ public:
     case Expression:
       Expr = o.Expr;
       break;
+    case TLSRegister:
+      TLSReg = o.TLSReg;
+      break;
     }
   }
 
@@ -307,6 +316,11 @@ public:
     return Expr.CRVal;
   }
 
+  const MCExpr *getTLSReg() const {
+    assert(Kind == TLSRegister && "Invalid access!");
+    return TLSReg.Sym;
+  }
+
   unsigned getReg() const {
     assert(isRegNumber() && "Invalid access!");
     return (unsigned) Imm.Val;
@@ -341,6 +355,7 @@ public:
                                     (getImm() & 3) == 0); }
   bool isS17Imm() const { return Kind == Expression ||
                                  (Kind == Immediate && isInt<17>(getImm())); }
+  bool isTLSReg() const { return Kind == TLSRegister; }
   bool isDirectBr() const { return Kind == Expression ||
                                    (Kind == Immediate && isInt<26>(getImm()) &&
                                     (getImm() & 3) == 0); }
@@ -445,6 +460,11 @@ public:
       Inst.addOperand(MCOperand::CreateExpr(getExpr()));
   }
 
+  void addTLSRegOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateExpr(getTLSReg()));
+  }
+
   StringRef getToken() const {
     assert(Kind == Token && "Invalid access!");
     return StringRef(Tok.Data, Tok.Length);
@@ -481,6 +501,28 @@ public:
     Op->IsPPC64 = IsPPC64;
     return Op;
   }
+
+  static PPCOperand *CreateTLSReg(const MCSymbolRefExpr *Sym,
+                                  SMLoc S, SMLoc E, bool IsPPC64) {
+    PPCOperand *Op = new PPCOperand(TLSRegister);
+    Op->TLSReg.Sym = Sym;
+    Op->StartLoc = S;
+    Op->EndLoc = E;
+    Op->IsPPC64 = IsPPC64;
+    return Op;
+  }
+
+  static PPCOperand *CreateFromMCExpr(const MCExpr *Val,
+                                      SMLoc S, SMLoc E, bool IsPPC64) {
+    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
+      return CreateImm(CE->getValue(), S, E, IsPPC64);
+
+    if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
+      if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS)
+        return CreateTLSReg(SRE, S, E, IsPPC64);
+
+    return CreateExpr(Val, S, E, IsPPC64);
+  }
 };
 
 } // end anonymous namespace.
@@ -496,6 +538,9 @@ void PPCOperand::print(raw_ostream &OS)
   case Expression:
     getExpr()->print(OS);
     break;
+  case TLSRegister:
+    getTLSReg()->print(OS);
+    break;
   }
 }
 
@@ -1011,12 +1056,8 @@ ParseOperand(SmallVectorImpl<MCParsedAsm
     return Error(S, "unknown operand");
   }
 
-  if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(EVal))
-    Op = PPCOperand::CreateImm(CE->getValue(), S, E, isPPC64());
-  else
-    Op = PPCOperand::CreateExpr(EVal, S, E, isPPC64());
-
   // Push the parsed operand into the list of operands
+  Op = PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64());
   Operands.push_back(Op);
 
   // Check whether this is a TLS call expression
@@ -1036,7 +1077,7 @@ ParseOperand(SmallVectorImpl<MCParsedAsm
     E = Parser.getTok().getLoc();
     Parser.Lex(); // Eat the ')'.
 
-    Op = PPCOperand::CreateExpr(TLSSym, S, E, isPPC64());
+    Op = PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64());
     Operands.push_back(Op);
   }
 

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp Fri Jul  5 07:22:36 2013
@@ -30,7 +30,6 @@ static uint64_t adjustFixupValue(unsigne
   case FK_Data_2:
   case FK_Data_4:
   case FK_Data_8:
-  case PPC::fixup_ppc_tlsreg:
   case PPC::fixup_ppc_nofixup:
     return Value;
   case PPC::fixup_ppc_brcond14:
@@ -64,7 +63,6 @@ static unsigned getFixupKindNumBytes(uns
     return 4;
   case FK_Data_8:
     return 8;
-  case PPC::fixup_ppc_tlsreg:
   case PPC::fixup_ppc_nofixup:
     return 0;
   }
@@ -101,7 +99,6 @@ public:
       { "fixup_ppc_brcond14abs", 16,     14,   0 },
       { "fixup_ppc_half16",       0,     16,   0 },
       { "fixup_ppc_half16ds",     0,     14,   0 },
-      { "fixup_ppc_tlsreg",       0,      0,   0 },
       { "fixup_ppc_nofixup",      0,      0,   0 }
     };
 

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp Fri Jul  5 07:22:36 2013
@@ -289,9 +289,6 @@ unsigned PPCELFObjectWriter::getRelocTyp
         break;
       }
       break;
-    case PPC::fixup_ppc_tlsreg:
-      Type = ELF::R_PPC64_TLS;
-      break;
     case PPC::fixup_ppc_nofixup:
       switch (Modifier) {
       default: llvm_unreachable("Unsupported Modifier");
@@ -301,6 +298,9 @@ unsigned PPCELFObjectWriter::getRelocTyp
       case MCSymbolRefExpr::VK_TLSLD:
         Type = ELF::R_PPC64_TLSLD;
         break;
+      case MCSymbolRefExpr::VK_PPC_TLS:
+        Type = ELF::R_PPC64_TLS;
+        break;
       }
       break;
     case FK_Data_8:

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h Fri Jul  5 07:22:36 2013
@@ -41,11 +41,9 @@ enum Fixups {
   /// implied 2 zero bits for instrs like 'std'.
   fixup_ppc_half16ds,
 
-  /// fixup_ppc_tlsreg - Insert thread-pointer register number.
-  fixup_ppc_tlsreg,
-
   /// fixup_ppc_nofixup - Not a true fixup, but ties a symbol to a call
-  /// to __tls_get_addr for the TLS general and local dynamic models.
+  /// to __tls_get_addr for the TLS general and local dynamic models,
+  /// or inserts the thread-pointer register number.
   fixup_ppc_nofixup,
   
   // Marker

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=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp Fri Jul  5 07:22:36 2013
@@ -209,7 +209,7 @@ unsigned PPCMCCodeEmitter::getTLSRegEnco
   // hint to the linker that this statement is part of a relocation sequence.
   // Return the thread-pointer register's encoding.
   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
-                                   (MCFixupKind)PPC::fixup_ppc_tlsreg));
+                                   (MCFixupKind)PPC::fixup_ppc_nofixup));
   return CTX.getRegisterInfo()->getEncodingValue(PPC::X13);
 }
 

Modified: llvm/trunk/lib/Target/PowerPC/PPC.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.h?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPC.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPC.h Fri Jul  5 07:22:36 2013
@@ -85,7 +85,10 @@ namespace llvm {
     /// into memory operations.
     MO_DTPREL_LO = 5 << 4,
     MO_TLSLD_LO  = 6 << 4,
-    MO_TOC_LO    = 7 << 4
+    MO_TOC_LO    = 7 << 4,
+
+    // Symbol for VK_PPC_TLS fixup attached to an ADD instruction
+    MO_TLS       = 8 << 4
   };
   } // end namespace PPCII
   

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Jul  5 07:22:36 2013
@@ -1359,12 +1359,14 @@ SDValue PPCTargetLowering::LowerGlobalTL
 
   if (Model == TLSModel::InitialExec) {
     SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
+    SDValue TGATLS = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
+                                                PPCII::MO_TLS);
     SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
     SDValue TPOffsetHi = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl,
                                      PtrVT, GOTReg, TGA);
     SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl,
                                    PtrVT, TGA, TPOffsetHi);
-    return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGA);
+    return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
   }
 
   if (Model == TLSModel::GeneralDynamic) {

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Fri Jul  5 07:22:36 2013
@@ -36,8 +36,13 @@ def s17imm64 : Operand<i64> {
 def tocentry : Operand<iPTR> {
   let MIOperandInfo = (ops i64imm:$imm);
 }
+def PPCTLSRegOperand : AsmOperandClass {
+  let Name = "TLSReg"; let PredicateMethod = "isTLSReg";
+  let RenderMethod = "addTLSRegOperands";
+}
 def tlsreg : Operand<i64> {
   let EncoderMethod = "getTLSRegEncoding";
+  let ParserMatchClass = PPCTLSRegOperand;
 }
 def tlsgd : Operand<i64> {}
 def tlscall : Operand<i64> {
@@ -404,9 +409,8 @@ defm ADD8  : XOForm_1r<31, 266, 0, (outs
                        [(set i64:$rT, (add i64:$rA, i64:$rB))]>;
 // ADD8 has a special form: reg = ADD8(reg, sym at tls) for use by the
 // initial-exec thread-local storage model.
-let isCodeGenOnly = 1 in
 def ADD8TLS  : XOForm_1<31, 266, 0, (outs g8rc:$rT), (ins g8rc:$rA, tlsreg:$rB),
-                        "add $rT, $rA, $rB at tls", IntSimple,
+                        "add $rT, $rA, $rB", IntSimple,
                         [(set i64:$rT, (add i64:$rA, tglobaltlsaddr:$rB))]>;
                      
 defm ADDC8 : XOForm_1rc<31, 10, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),

Modified: llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp Fri Jul  5 07:22:36 2013
@@ -127,6 +127,9 @@ static MCOperand GetSymbolRef(const Mach
     case PPCII::MO_TOC_LO:
       RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO;
       break;
+    case PPCII::MO_TLS:
+      RefKind = MCSymbolRefExpr::VK_PPC_TLS;
+      break;
   }
 
   const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);

Modified: llvm/trunk/test/MC/PowerPC/ppc64-errors.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-errors.s?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-errors.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-errors.s Fri Jul  5 07:22:36 2013
@@ -12,6 +12,16 @@
 # CHECK-NEXT: add %r32, %r32, %r32
               add %r32, %r32, %r32
 
+# TLS register operands
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: add 3, symbol at tls, 4
+              add 3, symbol at tls, 4
+
+# CHECK: error: invalid operand for instruction
+# CHECK-NEXT: subf 3, 4, symbol at tls
+              subf 3, 4, symbol at tls
+
 # Signed 16-bit immediate operands
 
 # CHECK: error: invalid operand for instruction

Modified: llvm/trunk/test/MC/PowerPC/ppc64-fixups.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/ppc64-fixups.s?rev=185692&r1=185691&r2=185692&view=diff
==============================================================================
--- llvm/trunk/test/MC/PowerPC/ppc64-fixups.s (original)
+++ llvm/trunk/test/MC/PowerPC/ppc64-fixups.s Fri Jul  5 07:22:36 2013
@@ -206,8 +206,6 @@ base:
 # CHECK-REL:                             0x{{[0-9A-F]*[26AE]}} R_PPC64_GOT16_LO_DS target 0x0
          ld 1, target at got@l(3)
 
-# FIXME: @tls
-
 
 # CHECK: addis 3, 2, target at tprel@ha     # encoding: [0x3c,0x62,A,A]
 # CHECK-NEXT:                            #   fixup A - offset: 2, value: target at tprel@ha, kind: fixup_ppc_half16
@@ -405,6 +403,11 @@ base:
 # CHECK-REL-NEXT:                        0x{{[0-9A-F]*[048C]}} R_PPC64_REL24 __tls_get_addr 0x0
          bl __tls_get_addr(target at tlsld)
 
+# CHECK: add 3, 4, target at tls            # encoding: [0x7c,0x64,0x6a,0x14]
+# CHECK-NEXT:                            #   fixup A - offset: 0, value: target at tls, kind: fixup_ppc_nofixup
+# CHECK-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_TLS target 0x0
+         add 3, 4, target at tls
+
 
 # Data relocs
 # llvm-mc does not show any "encoding" string for data, so we just check the relocs





More information about the llvm-commits mailing list