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

     1  // Inferno utils/6c/sgen.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6c/sgen.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  #include "../../pkg/runtime/funcdata.h"
    33  
    34  Prog*
    35  gtext(Sym *s, int32 stkoff)
    36  {
    37  	vlong v;
    38  
    39  	v = ((uvlong)argsize() << 32) | (stkoff & 0xffffffff);
    40  	if((textflag & NOSPLIT) && stkoff >= 128)
    41  		yyerror("stack frame too large for NOSPLIT function");
    42  
    43  	gpseudo(ATEXT, s, nodgconst(v, types[TVLONG]));
    44  	return p;
    45  }
    46  
    47  void
    48  noretval(int n)
    49  {
    50  
    51  	if(n & 1) {
    52  		gins(ANOP, Z, Z);
    53  		p->to.type = REGRET;
    54  	}
    55  	if(n & 2) {
    56  		gins(ANOP, Z, Z);
    57  		p->to.type = FREGRET;
    58  	}
    59  }
    60  
    61  /* welcome to commute */
    62  static void
    63  commute(Node *n)
    64  {
    65  	Node *l, *r;
    66  
    67  	l = n->left;
    68  	r = n->right;
    69  	if(r->complex > l->complex) {
    70  		n->left = r;
    71  		n->right = l;
    72  	}
    73  }
    74  
    75  void
    76  indexshift(Node *n)
    77  {
    78  	int g;
    79  
    80  	if(!typechlpv[n->type->etype])
    81  		return;
    82  	simplifyshift(n);
    83  	if(n->op == OASHL && n->right->op == OCONST){
    84  		g = vconst(n->right);
    85  		if(g >= 0 && g <= 3)
    86  			n->addable = 7;
    87  	}
    88  }
    89  
    90  /*
    91   *	calculate addressability as follows
    92   *		NAME ==> 10/11		name+value(SB/SP)
    93   *		REGISTER ==> 12		register
    94   *		CONST ==> 20		$value
    95   *		*(20) ==> 21		value
    96   *		&(10) ==> 13		$name+value(SB)
    97   *		&(11) ==> 1		$name+value(SP)
    98   *		(13) + (20) ==> 13	fold constants
    99   *		(1) + (20) ==> 1	fold constants
   100   *		*(13) ==> 10		back to name
   101   *		*(1) ==> 11		back to name
   102   *
   103   *		(20) * (X) ==> 7	multiplier in indexing
   104   *		(X,7) + (13,1) ==> 8	adder in indexing (addresses)
   105   *		(8) ==> &9(OINDEX)	index, almost addressable
   106   *
   107   *	calculate complexity (number of registers)
   108   */
   109  void
   110  xcom(Node *n)
   111  {
   112  	Node *l, *r;
   113  	int g;
   114  
   115  	if(n == Z)
   116  		return;
   117  	l = n->left;
   118  	r = n->right;
   119  	n->complex = 0;
   120  	n->addable = 0;
   121  	switch(n->op) {
   122  	case OCONST:
   123  		n->addable = 20;
   124  		break;
   125  
   126  	case ONAME:
   127  		if(flag_largemodel)
   128  			n->addable = 9;
   129  		else
   130  			n->addable = 10;
   131  		if(n->class == CPARAM || n->class == CAUTO)
   132  			n->addable = 11;
   133  		break;
   134  
   135  	case OEXREG:
   136  		n->addable = 0;
   137  		break;
   138  
   139  	case OREGISTER:
   140  		n->addable = 12;
   141  		break;
   142  
   143  	case OINDREG:
   144  		n->addable = 12;
   145  		break;
   146  
   147  	case OADDR:
   148  		xcom(l);
   149  		if(l->addable == 10)
   150  			n->addable = 13;
   151  		else
   152  		if(l->addable == 11)
   153  			n->addable = 1;
   154  		break;
   155  
   156  	case OADD:
   157  		xcom(l);
   158  		xcom(r);
   159  		if(n->type->etype != TIND)
   160  			break;
   161  
   162  		switch(r->addable) {
   163  		case 20:
   164  			switch(l->addable) {
   165  			case 1:
   166  			case 13:
   167  			commadd:
   168  				l->type = n->type;
   169  				*n = *l;
   170  				l = new(0, Z, Z);
   171  				*l = *(n->left);
   172  				l->xoffset += r->vconst;
   173  				n->left = l;
   174  				r = n->right;
   175  				goto brk;
   176  			}
   177  			break;
   178  
   179  		case 1:
   180  		case 13:
   181  		case 10:
   182  		case 11:
   183  			/* l is the base, r is the index */
   184  			if(l->addable != 20)
   185  				n->addable = 8;
   186  			break;
   187  		}
   188  		switch(l->addable) {
   189  		case 20:
   190  			switch(r->addable) {
   191  			case 13:
   192  			case 1:
   193  				r = n->left;
   194  				l = n->right;
   195  				n->left = l;
   196  				n->right = r;
   197  				goto commadd;
   198  			}
   199  			break;
   200  
   201  		case 13:
   202  		case 1:
   203  		case 10:
   204  		case 11:
   205  			/* r is the base, l is the index */
   206  			if(r->addable != 20)
   207  				n->addable = 8;
   208  			break;
   209  		}
   210  		if(n->addable == 8 && !side(n)) {
   211  			indx(n);
   212  			l = new1(OINDEX, idx.basetree, idx.regtree);
   213  			l->scale = idx.scale;
   214  			l->addable = 9;
   215  			l->complex = l->right->complex;
   216  			l->type = l->left->type;
   217  			n->op = OADDR;
   218  			n->left = l;
   219  			n->right = Z;
   220  			n->addable = 8;
   221  			break;
   222  		}
   223  		break;
   224  
   225  	case OINDEX:
   226  		xcom(l);
   227  		xcom(r);
   228  		n->addable = 9;
   229  		break;
   230  
   231  	case OIND:
   232  		xcom(l);
   233  		if(l->op == OADDR) {
   234  			l = l->left;
   235  			l->type = n->type;
   236  			*n = *l;
   237  			return;
   238  		}
   239  		switch(l->addable) {
   240  		case 20:
   241  			n->addable = 21;
   242  			break;
   243  		case 1:
   244  			n->addable = 11;
   245  			break;
   246  		case 13:
   247  			n->addable = 10;
   248  			break;
   249  		}
   250  		break;
   251  
   252  	case OASHL:
   253  		xcom(l);
   254  		xcom(r);
   255  		indexshift(n);
   256  		break;
   257  
   258  	case OMUL:
   259  	case OLMUL:
   260  		xcom(l);
   261  		xcom(r);
   262  		g = vlog(l);
   263  		if(g >= 0) {
   264  			n->left = r;
   265  			n->right = l;
   266  			l = r;
   267  			r = n->right;
   268  		}
   269  		g = vlog(r);
   270  		if(g >= 0) {
   271  			n->op = OASHL;
   272  			r->vconst = g;
   273  			r->type = types[TINT];
   274  			indexshift(n);
   275  			break;
   276  		}
   277  		commute(n);
   278  		break;
   279  
   280  	case OASLDIV:
   281  		xcom(l);
   282  		xcom(r);
   283  		g = vlog(r);
   284  		if(g >= 0) {
   285  			n->op = OASLSHR;
   286  			r->vconst = g;
   287  			r->type = types[TINT];
   288  		}
   289  		break;
   290  
   291  	case OLDIV:
   292  		xcom(l);
   293  		xcom(r);
   294  		g = vlog(r);
   295  		if(g >= 0) {
   296  			n->op = OLSHR;
   297  			r->vconst = g;
   298  			r->type = types[TINT];
   299  			indexshift(n);
   300  			break;
   301  		}
   302  		break;
   303  
   304  	case OASLMOD:
   305  		xcom(l);
   306  		xcom(r);
   307  		g = vlog(r);
   308  		if(g >= 0) {
   309  			n->op = OASAND;
   310  			r->vconst--;
   311  		}
   312  		break;
   313  
   314  	case OLMOD:
   315  		xcom(l);
   316  		xcom(r);
   317  		g = vlog(r);
   318  		if(g >= 0) {
   319  			n->op = OAND;
   320  			r->vconst--;
   321  		}
   322  		break;
   323  
   324  	case OASMUL:
   325  	case OASLMUL:
   326  		xcom(l);
   327  		xcom(r);
   328  		g = vlog(r);
   329  		if(g >= 0) {
   330  			n->op = OASASHL;
   331  			r->vconst = g;
   332  		}
   333  		break;
   334  
   335  	case OLSHR:
   336  	case OASHR:
   337  		xcom(l);
   338  		xcom(r);
   339  		indexshift(n);
   340  		break;
   341  
   342  	default:
   343  		if(l != Z)
   344  			xcom(l);
   345  		if(r != Z)
   346  			xcom(r);
   347  		break;
   348  	}
   349  brk:
   350  	if(n->addable >= 10)
   351  		return;
   352  	if(l != Z)
   353  		n->complex = l->complex;
   354  	if(r != Z) {
   355  		if(r->complex == n->complex)
   356  			n->complex = r->complex+1;
   357  		else
   358  		if(r->complex > n->complex)
   359  			n->complex = r->complex;
   360  	}
   361  	if(n->complex == 0)
   362  		n->complex++;
   363  
   364  	switch(n->op) {
   365  
   366  	case OFUNC:
   367  		n->complex = FNX;
   368  		break;
   369  
   370  	case OCAST:
   371  		if(l->type->etype == TUVLONG && typefd[n->type->etype])
   372  			n->complex += 2;
   373  		break;
   374  
   375  	case OLMOD:
   376  	case OMOD:
   377  	case OLMUL:
   378  	case OLDIV:
   379  	case OMUL:
   380  	case ODIV:
   381  	case OASLMUL:
   382  	case OASLDIV:
   383  	case OASLMOD:
   384  	case OASMUL:
   385  	case OASDIV:
   386  	case OASMOD:
   387  		if(r->complex >= l->complex) {
   388  			n->complex = l->complex + 3;
   389  			if(r->complex > n->complex)
   390  				n->complex = r->complex;
   391  		} else {
   392  			n->complex = r->complex + 3;
   393  			if(l->complex > n->complex)
   394  				n->complex = l->complex;
   395  		}
   396  		break;
   397  
   398  	case OLSHR:
   399  	case OASHL:
   400  	case OASHR:
   401  	case OASLSHR:
   402  	case OASASHL:
   403  	case OASASHR:
   404  		if(r->complex >= l->complex) {
   405  			n->complex = l->complex + 2;
   406  			if(r->complex > n->complex)
   407  				n->complex = r->complex;
   408  		} else {
   409  			n->complex = r->complex + 2;
   410  			if(l->complex > n->complex)
   411  				n->complex = l->complex;
   412  		}
   413  		break;
   414  
   415  	case OADD:
   416  	case OXOR:
   417  	case OAND:
   418  	case OOR:
   419  		/*
   420  		 * immediate operators, make const on right
   421  		 */
   422  		if(l->op == OCONST) {
   423  			n->left = r;
   424  			n->right = l;
   425  		}
   426  		break;
   427  
   428  	case OEQ:
   429  	case ONE:
   430  	case OLE:
   431  	case OLT:
   432  	case OGE:
   433  	case OGT:
   434  	case OHI:
   435  	case OHS:
   436  	case OLO:
   437  	case OLS:
   438  		/*
   439  		 * compare operators, make const on left
   440  		 */
   441  		if(r->op == OCONST) {
   442  			n->left = r;
   443  			n->right = l;
   444  			n->op = invrel[relindex(n->op)];
   445  		}
   446  		break;
   447  	}
   448  }
   449  
   450  void
   451  indx(Node *n)
   452  {
   453  	Node *l, *r;
   454  
   455  	if(debug['x'])
   456  		prtree(n, "indx");
   457  
   458  	l = n->left;
   459  	r = n->right;
   460  	if(l->addable == 1 || l->addable == 13 || r->complex > l->complex) {
   461  		n->right = l;
   462  		n->left = r;
   463  		l = r;
   464  		r = n->right;
   465  	}
   466  	if(l->addable != 7) {
   467  		idx.regtree = l;
   468  		idx.scale = 1;
   469  	} else
   470  	if(l->right->addable == 20) {
   471  		idx.regtree = l->left;
   472  		idx.scale = 1 << l->right->vconst;
   473  	} else
   474  	if(l->left->addable == 20) {
   475  		idx.regtree = l->right;
   476  		idx.scale = 1 << l->left->vconst;
   477  	} else
   478  		diag(n, "bad index");
   479  
   480  	idx.basetree = r;
   481  	if(debug['x']) {
   482  		print("scale = %d\n", idx.scale);
   483  		prtree(idx.regtree, "index");
   484  		prtree(idx.basetree, "base");
   485  	}
   486  }