#! /usr/bin/awk -f # # create IOCS call interface from iocs.h # # written by ITOH Yasufumi # public domain # # $NetBSD: makeiocscalls.awk,v 1.3 2011/02/21 02:31:59 itohy Exp $ BEGIN { argsiz["l"] = 4; argsiz["w"] = 2 argsiz["lb31"] = 4; argsiz["wb8"] = 2 for (i = 0; i < 16; i++) { reg = substr("d0d1d2d3d4d5d6d7a0a1a2a3a4a5a6a7", i*2+1, 2) regno[reg] = i } print "#include " } $1 == "/*" && ($2 ~ /^[0-9a-f][0-9a-f]$/ || $2 == "(none)") { funcnam="" iocsno=$2 ptrval=0 narg=0 retd2=0 err_d0=0 noret=0 c_md=0 b_super=0 sp_regst=0 b_curmod = 0 b_curpat = 0 b_scroll = 0 iocs_trap15=0 for (i = 3; i <= NF && $i != "*/" && $i != ";"; i++) { arg[narg] = $i narg++ } if ($i == ";") { # process opts for (i++; i <= NF && $i != "*/"; i++) { if ($i == "retd2") retd2 = 1 else if ($i == "err_d0") err_d0 = 1 else if ($i == "noret") noret = 1 else if ($i == "c_md") c_md = 1 else if ($i == "b_super") b_super = 1 else if ($i == "sp_regst") sp_regst = 1 else if ($i == "b_curmod") b_curmod = 1 else if ($i == "b_curpat") b_curpat = 1 else if ($i == "b_scroll") b_scroll = 1 else if ($i == "trap15") iocs_trap15 = 1 else { print FILENAME ":" NR ": unknown opt", $i exit(1) } } } if ($i != "*/") { print FILENAME ":" NR ": malformed input line:" $0 exit(1) } # find out func name printf "|" for (i++; i <= NF; i++) { printf " %s", $i if ($i ~ /^\**IOCS_[A-Z0-9_]*$/) { funcnam = $i while (funcnam ~ /^\*/) { funcnam = substr(funcnam, 2, length(funcnam) -1) ptrval = 1 } } } print "" if (!funcnam) { print FILENAME ":" NR ": can't find function name" exit(1) } # output assembly code print "ENTRY_NOPROFILE(" funcnam ")" # SAVE REGISTERS for (i = 0; i < 16; i++) { savereg[i] = 0 } for (i = 0; i < narg; i++) { r = arg[i] if (r ~ /^o[ad][0-7]$/) r = substr(r, 2, 2) else if (r ~ /^d[0-7]=/) r = substr(r, 1, 2) if (r != "d0" && !regno[r]) { print FILENAME ":" NR ": unknown arg type:", arg[i] exit(1) } if (r !~ /^[da][01]$/) # may not be saved savereg[regno[r]] = r } # count reg to save nsave = 0 for (i = 0; i < 16; i++) { if (savereg[i]) nsave++ } if (iocs_trap15) { print "\tmoveml\t%d2-%d7/%a2-%a6,%sp@-" nsave = 11 } else if (nsave == 1 || nsave == 2){ # use movel for (i = 0; i < 16; i++) { if (savereg[i]) print "\tmovel\t%" savereg[i] ",%sp@-" } } else if (nsave > 2) { # use moveml saveregs = "" for (i = 0; i < 16; i++) { if (savereg[i]) saveregs = saveregs "/%" savereg[i] } saveregs = substr(saveregs, 2, length(saveregs) - 1) print "\tmoveml\t" saveregs ",%sp@-" } # LOAD ARGS # XXX this should be more intelligent argoff = nsave * 4 + 4 # input arguments for IOCS call iarg = "" iargreglist = "" niarg = 0 iarg_incorder = 1 immarg = "" nimmarg = 0 for (i = 0; i < narg && arg[i] ~ /^[ad]/; i++) { a = arg[i] if (a ~ /^d[1-7]=[0-9][0-9]*$/) { immarg = immarg " " a nimmarg++ } else { if (iarg) { if (regno[a1] >= regno[a]) iarg_incorder = 0 } a1 = a iarg = iarg "/" a iargreglist = iargreglist "/%" a niarg++ } } oarg = "" noarg = 0 for ( ; i < narg; i++) { if (arg[i] ~ /^[o]d[0-7]/) { oarg = oarg " " arg[i] noarg++ } else { print "unknown arg:", arg[i] exit(1) } } # remove leading char iarg = substr(iarg, 2, length(iarg) - 1); iargreglist = substr(iargreglist, 2, length(iargreglist) - 1); immarg = substr(immarg, 2, length(immarg) - 1); oarg = substr(oarg, 2, length(oarg) - 1); # load input args if (niarg == 0) ; else if (niarg == 1 && iarg !~ /\=/) { print "\tmovel\t%sp@(" argoff "),%" iarg "\t| 1arg" } else if (iarg_incorder && iarg !~ /\=/) { print "\tmoveml\t%sp@(" argoff ")," iargreglist "\t| inc order" } else if (iarg == "a1/d1") { print "\tmoveal\t%sp@(" argoff "),%a1" print "\tmovel\t%sp@(" argoff + 4 "),%d1" } else if (iarg == "d1/a1/d2") { print "\tmoveml\t%sp@(" argoff "),%d1-%d2/%a1" print "\texg\t%d2,%a1" } else if (iarg == "a1/a2/d1") { print "\tmoveml\t%sp@(" argoff "),%a1/%a2" print "\tmovel\t%sp@(" argoff + 8 "),%d1" } else if (iarg == "a1/a2/d1/d2") { print "\tmoveml\t%sp@(" argoff "),%d1-%d2/%a1-%a2" print "\texg\t%d1,%a1" print "\texg\t%d2,%a2" } else if (iarg == "a1/d1/d2") { print "\tmoveml\t%sp@(" argoff "),%d0-%d2" print "\tmovel\t%d0,%a1" } else if (iarg == "d1=bb") { print "\tmoveq\t#0,%d1" print "\tmoveb\t%sp@(" argoff + 3 "),%d1" print "\tlslw\t#8,%d1" print "\tmoveb\t%sp@(" argoff + 7 "),%d1" niarg = 2 } else if (iarg == "d1=ww") { print "\tmovew\t%sp@(" argoff + 2 "),%d1" print "\tswap\t%d1" print "\tmovew\t%sp@(" argoff + 6 "),%d1" niarg = 2 } else if (iarg == "d1=hsv") { print "\tmoveb\t%sp@(" argoff + 3 "),%d1" print "\tswap\t%d1" print "\tmoveb\t%sp@(" argoff + 7 "),%d1" print "\tlslw\t#8,%d1" print "\tmoveb\t%sp@(" argoff + 11 "),%d1" print "\tandl\t#0x00ff1f1f,%d1" niarg = 3 } else if (iarg == "a1/d1=bb") { print "\tmoveal\t%sp@(" argoff "),%a1" print "\tmoveq\t#0,%d1" print "\tmoveb\t%sp@(" argoff + 7 "),%d1" print "\tlslw\t#8,%d1" print "\tmoveb %sp@(" argoff + 11 "),%d1" niarg = 3 } else if (iarg == "d1/d2=ww") { print "\tmovel\t%sp@(" argoff "),%d1" print "\tmovew\t%sp@(" argoff + 6 "),%d2" print "\tswap\t%d2" print "\tmovew\t%sp@(" argoff + 10 "),%d2" niarg = 3 } else if (iarg == "d1=ww/a1") { print "\tmoveml\t%sp@(" argoff "),%d0-%d1/%a1" print "\tswap\t%d1" print "\tmovew\t%d0,%d1" print "\tswap\t%d1" niarg = 3 } else if (iarg == "d1=ww/d2=ww") { print "\tmoveml\t%sp@(" argoff "),%d1-%d2" print "\tswap\t%d1" print "\tmovew\t%d2,%d1" print "\tmovew\t%sp@(" argoff + 10 "),%d2" print "\tswap\t%d2" print "\tmovew\t%sp@(" argoff + 14 "),%d2" niarg = 4 } else { print "unsupported iarg:", iarg exit(1) } argoff += niarg * 4 if (sp_regst) { print "\tandl\t#0x80000000,%d1" print "\tmoveb\t%d0,%d1" } if (b_curmod) { print "\tmoveq\t#1,%d0" print "\tcmpl\t%d1,%d0" # print "\tbcss\tLerr" print "\tbcss\t6f" } if (b_curpat) { print "\ttstw\t%d2" # print "\tbeqs\tLerr" print "\tbeqs\t6f" } if (b_super) { print "\tmoval\t%sp@+,%a0" print "\tmoval\t%sp@,%a1" } # load imm args if (nimmarg) { for (i = 0; i < narg && arg[i] ~ /^[ad]/; i++) { a = arg[i] if (a ~ /^d[1-7]=[0-9][0-9]*$/) { r = substr(a, 1, 2) v = substr(a, 4, length(a)-3) print "\tmoveq\t#" v ",%" r } } } if (c_md) { # -1: flush(3), -2: set default(2), other: set by the value(4) print "\tmovel\t%d2,%d0" print "\taddql\t#1,%d0" print "\tbeqs\tLcachemd" print "\tmoveq\t#2,%d1" print "\taddql\t#1,%d0" print "\tbnes\tLcachemd" print "\tmoveq\t#4,%d1" print "Lcachemd:" } if (b_scroll) { # d1 has 16 print "\tcmpl\t%d1,%d2" print "\tbcss\tLscriocs" print "\tmovel\t%d2,%d1" print "Lscriocs:" } if (iocs_trap15) { print "\tmoveal\t%sp@(" argoff "),%a0 | inregs" print "\tmoveml\t%a0@,%d0-%d7/%a1-%a6" argoff += 4 } if (iocsno != "(none)") { if (iocsno ~ /^[89abcdef]./) iocsno = "ffffff" iocsno print "\tmoveq\t#0x" iocsno ",%d0" } print "\ttrap\t#15" if (iocs_trap15) { print "\tmoveal\t%sp@(" argoff "),%a0 | outregs" print "\tmoveml\t%d0-%d7/%a1-%a6,%a0@" } if (err_d0 && noarg) { print "\ttstl\t%d0" # print "\tbnes\tLerr" print "\tbnes\t6f" } # SAVERESULTS # XXX this should be more intelligent if (noarg == 0) ; else if (oarg == "od2") { print "\tmoveal\t%sp@(" argoff "),%a0" argoff += 4 print "\tmovel\t%d2,%a0@" } else if (oarg == "od1 od2 od0") { print "\tmoveml\t%sp@(" argoff "),%a0/%a1" argoff += 8 print "\tmovel\t%d1,%a0@" print "\tmovel\t%d2,%a1@" print "\tmoveal\t%sp@(" argoff "),%a0" argoff += 4 print "\tmovel\t%d0,%a0@" } else if (oarg == "od2 od3") { print "\tmoveml\t%sp@(" argoff "),%a0/%a1" argoff += 8 print "\tmovel\t%d2,%a0@" print "\tmovel\t%d3,%a1@" } else if (oarg == "od2 od3 od4 od5") { print "\tmoveml\t%sp@(" argoff "),%a0/%a1" argoff += 8 print "\tmovel\t%d2,%a0@" print "\tmovel\t%d3,%a1@" print "\tmoveml\t%sp@(" argoff "),%a0/%a1" argoff += 8 print "\tmovel\t%d4,%a0@" print "\tmovel\t%d5,%a1@" } else { print "unsupported oarg:", oarg exit(1) } if ((err_d0 && noarg) || b_curmod || b_curpat) # print "Lerr:" print "6:" # return value if (retd2) print "\tmovel\t%d2,%d0" # RESTORE REGISTERS if (iocs_trap15) { print "\tmoveml\t%sp@+,%d2-%d7/%a2-%a6" } else if (nsave == 1 || nsave == 2){ # use movel for (i = 16 - 1; i >= 0; i--) { if (savereg[i]) print "\tmovel\t%sp@+,%" savereg[i] } } else if (nsave > 2) { # use moveml print "\tmoveml\t%sp@+," saveregs } if (b_super) print "\tjmp\t%a0@" else if (!noret) { if (ptrval) print "#ifdef __SVR4_ABI__\n\tmoveal\t%d0,%a0\n#endif" print "\trts" } }