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