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						\
15fill##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						\
24fill##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					\
30fill##T##done:							\
31	ret							\
32	epilog
33#define FILLF(T)						\
34	name fill##T						\
35fill##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						\
44fill##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					\
50fill##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
58#define ARG(  T, N)			arg    $arg##T##N
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)
77#define ARG_uc(N)			ARG##N( , _uc)
78#define ARG_s(N)			ARG##N( , _s)
79#define ARG_us(N)			ARG##N( , _us)
80#define ARG_i(N)			ARG##N( , _i)
81#define ARG_ui(N)			ARG##N( , _ui)
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
86#define CHK(N, T, V)						\
87	getarg %r0 $arg##T##V					\
88	ldxi##T %r1 %v0 $(V * szof##T)				\
89	beqr N##T##V %r0 %r1					\
90	calli @abort						\
91N##T##V:
92#define CHKF(N, T, V)						\
93	getarg##T %f0 $arg##T##V				\
94	ldxi##T %f1 %v0 $(V * szof##T)				\
95	beqr##T N##T##V %f0 %f1					\
96	calli @abort						\
97N##T##V:
98
99#define GET1( K, N, T, V)				CHK##K(N, T, 0)
100#define GET2( K, N, T, V)	GET1( K, N, T, V)	CHK##K(N, T, 1)
101#define GET3( K, N, T, V)	GET2( K, N, T, V)	CHK##K(N, T, 2)
102#define GET4( K, N, T, V)	GET3( K, N, T, V)	CHK##K(N, T, 3)
103#define GET5( K, N, T, V)	GET4( K, N, T, V)	CHK##K(N, T, 4)
104#define GET6( K, N, T, V)	GET5( K, N, T, V)	CHK##K(N, T, 5)
105#define GET7( K, N, T, V)	GET6( K, N, T, V)	CHK##K(N, T, 6)
106#define GET8( K, N, T, V)	GET7( K, N, T, V)	CHK##K(N, T, 7)
107#define GET9( K, N, T, V)	GET8( K, N, T, V)	CHK##K(N, T, 8)
108#define GET10(K, N, T, V)	GET9( K, N, T, V)	CHK##K(N, T, 9)
109#define GET11(K, N, T, V)	GET10(K, N, T, V)	CHK##K(N, T, 10)
110#define GET12(K, N, T, V)	GET11(K, N, T, V)	CHK##K(N, T, 11)
111#define GET13(K, N, T, V)	GET12(K, N, T, V)	CHK##K(N, T, 12)
112#define GET14(K, N, T, V)	GET13(K, N, T, V)	CHK##K(N, T, 13)
113#define GET15(K, N, T, V)	GET14(K, N, T, V)	CHK##K(N, T, 14)
114#define GET16(K, N, T, V)	GET15(K, N, T, V)	CHK##K(N, T, 15)
115
116#define GET_c(N, M)		GET##N( , c##N,  _c,  M)
117#define GET_uc(N, M)		GET##N( , uc##N, _uc, M)
118#define GET_s(N, M)		GET##N( , s##N,  _s,  M)
119#define GET_us(N, M)		GET##N( , us##N, _us, M)
120#define GET_i(N, M)		GET##N( , i##N,  _i,  M)
121#define GET_ui(N, M)		GET##N( , ui##N, _ui, M)
122#define GET_l(N, M)		GET##N( , l##N,  _l,  M)
123#define GET_f(N, M)		GET##N(F, f##N,  _f,  M)
124#define GET_d(N, M)		GET##N(F, d##N,  _d,  M)
125
126#define PUSH(  T, V)		pushargi    V
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					\
159test##T##_0:							\
160	prolog							\
161	ret							\
162	epilog
163
164#define DEFN(N, M, T)						\
165	name test##T##_##N					\
166test##T##_##N:							\
167	prolog							\
168	arg $argp						\
169	/* stack buffer in %v0 */				\
170	getarg %v0 $argp					\
171	ARG##T(N)						\
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	allocai $(M * szof##T) $index				\
187	addi %v2 %fp $index					\
188	/* fill stack buffer for next function */		\
189	prepare							\
190		pushargr %v2					\
191		pushargi M					\
192	finishi fill##T						\
193	/* call next function */				\
194	prepare							\
195		pushargr %v2					\
196		PUSH##T(M)					\
197	finishi test##T##_##M					\
198	/* validate stack buffer */				\
199	prepare							\
200		pushargr %v1					\
201		pushargr %v0					\
202		pushargi $(N * szof##T)				\
203	finishi @memcmp						\
204	retval %r0						\
205	beqi test##T##_##N##_done %r0 0				\
206	calli @abort						\
207test##T##_##N##_done:						\
208	/* release heap bufer */				\
209	prepare							\
210		pushargr %v1					\
211	finishi @free						\
212	ret							\
213	epilog
214
215/* top function */
216#define DEFX(T)							\
217	name test##T##_17					\
218test##T##_17:							\
219	prolog							\
220	/* heap buffer in %v1 */				\
221	prepare							\
222		pushargi $(16 * szof##T)			\
223	finishi @malloc						\
224	retval %v1						\
225	/* stack buffer for next function in %v2 */		\
226	allocai $(16 * szof##T) $index				\
227	addi %v2 %fp $index					\
228	/* fill stack buffer for next function */		\
229	prepare							\
230		pushargr %v2					\
231		pushargi 16					\
232	finishi fill##T						\
233	/* copy stack buffer to heap buffer */			\
234	prepare							\
235		pushargr %v1					\
236		pushargr %v2					\
237		pushargi $(16 * szof##T)			\
238	finishi MEMCPY						\
239	/* call next function */				\
240	prepare							\
241		pushargr %v2					\
242		PUSH##T(16)					\
243	finishi test##T##_16					\
244	/* validate stack buffer */				\
245	prepare							\
246		pushargr %v1					\
247		pushargr %v2					\
248		pushargi $(16 * szof##T)			\
249	finishi @memcmp						\
250	retval %r0						\
251	beqi test##T##_17_done %r0 0				\
252	calli @abort						\
253test##T##_17_done:						\
254	/* release heap bufer */				\
255	prepare							\
256		pushargr %v1					\
257	finishi @free						\
258	ret							\
259	epilog
260
261#define DEF(  T)						\
262	DEF0( T)						\
263	DEFN( 1,  0, T)						\
264	DEFN( 2,  1, T)						\
265	DEFN( 3,  2, T)						\
266	DEFN( 4,  3, T)						\
267	DEFN( 5,  4, T)						\
268	DEFN( 6,  5, T)						\
269	DEFN( 7,  6, T)						\
270	DEFN( 8,  7, T)						\
271	DEFN( 9,  8, T)						\
272	DEFN(10,  9, T)						\
273	DEFN(11, 10, T)						\
274	DEFN(12, 11, T)						\
275	DEFN(13, 12, T)						\
276	DEFN(14, 13, T)						\
277	DEFN(15, 14, T)						\
278	DEFN(16, 15, T)						\
279	DEFX(T)
280
281#define CALL(T)			calli test##T##_17
282
283.data	16
284ok:
285.c	"ok\n"
286.code
287	jmpi main
288
289#if _AIX
290#  define MEMCPY		memcpy
291/* error: Function not implemented (memcpy) */
292	name memcpy
293memcpy:
294	prolog
295	arg $dst
296	arg $src
297	arg $len
298	getarg %r0 $dst
299	getarg %r1 $src
300	getarg %r2 $len
301	movr %v1 %r0
302	blti memcpy_done %r2 1
303memcpy_loop:
304	subi %r2 %r2 1
305	ldxr_c %v0 %r1 %r2
306	stxr_c %r2 %r0 %v0
307	bgti memcpy_loop %r2 0
308memcpy_done:
309	retr %v1
310	epilog
311#else
312#  define MEMCPY		@memcpy
313#endif
314
315	FILL(_c)
316	FILL(_s)
317	FILL(_i)
318#if __WORDSIZE == 64
319	FILL(_l)
320#endif
321	FILLF(_f)
322	FILLF(_d)
323
324	DEF(_c)
325	DEF(_uc)
326	DEF(_s)
327	DEF(_us)
328	DEF(_i)
329#if __WORDSIZE == 64
330	DEF(_ui)
331	DEF(_l)
332#endif
333	DEF(_f)
334	DEF(_d)
335
336	name main
337main:
338	prolog
339
340	CALL(_c)
341	CALL(_uc)
342	CALL(_s)
343	CALL(_us)
344	CALL(_i)
345#if __WORDSIZE == 64
346	CALL(_ui)
347	CALL(_l)
348#endif
349	CALL(_f)
350	CALL(_d)
351
352	prepare
353		pushargi ok
354		ellipsis
355	finishi @printf
356
357	ret
358	epilog
359