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