Home | History | Annotate | Line # | Download | only in libiocs
      1 #! /usr/bin/awk -f
      2 #
      3 #	create IOCS call interface from iocs.h
      4 #
      5 #	written by ITOH Yasufumi
      6 #	public domain
      7 #
      8 #	$NetBSD: makeiocscalls.awk,v 1.3 2011/02/21 02:31:59 itohy Exp $
      9 
     10 BEGIN {
     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