From 42a09dc12fa252cbabb4faf53606d5826f26a5bd Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 2 Jul 2013 21:31:59 +0000 Subject: [PATCH] [PowerPC] PR16512 - Support TLS call sequences in the asm parser 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 --- .../Target/PowerPC/AsmParser/PPCAsmParser.cpp | 25 +++++++++++++++++-- llvm/lib/Target/PowerPC/PPCInstr64Bit.td | 3 +++ llvm/test/MC/PowerPC/ppc64-fixups.s | 14 +++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 7a654ea8289e..489296311e14 100644 --- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -940,8 +940,29 @@ ParseOperand(SmallVectorImpl &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(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(); diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td index a2130e3b9bdb..f3c2892423ea 100644 --- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -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))]>; } diff --git a/llvm/test/MC/PowerPC/ppc64-fixups.s b/llvm/test/MC/PowerPC/ppc64-fixups.s index 612c899b06d7..937e55758e84 100644 --- a/llvm/test/MC/PowerPC/ppc64-fixups.s +++ b/llvm/test/MC/PowerPC/ppc64-fixups.s @@ -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