github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/6c/swt.c (about)

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