1 #include "l.h" 2 3 void 4 listinit(void) 5 { 6 7 fmtinstall('A', Aconv); 8 fmtinstall('C', Cconv); 9 fmtinstall('D', Dconv); 10 fmtinstall('P', Pconv); 11 fmtinstall('S', Sconv); 12 fmtinstall('N', Nconv); 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 switch(a) { 32 default: 33 s = str; 34 s += sprint(s, "(%ld)", p->line); 35 if(p->reg == NREG) 36 sprint(s, " %A%C %D,%D", 37 a, p->scond, &p->from, &p->to); 38 else 39 if(p->from.type != D_FREG) 40 sprint(s, " %A%C %D,R%d,%D", 41 a, p->scond, &p->from, p->reg, &p->to); 42 else 43 sprint(s, " %A%C %D,F%d,%D", 44 a, p->scond, &p->from, p->reg, &p->to); 45 break; 46 47 case ASWPW: 48 case ASWPBU: 49 sprint(str, "(%ld) %A%C R%d,%D,%D", 50 p->line, a, p->scond, p->reg, &p->from, &p->to); 51 break; 52 53 case ADATA: 54 case AINIT: 55 case ADYNT: 56 sprint(str, "(%ld) %A%C %D/%d,%D", 57 p->line, a, p->scond, &p->from, p->reg, &p->to); 58 break; 59 } 60 return fmtstrcpy(fp, str); 61 } 62 63 int 64 Aconv(Fmt *fp) 65 { 66 char *s; 67 int a; 68 69 a = va_arg(fp->args, int); 70 s = "?"; 71 if(a >= AXXX && a < ALAST) 72 s = anames[a]; 73 return fmtstrcpy(fp, s); 74 } 75 76 char* strcond[16] = 77 { 78 ".EQ", 79 ".NE", 80 ".HS", 81 ".LO", 82 ".MI", 83 ".PL", 84 ".VS", 85 ".VC", 86 ".HI", 87 ".LS", 88 ".GE", 89 ".LT", 90 ".GT", 91 ".LE", 92 "", 93 ".NV" 94 }; 95 96 int 97 Cconv(Fmt *fp) 98 { 99 char s[20]; 100 int c; 101 102 c = va_arg(fp->args, int); 103 strcpy(s, strcond[c & C_SCOND]); 104 if(c & C_SBIT) 105 strcat(s, ".S"); 106 if(c & C_PBIT) 107 strcat(s, ".P"); 108 if(c & C_WBIT) 109 strcat(s, ".W"); 110 if(c & C_UBIT) /* ambiguous with FBIT */ 111 strcat(s, ".U"); 112 return fmtstrcpy(fp, s); 113 } 114 115 int 116 Dconv(Fmt *fp) 117 { 118 char str[STRINGSZ]; 119 char *op; 120 Adr *a; 121 long v; 122 123 a = va_arg(fp->args, Adr*); 124 switch(a->type) { 125 126 default: 127 sprint(str, "GOK-type(%d)", a->type); 128 break; 129 130 case D_NONE: 131 str[0] = 0; 132 if(a->name != D_NONE || a->reg != NREG || a->sym != S) 133 sprint(str, "%N(R%d)(NONE)", a, a->reg); 134 break; 135 136 case D_CONST: 137 if(a->reg == NREG) 138 sprint(str, "$%N", a); 139 else 140 sprint(str, "$%N(R%d)", a, a->reg); 141 break; 142 143 case D_SHIFT: 144 v = a->offset; 145 op = "<<>>->@>" + (((v>>5) & 3) << 1); 146 if(v & (1<<4)) 147 sprint(str, "R%ld%c%cR%ld", v&15, op[0], op[1], (v>>8)&15); 148 else 149 sprint(str, "R%ld%c%c%ld", v&15, op[0], op[1], (v>>7)&31); 150 if(a->reg != NREG) 151 sprint(str+strlen(str), "(R%d)", a->reg); 152 break; 153 154 case D_OCONST: 155 sprint(str, "$*$%N", a); 156 if(a->reg != NREG) 157 sprint(str, "%N(R%d)(CONST)", a, a->reg); 158 break; 159 160 case D_OREG: 161 if(a->reg != NREG) 162 sprint(str, "%N(R%d)", a, a->reg); 163 else 164 sprint(str, "%N", a); 165 break; 166 167 case D_REG: 168 sprint(str, "R%d", a->reg); 169 if(a->name != D_NONE || a->sym != S) 170 sprint(str, "%N(R%d)(REG)", a, a->reg); 171 break; 172 173 case D_REGREG: 174 sprint(str, "(R%d,R%d)", a->reg, (int)a->offset); 175 if(a->name != D_NONE || a->sym != S) 176 sprint(str, "%N(R%d)(REG)", a, a->reg); 177 break; 178 179 case D_FREG: 180 sprint(str, "F%d", a->reg); 181 if(a->name != D_NONE || a->sym != S) 182 sprint(str, "%N(R%d)(REG)", a, a->reg); 183 break; 184 185 case D_PSR: 186 switch(a->reg) { 187 case 0: 188 sprint(str, "CPSR"); 189 break; 190 case 1: 191 sprint(str, "SPSR"); 192 break; 193 default: 194 sprint(str, "PSR%d", a->reg); 195 break; 196 } 197 if(a->name != D_NONE || a->sym != S) 198 sprint(str, "%N(PSR%d)(REG)", a, a->reg); 199 break; 200 201 case D_FPCR: 202 switch(a->reg){ 203 case 0: 204 sprint(str, "FPSR"); 205 break; 206 case 1: 207 sprint(str, "FPCR"); 208 break; 209 default: 210 sprint(str, "FCR%d", a->reg); 211 break; 212 } 213 if(a->name != D_NONE || a->sym != S) 214 sprint(str, "%N(FCR%d)(REG)", a, a->reg); 215 216 break; 217 218 case D_BRANCH: /* botch */ 219 if(curp->cond != P) { 220 v = curp->cond->pc; 221 if(a->sym != S) 222 sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v); 223 else 224 sprint(str, "%.5lux(BRANCH)", v); 225 } else 226 if(a->sym != S) 227 sprint(str, "%s+%ld(APC)", a->sym->name, a->offset); 228 else 229 sprint(str, "%ld(APC)", a->offset); 230 break; 231 232 case D_FCONST: 233 sprint(str, "$%e", ieeedtod(a->ieee)); 234 break; 235 236 case D_SCONST: 237 sprint(str, "$\"%S\"", a->sval); 238 break; 239 } 240 return fmtstrcpy(fp, str); 241 } 242 243 int 244 Nconv(Fmt *fp) 245 { 246 char str[STRINGSZ]; 247 Adr *a; 248 Sym *s; 249 250 a = va_arg(fp->args, Adr*); 251 s = a->sym; 252 switch(a->name) { 253 default: 254 sprint(str, "GOK-name(%d)", a->name); 255 break; 256 257 case D_NONE: 258 sprint(str, "%ld", a->offset); 259 break; 260 261 case D_EXTERN: 262 if(s == S) 263 sprint(str, "%ld(SB)", a->offset); 264 else 265 sprint(str, "%s+%ld(SB)", s->name, a->offset); 266 break; 267 268 case D_STATIC: 269 if(s == S) 270 sprint(str, "<>+%ld(SB)", a->offset); 271 else 272 sprint(str, "%s<>+%ld(SB)", s->name, a->offset); 273 break; 274 275 case D_AUTO: 276 if(s == S) 277 sprint(str, "%ld(SP)", a->offset); 278 else 279 sprint(str, "%s-%ld(SP)", s->name, -a->offset); 280 break; 281 282 case D_PARAM: 283 if(s == S) 284 sprint(str, "%ld(FP)", a->offset); 285 else 286 sprint(str, "%s+%ld(FP)", s->name, a->offset); 287 break; 288 } 289 return fmtstrcpy(fp, str); 290 } 291 292 int 293 Sconv(Fmt *fp) 294 { 295 int i, c; 296 char str[STRINGSZ], *p, *a; 297 298 a = va_arg(fp->args, char*); 299 p = str; 300 for(i=0; i<sizeof(long); i++) { 301 c = a[i] & 0xff; 302 if(c >= 'a' && c <= 'z' || 303 c >= 'A' && c <= 'Z' || 304 c >= '0' && c <= '9' || 305 c == ' ' || c == '%') { 306 *p++ = c; 307 continue; 308 } 309 *p++ = '\\'; 310 switch(c) { 311 case 0: 312 *p++ = 'z'; 313 continue; 314 case '\\': 315 case '"': 316 *p++ = c; 317 continue; 318 case '\n': 319 *p++ = 'n'; 320 continue; 321 case '\t': 322 *p++ = 't'; 323 continue; 324 } 325 *p++ = (c>>6) + '0'; 326 *p++ = ((c>>3) & 7) + '0'; 327 *p++ = (c & 7) + '0'; 328 } 329 *p = 0; 330 return fmtstrcpy(fp, str); 331 } 332 333 void 334 diag(char *fmt, ...) 335 { 336 char buf[STRINGSZ], *tn; 337 va_list arg; 338 339 tn = "??none??"; 340 if(curtext != P && curtext->from.sym != S) 341 tn = curtext->from.sym->name; 342 va_start(arg, fmt); 343 vseprint(buf, buf+sizeof(buf), fmt, arg); 344 va_end(arg); 345 print("%s: %s\n", tn, buf); 346 347 nerrors++; 348 if(nerrors > 10) { 349 print("too many errors\n"); 350 errorexit(); 351 } 352 } 353