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(void *o, Fconv *fp) 22 { 23 char str[STRINGSZ], *s; 24 Prog *p; 25 int a; 26 27 p = *(Prog**)o; 28 curp = p; 29 a = p->as; 30 if(a == ADATA || a == ADYNT || a == AINIT) 31 sprint(str, "(%ld) %A %D/%d,%D", 32 p->line, a, &p->from, p->reg, &p->to); 33 else{ 34 s = str; 35 s += sprint(s, "(%ld)", p->line); 36 if(p->mark & NOSCHED) 37 s += sprint(s, "*"); 38 if(p->reg == NREG) 39 sprint(s, " %A %D,%D", 40 a, &p->from, &p->to); 41 else 42 if(p->from.type != D_FREG) 43 sprint(s, " %A %D,R%d,%D", 44 a, &p->from, p->reg, &p->to); 45 else 46 sprint(s, " %A %D,F%d,%D", 47 a, &p->from, p->reg, &p->to); 48 } 49 strconv(str, fp); 50 return sizeof(p); 51 } 52 53 int 54 Aconv(void *o, Fconv *fp) 55 { 56 char *s; 57 int a; 58 59 a = *(int*)o; 60 s = "???"; 61 if(a >= AXXX && a < ALAST) 62 s = anames[a]; 63 strconv(s, fp); 64 return sizeof(a); 65 } 66 67 int 68 Dconv(void *o, Fconv *fp) 69 { 70 char str[STRINGSZ]; 71 Adr *a; 72 long v; 73 74 a = *(Adr**)o; 75 switch(a->type) { 76 77 default: 78 sprint(str, "GOK-type(%d)", a->type); 79 break; 80 81 case D_NONE: 82 str[0] = 0; 83 if(a->name != D_NONE || a->reg != NREG || a->sym != S) 84 sprint(str, "%N(R%d)(NONE)", a, a->reg); 85 break; 86 87 case D_CONST: 88 sprint(str, "$%N", a); 89 if(a->reg != NREG) 90 sprint(str, "%N(R%d)(CONST)", a, a->reg); 91 break; 92 93 case D_OCONST: 94 sprint(str, "$*$%N", a); 95 if(a->reg != NREG) 96 sprint(str, "%N(R%d)(CONST)", a, a->reg); 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_MREG: 113 sprint(str, "M%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(R%d)(REG)", a, a->reg); 122 break; 123 124 case D_FCREG: 125 sprint(str, "FC%d", a->reg); 126 if(a->name != D_NONE || a->sym != S) 127 sprint(str, "%N(R%d)(REG)", a, a->reg); 128 break; 129 130 case D_LO: 131 sprint(str, "LO", a->reg); 132 if(a->name != D_NONE || a->sym != S) 133 sprint(str, "%N(LO)(REG)", a, a->reg); 134 break; 135 136 case D_HI: 137 sprint(str, "HI", a->reg); 138 if(a->name != D_NONE || a->sym != S) 139 sprint(str, "%N(HI)(REG)", a, a->reg); 140 break; 141 142 case D_BRANCH: /* botch */ 143 if(curp->cond != P) { 144 v = curp->cond->pc; 145 if(v >= INITTEXT) 146 v -= INITTEXT-HEADR; 147 if(a->sym != S) 148 sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v); 149 else 150 sprint(str, "%.5lux(BRANCH)", v); 151 } else 152 if(a->sym != S) 153 sprint(str, "%s+%ld(APC)", a->sym->name, a->offset); 154 else 155 sprint(str, "%ld(APC)", a->offset); 156 break; 157 158 case D_FCONST: 159 sprint(str, "$%e", ieeedtod(a->ieee)); 160 break; 161 162 case D_SCONST: 163 sprint(str, "$\"%S\"", a->sval); 164 break; 165 } 166 strconv(str, fp); 167 return sizeof(a); 168 } 169 170 int 171 Nconv(void *o, Fconv *fp) 172 { 173 char str[STRINGSZ]; 174 Adr *a; 175 Sym *s; 176 177 a = *(Adr**)o; 178 s = a->sym; 179 switch(a->name) { 180 default: 181 sprint(str, "GOK-name(%d)", a->name); 182 break; 183 184 case D_NONE: 185 sprint(str, "%ld", a->offset); 186 break; 187 188 case D_EXTERN: 189 if(s == S) 190 sprint(str, "%ld(SB)", a->offset); 191 else 192 sprint(str, "%s+%ld(SB)", s->name, a->offset); 193 break; 194 195 case D_STATIC: 196 if(s == S) 197 sprint(str, "<>+%ld(SB)", a->offset); 198 else 199 sprint(str, "%s<>+%ld(SB)", s->name, a->offset); 200 break; 201 202 case D_AUTO: 203 if(s == S) 204 sprint(str, "%ld(SP)", a->offset); 205 else 206 sprint(str, "%s-%ld(SP)", s->name, -a->offset); 207 break; 208 209 case D_PARAM: 210 if(s == S) 211 sprint(str, "%ld(FP)", a->offset); 212 else 213 sprint(str, "%s+%ld(FP)", s->name, a->offset); 214 break; 215 } 216 out: 217 strconv(str, fp); 218 return sizeof(a); 219 } 220 221 int 222 Sconv(void *o, Fconv *fp) 223 { 224 int i, c; 225 char str[STRINGSZ], *p, *a; 226 227 a = *(char**)o; 228 p = str; 229 for(i=0; i<sizeof(long); i++) { 230 c = a[i] & 0xff; 231 if(c >= 'a' && c <= 'z' || 232 c >= 'A' && c <= 'Z' || 233 c >= '0' && c <= '9' || 234 c == ' ' || c == '%') { 235 *p++ = c; 236 continue; 237 } 238 *p++ = '\\'; 239 switch(c) { 240 case 0: 241 *p++ = 'z'; 242 continue; 243 case '\\': 244 case '"': 245 *p++ = c; 246 continue; 247 case '\n': 248 *p++ = 'n'; 249 continue; 250 case '\t': 251 *p++ = 't'; 252 continue; 253 } 254 *p++ = (c>>6) + '0'; 255 *p++ = ((c>>3) & 7) + '0'; 256 *p++ = (c & 7) + '0'; 257 } 258 *p = 0; 259 strconv(str, fp); 260 return sizeof(a); 261 } 262 263 void 264 diag(char *a, ...) 265 { 266 char buf[STRINGSZ], *tn; 267 268 tn = "??none??"; 269 if(curtext != P && curtext->from.sym != S) 270 tn = curtext->from.sym->name; 271 doprint(buf, buf+sizeof(buf), a, &(&a)[1]); /* ugly */ 272 print("%s: %s\n", tn, buf); 273 274 nerrors++; 275 if(nerrors > 10) { 276 print("too many errors\n"); 277 errorexit(); 278 } 279 } 280