github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/cmd/cc/funct.c (about)

     1  // Inferno utils/cc/funct.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/cc/funct.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	<u.h>
    32  #include	"cc.h"
    33  
    34  typedef	struct	Ftab	Ftab;
    35  struct	Ftab
    36  {
    37  	char	op;
    38  	char*	name;
    39  	char	typ;
    40  };
    41  typedef	struct	Gtab	Gtab;
    42  struct	Gtab
    43  {
    44  	char	etype;
    45  	char*	name;
    46  };
    47  
    48  Ftab	ftabinit[OEND];
    49  Gtab	gtabinit[NALLTYPES];
    50  
    51  int
    52  isfunct(Node *n)
    53  {
    54  	Type *t, *t1;
    55  	Funct *f;
    56  	Node *l;
    57  	Sym *s;
    58  	int o;
    59  
    60  	o = n->op;
    61  	if(n->left == Z)
    62  		goto no;
    63  	t = n->left->type;
    64  	if(t == T)
    65  		goto no;
    66  	f = t->funct;
    67  
    68  	switch(o) {
    69  	case OAS:	// put cast on rhs
    70  	case OASI:
    71  	case OASADD:
    72  	case OASAND:
    73  	case OASASHL:
    74  	case OASASHR:
    75  	case OASDIV:
    76  	case OASLDIV:
    77  	case OASLMOD:
    78  	case OASLMUL:
    79  	case OASLSHR:
    80  	case OASMOD:
    81  	case OASMUL:
    82  	case OASOR:
    83  	case OASSUB:
    84  	case OASXOR:
    85  		if(n->right == Z)
    86  			goto no;
    87  		t1 = n->right->type;
    88  		if(t1 == T)
    89  			goto no;
    90  		if(t1->funct == f)
    91  			break;
    92  
    93  		l = new(OXXX, Z, Z);
    94  		*l = *n->right;
    95  
    96  		n->right->left = l;
    97  		n->right->right = Z;
    98  		n->right->type = t;
    99  		n->right->op = OCAST;
   100  
   101  		if(!isfunct(n->right))
   102  			prtree(n, "isfunc !");
   103  		break;
   104  
   105  	case OCAST:	// t f(T) or T f(t)
   106  		t1 = n->type;
   107  		if(t1 == T)
   108  			goto no;
   109  		if(f != nil) {
   110  			s = f->castfr[t1->etype];
   111  			if(s == S)
   112  				goto no;
   113  			n->right = n->left;
   114  			goto build;
   115  		}
   116  		f = t1->funct;
   117  		if(f != nil) {
   118  			s = f->castto[t->etype];
   119  			if(s == S)
   120  				goto no;
   121  			n->right = n->left;
   122  			goto build;
   123  		}
   124  		goto no;
   125  	}
   126  
   127  	if(f == nil)
   128  		goto no;
   129  	s = f->sym[o];
   130  	if(s == S)
   131  		goto no;
   132  
   133  	/*
   134  	 * the answer is yes,
   135  	 * now we rewrite the node
   136  	 * and give diagnostics
   137  	 */
   138  	switch(o) {
   139  	default:
   140  		diag(n, "isfunct op missing %O\n", o);
   141  		goto bad;
   142  
   143  	case OADD:	// T f(T, T)
   144  	case OAND:
   145  	case OASHL:
   146  	case OASHR:
   147  	case ODIV:
   148  	case OLDIV:
   149  	case OLMOD:
   150  	case OLMUL:
   151  	case OLSHR:
   152  	case OMOD:
   153  	case OMUL:
   154  	case OOR:
   155  	case OSUB:
   156  	case OXOR:
   157  
   158  	case OEQ:	// int f(T, T)
   159  	case OGE:
   160  	case OGT:
   161  	case OHI:
   162  	case OHS:
   163  	case OLE:
   164  	case OLO:
   165  	case OLS:
   166  	case OLT:
   167  	case ONE:
   168  		if(n->right == Z)
   169  			goto bad;
   170  		t1 = n->right->type;
   171  		if(t1 == T)
   172  			goto bad;
   173  		if(t1->funct != f)
   174  			goto bad;
   175  		n->right = new(OLIST, n->left, n->right);
   176  		break;
   177  
   178  	case OAS:	// structure copies done by the compiler
   179  	case OASI:
   180  		goto no;
   181  
   182  	case OASADD:	// T f(T*, T)
   183  	case OASAND:
   184  	case OASASHL:
   185  	case OASASHR:
   186  	case OASDIV:
   187  	case OASLDIV:
   188  	case OASLMOD:
   189  	case OASLMUL:
   190  	case OASLSHR:
   191  	case OASMOD:
   192  	case OASMUL:
   193  	case OASOR:
   194  	case OASSUB:
   195  	case OASXOR:
   196  		if(n->right == Z)
   197  			goto bad;
   198  		t1 = n->right->type;
   199  		if(t1 == T)
   200  			goto bad;
   201  		if(t1->funct != f)
   202  			goto bad;
   203  		n->right = new(OLIST, new(OADDR, n->left, Z), n->right);
   204  		break;
   205  
   206  	case OPOS:	// T f(T)
   207  	case ONEG:
   208  	case ONOT:
   209  	case OCOM:
   210  		n->right = n->left;
   211  		break;
   212  
   213  
   214  	}
   215  
   216  build:
   217  	l = new(ONAME, Z, Z);
   218  	l->sym = s;
   219  	l->type = s->type;
   220  	l->etype = s->type->etype;
   221  	l->xoffset = s->offset;
   222  	l->class = s->class;
   223  	tcomo(l, 0);
   224  
   225  	n->op = OFUNC;
   226  	n->left = l;
   227  	n->type = l->type->link;
   228  	if(tcompat(n, T, l->type, tfunct))
   229  		goto bad;
   230  	if(tcoma(n->left, n->right, l->type->down, 1))
   231  		goto bad;
   232  	return 1;
   233  
   234  no:
   235  	return 0;
   236  
   237  bad:
   238  	diag(n, "can't rewrite typestr for op %O\n", o);
   239  	prtree(n, "isfunct");
   240  	n->type = T;
   241  	return 1;
   242  }
   243  
   244  void
   245  dclfunct(Type *t, Sym *s)
   246  {
   247  	Funct *f;
   248  	Node *n;
   249  	Type *f1, *f2, *f3, *f4;
   250  	int o, i, c;
   251  	char str[100];
   252  
   253  	if(t->funct)
   254  		return;
   255  
   256  	// recognize generated tag of dorm _%d_
   257  	if(t->tag == S)
   258  		goto bad;
   259  	for(i=0; c = t->tag->name[i]; i++) {
   260  		if(c == '_') {
   261  			if(i == 0 || t->tag->name[i+1] == 0)
   262  				continue;
   263  			break;
   264  		}
   265  		if(c < '0' || c > '9')
   266  			break;
   267  	}
   268  	if(c == 0)
   269  		goto bad;
   270  
   271  	f = alloc(sizeof(*f));
   272  	for(o=0; o<nelem(f->sym); o++)
   273  		f->sym[o] = S;
   274  
   275  	t->funct = f;
   276  
   277  	f1 = typ(TFUNC, t);
   278  	f1->down = copytyp(t);
   279  	f1->down->down = t;
   280  
   281  	f2 = typ(TFUNC, types[TINT]);
   282  	f2->down = copytyp(t);
   283  	f2->down->down = t;
   284  
   285  	f3 = typ(TFUNC, t);
   286  	f3->down = typ(TIND, t);
   287  	f3->down->down = t;
   288  
   289  	f4 = typ(TFUNC, t);
   290  	f4->down = t;
   291  
   292  	for(i=0;; i++) {
   293  		o = ftabinit[i].op;
   294  		if(o == OXXX)
   295  			break;
   296  		sprint(str, "%s_%s_", t->tag->name, ftabinit[i].name);
   297  		n = new(ONAME, Z, Z);
   298  		n->sym = slookup(str);
   299  		f->sym[o] = n->sym;
   300  		switch(ftabinit[i].typ) {
   301  		default:
   302  			diag(Z, "dclfunct op missing %d\n", ftabinit[i].typ);
   303  			break;
   304  
   305  		case 1:	// T f(T,T)	+
   306  			dodecl(xdecl, CEXTERN, f1, n);
   307  			break;
   308  
   309  		case 2:	// int f(T,T)	==
   310  			dodecl(xdecl, CEXTERN, f2, n);
   311  			break;
   312  
   313  		case 3:	// void f(T*,T)	+=
   314  			dodecl(xdecl, CEXTERN, f3, n);
   315  			break;
   316  
   317  		case 4:	// T f(T)	~
   318  			dodecl(xdecl, CEXTERN, f4, n);
   319  			break;
   320  		}
   321  	}
   322  	for(i=0;; i++) {
   323  		o = gtabinit[i].etype;
   324  		if(o == TXXX)
   325  			break;
   326  
   327  		/*
   328  		 * OCAST types T1 _T2_T1_(T2)
   329  		 */
   330  		sprint(str, "_%s%s_", gtabinit[i].name, t->tag->name);
   331  		n = new(ONAME, Z, Z);
   332  		n->sym = slookup(str);
   333  		f->castto[o] = n->sym;
   334  
   335  		f1 = typ(TFUNC, t);
   336  		f1->down = types[o];
   337  		dodecl(xdecl, CEXTERN, f1, n);
   338  
   339  		sprint(str, "%s_%s_", t->tag->name, gtabinit[i].name);
   340  		n = new(ONAME, Z, Z);
   341  		n->sym = slookup(str);
   342  		f->castfr[o] = n->sym;
   343  
   344  		f1 = typ(TFUNC, types[o]);
   345  		f1->down = t;
   346  		dodecl(xdecl, CEXTERN, f1, n);
   347  	}
   348  	return;
   349  bad:
   350  	diag(Z, "dclfunct bad %T %s\n", t, s->name);
   351  }
   352  
   353  Gtab	gtabinit[NALLTYPES] =
   354  {
   355  	TCHAR,		"c",
   356  	TUCHAR,		"uc",
   357  	TSHORT,		"h",
   358  	TUSHORT,	"uh",
   359  	TINT,		"i",
   360  	TUINT,		"ui",
   361  	TLONG,		"l",
   362  	TULONG,		"ul",
   363  	TVLONG,		"v",
   364  	TUVLONG,	"uv",
   365  	TFLOAT,		"f",
   366  	TDOUBLE,	"d",
   367  	TXXX
   368  };
   369  
   370  Ftab	ftabinit[OEND] =
   371  {
   372  	OADD,		"add",		1,
   373  	OAND,		"and",		1,
   374  	OASHL,		"ashl",		1,
   375  	OASHR,		"ashr",		1,
   376  	ODIV,		"div",		1,
   377  	OLDIV,		"ldiv",		1,
   378  	OLMOD,		"lmod",		1,
   379  	OLMUL,		"lmul",		1,
   380  	OLSHR,		"lshr",		1,
   381  	OMOD,		"mod",		1,
   382  	OMUL,		"mul",		1,
   383  	OOR,		"or",		1,
   384  	OSUB,		"sub",		1,
   385  	OXOR,		"xor",		1,
   386  
   387  	OEQ,		"eq",		2,
   388  	OGE,		"ge",		2,
   389  	OGT,		"gt",		2,
   390  	OHI,		"hi",		2,
   391  	OHS,		"hs",		2,
   392  	OLE,		"le",		2,
   393  	OLO,		"lo",		2,
   394  	OLS,		"ls",		2,
   395  	OLT,		"lt",		2,
   396  	ONE,		"ne",		2,
   397  
   398  	OASADD,		"asadd",	3,
   399  	OASAND,		"asand",	3,
   400  	OASASHL,	"asashl",	3,
   401  	OASASHR,	"asashr",	3,
   402  	OASDIV,		"asdiv",	3,
   403  	OASLDIV,	"asldiv",	3,
   404  	OASLMOD,	"aslmod",	3,
   405  	OASLMUL,	"aslmul",	3,
   406  	OASLSHR,	"aslshr",	3,
   407  	OASMOD,		"asmod",	3,
   408  	OASMUL,		"asmul",	3,
   409  	OASOR,		"asor",		3,
   410  	OASSUB,		"assub",	3,
   411  	OASXOR,		"asxor",	3,
   412  
   413  	OPOS,		"pos",		4,
   414  	ONEG,		"neg",		4,
   415  	OCOM,		"com",		4,
   416  	ONOT,		"not",		4,
   417  
   418  //	OPOSTDEC,
   419  //	OPOSTINC,
   420  //	OPREDEC,
   421  //	OPREINC,
   422  
   423  	OXXX,
   424  };
   425  
   426  //	Node*	nodtestv;
   427  
   428  //	Node*	nodvpp;
   429  //	Node*	nodppv;
   430  //	Node*	nodvmm;
   431  //	Node*	nodmmv;