]> git.llucax.com Git - software/druntime.git/blob - src/compiler/dmd/arrayreal.d
Add .gitignore files
[software/druntime.git] / src / compiler / dmd / arrayreal.d
1 /***************************
2  * D programming language http://www.digitalmars.com/d/
3  * Runtime support for double array operations.
4  * Placed in public domain.
5  */
6
7 module rt.arrayreal;
8
9 import util.cpuid;
10
11 version (unittest)
12 {
13     private import core.stdc.stdio : printf;
14     /* This is so unit tests will test every CPU variant
15      */
16     int cpuid;
17     const int CPUID_MAX = 1;
18     bool mmx()      { return cpuid == 1 && util.cpuid.mmx(); }
19     bool sse()      { return cpuid == 2 && util.cpuid.sse(); }
20     bool sse2()     { return cpuid == 3 && util.cpuid.sse2(); }
21     bool amd3dnow() { return cpuid == 4 && util.cpuid.amd3dnow(); }
22 }
23 else
24 {
25     alias util.cpuid.mmx mmx;
26     alias util.cpuid.sse sse;
27     alias util.cpuid.sse2 sse2;
28     alias util.cpuid.amd3dnow amd3dnow;
29 }
30
31 //version = log;
32
33 bool disjoint(T)(T[] a, T[] b)
34 {
35     return (a.ptr + a.length <= b.ptr || b.ptr + b.length <= a.ptr);
36 }
37
38 alias real T;
39
40 extern (C):
41
42 /* ======================================================================== */
43
44 /***********************
45  * Computes:
46  *      a[] = b[] + c[]
47  */
48
49 T[] _arraySliceSliceAddSliceAssign_r(T[] a, T[] c, T[] b)
50 in
51 {
52         assert(a.length == b.length && b.length == c.length);
53         assert(disjoint(a, b));
54         assert(disjoint(a, c));
55         assert(disjoint(b, c));
56 }
57 body
58 {
59     for (int i = 0; i < a.length; i++)
60         a[i] = b[i] + c[i];
61     return a;
62 }
63
64 unittest
65 {
66     printf("_arraySliceSliceAddSliceAssign_r unittest\n");
67     for (cpuid = 0; cpuid < CPUID_MAX; cpuid++)
68     {
69         version (log) printf("    cpuid %d\n", cpuid);
70
71         for (int j = 0; j < 2; j++)
72         {
73             const int dim = 67;
74             T[] a = new T[dim + j];     // aligned on 16 byte boundary
75             a = a[j .. dim + j];        // misalign for second iteration
76             T[] b = new T[dim + j];
77             b = b[j .. dim + j];
78             T[] c = new T[dim + j];
79             c = c[j .. dim + j];
80
81             for (int i = 0; i < dim; i++)
82             {   a[i] = cast(T)i;
83                 b[i] = cast(T)(i + 7);
84                 c[i] = cast(T)(i * 2);
85             }
86
87             c[] = a[] + b[];
88
89             for (int i = 0; i < dim; i++)
90             {
91                 if (c[i] != cast(T)(a[i] + b[i]))
92                 {
93                     printf("[%d]: %Lg != %Lg + %Lg\n", i, c[i], a[i], b[i]);
94                     assert(0);
95                 }
96             }
97         }
98     }
99 }
100
101 /* ======================================================================== */
102
103 /***********************
104  * Computes:
105  *      a[] = b[] - c[]
106  */
107
108 T[] _arraySliceSliceMinSliceAssign_r(T[] a, T[] c, T[] b)
109 in
110 {
111         assert(a.length == b.length && b.length == c.length);
112         assert(disjoint(a, b));
113         assert(disjoint(a, c));
114         assert(disjoint(b, c));
115 }
116 body
117 {
118     for (int i = 0; i < a.length; i++)
119         a[i] = b[i] - c[i];
120     return a;
121 }
122
123
124 unittest
125 {
126     printf("_arraySliceSliceMinSliceAssign_r unittest\n");
127     for (cpuid = 0; cpuid < CPUID_MAX; cpuid++)
128     {
129         version (log) printf("    cpuid %d\n", cpuid);
130
131         for (int j = 0; j < 2; j++)
132         {
133             const int dim = 67;
134             T[] a = new T[dim + j];     // aligned on 16 byte boundary
135             a = a[j .. dim + j];        // misalign for second iteration
136             T[] b = new T[dim + j];
137             b = b[j .. dim + j];
138             T[] c = new T[dim + j];
139             c = c[j .. dim + j];
140
141             for (int i = 0; i < dim; i++)
142             {   a[i] = cast(T)i;
143                 b[i] = cast(T)(i + 7);
144                 c[i] = cast(T)(i * 2);
145             }
146
147             c[] = a[] - b[];
148
149             for (int i = 0; i < dim; i++)
150             {
151                 if (c[i] != cast(T)(a[i] - b[i]))
152                 {
153                     printf("[%d]: %Lg != %Lg - %Lg\n", i, c[i], a[i], b[i]);
154                     assert(0);
155                 }
156             }
157         }
158     }
159 }
160
161 /* ======================================================================== */
162
163 /***********************
164  * Computes:
165  *      a[] -= b[] * value
166  */
167
168 T[] _arraySliceExpMulSliceMinass_r(T[] a, T value, T[] b)
169 {
170     return _arraySliceExpMulSliceAddass_r(a, -value, b);
171 }
172
173 /***********************
174  * Computes:
175  *      a[] += b[] * value
176  */
177
178 T[] _arraySliceExpMulSliceAddass_r(T[] a, T value, T[] b)
179 in
180 {
181         assert(a.length == b.length);
182         assert(disjoint(a, b));
183 }
184 body
185 {
186     auto aptr = a.ptr;
187     auto aend = aptr + a.length;
188     auto bptr = b.ptr;
189
190     // Handle remainder
191     while (aptr < aend)
192         *aptr++ += *bptr++ * value;
193
194     return a;
195 }
196
197 unittest
198 {
199     printf("_arraySliceExpMulSliceAddass_r unittest\n");
200
201     cpuid = 1;
202     {
203         version (log) printf("    cpuid %d\n", cpuid);
204
205         for (int j = 0; j < 1; j++)
206         {
207             const int dim = 67;
208             T[] a = new T[dim + j];     // aligned on 16 byte boundary
209             a = a[j .. dim + j];        // misalign for second iteration
210             T[] b = new T[dim + j];
211             b = b[j .. dim + j];
212             T[] c = new T[dim + j];
213             c = c[j .. dim + j];
214
215             for (int i = 0; i < dim; i++)
216             {   a[i] = cast(T)i;
217                 b[i] = cast(T)(i + 7);
218                 c[i] = cast(T)(i * 2);
219             }
220
221             b[] = c[];
222             c[] += a[] * 6;
223
224             for (int i = 0; i < dim; i++)
225             {
226                 //printf("[%d]: %Lg ?= %Lg + %Lg * 6\n", i, c[i], b[i], a[i]);
227                 if (c[i] != cast(T)(b[i] + a[i] * 6))
228                 {
229                     printf("[%d]: %Lg ?= %Lg + %Lg * 6\n", i, c[i], b[i], a[i]);
230                     assert(0);
231                 }
232             }
233         }
234     }
235 }