Mercurial > projects > ldc
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 } |