1#define def_wi(i)			\
2	name _w##i			\
3_w##i:					\
4	prolog				\
5	arg $arg##i			\
6	getarg##i %r0 $arg##i		\
7	retr %r0			\
8	epilog
9#define def_wf(f)			\
10	name _w##f			\
11_w##f:					\
12	prolog				\
13	arg##f $arg##f			\
14	getarg##f %f0 $arg##f		\
15	truncr##f %r0 %f0		\
16	retr %r0			\
17	epilog
18#define def_fi(f, i)			\
19	name f##i			\
20f##i:					\
21	prolog				\
22	arg $arg##i			\
23	getarg##i %r0 $arg##i		\
24	extr##f %f0 %r0			\
25	retr##f %f0			\
26	epilog
27#define def_f(f)			\
28	name f##f			\
29f##f:					\
30	prolog				\
31	arg##f $arg##f			\
32	getarg##f %f0 $arg##f		\
33	retr##f %f0			\
34	epilog
35#define def_ff(f, g)			\
36	name f##g			\
37	name f##g			\
38f##g:					\
39	prolog				\
40	arg##g $arg##g			\
41	getarg##g %f0 $arg##g		\
42	extr##g##f %f0 %f0		\
43	retr##f %f0			\
44	epilog
45
46.data	32
47fstr:
48.c	"forward"
49bstr:
50.c	"backward"
51
52.code
53	jmpi main
54
55	def_wi(_c)
56	def_wi(_uc)
57	def_wi(_s)
58	def_wi(_us)
59#if __WORDSIZE == 64
60	def_wi(_i)
61	def_wi(_ui)
62#endif
63	def_wf(_f)
64	def_wf(_d)
65	def_fi(_f, _c)
66	def_fi(_f, _uc)
67	def_fi(_f, _s)
68	def_fi(_f, _us)
69	def_fi(_f, _i)
70#if __WORDSIZE == 64
71	def_fi(_f, _ui)
72	def_fi(_f, _l)
73#endif
74	def_fi(_d, _c)
75	def_fi(_d, _uc)
76	def_fi(_d, _s)
77	def_fi(_d, _us)
78	def_fi(_d, _i)
79#if __WORDSIZE == 64
80	def_fi(_d, _ui)
81	def_fi(_d, _l)
82#endif
83	def_f(_f)
84	def_f(_d)
85	def_ff(_f, _d)
86	def_ff(_d, _f)
87
88	name main
89main:
90	prolog
91
92#define _call_w(n, i, a, r)		\
93	prepare				\
94		pushargi a		\
95	finishi _w##i			\
96	retval %r0			\
97	extr##i %r0 %r0			\
98	beqi _w##i##_##n %r0 r		\
99	calli @abort			\
100_w##i##_##n:
101#define call_w(n, i, a, r)		_call_w(n, i, a, r)
102#define _call_wf(n, f, a, r)		\
103	prepare				\
104		pushargi##f a		\
105	finishi _w##f			\
106	retval %r0			\
107	extr##f %f0 %r0			\
108	beqi##f _w##f##_##n %f0 r	\
109	calli @abort			\
110_w##f##_##n:
111#define call_wf(n, f, a, r)		_call_wf(n, f, a, r)
112#define _call_fi(n, f, i, a, r)		\
113	prepare				\
114		pushargi a		\
115	finishi f##i			\
116	retval##f %f0			\
117	beqi##f f##i##n %f0 r		\
118	calli @abort			\
119f##i##n:
120#define call_fi(n, f, i, a, r)		_call_fi(n, f, i, a, r)
121#define _call_f(n, f, a, r)		\
122	prepare				\
123		pushargi##f a		\
124	finishi f##f			\
125	retval##f %f0			\
126	beqi##f f##f##n %f0 r		\
127	calli @abort			\
128f##f##n:
129#define call_f(n, f, a, r)		_call_f(n, f, a, r)
130#define _call_ff(n, f, g, a, r)		\
131	prepare				\
132		pushargi##g a		\
133	finishi f##g			\
134	retval##f %f0			\
135	beqi##f f##g##n %f0 r		\
136	calli @abort			\
137f##g##n:
138#define call_ff(n, f, g, a, r)		_call_ff(n, f, g, a, r)
139
140#define c7f		0x7f
141#define c80		0x80
142#define c81		0x81
143#define cff		0xff
144#define s7f		0x7fff
145#define s80		0x8000
146#define s81		0x8001
147#define i7f		0x7fffffff
148#define i80		0x80000000
149#define i81		0x80000001
150#define iff		0xffffffff
151#define l7f		0x7fffffffffffffff
152#define l80		0x8000000000000000
153#define l81		0x8000000000000001
154#define f7f		 127.0
155#define f80		-128.0
156#define f81		-127.0
157#define uf80		 128.0
158#define uf81		 127.0
159#if __WORDSIZE == 32
160#  define wc80		0xffffff80
161#  define wc81		0xffffff81
162#  define ws80		0xffff8000
163#  define ws81		0xffff8001
164#else
165#  define wc80		0xffffffffffffff80
166#  define wc81		0xffffffffffffff81
167#  define ws80		0xffffffffffff8000
168#  define ws81		0xffffffffffff8001
169#  define wi80		0xffffffff80000000
170#  define wi81		0xffffffff80000001
171#endif
172
173	call_w(__LINE__, _c,  c7f, c7f)
174	call_w(__LINE__, _c,  c80, wc80)
175	call_w(__LINE__, _c,  c81, wc81)
176	call_w(__LINE__, _uc, c7f, c7f)
177	call_w(__LINE__, _uc, c80, c80)
178	call_w(__LINE__, _uc, c81, c81)
179	call_w(__LINE__, _s,  s7f, s7f)
180	call_w(__LINE__, _s,  s80, ws80)
181	call_w(__LINE__, _s,  s81, ws81)
182	call_w(__LINE__, _us, s7f, s7f)
183	call_w(__LINE__, _us, s80, s80)
184	call_w(__LINE__, _us, s81, s81)
185#if __WORDSIZE == 64
186	call_w(__LINE__, _i,  i7f, i7f)
187	call_w(__LINE__, _i,  i80, wi80)
188	call_w(__LINE__, _i,  i81, wi81)
189	call_w(__LINE__, _ui, i7f, i7f)
190	call_w(__LINE__, _ui, i80, i80)
191	call_w(__LINE__, _ui, i81, i81)
192#endif
193	call_wf(__LINE__, _f, c7f, f7f)
194	call_wf(__LINE__, _f, wc80, f80)
195	call_wf(__LINE__, _f, wc81, f81)
196	call_wf(__LINE__, _d, c7f, f7f)
197	call_wf(__LINE__, _d, wc80, f80)
198	call_wf(__LINE__, _d, wc81, f81)
199	call_fi(__LINE__, _f, _c, c7f, f7f)
200	call_fi(__LINE__, _f, _c, c80, f80)
201	call_fi(__LINE__, _f, _uc, c7f, f7f)
202	call_fi(__LINE__, _f, _uc, c80, uf80)
203	call_fi(__LINE__, _f, _s, c7f, f7f)
204	call_fi(__LINE__, _f, _s, c80, uf80)
205	call_fi(__LINE__, _f, _us, c7f, f7f)
206	call_fi(__LINE__, _f, _us, c80, uf80)
207	call_fi(__LINE__, _f, _i, c7f, f7f)
208	call_fi(__LINE__, _f, _i, c80, uf80)
209#if __WORDSIZE == 64
210	call_fi(__LINE__, _f, _ui, c7f, f7f)
211	call_fi(__LINE__, _f, _ui, c80, uf80)
212	call_fi(__LINE__, _f, _l, c7f, f7f)
213	call_fi(__LINE__, _f, _l, c80, uf80)
214#endif
215	call_fi(__LINE__, _d, _c, c7f, f7f)
216	call_fi(__LINE__, _d, _c, c80, f80)
217	call_fi(__LINE__, _d, _uc, c7f, f7f)
218	call_fi(__LINE__, _d, _uc, c80, uf80)
219	call_fi(__LINE__, _d, _s, c7f, f7f)
220	call_fi(__LINE__, _d, _s, c80, uf80)
221	call_fi(__LINE__, _d, _us, c7f, f7f)
222	call_fi(__LINE__, _d, _us, c80, uf80)
223	call_fi(__LINE__, _d, _i, c7f, f7f)
224	call_fi(__LINE__, _d, _i, c80, uf80)
225#if __WORDSIZE == 64
226	call_fi(__LINE__, _d, _ui, c7f, f7f)
227	call_fi(__LINE__, _d, _ui, c80, uf80)
228	call_fi(__LINE__, _d, _l, c7f, f7f)
229	call_fi(__LINE__, _d, _l, c80, uf80)
230#endif
231	call_f(__LINE__, _f, f7f, f7f)
232	call_f(__LINE__, _d, f7f, f7f)
233	call_ff(__LINE__, _f, _d, f80, f80)
234	call_ff(__LINE__, _d, _f, f81, f81)
235
236	movi %r0 forward
237	callr %r0
238
239	calli iforward
240
241	ret
242	epilog
243
244	name backward
245backward:
246	prolog
247	prepare
248		pushargi bstr
249	finishi @puts
250	ret
251	epilog
252
253	name forward
254forward:
255	prolog
256	prepare
257		pushargi fstr
258	finishi @puts
259	movi %r0 backward
260	callr %r0
261	ret
262	epilog
263
264	name iforward
265iforward:
266	prolog
267	prepare
268		pushargi fstr
269	finishi @puts
270	calli backward
271	ret
272	epilog
273