github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/src/cmd/6a/a.y (about)

     1  // Inferno utils/6a/a.y
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6a/a.y
     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 <u.h>
    33  #include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
    34  #include <libc.h>
    35  #include "a.h"
    36  #include "../../runtime/funcdata.h"
    37  %}
    38  %union	{
    39  	Sym	*sym;
    40  	vlong	lval;
    41  	double	dval;
    42  	char	sval[8];
    43  	Addr	addr;
    44  	Addr2	addr2;
    45  }
    46  %left	'|'
    47  %left	'^'
    48  %left	'&'
    49  %left	'<' '>'
    50  %left	'+' '-'
    51  %left	'*' '/' '%'
    52  %token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
    53  %token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG LTYPEPC
    54  %token	<lval>	LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT LTYPEF
    55  %token	<lval>	LCONST LFP LPC LSB
    56  %token	<lval>	LBREG LLREG LSREG LFREG LMREG LXREG
    57  %token	<dval>	LFCONST
    58  %token	<sval>	LSCONST LSP
    59  %token	<sym>	LNAME LLAB LVAR
    60  %type	<lval>	con con2 expr pointer offset
    61  %type	<addr>	mem imm imm2 reg nam rel rem rim rom omem nmem
    62  %type	<addr2>	nonnon nonrel nonrem rimnon rimrem remrim
    63  %type	<addr2>	spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
    64  %type	<addr2>	spec10 spec11 spec12 spec13
    65  %%
    66  prog:
    67  |	prog 
    68  	{
    69  		stmtline = lineno;
    70  	}
    71  	line
    72  
    73  line:
    74  	LLAB ':'
    75  	{
    76  		if($1->value != pc)
    77  			yyerror("redeclaration of %s", $1->name);
    78  		$1->value = pc;
    79  	}
    80  	line
    81  |	LNAME ':'
    82  	{
    83  		$1->type = LLAB;
    84  		$1->value = pc;
    85  	}
    86  	line
    87  |	';'
    88  |	inst ';'
    89  |	error ';'
    90  
    91  inst:
    92  	LNAME '=' expr
    93  	{
    94  		$1->type = LVAR;
    95  		$1->value = $3;
    96  	}
    97  |	LVAR '=' expr
    98  	{
    99  		if($1->value != $3)
   100  			yyerror("redeclaration of %s", $1->name);
   101  		$1->value = $3;
   102  	}
   103  |	LTYPE0 nonnon	{ outcode($1, &$2); }
   104  |	LTYPE1 nonrem	{ outcode($1, &$2); }
   105  |	LTYPE2 rimnon	{ outcode($1, &$2); }
   106  |	LTYPE3 rimrem	{ outcode($1, &$2); }
   107  |	LTYPE4 remrim	{ outcode($1, &$2); }
   108  |	LTYPER nonrel	{ outcode($1, &$2); }
   109  |	LTYPED spec1	{ outcode($1, &$2); }
   110  |	LTYPET spec2	{ outcode($1, &$2); }
   111  |	LTYPEC spec3	{ outcode($1, &$2); }
   112  |	LTYPEN spec4	{ outcode($1, &$2); }
   113  |	LTYPES spec5	{ outcode($1, &$2); }
   114  |	LTYPEM spec6	{ outcode($1, &$2); }
   115  |	LTYPEI spec7	{ outcode($1, &$2); }
   116  |	LTYPEXC spec8	{ outcode($1, &$2); }
   117  |	LTYPEX spec9	{ outcode($1, &$2); }
   118  |	LTYPERT spec10	{ outcode($1, &$2); }
   119  |	LTYPEG spec11	{ outcode($1, &$2); }
   120  |	LTYPEPC spec12	{ outcode($1, &$2); }
   121  |	LTYPEF spec13	{ outcode($1, &$2); }
   122  
   123  nonnon:
   124  	{
   125  		$$.from = nullgen;
   126  		$$.to = nullgen;
   127  	}
   128  |	','
   129  	{
   130  		$$.from = nullgen;
   131  		$$.to = nullgen;
   132  	}
   133  
   134  rimrem:
   135  	rim ',' rem
   136  	{
   137  		$$.from = $1;
   138  		$$.to = $3;
   139  	}
   140  
   141  remrim:
   142  	rem ',' rim
   143  	{
   144  		$$.from = $1;
   145  		$$.to = $3;
   146  	}
   147  
   148  rimnon:
   149  	rim ','
   150  	{
   151  		$$.from = $1;
   152  		$$.to = nullgen;
   153  	}
   154  |	rim
   155  	{
   156  		$$.from = $1;
   157  		$$.to = nullgen;
   158  	}
   159  
   160  nonrem:
   161  	',' rem
   162  	{
   163  		$$.from = nullgen;
   164  		$$.to = $2;
   165  	}
   166  |	rem
   167  	{
   168  		$$.from = nullgen;
   169  		$$.to = $1;
   170  	}
   171  
   172  nonrel:
   173  	',' rel
   174  	{
   175  		$$.from = nullgen;
   176  		$$.to = $2;
   177  	}
   178  |	rel
   179  	{
   180  		$$.from = nullgen;
   181  		$$.to = $1;
   182  	}
   183  |	imm ',' rel
   184  	{
   185  		$$.from = $1;
   186  		$$.to = $3;
   187  	}
   188  
   189  spec1:	/* DATA */
   190  	nam '/' con ',' imm
   191  	{
   192  		$$.from = $1;
   193  		$$.from.scale = $3;
   194  		$$.to = $5;
   195  	}
   196  
   197  spec2:	/* TEXT */
   198  	mem ',' imm2
   199  	{
   200  		$$.from = $1;
   201  		$$.to = $3;
   202  	}
   203  |	mem ',' con ',' imm2
   204  	{
   205  		$$.from = $1;
   206  		$$.from.scale = $3;
   207  		$$.to = $5;
   208  	}
   209  
   210  spec3:	/* JMP/CALL */
   211  	',' rom
   212  	{
   213  		$$.from = nullgen;
   214  		$$.to = $2;
   215  	}
   216  |	rom
   217  	{
   218  		$$.from = nullgen;
   219  		$$.to = $1;
   220  	}
   221  
   222  spec4:	/* NOP */
   223  	nonnon
   224  |	nonrem
   225  
   226  spec5:	/* SHL/SHR */
   227  	rim ',' rem
   228  	{
   229  		$$.from = $1;
   230  		$$.to = $3;
   231  	}
   232  |	rim ',' rem ':' LLREG
   233  	{
   234  		$$.from = $1;
   235  		$$.to = $3;
   236  		if($$.from.index != D_NONE)
   237  			yyerror("dp shift with lhs index");
   238  		$$.from.index = $5;
   239  	}
   240  
   241  spec6:	/* MOVW/MOVL */
   242  	rim ',' rem
   243  	{
   244  		$$.from = $1;
   245  		$$.to = $3;
   246  	}
   247  |	rim ',' rem ':' LSREG
   248  	{
   249  		$$.from = $1;
   250  		$$.to = $3;
   251  		if($$.to.index != D_NONE)
   252  			yyerror("dp move with lhs index");
   253  		$$.to.index = $5;
   254  	}
   255  
   256  spec7:
   257  	rim ','
   258  	{
   259  		$$.from = $1;
   260  		$$.to = nullgen;
   261  	}
   262  |	rim
   263  	{
   264  		$$.from = $1;
   265  		$$.to = nullgen;
   266  	}
   267  |	rim ',' rem
   268  	{
   269  		$$.from = $1;
   270  		$$.to = $3;
   271  	}
   272  
   273  spec8:	/* CMPPS/CMPPD */
   274  	reg ',' rem ',' con
   275  	{
   276  		$$.from = $1;
   277  		$$.to = $3;
   278  		$$.to.offset = $5;
   279  	}
   280  
   281  spec9:	/* shufl */
   282  	imm ',' rem ',' reg
   283  	{
   284  		$$.from = $3;
   285  		$$.to = $5;
   286  		if($1.type != D_CONST)
   287  			yyerror("illegal constant");
   288  		$$.to.offset = $1.offset;
   289  	}
   290  
   291  spec10:	/* RET/RETF */
   292  	{
   293  		$$.from = nullgen;
   294  		$$.to = nullgen;
   295  	}
   296  |	imm
   297  	{
   298  		$$.from = $1;
   299  		$$.to = nullgen;
   300  	}
   301  
   302  spec11:	/* GLOBL */
   303  	mem ',' imm
   304  	{
   305  		$$.from = $1;
   306  		$$.to = $3;
   307  	}
   308  |	mem ',' con ',' imm
   309  	{
   310  		$$.from = $1;
   311  		$$.from.scale = $3;
   312  		$$.to = $5;
   313  	}
   314  
   315  spec12:	/* PCDATA */
   316  	rim ',' rim
   317  	{
   318  		if($1.type != D_CONST || $3.type != D_CONST)
   319  			yyerror("arguments to PCDATA must be integer constants");
   320  		$$.from = $1;
   321  		$$.to = $3;
   322  	}
   323  
   324  spec13:	/* FUNCDATA */
   325  	rim ',' rim
   326  	{
   327  		if($1.type != D_CONST)
   328  			yyerror("index for FUNCDATA must be integer constant");
   329  		if($3.type != D_EXTERN && $3.type != D_STATIC)
   330  			yyerror("value for FUNCDATA must be symbol reference");
   331  		$$.from = $1;
   332  		$$.to = $3;
   333  	}
   334  
   335  rem:
   336  	reg
   337  |	mem
   338  
   339  rom:
   340  	rel
   341  |	nmem
   342  |	'*' reg
   343  	{
   344  		$$ = $2;
   345  	}
   346  |	'*' omem
   347  	{
   348  		$$ = $2;
   349  	}
   350  |	reg
   351  |	omem
   352  
   353  rim:
   354  	rem
   355  |	imm
   356  
   357  rel:
   358  	con '(' LPC ')'
   359  	{
   360  		$$ = nullgen;
   361  		$$.type = D_BRANCH;
   362  		$$.offset = $1 + pc;
   363  	}
   364  |	LNAME offset
   365  	{
   366  		$$ = nullgen;
   367  		if(pass == 2)
   368  			yyerror("undefined label: %s", $1->name);
   369  		$$.type = D_BRANCH;
   370  		$$.offset = $2;
   371  	}
   372  |	LLAB offset
   373  	{
   374  		$$ = nullgen;
   375  		$$.type = D_BRANCH;
   376  		$$.offset = $1->value + $2;
   377  	}
   378  
   379  reg:
   380  	LBREG
   381  	{
   382  		$$ = nullgen;
   383  		$$.type = $1;
   384  	}
   385  |	LFREG
   386  	{
   387  		$$ = nullgen;
   388  		$$.type = $1;
   389  	}
   390  |	LLREG
   391  	{
   392  		$$ = nullgen;
   393  		$$.type = $1;
   394  	}
   395  |	LMREG
   396  	{
   397  		$$ = nullgen;
   398  		$$.type = $1;
   399  	}
   400  |	LSP
   401  	{
   402  		$$ = nullgen;
   403  		$$.type = D_SP;
   404  	}
   405  |	LSREG
   406  	{
   407  		$$ = nullgen;
   408  		$$.type = $1;
   409  	}
   410  |	LXREG
   411  	{
   412  		$$ = nullgen;
   413  		$$.type = $1;
   414  	}
   415  imm2:
   416  	'$' con2
   417  	{
   418  		$$ = nullgen;
   419  		$$.type = D_CONST;
   420  		$$.offset = $2;
   421  	}
   422  
   423  imm:
   424  	'$' con
   425  	{
   426  		$$ = nullgen;
   427  		$$.type = D_CONST;
   428  		$$.offset = $2;
   429  	}
   430  |	'$' nam
   431  	{
   432  		$$ = $2;
   433  		$$.index = $2.type;
   434  		$$.type = D_ADDR;
   435  		/*
   436  		if($2.type == D_AUTO || $2.type == D_PARAM)
   437  			yyerror("constant cannot be automatic: %s",
   438  				$2.sym->name);
   439  		 */
   440  	}
   441  |	'$' LSCONST
   442  	{
   443  		$$ = nullgen;
   444  		$$.type = D_SCONST;
   445  		memcpy($$.u.sval, $2, sizeof($$.u.sval));
   446  	}
   447  |	'$' LFCONST
   448  	{
   449  		$$ = nullgen;
   450  		$$.type = D_FCONST;
   451  		$$.u.dval = $2;
   452  	}
   453  |	'$' '(' LFCONST ')'
   454  	{
   455  		$$ = nullgen;
   456  		$$.type = D_FCONST;
   457  		$$.u.dval = $3;
   458  	}
   459  |	'$' '(' '-' LFCONST ')'
   460  	{
   461  		$$ = nullgen;
   462  		$$.type = D_FCONST;
   463  		$$.u.dval = -$4;
   464  	}
   465  |	'$' '-' LFCONST
   466  	{
   467  		$$ = nullgen;
   468  		$$.type = D_FCONST;
   469  		$$.u.dval = -$3;
   470  	}
   471  
   472  mem:
   473  	omem
   474  |	nmem
   475  
   476  omem:
   477  	con
   478  	{
   479  		$$ = nullgen;
   480  		$$.type = D_INDIR+D_NONE;
   481  		$$.offset = $1;
   482  	}
   483  |	con '(' LLREG ')'
   484  	{
   485  		$$ = nullgen;
   486  		$$.type = D_INDIR+$3;
   487  		$$.offset = $1;
   488  	}
   489  |	con '(' LSP ')'
   490  	{
   491  		$$ = nullgen;
   492  		$$.type = D_INDIR+D_SP;
   493  		$$.offset = $1;
   494  	}
   495  |	con '(' LSREG ')'
   496  	{
   497  		$$ = nullgen;
   498  		$$.type = D_INDIR+$3;
   499  		$$.offset = $1;
   500  	}
   501  |	con '(' LLREG '*' con ')'
   502  	{
   503  		$$ = nullgen;
   504  		$$.type = D_INDIR+D_NONE;
   505  		$$.offset = $1;
   506  		$$.index = $3;
   507  		$$.scale = $5;
   508  		checkscale($$.scale);
   509  	}
   510  |	con '(' LLREG ')' '(' LLREG '*' con ')'
   511  	{
   512  		$$ = nullgen;
   513  		$$.type = D_INDIR+$3;
   514  		$$.offset = $1;
   515  		$$.index = $6;
   516  		$$.scale = $8;
   517  		checkscale($$.scale);
   518  	}
   519  |	con '(' LLREG ')' '(' LSREG '*' con ')'
   520  	{
   521  		$$ = nullgen;
   522  		$$.type = D_INDIR+$3;
   523  		$$.offset = $1;
   524  		$$.index = $6;
   525  		$$.scale = $8;
   526  		checkscale($$.scale);
   527  	}
   528  |	'(' LLREG ')'
   529  	{
   530  		$$ = nullgen;
   531  		$$.type = D_INDIR+$2;
   532  	}
   533  |	'(' LSP ')'
   534  	{
   535  		$$ = nullgen;
   536  		$$.type = D_INDIR+D_SP;
   537  	}
   538  |	'(' LLREG '*' con ')'
   539  	{
   540  		$$ = nullgen;
   541  		$$.type = D_INDIR+D_NONE;
   542  		$$.index = $2;
   543  		$$.scale = $4;
   544  		checkscale($$.scale);
   545  	}
   546  |	'(' LLREG ')' '(' LLREG '*' con ')'
   547  	{
   548  		$$ = nullgen;
   549  		$$.type = D_INDIR+$2;
   550  		$$.index = $5;
   551  		$$.scale = $7;
   552  		checkscale($$.scale);
   553  	}
   554  
   555  nmem:
   556  	nam
   557  	{
   558  		$$ = $1;
   559  	}
   560  |	nam '(' LLREG '*' con ')'
   561  	{
   562  		$$ = $1;
   563  		$$.index = $3;
   564  		$$.scale = $5;
   565  		checkscale($$.scale);
   566  	}
   567  
   568  nam:
   569  	LNAME offset '(' pointer ')'
   570  	{
   571  		$$ = nullgen;
   572  		$$.type = $4;
   573  		$$.sym = linklookup(ctxt, $1->name, 0);
   574  		$$.offset = $2;
   575  	}
   576  |	LNAME '<' '>' offset '(' LSB ')'
   577  	{
   578  		$$ = nullgen;
   579  		$$.type = D_STATIC;
   580  		$$.sym = linklookup(ctxt, $1->name, 1);
   581  		$$.offset = $4;
   582  	}
   583  
   584  offset:
   585  	{
   586  		$$ = 0;
   587  	}
   588  |	'+' con
   589  	{
   590  		$$ = $2;
   591  	}
   592  |	'-' con
   593  	{
   594  		$$ = -$2;
   595  	}
   596  
   597  pointer:
   598  	LSB
   599  |	LSP
   600  	{
   601  		$$ = D_AUTO;
   602  	}
   603  |	LFP
   604  
   605  con:
   606  	LCONST
   607  |	LVAR
   608  	{
   609  		$$ = $1->value;
   610  	}
   611  |	'-' con
   612  	{
   613  		$$ = -$2;
   614  	}
   615  |	'+' con
   616  	{
   617  		$$ = $2;
   618  	}
   619  |	'~' con
   620  	{
   621  		$$ = ~$2;
   622  	}
   623  |	'(' expr ')'
   624  	{
   625  		$$ = $2;
   626  	}
   627  
   628  con2:
   629  	LCONST
   630  	{
   631  		$$ = ($1 & 0xffffffffLL) +
   632  			((vlong)ArgsSizeUnknown << 32);
   633  	}
   634  |	'-' LCONST
   635  	{
   636  		$$ = (-$2 & 0xffffffffLL) +
   637  			((vlong)ArgsSizeUnknown << 32);
   638  	}
   639  |	LCONST '-' LCONST
   640  	{
   641  		$$ = ($1 & 0xffffffffLL) +
   642  			(($3 & 0xffffLL) << 32);
   643  	}
   644  |	'-' LCONST '-' LCONST
   645  	{
   646  		$$ = (-$2 & 0xffffffffLL) +
   647  			(($4 & 0xffffLL) << 32);
   648  	}
   649  
   650  expr:
   651  	con
   652  |	expr '+' expr
   653  	{
   654  		$$ = $1 + $3;
   655  	}
   656  |	expr '-' expr
   657  	{
   658  		$$ = $1 - $3;
   659  	}
   660  |	expr '*' expr
   661  	{
   662  		$$ = $1 * $3;
   663  	}
   664  |	expr '/' expr
   665  	{
   666  		$$ = $1 / $3;
   667  	}
   668  |	expr '%' expr
   669  	{
   670  		$$ = $1 % $3;
   671  	}
   672  |	expr '<' '<' expr
   673  	{
   674  		$$ = $1 << $4;
   675  	}
   676  |	expr '>' '>' expr
   677  	{
   678  		$$ = $1 >> $4;
   679  	}
   680  |	expr '&' expr
   681  	{
   682  		$$ = $1 & $3;
   683  	}
   684  |	expr '^' expr
   685  	{
   686  		$$ = $1 ^ $3;
   687  	}
   688  |	expr '|' expr
   689  	{
   690  		$$ = $1 | $3;
   691  	}