2009-01-19 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mcs / class / Mono.Simd / Mono.Simd / Vector8us.cs
1 // Vector8us.cs
2 //
3 // Author:
4 //   Rodrigo Kumpera (rkumpera@novell.com)
5 //
6 // (C) 2008 Novell, Inc. (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 //
27 using System;
28 using System.Runtime.InteropServices;
29
30 namespace Mono.Simd
31 {
32         [StructLayout(LayoutKind.Explicit, Pack = 0, Size = 16)]
33         [CLSCompliant(false)]
34         public struct Vector8us
35         {
36                 [ FieldOffset(0) ]
37                 internal ushort v0;
38                 [ FieldOffset(2) ]
39                 internal ushort v1;
40                 [ FieldOffset(4) ]
41                 internal ushort v2;
42                 [ FieldOffset(6) ]
43                 internal ushort v3;
44                 [ FieldOffset(8) ]
45                 internal ushort v4;
46                 [ FieldOffset(10) ]
47                 internal ushort v5;
48                 [ FieldOffset(12) ]
49                 internal ushort v6;
50                 [ FieldOffset(14) ]
51                 internal ushort v7;
52
53                 public Vector8us (ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7)
54                 {
55                         this.v0 = v0;
56                         this.v1 = v1;
57                         this.v2 = v2;
58                         this.v3 = v3;
59                         this.v4 = v4;
60                         this.v5 = v5;
61                         this.v6 = v6;
62                         this.v7 = v7;
63                 }
64                 
65                 public Vector8us (ushort us)
66                 {
67                         this.v0 = us;
68                         this.v1 = us;
69                         this.v2 = us;
70                         this.v3 = us;
71                         this.v4 = us;
72                         this.v5 = us;
73                         this.v6 = us;
74                         this.v7 = us;
75                 }
76
77                 public ushort V0 { get { return v0; } set { v0 = value; } }
78                 public ushort V1 { get { return v1; } set { v1 = value; } }
79                 public ushort V2 { get { return v2; } set { v2 = value; } }
80                 public ushort V3 { get { return v3; } set { v3 = value; } }
81                 public ushort V4 { get { return v4; } set { v4 = value; } }
82                 public ushort V5 { get { return v5; } set { v5 = value; } }
83                 public ushort V6 { get { return v6; } set { v6 = value; } }
84                 public ushort V7 { get { return v7; } set { v7 = value; } }
85
86                 public static Vector8us Identity
87                 {
88                         get { return  new Vector8us (1); }
89                 }
90
91                 public static Vector8us Zero
92                 {
93                         get { return  new Vector8us (0); }
94                 }
95
96                 [System.Runtime.CompilerServices.IndexerName ("Component")]
97                 public unsafe ushort this [int index]
98                 {
99                         get {
100                                 if ((index | 0x7) != 0x7) //index < 0 || index > 7
101                                         throw new ArgumentOutOfRangeException ("index");
102                                 fixed (ushort *v = &v0) {
103                                         return * (v + index);
104                                 }
105                         }
106                         set {
107                                 if ( (index | 0x7) != 0x7) //index < 0 || index > 7
108                                         throw new ArgumentOutOfRangeException ("index");
109                                 fixed (ushort *v = &v0) {
110                                         * (v + index) = value;
111                                 }
112                         }
113                 }
114
115                 [Acceleration (AccelMode.SSE2)]
116                 public static unsafe Vector8us operator + (Vector8us va, Vector8us vb)
117                 {
118                         Vector8us res = new Vector8us ();
119                         ushort *a = &va.v0;
120                         ushort *b = &vb.v0;
121                         ushort *c = &res.v0;
122                         for (int i = 0; i < 8; ++i)
123                                 *c++ = (ushort)(*a++ + *b++);
124                         return res;
125                 }
126
127                 [Acceleration (AccelMode.SSE2)]
128                 public static unsafe Vector8us operator - (Vector8us va, Vector8us vb)
129                 {
130                         Vector8us res = new Vector8us ();
131                         ushort *a = &va.v0;
132                         ushort *b = &vb.v0;
133                         ushort *c = &res.v0;
134                         for (int i = 0; i < 8; ++i)
135                                 *c++ = (ushort)(*a++ - *b++);
136                         return res;
137                 }
138
139                 /*
140                  * NOTE: Thou pmullw states it does signed multiplication, it works for unsigned numbers
141                  * if only the lower part is considered and the flags disregarded.
142                  */
143                 [Acceleration (AccelMode.SSE2)]
144                 public static unsafe Vector8us operator * (Vector8us va, Vector8us vb)
145                 {
146                         Vector8us res = new Vector8us ();
147                         ushort *a = &va.v0;
148                         ushort *b = &vb.v0;
149                         ushort *c = &res.v0;
150                         for (int i = 0; i < 8; ++i)
151                                 *c++ = (ushort)(*a++ * (*b++));
152                         return res;
153                 }
154
155                 [Acceleration (AccelMode.SSE2)]
156                 public static unsafe Vector8us operator >> (Vector8us va, int amount)
157                 {
158                         Vector8us res = new Vector8us ();
159                         ushort *a = &va.v0;
160                         ushort *b = &res.v0;
161                         for (int i = 0; i < 8; ++i)
162                                 *b++ = (ushort)(*a++ >> amount);
163                         return res;
164                 }
165
166                 [Acceleration (AccelMode.SSE2)]
167                 public static unsafe Vector8us operator << (Vector8us va, int amount)
168                 {
169                         Vector8us res = new Vector8us ();
170                         ushort *a = &va.v0;
171                         ushort *b = &res.v0;
172                         for (int i = 0; i < 8; ++i)
173                                 *b++ = (ushort)(*a++ << amount);
174                         return res;
175                 }
176
177                 [Acceleration (AccelMode.SSE2)]
178                 public static unsafe Vector8us operator & (Vector8us va, Vector8us vb)
179                 {
180                         Vector8us res = new Vector8us ();
181                         uint *a = (uint*) &va.v0;
182                         uint *b = (uint*) &vb.v0;
183                         uint *c = (uint*) &res.v0;
184                         *c++ = *a++ & *b++;
185                         *c++ = *a++ & *b++;
186                         *c++ = *a++ & *b++;
187                         *c = *a & *b;
188                         return res;
189                 }
190
191                 [Acceleration (AccelMode.SSE2)]
192                 public static unsafe Vector8us operator | (Vector8us va, Vector8us vb)
193                 {
194                         Vector8us res = new Vector8us ();
195                         uint *a = (uint*) &va.v0;
196                         uint *b = (uint*) &vb.v0;
197                         uint *c = (uint*) &res.v0;
198                         *c++ = *a++ | *b++;
199                         *c++ = *a++ | *b++;
200                         *c++ = *a++ | *b++;
201                         *c = *a | *b;
202                         return res;
203                 }
204
205                 [Acceleration (AccelMode.SSE2)]
206                 public static unsafe Vector8us operator ^ (Vector8us va, Vector8us vb)
207                 {
208                         Vector8us res = new Vector8us ();
209                         uint *a = (uint*) &va.v0;
210                         uint *b = (uint*) &vb.v0;
211                         uint *c = (uint*) &res.v0;
212                         *c++ = *a++ ^ *b++;
213                         *c++ = *a++ ^ *b++;
214                         *c++ = *a++ ^ *b++;
215                         *c = *a ^ *b;
216                         return res;
217                 }
218
219                 [Acceleration (AccelMode.SSE2)]
220                 public unsafe static bool operator ==(Vector8us va, Vector8us vb)
221                 {
222                         ushort *a = &va.v0;
223                         ushort *b = &vb.v0;
224                         for (int i = 0; i < 8; ++i)
225                                 if (*a++ != *b++)
226                                         return false;
227                         return true;
228                 }
229
230                 [Acceleration (AccelMode.SSE2)]
231                 public unsafe static bool operator !=(Vector8us va, Vector8us vb)
232                 {
233                         ushort *a = &va.v0;
234                         ushort *b = &vb.v0;
235                         for (int i = 0; i < 8; ++i)
236                                 if (*a++ != *b++)
237                                         return true;
238                         return false;
239                 }
240
241                 [Acceleration (AccelMode.SSE1)]
242                 public static unsafe explicit operator Vector2d (Vector8us v)
243                 {
244                         Vector2d* p = (Vector2d*)&v;
245                         return *p;
246                 }
247
248                 [Acceleration (AccelMode.SSE1)]
249                 public static unsafe explicit operator Vector4f (Vector8us v)
250                 {
251                         Vector4f* p = (Vector4f*)&v;
252                         return *p;
253                 }
254
255                 [Acceleration (AccelMode.SSE1)]
256                 public static unsafe explicit operator Vector2l (Vector8us v)
257                 {
258                         Vector2l* p = (Vector2l*)&v;
259                         return *p;
260                 }
261
262                 [Acceleration (AccelMode.SSE1)]
263                 public static unsafe explicit operator Vector2ul (Vector8us v)
264                 {
265                         Vector2ul* p = (Vector2ul*)&v;
266                         return *p;
267                 }
268
269                 [Acceleration (AccelMode.SSE1)]
270                 public static unsafe explicit operator Vector4i (Vector8us v)
271                 {
272                         Vector4i* p = (Vector4i*)&v;
273                         return *p;
274                 }
275
276                 [Acceleration (AccelMode.SSE1)]
277                 public static unsafe explicit operator Vector4ui (Vector8us v)
278                 {
279                         Vector4ui* p = (Vector4ui*)&v;
280                         return *p;
281                 }
282
283                 [Acceleration (AccelMode.SSE1)]
284                 public static unsafe explicit operator Vector8s (Vector8us v)
285                 {
286                         Vector8s* p = (Vector8s*)&v;
287                         return *p;
288                 }
289
290                 [Acceleration (AccelMode.SSE1)]
291                 public static unsafe explicit operator Vector16sb (Vector8us v)
292                 {
293                         Vector16sb* p = (Vector16sb*)&v;
294                         return *p;
295                 }
296
297                 [Acceleration (AccelMode.SSE1)]
298                 public static unsafe explicit operator Vector16b (Vector8us v)
299                 {
300                         Vector16b* p = (Vector16b*)&v;
301                         return *p;
302                 }
303
304
305                 [Acceleration (AccelMode.SSE1)]
306                 public static Vector8us LoadAligned (ref Vector8us v)
307                 {
308                         return v;
309                 }
310
311                 [Acceleration (AccelMode.SSE1)]
312                 public static void StoreAligned (ref Vector8us res, Vector8us val)
313                 {
314                         res = val;
315                 }
316
317                 [Acceleration (AccelMode.SSE1)]
318                 public static unsafe Vector8us LoadAligned (Vector8us *v)
319                 {
320                         return *v;
321                 }
322
323                 [Acceleration (AccelMode.SSE1)]
324                 public static unsafe void StoreAligned (Vector8us *res, Vector8us val)
325                 {
326                         *res = val;
327                 }
328
329                 [Acceleration (AccelMode.SSE1)]
330                 [CLSCompliant(false)]
331                 public static void PrefetchTemporalAllCacheLevels (ref Vector8us res)
332                 {
333                 }
334
335                 [Acceleration (AccelMode.SSE1)]
336                 [CLSCompliant(false)]
337                 public static void PrefetchTemporal1stLevelCache (ref Vector8us res)
338                 {
339                 }
340
341                 [Acceleration (AccelMode.SSE1)]
342                 [CLSCompliant(false)]
343                 public static void PrefetchTemporal2ndLevelCache (ref Vector8us res)
344                 {
345                 }
346
347                 [Acceleration (AccelMode.SSE1)]
348                 [CLSCompliant(false)]
349                 public static void PrefetchNonTemporal (ref Vector8us res)
350                 {
351                 }
352
353                 [Acceleration (AccelMode.SSE1)]
354                 [CLSCompliant(false)]
355                 public static unsafe void PrefetchTemporalAllCacheLevels (Vector8us *res)
356                 {
357                 }
358
359                 [Acceleration (AccelMode.SSE1)]
360                 [CLSCompliant(false)]
361                 public static unsafe void PrefetchTemporal1stLevelCache (Vector8us *res)
362                 {
363                 }
364
365                 [Acceleration (AccelMode.SSE1)]
366                 [CLSCompliant(false)]
367                 public static unsafe void PrefetchTemporal2ndLevelCache (Vector8us *res)
368                 {
369                 }
370
371                 [Acceleration (AccelMode.SSE1)]
372                 [CLSCompliant(false)]
373                 public static unsafe void PrefetchNonTemporal (Vector8us *res)
374                 {
375                 }
376                 
377                 public override string ToString()
378                 {
379                         return "<" + v0 + ", " + v1 + ", " + v2 + ", " + v3 + ", " +
380                                         v4 + ", " + v5 + ", " + v6 + ", " + v7 + ">"; 
381                 }
382         }
383 }