github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/5c/sgen.c (about)

     1  // Inferno utils/5c/sgen.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/5c/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  
    32  #include "gc.h"
    33  
    34  Prog*
    35  gtext(Sym *s, int32 stkoff)
    36  {
    37  	int32 a;
    38  	
    39  	a = 0;
    40  	if(!(textflag & NOSPLIT))
    41  		a = argsize();
    42  	else if(stkoff >= 128)
    43  		yyerror("stack frame too large for NOSPLIT function");
    44  
    45  	gpseudo(ATEXT, s, nodconst(stkoff));
    46  	p->to.type = D_CONST2;
    47  	p->to.offset2 = a;
    48  	return p;
    49  }
    50  
    51  void
    52  noretval(int n)
    53  {
    54  
    55  	if(n & 1) {
    56  		gins(ANOP, Z, Z);
    57  		p->to.type = D_REG;
    58  		p->to.reg = REGRET;
    59  	}
    60  	if(n & 2) {
    61  		gins(ANOP, Z, Z);
    62  		p->to.type = D_FREG;
    63  		p->to.reg = FREGRET;
    64  	}
    65  }
    66  
    67  /*
    68   *	calculate addressability as follows
    69   *		CONST ==> 20		$value
    70   *		NAME ==> 10		name
    71   *		REGISTER ==> 11		register
    72   *		INDREG ==> 12		*[(reg)+offset]
    73   *		&10 ==> 2		$name
    74   *		ADD(2, 20) ==> 2	$name+offset
    75   *		ADD(3, 20) ==> 3	$(reg)+offset
    76   *		&12 ==> 3		$(reg)+offset
    77   *		*11 ==> 11		??
    78   *		*2 ==> 10		name
    79   *		*3 ==> 12		*(reg)+offset
    80   *	calculate complexity (number of registers)
    81   */
    82  void
    83  xcom(Node *n)
    84  {
    85  	Node *l, *r;
    86  	int t;
    87  
    88  	if(n == Z)
    89  		return;
    90  	l = n->left;
    91  	r = n->right;
    92  	n->addable = 0;
    93  	n->complex = 0;
    94  	switch(n->op) {
    95  	case OCONST:
    96  		n->addable = 20;
    97  		return;
    98  
    99  	case OREGISTER:
   100  		n->addable = 11;
   101  		return;
   102  
   103  	case OINDREG:
   104  		n->addable = 12;
   105  		return;
   106  
   107  	case ONAME:
   108  		n->addable = 10;
   109  		return;
   110  
   111  	case OADDR:
   112  		xcom(l);
   113  		if(l->addable == 10)
   114  			n->addable = 2;
   115  		if(l->addable == 12)
   116  			n->addable = 3;
   117  		break;
   118  
   119  	case OIND:
   120  		xcom(l);
   121  		if(l->addable == 11)
   122  			n->addable = 12;
   123  		if(l->addable == 3)
   124  			n->addable = 12;
   125  		if(l->addable == 2)
   126  			n->addable = 10;
   127  		break;
   128  
   129  	case OADD:
   130  		xcom(l);
   131  		xcom(r);
   132  		if(l->addable == 20) {
   133  			if(r->addable == 2)
   134  				n->addable = 2;
   135  			if(r->addable == 3)
   136  				n->addable = 3;
   137  		}
   138  		if(r->addable == 20) {
   139  			if(l->addable == 2)
   140  				n->addable = 2;
   141  			if(l->addable == 3)
   142  				n->addable = 3;
   143  		}
   144  		break;
   145  
   146  	case OASLMUL:
   147  	case OASMUL:
   148  		xcom(l);
   149  		xcom(r);
   150  		t = vlog(r);
   151  		if(t >= 0) {
   152  			n->op = OASASHL;
   153  			r->vconst = t;
   154  			r->type = types[TINT];
   155  		}
   156  		break;
   157  
   158  	case OMUL:
   159  	case OLMUL:
   160  		xcom(l);
   161  		xcom(r);
   162  		t = vlog(r);
   163  		if(t >= 0) {
   164  			n->op = OASHL;
   165  			r->vconst = t;
   166  			r->type = types[TINT];
   167  		}
   168  		t = vlog(l);
   169  		if(t >= 0) {
   170  			n->op = OASHL;
   171  			n->left = r;
   172  			n->right = l;
   173  			r = l;
   174  			l = n->left;
   175  			r->vconst = t;
   176  			r->type = types[TINT];
   177  		}
   178  		break;
   179  
   180  	case OASLDIV:
   181  		xcom(l);
   182  		xcom(r);
   183  		t = vlog(r);
   184  		if(t >= 0) {
   185  			n->op = OASLSHR;
   186  			r->vconst = t;
   187  			r->type = types[TINT];
   188  		}
   189  		break;
   190  
   191  	case OLDIV:
   192  		xcom(l);
   193  		xcom(r);
   194  		t = vlog(r);
   195  		if(t >= 0) {
   196  			n->op = OLSHR;
   197  			r->vconst = t;
   198  			r->type = types[TINT];
   199  		}
   200  		break;
   201  
   202  	case OASLMOD:
   203  		xcom(l);
   204  		xcom(r);
   205  		t = vlog(r);
   206  		if(t >= 0) {
   207  			n->op = OASAND;
   208  			r->vconst--;
   209  		}
   210  		break;
   211  
   212  	case OLMOD:
   213  		xcom(l);
   214  		xcom(r);
   215  		t = vlog(r);
   216  		if(t >= 0) {
   217  			n->op = OAND;
   218  			r->vconst--;
   219  		}
   220  		break;
   221  
   222  	default:
   223  		if(l != Z)
   224  			xcom(l);
   225  		if(r != Z)
   226  			xcom(r);
   227  		break;
   228  	}
   229  	if(n->addable >= 10)
   230  		return;
   231  
   232  	if(l != Z)
   233  		n->complex = l->complex;
   234  	if(r != Z) {
   235  		if(r->complex == n->complex)
   236  			n->complex = r->complex+1;
   237  		else
   238  		if(r->complex > n->complex)
   239  			n->complex = r->complex;
   240  	}
   241  	if(n->complex == 0)
   242  		n->complex++;
   243  
   244  	if(com64(n))
   245  		return;
   246  
   247  	switch(n->op) {
   248  	case OFUNC:
   249  		n->complex = FNX;
   250  		break;
   251  
   252  	case OADD:
   253  	case OXOR:
   254  	case OAND:
   255  	case OOR:
   256  	case OEQ:
   257  	case ONE:
   258  		/*
   259  		 * immediate operators, make const on right
   260  		 */
   261  		if(l->op == OCONST) {
   262  			n->left = r;
   263  			n->right = l;
   264  		}
   265  		break;
   266  	}
   267  }