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