1 #include "l.h" 2 3 void 4 listinit(void) 5 { 6 7 fmtinstall('A', Aconv); 8 fmtinstall('D', Dconv); 9 fmtinstall('P', Pconv); 10 fmtinstall('S', Sconv); 11 fmtinstall('N', Nconv); 12 fmtinstall('R', Rconv); 13 } 14 15 void 16 prasm(Prog *p) 17 { 18 print("%P\n", p); 19 } 20 21 int 22 Pconv(Fmt *fp) 23 { 24 char str[STRINGSZ], *s; 25 Prog *p; 26 int a; 27 28 p = va_arg(fp->args, Prog*); 29 curp = p; 30 a = p->as; 31 if(a == ADATA || a == AINIT || a == ADYNT) 32 sprint(str, "(%d) %A %D/%d,%D", p->line, a, &p->from, p->reg, &p->to); 33 else { 34 s = str; 35 if(p->mark & NOSCHED) 36 s += sprint(s, "*"); 37 if(p->reg == NREG && p->from3.type == D_NONE) 38 sprint(s, "(%d) %A %D,%D", p->line, a, &p->from, &p->to); 39 else 40 if(a != ATEXT && p->from.type == D_OREG) { 41 sprint(s, "(%d) %A %ld(R%d+R%d),%D", p->line, a, 42 p->from.offset, p->from.reg, p->reg, &p->to); 43 } else 44 if(p->to.type == D_OREG) { 45 sprint(s, "(%d) %A %D,%ld(R%d+R%d)", p->line, a, 46 &p->from, p->to.offset, p->to.reg, p->reg); 47 } else { 48 s += sprint(s, "(%d) %A %D", p->line, a, &p->from); 49 if(p->reg != NREG) 50 s += sprint(s, ",%c%d", p->from.type==D_FREG?'F':'R', p->reg); 51 if(p->from3.type != D_NONE) 52 s += sprint(s, ",%D", &p->from3); 53 sprint(s, ",%D", &p->to); 54 } 55 } 56 return fmtstrcpy(fp, str); 57 } 58 59 int 60 Aconv(Fmt *fp) 61 { 62 char *s; 63 int a; 64 65 a = va_arg(fp->args, int); 66 s = "???"; 67 if(a >= AXXX && a < ALAST) 68 s = anames[a]; 69 return fmtstrcpy(fp, s); 70 } 71 72 int 73 Dconv(Fmt *fp) 74 { 75 char str[STRINGSZ]; 76 Adr *a; 77 long v; 78 79 a = va_arg(fp->args, Adr*); 80 switch(a->type) { 81 82 default: 83 sprint(str, "GOK-type(%d)", a->type); 84 break; 85 86 case D_NONE: 87 str[0] = 0; 88 if(a->name != D_NONE || a->reg != NREG || a->sym != S) 89 sprint(str, "%N(R%d)(NONE)", a, a->reg); 90 break; 91 92 case D_CONST: 93 if(a->reg != NREG) 94 sprint(str, "$%N(R%d)", a, a->reg); 95 else 96 sprint(str, "$%N", a); 97 break; 98 99 case D_OREG: 100 if(a->reg != NREG) 101 sprint(str, "%N(R%d)", a, a->reg); 102 else 103 sprint(str, "%N", a); 104 break; 105 106 case D_REG: 107 sprint(str, "R%d", a->reg); 108 if(a->name != D_NONE || a->sym != S) 109 sprint(str, "%N(R%d)(REG)", a, a->reg); 110 break; 111 112 case D_FREG: 113 sprint(str, "F%d", a->reg); 114 if(a->name != D_NONE || a->sym != S) 115 sprint(str, "%N(F%d)(REG)", a, a->reg); 116 break; 117 118 case D_CREG: 119 if(a->reg == NREG) 120 strcpy(str, "CR"); 121 else 122 sprint(str, "CR%d", a->reg); 123 if(a->name != D_NONE || a->sym != S) 124 sprint(str, "%N(C%d)(REG)", a, a->reg); 125 break; 126 127 case D_SPR: 128 if(a->name == D_NONE && a->sym == S) { 129 switch(a->offset) { 130 case D_XER: sprint(str, "XER"); break; 131 case D_LR: sprint(str, "LR"); break; 132 case D_CTR: sprint(str, "CTR"); break; 133 default: sprint(str, "SPR(%ld)", a->offset); break; 134 } 135 break; 136 } 137 sprint(str, "SPR-GOK(%d)", a->reg); 138 if(a->name != D_NONE || a->sym != S) 139 sprint(str, "%N(SPR-GOK%d)(REG)", a, a->reg); 140 break; 141 142 case D_DCR: 143 if(a->name == D_NONE && a->sym == S) { 144 sprint(str, "DCR(%ld)", a->offset); 145 break; 146 } 147 sprint(str, "DCR-GOK(%d)", a->reg); 148 if(a->name != D_NONE || a->sym != S) 149 sprint(str, "%N(DCR-GOK%d)(REG)", a, a->reg); 150 break; 151 152 case D_OPT: 153 sprint(str, "OPT(%d)", a->reg); 154 break; 155 156 case D_FPSCR: 157 if(a->reg == NREG) 158 strcpy(str, "FPSCR"); 159 else 160 sprint(str, "FPSCR(%d)", a->reg); 161 break; 162 163 case D_MSR: 164 sprint(str, "MSR"); 165 break; 166 167 case D_SREG: 168 sprint(str, "SREG(%d)", a->reg); 169 if(a->name != D_NONE || a->sym != S) 170 sprint(str, "%N(SREG%d)(REG)", a, a->reg); 171 break; 172 173 case D_BRANCH: 174 if(curp->cond != P) { 175 v = curp->cond->pc; 176 if(v >= INITTEXT) 177 v -= INITTEXT-HEADR; 178 if(a->sym != S) 179 sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v); 180 else 181 sprint(str, "%.5lux(BRANCH)", v); 182 } else 183 if(a->sym != S) 184 sprint(str, "%s+%ld(APC)", a->sym->name, a->offset); 185 else 186 sprint(str, "%ld(APC)", a->offset); 187 break; 188 189 case D_FCONST: 190 sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l); 191 break; 192 193 case D_SCONST: 194 sprint(str, "$\"%S\"", a->sval); 195 break; 196 } 197 return fmtstrcpy(fp, str); 198 } 199 200 int 201 Nconv(Fmt *fp) 202 { 203 char str[STRINGSZ]; 204 Adr *a; 205 Sym *s; 206 207 a = va_arg(fp->args, Adr*); 208 s = a->sym; 209 if(s == S) { 210 sprint(str, "%ld", a->offset); 211 goto out; 212 } 213 switch(a->name) { 214 default: 215 sprint(str, "GOK-name(%d)", a->name); 216 break; 217 218 case D_EXTERN: 219 sprint(str, "%s+%ld(SB)", s->name, a->offset); 220 break; 221 222 case D_STATIC: 223 sprint(str, "%s<>+%ld(SB)", s->name, a->offset); 224 break; 225 226 case D_AUTO: 227 sprint(str, "%s-%ld(SP)", s->name, -a->offset); 228 break; 229 230 case D_PARAM: 231 sprint(str, "%s+%ld(FP)", s->name, a->offset); 232 break; 233 } 234 out: 235 return fmtstrcpy(fp, str); 236 } 237 238 int 239 Rconv(Fmt *fp) 240 { 241 char *s; 242 int a; 243 244 a = va_arg(fp->args, int); 245 s = "C_??"; 246 if(a >= C_NONE && a <= C_NCLASS) 247 s = cnames[a]; 248 return fmtstrcpy(fp, s); 249 } 250 251 int 252 Sconv(Fmt *fp) 253 { 254 int i, c; 255 char str[STRINGSZ], *p, *a; 256 257 a = va_arg(fp->args, char*); 258 p = str; 259 for(i=0; i<sizeof(long); i++) { 260 c = a[i] & 0xff; 261 if(c >= 'a' && c <= 'z' || 262 c >= 'A' && c <= 'Z' || 263 c >= '0' && c <= '9' || 264 c == ' ' || c == '%') { 265 *p++ = c; 266 continue; 267 } 268 *p++ = '\\'; 269 switch(c) { 270 case 0: 271 *p++ = 'z'; 272 continue; 273 case '\\': 274 case '"': 275 *p++ = c; 276 continue; 277 case '\n': 278 *p++ = 'n'; 279 continue; 280 case '\t': 281 *p++ = 't'; 282 continue; 283 } 284 *p++ = (c>>6) + '0'; 285 *p++ = ((c>>3) & 7) + '0'; 286 *p++ = (c & 7) + '0'; 287 } 288 *p = 0; 289 return fmtstrcpy(fp, str); 290 } 291 292 void 293 diag(char *fmt, ...) 294 { 295 char buf[STRINGSZ], *tn; 296 va_list arg; 297 298 tn = "??none??"; 299 if(curtext != P && curtext->from.sym != S) 300 tn = curtext->from.sym->name; 301 va_start(arg, fmt); 302 vseprint(buf, buf+sizeof(buf), fmt, arg); 303 va_end(arg); 304 print("%s: %s\n", tn, buf); 305 306 nerrors++; 307 if(nerrors > 10) { 308 print("too many errors\n"); 309 errorexit(); 310 } 311 } 312