Matt Wala | 89a7c2b | 2014-07-22 10:55:30 -0700 | [diff] [blame] | 1 | //===- subzero/crosstest/vectors.h - Common SIMD vector utilies -*- C++ -*-===// |
| 2 | // |
| 3 | // The Subzero Code Generator |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file provides declarations for PNaCl portable SIMD vector types. In |
| 11 | // addition, this file provides utilies that may be useful for crosstesting |
| 12 | // vector code. |
| 13 | // |
| 14 | //===----------------------------------------------------------------------===// |
| 15 | |
| 16 | #ifndef VECTORS_H |
| 17 | #define VECTORS_H |
| 18 | |
| 19 | #include <stdint.h> |
| 20 | #include <string> |
| 21 | #include <sstream> |
| 22 | |
Jim Stichnoth | 7da431b | 2014-08-05 11:22:37 -0700 | [diff] [blame] | 23 | // The driver and the test program may be compiled by different |
| 24 | // versions of clang, with different standard libraries that have |
| 25 | // different definitions of int8_t. Specifically, int8_t may be |
| 26 | // typedef'd as either 'char' or 'signed char', which mangle to |
| 27 | // different strings. Avoid int8_t and use an explicit myint8_t. |
| 28 | typedef signed char myint8_t; |
| 29 | |
Matt Wala | 89a7c2b | 2014-07-22 10:55:30 -0700 | [diff] [blame] | 30 | #include "vectors.def" |
| 31 | |
| 32 | // PNaCl portable vector types |
| 33 | // Types declared: v4si32, v4ui32, v8si16, v8ui16, v16si8, v16ui8, v4f32 |
| 34 | #define X(ty, eltty, castty) typedef eltty ty __attribute__((vector_size(16))); |
| 35 | VECTOR_TYPE_TABLE |
| 36 | #undef X |
| 37 | |
| 38 | // i1 vector types are not native C++ SIMD vector types. Instead, for |
| 39 | // testing, they are expanded by the test code into native 128 bit |
| 40 | // SIMD vector types with the appropriate number of elements. |
| 41 | // Representing the types in Vectors<> requires a unique label for each |
| 42 | // type which this declaration provides. |
| 43 | // Types declared: v4i1, v8i1, v16i1 |
| 44 | #define X(ty, expandedty, numelements) class ty; |
| 45 | I1_VECTOR_TYPE_TABLE |
| 46 | #undef X |
| 47 | |
| 48 | namespace { |
| 49 | |
| 50 | template <typename T> struct Vectors; |
| 51 | |
| 52 | // Vectors<T> provides information about a vector type with label T: |
| 53 | // * Vectors<T>::Ty is the C++ vector type |
| 54 | // * Vectors<T>::ElementTy is the C++ element type |
| 55 | // * Vectors<T>::CastTy is a type that is safe to cast elements to and from |
| 56 | // and is used for getting the representation of elements in ostreams |
| 57 | // * Vectors<T>::NumElements is the number of elements |
| 58 | // * Vectors<T>::TypeName is a string that names the type |
| 59 | |
| 60 | #define DECLARE_VECTOR_TYPE(LABEL, TY, ELTTY, CASTTY, NUM_ELEMENTS) \ |
| 61 | template <> struct Vectors<LABEL> { \ |
| 62 | typedef TY Ty; \ |
| 63 | typedef ELTTY ElementTy; \ |
| 64 | typedef CASTTY CastTy; \ |
| 65 | static const size_t NumElements; \ |
| 66 | static const char *const TypeName; \ |
| 67 | }; \ |
| 68 | const size_t Vectors<LABEL>::NumElements = NUM_ELEMENTS; \ |
| 69 | const char *const Vectors<LABEL>::TypeName = #LABEL; |
| 70 | |
| 71 | #define X(ty, eltty, castty) \ |
| 72 | DECLARE_VECTOR_TYPE(ty, ty, eltty, castty, (sizeof(ty) / sizeof(eltty))) |
| 73 | VECTOR_TYPE_TABLE |
| 74 | #undef X |
| 75 | |
| 76 | #define X(ty, expandedty, numelements) \ |
| 77 | DECLARE_VECTOR_TYPE(ty, expandedty, bool, int64_t, numelements) |
| 78 | I1_VECTOR_TYPE_TABLE |
| 79 | #undef X |
| 80 | |
| 81 | #undef DECLARE_VECTOR_TYPE |
| 82 | |
| 83 | // Return a string representation of the vector. |
| 84 | template <typename T> |
| 85 | std::string vectAsString(const typename Vectors<T>::Ty Vect) { |
| 86 | std::ostringstream OS; |
| 87 | for (size_t i = 0; i < Vectors<T>::NumElements; ++i) { |
| 88 | if (i > 0) |
| 89 | OS << " "; |
| 90 | OS << (typename Vectors<T>::CastTy)Vect[i]; |
| 91 | } |
| 92 | return OS.str(); |
| 93 | } |
| 94 | |
| 95 | // In some crosstests, test vectors are deterministically constructed by |
| 96 | // selecting elements from a pool of scalar values based on a |
| 97 | // pseudorandom sequence. Testing all possible combinations of scalar |
| 98 | // values from the value pool is often not tractable. |
| 99 | // |
| 100 | // TODO: Replace with a portable PRNG from C++11. |
| 101 | class PRNG { |
| 102 | public: |
Jim Stichnoth | c6ead20 | 2015-02-24 09:30:30 -0800 | [diff] [blame] | 103 | explicit PRNG(uint32_t Seed = 1) : State(Seed) {} |
Matt Wala | 89a7c2b | 2014-07-22 10:55:30 -0700 | [diff] [blame] | 104 | |
| 105 | uint32_t operator()() { |
| 106 | // Lewis, Goodman, and Miller (1969) |
| 107 | State = (16807 * State) % 2147483647; |
| 108 | return State; |
| 109 | } |
| 110 | |
| 111 | private: |
| 112 | uint32_t State; |
| 113 | }; |
| 114 | |
| 115 | } // end anonymous namespace |
| 116 | |
| 117 | #endif // VECTORS_H |