• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <sstream>
20 #include <stdint.h>
21 #include <string>
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