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
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
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>
vectAsString(const typename Vectors<T>::Ty Vect)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:
State(Seed)103 explicit PRNG(uint32_t Seed = 1) : State(Seed) {}
104
operator()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
118