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