diff options
author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2013-07-05 12:22:36 +0000 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2013-07-05 12:22:36 +0000 |
commit | 23a72c8f7e46618ff8dbdbba4e8c1a2c4e44e3df (patch) | |
tree | 93954d1ea2e8230d74fceb259dbc4566b6ea8901 /lib/Target/PowerPC/AsmParser | |
parent | 87b8a7f9996ee7463b787fc85394287de903c7d7 (diff) | |
download | external_llvm-23a72c8f7e46618ff8dbdbba4e8c1a2c4e44e3df.zip external_llvm-23a72c8f7e46618ff8dbdbba4e8c1a2c4e44e3df.tar.gz external_llvm-23a72c8f7e46618ff8dbdbba4e8c1a2c4e44e3df.tar.bz2 |
[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@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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185692 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/AsmParser')
-rw-r--r-- | lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index e4fc3b9..237ecdc 100644 --- a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -237,7 +237,8 @@ struct PPCOperand : public MCParsedAsmOperand { enum KindTy { Token, Immediate, - Expression + Expression, + TLSRegister } Kind; SMLoc StartLoc, EndLoc; @@ -257,10 +258,15 @@ struct PPCOperand : public MCParsedAsmOperand { 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) const { case Expression: getExpr()->print(OS); break; + case TLSRegister: + getTLSReg()->print(OS); + break; } } @@ -1011,12 +1056,8 @@ ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 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<MCParsedAsmOperand*> &Operands) { 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); } |