1 #include "l.h" 2 3 void 4 listinit(void) 5 { 6 7 fmtinstall('R', Rconv); 8 fmtinstall('A', Aconv); 9 fmtinstall('D', Dconv); 10 fmtinstall('X', Xconv); 11 fmtinstall('S', Sconv); 12 fmtinstall('P', Pconv); 13 } 14 15 static Prog *bigP; 16 17 int 18 Pconv(void *o, Fconv *fp) 19 { 20 char str[STRINGSZ]; 21 Prog *p; 22 23 p = *(Prog**)o; 24 bigP = p; 25 if(p->as == ADATA) 26 sprint(str, "(%ld) %A %D/%d,%D", 27 p->line, p->as, &p->from, p->from.scale, &p->to); 28 else 29 if(p->type != D_NONE) { 30 if(p->type >= D_R0 && p->type < D_R0+32) 31 sprint(str, "(%ld) %A %D,%R,%D", 32 p->line, p->as, &p->from, p->type, &p->to); 33 else 34 if(p->type == D_CONST) 35 sprint(str, "(%ld) %A %D,$%d,%D", 36 p->line, p->as, &p->from, p->offset, &p->to); 37 else 38 sprint(str, "(%ld) %A %D,gok(%d),%D", 39 p->line, p->as, &p->from, p->type, &p->to); 40 } else 41 sprint(str, "(%ld) %A %D,%D", 42 p->line, p->as, &p->from, &p->to); 43 strconv(str, fp); 44 bigP = P; 45 return sizeof(Prog*); 46 } 47 48 int 49 Aconv(void *o, Fconv *fp) 50 { 51 52 strconv(anames[*(int*)o], fp); 53 return sizeof(int); 54 } 55 56 int 57 Xconv(void *o, Fconv *fp) 58 { 59 char str[20]; 60 int i; 61 62 str[0] = 0; 63 i = ((int*)o)[0]; 64 if(i != D_NONE) 65 sprint(str, "(%R*%d)", i, ((int*)o)[1]); 66 strconv(str, fp); 67 return sizeof(int[2]); 68 } 69 70 int 71 Dconv(void *o, Fconv *fp) 72 { 73 char str[40], s[20]; 74 Adr *a; 75 int i; 76 77 a = *(Adr**)o; 78 i = a->type; 79 if(i >= D_INDIR) { 80 if(a->offset) 81 sprint(str, "%ld(%R)", a->offset, i-D_INDIR); 82 else 83 sprint(str, "(%R)", i-D_INDIR); 84 goto brk; 85 } 86 switch(i) { 87 88 default: 89 sprint(str, "%R", i); 90 break; 91 92 case D_NONE: 93 str[0] = 0; 94 break; 95 96 case D_BRANCH: 97 if(bigP != P && bigP->cond != P) 98 if(a->sym != S) 99 sprint(str, "%lux+%s", bigP->cond->pc, 100 a->sym->name); 101 else 102 sprint(str, "%lux", bigP->cond->pc); 103 else 104 sprint(str, "%ld(PC)", a->offset); 105 break; 106 107 case D_EXTERN: 108 sprint(str, "%s+%ld(SB)", a->sym->name, a->offset); 109 break; 110 111 case D_STATIC: 112 sprint(str, "%s<%d>+%ld(SB)", a->sym->name, 113 a->sym->version, a->offset); 114 break; 115 116 case D_AUTO: 117 sprint(str, "%s+%ld(SP)", a->sym->name, a->offset); 118 break; 119 120 case D_PARAM: 121 if(a->sym) 122 sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); 123 else 124 sprint(str, "%ld(FP)", a->offset); 125 break; 126 127 case D_CONST: 128 sprint(str, "$%ld", a->offset); 129 break; 130 131 case D_FCONST: 132 sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); 133 break; 134 135 case D_SCONST: 136 sprint(str, "$\"%S\"", a->scon); 137 break; 138 139 case D_ADDR: 140 a->type = a->index; 141 a->index = D_NONE; 142 sprint(str, "$%D", a); 143 a->index = a->type; 144 a->type = D_ADDR; 145 goto conv; 146 } 147 brk: 148 if(a->index != D_NONE) { 149 sprint(s, "%X", a->index, a->scale); 150 strcat(str, s); 151 } 152 conv: 153 strconv(str, fp); 154 return sizeof(Adr*); 155 } 156 157 int 158 Rconv(void *o, Fconv *fp) 159 { 160 char str[20]; 161 int r; 162 163 r = *(int*)o; 164 if(r >= D_R0 && r < D_R0+32) 165 sprint(str, "R%d", r); 166 else 167 if(r == D_NONE) 168 sprint(str, ""); 169 else 170 sprint(str, "gok(%d)", r); 171 172 strconv(str, fp); 173 return sizeof(int); 174 } 175 176 int 177 Sconv(void *o, Fconv *fp) 178 { 179 int i, c; 180 char str[30], *p, *a; 181 182 a = *(char**)o; 183 p = str; 184 for(i=0; i<sizeof(double); i++) { 185 c = a[i] & 0xff; 186 if(c >= 'a' && c <= 'z' || 187 c >= 'A' && c <= 'Z' || 188 c >= '0' && c <= '9') { 189 *p++ = c; 190 continue; 191 } 192 *p++ = '\\'; 193 switch(c) { 194 default: 195 if(c < 040 || c >= 0177) 196 break; /* not portable */ 197 p[-1] = c; 198 continue; 199 case 0: 200 *p++ = 'z'; 201 continue; 202 case '\\': 203 case '"': 204 *p++ = c; 205 continue; 206 case '\n': 207 *p++ = 'n'; 208 continue; 209 case '\t': 210 *p++ = 't'; 211 continue; 212 } 213 *p++ = (c>>6) + '0'; 214 *p++ = ((c>>3) & 7) + '0'; 215 *p++ = (c & 7) + '0'; 216 } 217 *p = 0; 218 strconv(str, fp); 219 return sizeof(char*); 220 } 221 222 void 223 diag(char *a, ...) 224 { 225 char buf[STRINGSZ], *tn; 226 227 tn = "??none??"; 228 if(curtext != P && curtext->from.sym != S) 229 tn = curtext->from.sym->name; 230 doprint(buf, buf+sizeof(buf), a, &(&a)[1]); /* ugly */ 231 print("%s: %s\n", tn, buf); 232 233 nerrors++; 234 if(nerrors > 10) { 235 print("too many errors\n"); 236 errorexit(); 237 } 238 } 239