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