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