[PowerPC] PR16512 - Support TLS call sequences in the asm parser
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Tue, 2 Jul 2013 21:31:59 +0000 (21:31 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Tue, 2 Jul 2013 21:31:59 +0000 (21:31 +0000)
This patch now adds support for recognizing TLS call sequences in
the asm parser.  This needs a new pattern BL8_TLS, which is like
BL8_NOP_TLS except without nop.  That pattern is used for the
asm parser only.

llvm-svn: 185478

llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
llvm/lib/Target/PowerPC/PPCInstr64Bit.td
llvm/test/MC/PowerPC/ppc64-fixups.s

index 7a654ea..4892963 100644 (file)
@@ -940,8 +940,29 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   // Push the parsed operand into the list of operands
   Operands.push_back(Op);
 
-  // Check for D-form memory operands
-  if (getLexer().is(AsmToken::LParen)) {
+  // Check whether this is a TLS call expression
+  bool TLSCall = false;
+  if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal))
+    TLSCall = Ref->getSymbol().getName() == "__tls_get_addr";
+
+  if (TLSCall && getLexer().is(AsmToken::LParen)) {
+    const MCExpr *TLSSym;
+
+    Parser.Lex(); // Eat the '('.
+    S = Parser.getTok().getLoc();
+    if (ParseExpression(TLSSym))
+      return Error(S, "invalid TLS call expression");
+    if (getLexer().isNot(AsmToken::RParen))
+      return Error(Parser.getTok().getLoc(), "missing ')'");
+    E = Parser.getTok().getLoc();
+    Parser.Lex(); // Eat the ')'.
+
+    Op = PPCOperand::CreateExpr(TLSSym, S, E, isPPC64());
+    Operands.push_back(Op);
+  }
+
+  // Otherwise, check for D-form memory operands
+  if (!TLSCall && getLexer().is(AsmToken::LParen)) {
     Parser.Lex(); // Eat the '('.
     S = Parser.getTok().getLoc();
 
index a2130e3..f3c2892 100644 (file)
@@ -116,6 +116,9 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR8] in {
     def BL8  : IForm<18, 0, 1, (outs), (ins calltarget:$func),
                      "bl $func", BrB, []>;  // See Pat patterns below.
 
+    def BL8_TLS  : IForm<18, 0, 1, (outs), (ins tlscall:$func),
+                         "bl $func", BrB, []>;
+
     def BLA8 : IForm<18, 1, 1, (outs), (ins abscalltarget:$func),
                      "bla $func", BrB, [(PPCcall (i64 imm:$func))]>;
   }
index 612c899..937e557 100644 (file)
@@ -391,6 +391,20 @@ base:
 # CHECK-REL:                             0x{{[0-9A-F]*[26AE]}} R_PPC64_GOT_TLSLD16 target 0x0
          addi 3, 3, target@got@tlsld
 
+# CHECK: bl __tls_get_addr(target@TLSGD) # encoding: [0b010010BB,B,B,0bBBBBBB01]
+# CHECK-NEXT:                            #   fixup A - offset: 0, value: target@TLSGD, kind: fixup_ppc_nofixup
+# CHECK-NEXT:                            #   fixup B - offset: 0, value: __tls_get_addr, kind: fixup_ppc_br24
+# CHECK-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_TLSGD target 0x0
+# CHECK-REL-NEXT:                        0x{{[0-9A-F]*[048C]}} R_PPC64_REL24 __tls_get_addr 0x0
+         bl __tls_get_addr(target@tlsgd)
+
+# CHECK: bl __tls_get_addr(target@TLSLD) # encoding: [0b010010BB,B,B,0bBBBBBB01]
+# CHECK-NEXT:                            #   fixup A - offset: 0, value: target@TLSLD, kind: fixup_ppc_nofixup
+# CHECK-NEXT:                            #   fixup B - offset: 0, value: __tls_get_addr, kind: fixup_ppc_br24
+# CHECK-REL:                             0x{{[0-9A-F]*[048C]}} R_PPC64_TLSLD target 0x0
+# CHECK-REL-NEXT:                        0x{{[0-9A-F]*[048C]}} R_PPC64_REL24 __tls_get_addr 0x0
+         bl __tls_get_addr(target@tlsld)
+
 
 # Data relocs
 # llvm-mc does not show any "encoding" string for data, so we just check the relocs