1 #define EXTERN 2 #include "gc.h" 3 4 void 5 listinit(void) 6 { 7 8 fmtinstall('A', Aconv); 9 fmtinstall('P', Pconv); 10 fmtinstall('S', Sconv); 11 fmtinstall('N', Nconv); 12 fmtinstall('B', Bconv); 13 fmtinstall('D', Dconv); 14 fmtinstall('R', Rconv); 15 } 16 17 int 18 Bconv(Fmt *fp) 19 { 20 char str[STRINGSZ], ss[STRINGSZ], *s; 21 Bits bits; 22 int i; 23 24 str[0] = 0; 25 bits = va_arg(fp->args, Bits); 26 while(bany(&bits)) { 27 i = bnum(bits); 28 if(str[0]) 29 strcat(str, " "); 30 if(var[i].sym == S) { 31 sprint(ss, "$%ld", var[i].offset); 32 s = ss; 33 } else 34 s = var[i].sym->name; 35 if(strlen(str) + strlen(s) + 1 >= STRINGSZ) 36 break; 37 strcat(str, s); 38 bits.b[i/32] &= ~(1L << (i%32)); 39 } 40 return fmtstrcpy(fp, str); 41 } 42 43 char *extra [] = { 44 ".EQ", ".NE", ".CS", ".CC", 45 ".MI", ".PL", ".VS", ".VC", 46 ".HI", ".LS", ".GE", ".LT", 47 ".GT", ".LE", "", ".NV", 48 }; 49 50 int 51 Pconv(Fmt *fp) 52 { 53 char str[STRINGSZ], sc[20]; 54 Prog *p; 55 int a, s; 56 57 p = va_arg(fp->args, Prog*); 58 a = p->as; 59 s = p->scond; 60 strcpy(sc, extra[s & C_SCOND]); 61 if(s & C_SBIT) 62 strcat(sc, ".S"); 63 if(s & C_PBIT) 64 strcat(sc, ".P"); 65 if(s & C_WBIT) 66 strcat(sc, ".W"); 67 if(s & C_UBIT) /* ambiguous with FBIT */ 68 strcat(sc, ".U"); 69 if(a == AMOVM) { 70 if(p->from.type == D_CONST) 71 sprint(str, " %A%s %R,%D", a, sc, &p->from, &p->to); 72 else 73 if(p->to.type == D_CONST) 74 sprint(str, " %A%s %D,%R", a, sc, &p->from, &p->to); 75 else 76 sprint(str, " %A%s %D,%D", a, sc, &p->from, &p->to); 77 } else 78 if(a == ADATA) 79 sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to); 80 else 81 if(p->as == ATEXT) 82 sprint(str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to); 83 else 84 if(p->reg == NREG) 85 sprint(str, " %A%s %D,%D", a, sc, &p->from, &p->to); 86 else 87 if(p->from.type != D_FREG) 88 sprint(str, " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to); 89 else 90 sprint(str, " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to); 91 return fmtstrcpy(fp, str); 92 } 93 94 int 95 Aconv(Fmt *fp) 96 { 97 char *s; 98 int a; 99 100 a = va_arg(fp->args, int); 101 s = "???"; 102 if(a >= AXXX && a < ALAST) 103 s = anames[a]; 104 return fmtstrcpy(fp, s); 105 } 106 107 int 108 Dconv(Fmt *fp) 109 { 110 char str[STRINGSZ]; 111 Adr *a; 112 char *op; 113 int v; 114 115 a = va_arg(fp->args, Adr*); 116 switch(a->type) { 117 118 default: 119 sprint(str, "GOK-type(%d)", a->type); 120 break; 121 122 case D_NONE: 123 str[0] = 0; 124 if(a->name != D_NONE || a->reg != NREG || a->sym != S) 125 sprint(str, "%N(R%d)(NONE)", a, a->reg); 126 break; 127 128 case D_CONST: 129 if(a->reg != NREG) 130 sprint(str, "$%N(R%d)", a, a->reg); 131 else 132 sprint(str, "$%N", a); 133 break; 134 135 case D_SHIFT: 136 v = a->offset; 137 op = "<<>>->@>" + (((v>>5) & 3) << 1); 138 if(v & (1<<4)) 139 sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15); 140 else 141 sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31); 142 if(a->reg != NREG) 143 sprint(str+strlen(str), "(R%d)", a->reg); 144 break; 145 146 case D_OREG: 147 if(a->reg != NREG) 148 sprint(str, "%N(R%d)", a, a->reg); 149 else 150 sprint(str, "%N", a); 151 break; 152 153 case D_REG: 154 sprint(str, "R%d", a->reg); 155 if(a->name != D_NONE || a->sym != S) 156 sprint(str, "%N(R%d)(REG)", a, a->reg); 157 break; 158 159 case D_FREG: 160 sprint(str, "F%d", a->reg); 161 if(a->name != D_NONE || a->sym != S) 162 sprint(str, "%N(R%d)(REG)", a, a->reg); 163 break; 164 165 case D_PSR: 166 sprint(str, "PSR"); 167 if(a->name != D_NONE || a->sym != S) 168 sprint(str, "%N(PSR)(REG)", a); 169 break; 170 171 case D_BRANCH: 172 sprint(str, "%ld(PC)", a->offset-pc); 173 break; 174 175 case D_FCONST: 176 sprint(str, "$%.17e", a->dval); 177 break; 178 179 case D_SCONST: 180 sprint(str, "$\"%S\"", a->sval); 181 break; 182 } 183 return fmtstrcpy(fp, str); 184 } 185 186 int 187 Rconv(Fmt *fp) 188 { 189 char str[STRINGSZ]; 190 Adr *a; 191 int i, v; 192 193 a = va_arg(fp->args, Adr*); 194 sprint(str, "GOK-reglist"); 195 switch(a->type) { 196 case D_CONST: 197 if(a->reg != NREG) 198 break; 199 if(a->sym != S) 200 break; 201 v = a->offset; 202 strcpy(str, ""); 203 for(i=0; i<NREG; i++) { 204 if(v & (1<<i)) { 205 if(str[0] == 0) 206 strcat(str, "[R"); 207 else 208 strcat(str, ",R"); 209 sprint(strchr(str, 0), "%d", i); 210 } 211 } 212 strcat(str, "]"); 213 } 214 return fmtstrcpy(fp, str); 215 } 216 217 int 218 Sconv(Fmt *fp) 219 { 220 int i, c; 221 char str[STRINGSZ], *p, *a; 222 223 a = va_arg(fp->args, char*); 224 p = str; 225 for(i=0; i<NSNAME; i++) { 226 c = a[i] & 0xff; 227 if(c >= 'a' && c <= 'z' || 228 c >= 'A' && c <= 'Z' || 229 c >= '0' && c <= '9' || 230 c == ' ' || c == '%') { 231 *p++ = c; 232 continue; 233 } 234 *p++ = '\\'; 235 switch(c) { 236 case 0: 237 *p++ = 'z'; 238 continue; 239 case '\\': 240 case '"': 241 *p++ = c; 242 continue; 243 case '\n': 244 *p++ = 'n'; 245 continue; 246 case '\t': 247 *p++ = 't'; 248 continue; 249 case '\r': 250 *p++ = 'r'; 251 continue; 252 case '\f': 253 *p++ = 'f'; 254 continue; 255 } 256 *p++ = (c>>6) + '0'; 257 *p++ = ((c>>3) & 7) + '0'; 258 *p++ = (c & 7) + '0'; 259 } 260 *p = 0; 261 return fmtstrcpy(fp, str); 262 } 263 264 int 265 Nconv(Fmt *fp) 266 { 267 char str[STRINGSZ]; 268 Adr *a; 269 Sym *s; 270 271 a = va_arg(fp->args, Adr*); 272 s = a->sym; 273 if(s == S) { 274 sprint(str, "%ld", a->offset); 275 goto out; 276 } 277 switch(a->name) { 278 default: 279 sprint(str, "GOK-name(%d)", a->name); 280 break; 281 282 case D_NONE: 283 sprint(str, "%ld", a->offset); 284 break; 285 286 case D_EXTERN: 287 sprint(str, "%s+%ld(SB)", s->name, a->offset); 288 break; 289 290 case D_STATIC: 291 sprint(str, "%s<>+%ld(SB)", s->name, a->offset); 292 break; 293 294 case D_AUTO: 295 sprint(str, "%s-%ld(SP)", s->name, -a->offset); 296 break; 297 298 case D_PARAM: 299 sprint(str, "%s+%ld(FP)", s->name, a->offset); 300 break; 301 } 302 out: 303 return fmtstrcpy(fp, str); 304 } 305