1#! /usr/bin/awk -f 2# 3# create DOS call interface from dos.h 4# 5# written by Yasha (ITOH Yasufumi) 6# public domain 7# 8# $NetBSD: makedoscalls.awk,v 1.3 2000/06/19 03:43:12 itohy Exp $ 9 10BEGIN { 11 errno_nomem = 8 # errno for "Cannot allocate memory" 12 argsiz["l"] = 4; argsiz["w"] = 2 13 argsiz["lb31"] = 4; argsiz["wb8"] = 2; argsiz["wb15"] = 2 14 print "#include \"dos_asm.h\"" 15} 16 17$1 == "/*" && $2 ~ /^ff[0-9a-f][0-9a-f]$/ { 18 funcnam="" 19 dosno=$2 20 ptrval=0 21 narg=0 22 ncarg=0 # number of 32bit C function argument 23 argbyte=0 24 opt_e=0 25 e_strict=0 26 e_alloc=0 27 e_proc=0 28 svreg=0 29 noret=0 30 super=0 31 super_jsr=0 32 alias="" 33 for (i = 3; i <= NF && $i != "*/" && $i != ";"; i++) { 34 arg[narg] = $i 35 narg++ 36 if (argsiz[$i]) 37 ncarg++ 38 } 39 if ($i == ";") { 40 # process opts 41 for (i++; i <= NF && $i != "*/"; i++) { 42 if ($i == "e") 43 opt_e = 1 44 else if ($i == "estrct") { 45 opt_e = 1 46 e_strict = 1 47 } else if ($i == "ep") { 48 opt_e = 1 49 e_proc = 1 50 } else if ($i == "ealloc") { 51 opt_e = 1 52 e_alloc = 1 53 } else if ($i == "sv") 54 svreg = 1 55 else if ($i == "noret") 56 noret = 1 57 else if ($i == "alias") { 58 i++ 59 alias = $i 60 } else if ($i == "super") 61 super = 1 62 else if ($i == "super_jsr") 63 super_jsr = 1 64 else { 65 print FILENAME ":" NR ": unknown opt", $i 66 exit(1) 67 } 68 } 69 } 70 if ($i != "*/") { 71 print FILENAME ":" NR ": malformed input line:" $0 72 exit(1) 73 } 74 # find out func name 75 printf "|" 76 for (i++; i <= NF; i++) { 77 printf " %s", $i 78 if ($i ~ /^\**DOS_[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 if (alias) { 95 print "GLOBAL(" alias ")" 96 } 97 if (svreg) print "\tmoveml\t%d2-%d7/%a2-%a6,%sp@-" 98 99 # PUSH ARGS 100 argoff = ncarg * 4 101 if (svreg) 102 argoff += 4 * 11 103 for (i = narg - 1; i >= 0; i--) { 104 a = arg[i] 105 asz = argsiz[a] 106 if (asz) { 107 if (a == "l") { 108 # optimize with movem 109 if (arg[i-1] == "l" && arg[i-2] == "l") { 110 if (arg[i-3] == "l") { 111 print "\tmoveml\t%sp@(" argoff - 12 "),%d0-%d1/%a0-%a1" 112 print "\tmoveml\t%d0-%d1/%a0-%a1,%sp@-" 113 asz = 16 114 i -= 3 115 } else if (arg[i-3] == "w") { 116 print "\tmoveml\t%sp@(" argoff - 12 "),%d0-%d1/%a0-%a1" 117 print "\tmoveml\t%d1/%a0-%a1,%sp@-" 118 print "\tmovew\t%d0,%sp@-" 119 asz = 14 120 i -= 3 121 } else { 122 print "\tmoveml\t%sp@(" argoff - 8 "),%d0-%d1/%a0" 123 print "\tmoveml\t%d0-%d1/%a0,%sp@-" 124 asz = 12 125 i -= 2 126 } 127 } else { 128 print "\tmovel\t%sp@(" argoff "),%sp@-" 129 } 130 } else if (a == "w") 131 print "\tmovew\t%sp@(" argoff + 2 "),%sp@-" 132 else if (a == "lb31") { 133 print "\tmovel\t%sp@(" argoff "),%d0" 134 print "\tbset\t#31,%d0" 135 print "\tmovel\t%d0,%sp@-" 136 } else if (a == "wb8") { 137 print "\tmovew\t%sp@(" argoff + 2 "),%d0" 138 print "\torw\t#0x100,%d0" 139 print "\tmovew\t%d0,%sp@-" 140 } else if (a == "wb15") { 141 print "\tmovew\t%sp@(" argoff + 2 "),%d0" 142 print "\torw\t#0x8000,%d0" 143 print "\tmovew\t%d0,%sp@-" 144 } else { 145 print "??? unknown type" 146 exit(1) 147 } 148 149 if (asz == 2) 150 argoff -= 2 151 } else if (a ~ /^[0-9][0-9]*\.w$/) { 152 asz = 2 153 argoff += 2 154 val = substr(a, 1, length(a) - 2) 155 if (val == 0) 156 print "\tclrw\t%sp@-" 157 else 158 print "\tmovew\t#" val ",%sp@-" 159 } else if (a ~ /^[0-9][0-9]*\.l$/) { 160 asz = 4; 161 argoff += 4 162 val = substr(a, 1, length(a) - 2) 163 if (val == 0) 164 print "\tclrl\t%sp@-" 165 else if (val <= 32767) 166 print "\tpea\t" val ":w" 167 else 168 print "\tmovel\t#" val ",%sp@-" 169 } else if (a == "drvctrl" && narg == 1) { 170 # only for DOS_DRVCTRL 171 asz = 2 172 print "\tmoveb\t%sp@(7),%d0" 173 print "\tlslw\t#8,%d0" 174 print "\tmoveb\t%sp@(11),%d0" 175 print "\tmovew\t%d0,%sp@-" 176 } else if (a == "super" && narg == 1) { 177 # only for DOS_SUPER 178 print "\tmoveal\t%sp@+,%a1" 179 } else { 180 print FILENAME ":" NR ": unknown arg type:", a 181 exit(1) 182 } 183 argbyte += asz 184 } 185 186 if (super_jsr) { 187 print "\tmoveal\t%sp@(" argoff + 8 "),%a0 | inregs" 188 print "\tmoveml\t%a0@,%d0-%d7/%a0-%a6" 189 } 190 191 if (dosno ~ /^ff[8a]./) { 192 if (dosno ~ /^..8./) 193 v2dosno = "ff5" substr(dosno, 4, 1) 194 else 195 v2dosno = "ff7" substr(dosno, 4, 1) 196 print "\tcmpiw #0x200+14,_C_LABEL(_vernum)+2 | 2.14" 197# print "\tbcss\tLv2doscall" 198 print "\tbcss\t2f" 199 print "\t.word\t0x" dosno 200 if (!noret) 201# print "\tbras\tLedoscall" 202 print "\tbras\t3f" 203# print "Lv2doscall:" 204 print "2:" 205 print "\t.word\t0x" v2dosno 206 if (!noret) 207# print "Ledoscall:" 208 print "3:" 209 } else { 210 print "\t.word\t0x" dosno 211 } 212 213 # no postprocess needed for dead calls 214 if (noret) 215 next 216 217 if (super_jsr) { 218 print "\tmovel\t%a6,%sp@" 219 print "\tmoveal\t%sp@(" argoff + 12 "),%a6 | outregs" 220 print "\tmovel\t%sp@+,%a6@(" 4 * 14 ")" 221 print "\tmoveml\t%d0-%d7/%a0-%a5,%a6@" 222 } else if (argbyte > 0) { 223 # POP ARGS 224 if (argbyte <= 8) 225 print "\taddql\t#" argbyte ",%sp" 226 else 227 print "\tlea\t%sp@(" argbyte "),%sp" 228 } 229 230 if (svreg) print "\tmoveml\t%sp@+,%d2-%d7/%a2-%a6" 231 if (ptrval) print "#ifdef __SVR4_ABI__\n\tmoveal\t%d0,%a0\n#endif" 232 if (opt_e) { 233 if (e_strict) { 234 print "\tcmpil\t#0xffffff00,%d0" 235 print "\tbcc\tCERROR" 236 } else { 237 print "\ttstl\t%d0" 238 if (super) { 239# print "\tbpls\tLnoerr" 240 print "\tbpls\t5f" 241 print "\tnegl\t%d0" 242 print "\tmovel\t%d0,_C_LABEL(dos_errno)" 243 print "\tnegl\t%d0" 244# print "Lnoerr:" 245 print "5:" 246 } else if (e_alloc) { 247# print "\tbpls\tLnoerr" 248 print "\tbpls\t5f" 249 print "\tmovel\t#" errno_nomem ",_C_LABEL(dos_errno)" 250# print "Lnoerr:" 251 print "5:" 252 } else if (e_proc) { 253 print "\tbmi\tPRCERROR" 254 } else 255 print "\tbmi\tCERROR" 256 } 257 } 258 if (super) 259 print "\tjmp\t%a1@" 260 else 261 print "\trts" 262} 263