github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/8c/swt.c (about) 1 // Inferno utils/8c/swt.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/8c/swt.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 #include "gc.h" 32 33 void 34 swit1(C1 *q, int nc, int32 def, Node *n) 35 { 36 Node nreg; 37 38 if(typev[n->type->etype]) { 39 regsalloc(&nreg, n); 40 nreg.type = types[TVLONG]; 41 cgen(n, &nreg); 42 swit2(q, nc, def, &nreg); 43 return; 44 } 45 46 regalloc(&nreg, n, Z); 47 nreg.type = types[TLONG]; 48 cgen(n, &nreg); 49 swit2(q, nc, def, &nreg); 50 regfree(&nreg); 51 } 52 53 void 54 swit2(C1 *q, int nc, int32 def, Node *n) 55 { 56 C1 *r; 57 int i; 58 Prog *sp; 59 60 if(nc < 5) { 61 for(i=0; i<nc; i++) { 62 if(debug['W']) 63 print("case = %.8ux\n", q->val); 64 gopcode(OEQ, n->type, n, nodconst(q->val)); 65 patch(p, q->label); 66 q++; 67 } 68 gbranch(OGOTO); 69 patch(p, def); 70 return; 71 } 72 i = nc / 2; 73 r = q+i; 74 if(debug['W']) 75 print("case > %.8ux\n", r->val); 76 gopcode(OGT, n->type, n, nodconst(r->val)); 77 sp = p; 78 gbranch(OGOTO); 79 p->as = AJEQ; 80 patch(p, r->label); 81 swit2(q, i, def, n); 82 83 if(debug['W']) 84 print("case < %.8ux\n", r->val); 85 patch(sp, pc); 86 swit2(r+1, nc-i-1, def, n); 87 } 88 89 void 90 bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) 91 { 92 int sh; 93 int32 v; 94 Node *l; 95 96 /* 97 * n1 gets adjusted/masked value 98 * n2 gets address of cell 99 * n3 gets contents of cell 100 */ 101 l = b->left; 102 if(n2 != Z) { 103 regalloc(n1, l, nn); 104 reglcgen(n2, l, Z); 105 regalloc(n3, l, Z); 106 gmove(n2, n3); 107 gmove(n3, n1); 108 } else { 109 regalloc(n1, l, nn); 110 cgen(l, n1); 111 } 112 if(b->type->shift == 0 && typeu[b->type->etype]) { 113 v = ~0 + (1L << b->type->nbits); 114 gopcode(OAND, types[TLONG], nodconst(v), n1); 115 } else { 116 sh = 32 - b->type->shift - b->type->nbits; 117 if(sh > 0) 118 gopcode(OASHL, types[TLONG], nodconst(sh), n1); 119 sh += b->type->shift; 120 if(sh > 0) 121 if(typeu[b->type->etype]) 122 gopcode(OLSHR, types[TLONG], nodconst(sh), n1); 123 else 124 gopcode(OASHR, types[TLONG], nodconst(sh), n1); 125 } 126 } 127 128 void 129 bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) 130 { 131 int32 v; 132 Node nod; 133 int sh; 134 135 regalloc(&nod, b->left, Z); 136 v = ~0 + (1L << b->type->nbits); 137 gopcode(OAND, types[TLONG], nodconst(v), n1); 138 gmove(n1, &nod); 139 if(nn != Z) 140 gmove(n1, nn); 141 sh = b->type->shift; 142 if(sh > 0) 143 gopcode(OASHL, types[TLONG], nodconst(sh), &nod); 144 v <<= sh; 145 gopcode(OAND, types[TLONG], nodconst(~v), n3); 146 gopcode(OOR, types[TLONG], n3, &nod); 147 gmove(&nod, n2); 148 149 regfree(&nod); 150 regfree(n1); 151 regfree(n2); 152 regfree(n3); 153 } 154 155 int32 156 outstring(char *s, int32 n) 157 { 158 int32 r; 159 160 if(suppress) 161 return nstring; 162 r = nstring; 163 while(n) { 164 string[mnstring] = *s++; 165 mnstring++; 166 nstring++; 167 if(mnstring >= NSNAME) { 168 gpseudo(ADATA, symstring, nodconst(0L)); 169 p->from.offset += nstring - NSNAME; 170 p->from.scale = NSNAME; 171 p->to.type = D_SCONST; 172 memmove(p->to.sval, string, NSNAME); 173 mnstring = 0; 174 } 175 n--; 176 } 177 return r; 178 } 179 180 void 181 sextern(Sym *s, Node *a, int32 o, int32 w) 182 { 183 int32 e, lw; 184 185 for(e=0; e<w; e+=NSNAME) { 186 lw = NSNAME; 187 if(w-e < lw) 188 lw = w-e; 189 gpseudo(ADATA, s, nodconst(0L)); 190 p->from.offset += o+e; 191 p->from.scale = lw; 192 p->to.type = D_SCONST; 193 memmove(p->to.sval, a->cstring+e, lw); 194 } 195 } 196 197 void 198 gextern(Sym *s, Node *a, int32 o, int32 w) 199 { 200 if(a->op == OCONST && typev[a->type->etype]) { 201 gpseudo(ADATA, s, lo64(a)); 202 p->from.offset += o; 203 p->from.scale = 4; 204 gpseudo(ADATA, s, hi64(a)); 205 p->from.offset += o + 4; 206 p->from.scale = 4; 207 return; 208 } 209 gpseudo(ADATA, s, a); 210 p->from.offset += o; 211 p->from.scale = w; 212 switch(p->to.type) { 213 default: 214 p->to.index = p->to.type; 215 p->to.type = D_ADDR; 216 case D_CONST: 217 case D_FCONST: 218 case D_ADDR: 219 break; 220 } 221 } 222 223 void zname(Biobuf*, Sym*, int); 224 void zaddr(Biobuf*, Adr*, int); 225 void outhist(Biobuf*); 226 227 void 228 outcode(void) 229 { 230 struct { Sym *sym; short type; } h[NSYM]; 231 Prog *p; 232 Sym *s; 233 int f, sf, st, t, sym; 234 Biobuf b; 235 236 if(debug['S']) { 237 for(p = firstp; p != P; p = p->link) 238 if(p->as != ADATA && p->as != AGLOBL) 239 pc--; 240 for(p = firstp; p != P; p = p->link) { 241 print("%P\n", p); 242 if(p->as != ADATA && p->as != AGLOBL) 243 pc++; 244 } 245 } 246 f = open(outfile, OWRITE); 247 if(f < 0) { 248 diag(Z, "cannot open %s", outfile); 249 return; 250 } 251 Binit(&b, f, OWRITE); 252 253 Bprint(&b, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); 254 if(pragcgobuf.to > pragcgobuf.start) { 255 Bprint(&b, "\n"); 256 Bprint(&b, "$$ // exports\n\n"); 257 Bprint(&b, "$$ // local types\n\n"); 258 Bprint(&b, "$$ // cgo\n"); 259 Bprint(&b, "%s", fmtstrflush(&pragcgobuf)); 260 Bprint(&b, "\n$$\n\n"); 261 } 262 Bprint(&b, "!\n"); 263 264 outhist(&b); 265 for(sym=0; sym<NSYM; sym++) { 266 h[sym].sym = S; 267 h[sym].type = 0; 268 } 269 sym = 1; 270 for(p = firstp; p != P; p = p->link) { 271 jackpot: 272 sf = 0; 273 s = p->from.sym; 274 while(s != S) { 275 sf = s->sym; 276 if(sf < 0 || sf >= NSYM) 277 sf = 0; 278 t = p->from.type; 279 if(t == D_ADDR) 280 t = p->from.index; 281 if(h[sf].type == t) 282 if(h[sf].sym == s) 283 break; 284 s->sym = sym; 285 zname(&b, s, t); 286 h[sym].sym = s; 287 h[sym].type = t; 288 sf = sym; 289 sym++; 290 if(sym >= NSYM) 291 sym = 1; 292 break; 293 } 294 st = 0; 295 s = p->to.sym; 296 while(s != S) { 297 st = s->sym; 298 if(st < 0 || st >= NSYM) 299 st = 0; 300 t = p->to.type; 301 if(t == D_ADDR) 302 t = p->to.index; 303 if(h[st].type == t) 304 if(h[st].sym == s) 305 break; 306 s->sym = sym; 307 zname(&b, s, t); 308 h[sym].sym = s; 309 h[sym].type = t; 310 st = sym; 311 sym++; 312 if(sym >= NSYM) 313 sym = 1; 314 if(st == sf) 315 goto jackpot; 316 break; 317 } 318 BPUTLE2(&b, p->as); 319 BPUTLE4(&b, p->lineno); 320 zaddr(&b, &p->from, sf); 321 zaddr(&b, &p->to, st); 322 } 323 Bterm(&b); 324 close(f); 325 firstp = P; 326 lastp = P; 327 } 328 329 void 330 outhist(Biobuf *b) 331 { 332 Hist *h; 333 char *p, *q, *op, c; 334 Prog pg; 335 int n; 336 char *tofree; 337 static int first = 1; 338 static char *goroot, *goroot_final; 339 340 if(first) { 341 // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL. 342 first = 0; 343 goroot = getenv("GOROOT"); 344 goroot_final = getenv("GOROOT_FINAL"); 345 if(goroot == nil) 346 goroot = ""; 347 if(goroot_final == nil) 348 goroot_final = goroot; 349 if(strcmp(goroot, goroot_final) == 0) { 350 goroot = nil; 351 goroot_final = nil; 352 } 353 } 354 355 tofree = nil; 356 pg = zprog; 357 pg.as = AHISTORY; 358 c = pathchar(); 359 for(h = hist; h != H; h = h->link) { 360 p = h->name; 361 if(p != nil && goroot != nil) { 362 n = strlen(goroot); 363 if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') { 364 tofree = smprint("%s%s", goroot_final, p+n); 365 p = tofree; 366 } 367 } 368 op = 0; 369 if(systemtype(Windows) && p && p[1] == ':'){ 370 c = p[2]; 371 } else if(p && p[0] != c && h->offset == 0 && pathname){ 372 if(systemtype(Windows) && pathname[1] == ':') { 373 op = p; 374 p = pathname; 375 c = p[2]; 376 } else if(pathname[0] == c){ 377 op = p; 378 p = pathname; 379 } 380 } 381 while(p) { 382 q = utfrune(p, c); 383 if(q) { 384 n = q-p; 385 if(n == 0){ 386 n = 1; /* leading "/" */ 387 *p = '/'; /* don't emit "\" on windows */ 388 } 389 q++; 390 } else { 391 n = strlen(p); 392 q = 0; 393 } 394 if(n) { 395 BPUTLE2(b, ANAME); 396 BPUTC(b, D_FILE); 397 BPUTC(b, 1); 398 BPUTC(b, '<'); 399 Bwrite(b, p, n); 400 BPUTC(b, 0); 401 } 402 p = q; 403 if(p == 0 && op) { 404 p = op; 405 op = 0; 406 } 407 } 408 pg.lineno = h->line; 409 pg.to.type = zprog.to.type; 410 pg.to.offset = h->offset; 411 if(h->offset) 412 pg.to.type = D_CONST; 413 414 BPUTLE2(b, pg.as); 415 BPUTLE4(b, pg.lineno); 416 zaddr(b, &pg.from, 0); 417 zaddr(b, &pg.to, 0); 418 419 if(tofree) { 420 free(tofree); 421 tofree = nil; 422 } 423 } 424 } 425 426 void 427 zname(Biobuf *b, Sym *s, int t) 428 { 429 char *n; 430 uint32 sig; 431 432 if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){ 433 sig = sign(s); 434 BPUTLE2(b, ASIGNAME); 435 BPUTLE4(b, sig); 436 s->sig = SIGDONE; 437 } 438 else{ 439 BPUTLE2(b, ANAME); /* as */ 440 } 441 BPUTC(b, t); /* type */ 442 BPUTC(b, s->sym); /* sym */ 443 n = s->name; 444 while(*n) { 445 BPUTC(b, *n); 446 n++; 447 } 448 BPUTC(b, 0); 449 } 450 451 void 452 zaddr(Biobuf *b, Adr *a, int s) 453 { 454 int32 l; 455 int i, t; 456 char *n; 457 Ieee e; 458 459 t = 0; 460 if(a->index != D_NONE || a->scale != 0) 461 t |= T_INDEX; 462 if(s != 0) 463 t |= T_SYM; 464 465 switch(a->type) { 466 default: 467 t |= T_TYPE; 468 case D_NONE: 469 if(a->offset != 0) 470 t |= T_OFFSET; 471 break; 472 case D_FCONST: 473 t |= T_FCONST; 474 break; 475 case D_SCONST: 476 t |= T_SCONST; 477 break; 478 case D_CONST2: 479 t |= T_OFFSET|T_OFFSET2; 480 break; 481 } 482 BPUTC(b, t); 483 484 if(t & T_INDEX) { /* implies index, scale */ 485 BPUTC(b, a->index); 486 BPUTC(b, a->scale); 487 } 488 if(t & T_OFFSET) { /* implies offset */ 489 l = a->offset; 490 BPUTLE4(b, l); 491 } 492 if(t & T_OFFSET2) { /* implies offset2 */ 493 l = a->offset2; 494 BPUTLE4(b, l); 495 } 496 if(t & T_SYM) /* implies sym */ 497 BPUTC(b, s); 498 if(t & T_FCONST) { 499 ieeedtod(&e, a->dval); 500 BPUTLE4(b, e.l); 501 BPUTLE4(b, e.h); 502 return; 503 } 504 if(t & T_SCONST) { 505 n = a->sval; 506 for(i=0; i<NSNAME; i++) { 507 BPUTC(b, *n); 508 n++; 509 } 510 return; 511 } 512 if(t & T_TYPE) 513 BPUTC(b, a->type); 514 } 515 516 int32 517 align(int32 i, Type *t, int op, int32 *maxalign) 518 { 519 int32 o; 520 Type *v; 521 int w; 522 523 o = i; 524 w = 1; 525 switch(op) { 526 default: 527 diag(Z, "unknown align opcode %d", op); 528 break; 529 530 case Asu2: /* padding at end of a struct */ 531 w = *maxalign; 532 if(w < 1) 533 w = 1; 534 if(packflg) 535 w = packflg; 536 break; 537 538 case Ael1: /* initial align of struct element */ 539 for(v=t; v->etype==TARRAY; v=v->link) 540 ; 541 if(v->etype == TSTRUCT || v->etype == TUNION) 542 w = v->align; 543 else { 544 w = ewidth[v->etype]; 545 if(w == 8) 546 w = 4; 547 } 548 if(w < 1 || w > SZ_LONG) 549 fatal(Z, "align"); 550 if(packflg) 551 w = packflg; 552 break; 553 554 case Ael2: /* width of a struct element */ 555 o += t->width; 556 break; 557 558 case Aarg0: /* initial passbyptr argument in arg list */ 559 if(typesuv[t->etype]) { 560 o = align(o, types[TIND], Aarg1, nil); 561 o = align(o, types[TIND], Aarg2, nil); 562 } 563 break; 564 565 case Aarg1: /* initial align of parameter */ 566 w = ewidth[t->etype]; 567 if(w <= 0 || w >= SZ_LONG) { 568 w = SZ_LONG; 569 break; 570 } 571 w = 1; /* little endian no adjustment */ 572 break; 573 574 case Aarg2: /* width of a parameter */ 575 o += t->width; 576 w = t->width; 577 if(w > SZ_LONG) 578 w = SZ_LONG; 579 break; 580 581 case Aaut3: /* total align of automatic */ 582 o = align(o, t, Ael1, nil); 583 o = align(o, t, Ael2, nil); 584 break; 585 } 586 o = xround(o, w); 587 if(maxalign && *maxalign < w) 588 *maxalign = w; 589 if(debug['A']) 590 print("align %s %d %T = %d\n", bnames[op], i, t, o); 591 return o; 592 } 593 594 int32 595 maxround(int32 max, int32 v) 596 { 597 v = xround(v, SZ_LONG); 598 if(v > max) 599 return v; 600 return max; 601 }