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, "$%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 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[STRINGSZ], s[STRINGSZ]; 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, "%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 if(a->offset) 90 sprint(str, "$%ld,%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, "%ld(PC)", a->offset-pc); 101 break; 102 103 case D_EXTERN: 104 sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); 105 break; 106 107 case D_STATIC: 108 sprint(str, "%s<>+%ld(SB)", a->sym->name, 109 a->offset); 110 break; 111 112 case D_AUTO: 113 sprint(str, "%s+%ld(SP)", a->sym->name, a->offset); 114 break; 115 116 case D_PARAM: 117 if(a->sym) 118 sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); 119 else 120 sprint(str, "%ld(FP)", a->offset); 121 break; 122 123 case D_CONST: 124 sprint(str, "$%ld", 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 "AH", 159 "CH", 160 "DH", 161 "BH", 162 163 "AX", /*[D_AX]*/ 164 "CX", 165 "DX", 166 "BX", 167 "SP", 168 "BP", 169 "SI", 170 "DI", 171 172 "F0", /*[D_F0]*/ 173 "F1", 174 "F2", 175 "F3", 176 "F4", 177 "F5", 178 "F6", 179 "F7", 180 181 "CS", /*[D_CS]*/ 182 "SS", 183 "DS", 184 "ES", 185 "FS", 186 "GS", 187 188 "GDTR", /*[D_GDTR]*/ 189 "IDTR", /*[D_IDTR]*/ 190 "LDTR", /*[D_LDTR]*/ 191 "MSW", /*[D_MSW] */ 192 "TASK", /*[D_TASK]*/ 193 194 "CR0", /*[D_CR]*/ 195 "CR1", 196 "CR2", 197 "CR3", 198 "CR4", 199 "CR5", 200 "CR6", 201 "CR7", 202 203 "DR0", /*[D_DR]*/ 204 "DR1", 205 "DR2", 206 "DR3", 207 "DR4", 208 "DR5", 209 "DR6", 210 "DR7", 211 212 "TR0", /*[D_TR]*/ 213 "TR1", 214 "TR2", 215 "TR3", 216 "TR4", 217 "TR5", 218 "TR6", 219 "TR7", 220 221 "NONE", /*[D_NONE]*/ 222 }; 223 224 int 225 Rconv(Fmt *fp) 226 { 227 char str[STRINGSZ]; 228 int r; 229 230 r = va_arg(fp->args, int); 231 if(r >= D_AL && r <= D_NONE) 232 sprint(str, "%s", regstr[r-D_AL]); 233 else 234 sprint(str, "gok(%d)", r); 235 236 return fmtstrcpy(fp, str); 237 } 238 239 int 240 Sconv(Fmt *fp) 241 { 242 int i, c; 243 char str[STRINGSZ], *p, *a; 244 245 a = va_arg(fp->args, char*); 246 p = str; 247 for(i=0; i<sizeof(double); i++) { 248 c = a[i] & 0xff; 249 if(c >= 'a' && c <= 'z' || 250 c >= 'A' && c <= 'Z' || 251 c >= '0' && c <= '9') { 252 *p++ = c; 253 continue; 254 } 255 *p++ = '\\'; 256 switch(c) { 257 default: 258 if(c < 040 || c >= 0177) 259 break; /* not portable */ 260 p[-1] = c; 261 continue; 262 case 0: 263 *p++ = 'z'; 264 continue; 265 case '\\': 266 case '"': 267 *p++ = c; 268 continue; 269 case '\n': 270 *p++ = 'n'; 271 continue; 272 case '\t': 273 *p++ = 't'; 274 continue; 275 } 276 *p++ = (c>>6) + '0'; 277 *p++ = ((c>>3) & 7) + '0'; 278 *p++ = (c & 7) + '0'; 279 } 280 *p = 0; 281 return fmtstrcpy(fp, str); 282 } 283