comparison druntime/src/compiler/dmd/arrayreal.d @ 1458:e0b2d67cfe7c

Added druntime (this should be removed once it works).
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 02 Jun 2009 17:43:06 +0100
parents
children
comparison
equal deleted inserted replaced
1456:7b218ec1044f 1458:e0b2d67cfe7c
1 /**
2 * Contains SSE2 and MMX versions of certain operations for real.
3 *
4 * Copyright: Copyright Digital Mars 2008 - 2009.
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>.
6 * Authors: Walter Bright, based on code originally written by Burton Radons
7 *
8 * Copyright Digital Mars 2008 - 2009.
9 * Distributed under the Boost Software License, Version 1.0.
10 * (See accompanying file LICENSE_1_0.txt or copy at
11 * http://www.boost.org/LICENSE_1_0.txt)
12 */
13 module rt.arrayreal;
14
15 import rt.util.cpuid;
16
17 version (unittest)
18 {
19 private import core.stdc.stdio : printf;
20 /* This is so unit tests will test every CPU variant
21 */
22 int cpuid;
23 const int CPUID_MAX = 1;
24 bool mmx() { return cpuid == 1 && rt.util.cpuid.mmx(); }
25 bool sse() { return cpuid == 2 && rt.util.cpuid.sse(); }
26 bool sse2() { return cpuid == 3 && rt.util.cpuid.sse2(); }
27 bool amd3dnow() { return cpuid == 4 && rt.util.cpuid.amd3dnow(); }
28 }
29 else
30 {
31 alias rt.util.cpuid.mmx mmx;
32 alias rt.util.cpuid.sse sse;
33 alias rt.util.cpuid.sse2 sse2;
34 alias rt.util.cpuid.amd3dnow amd3dnow;
35 }
36
37 //version = log;
38
39 bool disjoint(T)(T[] a, T[] b)
40 {
41 return (a.ptr + a.length <= b.ptr || b.ptr + b.length <= a.ptr);
42 }
43
44 alias real T;
45
46 extern (C):
47
48 /* ======================================================================== */
49
50 /***********************
51 * Computes:
52 * a[] = b[] + c[]
53 */
54
55 T[] _arraySliceSliceAddSliceAssign_r(T[] a, T[] c, T[] b)
56 in
57 {
58 assert(a.length == b.length && b.length == c.length);
59 assert(disjoint(a, b));
60 assert(disjoint(a, c));
61 assert(disjoint(b, c));
62 }
63 body
64 {
65 for (int i = 0; i < a.length; i++)
66 a[i] = b[i] + c[i];
67 return a;
68 }
69
70 unittest
71 {
72 printf("_arraySliceSliceAddSliceAssign_r unittest\n");
73 for (cpuid = 0; cpuid < CPUID_MAX; cpuid++)
74 {
75 version (log) printf(" cpuid %d\n", cpuid);
76
77 for (int j = 0; j < 2; j++)
78 {
79 const int dim = 67;
80 T[] a = new T[dim + j]; // aligned on 16 byte boundary
81 a = a[j .. dim + j]; // misalign for second iteration
82 T[] b = new T[dim + j];
83 b = b[j .. dim + j];
84 T[] c = new T[dim + j];
85 c = c[j .. dim + j];
86
87 for (int i = 0; i < dim; i++)
88 { a[i] = cast(T)i;
89 b[i] = cast(T)(i + 7);
90 c[i] = cast(T)(i * 2);
91 }
92
93 c[] = a[] + b[];
94
95 for (int i = 0; i < dim; i++)
96 {
97 if (c[i] != cast(T)(a[i] + b[i]))
98 {
99 printf("[%d]: %Lg != %Lg + %Lg\n", i, c[i], a[i], b[i]);
100 assert(0);
101 }
102 }
103 }
104 }
105 }
106
107 /* ======================================================================== */
108
109 /***********************
110 * Computes:
111 * a[] = b[] - c[]
112 */
113
114 T[] _arraySliceSliceMinSliceAssign_r(T[] a, T[] c, T[] b)
115 in
116 {
117 assert(a.length == b.length && b.length == c.length);
118 assert(disjoint(a, b));
119 assert(disjoint(a, c));
120 assert(disjoint(b, c));
121 }
122 body
123 {
124 for (int i = 0; i < a.length; i++)
125 a[i] = b[i] - c[i];
126 return a;
127 }
128
129
130 unittest
131 {
132 printf("_arraySliceSliceMinSliceAssign_r unittest\n");
133 for (cpuid = 0; cpuid < CPUID_MAX; cpuid++)
134 {
135 version (log) printf(" cpuid %d\n", cpuid);
136
137 for (int j = 0; j < 2; j++)
138 {
139 const int dim = 67;
140 T[] a = new T[dim + j]; // aligned on 16 byte boundary
141 a = a[j .. dim + j]; // misalign for second iteration
142 T[] b = new T[dim + j];
143 b = b[j .. dim + j];
144 T[] c = new T[dim + j];
145 c = c[j .. dim + j];
146
147 for (int i = 0; i < dim; i++)
148 { a[i] = cast(T)i;
149 b[i] = cast(T)(i + 7);
150 c[i] = cast(T)(i * 2);
151 }
152
153 c[] = a[] - b[];
154
155 for (int i = 0; i < dim; i++)
156 {
157 if (c[i] != cast(T)(a[i] - b[i]))
158 {
159 printf("[%d]: %Lg != %Lg - %Lg\n", i, c[i], a[i], b[i]);
160 assert(0);
161 }
162 }
163 }
164 }
165 }
166
167 /* ======================================================================== */
168
169 /***********************
170 * Computes:
171 * a[] -= b[] * value
172 */
173
174 T[] _arraySliceExpMulSliceMinass_r(T[] a, T value, T[] b)
175 {
176 return _arraySliceExpMulSliceAddass_r(a, -value, b);
177 }
178
179 /***********************
180 * Computes:
181 * a[] += b[] * value
182 */
183
184 T[] _arraySliceExpMulSliceAddass_r(T[] a, T value, T[] b)
185 in
186 {
187 assert(a.length == b.length);
188 assert(disjoint(a, b));
189 }
190 body
191 {
192 auto aptr = a.ptr;
193 auto aend = aptr + a.length;
194 auto bptr = b.ptr;
195
196 // Handle remainder
197 while (aptr < aend)
198 *aptr++ += *bptr++ * value;
199
200 return a;
201 }
202
203 unittest
204 {
205 printf("_arraySliceExpMulSliceAddass_r unittest\n");
206
207 cpuid = 1;
208 {
209 version (log) printf(" cpuid %d\n", cpuid);
210
211 for (int j = 0; j < 1; j++)
212 {
213 const int dim = 67;
214 T[] a = new T[dim + j]; // aligned on 16 byte boundary
215 a = a[j .. dim + j]; // misalign for second iteration
216 T[] b = new T[dim + j];
217 b = b[j .. dim + j];
218 T[] c = new T[dim + j];
219 c = c[j .. dim + j];
220
221 for (int i = 0; i < dim; i++)
222 { a[i] = cast(T)i;
223 b[i] = cast(T)(i + 7);
224 c[i] = cast(T)(i * 2);
225 }
226
227 b[] = c[];
228 c[] += a[] * 6;
229
230 for (int i = 0; i < dim; i++)
231 {
232 //printf("[%d]: %Lg ?= %Lg + %Lg * 6\n", i, c[i], b[i], a[i]);
233 if (c[i] != cast(T)(b[i] + a[i] * 6))
234 {
235 printf("[%d]: %Lg ?= %Lg + %Lg * 6\n", i, c[i], b[i], a[i]);
236 assert(0);
237 }
238 }
239 }
240 }
241 }