diff options
author | John Thompson <John.Thompson.JTSoftware@gmail.com> | 2010-02-05 00:12:22 +0000 |
---|---|---|
committer | John Thompson <John.Thompson.JTSoftware@gmail.com> | 2010-02-05 00:12:22 +0000 |
commit | 82287d19ded35248c4ce6a425ce74116a13ce44e (patch) | |
tree | f68c23eac705cff9c21622e5bb7a561364424217 /lib | |
parent | 6202119003aba91e5ff4e579cb9c26a8d1b9514f (diff) |
First stage of adding AltiVec support
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95335 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 20 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 27 | ||||
-rw-r--r-- | lib/Basic/IdentifierTable.cpp | 4 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 8 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/DeclSpec.cpp | 38 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 35 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 9 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 12 |
12 files changed, 139 insertions, 29 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 676be72787..b61ce8e529 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1610,7 +1610,8 @@ QualType ASTContext::getIncompleteArrayType(QualType EltTy, /// getVectorType - Return the unique reference to a vector type of /// the specified element type and size. VectorType must be a built-in type. -QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) { +QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, + bool IsAltiVec, bool IsPixel) { BuiltinType *baseType; baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr()); @@ -1618,7 +1619,8 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) { // Check if we've already instantiated a vector of this type. llvm::FoldingSetNodeID ID; - VectorType::Profile(ID, vecType, NumElts, Type::Vector); + VectorType::Profile(ID, vecType, NumElts, Type::Vector, + IsAltiVec, IsPixel); void *InsertPos = 0; if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(VTP, 0); @@ -1626,15 +1628,16 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) { // If the element type isn't canonical, this won't be a canonical type either, // so fill in the canonical type field. QualType Canonical; - if (!vecType.isCanonical()) { - Canonical = getVectorType(getCanonicalType(vecType), NumElts); + if (!vecType.isCanonical() || IsAltiVec || IsPixel) { + Canonical = getVectorType(getCanonicalType(vecType), + NumElts, false, false); // Get the new insert position for the node we care about. VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } VectorType *New = new (*this, TypeAlignment) - VectorType(vecType, NumElts, Canonical); + VectorType(vecType, NumElts, Canonical, IsAltiVec, IsPixel); VectorTypes.InsertNode(New, InsertPos); Types.push_back(New); return QualType(New, 0); @@ -1650,7 +1653,7 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) { // Check if we've already instantiated a vector of this type. llvm::FoldingSetNodeID ID; - VectorType::Profile(ID, vecType, NumElts, Type::ExtVector); + VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, false, false); void *InsertPos = 0; if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(VTP, 0); @@ -4636,7 +4639,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) { // Turn <4 x signed int> -> <4 x unsigned int> if (const VectorType *VTy = T->getAs<VectorType>()) return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()), - VTy->getNumElements()); + VTy->getNumElements(), VTy->isAltiVec(), VTy->isPixel()); // For enums, we return the unsigned version of the base type. if (const EnumType *ETy = T->getAs<EnumType>()) @@ -4793,7 +4796,8 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context, Str = End; QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false); - Type = Context.getVectorType(ElementType, NumElements); + // FIXME: Don't know what to do about AltiVec. + Type = Context.getVectorType(ElementType, NumElements, false, false); break; } case 'X': { diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 597ab37d2b..5b621cf728 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -225,15 +225,24 @@ void TypePrinter::PrintDependentSizedExtVector( } void TypePrinter::PrintVector(const VectorType *T, std::string &S) { - // FIXME: We prefer to print the size directly here, but have no way - // to get the size of the type. - Print(T->getElementType(), S); - std::string V = "__attribute__((__vector_size__("; - V += llvm::utostr_32(T->getNumElements()); // convert back to bytes. - std::string ET; - Print(T->getElementType(), ET); - V += " * sizeof(" + ET + ")))) "; - S = V + S; + if (T->isAltiVec()) { + if (T->isPixel()) + S = "__vector __pixel " + S; + else { + Print(T->getElementType(), S); + S = "__vector " + S; + } + } else { + // FIXME: We prefer to print the size directly here, but have no way + // to get the size of the type. + Print(T->getElementType(), S); + std::string V = "__attribute__((__vector_size__("; + V += llvm::utostr_32(T->getNumElements()); // convert back to bytes. + std::string ET; + Print(T->getElementType(), ET); + V += " * sizeof(" + ET + ")))) "; + S = V + S; + } } void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index 401e6cba06..16a61b7156 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -68,7 +68,8 @@ namespace { KEYCXX0X = 8, KEYGNU = 16, KEYMS = 32, - BOOLSUPPORT = 64 + BOOLSUPPORT = 64, + KEYALTIVEC = 128 }; } @@ -91,6 +92,7 @@ static void AddKeyword(const char *Keyword, unsigned KWLen, else if (LangOpts.GNUMode && (Flags & KEYGNU)) AddResult = 1; else if (LangOpts.Microsoft && (Flags & KEYMS)) AddResult = 1; else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2; + else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2; // Don't add this keyword if disabled in this language. if (AddResult == 0) return; diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index bd93cf6b08..1ed5260a88 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -1880,18 +1880,20 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { } case pch::TYPE_VECTOR: { - if (Record.size() != 2) { + if (Record.size() != 4) { Error("incorrect encoding of vector type in PCH file"); return QualType(); } QualType ElementType = GetType(Record[0]); unsigned NumElements = Record[1]; - return Context->getVectorType(ElementType, NumElements); + bool AltiVec = Record[2]; + bool Pixel = Record[3]; + return Context->getVectorType(ElementType, NumElements, AltiVec, Pixel); } case pch::TYPE_EXT_VECTOR: { - if (Record.size() != 2) { + if (Record.size() != 4) { Error("incorrect encoding of extended vector type in PCH file"); return QualType(); } diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index caf1ce47a1..a87b8cde2c 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -128,6 +128,8 @@ void PCHTypeWriter::VisitVariableArrayType(const VariableArrayType *T) { void PCHTypeWriter::VisitVectorType(const VectorType *T) { Writer.AddTypeRef(T->getElementType(), Record); Record.push_back(T->getNumElements()); + Record.push_back(T->isAltiVec()); + Record.push_back(T->isPixel()); Code = pch::TYPE_VECTOR; } diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index 9e5f5a2ac0..0f1063eb3c 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -192,6 +192,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { case DeclSpec::TST_decimal32: return "_Decimal32"; case DeclSpec::TST_decimal64: return "_Decimal64"; case DeclSpec::TST_decimal128: return "_Decimal128"; + case DeclSpec::TST_pixel: return "__pixel"; case DeclSpec::TST_enum: return "enum"; case DeclSpec::TST_class: return "class"; case DeclSpec::TST_union: return "union"; @@ -253,6 +254,11 @@ bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); TypeSpecWidth = W; TSWLoc = Loc; + if (TypeAltiVecVector && ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); + DiagID = diag::warn_vector_long_decl_spec_combination; + return true; + } return false; } @@ -289,6 +295,38 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, TypeRep = Rep; TSTLoc = Loc; TypeSpecOwned = Owned; + if (TypeAltiVecVector && (TypeSpecType == TST_double)) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); + DiagID = diag::err_invalid_vector_double_decl_spec_combination; + return true; + } + return false; +} + +bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID) { + if (TypeSpecType != TST_unspecified) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); + DiagID = diag::err_invalid_vector_decl_spec_combination; + return true; + } + TypeAltiVecVector = isAltiVecVector; + AltiVecLoc = Loc; + return false; +} + +bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID) { + if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); + DiagID = diag::err_invalid_pixel_decl_spec_combination; + return true; + } + TypeSpecType = TST_int; + TypeSpecSign = TSS_unsigned; + TypeSpecWidth = TSW_short; + TypeAltiVecPixel = isAltiVecPixel; + TSTLoc = Loc; return false; } diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 9960238300..7856e62f04 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1029,6 +1029,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (DS.hasTypeSpecifier()) goto DoneWithDeclSpec; + // Check for need to substitute AltiVec keyword tokens. + if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) + break; + // It has to be available as a typedef too! TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(), CurScope); @@ -1270,6 +1274,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, DiagID); break; + case tok::kw___vector: + isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); + break; + case tok::kw___pixel: + isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); + break; // class-specifier: case tok::kw_class: @@ -1395,6 +1405,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, /// [OBJC] class-name objc-protocol-refs[opt] [TODO] /// [OBJC] typedef-name objc-protocol-refs[opt] [TODO] /// [C++0x] 'decltype' ( expression ) +/// [AltiVec] '__vector' bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, const char *&PrevSpec, unsigned &DiagID, @@ -1404,6 +1415,10 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, switch (Tok.getKind()) { case tok::identifier: // foo::bar + // Check for need to substitute AltiVec keyword tokens. + if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) + break; + // Fall through. case tok::kw_typename: // typename foo::bar // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. @@ -1520,7 +1535,13 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, DiagID); break; - + case tok::kw___vector: + isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); + break; + case tok::kw___pixel: + isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); + break; + // class-specifier: case tok::kw_class: case tok::kw_struct: @@ -1987,6 +2008,9 @@ bool Parser::isTypeSpecifierQualifier() { default: return false; case tok::identifier: // foo::bar + if (TryAltiVecVectorToken()) + return true; + // Fall through. case tok::kw_typename: // typename T::type // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. @@ -2032,6 +2056,7 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw__Decimal32: case tok::kw__Decimal64: case tok::kw__Decimal128: + case tok::kw___vector: // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: @@ -2072,7 +2097,9 @@ bool Parser::isDeclarationSpecifier() { // Unfortunate hack to support "Class.factoryMethod" notation. if (getLang().ObjC1 && NextToken().is(tok::period)) return false; - // Fall through + if (TryAltiVecVectorToken()) + return true; + // Fall through. case tok::kw_typename: // typename T::type // Annotate typenames and C++ scope specifiers. If we get one, just @@ -2123,6 +2150,7 @@ bool Parser::isDeclarationSpecifier() { case tok::kw__Decimal32: case tok::kw__Decimal64: case tok::kw__Decimal128: + case tok::kw___vector: // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: @@ -2768,7 +2796,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Alternatively, this parameter list may be an identifier list form for a // K&R-style function: void foo(a,b,c) - if (!getLang().CPlusPlus && Tok.is(tok::identifier)) { + if (!getLang().CPlusPlus && Tok.is(tok::identifier) + && !TryAltiVecVectorToken()) { if (!TryAnnotateTypeOrScopeToken()) { // K&R identifier lists can't have typedefs as identifiers, per // C99 6.7.5.3p11. diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 669575c4f0..c6091367fd 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -780,6 +780,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_void: case tok::kw_typename: case tok::kw_typeof: + case tok::kw___vector: case tok::annot_typename: { if (!getLang().CPlusPlus) { Diag(Tok, diag::err_expected_expression); diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 51c56706bb..6251a2f367 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -672,6 +672,11 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, Parser::TPResult Parser::isCXXDeclarationSpecifier() { switch (Tok.getKind()) { case tok::identifier: // foo::bar + // Check for need to substitute AltiVec __vector keyword + // for "vector" identifier. + if (TryAltiVecVectorToken()) + return TPResult::True(); + // Fall through. case tok::kw_typename: // typename T::type // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. @@ -750,6 +755,10 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { case tok::kw___ptr64: case tok::kw___forceinline: return TPResult::True(); + + // AltiVec + case tok::kw___vector: + return TPResult::True(); case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed // We've already annotated a scope; try to annotate a type. diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 63b0a27c08..f15b39a83e 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -346,6 +346,11 @@ void Parser::Initialize() { } Ident_super = &PP.getIdentifierTable().get("super"); + + if (getLang().AltiVec) { + Ident_vector = &PP.getIdentifierTable().get("vector"); + Ident_pixel = &PP.getIdentifierTable().get("pixel"); + } } /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 8833792494..60f3b19060 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -343,6 +343,11 @@ static QualType ConvertDeclSpecToType(Declarator &TheDeclarator, Sema &TheSema){ if (TheSema.getLangOptions().Freestanding) TheSema.Diag(DS.getTypeSpecComplexLoc(), diag::ext_freestanding_complex); Result = Context.getComplexType(Result); + } else if (DS.isTypeAltiVecVector()) { + unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(Result)); + assert(typeSize > 0 && "type size for vector must be greater than 0 bits"); + Result = Context.getVectorType(Result, 128/typeSize, true, + DS.isTypeAltiVecPixel()); } assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary && @@ -1753,7 +1758,7 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, S // Success! Instantiate the vector type, the number of elements is > 0, and // not required to be a power of 2, unlike GCC. - CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); + CurType = S.Context.getVectorType(CurType, vectorSize/typeSize, false, false); } void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL, diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index b1b85e5928..8bac64e127 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -428,7 +428,8 @@ public: /// /// By default, performs semantic analysis when building the vector type. /// Subclasses may override this routine to provide different behavior. - QualType RebuildVectorType(QualType ElementType, unsigned NumElements); + QualType RebuildVectorType(QualType ElementType, unsigned NumElements, + bool IsAltiVec, bool IsPixel); /// \brief Build a new extended vector type given the element type and /// number of elements. @@ -2472,7 +2473,8 @@ QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB, QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) { - Result = getDerived().RebuildVectorType(ElementType, T->getNumElements()); + Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(), + T->isAltiVec(), T->isPixel()); if (Result.isNull()) return QualType(); } @@ -5421,9 +5423,11 @@ TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType, template<typename Derived> QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType, - unsigned NumElements) { + unsigned NumElements, + bool IsAltiVec, bool IsPixel) { // FIXME: semantic checking! - return SemaRef.Context.getVectorType(ElementType, NumElements); + return SemaRef.Context.getVectorType(ElementType, NumElements, + IsAltiVec, IsPixel); } template<typename Derived> |