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