//===- subzero/crosstest/vectors.h - Common SIMD vector utilies -*- C++ -*-===// // // The Subzero Code Generator // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file provides declarations for PNaCl portable SIMD vector types. In // addition, this file provides utilies that may be useful for crosstesting // vector code. // //===----------------------------------------------------------------------===// #ifndef VECTORS_H #define VECTORS_H #include <stdint.h> #include <string> #include <sstream> // The driver and the test program may be compiled by different // versions of clang, with different standard libraries that have // different definitions of int8_t. Specifically, int8_t may be // typedef'd as either 'char' or 'signed char', which mangle to // different strings. Avoid int8_t and use an explicit myint8_t. typedef signed char myint8_t; #include "vectors.def" // PNaCl portable vector types // Types declared: v4si32, v4ui32, v8si16, v8ui16, v16si8, v16ui8, v4f32 #define X(ty, eltty, castty) typedef eltty ty __attribute__((vector_size(16))); VECTOR_TYPE_TABLE #undef X // i1 vector types are not native C++ SIMD vector types. Instead, for // testing, they are expanded by the test code into native 128 bit // SIMD vector types with the appropriate number of elements. // Representing the types in Vectors<> requires a unique label for each // type which this declaration provides. // Types declared: v4i1, v8i1, v16i1 #define X(ty, expandedty, numelements) class ty; I1_VECTOR_TYPE_TABLE #undef X namespace { template <typename T> struct Vectors; // Vectors<T> provides information about a vector type with label T: // * Vectors<T>::Ty is the C++ vector type // * Vectors<T>::ElementTy is the C++ element type // * Vectors<T>::CastTy is a type that is safe to cast elements to and from // and is used for getting the representation of elements in ostreams // * Vectors<T>::NumElements is the number of elements // * Vectors<T>::TypeName is a string that names the type #define DECLARE_VECTOR_TYPE(LABEL, TY, ELTTY, CASTTY, NUM_ELEMENTS) \ template <> struct Vectors<LABEL> { \ typedef TY Ty; \ typedef ELTTY ElementTy; \ typedef CASTTY CastTy; \ static const size_t NumElements; \ static const char *const TypeName; \ }; \ const size_t Vectors<LABEL>::NumElements = NUM_ELEMENTS; \ const char *const Vectors<LABEL>::TypeName = #LABEL; #define X(ty, eltty, castty) \ DECLARE_VECTOR_TYPE(ty, ty, eltty, castty, (sizeof(ty) / sizeof(eltty))) VECTOR_TYPE_TABLE #undef X #define X(ty, expandedty, numelements) \ DECLARE_VECTOR_TYPE(ty, expandedty, bool, int64_t, numelements) I1_VECTOR_TYPE_TABLE #undef X #undef DECLARE_VECTOR_TYPE // Return a string representation of the vector. template <typename T> std::string vectAsString(const typename Vectors<T>::Ty Vect) { std::ostringstream OS; for (size_t i = 0; i < Vectors<T>::NumElements; ++i) { if (i > 0) OS << " "; OS << (typename Vectors<T>::CastTy)Vect[i]; } return OS.str(); } // In some crosstests, test vectors are deterministically constructed by // selecting elements from a pool of scalar values based on a // pseudorandom sequence. Testing all possible combinations of scalar // values from the value pool is often not tractable. // // TODO: Replace with a portable PRNG from C++11. class PRNG { public: explicit PRNG(uint32_t Seed = 1) : State(Seed) {} uint32_t operator()() { // Lewis, Goodman, and Miller (1969) State = (16807 * State) % 2147483647; return State; } private: uint32_t State; }; } // end anonymous namespace #endif // VECTORS_H