github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/cc/com64.c (about)

     1  // Inferno utils/cc/com64.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/cc/com64.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  /*
    35   * this is machine depend, but it is totally
    36   * common on all of the 64-bit symulating machines.
    37   */
    38  
    39  #define	FNX	100	/* botch -- redefinition */
    40  
    41  Node*	nodaddv;
    42  Node*	nodsubv;
    43  Node*	nodmulv;
    44  Node*	noddivv;
    45  Node*	noddivvu;
    46  Node*	nodmodv;
    47  Node*	nodmodvu;
    48  Node*	nodlshv;
    49  Node*	nodrshav;
    50  Node*	nodrshlv;
    51  Node*	nodandv;
    52  Node*	nodorv;
    53  Node*	nodxorv;
    54  Node*	nodnegv;
    55  Node*	nodcomv;
    56  
    57  Node*	nodtestv;
    58  Node*	nodeqv;
    59  Node*	nodnev;
    60  Node*	nodlev;
    61  Node*	nodltv;
    62  Node*	nodgev;
    63  Node*	nodgtv;
    64  Node*	nodhiv;
    65  Node*	nodhsv;
    66  Node*	nodlov;
    67  Node*	nodlsv;
    68  
    69  Node*	nodf2v;
    70  Node*	nodd2v;
    71  Node*	nodp2v;
    72  Node*	nodsi2v;
    73  Node*	nodui2v;
    74  Node*	nodsl2v;
    75  Node*	nodul2v;
    76  Node*	nodsh2v;
    77  Node*	noduh2v;
    78  Node*	nodsc2v;
    79  Node*	noduc2v;
    80  
    81  Node*	nodv2f;
    82  Node*	nodv2d;
    83  Node*	nodv2ui;
    84  Node*	nodv2si;
    85  Node*	nodv2ul;
    86  Node*	nodv2sl;
    87  Node*	nodv2uh;
    88  Node*	nodv2sh;
    89  Node*	nodv2uc;
    90  Node*	nodv2sc;
    91  
    92  Node*	nodvpp;
    93  Node*	nodppv;
    94  Node*	nodvmm;
    95  Node*	nodmmv;
    96  
    97  Node*	nodvasop;
    98  
    99  char	etconv[NALLTYPES];	/* for _vasop */
   100  Init	initetconv[] =
   101  {
   102  	TCHAR,		1,	0,
   103  	TUCHAR,		2,	0,
   104  	TSHORT,		3,	0,
   105  	TUSHORT,	4,	0,
   106  	TLONG,		5,	0,
   107  	TULONG,		6,	0,
   108  	TVLONG,		7,	0,
   109  	TUVLONG,	8,	0,
   110  	TINT,		9,	0,
   111  	TUINT,		10,	0,
   112  	-1,		0,	0,
   113  };
   114  
   115  Node*
   116  fvn(char *name, int type)
   117  {
   118  	Node *n;
   119  
   120  	n = new(ONAME, Z, Z);
   121  	n->sym = slookup(name);
   122  	n->sym->sig = SIGINTERN;
   123  	if(fntypes[type] == 0)
   124  		fntypes[type] = typ(TFUNC, types[type]);
   125  	n->type = fntypes[type];
   126  	n->etype = type;
   127  	n->class = CGLOBL;
   128  	n->addable = 10;
   129  	n->complex = 0;
   130  	return n;
   131  }
   132  
   133  void
   134  com64init(void)
   135  {
   136  	Init *p;
   137  
   138  	nodaddv = fvn("_addv", TVLONG);
   139  	nodsubv = fvn("_subv", TVLONG);
   140  	nodmulv = fvn("_mulv", TVLONG);
   141  	noddivv = fvn("_divv", TVLONG);
   142  	noddivvu = fvn("_divvu", TVLONG);
   143  	nodmodv = fvn("_modv", TVLONG);
   144  	nodmodvu = fvn("_modvu", TVLONG);
   145  	nodlshv = fvn("_lshv", TVLONG);
   146  	nodrshav = fvn("_rshav", TVLONG);
   147  	nodrshlv = fvn("_rshlv", TVLONG);
   148  	nodandv = fvn("_andv", TVLONG);
   149  	nodorv = fvn("_orv", TVLONG);
   150  	nodxorv = fvn("_xorv", TVLONG);
   151  	nodnegv = fvn("_negv", TVLONG);
   152  	nodcomv = fvn("_comv", TVLONG);
   153  
   154  	nodtestv = fvn("_testv", TLONG);
   155  	nodeqv = fvn("_eqv", TLONG);
   156  	nodnev = fvn("_nev", TLONG);
   157  	nodlev = fvn("_lev", TLONG);
   158  	nodltv = fvn("_ltv", TLONG);
   159  	nodgev = fvn("_gev", TLONG);
   160  	nodgtv = fvn("_gtv", TLONG);
   161  	nodhiv = fvn("_hiv", TLONG);
   162  	nodhsv = fvn("_hsv", TLONG);
   163  	nodlov = fvn("_lov", TLONG);
   164  	nodlsv = fvn("_lsv", TLONG);
   165  
   166  	nodf2v = fvn("_f2v", TVLONG);
   167  	nodd2v = fvn("_d2v", TVLONG);
   168  	nodp2v = fvn("_p2v", TVLONG);
   169  	nodsi2v = fvn("_si2v", TVLONG);
   170  	nodui2v = fvn("_ui2v", TVLONG);
   171  	nodsl2v = fvn("_sl2v", TVLONG);
   172  	nodul2v = fvn("_ul2v", TVLONG);
   173  	nodsh2v = fvn("_sh2v", TVLONG);
   174  	noduh2v = fvn("_uh2v", TVLONG);
   175  	nodsc2v = fvn("_sc2v", TVLONG);
   176  	noduc2v = fvn("_uc2v", TVLONG);
   177  
   178  	nodv2f = fvn("_v2f", TFLOAT);
   179  	nodv2d = fvn("_v2d", TDOUBLE);
   180  	nodv2sl = fvn("_v2sl", TLONG);
   181  	nodv2ul = fvn("_v2ul", TULONG);
   182  	nodv2si = fvn("_v2si", TINT);
   183  	nodv2ui = fvn("_v2ui", TUINT);
   184  	nodv2sh = fvn("_v2sh", TSHORT);
   185  	nodv2uh = fvn("_v2ul", TUSHORT);
   186  	nodv2sc = fvn("_v2sc", TCHAR);
   187  	nodv2uc = fvn("_v2uc", TUCHAR);
   188  
   189  	nodvpp = fvn("_vpp", TVLONG);
   190  	nodppv = fvn("_ppv", TVLONG);
   191  	nodvmm = fvn("_vmm", TVLONG);
   192  	nodmmv = fvn("_mmv", TVLONG);
   193  
   194  	nodvasop = fvn("_vasop", TVLONG);
   195  
   196  	for(p = initetconv; p->code >= 0; p++)
   197  		etconv[p->code] = p->value;
   198  }
   199  
   200  int
   201  com64(Node *n)
   202  {
   203  	Node *l, *r, *a, *t;
   204  	int lv, rv;
   205  
   206  	if(n->type == 0)
   207  		return 0;
   208  
   209  	l = n->left;
   210  	r = n->right;
   211  
   212  	lv = 0;
   213  	if(l && l->type && typev[l->type->etype])
   214  		lv = 1;
   215  	rv = 0;
   216  	if(r && r->type && typev[r->type->etype])
   217  		rv = 1;
   218  
   219  	if(lv) {
   220  		switch(n->op) {
   221  		case OEQ:
   222  			a = nodeqv;
   223  			goto setbool;
   224  		case ONE:
   225  			a = nodnev;
   226  			goto setbool;
   227  		case OLE:
   228  			a = nodlev;
   229  			goto setbool;
   230  		case OLT:
   231  			a = nodltv;
   232  			goto setbool;
   233  		case OGE:
   234  			a = nodgev;
   235  			goto setbool;
   236  		case OGT:
   237  			a = nodgtv;
   238  			goto setbool;
   239  		case OHI:
   240  			a = nodhiv;
   241  			goto setbool;
   242  		case OHS:
   243  			a = nodhsv;
   244  			goto setbool;
   245  		case OLO:
   246  			a = nodlov;
   247  			goto setbool;
   248  		case OLS:
   249  			a = nodlsv;
   250  			goto setbool;
   251  
   252  		case OANDAND:
   253  		case OOROR:
   254  			if(machcap(n))
   255  				return 1;
   256  
   257  			if(rv) {
   258  				r = new(OFUNC, nodtestv, r);
   259  				n->right = r;
   260  				r->complex = FNX;
   261  				r->op = OFUNC;
   262  				r->type = types[TLONG];
   263  			}
   264  
   265  		case OCOND:
   266  		case ONOT:
   267  			if(machcap(n))
   268  				return 1;
   269  
   270  			l = new(OFUNC, nodtestv, l);
   271  			n->left = l;
   272  			l->complex = FNX;
   273  			l->op = OFUNC;
   274  			l->type = types[TLONG];
   275  			n->complex = FNX;
   276  			return 1;
   277  		}
   278  	}
   279  
   280  	if(rv) {
   281  		if(machcap(n))
   282  			return 1;
   283  		switch(n->op) {
   284  		case OANDAND:
   285  		case OOROR:
   286  			r = new(OFUNC, nodtestv, r);
   287  			n->right = r;
   288  			r->complex = FNX;
   289  			r->op = OFUNC;
   290  			r->type = types[TLONG];
   291  			return 1;
   292  		}
   293  	}
   294  
   295  	if(typev[n->type->etype]) {
   296  		if(machcap(n))
   297  			return 1;
   298  		switch(n->op) {
   299  		default:
   300  			diag(n, "unknown vlong %O", n->op);
   301  		case OFUNC:
   302  			n->complex = FNX;
   303  		case ORETURN:
   304  		case OAS:
   305  		case OIND:
   306  			return 1;
   307  		case OADD:
   308  			a = nodaddv;
   309  			goto setbop;
   310  		case OSUB:
   311  			a = nodsubv;
   312  			goto setbop;
   313  		case OMUL:
   314  		case OLMUL:
   315  			a = nodmulv;
   316  			goto setbop;
   317  		case ODIV:
   318  			a = noddivv;
   319  			goto setbop;
   320  		case OLDIV:
   321  			a = noddivvu;
   322  			goto setbop;
   323  		case OMOD:
   324  			a = nodmodv;
   325  			goto setbop;
   326  		case OLMOD:
   327  			a = nodmodvu;
   328  			goto setbop;
   329  		case OASHL:
   330  			a = nodlshv;
   331  			goto setbop;
   332  		case OASHR:
   333  			a = nodrshav;
   334  			goto setbop;
   335  		case OLSHR:
   336  			a = nodrshlv;
   337  			goto setbop;
   338  		case OAND:
   339  			a = nodandv;
   340  			goto setbop;
   341  		case OOR:
   342  			a = nodorv;
   343  			goto setbop;
   344  		case OXOR:
   345  			a = nodxorv;
   346  			goto setbop;
   347  		case OPOSTINC:
   348  			a = nodvpp;
   349  			goto setvinc;
   350  		case OPOSTDEC:
   351  			a = nodvmm;
   352  			goto setvinc;
   353  		case OPREINC:
   354  			a = nodppv;
   355  			goto setvinc;
   356  		case OPREDEC:
   357  			a = nodmmv;
   358  			goto setvinc;
   359  		case ONEG:
   360  			a = nodnegv;
   361  			goto setfnx;
   362  		case OCOM:
   363  			a = nodcomv;
   364  			goto setfnx;
   365  		case OCAST:
   366  			switch(l->type->etype) {
   367  			case TCHAR:
   368  				a = nodsc2v;
   369  				goto setfnxl;
   370  			case TUCHAR:
   371  				a = noduc2v;
   372  				goto setfnxl;
   373  			case TSHORT:
   374  				a = nodsh2v;
   375  				goto setfnxl;
   376  			case TUSHORT:
   377  				a = noduh2v;
   378  				goto setfnxl;
   379  			case TINT:
   380  				a = nodsi2v;
   381  				goto setfnx;
   382  			case TUINT:
   383  				a = nodui2v;
   384  				goto setfnx;
   385  			case TLONG:
   386  				a = nodsl2v;
   387  				goto setfnx;
   388  			case TULONG:
   389  				a = nodul2v;
   390  				goto setfnx;
   391  			case TFLOAT:
   392  				a = nodf2v;
   393  				goto setfnx;
   394  			case TDOUBLE:
   395  				a = nodd2v;
   396  				goto setfnx;
   397  			case TIND:
   398  				a = nodp2v;
   399  				goto setfnx;
   400  			}
   401  			diag(n, "unknown %T->vlong cast", l->type);
   402  			return 1;
   403  		case OASADD:
   404  			a = nodaddv;
   405  			goto setasop;
   406  		case OASSUB:
   407  			a = nodsubv;
   408  			goto setasop;
   409  		case OASMUL:
   410  		case OASLMUL:
   411  			a = nodmulv;
   412  			goto setasop;
   413  		case OASDIV:
   414  			a = noddivv;
   415  			goto setasop;
   416  		case OASLDIV:
   417  			a = noddivvu;
   418  			goto setasop;
   419  		case OASMOD:
   420  			a = nodmodv;
   421  			goto setasop;
   422  		case OASLMOD:
   423  			a = nodmodvu;
   424  			goto setasop;
   425  		case OASASHL:
   426  			a = nodlshv;
   427  			goto setasop;
   428  		case OASASHR:
   429  			a = nodrshav;
   430  			goto setasop;
   431  		case OASLSHR:
   432  			a = nodrshlv;
   433  			goto setasop;
   434  		case OASAND:
   435  			a = nodandv;
   436  			goto setasop;
   437  		case OASOR:
   438  			a = nodorv;
   439  			goto setasop;
   440  		case OASXOR:
   441  			a = nodxorv;
   442  			goto setasop;
   443  		}
   444  	}
   445  
   446  	if(typefd[n->type->etype] && l && l->op == OFUNC) {
   447  		switch(n->op) {
   448  		case OASADD:
   449  		case OASSUB:
   450  		case OASMUL:
   451  		case OASLMUL:
   452  		case OASDIV:
   453  		case OASLDIV:
   454  		case OASMOD:
   455  		case OASLMOD:
   456  		case OASASHL:
   457  		case OASASHR:
   458  		case OASLSHR:
   459  		case OASAND:
   460  		case OASOR:
   461  		case OASXOR:
   462  			if(l->right && typev[l->right->etype]) {
   463  				diag(n, "sorry float <asop> vlong not implemented\n");
   464  			}
   465  		}
   466  	}
   467  
   468  	if(n->op == OCAST) {
   469  		if(l->type && typev[l->type->etype]) {
   470  			if(machcap(n))
   471  				return 1;
   472  			switch(n->type->etype) {
   473  			case TDOUBLE:
   474  				a = nodv2d;
   475  				goto setfnx;
   476  			case TFLOAT:
   477  				a = nodv2f;
   478  				goto setfnx;
   479  			case TLONG:
   480  				a = nodv2sl;
   481  				goto setfnx;
   482  			case TULONG:
   483  				a = nodv2ul;
   484  				goto setfnx;
   485  			case TINT:
   486  				a = nodv2si;
   487  				goto setfnx;
   488  			case TUINT:
   489  				a = nodv2ui;
   490  				goto setfnx;
   491  			case TSHORT:
   492  				a = nodv2sh;
   493  				goto setfnx;
   494  			case TUSHORT:
   495  				a = nodv2uh;
   496  				goto setfnx;
   497  			case TCHAR:
   498  				a = nodv2sc;
   499  				goto setfnx;
   500  			case TUCHAR:
   501  				a = nodv2uc;
   502  				goto setfnx;
   503  			case TIND:	// small pun here
   504  				a = nodv2ul;
   505  				goto setfnx;
   506  			}
   507  			diag(n, "unknown vlong->%T cast", n->type);
   508  			return 1;
   509  		}
   510  	}
   511  
   512  	return 0;
   513  
   514  setbop:
   515  	n->left = a;
   516  	n->right = new(OLIST, l, r);
   517  	n->complex = FNX;
   518  	n->op = OFUNC;
   519  	return 1;
   520  
   521  setfnxl:
   522  	l = new(OCAST, l, 0);
   523  	l->type = types[TLONG];
   524  	l->complex = l->left->complex;
   525  
   526  setfnx:
   527  	n->left = a;
   528  	n->right = l;
   529  	n->complex = FNX;
   530  	n->op = OFUNC;
   531  	return 1;
   532  
   533  setvinc:
   534  	n->left = a;
   535  	l = new(OADDR, l, Z);
   536  	l->type = typ(TIND, l->left->type);
   537  	n->right = new(OLIST, l, r);
   538  	n->complex = FNX;
   539  	n->op = OFUNC;
   540  	return 1;
   541  
   542  setbool:
   543  	if(machcap(n))
   544  		return 1;
   545  	n->left = a;
   546  	n->right = new(OLIST, l, r);
   547  	n->complex = FNX;
   548  	n->op = OFUNC;
   549  	n->type = types[TLONG];
   550  	return 1;
   551  
   552  setasop:
   553  	if(l->op == OFUNC) {
   554  		l = l->right;
   555  		goto setasop;
   556  	}
   557  
   558  	t = new(OCONST, 0, 0);
   559  	t->vconst = etconv[l->type->etype];
   560  	t->type = types[TLONG];
   561  	t->addable = 20;
   562  	r = new(OLIST, t, r);
   563  
   564  	t = new(OADDR, a, 0);
   565  	t->type = typ(TIND, a->type);
   566  	r = new(OLIST, t, r);
   567  
   568  	t = new(OADDR, l, 0);
   569  	t->type = typ(TIND, l->type);
   570  	r = new(OLIST, t, r);
   571  
   572  	n->left = nodvasop;
   573  	n->right = r;
   574  	n->complex = FNX;
   575  	n->op = OFUNC;
   576  
   577  	return 1;
   578  }
   579  
   580  void
   581  bool64(Node *n)
   582  {
   583  	Node *n1;
   584  
   585  	if(machcap(Z))
   586  		return;
   587  	if(typev[n->type->etype]) {
   588  		n1 = new(OXXX, 0, 0);
   589  		*n1 = *n;
   590  
   591  		n->right = n1;
   592  		n->left = nodtestv;
   593  		n->complex = FNX;
   594  		n->addable = 0;
   595  		n->op = OFUNC;
   596  		n->type = types[TLONG];
   597  	}
   598  }
   599  
   600  /*
   601   * more machine depend stuff.
   602   * this is common for 8,16,32,64 bit machines.
   603   * this is common for ieee machines.
   604   */
   605  double
   606  convvtof(vlong v)
   607  {
   608  	double d;
   609  
   610  	d = v;		/* BOTCH */
   611  	return d;
   612  }
   613  
   614  vlong
   615  convftov(double d)
   616  {
   617  	vlong v;
   618  
   619  
   620  	v = d;		/* BOTCH */
   621  	return v;
   622  }
   623  
   624  double
   625  convftox(double d, int et)
   626  {
   627  
   628  	if(!typefd[et])
   629  		diag(Z, "bad type in castftox %s", tnames[et]);
   630  	return d;
   631  }
   632  
   633  vlong
   634  convvtox(vlong c, int et)
   635  {
   636  	int n;
   637  
   638  	n = 8 * ewidth[et];
   639  	c &= MASK(n);
   640  	if(!typeu[et])
   641  		if(c & SIGN(n))
   642  			c |= ~MASK(n);
   643  	return c;
   644  }