diff options
Diffstat (limited to 'lib/AsmParser')
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 9 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 56 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 3 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 3 |
4 files changed, 62 insertions, 9 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 8818168..670c1bb 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -474,6 +474,9 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(extern_weak); KEYWORD(external); KEYWORD(thread_local); + KEYWORD(localdynamic); + KEYWORD(initialexec); + KEYWORD(localexec); KEYWORD(zeroinitializer); KEYWORD(undef); KEYWORD(null); @@ -673,11 +676,12 @@ lltok::Kind LLLexer::LexIdentifier() { /// HexFP80Constant 0xK[0-9A-Fa-f]+ /// HexFP128Constant 0xL[0-9A-Fa-f]+ /// HexPPC128Constant 0xM[0-9A-Fa-f]+ +/// HexHalfConstant 0xH[0-9A-Fa-f]+ lltok::Kind LLLexer::Lex0x() { CurPtr = TokStart + 2; char Kind; - if (CurPtr[0] >= 'K' && CurPtr[0] <= 'M') { + if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H') { Kind = *CurPtr++; } else { Kind = 'J'; @@ -718,6 +722,9 @@ lltok::Kind LLLexer::Lex0x() { HexToIntPair(TokStart+3, CurPtr, Pair); APFloatVal = APFloat(APInt(128, Pair)); return lltok::APFloat; + case 'H': + APFloatVal = APFloat(APInt(16,HexIntToVal(TokStart+3, CurPtr))); + return lltok::APFloat; } } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 068be3d..095b7c5 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -645,12 +645,13 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility) { unsigned AddrSpace; - bool ThreadLocal, IsConstant, UnnamedAddr; + bool IsConstant, UnnamedAddr; + GlobalVariable::ThreadLocalMode TLM; LocTy UnnamedAddrLoc; LocTy TyLoc; Type *Ty = 0; - if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) || + if (ParseOptionalThreadLocal(TLM) || ParseOptionalAddrSpace(AddrSpace) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || @@ -691,7 +692,8 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, if (GV == 0) { GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, 0, - Name, 0, false, AddrSpace); + Name, 0, GlobalVariable::NotThreadLocal, + AddrSpace); } else { if (GV->getType()->getElementType() != Ty) return Error(TyLoc, @@ -710,7 +712,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GV->setConstant(IsConstant); GV->setLinkage((GlobalValue::LinkageTypes)Linkage); GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); - GV->setThreadLocal(ThreadLocal); + GV->setThreadLocalMode(TLM); GV->setUnnamedAddr(UnnamedAddr); // Parse attributes on the global. @@ -858,6 +860,46 @@ bool LLParser::ParseUInt32(unsigned &Val) { return false; } +/// ParseTLSModel +/// := 'localdynamic' +/// := 'initialexec' +/// := 'localexec' +bool LLParser::ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM) { + switch (Lex.getKind()) { + default: + return TokError("expected localdynamic, initialexec or localexec"); + case lltok::kw_localdynamic: + TLM = GlobalVariable::LocalDynamicTLSModel; + break; + case lltok::kw_initialexec: + TLM = GlobalVariable::InitialExecTLSModel; + break; + case lltok::kw_localexec: + TLM = GlobalVariable::LocalExecTLSModel; + break; + } + + Lex.Lex(); + return false; +} + +/// ParseOptionalThreadLocal +/// := /*empty*/ +/// := 'thread_local' +/// := 'thread_local' '(' tlsmodel ')' +bool LLParser::ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) { + TLM = GlobalVariable::NotThreadLocal; + if (!EatIfPresent(lltok::kw_thread_local)) + return false; + + TLM = GlobalVariable::GeneralDynamicTLSModel; + if (Lex.getKind() == lltok::lparen) { + Lex.Lex(); + return ParseTLSModel(TLM) || + ParseToken(lltok::rparen, "expected ')' after thread local model"); + } + return false; +} /// ParseOptionalAddrSpace /// := /*empty*/ @@ -2692,7 +2734,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (FuncAttrs != Attribute::None) Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs)); - AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + AttrListPtr PAL = AttrListPtr::get(Attrs); if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy()) return Error(RetTypeLoc, "functions with 'sret' argument must return void"); @@ -3239,7 +3281,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs)); // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + AttrListPtr PAL = AttrListPtr::get(Attrs); InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args); II->setCallingConv(CC); @@ -3635,7 +3677,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs)); // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + AttrListPtr PAL = AttrListPtr::get(Attrs); CallInst *CI = CallInst::Create(Callee, Args); CI->setTailCall(isTail); diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index dda8808..257c726 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -171,6 +171,9 @@ namespace llvm { Loc = Lex.getLoc(); return ParseUInt32(Val); } + + bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM); + bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalAddrSpace(unsigned &AddrSpace); bool ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind); bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage); diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index adf5d4f..0461e7b 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -44,13 +44,14 @@ namespace lltok { kw_unnamed_addr, kw_extern_weak, kw_external, kw_thread_local, + kw_localdynamic, kw_initialexec, kw_localexec, kw_zeroinitializer, kw_undef, kw_null, kw_to, kw_tail, kw_target, kw_triple, - kw_unwind, + kw_unwind, kw_deplibs, kw_datalayout, kw_volatile, |