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, "%ld(%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 sprint(str, "%R", i); 75 break; 76 77 case D_NONE: 78 str[0] = 0; 79 break; 80 81 case D_BRANCH: 82 if(bigP != P && bigP->pcond != P) 83 if(a->sym != S) 84 sprint(str, "%lux+%s", bigP->pcond->pc, 85 a->sym->name); 86 else 87 sprint(str, "%lux", bigP->pcond->pc); 88 else 89 sprint(str, "%ld(PC)", a->offset); 90 break; 91 92 case D_EXTERN: 93 sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); 94 break; 95 96 case D_STATIC: 97 sprint(str, "%s<%d>+%ld(SB)", a->sym->name, 98 a->sym->version, a->offset); 99 break; 100 101 case D_AUTO: 102 sprint(str, "%s+%ld(SP)", a->sym->name, a->offset); 103 break; 104 105 case D_PARAM: 106 if(a->sym) 107 sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); 108 else 109 sprint(str, "%ld(FP)", a->offset); 110 break; 111 112 case D_CONST: 113 sprint(str, "$%ld", a->offset); 114 break; 115 116 case D_FCONST: 117 sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); 118 break; 119 120 case D_SCONST: 121 sprint(str, "$\"%S\"", a->scon); 122 break; 123 124 case D_ADDR: 125 a->type = a->index; 126 a->index = D_NONE; 127 sprint(str, "$%D", a); 128 a->index = a->type; 129 a->type = D_ADDR; 130 goto conv; 131 } 132 brk: 133 if(a->index != D_NONE) { 134 sprint(s, "(%R*%d)", a->index, a->scale); 135 strcat(str, s); 136 } 137 conv: 138 return fmtstrcpy(fp, str); 139 } 140 141 char* regstr[] = 142 { 143 "AL", /* [D_AL] */ 144 "CL", 145 "DL", 146 "BL", 147 "AH", 148 "CH", 149 "DH", 150 "BH", 151 152 "AX", /* [D_AX] */ 153 "CX", 154 "DX", 155 "BX", 156 "SP", 157 "BP", 158 "SI", 159 "DI", 160 161 "F0", /* [D_F0] */ 162 "F1", 163 "F2", 164 "F3", 165 "F4", 166 "F5", 167 "F6", 168 "F7", 169 170 "CS", /* [D_CS] */ 171 "SS", 172 "DS", 173 "ES", 174 "FS", 175 "GS", 176 177 "GDTR", /* [D_GDTR] */ 178 "IDTR", /* [D_IDTR] */ 179 "LDTR", /* [D_LDTR] */ 180 "MSW", /* [D_MSW] */ 181 "TASK", /* [D_TASK] */ 182 183 "CR0", /* [D_CR] */ 184 "CR1", 185 "CR2", 186 "CR3", 187 "CR4", 188 "CR5", 189 "CR6", 190 "CR7", 191 192 "DR0", /* [D_DR] */ 193 "DR1", 194 "DR2", 195 "DR3", 196 "DR4", 197 "DR5", 198 "DR6", 199 "DR7", 200 201 "TR0", /* [D_TR] */ 202 "TR1", 203 "TR2", 204 "TR3", 205 "TR4", 206 "TR5", 207 "TR6", 208 "TR7", 209 210 "NONE", /* [D_NONE] */ 211 }; 212 213 int 214 Rconv(Fmt *fp) 215 { 216 char str[20]; 217 int r; 218 219 r = va_arg(fp->args, int); 220 if(r >= D_AL && r <= D_NONE) 221 sprint(str, "%s", regstr[r-D_AL]); 222 else 223 sprint(str, "gok(%d)", r); 224 225 return fmtstrcpy(fp, str); 226 } 227 228 int 229 Sconv(Fmt *fp) 230 { 231 int i, c; 232 char str[30], *p, *a; 233 234 a = va_arg(fp->args, char*); 235 p = str; 236 for(i=0; i<sizeof(double); i++) { 237 c = a[i] & 0xff; 238 if(c >= 'a' && c <= 'z' || 239 c >= 'A' && c <= 'Z' || 240 c >= '0' && c <= '9') { 241 *p++ = c; 242 continue; 243 } 244 *p++ = '\\'; 245 switch(c) { 246 default: 247 if(c < 040 || c >= 0177) 248 break; /* not portable */ 249 p[-1] = c; 250 continue; 251 case 0: 252 *p++ = 'z'; 253 continue; 254 case '\\': 255 case '"': 256 *p++ = c; 257 continue; 258 case '\n': 259 *p++ = 'n'; 260 continue; 261 case '\t': 262 *p++ = 't'; 263 continue; 264 } 265 *p++ = (c>>6) + '0'; 266 *p++ = ((c>>3) & 7) + '0'; 267 *p++ = (c & 7) + '0'; 268 } 269 *p = 0; 270 return fmtstrcpy(fp, str); 271 } 272 273 void 274 diag(char *fmt, ...) 275 { 276 char buf[STRINGSZ], *tn; 277 va_list arg; 278 279 tn = "??none??"; 280 if(curtext != P && curtext->from.sym != S) 281 tn = curtext->from.sym->name; 282 va_start(arg, fmt); 283 vseprint(buf, buf+sizeof(buf), fmt, arg); 284 va_end(arg); 285 print("%s: %s\n", tn, buf); 286 287 nerrors++; 288 if(nerrors > 20 && !debug['A']) { 289 print("too many errors\n"); 290 errorexit(); 291 } 292 } 293