aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-06-23 06:00:24 +0000
committerChris Lattner <sabre@nondot.org>2010-06-23 06:00:24 +0000
commit788b0fd67e1992f23555454efcdb16a19dfefac3 (patch)
tree9a2fb45262ab3d833202750f6cf4c5150ed2c521 /lib
parent8dab6571b2cab96f44d0a1d6e3edbfdb68b7ed6b (diff)
improve altivec vector bool/pixel support, patch by Anton Yartsev
with several tweaks by me. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106619 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp25
-rw-r--r--lib/AST/ASTImporter.cpp7
-rw-r--r--lib/AST/TypePrinter.cpp7
-rw-r--r--lib/CodeGen/Mangle.cpp16
-rw-r--r--lib/Frontend/PCHReader.cpp10
-rw-r--r--lib/Frontend/PCHWriter.cpp3
-rw-r--r--lib/Parse/DeclSpec.cpp55
-rw-r--r--lib/Sema/SemaChecking.cpp3
-rw-r--r--lib/Sema/SemaType.cpp17
-rw-r--r--lib/Sema/TreeTransform.h11
10 files changed, 105 insertions, 49 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 80bda841fe..0be1778260 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1514,7 +1514,7 @@ 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,
- bool IsAltiVec, bool IsPixel) {
+ VectorType::AltiVecSpecific AltiVecSpec) {
BuiltinType *baseType;
baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
@@ -1522,8 +1522,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,
- IsAltiVec, IsPixel);
+ VectorType::Profile(ID, vecType, NumElts, Type::Vector, AltiVecSpec);
+
void *InsertPos = 0;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@@ -1531,16 +1531,19 @@ 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() || IsAltiVec || IsPixel) {
- Canonical = getVectorType(getCanonicalType(vecType),
- NumElts, false, false);
+ if (!vecType.isCanonical() || (AltiVecSpec == VectorType::AltiVec)) {
+ // pass VectorType::NotAltiVec for AltiVecSpec to make AltiVec canonical
+ // vector type (except 'vector bool ...' and 'vector Pixel') the same as
+ // the equivalent GCC vector types
+ Canonical = getVectorType(getCanonicalType(vecType), NumElts,
+ VectorType::NotAltiVec);
// 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, IsAltiVec, IsPixel);
+ VectorType(vecType, NumElts, Canonical, AltiVecSpec);
VectorTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, 0);
@@ -1556,7 +1559,8 @@ 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, false, false);
+ VectorType::Profile(ID, vecType, NumElts, Type::ExtVector,
+ VectorType::NotAltiVec);
void *InsertPos = 0;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@@ -4933,7 +4937,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->isAltiVec(), VTy->isPixel());
+ VTy->getNumElements(), VTy->getAltiVecSpecific());
// For enums, we return the unsigned version of the base type.
if (const EnumType *ETy = T->getAs<EnumType>())
@@ -5091,7 +5095,8 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false);
// FIXME: Don't know what to do about AltiVec.
- Type = Context.getVectorType(ElementType, NumElements, false, false);
+ Type = Context.getVectorType(ElementType, NumElements,
+ VectorType::NotAltiVec);
break;
}
case 'X': {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index e1c2abd251..8d347d1716 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -440,9 +440,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
if (Vec1->getNumElements() != Vec2->getNumElements())
return false;
- if (Vec1->isAltiVec() != Vec2->isAltiVec())
- return false;
- if (Vec1->isPixel() != Vec2->isPixel())
+ if (Vec1->getAltiVecSpecific() != Vec2->getAltiVecSpecific())
return false;
break;
}
@@ -1191,8 +1189,7 @@ QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
return Importer.getToContext().getVectorType(ToElementType,
T->getNumElements(),
- T->isAltiVec(),
- T->isPixel());
+ T->getAltiVecSpecific());
}
QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 2fa84f350b..a08ee1ae69 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -227,12 +227,13 @@ void TypePrinter::PrintDependentSizedExtVector(
}
void TypePrinter::PrintVector(const VectorType *T, std::string &S) {
- if (T->isAltiVec()) {
- if (T->isPixel())
+ if (T->getAltiVecSpecific() != VectorType::NotAltiVec) {
+ if (T->getAltiVecSpecific() == VectorType::Pixel)
S = "__vector __pixel " + S;
else {
Print(T->getElementType(), S);
- S = "__vector " + S;
+ S = ((T->getAltiVecSpecific() == VectorType::Bool)
+ ? "__vector __bool " : "__vector ") + S;
}
} else {
// FIXME: We prefer to print the size directly here, but have no way
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index e1e2f1069b..01838f98d4 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -1322,12 +1322,20 @@ void CXXNameMangler::mangleType(const ComplexType *T) {
}
// GNU extension: vector types
-// <type> ::= <vector-type>
-// <vector-type> ::= Dv <positive dimension number> _ <element type>
-// ::= Dv [<dimension expression>] _ <element type>
+// <type> ::= <vector-type>
+// <vector-type> ::= Dv <positive dimension number> _
+// <extended element type>
+// ::= Dv [<dimension expression>] _ <element type>
+// <extended element type> ::= <element type>
+// ::= p # AltiVec vector pixel
void CXXNameMangler::mangleType(const VectorType *T) {
Out << "Dv" << T->getNumElements() << '_';
- mangleType(T->getElementType());
+ if (T->getAltiVecSpecific() == VectorType::Pixel)
+ Out << 'p';
+ else if (T->getAltiVecSpecific() == VectorType::Bool)
+ Out << 'b';
+ else
+ mangleType(T->getElementType());
}
void CXXNameMangler::mangleType(const ExtVectorType *T) {
mangleType(static_cast<const VectorType*>(T));
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index b83445bc50..97c4d380eb 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -2060,20 +2060,20 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
}
case pch::TYPE_VECTOR: {
- if (Record.size() != 4) {
+ if (Record.size() != 3) {
Error("incorrect encoding of vector type in PCH file");
return QualType();
}
QualType ElementType = GetType(Record[0]);
unsigned NumElements = Record[1];
- bool AltiVec = Record[2];
- bool Pixel = Record[3];
- return Context->getVectorType(ElementType, NumElements, AltiVec, Pixel);
+ unsigned AltiVecSpec = Record[2];
+ return Context->getVectorType(ElementType, NumElements,
+ (VectorType::AltiVecSpecific)AltiVecSpec);
}
case pch::TYPE_EXT_VECTOR: {
- if (Record.size() != 4) {
+ if (Record.size() != 3) {
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 1fb90851b5..a55684a29a 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -128,8 +128,7 @@ 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());
+ Record.push_back(T->getAltiVecSpecific());
Code = pch::TYPE_VECTOR;
}
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index 5dc08b3dfa..2f328b0e65 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Parse/DeclSpec.cpp
@@ -253,7 +253,8 @@ 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))) {
+ if (TypeAltiVecVector && !TypeAltiVecBool &&
+ ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
DiagID = diag::warn_vector_long_decl_spec_combination;
return true;
@@ -290,13 +291,18 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
DiagID = diag::err_invalid_decl_spec_combination;
return true;
}
+ if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
+ TypeAltiVecBool = true;
+ TSTLoc = Loc;
+ return false;
+ }
TypeSpecType = T;
TypeRep = Rep;
TSTLoc = Loc;
TypeSpecOwned = Owned;
- if (TypeAltiVecVector && (TypeSpecType == TST_double)) {
+ if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
- DiagID = diag::err_invalid_vector_double_decl_spec_combination;
+ DiagID = diag::err_invalid_vector_decl_spec;
return true;
}
return false;
@@ -316,14 +322,12 @@ bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID) {
- if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) {
+ if (!TypeAltiVecVector || TypeAltiVecPixel ||
+ (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;
@@ -438,6 +442,42 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
// Check the type specifier components first.
SourceManager &SrcMgr = PP.getSourceManager();
+ // Validate and finalize AltiVec vector declspec.
+ if (TypeAltiVecVector) {
+ if (TypeAltiVecBool) {
+ // Sign specifiers are not allowed with vector bool. (PIM 2.1)
+ if (TypeSpecSign != TSS_unspecified) {
+ Diag(D, TSSLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+ << getSpecifierName((TSS)TypeSpecSign);
+ }
+
+ // Only char/int are valid with vector bool. (PIM 2.1)
+ if ((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
+ (TypeSpecType != TST_int) || TypeAltiVecPixel) {
+ Diag(D, TSTLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+ << (TypeAltiVecPixel ? "__pixel" :
+ getSpecifierName((TST)TypeSpecType));
+ }
+
+ // Only 'short' is valid with vector bool. (PIM 2.1)
+ if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
+ Diag(D, TSWLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+ << getSpecifierName((TSW)TypeSpecWidth);
+
+ // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
+ if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
+ (TypeSpecWidth != TSW_unspecified))
+ TypeSpecSign = TSS_unsigned;
+ }
+
+ if (TypeAltiVecPixel) {
+ //TODO: perform validation
+ TypeSpecType = TST_int;
+ TypeSpecSign = TSS_unsigned;
+ TypeSpecWidth = TSW_short;
+ }
+ }
+
// signed/unsigned are only valid with int/char/wchar_t.
if (TypeSpecSign != TSS_unspecified) {
if (TypeSpecType == TST_unspecified)
@@ -513,7 +553,6 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
ClearStorageClassSpecs();
}
-
// Okay, now we can infer the real type.
// TODO: return "auto function" and other bad things based on the real type.
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index d9264870ae..b61b4d65c9 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -782,7 +782,8 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
return ExprError();
} else if (numElements != numResElements) {
QualType eltType = LHSType->getAs<VectorType>()->getElementType();
- resType = Context.getVectorType(eltType, numResElements, false, false);
+ resType = Context.getVectorType(eltType, numResElements,
+ VectorType::NotAltiVec);
}
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 48c17cde43..244f218860 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -383,8 +383,12 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
} 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());
+ VectorType::AltiVecSpecific AltiVecSpec = VectorType::AltiVec;
+ if (DS.isTypeAltiVecPixel())
+ AltiVecSpec = VectorType::Pixel;
+ else if (DS.isTypeAltiVecBool())
+ AltiVecSpec = VectorType::Bool;
+ Result = Context.getVectorType(Result, 128/typeSize, AltiVecSpec);
}
assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary &&
@@ -1162,7 +1166,8 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
}
if (FTI.NumArgs && FTI.ArgInfo[0].Param == 0) {
- // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
+ // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function
+ // definition.
Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
D.setInvalidType(true);
break;
@@ -1880,7 +1885,8 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
/// The raw attribute should contain precisely 1 argument, the vector size for
/// the variable, measured in bytes. If curType and rawAttr are well formed,
/// this routine will return a new vector type.
-static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, Sema &S) {
+static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr,
+ Sema &S) {
// Check the attribute arugments.
if (Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
@@ -1923,7 +1929,8 @@ 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, false, false);
+ CurType = S.Context.getVectorType(CurType, vectorSize/typeSize,
+ VectorType::NotAltiVec);
}
void ProcessTypeAttributeList(Sema &S, QualType &Result,
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index d959f1c22e..b2a405934c 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -442,7 +442,7 @@ 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,
- bool IsAltiVec, bool IsPixel);
+ VectorType::AltiVecSpecific AltiVecSpec);
/// \brief Build a new extended vector type given the element type and
/// number of elements.
@@ -2811,7 +2811,7 @@ QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
if (getDerived().AlwaysRebuild() ||
ElementType != T->getElementType()) {
Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
- T->isAltiVec(), T->isPixel());
+ T->getAltiVecSpecific());
if (Result.isNull())
return QualType();
}
@@ -6345,11 +6345,10 @@ TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
template<typename Derived>
QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
- unsigned NumElements,
- bool IsAltiVec, bool IsPixel) {
+ unsigned NumElements,
+ VectorType::AltiVecSpecific AltiVecSpec) {
// FIXME: semantic checking!
- return SemaRef.Context.getVectorType(ElementType, NumElements,
- IsAltiVec, IsPixel);
+ return SemaRef.Context.getVectorType(ElementType, NumElements, AltiVecSpec);
}
template<typename Derived>