1#! /usr/bin/awk -f
2#
3#	create IOCS call interface from iocs.h
4#
5#	written by Yasha (ITOH Yasufumi)
6#	public domain
7#
8#	$NetBSD: makeiocscalls.awk,v 1.2 1999/11/11 08:16:20 itohy Exp $
9
10BEGIN {
11	argsiz["l"] = 4; argsiz["w"] = 2
12	argsiz["lb31"] = 4; argsiz["wb8"] = 2
13
14	for (i = 0; i < 16; i++) {
15		reg = substr("d0d1d2d3d4d5d6d7a0a1a2a3a4a5a6a7", i*2+1, 2)
16		regno[reg] = i
17	}
18	print "#include <machine/asm.h>"
19}
20
21$1 == "/*" && ($2 ~ /^[0-9a-f][0-9a-f]$/ || $2 == "(none)") {
22	funcnam=""
23	iocsno=$2
24	ptrval=0
25	narg=0
26	retd2=0
27	err_d0=0
28	noret=0
29	c_md=0
30	b_super=0
31	sp_regst=0
32	b_curmod = 0
33	b_curpat = 0
34	b_scroll = 0
35	iocs_trap15=0
36	for (i = 3; i <= NF && $i != "*/" && $i != ";"; i++) {
37		arg[narg] = $i
38		narg++
39	}
40	if ($i == ";") {
41		# process opts
42		for (i++; i <= NF && $i != "*/"; i++) {
43			if ($i == "retd2")
44				retd2 = 1
45			else if ($i == "err_d0")
46				err_d0 = 1
47			else if ($i == "noret")
48				noret = 1
49			else if ($i == "c_md")
50				c_md = 1
51			else if ($i == "b_super")
52				b_super = 1
53			else if ($i == "sp_regst")
54				sp_regst = 1
55			else if ($i == "b_curmod")
56				b_curmod = 1
57			else if ($i == "b_curpat")
58				b_curpat = 1
59			else if ($i == "b_scroll")
60				b_scroll = 1
61			else if ($i == "trap15")
62				iocs_trap15 = 1
63			else {
64				print FILENAME ":" NR ": unknown opt", $i
65				exit(1)
66			}
67		}
68	}
69	if ($i != "*/") {
70		print FILENAME ":" NR ": malformed input line:" $0
71		exit(1)
72	}
73
74	# find out func name
75	printf "|"
76	for (i++; i <= NF; i++) {
77		printf " %s", $i
78		if ($i ~ /^\**IOCS_[A-Z0-9_]*$/) {
79			funcnam = $i
80			while (funcnam ~ /^\*/) {
81				funcnam = substr(funcnam, 2, length(funcnam) -1)
82				ptrval = 1
83			}
84		}
85	}
86	print ""
87	if (!funcnam) {
88		print FILENAME ":" NR ": can't find function name"
89		exit(1)
90	}
91
92	# output assembly code
93	print "ENTRY_NOPROFILE(" funcnam ")"
94
95	# SAVE REGISTERS
96	for (i = 0; i < 16; i++) {
97		savereg[i] = 0
98	}
99	for (i = 0; i < narg; i++) {
100		r = arg[i]
101		if (r ~ /^o[ad][0-7]$/)
102			r = substr(r, 2, 2)
103		else if (r ~ /^d[0-7]=/)
104			r = substr(r, 1, 2)
105		if (r != "d0" && !regno[r]) {
106			print FILENAME ":" NR ": unknown arg type:", arg[i]
107			exit(1)
108		}
109		if (r !~ /^[da][01]$/)		# may not be saved
110			savereg[regno[r]] = r
111	}
112	# count reg to save
113	nsave = 0
114	for (i = 0; i < 16; i++) {
115		if (savereg[i])
116			nsave++
117	}
118
119	if (iocs_trap15) {
120		print "\tmoveml\t%d2-%d7/%a2-%a6,%sp@-"
121		nsave = 11
122	} else if (nsave == 1 || nsave == 2){
123		# use movel
124		for (i = 0; i < 16; i++) {
125			if (savereg[i])
126				print "\tmovel\t%" savereg[i] ",%sp@-"
127		}
128	} else if (nsave > 2) {
129		# use moveml
130		saveregs = ""
131		for (i = 0; i < 16; i++) {
132			if (savereg[i])
133				saveregs = saveregs "/%" savereg[i]
134		}
135		saveregs = substr(saveregs, 2, length(saveregs) - 1)
136		print "\tmoveml\t" saveregs ",%sp@-"
137	}
138
139	# LOAD ARGS
140	# XXX this should be more intelligent
141	argoff = nsave * 4 + 4
142	# input arguments for IOCS call
143	iarg = ""
144	iargreglist = ""
145	niarg = 0
146	iarg_incorder = 1
147	immarg = ""
148	nimmarg = 0
149	for (i = 0; i < narg && arg[i] ~ /^[ad]/; i++) {
150		a = arg[i]
151		if (a ~ /^d[1-7]=[0-9][0-9]*$/) {
152			immarg = immarg " " a
153			nimmarg++
154		} else {
155			if (iarg) {
156				if (regno[a1] >= regno[a])
157					iarg_incorder = 0
158			}
159			a1 = a
160			iarg = iarg "/" a
161			iargreglist = iargreglist "/%" a
162			niarg++
163		}
164	}
165	oarg = ""
166	noarg = 0
167	for ( ; i < narg; i++) {
168		if (arg[i] ~ /^[o]d[0-7]/) {
169			oarg = oarg " " arg[i]
170			noarg++
171		} else {
172			print "unknown arg:", arg[i]
173			exit(1)
174		}
175	}
176	# remove leading char
177	iarg = substr(iarg, 2, length(iarg) - 1);
178	iargreglist = substr(iargreglist, 2, length(iargreglist) - 1);
179	immarg = substr(immarg, 2, length(immarg) - 1);
180	oarg = substr(oarg, 2, length(oarg) - 1);
181	# load input args
182	if (niarg == 0)
183		;
184	else if (niarg == 1 && iarg !~ /\=/) {
185		print "\tmovel\t%sp@(" argoff "),%" iarg	"\t| 1arg"
186	} else if (iarg_incorder && iarg !~ /\=/) {
187		print "\tmoveml\t%sp@(" argoff ")," iargreglist	"\t| inc order"
188	} else if (iarg == "a1/d1") {
189		print "\tmoveal\t%sp@(" argoff "),%a1"
190		print "\tmovel\t%sp@(" argoff + 4 "),%d1"
191	} else if (iarg == "d1/a1/d2") {
192		print "\tmoveml\t%sp@(" argoff "),%d1-%d2/%a1"
193		print "\texg\t%d2,%a1"
194	} else if (iarg == "a1/a2/d1") {
195		print "\tmoveml\t%sp@(" argoff "),%a1/%a2"
196		print "\tmovel\t%sp@(" argoff + 8 "),%d1"
197	} else if (iarg == "a1/a2/d1/d2") {
198		print "\tmoveml\t%sp@(" argoff "),%d1-%d2/%a1-%a2"
199		print "\texg\t%d1,%a1"
200		print "\texg\t%d2,%a2"
201	} else if (iarg == "a1/d1/d2") {
202		print "\tmoveml\t%sp@(" argoff "),%d0-%d2"
203		print "\tmovel\t%d0,%a1"
204	} else if (iarg == "d1=bb") {
205		print "\tmoveq\t#0,%d1"
206		print "\tmoveb\t%sp@(" argoff + 3 "),%d1"
207		print "\tlslw\t#8,%d1"
208		print "\tmoveb\t%sp@(" argoff + 7 "),%d1"
209		niarg = 2
210	} else if (iarg == "d1=ww") {
211		print "\tmovew\t%sp@(" argoff + 2 "),%d1"
212		print "\tswap\t%d1"
213		print "\tmovew\t%sp@(" argoff + 6 "),%d1"
214		niarg = 2
215	} else if (iarg == "d1=hsv") {
216		print "\tmoveb\t%sp@(" argoff + 3 "),%d1"
217		print "\tswap\t%d1"
218		print "\tmoveb\t%sp@(" argoff + 7 "),%d1"
219		print "\tlslw\t#8,%d1"
220		print "\tmoveb\t%sp@(" argoff + 11 "),%d1"
221		print "\tandl\t#0x00ff1f1f,%d1"
222		niarg = 3
223	} else if (iarg == "a1/d1=bb") {
224		print "\tmoveal\t%sp@(" argoff "),%a1"
225		print "\tmoveq\t#0,%d1"
226		print "\tmoveb\t%sp@(" argoff + 7 "),%d1"
227		print "\tlslw\t#8,%d1"
228		print "\tmoveb	%sp@(" argoff + 11 "),%d1"
229		niarg = 3
230	} else if (iarg == "d1/d2=ww") {
231		print "\tmovel\t%sp@(" argoff "),%d1"
232		print "\tmovew\t%sp@(" argoff + 6 "),%d2"
233		print "\tswap\t%d2"
234		print "\tmovew\t%sp@(" argoff + 10 "),%d2"
235		niarg = 3
236	} else if (iarg == "d1=ww/a1") {
237		print "\tmoveml\t%sp@(" argoff "),%d0-%d1/%a1"
238		print "\tswap\t%d1"
239		print "\tmovew\t%d0,%d1"
240		print "\tswap\t%d1"
241		niarg = 3
242	} else if (iarg == "d1=ww/d2=ww") {
243		print "\tmoveml\t%sp@(" argoff "),%d1-%d2"
244		print "\tswap\t%d1"
245		print "\tmovew\t%d2,%d1"
246		print "\tmovew\t%sp@(" argoff + 10 "),%d2"
247		print "\tswap\t%d2"
248		print "\tmovew\t%sp@(" argoff + 14 "),%d2"
249		niarg = 4
250	} else {
251		print "unsupported iarg:", iarg
252		exit(1)
253	}
254	argoff += niarg * 4
255
256	if (sp_regst) {
257		print "\tandl\t#0x80000000,%d1"
258		print "\tmoveb\t%d0,%d1"
259	}
260
261	if (b_curmod) {
262		print "\tmoveq\t#1,%d0"
263		print "\tcmpl\t%d1,%d0"
264#		print "\tbcss\tLerr"
265		print "\tbcss\t6f"
266	}
267
268	if (b_curpat) {
269		print "\ttstw\t%d2"
270#		print "\tbeqs\tLerr"
271		print "\tbeqs\t6f"
272	}
273
274	if (b_super) {
275		print "\tmoval\t%sp@+,%a0"
276		print "\tmoval\t%sp@,%a1"
277	}
278
279	# load imm args
280	if (nimmarg) {
281		for (i = 0; i < narg && arg[i] ~ /^[ad]/; i++) {
282			a = arg[i]
283			if (a ~ /^d[1-7]=[0-9][0-9]*$/) {
284				r = substr(a, 1, 2)
285				v = substr(a, 4, length(a)-3)
286				print "\tmoveq\t#" v ",%" r
287			}
288		}
289	}
290
291	if (c_md) {
292		# -1: flush(3), -2: set default(2), other: set by the value(4)
293		print "\tmovel\t%d2,%d0"
294		print "\taddql\t#1,%d0"
295		print "\tbeqs\tLcachemd"
296		print "\tmoveq\t#2,%d1"
297		print "\taddql\t#1,%d0"
298		print "\tbnes\tLcachemd"
299		print "\tmoveq\t#4,%d1"
300		print "Lcachemd:"
301	}
302
303	if (b_scroll) {
304		# d1 has 16
305		print "\tcmpl\t%d1,%d2"
306		print "\tbcss\tLscriocs"
307		print "\tmovel\t%d2,%d1"
308		print "Lscriocs:"
309	}
310
311	if (iocs_trap15) {
312		print "\tmoveal\t%sp@(" argoff "),%a0	| inregs"
313		print "\tmoveml\t%a0@,%d0-%d7/%a1-%a6"
314		argoff += 4
315	}
316
317	if (iocsno != "(none)") {
318		if (iocsno ~ /^[89abcdef]./)
319			iocsno = "ffffff" iocsno
320		print "\tmoveq\t#0x" iocsno ",%d0"
321	}
322	print "\ttrap\t#15"
323
324	if (iocs_trap15) {
325		print "\tmoveal\t%sp@(" argoff "),%a0	| outregs"
326		print "\tmoveml\t%d0-%d7/%a1-%a6,%a0@"
327	}
328
329	if (err_d0 && noarg) {
330		print "\ttstl\t%d0"
331#		print "\tbnes\tLerr"
332		print "\tbnes\t6f"
333	}
334
335	# SAVERESULTS
336	# XXX this should be more intelligent
337	if (noarg == 0)
338		;
339	else if (oarg == "od2") {
340		print "\tmoveal\t%sp@(" argoff "),%a0"
341		argoff += 4
342		print "\tmovel\t%d2,%a0@"
343	} else if (oarg == "od1 od2 od0") {
344		print "\tmoveml\t%sp@(" argoff "),%a0/%a1"
345		argoff += 8
346		print "\tmovel\t%d1,%a0@"
347		print "\tmovel\t%d2,%a1@"
348		print "\tmoveal\t%sp@(" argoff "),%a0"
349		argoff += 4
350		print "\tmovel\t%d0,%a0@"
351	} else if (oarg == "od2 od3") {
352		print "\tmoveml\t%sp@(" argoff "),%a0/%a1"
353		argoff += 8
354		print "\tmovel\t%d2,%a0@"
355		print "\tmovel\t%d3,%a1@"
356	} else if (oarg == "od2 od3 od4 od5") {
357		print "\tmoveml\t%sp@(" argoff "),%a0/%a1"
358		argoff += 8
359		print "\tmovel\t%d2,%a0@"
360		print "\tmovel\t%d3,%a1@"
361		print "\tmoveml\t%sp@(" argoff "),%a0/%a1"
362		argoff += 8
363		print "\tmovel\t%d4,%a0@"
364		print "\tmovel\t%d5,%a1@"
365	} else {
366		print "unsupported oarg:", oarg
367		exit(1)
368	}
369
370	if ((err_d0 && noarg) || b_curmod || b_curpat)
371#		print "Lerr:"
372		print "6:"
373
374	# return value
375	if (retd2)
376		print "\tmovel\t%d2,%d0"
377
378	# RESTORE REGISTERS
379	if (iocs_trap15) {
380		print "\tmoveml\t%sp@+,%d2-%d7/%a2-%a6"
381	} else if (nsave == 1 || nsave == 2){
382		# use movel
383		for (i = 16 - 1; i >= 0; i--) {
384			if (savereg[i])
385				print "\tmovel\t%sp@+,%" savereg[i]
386		}
387	} else if (nsave > 2) {
388		# use moveml
389		print "\tmoveml\t%sp@+," saveregs
390	}
391
392
393	if (b_super)
394		print "\tjmp\t%a0@"
395	else if (!noret) {
396		if (ptrval)
397			print "#ifdef __SVR4_ABI__\n\tmoveal\t%d0,%a0\n#endif"
398		print "\trts"
399	}
400}
401