1 #include "l.h" 2 3 void 4 listinit(void) 5 { 6 7 fmtinstall('R', Rconv); 8 fmtinstall('A', Aconv); 9 fmtinstall('D', Dconv); 10 fmtinstall('S', Sconv); 11 fmtinstall('P', Pconv); 12 } 13 14 static Prog *bigP; 15 16 int 17 Pconv(Fmt *fp) 18 { 19 char str[STRINGSZ]; 20 Prog *p; 21 22 p = va_arg(fp->args, Prog*); 23 bigP = p; 24 switch(p->as) { 25 case ATEXT: 26 if(p->from.scale) { 27 sprint(str, "(%ld) %A %D,%d,%D", 28 p->line, p->as, &p->from, p->from.scale, &p->to); 29 break; 30 } 31 default: 32 sprint(str, "(%ld) %A %D,%D", 33 p->line, p->as, &p->from, &p->to); 34 break; 35 case ADATA: 36 case AINIT: 37 case ADYNT: 38 sprint(str, "(%ld) %A %D/%d,%D", 39 p->line, p->as, &p->from, p->from.scale, &p->to); 40 break; 41 } 42 bigP = P; 43 return fmtstrcpy(fp, str); 44 } 45 46 int 47 Aconv(Fmt *fp) 48 { 49 int i; 50 51 i = va_arg(fp->args, int); 52 return fmtstrcpy(fp, anames[i]); 53 } 54 55 int 56 Dconv(Fmt *fp) 57 { 58 char str[40], s[20]; 59 Adr *a; 60 int i; 61 62 a = va_arg(fp->args, Adr*); 63 i = a->type; 64 if(i >= D_INDIR) { 65 if(a->offset) 66 sprint(str, "%lld(%R)", a->offset, i-D_INDIR); 67 else 68 sprint(str, "(%R)", i-D_INDIR); 69 goto brk; 70 } 71 switch(i) { 72 73 default: 74 if(a->offset) 75 sprint(str, "$%lld,%R", a->offset, i); 76 else 77 sprint(str, "%R", i); 78 break; 79 80 case D_NONE: 81 str[0] = 0; 82 break; 83 84 case D_BRANCH: 85 if(bigP != P && bigP->pcond != P) 86 if(a->sym != S) 87 sprint(str, "%llux+%s", bigP->pcond->pc, 88 a->sym->name); 89 else 90 sprint(str, "%llux", bigP->pcond->pc); 91 else 92 sprint(str, "%lld(PC)", a->offset); 93 break; 94 95 case D_EXTERN: 96 sprint(str, "%s+%lld(SB)", a->sym->name, a->offset); 97 break; 98 99 case D_STATIC: 100 sprint(str, "%s<%d>+%lld(SB)", a->sym->name, 101 a->sym->version, a->offset); 102 break; 103 104 case D_AUTO: 105 sprint(str, "%s+%lld(SP)", a->sym->name, a->offset); 106 break; 107 108 case D_PARAM: 109 if(a->sym) 110 sprint(str, "%s+%lld(%s)", a->sym->name, a->offset, paramspace); 111 else 112 sprint(str, "%lld(%s)", a->offset, paramspace); 113 break; 114 115 case D_CONST: 116 sprint(str, "$%lld", a->offset); 117 break; 118 119 case D_FCONST: 120 sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); 121 break; 122 123 case D_SCONST: 124 sprint(str, "$\"%S\"", a->scon); 125 break; 126 127 case D_ADDR: 128 a->type = a->index; 129 a->index = D_NONE; 130 sprint(str, "$%D", a); 131 a->index = a->type; 132 a->type = D_ADDR; 133 goto conv; 134 } 135 brk: 136 if(a->index != D_NONE) { 137 sprint(s, "(%R*%d)", a->index, a->scale); 138 strcat(str, s); 139 } 140 conv: 141 return fmtstrcpy(fp, str); 142 } 143 144 char* regstr[] = 145 { 146 "AL", /* [D_AL] */ 147 "CL", 148 "DL", 149 "BL", 150 "SPB", 151 "BPB", 152 "SIB", 153 "DIB", 154 "R8B", 155 "R9B", 156 "R10B", 157 "R11B", 158 "R12B", 159 "R13B", 160 "R14B", 161 "R15B", 162 163 "AX", /* [D_AX] */ 164 "CX", 165 "DX", 166 "BX", 167 "SP", 168 "BP", 169 "SI", 170 "DI", 171 "R8", 172 "R9", 173 "R10", 174 "R11", 175 "R12", 176 "R13", 177 "R14", 178 "R15", 179 180 "AH", 181 "CH", 182 "DH", 183 "BH", 184 185 "F0", /* [D_F0] */ 186 "F1", 187 "F2", 188 "F3", 189 "F4", 190 "F5", 191 "F6", 192 "F7", 193 194 "M0", 195 "M1", 196 "M2", 197 "M3", 198 "M4", 199 "M5", 200 "M6", 201 "M7", 202 203 "X0", 204 "X1", 205 "X2", 206 "X3", 207 "X4", 208 "X5", 209 "X6", 210 "X7", 211 "X8", 212 "X9", 213 "X10", 214 "X11", 215 "X12", 216 "X13", 217 "X14", 218 "X15", 219 220 "CS", /* [D_CS] */ 221 "SS", 222 "DS", 223 "ES", 224 "FS", 225 "GS", 226 227 "GDTR", /* [D_GDTR] */ 228 "IDTR", /* [D_IDTR] */ 229 "LDTR", /* [D_LDTR] */ 230 "MSW", /* [D_MSW] */ 231 "TASK", /* [D_TASK] */ 232 233 "CR0", /* [D_CR] */ 234 "CR1", 235 "CR2", 236 "CR3", 237 "CR4", 238 "CR5", 239 "CR6", 240 "CR7", 241 "CR8", 242 "CR9", 243 "CR10", 244 "CR11", 245 "CR12", 246 "CR13", 247 "CR14", 248 "CR15", 249 250 "DR0", /* [D_DR] */ 251 "DR1", 252 "DR2", 253 "DR3", 254 "DR4", 255 "DR5", 256 "DR6", 257 "DR7", 258 259 "TR0", /* [D_TR] */ 260 "TR1", 261 "TR2", 262 "TR3", 263 "TR4", 264 "TR5", 265 "TR6", 266 "TR7", 267 268 "NONE", /* [D_NONE] */ 269 }; 270 271 int 272 Rconv(Fmt *fp) 273 { 274 char str[20]; 275 int r; 276 277 r = va_arg(fp->args, int); 278 if(r >= D_AL && r <= D_NONE) 279 sprint(str, "%s", regstr[r-D_AL]); 280 else 281 sprint(str, "gok(%d)", r); 282 283 return fmtstrcpy(fp, str); 284 } 285 286 int 287 Sconv(Fmt *fp) 288 { 289 int i, c; 290 char str[30], *p, *a; 291 292 a = va_arg(fp->args, char*); 293 p = str; 294 for(i=0; i<sizeof(double); i++) { 295 c = a[i] & 0xff; 296 if(c >= 'a' && c <= 'z' || 297 c >= 'A' && c <= 'Z' || 298 c >= '0' && c <= '9') { 299 *p++ = c; 300 continue; 301 } 302 *p++ = '\\'; 303 switch(c) { 304 default: 305 if(c < 040 || c >= 0177) 306 break; /* not portable */ 307 p[-1] = c; 308 continue; 309 case 0: 310 *p++ = 'z'; 311 continue; 312 case '\\': 313 case '"': 314 *p++ = c; 315 continue; 316 case '\n': 317 *p++ = 'n'; 318 continue; 319 case '\t': 320 *p++ = 't'; 321 continue; 322 } 323 *p++ = (c>>6) + '0'; 324 *p++ = ((c>>3) & 7) + '0'; 325 *p++ = (c & 7) + '0'; 326 } 327 *p = 0; 328 return fmtstrcpy(fp, str); 329 } 330 331 void 332 diag(char *fmt, ...) 333 { 334 char buf[STRINGSZ], *tn; 335 va_list arg; 336 337 tn = "??none??"; 338 if(curtext != P && curtext->from.sym != S) 339 tn = curtext->from.sym->name; 340 va_start(arg, fmt); 341 vseprint(buf, buf+sizeof(buf), fmt, arg); 342 va_end(arg); 343 print("%s: %s\n", tn, buf); 344 345 nerrors++; 346 if(nerrors > 20) { 347 print("too many errors\n"); 348 errorexit(); 349 } 350 } 351