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