OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [language/] [cxx/] [ustl/] [current/] [include/] [ustl/] [utuple.h] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
// This file is part of the uSTL library, an STL implementation.
2
//
3
// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net>
4
// This file is free software, distributed under the MIT License.
5
 
6
#ifndef UTUPLE_H_7324ADEC49B397CA74A56F6050FD5A6B
7
#define UTUPLE_H_7324ADEC49B397CA74A56F6050FD5A6B
8
 
9
#include "ualgo.h"
10
#include "metamac.h"
11
 
12
namespace ustl {
13
 
14
/// \class tuple utuple.h ustl.h
15
/// \ingroup Sequences
16
///
17
/// \brief A fixed-size array of \p N \p Ts.
18
///
19
template <size_t N, typename T>
20
class tuple {
21
public:
22
    typedef T                                           value_type;
23
    typedef size_t                                      size_type;
24
    typedef value_type*                                 pointer;
25
    typedef const value_type*                           const_pointer;
26
    typedef value_type&                                 reference;
27
    typedef const value_type&                           const_reference;
28
    typedef pointer                                     iterator;
29
    typedef const_pointer                               const_iterator;
30
    typedef ::ustl::reverse_iterator<iterator>          reverse_iterator;
31
    typedef ::ustl::reverse_iterator<const_iterator>    const_reverse_iterator;
32
    typedef pair<iterator,iterator>                     range_t;
33
    typedef pair<const_iterator,const_iterator>         const_range_t;
34
public:
35
    template <typename T2>
36
    inline                      tuple (const tuple<N,T2>& t);
37
    inline                      tuple (const tuple<N,T>& t);
38
    inline                      tuple (const_pointer v);
39
    inline                      tuple (void);
40
    explicit inline             tuple (const_reference v0, const_reference v1 = T(), const_reference v2 = T(), const_reference v3 = T());
41
    inline iterator             begin (void)                    { return (m_v); }
42
    inline const_iterator       begin (void) const              { return (m_v); }
43
    inline iterator             end (void)                      { return (begin() + N); }
44
    inline const_iterator       end (void) const                { return (begin() + N); }
45
    inline size_type            size (void) const               { return (N); }
46
    inline size_type            max_size (void) const           { return (N); }
47
    inline bool                 empty (void) const              { return (N == 0); }
48
    inline const_reference      at (size_type i) const          { return (m_v[i]); }
49
    inline reference            at (size_type i)                { return (m_v[i]); }
50
    inline const_reference      operator[] (size_type i) const  { return (m_v[i]); }
51
    inline reference            operator[] (size_type i)        { return (m_v[i]); }
52
    template <typename T2>
53
    inline const tuple&         operator= (const tuple<N,T2>& src);
54
    inline const tuple&         operator= (const tuple<N,T>& src);
55
    inline const tuple&         operator+= (const_reference v)
56
                                    { for (uoff_t i = 0; i < N; ++ i) m_v[i] += v; return (*this); }
57
    inline const tuple&         operator-= (const_reference v)
58
                                    { for (uoff_t i = 0; i < N; ++ i) m_v[i] -= v; return (*this); }
59
    inline const tuple&         operator*= (const_reference v)
60
                                    { for (uoff_t i = 0; i < N; ++ i) m_v[i] *= v; return (*this); }
61
    inline const tuple&         operator/= (const_reference v)
62
                                    { for (uoff_t i = 0; i < N; ++ i) m_v[i] /= v; return (*this); }
63
    inline const tuple          operator+ (const_reference v) const
64
                                    { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] + v; return (result); }
65
    inline const tuple          operator- (const_reference v) const
66
                                    { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] - v; return (result); }
67
    inline const tuple          operator* (const_reference v) const
68
                                    { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] * v; return (result); }
69
    inline const tuple          operator/ (const_reference v) const
70
                                    { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] / v; return (result); }
71
    inline void                 swap (tuple<N,T>& v)
72
                                    { for (uoff_t i = 0; i < N; ++ i) ::ustl::swap (m_v[i], v.m_v[i]); }
73
    inline void                 read (istream& is)                      { nr_container_read (is, *this); }
74
    inline void                 write (ostream& os) const               { nr_container_write (os, *this); }
75
    inline void                 text_write (ostringstream& os) const    { container_text_write (os, *this); }
76
    inline size_t               stream_size (void) const                { return (nr_container_stream_size (*this)); }
77
private:
78
    T                           m_v [N];
79
};
80
 
81
} // namespace ustl
82
 
83
#include "simd.h"
84
 
85
namespace ustl {
86
 
87
template <size_t N, typename T>
88
template <typename T2>
89
inline tuple<N,T>::tuple (const tuple<N,T2>& t)
90
{ simd::pconvert (t, *this, simd::fcast<T2,T>()); }
91
 
92
template <size_t N, typename T>
93
inline tuple<N,T>::tuple (const tuple<N,T>& t)
94
{ simd::passign (t, *this); }
95
 
96
template <size_t N, typename T>
97
inline tuple<N,T>::tuple (const_pointer v)
98
{ simd::ipassign (v, *this); }
99
 
100
template <size_t N, typename T>
101
inline tuple<N,T>::tuple (void)
102
{
103
    const T v = T();
104
    if (N > 4 || !numeric_limits<T>::is_integral)
105
        fill_n (m_v, N, v);
106
    else {
107
        m_v[0] = v;
108
        if (N > 1) m_v[1] = v;
109
        if (N > 2) m_v[2] = v;
110
        if (N > 3) m_v[3] = v;
111
    }
112
}
113
 
114
template <size_t N, typename T>
115
inline tuple<N,T>::tuple (const_reference v0, const_reference v1, const_reference v2, const_reference v3)
116
{
117
    m_v[0] = v0;
118
    if (N > 1) m_v[1] = v1;
119
    if (N > 2) m_v[2] = v2;
120
    if (N > 3) m_v[3] = v3;
121
    if (N > 4) fill_n (m_v + 4, N - 4, T());
122
}
123
 
124
template <size_t N, typename T>
125
template <typename T2>
126
inline const tuple<N,T>& tuple<N,T>::operator= (const tuple<N,T2>& src)
127
{ simd::pconvert (src, *this, simd::fcast<T2,T>()); return (*this); }
128
 
129
template <size_t N, typename T>
130
inline const tuple<N,T>& tuple<N,T>::operator= (const tuple<N,T>& src)
131
{ simd::passign (src, *this); return (*this); }
132
 
133
template <size_t N, typename T1, typename T2>
134
inline bool operator== (const tuple<N,T1>& t1, const tuple<N,T2>& t2)
135
{
136
    for (uoff_t i = 0; i < N; ++ i)
137
        if (t1[i] != t2[i])
138
            return (false);
139
    return (true);
140
}
141
 
142
template <size_t N, typename T1, typename T2>
143
inline bool operator< (const tuple<N,T1>& t1, const tuple<N,T2>& t2)
144
{
145
    for (uoff_t i = 0; i < N && t1[i] <= t2[i]; ++ i)
146
        if (t1[i] < t2[i])
147
            return (true);
148
    return (false);
149
}
150
 
151
template <size_t N, typename T1, typename T2>
152
inline const tuple<N,T1>& operator+= (tuple<N,T1>& t1, const tuple<N,T2>& t2)
153
    { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] + t2[i]); return (t1); }
154
 
155
template <size_t N, typename T1, typename T2>
156
inline const tuple<N,T1>& operator-= (tuple<N,T1>& t1, const tuple<N,T2>& t2)
157
    { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] - t2[i]); return (t1); }
158
 
159
template <size_t N, typename T1, typename T2>
160
inline const tuple<N,T1>& operator*= (tuple<N,T1>& t1, const tuple<N,T2>& t2)
161
    { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] * t2[i]); return (t1); }
162
 
163
template <size_t N, typename T1, typename T2>
164
inline const tuple<N,T1>& operator/= (tuple<N,T1>& t1, const tuple<N,T2>& t2)
165
    { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] / t2[i]); return (t1); }
166
 
167
template <size_t N, typename T1, typename T2>
168
inline const tuple<N,T1> operator+ (const tuple<N,T1>& t1, const tuple<N,T2>& t2)
169
{
170
    tuple<N,T1> result;
171
    for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] + t2[i]);
172
    return (result);
173
}
174
 
175
template <size_t N, typename T1, typename T2>
176
inline const tuple<N,T1> operator- (const tuple<N,T1>& t1, const tuple<N,T2>& t2)
177
{
178
    tuple<N,T1> result;
179
    for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] - t2[i]);
180
    return (result);
181
}
182
 
183
template <size_t N, typename T1, typename T2>
184
inline const tuple<N,T1> operator* (const tuple<N,T1>& t1, const tuple<N,T2>& t2)
185
{
186
    tuple<N,T1> result;
187
    for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] * t2[i]);
188
    return (result);
189
}
190
 
191
template <size_t N, typename T1, typename T2>
192
inline const tuple<N,T1> operator/ (const tuple<N,T1>& t1, const tuple<N,T2>& t2)
193
{
194
    tuple<N,T1> result;
195
    for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] / t2[i]);
196
    return (result);
197
}
198
 
199
//----------------------------------------------------------------------
200
// Define SIMD specializations for member functions.
201
 
202
#if CPU_HAS_SSE
203
#define SSE_TUPLE_SPECS(n,type)                                                 \
204
template <> inline tuple<n,type>::tuple (void)                                  \
205
{ asm("xorps %%xmm0, %%xmm0\n\tmovups %%xmm0, %0":"+m"(m_v[0])::"xmm0","memory"); } \
206
template<> inline void tuple<n,type>::swap (tuple<n,type>& v)                   \
207
{                                                                               \
208
    asm ("movups %0,%%xmm0\n\tmovups %1,%%xmm1\n\t"                             \
209
        "movups %%xmm0,%1\n\tmovups %%xmm1,%0"                                  \
210
        : "+m"(m_v[0]), "+m"(v.m_v[0]) :: "xmm0","xmm1","memory");                \
211
}
212
SSE_TUPLE_SPECS(4,float)
213
SSE_TUPLE_SPECS(4,int32_t)
214
SSE_TUPLE_SPECS(4,uint32_t)
215
#undef SSE_TUPLE_SPECS
216
#endif
217
#if SIZE_OF_LONG == 8 && __GNUC__
218
#define LONG_TUPLE_SPECS(n,type)                \
219
template <> inline tuple<n,type>::tuple (void)  \
220
{ asm("":"+m"(m_v[0])::"memory");                \
221
  *noalias_cast<long*>(m_v) = 0; }                               \
222
template<> inline void tuple<n,type>::swap (tuple<n,type>& v)   \
223
{ asm("":"+m"(m_v[0]),"+m"(v.m_v[0])::"memory");                  \
224
  iter_swap (noalias_cast<long*>(m_v), noalias_cast<long*>(v.m_v));     \
225
  asm("":"+m"(m_v[0]),"+m"(v.m_v[0])::"memory");                  \
226
}
227
LONG_TUPLE_SPECS(2,float)
228
LONG_TUPLE_SPECS(4,int16_t)
229
LONG_TUPLE_SPECS(4,uint16_t)
230
LONG_TUPLE_SPECS(2,int32_t)
231
LONG_TUPLE_SPECS(2,uint32_t)
232
LONG_TUPLE_SPECS(8,int8_t)
233
LONG_TUPLE_SPECS(8,uint8_t)
234
#undef LONG_TUPLE_SPECS
235
#elif CPU_HAS_MMX
236
#define MMX_TUPLE_SPECS(n,type)         \
237
template <> inline tuple<n,type>::tuple (void)  \
238
{  asm ("pxor %%mm0, %%mm0\n\tmovq %%mm0, %0"   \
239
        :"=m"(m_v[0])::"mm0","st","memory"); simd::reset_mmx(); }        \
240
template<> inline void tuple<n,type>::swap (tuple<n,type>& v)           \
241
{  asm ("movq %2,%%mm0\n\tmovq %3,%%mm1\n\t"                            \
242
        "movq %%mm0,%1\n\tmovq %%mm1,%0"                                \
243
        :"=m"(m_v[0]),"=m"(v.m_v[0]):"m"(m_v[0]),"m"(v.m_v[0]):"mm0","mm1","st","st(1)","memory"); \
244
   simd::reset_mmx();                                                   \
245
}
246
MMX_TUPLE_SPECS(2,float)
247
MMX_TUPLE_SPECS(4,int16_t)
248
MMX_TUPLE_SPECS(4,uint16_t)
249
MMX_TUPLE_SPECS(2,int32_t)
250
MMX_TUPLE_SPECS(2,uint32_t)
251
MMX_TUPLE_SPECS(8,int8_t)
252
MMX_TUPLE_SPECS(8,uint8_t)
253
#undef MMX_TUPLE_SPECS
254
#endif
255
 
256
#if __i386__ || __x86_64__
257
#define UINT32_TUPLE_SPECS(type,otype)          \
258
template <> inline tuple<2,type>::tuple (void)  \
259
{ asm("":"+m"(m_v[0]),"+m"(m_v[1])::"memory");   \
260
  *noalias_cast<uint32_t*>(m_v) = 0;             \
261
  asm("":"+m"(m_v[0]),"+m"(m_v[1])::"memory"); }\
262
template <> inline const tuple<2,type>& tuple<2,type>::operator= (const tuple<2,type>& v)\
263
{ asm ("mov %3, %0"                                                     \
264
       :"=m"(*noalias_cast<uint32_t*>(m_v)),"=m"(m_v[0]),"=m"(m_v[1])    \
265
       :"r"(*noalias_cast<const uint32_t*>(v.begin())),"m"(v[0]),"m"(v[1]):"memory");    \
266
  return (*this); }                                                     \
267
template <> template <>                                                 \
268
inline const tuple<2,type>& tuple<2,type>::operator= (const tuple<2,otype>& v)\
269
{ asm ("mov %3, %0"                                                     \
270
       :"=m"(*noalias_cast<uint32_t*>(m_v)),"=m"(m_v[0]),"=m"(m_v[1])    \
271
       :"r"(*noalias_cast<const uint32_t*>(v.begin())),"m"(v[0]),"m"(v[1]):"memory");    \
272
  return (*this); }                                                     \
273
template <> inline tuple<2,type>::tuple (const tuple<2,type>& v)        \
274
{ operator= (v); }                                                      \
275
template <> template <>                                                 \
276
inline tuple<2,type>::tuple (const tuple<2,otype>& v)                   \
277
{ operator= (v); }                                                      \
278
template<> inline void tuple<2,type>::swap (tuple<2,type>& v)           \
279
{ asm(""::"m"(m_v[0]),"m"(m_v[1]),"m"(v.m_v[0]),"m"(v.m_v[1]):"memory");\
280
  iter_swap (noalias_cast<uint32_t*>(m_v), noalias_cast<uint32_t*>(v.m_v));                     \
281
  asm("":"=m"(m_v[0]),"=m"(m_v[1]),"=m"(v.m_v[0]),"=m"(v.m_v[1])::"memory"); }                            \
282
template <> inline const tuple<2,type>& operator+= (tuple<2,type>& t1, const tuple<2,type>& t2) \
283
    { t1[0] += t2[0]; t1[1] += t2[1]; return (t1); }                                              \
284
template <> inline const tuple<2,type>& operator-= (tuple<2,type>& t1, const tuple<2,type>& t2) \
285
    { t1[0] -= t2[0]; t1[1] -= t2[1]; return (t1); }                                              \
286
template <> inline const tuple<2,type> operator+ (const tuple<2,type>& t1, const tuple<2,type>& t2) \
287
    { return (tuple<2,type> (t1[0] + t2[0], t1[1] + t2[1])); }                                    \
288
template <> inline const tuple<2,type> operator- (const tuple<2,type>& t1, const tuple<2,type>& t2) \
289
    { return (tuple<2,type> (t1[0] - t2[0], t1[1] - t2[1])); }
290
UINT32_TUPLE_SPECS(int16_t,uint16_t)
291
UINT32_TUPLE_SPECS(uint16_t,int16_t)
292
#undef UINT32_TUPLE_SPECS
293
#endif
294
 
295
#undef TUPLEV_R1
296
#undef TUPLEV_R2
297
#undef TUPLEV_W1
298
#undef TUPLEV_W2
299
 
300
#define SIMD_TUPLE_PACKOP(N,T)  \
301
template <> inline const tuple<N,T>& operator+= (tuple<N,T>& t1, const tuple<N,T>& t2)  \
302
    { simd::padd (t2, t1); return (t1); }                                               \
303
template <> inline const tuple<N,T>& operator-= (tuple<N,T>& t1, const tuple<N,T>& t2)  \
304
    { simd::psub (t2, t1); return (t1); }                                               \
305
template <> inline const tuple<N,T>& operator*= (tuple<N,T>& t1, const tuple<N,T>& t2)  \
306
    { simd::pmul (t2, t1); return (t1); }                                               \
307
template <> inline const tuple<N,T>& operator/= (tuple<N,T>& t1, const tuple<N,T>& t2)  \
308
    { simd::pdiv (t2, t1); return (t1); }                                               \
309
template <> inline const tuple<N,T> operator+ (const tuple<N,T>& t1, const tuple<N,T>& t2) \
310
    { tuple<N,T> result (t1); simd::padd (t2, result); return (result); }               \
311
template <> inline const tuple<N,T> operator- (const tuple<N,T>& t1, const tuple<N,T>& t2) \
312
    { tuple<N,T> result (t1); simd::psub (t2, result); return (result); }               \
313
template <> inline const tuple<N,T> operator* (const tuple<N,T>& t1, const tuple<N,T>& t2) \
314
    { tuple<N,T> result (t1); simd::pmul (t2, result); return (result); }               \
315
template <> inline const tuple<N,T> operator/ (const tuple<N,T>& t1, const tuple<N,T>& t2) \
316
    { tuple<N,T> result (t1); simd::pdiv (t2, result); return (result); }
317
SIMD_TUPLE_PACKOP(4,float)
318
SIMD_TUPLE_PACKOP(2,float)
319
SIMD_TUPLE_PACKOP(2,double)
320
SIMD_TUPLE_PACKOP(4,int32_t)
321
SIMD_TUPLE_PACKOP(4,uint32_t)
322
SIMD_TUPLE_PACKOP(4,int16_t)
323
SIMD_TUPLE_PACKOP(4,uint16_t)
324
SIMD_TUPLE_PACKOP(2,int32_t)
325
SIMD_TUPLE_PACKOP(2,uint32_t)
326
SIMD_TUPLE_PACKOP(8,int8_t)
327
SIMD_TUPLE_PACKOP(8,uint8_t)
328
#undef SIMD_TUPLE_PACKOP
329
 
330
} // namespace ustl
331
 
332
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.