github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/6c/list.c (about) 1 // Inferno utils/6c/list.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/list.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 #define EXTERN 32 #include "gc.h" 33 34 void 35 listinit(void) 36 { 37 38 fmtinstall('A', Aconv); 39 fmtinstall('B', Bconv); 40 fmtinstall('P', Pconv); 41 fmtinstall('S', Sconv); 42 fmtinstall('D', Dconv); 43 fmtinstall('R', Rconv); 44 } 45 46 int 47 Bconv(Fmt *fp) 48 { 49 char str[STRINGSZ], ss[STRINGSZ], *s; 50 Bits bits; 51 int i; 52 53 str[0] = 0; 54 bits = va_arg(fp->args, Bits); 55 while(bany(&bits)) { 56 i = bnum(bits); 57 if(str[0]) 58 strcat(str, " "); 59 if(var[i].sym == S) { 60 sprint(ss, "$%lld", var[i].offset); 61 s = ss; 62 } else 63 s = var[i].sym->name; 64 if(strlen(str) + strlen(s) + 1 >= STRINGSZ) 65 break; 66 strcat(str, s); 67 bits.b[i/32] &= ~(1L << (i%32)); 68 } 69 return fmtstrcpy(fp, str); 70 } 71 72 int 73 Pconv(Fmt *fp) 74 { 75 char str[STRINGSZ]; 76 Prog *p; 77 78 p = va_arg(fp->args, Prog*); 79 switch(p->as) { 80 case ADATA: 81 sprint(str, "(%L) %A %D/%d,%D", 82 p->lineno, p->as, &p->from, p->from.scale, &p->to); 83 break; 84 85 case ATEXT: 86 if(p->from.scale) { 87 sprint(str, "(%L) %A %D,%d,%lD", 88 p->lineno, p->as, &p->from, p->from.scale, &p->to); 89 break; 90 } 91 sprint(str, "(%L) %A %D,%lD", 92 p->lineno, p->as, &p->from, &p->to); 93 break; 94 95 default: 96 sprint(str, "(%L) %A %D,%D", 97 p->lineno, p->as, &p->from, &p->to); 98 break; 99 } 100 return fmtstrcpy(fp, str); 101 } 102 103 int 104 Aconv(Fmt *fp) 105 { 106 int i; 107 108 i = va_arg(fp->args, int); 109 return fmtstrcpy(fp, anames[i]); 110 } 111 112 int 113 Dconv(Fmt *fp) 114 { 115 char str[STRINGSZ], s[STRINGSZ]; 116 Adr *a; 117 int i; 118 119 a = va_arg(fp->args, Adr*); 120 i = a->type; 121 122 if(fp->flags & FmtLong) { 123 if(i == D_CONST) 124 sprint(str, "$%lld-%lld", a->offset&0xffffffffLL, a->offset>>32); 125 else { 126 // ATEXT dst is not constant 127 sprint(str, "!!%D", a); 128 } 129 goto brk; 130 } 131 132 if(i >= D_INDIR) { 133 if(a->offset) 134 sprint(str, "%lld(%R)", a->offset, i-D_INDIR); 135 else 136 sprint(str, "(%R)", i-D_INDIR); 137 goto brk; 138 } 139 switch(i) { 140 default: 141 if(a->offset) 142 sprint(str, "$%lld,%R", a->offset, i); 143 else 144 sprint(str, "%R", i); 145 break; 146 147 case D_NONE: 148 str[0] = 0; 149 break; 150 151 case D_BRANCH: 152 sprint(str, "%lld", a->offset); 153 break; 154 155 case D_EXTERN: 156 sprint(str, "%s+%lld(SB)", a->sym->name, a->offset); 157 break; 158 159 case D_STATIC: 160 sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset); 161 break; 162 163 case D_AUTO: 164 if(a->sym) 165 sprint(str, "%s+%lld(SP)", a->sym->name, a->offset); 166 else 167 sprint(str, "%lld(SP)", a->offset); 168 break; 169 170 case D_PARAM: 171 if(a->sym) 172 sprint(str, "%s+%lld(FP)", a->sym->name, a->offset); 173 else 174 sprint(str, "%lld(FP)", a->offset); 175 break; 176 177 case D_CONST: 178 sprint(str, "$%lld", a->offset); 179 break; 180 181 case D_FCONST: 182 sprint(str, "$(%.17e)", a->dval); 183 break; 184 185 case D_SCONST: 186 sprint(str, "$\"%S\"", a->sval); 187 break; 188 189 case D_ADDR: 190 a->type = a->index; 191 a->index = D_NONE; 192 sprint(str, "$%D", a); 193 a->index = a->type; 194 a->type = D_ADDR; 195 goto conv; 196 } 197 brk: 198 if(a->index != D_NONE) { 199 sprint(s, "(%R*%d)", (int)a->index, (int)a->scale); 200 strcat(str, s); 201 } 202 conv: 203 return fmtstrcpy(fp, str); 204 } 205 206 char* regstr[] = 207 { 208 "AL", /* [D_AL] */ 209 "CL", 210 "DL", 211 "BL", 212 "SPB", 213 "BPB", 214 "SIB", 215 "DIB", 216 "R8B", 217 "R9B", 218 "R10B", 219 "R11B", 220 "R12B", 221 "R13B", 222 "R14B", 223 "R15B", 224 225 "AX", /* [D_AX] */ 226 "CX", 227 "DX", 228 "BX", 229 "SP", 230 "BP", 231 "SI", 232 "DI", 233 "R8", 234 "R9", 235 "R10", 236 "R11", 237 "R12", 238 "R13", 239 "R14", 240 "R15", 241 242 "AH", 243 "CH", 244 "DH", 245 "BH", 246 247 "F0", /* [D_F0] */ 248 "F1", 249 "F2", 250 "F3", 251 "F4", 252 "F5", 253 "F6", 254 "F7", 255 256 "M0", 257 "M1", 258 "M2", 259 "M3", 260 "M4", 261 "M5", 262 "M6", 263 "M7", 264 265 "X0", 266 "X1", 267 "X2", 268 "X3", 269 "X4", 270 "X5", 271 "X6", 272 "X7", 273 "X8", 274 "X9", 275 "X10", 276 "X11", 277 "X12", 278 "X13", 279 "X14", 280 "X15", 281 282 "CS", /* [D_CS] */ 283 "SS", 284 "DS", 285 "ES", 286 "FS", 287 "GS", 288 289 "GDTR", /* [D_GDTR] */ 290 "IDTR", /* [D_IDTR] */ 291 "LDTR", /* [D_LDTR] */ 292 "MSW", /* [D_MSW] */ 293 "TASK", /* [D_TASK] */ 294 295 "CR0", /* [D_CR] */ 296 "CR1", 297 "CR2", 298 "CR3", 299 "CR4", 300 "CR5", 301 "CR6", 302 "CR7", 303 "CR8", 304 "CR9", 305 "CR10", 306 "CR11", 307 "CR12", 308 "CR13", 309 "CR14", 310 "CR15", 311 312 "DR0", /* [D_DR] */ 313 "DR1", 314 "DR2", 315 "DR3", 316 "DR4", 317 "DR5", 318 "DR6", 319 "DR7", 320 321 "TR0", /* [D_TR] */ 322 "TR1", 323 "TR2", 324 "TR3", 325 "TR4", 326 "TR5", 327 "TR6", 328 "TR7", 329 330 "NONE", /* [D_NONE] */ 331 }; 332 333 int 334 Rconv(Fmt *fp) 335 { 336 char str[STRINGSZ]; 337 int r; 338 339 r = va_arg(fp->args, int); 340 if(r >= D_AL && r <= D_NONE) 341 sprint(str, "%s", regstr[r-D_AL]); 342 else 343 sprint(str, "gok(%d)", r); 344 345 return fmtstrcpy(fp, str); 346 } 347 348 int 349 Sconv(Fmt *fp) 350 { 351 int i, c; 352 char str[STRINGSZ], *p, *a; 353 354 a = va_arg(fp->args, char*); 355 p = str; 356 for(i=0; i<sizeof(double); i++) { 357 c = a[i] & 0xff; 358 if(c >= 'a' && c <= 'z' || 359 c >= 'A' && c <= 'Z' || 360 c >= '0' && c <= '9') { 361 *p++ = c; 362 continue; 363 } 364 *p++ = '\\'; 365 switch(c) { 366 default: 367 if(c < 040 || c >= 0177) 368 break; /* not portable */ 369 p[-1] = c; 370 continue; 371 case 0: 372 *p++ = 'z'; 373 continue; 374 case '\\': 375 case '"': 376 *p++ = c; 377 continue; 378 case '\n': 379 *p++ = 'n'; 380 continue; 381 case '\t': 382 *p++ = 't'; 383 continue; 384 } 385 *p++ = (c>>6) + '0'; 386 *p++ = ((c>>3) & 7) + '0'; 387 *p++ = (c & 7) + '0'; 388 } 389 *p = 0; 390 return fmtstrcpy(fp, str); 391 }