|  | //===- 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 |