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('D', Dconv); 13 fmtinstall('B', Bconv); 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], *s; 46 Prog *p; 47 int a; 48 49 p = va_arg(fp->args, Prog*); 50 a = p->as; 51 if(a == ADATA) 52 sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to); 53 else if(p->as == ATEXT) 54 sprint(str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to); 55 else { 56 s = seprint(str, str+sizeof(str), " %A %D", a, &p->from); 57 if(p->reg != NREG) 58 s = seprint(s, str+sizeof(str), ",%c%d", p->from.type==D_FREG? 'F': 'R', p->reg); 59 if(p->from3.type != D_NONE) 60 s = seprint(s, str+sizeof(str), ",%D", &p->from3); 61 seprint(s, s+sizeof(str), ",%D", &p->to); 62 } 63 return fmtstrcpy(fp, str); 64 } 65 66 int 67 Aconv(Fmt *fp) 68 { 69 char *s; 70 int a; 71 72 a = va_arg(fp->args, int); 73 s = "?"; 74 if(a >= AXXX && a <= ALAST) 75 s = anames[a]; 76 return fmtstrcpy(fp, s); 77 } 78 79 int 80 Dconv(Fmt *fp) 81 { 82 char str[STRINGSZ]; 83 Adr *a; 84 85 a = va_arg(fp->args, Adr*); 86 switch(a->type) { 87 88 default: 89 sprint(str, "GOK-type(%d)", a->type); 90 break; 91 92 case D_NONE: 93 str[0] = 0; 94 if(a->name != D_NONE || a->reg != NREG || a->sym != S) 95 sprint(str, "%N(R%d)(NONE)", a, a->reg); 96 break; 97 98 case D_CONST: 99 if(a->reg != NREG) 100 sprint(str, "$%N(R%d)", a, a->reg); 101 else 102 sprint(str, "$%N", a); 103 break; 104 105 case D_OREG: 106 if(a->reg != NREG) 107 sprint(str, "%N(R%d)", a, a->reg); 108 else 109 sprint(str, "%N", a); 110 break; 111 112 case D_REG: 113 sprint(str, "R%d", a->reg); 114 if(a->name != D_NONE || a->sym != S) 115 sprint(str, "%N(R%d)(REG)", a, a->reg); 116 break; 117 118 case D_FREG: 119 sprint(str, "F%d", a->reg); 120 if(a->name != D_NONE || a->sym != S) 121 sprint(str, "%N(F%d)(REG)", a, a->reg); 122 break; 123 124 case D_CREG: 125 sprint(str, "C%d", a->reg); 126 if(a->name != D_NONE || a->sym != S) 127 sprint(str, "%N(C%d)(REG)", a, a->reg); 128 break; 129 130 case D_BRANCH: 131 sprint(str, "%ld(PC)", a->offset-pc); 132 break; 133 134 case D_FCONST: 135 sprint(str, "$%.17e", a->dval); 136 break; 137 138 case D_SCONST: 139 sprint(str, "$\"%S\"", a->sval); 140 break; 141 } 142 return fmtstrcpy(fp, str); 143 } 144 145 int 146 Sconv(Fmt *fp) 147 { 148 int i, c; 149 char str[STRINGSZ], *p, *a; 150 151 a = va_arg(fp->args, char*); 152 p = str; 153 for(i=0; i<NSNAME; i++) { 154 c = a[i] & 0xff; 155 if(c >= 'a' && c <= 'z' || 156 c >= 'A' && c <= 'Z' || 157 c >= '0' && c <= '9' || 158 c == ' ' || c == '%') { 159 *p++ = c; 160 continue; 161 } 162 *p++ = '\\'; 163 switch(c) { 164 case 0: 165 *p++ = 'z'; 166 continue; 167 case '\\': 168 case '"': 169 *p++ = c; 170 continue; 171 case '\n': 172 *p++ = 'n'; 173 continue; 174 case '\t': 175 *p++ = 't'; 176 continue; 177 case '\r': 178 *p++ = 'r'; 179 continue; 180 case '\f': 181 *p++ = 'f'; 182 continue; 183 } 184 *p++ = (c>>6) + '0'; 185 *p++ = ((c>>3) & 7) + '0'; 186 *p++ = (c & 7) + '0'; 187 } 188 *p = 0; 189 return fmtstrcpy(fp, str); 190 } 191 192 int 193 Nconv(Fmt *fp) 194 { 195 char str[STRINGSZ]; 196 Adr *a; 197 Sym *s; 198 int i, l, b, n; 199 200 a = va_arg(fp->args, Adr*); 201 s = a->sym; 202 if(s == S) { 203 if(a->offset > 64 || -a->offset > 64) { 204 n = 0; 205 l = a->offset & 1; 206 for(i=0; i<32; i++){ 207 b = (a->offset >> i) & 1; 208 if(b != l) 209 n++; 210 l = b; 211 } 212 if(n < 2) { 213 sprint(str, "%#lux", a->offset); 214 goto out; 215 } 216 } 217 sprint(str, "%ld", a->offset); 218 goto out; 219 } 220 switch(a->name) { 221 default: 222 sprint(str, "GOK-name(%d)", a->name); 223 break; 224 225 case D_EXTERN: 226 sprint(str, "%s+%ld(SB)", s->name, a->offset); 227 break; 228 229 case D_STATIC: 230 sprint(str, "%s<>+%ld(SB)", s->name, a->offset); 231 break; 232 233 case D_AUTO: 234 sprint(str, "%s-%ld(SP)", s->name, -a->offset); 235 break; 236 237 case D_PARAM: 238 sprint(str, "%s+%ld(FP)", s->name, a->offset); 239 break; 240 } 241 out: 242 return fmtstrcpy(fp, str); 243 } 244