Commit | Line | Data |
---|---|---|
4a71579b PC |
1 | #define szof_c 1 |
2 | #define szof_uc szof_c | |
3 | #define szof_s 2 | |
4 | #define szof_us szof_s | |
5 | #define szof_i 4 | |
6 | #if __WORDSIZE == 64 | |
7 | # define szof_ui szof_i | |
8 | # define szof_l 8 | |
9 | #endif | |
10 | #define szof_f 4 | |
11 | #define szof_d 8 | |
12 | ||
13 | #define FILL(T) \ | |
14 | name fill##T \ | |
15 | fill##T: \ | |
16 | prolog \ | |
17 | arg $argp \ | |
18 | getarg %v0 $argp \ | |
19 | arg $argi \ | |
20 | getarg %r0 $argi \ | |
21 | muli %r0 %r0 szof##T \ | |
22 | addr %v1 %v0 %r0 \ | |
23 | movi %r0 0 \ | |
24 | fill##T##loop: \ | |
25 | bger fill##T##done %v0 %v1 \ | |
26 | str##T %v0 %r0 \ | |
27 | addi %r0 %r0 1 \ | |
28 | addi %v0 %v0 szof##T \ | |
29 | jmpi fill##T##loop \ | |
30 | fill##T##done: \ | |
31 | ret \ | |
32 | epilog | |
33 | #define FILLF(T) \ | |
34 | name fill##T \ | |
35 | fill##T: \ | |
36 | prolog \ | |
37 | arg $argp \ | |
38 | getarg %v0 $argp \ | |
39 | arg $argi \ | |
40 | getarg %r0 $argi \ | |
41 | muli %r0 %r0 szof##T \ | |
42 | addr %v1 %v0 %r0 \ | |
43 | movi##T %f0 0.0 \ | |
44 | fill##T##loop: \ | |
45 | bger fill##T##done %v0 %v1 \ | |
46 | str##T %v0 %f0 \ | |
47 | addi##T %f0 %f0 1.0 \ | |
48 | addi %v0 %v0 szof##T \ | |
49 | jmpi fill##T##loop \ | |
50 | fill##T##done: \ | |
51 | ret \ | |
52 | epilog | |
53 | ||
54 | #define fill_uc fill_c | |
55 | #define fill_us fill_s | |
56 | #define fill_ui fill_i | |
57 | ||
79bfeef6 | 58 | #define ARG( T, N) arg##T $arg##T##N |
4a71579b PC |
59 | #define ARGF( T, N) arg##T $arg##T##N |
60 | #define ARG1( K, T) ARG##K(T, 0) | |
61 | #define ARG2( K, T) ARG1( K, T) ARG##K(T, 1) | |
62 | #define ARG3( K, T) ARG2( K, T) ARG##K(T, 2) | |
63 | #define ARG4( K, T) ARG3( K, T) ARG##K(T, 3) | |
64 | #define ARG5( K, T) ARG4( K, T) ARG##K(T, 4) | |
65 | #define ARG6( K, T) ARG5( K, T) ARG##K(T, 5) | |
66 | #define ARG7( K, T) ARG6( K, T) ARG##K(T, 6) | |
67 | #define ARG8( K, T) ARG7( K, T) ARG##K(T, 7) | |
68 | #define ARG9( K, T) ARG8( K, T) ARG##K(T, 8) | |
69 | #define ARG10(K, T) ARG9( K, T) ARG##K(T, 9) | |
70 | #define ARG11(K, T) ARG10(K, T) ARG##K(T, 10) | |
71 | #define ARG12(K, T) ARG11(K, T) ARG##K(T, 11) | |
72 | #define ARG13(K, T) ARG12(K, T) ARG##K(T, 12) | |
73 | #define ARG14(K, T) ARG13(K, T) ARG##K(T, 13) | |
74 | #define ARG15(K, T) ARG14(K, T) ARG##K(T, 14) | |
75 | #define ARG16(K, T) ARG15(K, T) ARG##K(T, 15) | |
76 | #define ARG_c(N) ARG##N( , _c) | |
79bfeef6 | 77 | #define ARG_uc(N) ARG##N( , _c) |
4a71579b | 78 | #define ARG_s(N) ARG##N( , _s) |
79bfeef6 | 79 | #define ARG_us(N) ARG##N( , _s) |
4a71579b | 80 | #define ARG_i(N) ARG##N( , _i) |
79bfeef6 | 81 | #define ARG_ui(N) ARG##N( , _i) |
4a71579b PC |
82 | #define ARG_l(N) ARG##N( , _l) |
83 | #define ARG_f(N) ARG##N(F, _f) | |
84 | #define ARG_d(N) ARG##N(F, _d) | |
85 | ||
79bfeef6 PC |
86 | #define CHK(N, T, TT, V) \ |
87 | getarg##T %r0 $arg##TT##V \ | |
4a71579b PC |
88 | ldxi##T %r1 %v0 $(V * szof##T) \ |
89 | beqr N##T##V %r0 %r1 \ | |
90 | calli @abort \ | |
91 | N##T##V: | |
79bfeef6 PC |
92 | #define CHKF(N, T, TT, V) \ |
93 | getarg##T %f0 $arg##TT##V \ | |
4a71579b PC |
94 | ldxi##T %f1 %v0 $(V * szof##T) \ |
95 | beqr##T N##T##V %f0 %f1 \ | |
96 | calli @abort \ | |
97 | N##T##V: | |
98 | ||
79bfeef6 PC |
99 | #define GET1( K, N, T, TT, V) CHK##K(N, T, TT, 0) |
100 | #define GET2( K, N, T, TT, V) GET1( K, N, T, TT, V) CHK##K(N, T, TT, 1) | |
101 | #define GET3( K, N, T, TT, V) GET2( K, N, T, TT, V) CHK##K(N, T, TT, 2) | |
102 | #define GET4( K, N, T, TT, V) GET3( K, N, T, TT, V) CHK##K(N, T, TT, 3) | |
103 | #define GET5( K, N, T, TT, V) GET4( K, N, T, TT, V) CHK##K(N, T, TT, 4) | |
104 | #define GET6( K, N, T, TT, V) GET5( K, N, T, TT, V) CHK##K(N, T, TT, 5) | |
105 | #define GET7( K, N, T, TT, V) GET6( K, N, T, TT, V) CHK##K(N, T, TT, 6) | |
106 | #define GET8( K, N, T, TT, V) GET7( K, N, T, TT, V) CHK##K(N, T, TT, 7) | |
107 | #define GET9( K, N, T, TT, V) GET8( K, N, T, TT, V) CHK##K(N, T, TT, 8) | |
108 | #define GET10(K, N, T, TT, V) GET9( K, N, T, TT, V) CHK##K(N, T, TT, 9) | |
109 | #define GET11(K, N, T, TT, V) GET10(K, N, T, TT, V) CHK##K(N, T, TT, 10) | |
110 | #define GET12(K, N, T, TT, V) GET11(K, N, T, TT, V) CHK##K(N, T, TT, 11) | |
111 | #define GET13(K, N, T, TT, V) GET12(K, N, T, TT, V) CHK##K(N, T, TT, 12) | |
112 | #define GET14(K, N, T, TT, V) GET13(K, N, T, TT, V) CHK##K(N, T, TT, 13) | |
113 | #define GET15(K, N, T, TT, V) GET14(K, N, T, TT, V) CHK##K(N, T, TT, 14) | |
114 | #define GET16(K, N, T, TT, V) GET15(K, N, T, TT, V) CHK##K(N, T, TT, 15) | |
4a71579b | 115 | |
79bfeef6 PC |
116 | #define GET_c(N, M) GET##N( , c##N, _c, _c, M) |
117 | #define GET_uc(N, M) GET##N( , uc##N, _uc, _c, M) | |
118 | #define GET_s(N, M) GET##N( , s##N, _s, _s, M) | |
119 | #define GET_us(N, M) GET##N( , us##N, _us, _s, M) | |
120 | #define GET_i(N, M) GET##N( , i##N, _i, _i, M) | |
121 | #define GET_ui(N, M) GET##N( , ui##N, _ui, _i, M) | |
122 | #define GET_l(N, M) GET##N( , l##N, _l, _l, M) | |
123 | #define GET_f(N, M) GET##N(F, f##N, _f, _f, M) | |
124 | #define GET_d(N, M) GET##N(F, d##N, _d, _d, M) | |
4a71579b | 125 | |
79bfeef6 | 126 | #define PUSH( T, V) pushargi##T V |
4a71579b PC |
127 | #define PUSHF( T, V) pushargi##T V |
128 | #define PUSH0( K, T) /**/ | |
129 | #define PUSH1( K, T) PUSH##K(T, 0) | |
130 | #define PUSH2( K, T) PUSH1( K, T) PUSH##K(T, 1) | |
131 | #define PUSH3( K, T) PUSH2( K, T) PUSH##K(T, 2) | |
132 | #define PUSH4( K, T) PUSH3( K, T) PUSH##K(T, 3) | |
133 | #define PUSH5( K, T) PUSH4( K, T) PUSH##K(T, 4) | |
134 | #define PUSH6( K, T) PUSH5( K, T) PUSH##K(T, 5) | |
135 | #define PUSH7( K, T) PUSH6( K, T) PUSH##K(T, 6) | |
136 | #define PUSH8( K, T) PUSH7( K, T) PUSH##K(T, 7) | |
137 | #define PUSH9( K, T) PUSH8( K, T) PUSH##K(T, 8) | |
138 | #define PUSH10(K, T) PUSH9( K, T) PUSH##K(T, 9) | |
139 | #define PUSH11(K, T) PUSH10(K, T) PUSH##K(T, 10) | |
140 | #define PUSH12(K, T) PUSH11(K, T) PUSH##K(T, 11) | |
141 | #define PUSH13(K, T) PUSH12(K, T) PUSH##K(T, 12) | |
142 | #define PUSH14(K, T) PUSH13(K, T) PUSH##K(T, 13) | |
143 | #define PUSH15(K, T) PUSH14(K, T) PUSH##K(T, 14) | |
144 | #define PUSH16(K, T) PUSH15(K, T) PUSH##K(T, 15) | |
145 | ||
146 | #define PUSH_c( N) PUSH##N( , _c) | |
147 | #define PUSH_uc(N) PUSH##N( , _uc) | |
148 | #define PUSH_s( N) PUSH##N( , _s) | |
149 | #define PUSH_us(N) PUSH##N( , _us) | |
150 | #define PUSH_i( N) PUSH##N( , _i) | |
151 | #define PUSH_ui(N) PUSH##N( , _ui) | |
152 | #define PUSH_l( N) PUSH##N( , _l) | |
153 | #define PUSH_f( N) PUSH##N(F, _f) | |
154 | #define PUSH_d( N) PUSH##N(F, _d) | |
155 | ||
156 | /* bottom function */ | |
157 | #define DEF0(T) \ | |
158 | name test##T##_0 \ | |
159 | test##T##_0: \ | |
160 | prolog \ | |
161 | ret \ | |
162 | epilog | |
163 | ||
79bfeef6 | 164 | #define DEFN(N, M, T, TT) \ |
4a71579b PC |
165 | name test##T##_##N \ |
166 | test##T##_##N: \ | |
167 | prolog \ | |
168 | arg $argp \ | |
169 | /* stack buffer in %v0 */ \ | |
170 | getarg %v0 $argp \ | |
79bfeef6 | 171 | ARG##TT(N) \ |
4a71579b PC |
172 | /* validate arguments */ \ |
173 | GET##T(N, M) \ | |
174 | /* heap buffer in %v1 */ \ | |
175 | prepare \ | |
176 | pushargi $(N * szof##T) \ | |
177 | finishi @malloc \ | |
178 | retval %v1 \ | |
179 | /* copy stack bufer to heap buffer */ \ | |
180 | prepare \ | |
181 | pushargr %v1 \ | |
182 | pushargr %v0 \ | |
183 | pushargi $(N * szof##T) \ | |
184 | finishi MEMCPY \ | |
185 | /* stack buffer for next function in %v2 */ \ | |
186 | movi %r0 $(M * szof##T) \ | |
187 | allocar %v2 %r0 \ | |
188 | addr %v2 %v2 %fp \ | |
189 | /* fill stack buffer for next function */ \ | |
190 | prepare \ | |
191 | pushargr %v2 \ | |
192 | pushargi M \ | |
193 | finishi fill##T \ | |
194 | /* call next function */ \ | |
195 | prepare \ | |
196 | pushargr %v2 \ | |
197 | PUSH##T(M) \ | |
198 | finishi test##T##_##M \ | |
199 | /* validate stack buffer */ \ | |
200 | prepare \ | |
201 | pushargr %v1 \ | |
202 | pushargr %v0 \ | |
203 | pushargi $(N * szof##T) \ | |
204 | finishi @memcmp \ | |
205 | retval %r0 \ | |
206 | beqi test##T##_##N##_done %r0 0 \ | |
207 | calli @abort \ | |
208 | test##T##_##N##_done: \ | |
209 | /* release heap bufer */ \ | |
210 | prepare \ | |
211 | pushargr %v1 \ | |
212 | finishi @free \ | |
213 | ret \ | |
214 | epilog | |
215 | ||
216 | /* top function */ | |
217 | #define DEFX(T) \ | |
218 | name test##T##_17 \ | |
219 | test##T##_17: \ | |
220 | prolog \ | |
221 | /* heap buffer in %v1 */ \ | |
222 | prepare \ | |
223 | pushargi $(16 * szof##T) \ | |
224 | finishi @malloc \ | |
225 | retval %v1 \ | |
226 | /* stack buffer for next function in %v2 */ \ | |
227 | movi %r0 $(16 * szof##T) \ | |
228 | allocar %v2 %r0 \ | |
229 | addr %v2 %v2 %fp \ | |
230 | /* fill stack buffer for next function */ \ | |
231 | prepare \ | |
232 | pushargr %v2 \ | |
233 | pushargi 16 \ | |
234 | finishi fill##T \ | |
235 | /* copy stack buffer to heap buffer */ \ | |
236 | prepare \ | |
237 | pushargr %v1 \ | |
238 | pushargr %v2 \ | |
239 | pushargi $(16 * szof##T) \ | |
240 | finishi MEMCPY \ | |
241 | /* call next function */ \ | |
242 | prepare \ | |
243 | pushargr %v2 \ | |
244 | PUSH##T(16) \ | |
245 | finishi test##T##_16 \ | |
246 | /* validate stack buffer */ \ | |
247 | prepare \ | |
248 | pushargr %v1 \ | |
249 | pushargr %v2 \ | |
250 | pushargi $(16 * szof##T) \ | |
251 | finishi @memcmp \ | |
252 | retval %r0 \ | |
253 | beqi test##T##_17_done %r0 0 \ | |
254 | calli @abort \ | |
255 | test##T##_17_done: \ | |
256 | /* release heap bufer */ \ | |
257 | prepare \ | |
258 | pushargr %v1 \ | |
259 | finishi @free \ | |
260 | ret \ | |
261 | epilog | |
262 | ||
79bfeef6 | 263 | #define DEF( T, TT) \ |
4a71579b | 264 | DEF0( T) \ |
79bfeef6 PC |
265 | DEFN( 1, 0, T, TT) \ |
266 | DEFN( 2, 1, T, TT) \ | |
267 | DEFN( 3, 2, T, TT) \ | |
268 | DEFN( 4, 3, T, TT) \ | |
269 | DEFN( 5, 4, T, TT) \ | |
270 | DEFN( 6, 5, T, TT) \ | |
271 | DEFN( 7, 6, T, TT) \ | |
272 | DEFN( 8, 7, T, TT) \ | |
273 | DEFN( 9, 8, T, TT) \ | |
274 | DEFN(10, 9, T, TT) \ | |
275 | DEFN(11, 10, T, TT) \ | |
276 | DEFN(12, 11, T, TT) \ | |
277 | DEFN(13, 12, T, TT) \ | |
278 | DEFN(14, 13, T, TT) \ | |
279 | DEFN(15, 14, T, TT) \ | |
280 | DEFN(16, 15, T, TT) \ | |
4a71579b PC |
281 | DEFX(T) |
282 | ||
283 | #define CALL(T) calli test##T##_17 | |
284 | ||
285 | .data 16 | |
286 | fmt: | |
287 | .c "%d %d %d\n" | |
288 | .code | |
289 | jmpi main | |
290 | ||
291 | #if _AIX | |
292 | # define MEMCPY memcpy | |
293 | /* error: Function not implemented (memcpy) */ | |
294 | name memcpy | |
295 | memcpy: | |
296 | prolog | |
297 | arg $dst | |
298 | arg $src | |
299 | arg $len | |
300 | getarg %r0 $dst | |
301 | getarg %r1 $src | |
302 | getarg %r2 $len | |
303 | movr %v1 %r0 | |
304 | blti memcpy_done %r2 1 | |
305 | memcpy_loop: | |
306 | subi %r2 %r2 1 | |
307 | ldxr_c %v0 %r1 %r2 | |
308 | stxr_c %r2 %r0 %v0 | |
309 | bgti memcpy_loop %r2 0 | |
310 | memcpy_done: | |
311 | retr %v1 | |
312 | epilog | |
313 | #else | |
314 | # define MEMCPY @memcpy | |
315 | #endif | |
316 | ||
317 | FILL(_c) | |
318 | FILL(_s) | |
319 | FILL(_i) | |
320 | #if __WORDSIZE == 64 | |
321 | FILL(_l) | |
322 | #endif | |
323 | FILLF(_f) | |
324 | FILLF(_d) | |
325 | ||
79bfeef6 PC |
326 | DEF(_c, _c) |
327 | DEF(_uc, _c) | |
328 | DEF(_s, _s) | |
329 | DEF(_us, _s) | |
330 | DEF(_i, _i) | |
4a71579b | 331 | #if __WORDSIZE == 64 |
79bfeef6 PC |
332 | DEF(_ui, _i) |
333 | DEF(_l, _l) | |
4a71579b | 334 | #endif |
79bfeef6 PC |
335 | DEF(_f, _f) |
336 | DEF(_d, _d) | |
4a71579b PC |
337 | |
338 | name main | |
339 | main: | |
340 | prolog | |
341 | ||
342 | CALL(_c) | |
343 | CALL(_uc) | |
344 | CALL(_s) | |
345 | CALL(_us) | |
346 | CALL(_i) | |
347 | #if __WORDSIZE == 64 | |
348 | CALL(_ui) | |
349 | CALL(_l) | |
350 | #endif | |
351 | CALL(_f) | |
352 | CALL(_d) | |
353 | ||
354 | // loop control | |
355 | movi %v2 1 | |
356 | ||
357 | // loop a few times calling allocar | |
358 | loop: | |
359 | // allocate 12 bytes | |
360 | movi %r0 12 | |
361 | allocar %v0 %r0 | |
362 | ||
363 | // offset | |
364 | movr %v1 %v0 | |
365 | ||
366 | // 1 | |
367 | stxr_i %v1 %fp %v2 | |
368 | ||
369 | // 2 | |
370 | addi %v2 %v2 1 | |
371 | addi %v1 %v1 4 | |
372 | stxr_i %v1 %fp %v2 | |
373 | ||
374 | // 3 | |
375 | addi %v2 %v2 1 | |
376 | addi %v1 %v1 4 | |
377 | stxr_i %v1 %fp %v2 | |
378 | ||
379 | // reload | |
380 | movr %v1 %v0 | |
381 | ||
382 | // 1 | |
383 | ldxr_i %r0 %fp %v1 | |
384 | ||
385 | // 2 | |
386 | addi %v1 %v1 4 | |
387 | ldxr_i %r1 %fp %v1 | |
388 | ||
389 | // 3 | |
390 | addi %v1 %v1 4 | |
391 | ldxr_i %r2 %fp %v1 | |
392 | ||
393 | prepare | |
394 | pushargi fmt | |
395 | ellipsis | |
396 | pushargr %r0 | |
397 | pushargr %r1 | |
398 | pushargr %r2 | |
399 | finishi @printf | |
400 | blti loop %v2 9 | |
401 | ||
402 | ret | |
403 | epilog |