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