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 } 13 14 void 15 prasm(Prog *p) 16 { 17 print("%P\n", p); 18 } 19 20 int 21 Pconv(Fmt *fp) 22 { 23 char str[STRINGSZ], *s; 24 Prog *p; 25 int a; 26 27 p = va_arg(fp->args, Prog*); 28 curp = p; 29 a = p->as; 30 if(a == ADATA || a == AINIT || a == ADYNT) 31 sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to); 32 else{ 33 s = str; 34 if(p->mark & NOSCHED) 35 s += sprint(s, "*"); 36 if(p->reg == NREG) 37 sprint(s, " %A %D,%D", a, &p->from, &p->to); 38 else 39 if(p->from.type == D_OREG) { 40 sprint(s, " %A %ld(R%d+R%d),%D", a, 41 p->from.offset, p->from.reg, p->reg, &p->to); 42 } else 43 if(p->to.type == D_OREG) { 44 sprint(s, " %A %D,%ld(R%d+R%d)", a, 45 &p->from, p->to.offset, p->to.reg, p->reg); 46 } else 47 if(p->from.type == D_FREG) 48 sprint(s, " %A %D,F%d,%D", a, &p->from, p->reg, &p->to); 49 else 50 sprint(s, " %A %D,R%d,%D", a, &p->from, p->reg, &p->to); 51 } 52 return fmtstrcpy(fp, str); 53 } 54 55 int 56 Aconv(Fmt *fp) 57 { 58 char *s; 59 int a; 60 61 a = va_arg(fp->args, int); 62 s = "?"; 63 if(a >= AXXX && a <= ALAST) 64 s = anames[a]; 65 return fmtstrcpy(fp, s); 66 } 67 68 int 69 Dconv(Fmt *fp) 70 { 71 char str[STRINGSZ]; 72 Adr *a; 73 long v; 74 75 a = va_arg(fp->args, Adr*); 76 switch(a->type) { 77 78 default: 79 sprint(str, "GOK-type(%d)", a->type); 80 break; 81 82 case D_NONE: 83 str[0] = 0; 84 if(a->name != D_NONE || a->reg != NREG || a->sym != S) 85 sprint(str, "%N(R%d)(NONE)", a, a->reg); 86 break; 87 88 case D_CONST: 89 if(a->reg != NREG) 90 sprint(str, "$%N(R%d)", a, a->reg); 91 else 92 sprint(str, "$%N", a); 93 break; 94 95 case D_ASI: 96 if(a->reg != NREG) 97 sprint(str, "(R%d,%ld)", a->reg, a->offset); 98 else 99 sprint(str, "(R%d,%ld)", 0, a->offset); 100 break; 101 102 case D_OREG: 103 if(a->reg != NREG) 104 sprint(str, "%N(R%d)", a, a->reg); 105 else 106 sprint(str, "%N", a); 107 break; 108 109 case D_REG: 110 sprint(str, "R%d", a->reg); 111 if(a->name != D_NONE || a->sym != S) 112 sprint(str, "%N(R%d)(REG)", a, a->reg); 113 break; 114 115 case D_FREG: 116 sprint(str, "F%d", a->reg); 117 if(a->name != D_NONE || a->sym != S) 118 sprint(str, "%N(F%d)(REG)", a, a->reg); 119 break; 120 121 case D_CREG: 122 sprint(str, "C%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_PREG: 128 sprint(str, "P%d", a->reg); 129 if(a->name != D_NONE || a->sym != S) 130 sprint(str, "%N(P%d)(REG)", a, a->reg); 131 break; 132 133 case D_BRANCH: 134 if(curp->cond != P) { 135 v = curp->cond->pc; 136 if(v >= INITTEXT) 137 v -= INITTEXT-HEADR; 138 if(a->sym != S) 139 sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v); 140 else 141 sprint(str, "%.5lux(BRANCH)", v); 142 } else 143 if(a->sym != S) 144 sprint(str, "%s+%ld(APC)", a->sym->name, a->offset); 145 else 146 sprint(str, "%ld(APC)", a->offset); 147 break; 148 149 case D_FCONST: 150 sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l); 151 break; 152 153 case D_SCONST: 154 sprint(str, "$\"%S\"", a->sval); 155 break; 156 } 157 return fmtstrcpy(fp, str); 158 } 159 160 int 161 Nconv(Fmt *fp) 162 { 163 char str[STRINGSZ]; 164 Adr *a; 165 Sym *s; 166 167 a = va_arg(fp->args, Adr*); 168 s = a->sym; 169 if(s == S) { 170 sprint(str, "%ld", a->offset); 171 goto out; 172 } 173 switch(a->name) { 174 default: 175 sprint(str, "GOK-name(%d)", a->name); 176 break; 177 178 case D_EXTERN: 179 sprint(str, "%s+%ld(SB)", s->name, a->offset); 180 break; 181 182 case D_STATIC: 183 sprint(str, "%s<>+%ld(SB)", s->name, a->offset); 184 break; 185 186 case D_AUTO: 187 sprint(str, "%s-%ld(SP)", s->name, -a->offset); 188 break; 189 190 case D_PARAM: 191 sprint(str, "%s+%ld(FP)", s->name, a->offset); 192 break; 193 } 194 out: 195 return fmtstrcpy(fp, str); 196 } 197 198 int 199 Sconv(Fmt *fp) 200 { 201 int i, c; 202 char str[STRINGSZ], *p, *a; 203 204 a = va_arg(fp->args, char*); 205 p = str; 206 for(i=0; i<sizeof(long); i++) { 207 c = a[i] & 0xff; 208 if(c >= 'a' && c <= 'z' || 209 c >= 'A' && c <= 'Z' || 210 c >= '0' && c <= '9' || 211 c == ' ' || c == '%') { 212 *p++ = c; 213 continue; 214 } 215 *p++ = '\\'; 216 switch(c) { 217 case 0: 218 *p++ = 'z'; 219 continue; 220 case '\\': 221 case '"': 222 *p++ = c; 223 continue; 224 case '\n': 225 *p++ = 'n'; 226 continue; 227 case '\t': 228 *p++ = 't'; 229 continue; 230 } 231 *p++ = (c>>6) + '0'; 232 *p++ = ((c>>3) & 7) + '0'; 233 *p++ = (c & 7) + '0'; 234 } 235 *p = 0; 236 return fmtstrcpy(fp, str); 237 } 238 239 void 240 diag(char *fmt, ...) 241 { 242 char buf[STRINGSZ], *tn; 243 va_list arg; 244 245 tn = "??none??"; 246 if(curtext != P && curtext->from.sym != S) 247 tn = curtext->from.sym->name; 248 va_start(arg, fmt); 249 vseprint(buf, buf+sizeof(buf), fmt, arg); 250 va_end(arg); 251 print("%s: %s\n", tn, buf); 252 253 nerrors++; 254 if(nerrors > 10) { 255 print("too many errors\n"); 256 errorexit(); 257 } 258 } 259