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  }